Skip to content

Commit 214aacf

Browse files
open-design-release-bot[bot]open-design-crew[bot]Cheems
authored
BACKPORT-CONFLICT (#6367)
Co-authored-by: open-design-crew[bot] <299007234+open-design-crew[bot]@users.noreply.github.com> Co-authored-by: Cheems <94773058+itscheems@users.noreply.github.com>
1 parent b3aca93 commit 214aacf

48 files changed

Lines changed: 364 additions & 3904 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/daemon/src/byok/credential-service.ts

Lines changed: 0 additions & 596 deletions
This file was deleted.

apps/daemon/src/cli.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { DESIGN_SYSTEMS_USAGE, isDesignSystemsHelpArg } from './cli-help/index.j
1212
import { BRAND_USAGE, isBrandHelpArg } from './cli-help/index.js';
1313
import { parseDesignSystemRenameArgs } from './design-systems/rename-args.js';
1414
import { runLiveArtifactsToolCli } from './tools-live-artifacts-cli.js';
15-
import { runByokToolCli } from './tools-byok-cli.js';
1615
import { splitResearchSubcommand } from './research/cli-args.js';
1716
import { resolveDaemonUrl } from './daemon-url.js';
1817
import { requestJsonIpc } from '@open-design/sidecar';
@@ -334,7 +333,6 @@ const SUBCOMMAND_MAP = {
334333
artifacts: runArtifacts,
335334
media: runMedia,
336335
mcp: runMcp,
337-
byok: runByok,
338336
amr: runAmr,
339337
'message-center': runMessageCenter,
340338
research: runResearch,
@@ -1472,15 +1470,6 @@ artifact / message body. The daemon writes the bytes into the project's
14721470
files folder so the FileViewer can preview them immediately.`);
14731471
}
14741472

1475-
// ---------------------------------------------------------------------------
1476-
// Subcommand: od byok
1477-
// ---------------------------------------------------------------------------
1478-
1479-
async function runByok(args) {
1480-
const result = await runByokToolCli(args);
1481-
if (result.exitCode !== 0) process.exit(result.exitCode);
1482-
}
1483-
14841473
// ---------------------------------------------------------------------------
14851474
// Subcommand: od mcp
14861475
// ---------------------------------------------------------------------------

apps/daemon/src/mcp-brief.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const BRIEF_COPY: Record<LocalMcpBriefLocale, LocalizedBriefCopy> = {
5151
artifactNames: ENGLISH_ARTIFACT_NAMES,
5252
title: (artifactName) => `Choose the ${artifactName} direction`,
5353
description:
54-
'Choose one option for each decision. The same readable brief can be used with Open Design Cloud, Local Codex, or Secure BYOK.',
54+
'Choose one option for each decision. The same readable brief can be used with Open Design Cloud or Local Codex.',
5555
submitLabel: 'Confirm brief',
5656
completeCard:
5757
'Complete the rendered Open Design brief card. The confirmation returns a readable summary; internal correlation values must remain hidden.',

apps/daemon/src/mcp-observability.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,19 +147,30 @@ export function validateExternalPluginContext(
147147
};
148148
}
149149

150-
export function validatePluginWorkflowId(value: unknown): string {
150+
function validateCanonicalPluginCorrelationId(
151+
value: unknown,
152+
fieldName: 'pluginWorkflowId' | 'requestId',
153+
): string {
151154
if (
152155
typeof value !== 'string'
153156
|| value.length > 64
154157
|| !WORKFLOW_ID_PATTERN.test(value)
155158
) {
156159
throw pluginContractError(
157-
'pluginWorkflowId must be a canonical UUID or ULID',
160+
`${fieldName} must be a canonical UUID or ULID`,
158161
);
159162
}
160163
return value;
161164
}
162165

166+
export function validatePluginWorkflowId(value: unknown): string {
167+
return validateCanonicalPluginCorrelationId(value, 'pluginWorkflowId');
168+
}
169+
170+
export function validatePluginRequestId(value: unknown): string {
171+
return validateCanonicalPluginCorrelationId(value, 'requestId');
172+
}
173+
163174
export function mapMcpHostProduct(
164175
clientInfo: { name?: unknown; version?: unknown } | null | undefined,
165176
): AnalyticsHostProduct {

apps/daemon/src/mcp.ts

Lines changed: 12 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import {
5757
pluginContractError,
5858
resolvePluginGenerationSloWindowMs,
5959
validateExternalPluginContext,
60+
validatePluginRequestId,
6061
validatePluginWorkflowId,
6162
} from './mcp-observability.js';
6263

@@ -67,7 +68,7 @@ const OPEN_DESIGN_BRIEF_APP_RESOURCE =
6768
'ui://open-design/artifact-card-v6.html';
6869

6970
export const MCP_SERVER_INSTRUCTIONS = [
70-
'Use only these product names in user-facing replies: Open Design Cloud, Local Codex, and Secure BYOK.',
71+
'Use only these product names in user-facing replies: Open Design Cloud and Local Codex.',
7172
'Tool names, runtime ids, endpoints, and correlation values are machine protocol. Never repeat them as product copy.',
7273
].join('\n');
7374

@@ -84,7 +85,7 @@ interface ProjectPayload { project?: ProjectSummary; id?: string; name?: string;
8485
interface ActiveContext { active?: boolean; projectId?: string; projectName?: string | null; fileName?: string | null; ageMs?: number | null }
8586
type ResolvedProject = { id: string; name: string; source: 'uuid' | 'id' | 'exact' | 'slug' | 'substring' };
8687
interface ProjectListCache { baseUrl: string; t: number; list: ProjectSummary[] }
87-
interface McpArgs extends JsonObject { project?: unknown; entry?: unknown; include?: unknown; maxBytes?: unknown; path?: unknown; offset?: unknown; limit?: unknown; since?: unknown; query?: unknown; pattern?: unknown; max?: unknown; name?: unknown; content?: unknown; encoding?: unknown; artifactManifest?: unknown; confirm?: unknown; prompt?: unknown; plugin?: unknown; inputs?: unknown; agent?: unknown; model?: unknown; serviceTier?: unknown; byokProfile?: unknown; apiKey?: unknown; requestId?: unknown; resume?: unknown; runId?: unknown; id?: unknown; designSystem?: unknown; skill?: unknown; includeUnavailable?: unknown; artifactType?: unknown; projectTitle?: unknown; locale?: unknown; knownAnswers?: unknown; skip?: unknown; briefDraftId?: unknown; nonce?: unknown; answers?: unknown; externalPluginContext?: unknown; pluginWorkflowId?: unknown }
88+
interface McpArgs extends JsonObject { project?: unknown; entry?: unknown; include?: unknown; maxBytes?: unknown; path?: unknown; offset?: unknown; limit?: unknown; since?: unknown; query?: unknown; pattern?: unknown; max?: unknown; name?: unknown; content?: unknown; encoding?: unknown; artifactManifest?: unknown; confirm?: unknown; prompt?: unknown; plugin?: unknown; inputs?: unknown; agent?: unknown; model?: unknown; serviceTier?: unknown; apiKey?: unknown; requestId?: unknown; resume?: unknown; runId?: unknown; id?: unknown; designSystem?: unknown; skill?: unknown; includeUnavailable?: unknown; artifactType?: unknown; projectTitle?: unknown; locale?: unknown; knownAnswers?: unknown; skip?: unknown; briefDraftId?: unknown; nonce?: unknown; answers?: unknown; externalPluginContext?: unknown; pluginWorkflowId?: unknown }
8889
interface ProjectFileBundleEntry { name: string; mime: string; size: number | null; content: string | null; binary: boolean }
8990
interface BundleInput { project: ProjectPayload | ProjectSummary; entry: string; files: ProjectFileBundleEntry[]; truncated: boolean; skippedFileCount?: number; active: ActiveContext | null; resolved?: ResolvedProject | null }
9091
interface ErrorWithCode { message?: string; code?: string; cause?: { code?: string } }
@@ -616,17 +617,6 @@ export const TOOL_DEFS = [
616617
},
617618
annotations: { ...READ_ANNOTATIONS, title: 'List Open Design plugins' },
618619
},
619-
{
620-
name: 'list_byok_profiles',
621-
description:
622-
'List secure local BYOK profile references available to start_run.byokProfile. Returns only non-secret metadata; API keys never cross MCP.',
623-
inputSchema: {
624-
type: 'object',
625-
properties: { pluginWorkflowId: PLUGIN_WORKFLOW_ID_ARG },
626-
additionalProperties: false,
627-
},
628-
annotations: { ...READ_ANNOTATIONS, title: 'List secure BYOK profiles' },
629-
},
630620
{
631621
name: 'start_vela_login',
632622
description:
@@ -695,15 +685,10 @@ export const TOOL_DEFS = [
695685
type: 'string',
696686
description: "Service tier override for the selected model, e.g. 'priority' for Codex Fast. Optional.",
697687
},
698-
byokProfile: {
699-
type: 'string',
700-
description:
701-
'Secure profile id from list_byok_profiles. Selects the local BYOK OpenCode runtime; raw API keys are never accepted by MCP.',
702-
},
703688
requestId: {
704689
type: 'string',
705690
description:
706-
'Stable id for this confirmed generation action. Generate it once before calling start_run and reuse it verbatim if the tool response is lost or retried; a different payload with the same id is rejected.',
691+
'Stable canonical UUID or ULID for this confirmed generation action. Generate it once before calling start_run and reuse it verbatim if the tool response is lost or retried; a different payload with the same id is rejected.',
707692
},
708693
resume: {
709694
type: 'boolean',
@@ -849,7 +834,7 @@ export function localMcpResourceDefinitions() {
849834
name: 'Open Design brief',
850835
title: 'Choose the artifact direction',
851836
description:
852-
'Interactive local Open Design brief card shared by Open Design Cloud, Local Codex, and Secure BYOK modes.',
837+
'Interactive local Open Design brief card shared by Open Design Cloud and Local Codex modes.',
853838
mimeType: 'text/html;profile=mcp-app',
854839
_meta: {
855840
ui: {
@@ -1271,7 +1256,7 @@ function mcpFailureFacts(
12711256
const failureStage =
12721257
name === 'collect_brief' || name === 'confirm_brief'
12731258
? 'brief'
1274-
: name.includes('vela_login') || name === 'list_byok_profiles'
1259+
: name.includes('vela_login')
12751260
? 'auth'
12761261
: name.includes('project')
12771262
? 'project'
@@ -1622,12 +1607,9 @@ export async function runMcpStdio({ daemonUrl }: RunMcpOptions): Promise<void> {
16221607
' - collect_brief first for a new artifact unless the user explicitly',
16231608
' asks to skip questions. Let the user complete the rendered card;',
16241609
' confirm_brief returns the readable brief to reuse with Open Design',
1625-
' Cloud, Local Codex, or Secure BYOK. Never print or ask the user to copy',
1610+
' Cloud or Local Codex. Never print or ask the user to copy',
16261611
' briefDraftId, nonce, or any other internal correlation value.',
16271612
' - list_skills / list_plugins to see what you can ask OD to make.',
1628-
' - list_byok_profiles returns secure local credential references when',
1629-
' the user explicitly chooses Secure BYOK. Never request or pass a',
1630-
' raw API key through MCP; pass only start_run.byokProfile.',
16311613
' - for Open Design Cloud, call the Cloud login-status tool first.',
16321614
' If signed out, call the Cloud sign-in tool once, show its activation',
16331615
' URL/code when present, and poll login status until loggedIn:true.',
@@ -1639,8 +1621,9 @@ export async function runMcpStdio({ daemonUrl }: RunMcpOptions): Promise<void> {
16391621
' generate into; start_run requires an existing project.',
16401622
' - start_run(prompt, requestId, [skill], [plugin], [inputs]) kicks off',
16411623
' generation in the active or named project and returns a runId.',
1642-
' Generate requestId once per confirmed user action and reuse the',
1643-
' exact same value after a timeout/lost response. Do not call',
1624+
' Generate a canonical UUID or ULID requestId once per confirmed',
1625+
' user action and reuse the exact same value after a timeout/lost',
1626+
' response. Do not call',
16441627
' start_run again while get_run reports the original run in flight.',
16451628
' If get_run returns failureAction:"recharge", show rechargeUrl;',
16461629
' after the user confirms top-up, call the exact original start_run',
@@ -2037,8 +2020,6 @@ async function handleMcpToolCall(
20372020
return ok(await getJson<SkillsPayload>(`${baseUrl}/api/skills`));
20382021
case 'list_plugins':
20392022
return ok(await listPlugins(baseUrl));
2040-
case 'list_byok_profiles':
2041-
return ok(await listByokProfiles(baseUrl));
20422023
case 'list_agents':
20432024
return ok(await listAgents(baseUrl, args.includeUnavailable === true));
20442025
case 'start_vela_login': {
@@ -2263,58 +2244,6 @@ async function listAgents(baseUrl: string, includeUnavailable: boolean): Promise
22632244
return { agents };
22642245
}
22652246

2266-
async function listByokProfiles(baseUrl: string): Promise<JsonObject> {
2267-
const payload = await getJson<JsonObject>(`${baseUrl}/api/byok/profiles`);
2268-
const rawProfiles = Array.isArray(payload.profiles) ? payload.profiles : [];
2269-
const profiles = rawProfiles.flatMap((value) => {
2270-
if (!value || typeof value !== 'object' || Array.isArray(value)) return [];
2271-
const profile = value as JsonObject;
2272-
if (
2273-
typeof profile.id !== 'string'
2274-
|| typeof profile.label !== 'string'
2275-
|| typeof profile.protocol !== 'string'
2276-
|| typeof profile.baseUrl !== 'string'
2277-
|| typeof profile.model !== 'string'
2278-
) {
2279-
return [];
2280-
}
2281-
try {
2282-
const parsed = new URL(profile.baseUrl);
2283-
if (
2284-
!['http:', 'https:'].includes(parsed.protocol)
2285-
|| parsed.username.length > 0
2286-
|| parsed.password.length > 0
2287-
|| parsed.search.length > 0
2288-
|| parsed.hash.length > 0
2289-
) {
2290-
return [];
2291-
}
2292-
} catch {
2293-
return [];
2294-
}
2295-
return [{
2296-
id: profile.id,
2297-
label: profile.label,
2298-
protocol: profile.protocol,
2299-
baseUrl: profile.baseUrl,
2300-
model: profile.model,
2301-
...(typeof profile.apiVersion === 'string'
2302-
? { apiVersion: profile.apiVersion }
2303-
: {}),
2304-
requiresApiKey: profile.requiresApiKey === true,
2305-
configured: profile.configured === true,
2306-
...(typeof profile.keyTail === 'string' ? { keyTail: profile.keyTail } : {}),
2307-
...(typeof profile.createdAt === 'number' ? { createdAt: profile.createdAt } : {}),
2308-
...(typeof profile.updatedAt === 'number' ? { updatedAt: profile.updatedAt } : {}),
2309-
}];
2310-
});
2311-
return {
2312-
available: payload.available === true,
2313-
backend: typeof payload.backend === 'string' ? payload.backend : 'unknown',
2314-
profiles,
2315-
};
2316-
}
2317-
23182247
// Derive a valid project id ([A-Za-z0-9._-], <=128) from a display name,
23192248
// with a short random suffix so repeated creates with the same name
23202249
// don't collide on the daemon's primary key.
@@ -2341,7 +2270,7 @@ async function startRun(
23412270
|| containsMcpCredentialField(args.inputs)
23422271
) {
23432272
throw new Error(
2344-
'raw API keys are not accepted by Open Design MCP. Save the key through the Open Design UI or `od byok save --api-key-stdin`, then pass only byokProfile.',
2273+
'raw API keys are not accepted by Open Design MCP. Configure Local BYOK in the Open Design UI and start that run from the local product instead.',
23452274
);
23462275
}
23472276
const { id, resolved, active } = await resolveProjectArg(baseUrl, args.project);
@@ -2360,7 +2289,7 @@ async function startRun(
23602289
: randomUUID();
23612290
const body: JsonObject = { projectId: id, clientRequestId: requestId };
23622291
if (options.pluginAttribution) {
2363-
validatePluginWorkflowId(requestId);
2292+
validatePluginRequestId(requestId);
23642293
const logical = logicalPluginRequestDigest(requestId);
23652294
body.analyticsHints = {
23662295
entrySurface: 'external_mcp',
@@ -2397,18 +2326,6 @@ async function startRun(
23972326
if (typeof args.serviceTier === 'string' && args.serviceTier.length > 0) {
23982327
body.serviceTier = args.serviceTier;
23992328
}
2400-
if (args.byokProfile !== undefined) {
2401-
requireString(args.byokProfile, 'byokProfile');
2402-
if (
2403-
typeof args.agent === 'string'
2404-
&& args.agent.length > 0
2405-
&& args.agent !== 'byok-opencode'
2406-
) {
2407-
throw new Error('byokProfile can only be used with the byok-opencode agent.');
2408-
}
2409-
body.agentId = 'byok-opencode';
2410-
body.byokProfileId = args.byokProfile;
2411-
}
24122329
if (args.inputs !== undefined) {
24132330
if (args.inputs === null || typeof args.inputs !== 'object' || Array.isArray(args.inputs)) {
24142331
throw new Error('inputs must be an object');

0 commit comments

Comments
 (0)