dsh-opendesign-corouter 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts", "../src/adapter.ts", "../src/catalog.ts", "../src/config.ts", "../src/protocol-options.ts", "../src/util.ts", "../src/model-settings.ts", "../src/conversion.ts", "../src/stream.ts", "../src/protocols/errors.ts", "../src/protocols/sse.ts", "../src/empty-turn.ts", "../src/protocols/index.ts", "../src/protocols/chat-completions.ts", "../src/protocols/headers.ts", "../src/protocols/messages.ts", "../src/protocols/parts.ts", "../src/protocols/usage.ts", "../src/protocols/responses.ts", "../src/model-discovery.ts", "../src/auth.ts", "../src/login.ts", "../src/quota.ts", "../src/desktop-quota.ts", "../src/remote.ts"],
4
- "sourcesContent": ["import { randomUUID, createHash } from 'node:crypto';\nimport type { Context } from '@deepseek-ai/cordis';\nimport { credentialKey, credentialRef, type CredentialRecord, type CredentialProvider } from '@deepseek-ai/dsh-credentials';\nimport { launchEnvironmentOf } from '@deepseek-ai/dsh-launch-environment';\nimport { Remote, RemoteError, TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';\nimport type {} from '@deepseek-ai/dsh-typert-registry';\nimport type {} from '@deepseek-ai/dsh-attachment';\nimport type {} from '@deepseek-ai/dsh-settings';\nimport type {} from '@deepseek-ai/cordis-plugin-loader';\nimport { LlmError } from '@deepseek-ai/dsh-llm';\nimport { CoRouterAdapter } from './adapter.js';\nimport { fetchModelCatalog, ModelDiscoveryError } from './model-discovery.js';\nimport { isModelEnabled } from './model-settings.js';\nimport type { CatalogModel } from './catalog.js';\nimport { Config, SETTINGS_NS, PLAN_PROVIDER, PAID_PROVIDER, readConfig, type LiveConfig } from './config.js';\nimport { MODELS } from './catalog.js';\nimport { resolveSession, cookieSession, type LoginGrant } from './auth.js';\nimport { ConsoleLogin } from './login.js';\nimport { readQuota, ConsoleError, type QuotaSnapshot } from './quota.js';\nimport { readDesktopQuota } from './desktop-quota.js';\nimport { record } from './util.js';\nimport { parseStatus, parseLoginState, parseStartLoginRequest as parseStartLogin, parseCancelLoginRequest as parseCancelLogin, parseSaveApiKeyRequest as parseSaveApiKey,\n type Status, type LoginState, type StartLoginRequest, type CancelLoginRequest, type SaveApiKeyRequest } from './remote.js';\n\nexport { Config } from './config.js';\nexport { CoRouterAdapter } from './adapter.js';\nexport { MODELS } from './catalog.js';\nexport const name = 'llm-opendesign-corouter';\nexport const inject = ['llm'];\nconst API_KEY = credentialKey(name, 'api-key');\nconst SESSION = credentialKey(name, 'console');\nconst hash = (value: unknown) => createHash('sha256').update(JSON.stringify(value) ?? '').digest('hex');\nconst needLogin = (): QuotaSnapshot => ({ state: 'need-login', updatedAt: new Date().toISOString(), windows: [], balances: {}, note: '\u5C1A\u672A\u8BFB\u53D6\u989D\u5EA6\uFF1B\u53EF\u4F7F\u7528\u684C\u9762\u767B\u5F55\u6001\u6216\u5728\u8FDE\u63A5\u9875\u767B\u5F55' });\ninterface CapturedState {\n apiRecord: CredentialRecord | undefined; sessionRecord: CredentialRecord | undefined;\n key: string | undefined; config: ReturnType<typeof readConfig>;\n}\ninterface LoginCapture { revision: string; sessionHash: string; configHash: string }\nexport interface HostDependencies {\n resolveSession: typeof resolveSession;\n readQuota: typeof readQuota;\n readDesktopQuota: typeof readDesktopQuota;\n fetchModels?: typeof fetchModelCatalog;\n modelsChanged?: () => void;\n}\nfunction grantOf(value: CredentialRecord | undefined): LoginGrant | undefined {\n if (value?.kind !== 'grant' || !record(value.payload) || typeof value.payload.cookie !== 'string') return;\n return { cookie: value.payload.cookie, ...(typeof value.payload.expiresAt === 'number' ? { expiresAt: value.payload.expiresAt } : {}) };\n}\nexport class OpenDesignCoRouterService extends TypertRemoteService {\n private readonly _config: () => ReturnType<typeof readConfig>;\n private readonly _login: ConsoleLogin;\n private readonly _lifetime = new AbortController();\n private _revision = randomUUID();\n private _fingerprint = '';\n private _quota = needLogin();\n private _quotaAt = 0;\n private _quotaConfig = '';\n private _quotaIdentity: string | undefined;\n private _quotaEpoch = 0;\n private _quotaPending: Promise<QuotaSnapshot> | undefined;\n private _quotaController: AbortController | undefined;\n guardedTurns: number = 0;\n private _models: readonly CatalogModel[] = MODELS;\n private _modelsUpdatedAt: string | undefined;\n private _modelsError: string | undefined;\n private _modelsFingerprint = '';\n private _modelsEpoch = 0;\n private _modelsPending: Promise<Status> | undefined;\n private _modelsController: AbortController | undefined;\n modelCatalog(): readonly CatalogModel[] { return this._models; }\n constructor(ctx: Context, config: () => ReturnType<typeof readConfig>, readonly dependencies: HostDependencies = { resolveSession, readQuota, readDesktopQuota }) {\n super(ctx, 'openDesignCoRouter');\n this._config = config;\n this._login = new ConsoleLogin({\n capture: async expectedRevision => {\n const state = await this._state();\n this._expect(expectedRevision);\n this._credentials();\n return { revision: expectedRevision, sessionHash: hash(state.sessionRecord), configHash: hash(state.config) } satisfies LoginCapture;\n },\n verify: async (cookie, signal) => {\n const session = cookieSession(cookie, 'login');\n if (!session) throw new ConsoleError('auth');\n const quota = await this.dependencies.readQuota(session, signal);\n return { balanceOk: true, coverage: quota.state === 'ok' ? 'complete' : 'partial', windows: quota.windows };\n },\n commit: async (cookie, captured, signal, expiresAt) => {\n if (!record(captured) || typeof captured.revision !== 'string' || typeof captured.sessionHash !== 'string' || typeof captured.configHash !== 'string') throw this._conflict();\n await this._state();\n this._expect(captured.revision);\n signal.throwIfAborted();\n await this._credentials().modifyRecord(SESSION, async current => {\n signal.throwIfAborted();\n if (hash(current) !== captured.sessionHash || hash(this._config()) !== captured.configHash) throw this._conflict();\n return { kind: 'grant', payload: { cookie, expiresAt, savedAt: new Date().toISOString() } };\n });\n this._invalidateQuota();\n },\n });\n ctx.effect(() => () => { this._lifetime.abort(); this._login.dispose(); });\n }\n private _credentials(): CredentialProvider {\n const service = this.ctx.get('credentials');\n if (!service) throw new RemoteError('opendesign/credentials-unavailable', 'DSH \u51ED\u636E\u670D\u52A1\u4E0D\u53EF\u7528\uFF1B\u53EF\u5148\u4F7F\u7528\u542F\u52A8\u73AF\u5883\u53D8\u91CF', undefined);\n return service;\n }\n async resolveApiKey(ref: string): Promise<string | undefined> {\n const credentials = this.ctx.get('credentials');\n const ambient = credentials ? (await credentials.resolve(credentialRef(ref)))?.value : launchEnvironmentOf(this.ctx).get(ref)?.value;\n if (ambient?.trim()) return ambient;\n const saved = await credentials?.readRecord(API_KEY);\n return saved?.kind === 'api-key' ? saved.key : undefined;\n }\n private async _state(): Promise<CapturedState> {\n const credentials = this.ctx.get('credentials'), config = this._config();\n const [apiRecord, sessionRecord, key] = await Promise.all([credentials?.readRecord(API_KEY), credentials?.readRecord(SESSION), this.resolveApiKey(config.apiKeyEnv)]);\n const state = { apiRecord, sessionRecord, key, config };\n const modelsFingerprint = hash({ key, baseURL: config.baseURL });\n if (modelsFingerprint !== this._modelsFingerprint) {\n const changed = this._modelsUpdatedAt !== undefined;\n this._modelsFingerprint = modelsFingerprint;\n this._modelsEpoch++;\n this._modelsController?.abort();\n this._modelsPending = undefined;\n this._models = MODELS;\n this._modelsUpdatedAt = undefined;\n this._modelsError = undefined;\n if (changed) this.dependencies.modelsChanged?.();\n }\n const fingerprint = hash(state);\n if (fingerprint !== this._fingerprint) { this._fingerprint = fingerprint; this._revision = randomUUID(); }\n return state;\n }\n private _conflict() { return new RemoteError('opendesign/revision-conflict', '\u8FDE\u63A5\u6216\u51ED\u636E\u5DF2\u6539\u53D8\uFF0C\u8BF7\u5237\u65B0\u9875\u9762\u540E\u91CD\u8BD5', undefined); }\n private _expect(revision: string) { if (revision !== this._revision) throw this._conflict(); }\n private _invalidateQuota(): void { this._quotaAt = 0; this._quotaEpoch++; this._quota = needLogin(); this._quotaIdentity = undefined; this._quotaController?.abort(); this._quotaPending = undefined; }\n @Remote('status')\n async status(): Promise<Status> {\n const state = await this._state();\n const quotaConfig = hash({ desktop: state.config.useDesktopCredential, session: state.sessionRecord, refreshSeconds: state.config.quotaRefreshSeconds });\n if (this._quotaConfig !== quotaConfig) { this._quotaConfig = quotaConfig; this._invalidateQuota(); }\n return parseStatus({\n revision: this._revision, apiKeyConfigured: Boolean(state.key?.trim()), ...(this._quota.source ? { sessionSource: this._quota.source } : {}),\n quota: this._quota, login: this._login.status(), config: state.config, guardedTurns: this.guardedTurns,\n models: this._models.map(({ id, name, group, contextWindow, maxOutputTokens, reasoningEfforts }) => ({\n id, name, group, enabled: isModelEnabled(id, state.config.modelSettings),\n ...(contextWindow === undefined ? {} : { contextWindow }),\n ...(maxOutputTokens === undefined ? {} : { maxOutputTokens }),\n ...(reasoningEfforts === undefined ? {} : { reasoningEfforts }),\n })),\n modelsSource: this._modelsUpdatedAt ? 'openai' : 'builtin',\n ...(this._modelsUpdatedAt ? { modelsUpdatedAt: this._modelsUpdatedAt } : {}),\n ...(this._modelsError ? { modelsError: this._modelsError } : {}),\n });\n }\n @Remote('refreshModels')\n async refreshModels(): Promise<Status> {\n const state = await this._state();\n if (this._modelsPending) return this._modelsPending;\n const key = state.key;\n if (!key?.trim()) {\n this._modelsError = '\u8BF7\u5148\u914D\u7F6E API Key\uFF0C\u518D\u4ECE OpenAI \u7AEF\u53E3\u62C9\u53D6\u6A21\u578B\u3002';\n return this.status();\n }\n const epoch = this._modelsEpoch;\n const controller = new AbortController();\n this._modelsController = controller;\n const signal = AbortSignal.any([controller.signal, this._lifetime.signal]);\n const run = (async () => {\n try {\n const models = await (this.dependencies.fetchModels ?? fetchModelCatalog)(state.config.baseURL, key, signal);\n await this._state();\n if (signal.aborted || epoch !== this._modelsEpoch) return this.status();\n this._models = models;\n this._modelsUpdatedAt = new Date().toISOString();\n this._modelsError = undefined;\n this.dependencies.modelsChanged?.();\n } catch (error) {\n if (!signal.aborted && epoch === this._modelsEpoch) this._modelsError = error instanceof ModelDiscoveryError ? error.message : '\u6A21\u578B\u5217\u8868\u66F4\u65B0\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002';\n }\n return this.status();\n })();\n this._modelsPending = run;\n try { return await run; }\n finally { if (this._modelsPending === run) this._modelsPending = undefined; }\n }\n @Remote('refreshQuota')\n async refreshQuota(): Promise<QuotaSnapshot> { return this._refreshQuota(false); }\n @Remote('refreshQuotaNow')\n async refreshQuotaNow(): Promise<QuotaSnapshot> { return this._refreshQuota(true); }\n private async _refreshQuota(force: boolean): Promise<QuotaSnapshot> {\n const state = await this._state();\n const fingerprint = hash({ desktop: state.config.useDesktopCredential, session: state.sessionRecord, refreshSeconds: state.config.quotaRefreshSeconds });\n if (fingerprint !== this._quotaConfig) { this._quotaConfig = fingerprint; this._invalidateQuota(); }\n if (this._quotaPending) return this._quotaPending;\n if (!force) {\n if (this._quota.autoRefreshPaused) return this._quota;\n const next = this._quota.nextRefreshAt ? Date.parse(this._quota.nextRefreshAt) : this._quotaAt + 5000;\n if (Date.now() < next) return this._quota;\n }\n const epoch = this._quotaEpoch;\n const controller = new AbortController(); this._quotaController = controller;\n const signal = AbortSignal.any([controller.signal, this._lifetime.signal]);\n const failures = force ? 0 : this._quota.refreshFailures ?? 0;\n const run = this._readQuota(epoch, signal, failures);\n this._quotaPending = run;\n void run.finally(() => { if (this._quotaPending === run) this._quotaPending = undefined; }).catch(() => {});\n return run;\n }\n private async _readQuota(epoch: number, signal: AbortSignal, failures: number): Promise<QuotaSnapshot> {\n const config = this._config();\n let result: QuotaSnapshot;\n let identity: string | undefined;\n let refreshFailed = false;\n try {\n const authDeps = {\n useDesktop: config.useDesktopCredential,\n readGrant: async () => grantOf(await this.ctx.get('credentials')?.readRecord(SESSION)),\n resolveRef: async (ref: string) => {\n const credentials = this.ctx.get('credentials');\n return credentials ? (await credentials.resolve(credentialRef(ref)))?.value : launchEnvironmentOf(this.ctx).get(ref)?.value;\n },\n };\n const auth = await this.dependencies.resolveSession(authDeps);\n if (auth.state === 'ready') identity = hash(auth.session);\n if (auth.state === 'need-login') result = needLogin();\n else if (auth.session.source !== 'desktop') result = await this.dependencies.readQuota(auth.session, signal);\n else {\n try {\n result = await this.dependencies.readDesktopQuota(auth.session, signal);\n if (result.state === 'partial') {\n const fallback = await this.dependencies.resolveSession({ ...authDeps, useDesktop: false });\n if (fallback.state === 'ready') {\n try {\n const complete = await this.dependencies.readQuota(fallback.session, signal);\n if (complete.state === 'ok' && (complete.windows.length > 0 || complete.eligible === false)) result = { ...complete, note: `\u684C\u9762\u767B\u5F55\u6001\u4EC5\u63D0\u4F9B\u90E8\u5206\u989D\u5EA6\uFF1B\u5F53\u524D\u663E\u793A\u72EC\u7ACB\u767B\u5F55\u8D26\u53F7\u7684\u5B8C\u6574\u989D\u5EA6\u3002${complete.note ? ` ${complete.note}` : ''}` };\n } catch (error) {\n if (signal.aborted) throw error;\n // A failed optional fallback does not discard the usable desktop snapshot.\n }\n }\n }\n }\n catch (error) {\n // An expired desktop credential must not permanently shadow a valid console login.\n if (!(error instanceof ConsoleError) || !['auth', 'permission'].includes(error.kind)) throw error;\n const fallback = await this.dependencies.resolveSession({ ...authDeps, useDesktop: false });\n if (fallback.state !== 'ready') throw new ConsoleError('auth');\n result = await this.dependencies.readQuota(fallback.session, signal);\n }\n }\n } catch (error) {\n const authFailure = error instanceof ConsoleError && error.kind === 'auth';\n refreshFailed = !authFailure;\n const hasReadings = this._quota.windows.length > 0 || Object.keys(this._quota.balances).length > 0;\n if (!authFailure && identity !== undefined && identity === this._quotaIdentity && hasReadings) {\n result = { ...this._quota, state: 'partial', stale: true, note: '\u989D\u5EA6\u5237\u65B0\u5931\u8D25\uFF0C\u5F53\u524D\u663E\u793A\u4E0A\u6B21\u6210\u529F\u8BFB\u6570\u3002' };\n } else {\n result = { ...needLogin(), state: authFailure ? 'need-login' : 'error', note: error instanceof ConsoleError ? error.message : '\u989D\u5EA6\u8BFB\u53D6\u6682\u65F6\u5931\u8D25\uFF1B\u8BF7\u68C0\u67E5\u8FDE\u63A5\u6216\u91CD\u65B0\u767B\u5F55' };\n }\n }\n if (!signal.aborted && epoch === this._quotaEpoch) {\n this._quotaAt = Date.now();\n if (refreshFailed) {\n const count = failures + 1;\n const paused = count >= 6;\n const { nextRefreshAt: _previousPlan, ...previous } = result;\n result = { ...previous, refreshFailures: count, autoRefreshPaused: paused,\n ...(paused ? { note: `${result.note ?? '\u989D\u5EA6\u5237\u65B0\u5931\u8D25'} \u81EA\u52A8\u91CD\u8BD5\u5DF2\u6682\u505C\uFF0C\u8BF7\u70B9\u51FB\u5237\u65B0\u989D\u5EA6\u91CD\u8BD5\u3002` } : { nextRefreshAt: new Date(this._quotaAt + Math.min(60_000, 5000 * 2 ** (count - 1))).toISOString() }),\n };\n } else if (result.state !== 'need-login') {\n result = { ...result, nextRefreshAt: new Date(this._quotaAt + (config.quotaRefreshSeconds ?? 60) * 1000).toISOString() };\n }\n this._quota = result;\n this._quotaIdentity = identity;\n }\n return epoch === this._quotaEpoch ? result : this._quota;\n }\n @Remote('startLogin')\n async startLogin(input: StartLoginRequest): Promise<LoginState> {\n const request = parseStartLogin(input);\n await this._state(); this._expect(request.expectedRevision); this._credentials();\n return parseLoginState(this._login.start(request));\n }\n @Remote('loginStatus')\n loginStatus(): LoginState { return parseLoginState(this._login.status()); }\n @Remote('cancelLogin')\n cancelLogin(input: CancelLoginRequest): LoginState { return parseLoginState(this._login.cancel(parseCancelLogin(input))); }\n @Remote('saveApiKey')\n async saveApiKey(input: SaveApiKeyRequest): Promise<Status> {\n const request = parseSaveApiKey(input), state = await this._state();\n this._expect(request.expectedRevision);\n const expected = hash(state.apiRecord);\n await this._credentials().modifyRecord(API_KEY, async current => {\n if (hash(current) !== expected || hash(this._config()) !== hash(state.config)) throw this._conflict();\n return { kind: 'api-key', key: request.value };\n });\n return this.status();\n }\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context { openDesignCoRouter: OpenDesignCoRouterService }\n}\ndeclare module '@deepseek-ai/dsh-typert-protocol' {\n interface RemoteErrorDetailsMap {\n 'opendesign/credentials-unavailable': undefined;\n 'opendesign/revision-conflict': undefined;\n }\n}\nexport function apply(ctx: Context, config: LiveConfig): void {\n const current = () => readConfig(config);\n current();\n ctx.inject(['settings'], scope => scope.effect(() => scope.settings.configure({ auto: false }, ctx.fiber)));\n let modelsChanged = () => {};\n const service = new OpenDesignCoRouterService(ctx, current, { resolveSession, readQuota, readDesktopQuota, modelsChanged: () => modelsChanged() });\n const adapter = new CoRouterAdapter({\n config: current, models: () => service.modelCatalog(), apiKey: ref => service.resolveApiKey(ref), onEmptyTurn: () => { service.guardedTurns++; },\n imageDataUrl: async (ref, signal) => {\n const attachments = ctx.get('attachments');\n if (!attachments) return undefined;\n const image = await attachments.readImage(ref, signal);\n return `data:${image.ref.mediaType};base64,${Buffer.from(image.data).toString('base64')}`;\n },\n });\n const registration = ctx.llm.registerAdapter([PLAN_PROVIDER, PAID_PROVIDER], adapter);\n modelsChanged = () => registration.replace([PLAN_PROVIDER, PAID_PROVIDER]);\n let configFingerprint = hash(current());\n ctx.on('loader/volatile-update', () => {\n const next = hash(current());\n if (next === configFingerprint) return;\n configFingerprint = next;\n modelsChanged();\n });\n ctx.llm.registerModelDiscovery(SETTINGS_NS, async (request, signal) => {\n if (request.provider !== undefined && ![PLAN_PROVIDER, PAID_PROVIDER].includes(request.provider)) throw new LlmError('\u4E0D\u662F\u672C\u63D2\u4EF6\u7684\u6A21\u578B\u901A\u9053', 'INVALID_REQUEST');\n const config = current();\n const key = request.apiKey ?? await service.resolveApiKey(config.apiKeyEnv);\n if (!key) throw new LlmError('\u8BF7\u5148\u914D\u7F6E CoRouter API Key', 'MISSING_CREDENTIAL');\n // Model discovery is always OpenAI-compatible, irrespective of request.api or inference protocol.\n const models = await fetchModelCatalog(config.baseURL, key, signal);\n return models.map(row => ({ id: row.id, name: row.name, ...(row.contextWindow === undefined ? {} : { contextWindow: row.contextWindow }), ...(row.maxOutputTokens === undefined ? {} : { maxTokens: row.maxOutputTokens }), ...(row.inputModalities ? { inputModalities: row.inputModalities } : {}) }));\n });\n ctx.llm.registerConfigurableProviders([\n { provider: PLAN_PROVIDER, displayName: 'OpenDesign CoRouter \u00B7 \u5957\u9910\u8D60\u9001', settingsNs: SETTINGS_NS, settingsPath: [], defaultBaseURL: current().baseURL },\n { provider: PAID_PROVIDER, displayName: 'OpenDesign CoRouter \u00B7 \u4ED8\u8D39\u6A21\u578B', settingsNs: SETTINGS_NS, settingsPath: [], defaultBaseURL: current().baseURL },\n ]);\n ctx.effect(() => () => adapter.dispose());\n}\n", "import {\n LlmAdapter, LlmError, ReasoningEffortId, assertUsableApiKey,\n type GenerateOptions, type LlmModelInfo, type LlmResolvedModelInfo, type PreparedAdapterCall, type StreamChunk,\n} from '@deepseek-ai/dsh-llm';\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';\nimport { MODELS, type CatalogModel } from './catalog.js';\nimport { PLAN_PROVIDER, PAID_PROVIDER, type RuntimeConfig } from './config.js';\nimport { chatMessages, chatTools, estimateTokens } from './conversion.js';\nimport { gatewayError } from './stream.js';\nimport { combinedSignal } from './util.js';\nimport { EmptyTurnTracker } from './empty-turn.js';\nimport { applyModelSettings, isModelEnabled, type ModelSettings } from './model-settings.js';\nimport { protocolFor } from './protocols/index.js';\nimport type { ApiProtocol } from './protocol-options.js';\n\nexport interface AdapterOptions {\n config(): RuntimeConfig;\n models?(): readonly CatalogModel[];\n apiKey(ref: string): Promise<string | undefined>;\n imageDataUrl?(image: ImageAttachmentRef, signal: AbortSignal): Promise<string | undefined>;\n onEmptyTurn?(): void;\n fetch?: typeof fetch;\n}\nfunction group(provider: string): 'plan' | 'paid' {\n if (provider === PLAN_PROVIDER) return 'plan';\n if (provider === PAID_PROVIDER) return 'paid';\n throw new LlmError('\u672A\u77E5\u7684 CoRouter Provider', 'INVALID_REQUEST');\n}\nfunction outputReserve(model: CatalogModel, protocol: ApiProtocol): number | undefined {\n const limit = model.maxOutputTokens ?? (protocol === 'messages' ? 4096 : undefined);\n return limit === undefined ? undefined : model.contextWindow === undefined ? limit : Math.min(limit, Math.floor(model.contextWindow / 4));\n}\nfunction metadata(provider: string, row: CatalogModel, config: RuntimeConfig): LlmResolvedModelInfo {\n const setting = config.modelSettings?.[row.id];\n const reserve = setting?.maxTokens ?? outputReserve(row, config.apiProtocol ?? 'chat-completions');\n const efforts = row.reasoningEfforts ?? (setting?.reasoningEffort ? [setting.reasoningEffort] : undefined);\n return {\n provider, id: row.id, name: row.name,\n ...(row.inputModalities ? { inputModalities: row.inputModalities } : {}),\n ...(row.contextWindow === undefined ? {} : { context: { contextWindow: row.contextWindow - (reserve ?? 0) } }),\n ...(reserve === undefined ? {} : { defaultMaxTokens: reserve }),\n ...(efforts?.length ? { reasoning: {\n efforts: efforts.map(id => ({ id: ReasoningEffortId(id), name: ({ none: '\u5173\u95ED', minimal: '\u6700\u4F4E', low: '\u4F4E', medium: '\u4E2D', high: '\u9AD8', xhigh: '\u8F83\u9AD8', ultra: '\u6781\u9AD8', max: '\u6700\u9AD8' } as Record<string, string>)[id] ?? id })),\n ...(setting?.reasoningEffort ? { defaultEffort: ReasoningEffortId(setting.reasoningEffort) } : {}),\n } } : {}),\n };\n}\nexport class CoRouterAdapter extends LlmAdapter {\n readonly #lifetime = new AbortController();\n constructor(readonly options: AdapterOptions) { super(); }\n dispose(): void { this.#lifetime.abort(new LlmError('CoRouter \u63D2\u4EF6\u5DF2\u5378\u8F7D', 'ABORTED')); }\n override providerInfo(provider: string) {\n return { id: provider, name: group(provider) === 'plan' ? 'OpenDesign CoRouter \u00B7 \u5957\u9910\u8D60\u9001' : 'OpenDesign CoRouter \u00B7 \u4ED8\u8D39\u6A21\u578B' };\n }\n private modelOf(provider: string, id: string, config: RuntimeConfig): CatalogModel {\n const row = (this.options.models?.() ?? MODELS).find(candidate => candidate.id === id);\n if (!row || row.group !== group(provider)) throw new LlmError('\u8BE5\u6A21\u578B\u4E0D\u5C5E\u4E8E\u5F53\u524D CoRouter Provider\uFF1B\u8BF7\u5237\u65B0\u6A21\u578B\u5217\u8868\u5E76\u9009\u62E9\u5BF9\u5E94\u901A\u9053', 'INVALID_REQUEST');\n if (!isModelEnabled(id, config.modelSettings)) throw new LlmError('\u8BE5\u6A21\u578B\u5DF2\u5728 CoRouter \u8BBE\u7F6E\u4E2D\u505C\u7528', 'MODEL_DISABLED');\n const configured = applyModelSettings(row, config.modelSettings?.[id]);\n const output = config.modelSettings?.[id]?.maxTokens;\n if (output !== undefined && configured.contextWindow !== undefined && output >= configured.contextWindow) throw new LlmError('\u6A21\u578B\u6700\u5927\u8F93\u51FA\u5FC5\u987B\u5C0F\u4E8E\u4E0A\u4E0B\u6587\u9884\u7B97\uFF0C\u8BF7\u8C03\u6574\u6A21\u578B\u53C2\u6570', 'INVALID_REQUEST');\n return configured;\n }\n override async listModels(provider: string): Promise<readonly LlmModelInfo[]> {\n const config = this.options.config(), selectedGroup = group(provider);\n return (this.options.models?.() ?? MODELS).filter(row => row.group === selectedGroup && isModelEnabled(row.id, config.modelSettings))\n .map(row => ({ provider, id: row.id, name: row.name, ...(row.inputModalities ? { inputModalities: row.inputModalities } : {}) }));\n }\n override async resolveModel(provider: string, model: string, signal?: AbortSignal): Promise<LlmResolvedModelInfo> {\n signal?.throwIfAborted();\n const config = this.options.config();\n return metadata(provider, this.modelOf(provider, model, config), config);\n }\n override async prepareCall(provider: string, model: string, signal?: AbortSignal): Promise<PreparedAdapterCall> {\n signal?.throwIfAborted();\n const config = this.options.config(), row = this.modelOf(provider, model, config);\n return { model: metadata(provider, row, config), stream: options => this.#stream(options, config, row) };\n }\n override stream(options: GenerateOptions): AsyncIterable<StreamChunk> {\n const config = this.options.config();\n return this.#stream(options, config, this.modelOf(options.provider, options.model, config));\n }\n async *#stream(options: GenerateOptions, config: RuntimeConfig, row: CatalogModel): AsyncGenerator<StreamChunk> {\n const signal = AbortSignal.any([combinedSignal(options.signal, config.requestTimeoutMs), this.#lifetime.signal]);\n signal.throwIfAborted();\n const raw = await this.options.apiKey(config.apiKeyEnv);\n if (!raw) throw new LlmError('\u672A\u914D\u7F6E CoRouter API Key\uFF1B\u8BF7\u5728\u63D2\u4EF6\u8BBE\u7F6E\u4E2D\u4FDD\u5B58\u6216\u8BBE\u7F6E\u5BF9\u5E94\u73AF\u5883\u53D8\u91CF', 'MISSING_CREDENTIAL');\n const key = assertUsableApiKey(raw, 'dsh-opendesign-corouter', config.apiKeyEnv);\n const setting: ModelSettings = config.modelSettings?.[row.id] ?? {};\n const protocolId = config.apiProtocol ?? 'chat-completions';\n const images = new Map<string, string>();\n const attemptedImages = new Set<string>();\n const unreadableImages = new Set<string>();\n if (row.inputModalities?.includes('image') && this.options.imageDataUrl) for (const message of options.messages.filter(item => item.role === 'user' || item.role === 'tool')) for (const block of message.content) {\n if (block.type !== 'image' || block.offloaded || attemptedImages.has(block.attachment.attachmentId)) continue;\n attemptedImages.add(block.attachment.attachmentId);\n try {\n const url = await this.options.imageDataUrl(block.attachment, signal);\n signal.throwIfAborted();\n if (url) images.set(block.attachment.attachmentId, url);\n else unreadableImages.add(block.attachment.attachmentId);\n } catch {\n // A missing image becomes the named placeholder; cancellation must still stop the call.\n signal.throwIfAborted();\n unreadableImages.add(block.attachment.attachmentId);\n }\n }\n const projectedOptions: GenerateOptions = unreadableImages.size === 0 ? options : {\n ...options,\n messages: options.messages.map(message => message.role !== 'user' && message.role !== 'tool' ? message : {\n ...message,\n content: message.content.map(block => block.type === 'image' && !block.offloaded && unreadableImages.has(block.attachment.attachmentId)\n ? { type: 'text' as const, text: `[Image ${JSON.stringify(block.attachment.name ?? 'attachment')} could not be read; attachment ${block.attachment.attachmentId}. The model's image capability has not changed.]` }\n : block),\n }),\n };\n const messages = chatMessages(projectedOptions, ref => images.get(ref.attachmentId), row.id.startsWith('deepseek-') || row.id.startsWith('kimi-'));\n const tools = chatTools(options);\n let maxTokens = options.maxTokens ?? setting.maxTokens ?? outputReserve(row, protocolId);\n if (maxTokens !== undefined) {\n if (!Number.isSafeInteger(maxTokens) || maxTokens <= 0) throw new LlmError('maxTokens \u5FC5\u987B\u662F\u6B63\u6574\u6570', 'INVALID_REQUEST');\n const capped = Math.min(maxTokens, row.maxOutputTokens ?? maxTokens);\n const room = row.contextWindow === undefined ? capped : row.contextWindow - estimateTokens({ messages, tools });\n if (room < 1) throw new LlmError('\u5F53\u524D\u8F93\u5165\u6CA1\u6709\u4E3A\u8F93\u51FA\u7559\u4E0B\u4E0A\u4E0B\u6587\u7A7A\u95F4', 'CONTEXT_WINDOW_EXCEEDED');\n maxTokens = Math.min(capped, Math.floor(room));\n }\n const effort = options.reasoningEffort ?? (setting.reasoningEffort ? ReasoningEffortId(setting.reasoningEffort) : undefined);\n if (effort !== undefined && row.reasoningEfforts && !row.reasoningEfforts.includes(effort)) throw new LlmError('\u8BE5\u6A21\u578B\u4E0D\u652F\u6301\u6240\u9009\u601D\u8003\u6DF1\u5EA6', 'UNSUPPORTED_OPTION');\n const effective: GenerateOptions = {\n ...projectedOptions,\n ...((options.temperature ?? setting.temperature) === undefined ? {} : { temperature: options.temperature ?? setting.temperature }),\n ...(maxTokens === undefined ? {} : { maxTokens }),\n ...(effort === undefined ? {} : { reasoningEffort: effort }),\n };\n const protocol = protocolFor(protocolId);\n const request = protocol.build({ baseURL: config.baseURL, apiKey: key, model: row, options: effective, images, ...(setting.topP === undefined ? {} : { topP: setting.topP }) });\n let response: Response;\n try {\n response = await (this.options.fetch ?? fetch)(request.url, {\n method: 'POST', headers: request.headers, body: JSON.stringify(request.body), signal, redirect: 'error',\n });\n } catch {\n if (options.signal?.aborted || this.#lifetime.signal.aborted) signal.throwIfAborted();\n throw new LlmError(signal.aborted ? 'CoRouter \u8BF7\u6C42\u8D85\u8FC7\u603B\u8D85\u65F6' : '\u65E0\u6CD5\u8FDE\u63A5 CoRouter \u63A8\u7406\u670D\u52A1', signal.aborted ? 'TIMEOUT' : 'SERVER');\n }\n if (!response.ok) {\n let error: unknown = {};\n const reader = response.body?.getReader();\n if (reader) {\n let size = 0, raw = '';\n const decoder = new TextDecoder();\n try {\n while (true) {\n const chunk = await reader.read();\n if (chunk.done) break;\n size += chunk.value.byteLength;\n if (size > 65536) { raw = ''; break; }\n raw += decoder.decode(chunk.value, { stream: true });\n }\n if (raw) error = JSON.parse(raw + decoder.decode());\n } catch { /* Untrusted non-JSON errors are not projected. */ }\n finally { await reader.cancel().catch(() => undefined); reader.releaseLock(); }\n }\n throw gatewayError(response.status, error);\n }\n if (!response.body) throw new LlmError('CoRouter \u8FD4\u56DE\u7A7A\u54CD\u5E94', 'EMPTY_RESPONSE');\n const tracker = new EmptyTurnTracker({ enabled: row.group === 'plan' && config.emptyTurnGuard && Boolean(options.tools?.length), onEmptyTurn: () => this.options.onEmptyTurn?.() });\n try {\n for await (const chunk of protocol.stream(response.body, signal, config.streamIdleTimeoutMs)) {\n tracker.observe(chunk);\n if (chunk.type === 'finish' && row.group === 'plan' && config.emptyTurnGuard) yield { ...chunk, reason: tracker.resolve(chunk.reason) };\n else yield chunk;\n }\n } catch (error) {\n if (options.signal?.aborted || this.#lifetime.signal.aborted) signal.throwIfAborted();\n if (signal.aborted) throw new LlmError('CoRouter \u8BF7\u6C42\u8D85\u8FC7\u603B\u8D85\u65F6', 'TIMEOUT');\n if (error instanceof LlmError) throw error;\n throw new LlmError('CoRouter \u54CD\u5E94\u6D41\u8FDE\u63A5\u4E2D\u65AD', 'SERVER');\n }\n }\n}\n", "/**\n * CoRouter \u6A21\u578B\u76EE\u5F55\uFF08\u4EC5\u5BF9\u8BDD\u6A21\u578B\uFF0C\u4F9B llm \u9002\u914D\u5668\u7684\u6A21\u578B\u9009\u62E9\u5668\u4F7F\u7528\uFF09\u3002\n *\n * \u53D6\u8BC1\u6765\u6E90\uFF1A\n * - \u6A21\u578B ID / \u663E\u793A\u540D / \u4F9B\u5E94\u5546 / \u5355\u4EF7\uFF1A`https://corouter.open-design.ai/zh/models/<slug>/`\n * \u8BE6\u60C5\u9875\u5185\u8054 `data-model=\"{...}\"` JSON\uFF08\u516C\u5F00\u9875\u9762\uFF0C2026-10-26\uFF09\u3002\n * - group\uFF1A\u5B98\u7F51\u9996\u9875\u5957\u9910\u5361 `https://corouter.open-design.ai/zh/` \u7684\n * `data-model-module=\"design-plan\"` 12 \u6B3E\u5F52 `plan`\uFF1B\u5176\u4F59\u5728\u552E\u5BF9\u8BDD\u6A21\u578B\u5F52 `paid`\u3002\n * - `plan` 12 \u6B3E\u7684 contextWindow / maxOutputTokens / inputModalities / reasoningEfforts\n * \u6765\u81EA Go \u4FA7 `dsh-opendesign-go` 0.1.9 \u7684 MODEL_DEFAULTS\uFF08\u540C\u4E00 `amr-link` endpoint \u90E8\u7F72\u8D44\u6599\uFF09\uFF0C\n * \u7531\u7236\u4F1A\u8BDD\u79FB\u690D\uFF0C**\u672A\u7ECF\u5B98\u7F51\u72EC\u7ACB\u590D\u6838**\uFF1B\u53EA\u7528\u4E8E plan \u901A\u9053\u3002\n * - \u5BA2\u6237\u7AEF\u684C\u9762\u5B89\u88C5\uFF08Open Design 0.26.1\uFF09\u4E0D\u5185\u8054 CoRouter \u76EE\u5F55\uFF1B\u5176\n * `vela model preset --format json` \u53EA\u6709 11 \u4E2A\u65E7\u9884\u8BBE id\uFF08\u89C1 docs/client-evidence.md\uFF09\uFF0C\n * \u4E0E\u672C\u8868\u4E0D\u540C\u4EE3\uFF0C\u6545\u4E0D\u7528\u4E8E\u672C\u76EE\u5F55\u3002\n *\n * \u5206\u7EC4\u8BED\u4E49\uFF08\u91CD\u8981\uFF09\uFF1A`plan`/`paid` \u662F**\u672C\u63D2\u4EF6\u672C\u5730\u76EE\u5F55\u5206\u7C7B**\uFF0C\u7528\u4E8E\u628A\u201C\u5957\u9910\u8D60\u9001\u901A\u9053\u201D\u4E0E\n * \u201C\u5176\u4F59\u4ED8\u8D39\u901A\u9053\u201D\u62C6\u6210\u4E24\u4E2A Provider\uFF0C\u4E0D\u662F\u4E0A\u6E38\u5F3A\u5236\u8BA1\u8D39\u5951\u7EA6\u3002\u6700\u7EC8\u53EF\u7528\u6027\u3001\u6263\u54EA\u4E2A\u989D\u5EA6\u6C60\u3001\n * \u662F\u5426\u5148\u6263 Design Plan \u989D\u5EA6\u518D\u7528\u5957\u9910\u6A21\u578B/\u94B1\u5305\u989D\u5EA6\uFF0C\u5168\u90E8\u7531\u670D\u52A1\u7AEF\u6309\u8D26\u53F7\u5957\u9910\u51B3\u5B9A\u3002\n * `paid` 21 \u6B3E\u91CC\u53EA\u6709 8 \u6B3E\u51FA\u73B0\u5728\u5B98\u7F51\u5957\u9910\u53EF\u62B5\u6263\u540D\u5355\uFF0C\u5176\u4F59 13 \u6B3E\u540C\u6837\u53EF\u7ECF\u94B1\u5305/\u6309\u91CF\u4ED8\u8D39\u8C03\u7528\uFF0C\n * \u56E0\u6B64 `paid` \u6536\u5F55 21 \u6B3E\u800C\u4E0D\u662F 13 \u6B3E\u3002\n *\n * \u672A\u6536\u5F55\uFF08\u8BC1\u636E\u4E0D\u8DB3\uFF0C\u4E0D\u731C\u6D4B\uFF09\uFF1A\n * - \u5957\u9910\u6A21\u578B\u7EC4\u4E2D\u5C1A\u672A\u516C\u5F00\u7CBE\u786E ID \u7684 `Muse Spark 1.3`\u3001`Gemini 4 Argon`\uFF1A\n * \u524D\u8005\u8BE6\u60C5\u9875\u6CA1\u6709 `data-model`/\u6A21\u578B ID\uFF0C\u540E\u8005\u5728\u6A21\u578B\u76EE\u5F55\u91CC\u6CA1\u6709\u8BE6\u60C5\u9875\u3002\n * - \u5A92\u4F53\u6A21\u578B `GPT Image 2`\u3001`Nano Banana 2`\u3001`Seedream 5 Lite / Pro`\uFF1A\n * \u8D70 `/api/v1/media/*`\uFF0C\u4E0D\u5E94\u51FA\u73B0\u5728\u5BF9\u8BDD\u6A21\u578B\u5217\u8868\u91CC\uFF0C\u907F\u514D\u9009\u4E2D\u540E chat \u8BF7\u6C42\u5FC5\u8D25\u3002\n *\n * `paid` 21 \u6B3E\u7684\u80FD\u529B\u5B57\u6BB5\u4E00\u5F8B\u7F3A\u7701\uFF1A\u65E2\u6CA1\u6709\u5B98\u7F51\u6570\u503C\uFF0C\u4E5F\u6CA1\u6709\u53EF\u4FE1\u9ED8\u8BA4\u8868\uFF0C\n * \u4E0D\u6309\u540D\u79F0\u63A8\u65AD\u56FE\u50CF\u80FD\u529B\uFF0C\u4E5F\u4E0D\u7ED9\u672A\u77E5\u9879\u586B `['text']` \u8C0E\u79F0\u4E0D\u652F\u6301\u56FE\u50CF\u3002\n */\nexport interface CatalogModel {\n id: string;\n name: string;\n group: 'plan' | 'paid';\n contextWindow?: number;\n maxOutputTokens?: number;\n inputModalities?: readonly ('text' | 'image')[];\n reasoningEfforts?: readonly string[];\n}\n\nconst TEXT_ONLY = ['text'] as const;\nconst TEXT_AND_IMAGE = ['text', 'image'] as const;\n\n/** Go 0.1.9 MODEL_DEFAULTS \u91CC\u7684\u601D\u8003\u6863\u4F4D\u96C6\u5408\uFF08\u540C amr-link endpoint \u90E8\u7F72\u8D44\u6599\uFF09\u3002 */\nconst EFFORTS_FULL = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'ultra', 'max'] as const;\nconst EFFORTS_STD = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'] as const;\nconst EFFORTS_LOW_HIGH = ['low', 'high', 'max'] as const;\n\n/**\n * \u987A\u5E8F\u6309\u4F9B\u5E94\u5546\u5206\u7EC4\uFF08\u4E0E\u5B98\u7F51\u6A21\u578B\u76EE\u5F55\u5BFC\u822A\u4E00\u81F4\uFF09\uFF1B`plan` \u4E3A Design Plan \u989D\u5EA6\u8986\u76D6\u7684 12 \u6B3E\uFF0C\n * \u5176\u4F59 21 \u6B3E\u516C\u5F00\u5BF9\u8BDD\u6A21\u578B\u5F52 `paid`\u3002\n */\nexport const MODELS: readonly CatalogModel[] = [\n // \u2500\u2500 OpenAI\uFF087\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n { id: 'gpt-6.1-sol', name: 'GPT-6.1 Sol', group: 'paid' },\n { id: 'gpt-6-astra', name: 'GPT-6 Astra', group: 'paid' },\n {\n id: 'gpt-6-luna',\n name: 'GPT-6 Luna',\n group: 'plan',\n contextWindow: 1_050_000,\n maxOutputTokens: 128_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_FULL,\n },\n { id: 'gpt-6-sol', name: 'GPT-6 Sol', group: 'paid' },\n { id: 'gpt-5.6-luna', name: 'GPT-5.6 Luna', group: 'paid' },\n { id: 'gpt-5.6-sol', name: 'GPT-5.6 Sol', group: 'paid' },\n { id: 'gpt-5.6-terra', name: 'GPT-5.6 Terra', group: 'paid' },\n\n // \u2500\u2500 Anthropic\uFF088\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n { id: 'claude-fable-5.1', name: 'Claude Fable 5.1', group: 'paid' },\n { id: 'claude-fable-5', name: 'Claude Fable 5', group: 'paid' },\n { id: 'claude-opus-5.5', name: 'Claude Opus 5.5', group: 'paid' },\n { id: 'claude-opus-5', name: 'Claude Opus 5', group: 'paid' },\n { id: 'claude-opus-4.8', name: 'Claude Opus 4.8', group: 'paid' },\n { id: 'claude-sonnet-5.5', name: 'Claude Sonnet 5.5', group: 'paid' },\n { id: 'claude-sonnet-5', name: 'Claude Sonnet 5', group: 'paid' },\n {\n id: 'claude-haiku-5.5',\n name: 'Claude Haiku 5.5',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 128_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_STD,\n },\n\n // \u2500\u2500 DeepSeek\uFF084\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n {\n id: 'deepseek-v4.1-flash',\n name: 'DeepSeek V4.1 Flash',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 384_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_FULL,\n },\n {\n id: 'deepseek-v4-pro',\n name: 'DeepSeek V4 Pro',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 384_000,\n inputModalities: TEXT_ONLY,\n reasoningEfforts: EFFORTS_FULL,\n },\n {\n id: 'deepseek-v4-flash',\n name: 'DeepSeek V4 Flash',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 384_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_FULL,\n },\n {\n id: 'deepseek-v4-flash-vision-exp',\n name: 'DeepSeek V4 Flash Vision Exp',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 384_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_FULL,\n },\n\n // \u2500\u2500 Z.ai\uFF083\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n {\n id: 'glm-5.3-flashx',\n name: 'GLM-5.3 Flash-X',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 128_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_LOW_HIGH,\n },\n {\n id: 'glm-5.3-flash',\n name: 'GLM-5.3 Flash',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 128_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_LOW_HIGH,\n },\n { id: 'glm-5.2', name: 'GLM-5.2', group: 'paid' },\n\n // \u2500\u2500 Moonshot\uFF082\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n {\n id: 'kimi-k2.7-code',\n name: 'Kimi K2.7 Code',\n group: 'plan',\n contextWindow: 262_144,\n maxOutputTokens: 262_144,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_STD,\n },\n { id: 'kimi-k3', name: 'Kimi K3', group: 'paid' },\n\n // \u2500\u2500 Google\uFF082\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n { id: 'gemini-3.8-flash', name: 'Gemini 3.8 Flash', group: 'paid' },\n { id: 'gemini-3.7-flash', name: 'Gemini 3.7 Flash', group: 'paid' },\n\n // \u2500\u2500 xAI\uFF083\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n { id: 'grok-4.7', name: 'Grok 4.7', group: 'paid' },\n { id: 'grok-4.6', name: 'Grok 4.6', group: 'paid' },\n { id: 'grok-4.5', name: 'Grok 4.5', group: 'paid' },\n\n // \u2500\u2500 Xiaomi\uFF082\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n {\n id: 'mimo-v2.6-pro',\n name: 'MiMo V2.6 Pro',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 128_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_STD,\n },\n {\n id: 'mimo-v2.6-flash',\n name: 'MiMo V2.6 Flash',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 128_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_STD,\n },\n\n // \u2500\u2500 Tencent\uFF081\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n {\n id: 'hy4-preview',\n name: 'Hunyuan H4 Preview',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 64_000,\n inputModalities: TEXT_ONLY,\n reasoningEfforts: EFFORTS_STD,\n },\n\n // \u2500\u2500 Alibaba\uFF081\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n { id: 'qwen3.7-max', name: 'Qwen3.7 Max', group: 'paid' },\n];\n\nconst BY_ID = new Map(MODELS.map(model => [model.id, model] as const));\n\nexport function modelsFor(group: 'plan' | 'paid'): readonly CatalogModel[] {\n return MODELS.filter(model => model.group === group);\n}\n\nexport function findModel(id: string): CatalogModel | undefined {\n return BY_ID.get(id);\n}\n", "import Schema from '@deepseek-ai/schemastery';\nimport { API_PROTOCOL_IDS, type ApiProtocol } from './protocol-options.js';\nimport { parseModelSettingsMap, type ModelSettingsMap } from './model-settings.js';\nexport const SETTINGS_NS = 'llm-opendesign-corouter';\nexport const PLAN_PROVIDER = 'opendesign-corouter-plan';\nexport const PAID_PROVIDER = 'opendesign-corouter-paid';\nexport const DEFAULT_BASE_URL = 'https://amr-link.open-design.ai/v1';\nexport const Config = Schema.object({\n apiKeyEnv: Schema.string().pattern(/^[A-Za-z_][A-Za-z0-9_]*$/u).default('COROUTER_API_KEY').description('CoRouter API Key \u7684\u73AF\u5883\u53D8\u91CF\u6216 DSH \u51ED\u636E\u5F15\u7528\u540D').volatile(),\n baseURL: Schema.transform(Schema.string(), value => assertBaseURL(value)).default(DEFAULT_BASE_URL).description('CoRouter \u7F51\u5173\u5730\u5740\uFF1B\u4E0D\u7528\u4E8E\u63A7\u5236\u53F0\u767B\u5F55\u6216\u989D\u5EA6\u67E5\u8BE2').volatile(),\n apiProtocol: Schema.union(API_PROTOCOL_IDS).default('chat-completions').description('\u63A8\u7406 API \u534F\u8BAE\uFF1B\u6A21\u578B\u53D1\u73B0\u59CB\u7EC8\u4F7F\u7528 OpenAI models \u63A5\u53E3').volatile(),\n modelSettings: Schema.transform(Schema.dict(Schema.any<unknown>()), value => parseModelSettingsMap(value)).default({}).description('\u9010\u6A21\u578B\u542F\u7528\u72B6\u6001\u548C\u8BF7\u6C42\u53C2\u6570').volatile(),\n useDesktopCredential: Schema.boolean().default(true).description('\u4F18\u5148\u8BFB\u53D6 OpenDesign \u684C\u9762\u7AEF\u767B\u5F55\u6001\u67E5\u8BE2\u989D\u5EA6').volatile(),\n emptyTurnGuard: Schema.boolean().default(true).description('\u76D1\u63A7\u5957\u9910\u8D60\u9001\u6A21\u578B\u7684\u7A7A\u8F6E/\u534F\u8BAE\u6B8B\u6E23\uFF1B\u7531\u5BBF\u4E3B\u91CD\u8BD5\u7B56\u7565\u5904\u7406\uFF0C\u53EF\u80FD\u989D\u5916\u6D88\u8017\u8D60\u9001\u989D\u5EA6').volatile(),\n quotaRefreshSeconds: Schema.natural().min(5).max(3600).default(60).description('\u989D\u5EA6\u81EA\u52A8\u5237\u65B0\u95F4\u9694\uFF08\u79D2\uFF09').volatile(),\n requestTimeoutMs: Schema.natural().min(1000).max(3600000).default(1800000).description('\u63A8\u7406\u8BF7\u6C42\u603B\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09').volatile(),\n streamIdleTimeoutMs: Schema.natural().min(1000).max(1800000).default(300000).description('\u6D41\u5F0F\u54CD\u5E94\u65E0\u6570\u636E\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09').volatile(),\n});\nexport type LiveConfig = ReturnType<typeof Config>;\nexport interface RuntimeConfig {\n apiKeyEnv: string; baseURL: string; useDesktopCredential: boolean; emptyTurnGuard: boolean; requestTimeoutMs: number; streamIdleTimeoutMs: number;\n apiProtocol?: ApiProtocol;\n modelSettings?: ModelSettingsMap;\n quotaRefreshSeconds?: number;\n}\nexport function assertBaseURL(raw: string): string {\n let url: URL;\n try { url = new URL(raw); } catch { throw new Error('\u63A8\u7406 Base URL \u5FC5\u987B\u662F\u7EDD\u5BF9 URL'); }\n if (!['https:', 'http:'].includes(url.protocol) || url.username || url.password || url.search || url.hash) throw new Error('\u63A8\u7406 Base URL \u4E0D\u53EF\u5305\u542B\u51ED\u636E\u3001\u67E5\u8BE2\u4E32\u6216\u7247\u6BB5');\n if (url.protocol === 'http:' && !['localhost', '127.0.0.1', '[::1]'].includes(url.hostname)) throw new Error('\u975E\u672C\u673A\u63A8\u7406\u5730\u5740\u5FC5\u987B\u4F7F\u7528 HTTPS');\n return url.href.replace(/\\/+$/u, '');\n}\nexport function readConfig(config: LiveConfig): RuntimeConfig {\n return {\n apiKeyEnv: config.apiKeyEnv.get(), baseURL: assertBaseURL(config.baseURL.get()),\n apiProtocol: config.apiProtocol.get(), modelSettings: parseModelSettingsMap(config.modelSettings.get()),\n quotaRefreshSeconds: config.quotaRefreshSeconds.get(),\n useDesktopCredential: config.useDesktopCredential.get(), emptyTurnGuard: config.emptyTurnGuard.get(),\n requestTimeoutMs: config.requestTimeoutMs.get(), streamIdleTimeoutMs: config.streamIdleTimeoutMs.get(),\n };\n}\n", "export const API_PROTOCOL_IDS = ['chat-completions', 'responses', 'messages'] as const;\nexport type ApiProtocol = typeof API_PROTOCOL_IDS[number];\n\n/** The public gateway origin and an explicit versioned API base are both accepted. */\nexport function openAiBaseURL(baseURL: string): string {\n const base = baseURL.replace(/\\/+$/u, '');\n return new URL(base).pathname === '/' ? `${base}/v1` : base;\n}\n\n/** Shared by request builders and the settings preview so their paths cannot diverge. */\nexport function inferenceEndpoint(baseURL: string, protocol: ApiProtocol): string {\n const suffix = protocol === 'responses' ? '/responses' : protocol === 'messages' ? '/messages' : '/chat/completions';\n return baseURL.trim() === '' ? suffix : `${openAiBaseURL(baseURL.trim())}${suffix}`;\n}\n\nexport const API_PROTOCOL_OPTIONS: readonly { id: ApiProtocol; name: string; description: string }[] = [\n { id: 'chat-completions', name: 'OpenAI Chat Completions', description: '\u4F7F\u7528 Chat Completions \u8BF7\u6C42\u4E0E\u6D41\u5F0F\u54CD\u5E94\u3002' },\n { id: 'responses', name: 'OpenAI Responses', description: '\u4F7F\u7528 Responses \u8BF7\u6C42\u4E0E\u6D41\u5F0F\u54CD\u5E94\u3002' },\n { id: 'messages', name: 'Anthropic Messages', description: '\u4F7F\u7528 Messages \u8BF7\u6C42\u4E0E\u6D41\u5F0F\u54CD\u5E94\u3002' },\n];\n", "export function record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\nexport function finite(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\nexport function positive(value: unknown): number | undefined {\n const n = finite(value);\n return n !== undefined && n > 0 ? n : undefined;\n}\nexport function safeSecret(raw: string): string {\n const value = raw.trim();\n if (!value || /[^\\x20-\\x7e]/u.test(value)) throw new Error('\u51ED\u636E\u4E3A\u7A7A\u6216\u542B\u6709\u4E0D\u53EF\u7528\u4E8E HTTP \u8BF7\u6C42\u5934\u7684\u5B57\u7B26');\n return value;\n}\nexport function combinedSignal(signal: AbortSignal | undefined, timeoutMs: number): AbortSignal {\n const deadline = AbortSignal.timeout(timeoutMs);\n return signal ? AbortSignal.any([signal, deadline]) : deadline;\n}\nexport function sleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise(resolve => {\n if (signal.aborted) return resolve();\n const done = () => { clearTimeout(timer); signal.removeEventListener('abort', done); resolve(); };\n const timer = setTimeout(done, ms);\n signal.addEventListener('abort', done, { once: true });\n });\n}\n", "/**\n * \u9010\u6A21\u578B\u8BBE\u7F6E\uFF1A\u7528\u6237\u5728\u76EE\u5F55\u884C\u4E4B\u4E0A\u663E\u5F0F\u8986\u76D6\u7684\u53D1\u9001\u53C2\u6570\u4E0E\u5BB9\u91CF\u3002\n *\n * \u72EC\u7ACB\u4E8E\u6A21\u578B\u53D1\u73B0\u4E0E\u63A8\u7406\u534F\u8BAE\uFF1A\u8FD9\u91CC\u53EA\u505A\u5F62\u72B6\u6821\u9A8C\u4E0E\u526F\u672C\u5408\u6210\uFF0C\u4E0D\u8BFB\u51ED\u636E\u3001\u4E0D\u8054\u7F51\u3001\n * \u4E5F\u4E0D\u5224\u65AD\u67D0\u4E2A\u63A8\u7406\u534F\u8BAE\u662F\u5426\u652F\u6301\u8FD9\u4E9B\u5B57\u6BB5\uFF08\u517C\u5BB9\u6027\u7531\u9002\u914D\u5668\u5728\u7EC4\u88C5\u8BF7\u6C42\u65F6\u51B3\u5B9A\uFF09\u3002\n *\n * \u5B89\u5168\u7EA6\u5B9A\uFF1A\n * - \u91C7\u7528\u5B57\u6BB5\u767D\u540D\u5355\uFF0C\u4EFB\u4F55\u672A\u77E5\u5B57\u6BB5\u4E00\u5F8B\u62D2\u7EDD\uFF0C\u907F\u514D `apiKey`/`headers` \u4E4B\u7C7B\u79D8\u5BC6\u6216\n * \u4E0D\u53EF\u5E8F\u5217\u5316\u503C\u501F\u9053\u8BBE\u7F6E\u5BF9\u8C61\u8FDB\u5165\u6301\u4E45\u5316\u3002\n * - \u62D2\u7EDD `__proto__` / `constructor` / `prototype` \u4F5C\u4E3A\u6A21\u578B ID\uFF0C\u9632\u539F\u578B\u6C61\u67D3\u3002\n * - \u53EA\u8FD4\u56DE\u65B0\u5BF9\u8C61\uFF1A\u4E0D\u628A\u5916\u90E8\u5F15\u7528\uFF08\u6570\u7EC4\u3001\u5D4C\u5957\u5BF9\u8C61\u3001\u76EE\u5F55\u884C\uFF09\u4EA4\u7ED9\u8C03\u7528\u65B9\uFF0C\u4E5F\u4E0D\u6539\u5165\u53C2\u3002\n * - \u9519\u8BEF\u6587\u5B57\u56FA\u5B9A\uFF0C\u4E0D\u56DE\u663E\u8BBE\u7F6E\u503C\u6216\u6A21\u578B ID\u3002\n */\n\nimport type { CatalogModel } from './catalog.js';\nimport { record } from './util.js';\n\n/** One model's optional overrides; every field absent means \"inherit the catalog row\". */\nexport interface ModelSettings {\n /** \u662F\u5426\u51FA\u73B0\u5728\u6A21\u578B\u9009\u62E9\u5668\uFF1B\u7F3A\u7701\u89C6\u4E3A\u542F\u7528\u3002 */\n enabled?: boolean;\n /** \u91C7\u6837\u6E29\u5EA6\uFF0C0\u20132\u3002 */\n temperature?: number;\n /** \u6838\u91C7\u6837\uFF0C0\u20131\u3002 */\n topP?: number;\n /** \u5355\u6B21\u8F93\u51FA\u4E0A\u9650\uFF1B\u8986\u76D6\u76EE\u5F55\u884C\u7684 maxOutputTokens\u3002 */\n maxTokens?: number;\n /** \u4E0A\u4E0B\u6587\u7A97\u53E3\uFF1B\u8986\u76D6\u76EE\u5F55\u884C\u7684 contextWindow\u3002 */\n contextWindow?: number;\n /** \u601D\u8003\u6DF1\u5EA6\uFF1B\u53EA\u5141\u8BB8\u76EE\u5F55\u540C\u4E00\u5957\u6863\u4F4D\u3002 */\n reasoningEffort?: string;\n}\n\n/** Model id \u2192 settings. Keys are model ids, never provider-scoped. */\nexport type ModelSettingsMap = Record<string, ModelSettings>;\n\n/** \u4E0A\u9650\u4E0E\u76EE\u5F55\u3001\u8FDC\u7A0B\u8BBE\u7F6E\u89C6\u56FE\u4FDD\u6301\u540C\u4E00\u91CF\u7EA7\u3002 */\nconst MAX_ENTRIES = 512;\nconst MAX_MODEL_ID_LENGTH = 128;\n/** \u5141\u8BB8\u5B57\u6BCD\u3001\u6570\u5B57\u4E0E `.` `_` `:` `/` `-`\uFF1B\u4E0D\u542B\u7A7A\u767D\u3001\u5F15\u53F7\u4E0E\u8DEF\u5F84\u7A7F\u8D8A\u7B26\u3002 */\nconst MODEL_ID = /^[A-Za-z0-9._:/-]{1,128}$/u;\nconst MAX_TEMPERATURE = 2;\nconst MAX_TOP_P = 1;\nconst MAX_TOKENS = 10_000_000;\nconst MAX_CONTEXT_WINDOW = 100_000_000;\n/** \u4E0E catalog.ts \u7684 EFFORTS_* \u540C\u4E00\u6863\u4F4D\u96C6\u5408\u3002 */\nconst REASONING_EFFORTS: readonly string[] = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'ultra', 'max'];\n/** Never accepted as a model id: they would reach `Object.prototype` through a plain copy. */\nconst RESERVED_KEYS: ReadonlySet<string> = new Set(['__proto__', 'constructor', 'prototype']);\n/** The only fields a settings object may carry; anything else is a smuggling attempt. */\nconst SETTINGS_FIELDS: ReadonlySet<string> = new Set(['enabled', 'temperature', 'topP', 'maxTokens', 'contextWindow', 'reasoningEffort']);\n\nfunction flag(value: unknown): boolean {\n if (typeof value !== 'boolean') throw new Error('\u6A21\u578B\u8BBE\u7F6E\u7684 enabled \u5FC5\u987B\u662F\u5E03\u5C14\u503C');\n return value;\n}\n\nfunction bounded(value: unknown, max: number, label: 'temperature' | 'topP'): number {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 0 || value > max) throw new Error(`\u6A21\u578B\u8BBE\u7F6E\u7684 ${label} \u5FC5\u987B\u662F 0 \u5230 ${max} \u4E4B\u95F4\u7684\u6709\u9650\u6570\u5B57`);\n return value;\n}\n\nfunction capacity(value: unknown, max: number, label: 'maxTokens' | 'contextWindow'): number {\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 1 || value > max) throw new Error(`\u6A21\u578B\u8BBE\u7F6E\u7684 ${label} \u5FC5\u987B\u662F 1 \u5230 ${max} \u4E4B\u95F4\u7684\u6574\u6570`);\n return value;\n}\n\nfunction effort(value: unknown): string {\n const hit = REASONING_EFFORTS.find(candidate => candidate === value);\n if (hit === undefined) throw new Error('\u6A21\u578B\u8BBE\u7F6E\u7684 reasoningEffort \u4E0D\u5728\u5141\u8BB8\u7684\u53D6\u503C\u5185');\n return hit;\n}\n\n/** Rebuild one entry from the allowlist; unknown fields and secrets never survive. */\nfunction settingsOf(value: unknown): ModelSettings {\n if (!record(value)) throw new Error('\u6BCF\u4E2A\u6A21\u578B\u7684\u8BBE\u7F6E\u5FC5\u987B\u662F\u5BF9\u8C61');\n for (const field of Object.keys(value)) {\n if (!SETTINGS_FIELDS.has(field)) throw new Error('\u6A21\u578B\u8BBE\u7F6E\u542B\u6709\u4E0D\u652F\u6301\u7684\u5B57\u6BB5');\n }\n const out: ModelSettings = {};\n if (value.enabled !== undefined) out.enabled = flag(value.enabled);\n if (value.temperature !== undefined) out.temperature = bounded(value.temperature, MAX_TEMPERATURE, 'temperature');\n if (value.topP !== undefined) out.topP = bounded(value.topP, MAX_TOP_P, 'topP');\n if (value.maxTokens !== undefined) out.maxTokens = capacity(value.maxTokens, MAX_TOKENS, 'maxTokens');\n if (value.contextWindow !== undefined) out.contextWindow = capacity(value.contextWindow, MAX_CONTEXT_WINDOW, 'contextWindow');\n if (value.reasoningEffort !== undefined) out.reasoningEffort = effort(value.reasoningEffort);\n return out;\n}\n\n/**\n * Validate an untrusted settings payload (settings store, credential-free Host state)\n * into a fresh map. Rejects non-objects, oversized maps, reserved/unsafe ids, unknown\n * fields and out-of-range values; never returns the input's objects or arrays.\n */\nexport function parseModelSettingsMap(value: unknown): ModelSettingsMap {\n if (!record(value)) throw new Error('\u6A21\u578B\u8BBE\u7F6E\u5FC5\u987B\u662F\u5BF9\u8C61');\n const keys = Object.keys(value);\n if (keys.length > MAX_ENTRIES) throw new Error(`\u6A21\u578B\u8BBE\u7F6E\u6700\u591A\u5141\u8BB8 ${MAX_ENTRIES} \u4E2A\u6A21\u578B`);\n const out: ModelSettingsMap = {};\n for (const id of keys) {\n if (RESERVED_KEYS.has(id)) throw new Error('\u6A21\u578B\u8BBE\u7F6E\u4E0D\u5141\u8BB8\u4FDD\u7559\u5B57\u6BB5\u540D');\n if (!MODEL_ID.test(id)) throw new Error(`\u6A21\u578B ID \u5FC5\u987B\u662F 1\u2013${MAX_MODEL_ID_LENGTH} \u4F4D\u5B57\u6BCD\u3001\u6570\u5B57\u6216 . _ : / -`);\n out[id] = settingsOf(value[id]);\n }\n return out;\n}\n\n/**\n * Copy a catalog row and apply the user's explicit capacity overrides. The input row and\n * its arrays are never mutated; other overrides (sampling, effort) belong to the request,\n * not to the catalog row, so they are not folded in here.\n */\nexport function applyModelSettings(row: CatalogModel, settings?: ModelSettings): CatalogModel {\n const { contextWindow, maxTokens } = settings ?? {};\n if (contextWindow === undefined && maxTokens === undefined) return { ...row };\n return {\n ...row,\n ...(contextWindow === undefined ? {} : { contextWindow: capacity(contextWindow, MAX_CONTEXT_WINDOW, 'contextWindow') }),\n ...(maxTokens === undefined ? {} : { maxOutputTokens: capacity(maxTokens, MAX_TOKENS, 'maxTokens') }),\n };\n}\n\n/** A model is selectable unless the map explicitly disables it; unknown ids and an absent map stay enabled. */\nexport function isModelEnabled(id: string, settings: ModelSettingsMap = {}): boolean {\n if (RESERVED_KEYS.has(id) || !Object.hasOwn(settings, id)) return true;\n return settings[id]?.enabled !== false;\n}\n", "// Adapted from dsh-opendesign-go message/image compatibility handling (MIT).\nimport { LlmError, textOnlyImageText, type ContentBlock, type GenerateOptions } from '@deepseek-ai/dsh-llm';\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';\n\nexport type ImageResolver = (ref: ImageAttachmentRef) => string | undefined;\ntype Part = { type: 'text'; text: string } | { type: 'image_url'; image_url: { url: string } };\nexport interface WireMessage {\n role: 'system' | 'user' | 'assistant' | 'tool';\n content: string | Part[];\n tool_call_id?: string;\n tool_calls?: { id: string; type: 'function'; function: { name: string; arguments: string } }[];\n reasoning_content?: string;\n}\nfunction parts(blocks: readonly ContentBlock[], image?: ImageResolver): { text: string; images: string[] } {\n let text = '';\n const images: string[] = [];\n for (const block of blocks) {\n switch (block.type) {\n case 'text': text += block.text; break;\n case 'image': {\n const url = block.offloaded ? undefined : image?.(block.attachment);\n if (url) images.push(url);\n else text += `${text ? '\\n' : ''}${textOnlyImageText(block.attachment)}`;\n break;\n }\n case 'file': throw new LlmError('\u539F\u59CB\u6587\u4EF6\u672A\u88AB\u5BBF\u4E3B\u6295\u5F71\u4E3A\u6587\u672C\u53E5\u67C4', 'UNSUPPORTED_OPTION');\n // Tool definitions are already materialized in options.tools by Core.\n default: break;\n }\n }\n return { text, images };\n}\nfunction content(text: string, images: string[]): string | Part[] {\n return images.length ? [...(text ? [{ type: 'text' as const, text }] : []), ...images.map(url => ({ type: 'image_url' as const, image_url: { url } }))] : text;\n}\nexport function chatMessages(options: GenerateOptions, image?: ImageResolver, replayReasoning = false): WireMessage[] {\n const out: WireMessage[] = [];\n let lifted: string[] = [];\n function flush() {\n if (!lifted.length) return;\n out.push({ role: 'user', content: content('(Image content from the preceding tool result.)', lifted) });\n lifted = [];\n }\n for (const message of options.messages) {\n if (message.role !== 'tool') flush();\n const parsed = parts(message.content, message.role === 'user' || message.role === 'tool' ? image : undefined);\n switch (message.role) {\n case 'system': case 'developer':\n if (parsed.text) out.push({ role: 'system', content: parsed.text });\n break;\n case 'user':\n if (parsed.text || parsed.images.length) out.push({ role: 'user', content: content(parsed.text, parsed.images) });\n break;\n case 'assistant': {\n const calls = message.content.filter(block => block.type === 'tool-call').map(block => ({ id: block.id, type: 'function' as const, function: { name: block.name, arguments: block.arguments } }));\n const reasoning = message.content.filter(block => block.type === 'reasoning').map(block => block.text).join('');\n if (parsed.text || calls.length || parsed.images.length) out.push({ role: 'assistant', content: content(parsed.text, parsed.images), ...(calls.length ? { tool_calls: calls } : {}), ...(replayReasoning && reasoning ? { reasoning_content: reasoning } : {}) });\n break;\n }\n case 'tool':\n out.push({ role: 'tool', tool_call_id: message.toolCallId, content: parsed.text || (parsed.images.length ? '(Image content follows in the next user message.)' : '') });\n lifted.push(...parsed.images);\n break;\n }\n }\n flush();\n if (options.system?.trim()) {\n const first = out[0];\n if (first?.role === 'system' && typeof first.content === 'string') first.content = `${options.system}\\n\\n${first.content}`;\n else out.unshift({ role: 'system', content: options.system });\n }\n return out;\n}\nexport function chatTools(options: GenerateOptions) {\n return options.tools?.length ? options.tools.map(tool => ({ type: 'function' as const, function: { name: tool.name, description: tool.description, parameters: tool.parameters } })) : undefined;\n}\nexport function estimateTokens(value: unknown): number {\n let ascii = 0, wide = 0, images = 0;\n function walk(x: unknown): void {\n if (typeof x === 'string') { for (const c of x) { if ((c.codePointAt(0) ?? 0) < 128) ascii++; else wide++; } }\n else if (Array.isArray(x)) for (const item of x) walk(item);\n else if (x && typeof x === 'object') {\n if ('type' in x && x.type === 'image_url') { images++; return; }\n for (const item of Object.values(x)) walk(item);\n }\n }\n walk(value);\n return Math.ceil(ascii / 3.5 + wide / 2) + images * 1024;\n}\n", "/**\n * Chat Completions \u7684\u6D41\u5F0F\u6295\u5F71\u4E0E\u5171\u4EAB\u9519\u8BEF\u5206\u7C7B\u3002\n *\n * \u5206\u5E27\u5DF2\u62BD\u5230 `protocols/sse.ts`\uFF08\u4E09\u79CD\u534F\u8BAE\u5171\u7528\u540C\u4E00\u5957\u53D6\u6D88/\u7A7A\u95F2/\u5927\u5C0F\u8FB9\u754C\uFF09\uFF0C\u8FD9\u91CC\u53EA\u4FDD\u7559\n * Chat Completions \u7684\u4E8B\u4EF6\u8BED\u4E49\uFF1B`gatewayError` \u4E5F\u4ECE `protocols/errors.ts` \u7EDF\u4E00\u63D0\u4F9B\uFF0C\n * \u4EE5\u4FDD\u6301\u65E2\u6709 `import { gatewayError } from './stream.js'` \u7684\u8C03\u7528\u70B9\u4E0D\u53D8\u3002\n */\n\nimport { LlmError, ToolCallId, type StreamChunk, type TokenUsage, type FinishReason } from '@deepseek-ai/dsh-llm';\nimport { record, finite } from './util.js';\nimport { gatewayError } from './protocols/errors.js';\nimport { sseFrames } from './protocols/sse.js';\n\nexport { gatewayError } from './protocols/errors.js';\n\n/** Chat Completions \u7684 `usage` \u6298\u7B97\uFF08`prompt_tokens` \u542B\u7F13\u5B58\uFF0C\u6309\u4E0D\u76F8\u4EA4\u53E3\u5F84\u51CF\u51FA\uFF09\u3002 */\nexport function tokenUsage(value: Record<string, unknown>): TokenUsage | undefined {\n const prompt = finite(value.prompt_tokens), output = finite(value.completion_tokens);\n if (prompt === undefined || output === undefined || prompt < 0 || output < 0) return;\n const pd = record(value.prompt_tokens_details) ? value.prompt_tokens_details : {};\n const cd = record(value.completion_tokens_details) ? value.completion_tokens_details : {};\n const read = finite(pd.cached_tokens) ?? finite(value.prompt_cache_hit_tokens) ?? 0;\n const write = finite(pd.cache_write_tokens) ?? finite(value.prompt_cache_write_tokens) ?? finite(value.cache_creation_input_tokens) ?? 0;\n // Invalid cache counters cannot become negative or invent input usage.\n const validCache = read >= 0 && write >= 0 && read + write <= prompt;\n const reasoning = finite(cd.reasoning_tokens);\n return {\n inputTokens: validCache ? prompt - read - write : prompt,\n outputTokens: output, totalTokens: prompt + output,\n ...(validCache && read > 0 ? { cacheReadTokens: read } : {}),\n ...(validCache && write > 0 ? { cacheWriteTokens: write } : {}),\n ...(reasoning !== undefined && reasoning >= 0 && reasoning <= output ? { reasoningTokens: reasoning } : {}),\n };\n}\n\ninterface OpenText { index: number; text: string }\ninterface OpenTool { index: number; id: string; name: string; arguments: string; started: boolean }\n\n/** Bounded SSE projection for Chat Completions; a broken/truncated response is never reported as success. */\nexport async function* consumeSse(body: ReadableStream<Uint8Array>, signal: AbortSignal, idleMs: number): AsyncGenerator<StreamChunk> {\n let nextIndex = 0, count = 0, sawTool = false, done = false;\n let text: OpenText | undefined, reasoning: OpenText | undefined;\n const tools = new Map<number, OpenTool>();\n let finish: FinishReason | undefined, usage: TokenUsage | undefined;\n function close(): StreamChunk[] {\n const out: StreamChunk[] = [];\n if (text) out.push({ type: 'block-end', index: text.index, block: { type: 'text', text: text.text } });\n if (reasoning) out.push({ type: 'block-end', index: reasoning.index, block: { type: 'reasoning', text: reasoning.text } });\n for (const call of tools.values()) {\n if (!call.id || !call.name) throw new LlmError('OpenDesign\uFF1A\u5DE5\u5177\u8C03\u7528\u7F3A\u5C11\u6807\u8BC6\u6216\u540D\u79F0', 'INVALID_RESPONSE');\n out.push({ type: 'block-end', index: call.index, block: { type: 'tool-call', id: ToolCallId(call.id), name: call.name, arguments: call.arguments } });\n }\n text = reasoning = undefined; tools.clear();\n return out.sort((a, b) => ('index' in a ? a.index : 0) - ('index' in b ? b.index : 0));\n }\n function event(payload: string): StreamChunk[] {\n if (!payload) return [];\n if (payload.trim() === '[DONE]') { done = true; return []; }\n let value: unknown;\n try { value = JSON.parse(payload); } catch { throw new LlmError('OpenDesign\uFF1A\u65E0\u6548\u7684\u6D41\u5F0F JSON', 'INVALID_RESPONSE'); }\n if (!record(value)) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u4E8B\u4EF6\u4E0D\u662F\u5BF9\u8C61', 'INVALID_RESPONSE');\n if (record(value.error)) throw gatewayError(undefined, value);\n if (record(value.usage)) usage = tokenUsage(value.usage) ?? usage;\n if (!Array.isArray(value.choices) || !value.choices.length) return [];\n const choice = value.choices[0];\n if (!record(choice)) throw new LlmError('OpenDesign\uFF1A\u65E0\u6548\u7684\u6D41\u5F0F\u9009\u9879', 'INVALID_RESPONSE');\n const delta = record(choice.delta) ? choice.delta : {};\n const out: StreamChunk[] = [];\n const hasDelta = typeof delta.content === 'string' && delta.content !== '' || typeof delta.reasoning_content === 'string' && delta.reasoning_content !== '' || Array.isArray(delta.tool_calls) && delta.tool_calls.length > 0;\n if (finish && hasDelta) throw new LlmError('OpenDesign\uFF1A\u54CD\u5E94\u7ED3\u675F\u540E\u4ECD\u6536\u5230\u5185\u5BB9', 'INVALID_RESPONSE');\n const thinking = typeof delta.reasoning_content === 'string' ? delta.reasoning_content : typeof delta.reasoning === 'string' ? delta.reasoning : '';\n if (thinking) {\n if (!reasoning) { reasoning = { index: nextIndex++, text: '' }; count++; out.push({ type: 'block-start', index: reasoning.index, blockType: 'reasoning' }); }\n reasoning.text += thinking;\n out.push({ type: 'reasoning-delta', index: reasoning.index, text: thinking });\n }\n if (typeof delta.content === 'string' && delta.content) {\n if (!text) { text = { index: nextIndex++, text: '' }; count++; out.push({ type: 'block-start', index: text.index, blockType: 'text' }); }\n text.text += delta.content;\n out.push({ type: 'text-delta', index: text.index, text: delta.content });\n }\n if (Array.isArray(delta.tool_calls)) for (const item of delta.tool_calls) {\n if (!record(item) || typeof item.index !== 'number' || !Number.isInteger(item.index) || item.index < 0) throw new LlmError('OpenDesign\uFF1A\u65E0\u6548\u7684\u5DE5\u5177\u8C03\u7528\u7D22\u5F15', 'INVALID_RESPONSE');\n let call = tools.get(item.index);\n if (!call) { call = { index: nextIndex++, id: '', name: '', arguments: '', started: false }; tools.set(item.index, call); count++; sawTool = true; }\n const fn = record(item.function) ? item.function : {};\n if (typeof item.id === 'string' && item.id) {\n if (call.id && call.id !== item.id) throw new LlmError('OpenDesign\uFF1A\u5DE5\u5177\u8C03\u7528\u6807\u8BC6\u53D1\u751F\u53D8\u5316', 'INVALID_RESPONSE');\n call.id = item.id;\n }\n if (typeof fn.name === 'string' && fn.name) call.name = fn.name; // gateway may repeat the complete name; only arguments are deltas\n if (typeof fn.arguments === 'string') call.arguments += fn.arguments;\n // A few gateways deliver the id after the first argument fragment.\n if (call.id) {\n const first = !call.started;\n if (first) { out.push({ type: 'block-start', index: call.index, blockType: 'tool-call' }); call.started = true; }\n out.push({ type: 'tool-call-delta', index: call.index, id: ToolCallId(call.id), ...(call.name ? { name: call.name } : {}), argumentsDelta: first ? call.arguments : typeof fn.arguments === 'string' ? fn.arguments : '' });\n }\n }\n if (typeof choice.finish_reason === 'string' && choice.finish_reason) {\n if (finish) throw new LlmError('OpenDesign\uFF1A\u91CD\u590D\u7684\u54CD\u5E94\u7EC8\u6B62\u4E8B\u4EF6', 'INVALID_RESPONSE');\n switch (choice.finish_reason) {\n case 'length': finish = { kind: 'max-tokens' }; break;\n case 'tool_calls': case 'function_call': finish = { kind: 'tool-calls' }; break;\n case 'stop': finish = { kind: 'stop' }; break;\n default: throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u54CD\u5E94\u88AB\u8FC7\u6EE4\u6216\u5F02\u5E38\u7EC8\u6B62', 'INVALID_RESPONSE');\n }\n out.push(...close());\n }\n return out;\n }\n\n for await (const frame of sseFrames(body, signal, idleMs)) {\n for (const chunk of event(frame.data)) yield chunk;\n if (done) break;\n }\n\n signal.throwIfAborted();\n if (!finish) throw new LlmError('OpenDesign\uFF1A\u54CD\u5E94\u6D41\u63D0\u524D\u4E2D\u65AD\uFF0C\u672A\u6536\u5230\u7ED3\u675F\u539F\u56E0', 'INVALID_RESPONSE');\n if (!count) throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u8FD4\u56DE\u7A7A\u54CD\u5E94', 'EMPTY_RESPONSE');\n if (finish.kind === 'tool-calls' && !sawTool) throw new LlmError('OpenDesign\uFF1A\u54CD\u5E94\u58F0\u660E\u5DE5\u5177\u8C03\u7528\uFF0C\u4F46\u672A\u8FD4\u56DE\u4EFB\u4F55\u5DE5\u5177\u5757', 'INVALID_RESPONSE');\n if (usage) yield { type: 'usage', usage };\n yield { type: 'finish', reason: finish };\n}\n", "/**\n * \u4E0A\u6E38\u5931\u8D25\u7684\u7A33\u5B9A\u5206\u7C7B\u3002\n *\n * \u4E09\u79CD\u534F\u8BAE\u7684\u4FE1\u5C01\u4E0D\u540C\uFF0C\u4F46\u5BF9\u5916\u53EA\u66B4\u9732\u56FA\u5B9A\u7684\u4E2D\u6587\u6587\u5B57\u4E0E\u673A\u5668\u7801\uFF1B\u4E0A\u6E38 `message`\u3001\u8BF7\u6C42\u5934\u3001\n * \u51ED\u636E\u4E0E\u54CD\u5E94\u4F53\u4E00\u5F8B\u4E0D\u8FDB\u5165\u9519\u8BEF\u6587\u5B57\uFF0C\u907F\u514D\u5BC6\u94A5\u6216\u7B2C\u4E09\u65B9\u5185\u5BB9\u8FDB\u5165\u65E5\u5FD7\u4E0E UI\u3002\n *\n * \u5224\u5B9A\u987A\u5E8F\uFF08\u524D\u8005\u4F18\u5148\uFF09\uFF1A\n * 1. \u4FE1\u5C01\u5185\u7ED3\u6784\u5316\u7684 `code` / `type`\uFF1A\u53EA\u8BA4\u660E\u786E\u7684\u679A\u4E3E\u5F0F\u5199\u6CD5\uFF1B\n * 2. \u4E3B\u9898\u660E\u786E\u7684 `message`\uFF1A\u4E0A\u4E0B\u6587\u6EA2\u51FA\u3001\u989D\u5EA6\u8017\u5C3D\u3001\u9650\u6D41\u3001\u8D85\u65F6\u3001\u670D\u52A1\u7AEF\u3001\u8BA4\u8BC1/\u6743\u9650\uFF1B\n * 3. HTTP \u72B6\u6001\uFF1A\u4EC5\u4F5C\u4E3A\u8865\u5145\u4E8B\u5B9E\uFF0C\u4E0D\u8986\u76D6\u4E0A\u9762\u66F4\u5177\u4F53\u7684\u5206\u7C7B\uFF1B\u552F\u4E00\u4F8B\u5916\u662F 5xx\u2014\u2014\n * \u6CA1\u6709\u7ED3\u6784\u5316\u4EE3\u7801\u65F6\u76F4\u63A5\u6309\u670D\u52A1\u7AEF\u5904\u7406\uFF08504 \u4ECD\u6309\u8D85\u65F6\uFF09\uFF0C\u4E0D\u56E0\u6B63\u6587\u63AA\u8F9E\u6539\u5224\u3002\n *\n * \u5173\u952E\u53D6\u820D\uFF1A\n * - \u989D\u5EA6\u5206\u4E24\u6C60\uFF1A\u5957\u9910/\u8BA2\u9605/\u8D26\u6237\u989D\u5EA6 \u2192 `ACCOUNT_QUOTA`\uFF1B\u94B1\u5305/\u5145\u503C/\u79EF\u5206/\u4F59\u989D \u2192 `QUOTA`\u3002\n * \u53EA\u6709\u201C\u989D\u5EA6\u4E0D\u8DB3\u201D\u800C\u6CA1\u6709\u6C60\u4FE1\u606F\u65F6\u6309\u8D26\u6237\u989D\u5EA6\u5904\u7406\u3002\n * - \u666E\u901A 401/403 \u53EA\u8868\u8FBE\u8BA4\u8BC1\u6216\u6743\u9650\u8BED\u4E49\uFF08`AUTH` / `PERMISSION`\uFF09\uFF0C\u4E0D\u63A8\u65AD API Key \u65E0\u6548\uFF1B\n * \u53EA\u6709\u4E0A\u6E38\u660E\u786E\u70B9\u540D Key/\u51ED\u636E\u65E0\u6548\u6216\u7F3A\u5931\uFF08\u7ED3\u6784\u5316 code \u6216\u660E\u786E\u6587\u6848\uFF09\u624D\u662F `INVALID_CREDENTIAL`\u3002\n * \u7ED3\u6784\u5316\u53EA\u7ED9\u51FA\u8BA4\u8BC1/\u6743\u9650\u8BED\u4E49\u65F6\uFF0C\u70B9\u540D Key \u7684\u660E\u786E\u6587\u6848\u53EF\u4EE5\u628A\u7ED3\u8BBA\u7EC6\u5316\u4E3A\u51ED\u636E\u9519\u8BEF\u3002\n * - `quota` / `context` \u5355\u72EC\u51FA\u73B0\u53EA\u662F\u80CC\u666F\u8BCD\uFF1B\u5FC5\u987B\u540C\u65F6\u51FA\u73B0\u201C\u8017\u5C3D/\u8D85\u51FA\u201D\u7B49\u8BED\u4E49\u624D\u7B97\u6570\uFF0C\n * \u56E0\u6B64 `rate_limit_exceeded` \u4E0D\u4F1A\u88AB\u6CDB\u5316\u6210\u989D\u5EA6\u4E0D\u8DB3\uFF0C\u4E5F\u4E0D\u4F1A\u56E0\u4E3A\u6B63\u6587\u63D0\u5230\u201C\u4E0A\u4E0B\u6587\u7F13\u5B58\u201D\u800C\u8BEF\u5224\u3002\n * - HTTP \u72B6\u6001\u4E0E\u7ED3\u6784\u5316\u9519\u8BEF\u51B2\u7A81\u65F6\u4EE5\u7ED3\u6784\u5316\u9519\u8BEF\u4E3A\u51C6\uFF1A\u5178\u578B\u7684 429 + `insufficient_quota`\n * \u5F52\u5165\u989D\u5EA6\u800C\u4E0D\u662F\u9650\u6D41\uFF0C401 + \u989D\u5EA6\u8BC1\u636E\u5F52\u5165\u989D\u5EA6\u800C\u4E0D\u662F\u8BA4\u8BC1\u3002\n */\n\nimport {\n ACCOUNT_QUOTA_EXCEEDED_CODE,\n CONTEXT_WINDOW_EXCEEDED_CODE,\n INVALID_CREDENTIAL_CODE,\n LlmError,\n QUOTA_EXCEEDED_CODE,\n isContextWindowExceededError,\n isQuotaExceededError,\n} from '@deepseek-ai/dsh-llm';\nimport { record } from '../util.js';\n\n/** \u56FA\u5B9A\u6587\u6848\uFF1A\u53EA\u8BF4\u660E\u5206\u7C7B\u4E0E\u4E0B\u4E00\u6B65\uFF0C\u7EDD\u4E0D\u62FC\u63A5\u4E0A\u6E38\u6587\u5B57\u3001\u72B6\u6001\u4EE5\u5916\u7684\u54CD\u5E94\u4E8B\u5B9E\u6216\u51ED\u636E\u3002 */\nconst MESSAGES: Readonly<Record<string, string>> = {\n [CONTEXT_WINDOW_EXCEEDED_CODE]: 'OpenDesign\uFF1A\u8BF7\u6C42\u8D85\u51FA\u6A21\u578B\u4E0A\u4E0B\u6587\u957F\u5EA6\uFF0C\u8BF7\u7F29\u77ED\u8F93\u5165\u540E\u91CD\u8BD5',\n [ACCOUNT_QUOTA_EXCEEDED_CODE]: 'OpenDesign\uFF1A\u5957\u9910\u6216\u8D26\u6237\u989D\u5EA6\u4E0D\u8DB3\uFF0C\u8BF7\u68C0\u67E5\u5957\u9910\u989D\u5EA6\u540E\u91CD\u8BD5',\n [QUOTA_EXCEEDED_CODE]: 'OpenDesign\uFF1A\u94B1\u5305\u6216\u79EF\u5206\u4F59\u989D\u4E0D\u8DB3\uFF0C\u8BF7\u5145\u503C\u540E\u91CD\u8BD5',\n [INVALID_CREDENTIAL_CODE]: 'OpenDesign\uFF1AAPI Key \u65E0\u6548\u6216\u7F3A\u5931\uFF0C\u8BF7\u5728\u8BBE\u7F6E\u4E2D\u66F4\u65B0\u51ED\u636E',\n AUTH: 'OpenDesign\uFF1A\u8BA4\u8BC1\u672A\u901A\u8FC7\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55\u540E\u91CD\u8BD5',\n PERMISSION: 'OpenDesign\uFF1A\u5F53\u524D\u8D26\u6237\u65E0\u6743\u8BBF\u95EE\u8BE5\u6A21\u578B',\n RATE_LIMIT: 'OpenDesign\uFF1A\u8BF7\u6C42\u8FC7\u4E8E\u9891\u7E41\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5',\n TIMEOUT: 'OpenDesign\uFF1A\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5',\n SERVER: 'OpenDesign\uFF1A\u4E0A\u6E38\u670D\u52A1\u6682\u4E0D\u53EF\u7528\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5',\n INVALID_REQUEST: 'OpenDesign\uFF1A\u8BF7\u6C42\u88AB\u4E0A\u6E38\u62D2\u7EDD',\n INVALID_RESPONSE: 'OpenDesign\uFF1A\u4E0A\u6E38\u54CD\u5E94\u683C\u5F0F\u65E0\u6548',\n};\nconst UNKNOWN_MESSAGE = 'OpenDesign\uFF1A\u8BF7\u6C42\u5931\u8D25';\n\n/* \u2500\u2500 \u7ED3\u6784\u5316 code/type\uFF1A\u53EA\u8BA4\u679A\u4E3E\u5F0F\u5199\u6CD5\uFF0C\u907F\u514D\u628A\u666E\u901A\u5355\u8BCD\u5F53\u5206\u7C7B\u4F9D\u636E \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\nconst STRUCTURED_CREDENTIAL =\n /invalid[_-]?(?:x[_-]?)?api[_-]?key|missing[_-]?(?:x[_-]?)?api[_-]?key|incorrect[_-]?(?:x[_-]?)?api[_-]?key|api[_-]?key[_-]?(?:invalid|missing|incorrect)|invalid[_-]?credentials?|credentials?[_-]?(?:invalid|missing)/u;\nconst STRUCTURED_CONTEXT =\n /context[_-]?(?:length|window)[_-]?(?:exceeded|exceed|overflow)|context[_-]?overflow|(?:prompt|input)[_-]?too[_-]?long/u;\nconst STRUCTURED_WALLET =\n /(?:insufficient|low|exhausted|depleted|empty|zero)[_-]?(?:credits?|balance|funds)|(?:credits?|balance|wallet|funds)[_-]?(?:insufficient|exhausted|depleted|low|empty)|(?:credit|wallet)[_-]balance[_-](?:too[_-]low|insufficient|exhausted)/u;\nconst STRUCTURED_PLAN =\n /(?:insufficient|exceeded|exhausted|reached|over)[_-]?(?:quota|plan|usage[_-]?limit)|quota[_-]?(?:exceeded|exhausted|reached)|billing[_-]?hard[_-]?limit|usage[_-]?limit[_-]?(?:exceeded|reached)|(?:subscription|membership|plan)(?:[_-](?:quota|credits?|limit))?[_-](?:exceeded|exhausted|insufficient|reached)/u;\nconst STRUCTURED_RATE =\n /rate[_-]?limit|too[_-]?many[_-]?requests|resource[_-]?exhausted|(?:requests?|tokens?)[_-]?per[_-]?(?:minute|second)/u;\nconst STRUCTURED_TIMEOUT = /timeout|timed[_-]?out|deadline[_-]?exceeded/u;\nconst STRUCTURED_SERVER =\n /server[_-]?error|api[_-]?error|internal[_-]?(?:server[_-]?)?error|service[_-]?unavailable|unavailable|overloaded|bad[_-]?gateway|gateway[_-]?error/u;\nconst STRUCTURED_AUTH = /authentication|unauthorized|not[_-]?authenticated/u;\nconst STRUCTURED_PERMISSION = /permission|forbidden|access[_-]?denied|insufficient[_-]?scope/u;\n\n/* \u2500\u2500 message \u6587\u6848\uFF1A\u6BCF\u6761\u90FD\u5FC5\u987B\u5E26\u660E\u786E\u7684\u5931\u8D25\u8BED\u4E49\uFF0C\u5355\u7EAF\u7684\u4E3B\u9898\u8BCD\u4E0D\u7B97 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/** \u53EA\u6709\u660E\u786E\u70B9\u540D Key/\u51ED\u636E\u65E0\u6548\u6216\u7F3A\u5931\u624D\u7B97\u51ED\u636E\u9519\u8BEF\uFF1B\u5173\u952E\u8BCD\u672C\u8EAB\u4E0D\u63A8\u65AD\u3002 */\nconst PROSE_CREDENTIAL =\n /invalid[ _-]?(?:x[ _-]?)?api[ _-]?key|(?:x[ _-]?)?api[ _-]?key[ _-]?(?:is[ _-]?)?(?:invalid|missing|incorrect|not[ _-]?valid)|missing[ _-]?(?:x[ _-]?)?api[ _-]?key|incorrect[ _-]?(?:x[ _-]?)?api[ _-]?key|invalid[ _-]?credentials?\\b|api[ _-]?key\\s*(?:\u65E0\u6548|\u7F3A\u5931|\u9519\u8BEF)|\u5BC6\u94A5(?:\u65E0\u6548|\u7F3A\u5931|\u9519\u8BEF)/u;\nconst PROSE_CONTEXT_EN =\n /\\b(?:prompt|input|messages?)\\s+(?:is\\s+|are\\s+)?too\\s+(?:long|large)\\b|\\bmaximum context\\b|\\btokens? > \\d+ maximum\\b/u;\nconst PROSE_CONTEXT_ZH =\n /\u8D85\u51FA[^\u3002]{0,8}\u4E0A\u4E0B\u6587|\u4E0A\u4E0B\u6587[^\u3002]{0,16}(?:\u8D85\u51FA|\u8D85\u8FC7|\u8D85\u9650|\u8FC7\u957F|\u5DF2\u6EE1)|(?:\u8F93\u5165|\u8BF7\u6C42|\u63D0\u793A\u8BCD)[^\u3002]{0,8}(?:\u8FC7\u957F|\u592A\u957F)|\u8D85\u8FC7[^\u3002]{0,8}\u4E0A\u4E0B\u6587/u;\nconst PROSE_QUOTA_EN =\n /\\b(?:credits?|balance|quota|funds|wallet)\\b[^.;]{0,24}\\b(?:insufficient|exhausted|depleted|used[ _-]?up|too[ _-]?low|empty|zero|exceeded)\\b|\\b(?:insufficient|exhausted|depleted|empty|zero)\\b[^.;]{0,24}\\b(?:credits?|balance|quota|funds|wallet)\\b/u;\nconst PROSE_QUOTA_ZH =\n /(?:\u4F59\u989D|\u79EF\u5206|\u989D\u5EA6|\u914D\u989D|\u94B1\u5305)[^\u3002]{0,12}(?:\u4E0D\u8DB3|\u7528\u5C3D|\u8017\u5C3D|\u7528\u5B8C|\u8D85\u9650|\u8D85\u51FA|\u5DF2\u8FBE\u4E0A\u9650|\u8D85\u8FC7\u4E0A\u9650)|(?:\u4E0D\u8DB3|\u7528\u5C3D|\u8017\u5C3D)[^\u3002]{0,6}(?:\u4F59\u989D|\u989D\u5EA6|\u914D\u989D|\u79EF\u5206)/u;\nconst PROSE_QUOTA_PLAN =\n /\u5957\u9910|\u8BA2\u9605|\u4F1A\u5458|\u8D26\u6237\u989D\u5EA6|\u8D26\u6237\u914D\u989D|\u7528\u91CF\u4E0A\u9650|\u4F7F\u7528\u4E0A\u9650|\\bplan\\b|\\bsubscription\\b|\\bmembership\\b|\\bbilling\\b|hard[ _-]?limit|usage[ _-]?limit/u;\nconst PROSE_QUOTA_WALLET =\n /\u94B1\u5305|\u5145\u503C|\u4F59\u989D|\u79EF\u5206|\\bwallet\\b|\\brecharge\\b|top[ _-]?up|\\bbalance\\b|\\bcredits?\\b|\\bfunds?\\b/u;\nconst PROSE_RATE = /rate[ _-]?limit|\\btoo many requests\\b|\\bresource[ _-]?exhausted\\b|\u8BF7\u6C42\u8FC7\u4E8E\u9891\u7E41|\u9891\u7387\u8D85\u9650|\u89E6\u53D1\u9650\u6D41|\u63A5\u53E3\u9650\u6D41/u;\nconst PROSE_TIMEOUT = /\\btimeout\\b|\\btimed out\\b|\\bdeadline exceeded\\b|\u8BF7\u6C42\u8D85\u65F6|\u8D85\u65F6/u;\nconst PROSE_SERVER =\n /\\bserver error\\b|\\bapi error\\b|\\binternal (?:server )?error\\b|\\bservice unavailable\\b|\\boverloaded\\b|\\bbad gateway\\b|\u670D\u52A1\u6682\u4E0D\u53EF\u7528|\u670D\u52A1\u4E0D\u53EF\u7528|\u670D\u52A1\u5668\u9519\u8BEF|\u670D\u52A1\u5668\u7E41\u5FD9|\u5185\u90E8\u9519\u8BEF/u;\nconst PROSE_AUTH = /\\bauthentication\\b|\\bunauthorized\\b|\\bnot authenticated\\b|\u8BA4\u8BC1\u5931\u8D25|\u767B\u5F55\u5DF2\u5931\u6548|\u672A\u767B\u5F55/u;\nconst PROSE_PERMISSION =\n /\\bpermission\\b|\\bforbidden\\b|\\baccess denied\\b|\\bnot authorized\\b|\\binsufficient (?:permissions?|scope)\\b|\u6743\u9650\u4E0D\u8DB3|\u65E0\u6743\u9650|\u65E0\u6743\u8BBF\u95EE/u;\n\n/** \u6784\u9020\u56FA\u5B9A\u6587\u6848\u7684\u9519\u8BEF\uFF1BHTTP \u72B6\u6001\u53EA\u4F5C\u4E3A\u7ED3\u6784\u5316\u4E8B\u5B9E\u4FDD\u7559\uFF0C\u4E0D\u62FC\u8FDB\u6587\u5B57\u3002 */\nfunction fail(code: string, status: number | undefined): LlmError {\n const options = status === undefined ? {} : { status };\n return new LlmError(MESSAGES[code] ?? UNKNOWN_MESSAGE, code, options);\n}\n\nfunction matches(fields: readonly string[], pattern: RegExp): boolean {\n return fields.some(field => pattern.test(field));\n}\n\n/** \u7ED3\u6784\u5316\u989D\u5EA6\u6309\u6C60\u62C6\u5206\uFF1A\u94B1\u5305/\u79EF\u5206\u4F18\u5148\uFF0C\u5176\u4F59\u89C6\u4E3A\u5957\u9910\u6216\u8D26\u6237\u989D\u5EA6\u3002 */\nfunction structuredQuota(fields: readonly string[]): string | undefined {\n if (matches(fields, STRUCTURED_WALLET)) return QUOTA_EXCEEDED_CODE;\n if (matches(fields, STRUCTURED_PLAN)) return ACCOUNT_QUOTA_EXCEEDED_CODE;\n return undefined;\n}\n\n/** \u6587\u6848\u989D\u5EA6\u540C\u6837\u6309\u6C60\u62C6\u5206\uFF1A\u5957\u9910/\u8BA2\u9605\u4F18\u5148\uFF0C\u5176\u6B21\u94B1\u5305/\u79EF\u5206\uFF0C\u672A\u6307\u660E\u6C60\u65F6\u6309\u8D26\u6237\u989D\u5EA6\u3002 */\nfunction proseQuota(detail: string): string {\n if (PROSE_QUOTA_PLAN.test(detail)) return ACCOUNT_QUOTA_EXCEEDED_CODE;\n if (PROSE_QUOTA_WALLET.test(detail)) return QUOTA_EXCEEDED_CODE;\n return ACCOUNT_QUOTA_EXCEEDED_CODE;\n}\n\nfunction classifyStructured(fields: readonly string[]): string | undefined {\n if (matches(fields, STRUCTURED_CREDENTIAL)) return INVALID_CREDENTIAL_CODE;\n if (matches(fields, STRUCTURED_CONTEXT)) return CONTEXT_WINDOW_EXCEEDED_CODE;\n const quota = structuredQuota(fields);\n if (quota !== undefined) return quota;\n if (matches(fields, STRUCTURED_RATE)) return 'RATE_LIMIT';\n if (matches(fields, STRUCTURED_TIMEOUT)) return 'TIMEOUT';\n if (matches(fields, STRUCTURED_SERVER)) return 'SERVER';\n if (matches(fields, STRUCTURED_AUTH)) return 'AUTH';\n if (matches(fields, STRUCTURED_PERMISSION)) return 'PERMISSION';\n return undefined;\n}\n\nfunction classifyProse(detail: string): string | undefined {\n if (detail === '') return undefined;\n if (isContextWindowExceededError(detail) || PROSE_CONTEXT_EN.test(detail) || PROSE_CONTEXT_ZH.test(detail)) return CONTEXT_WINDOW_EXCEEDED_CODE;\n if (isQuotaExceededError(detail) || PROSE_QUOTA_EN.test(detail) || PROSE_QUOTA_ZH.test(detail)) return proseQuota(detail);\n if (PROSE_RATE.test(detail)) return 'RATE_LIMIT';\n if (PROSE_TIMEOUT.test(detail)) return 'TIMEOUT';\n if (PROSE_SERVER.test(detail)) return 'SERVER';\n if (PROSE_AUTH.test(detail)) return 'AUTH';\n if (PROSE_PERMISSION.test(detail)) return 'PERMISSION';\n return undefined;\n}\n\n/** HTTP \u72B6\u6001\u53EA\u8865\u8DB3\u7ED3\u6784\u5316\u4E0E\u6587\u6848\u90FD\u6CA1\u6709\u7ED9\u51FA\u7684\u7C7B\u522B\uFF1B5xx \u4E00\u5F8B\u6309\u670D\u52A1\u7AEF\u5904\u7406\u3002 */\nfunction classifyStatus(status: number | undefined): string | undefined {\n if (status === undefined) return undefined;\n if (status === 401) return 'AUTH';\n if (status === 403) return 'PERMISSION';\n if (status === 402) return QUOTA_EXCEEDED_CODE;\n if (status === 429) return 'RATE_LIMIT';\n if (status === 408 || status === 504) return 'TIMEOUT';\n if (status >= 500) return 'SERVER';\n return undefined;\n}\n\ninterface Fields {\n /** `code` \u4E0E `type` \u5206\u5F00\u4FDD\u5B58\uFF0C\u907F\u514D\u8DE8\u5B57\u6BB5\u62FC\u51FA\u5E76\u4E0D\u5B58\u5728\u7684\u77ED\u8BED\u3002 */\n readonly structured: readonly string[];\n readonly prose: string;\n}\n\nfunction fieldsOf(error: Record<string, unknown>): Fields {\n const structured: string[] = [];\n for (const value of [error.code, error.type]) {\n if (typeof value !== 'string') continue;\n const normalized = value.trim().toLowerCase();\n if (normalized !== '') structured.push(normalized);\n }\n return { structured, prose: typeof error.message === 'string' ? error.message.toLowerCase() : '' };\n}\n\n/** \u4F9D\u636E\u7ED3\u6784\u5316\u5B57\u6BB5\u3001\u6587\u6848\u4E0E HTTP \u72B6\u6001\u7ED9\u51FA\u7A33\u5B9A\u7684 LlmError\uFF1B`fallback` \u51B3\u5B9A\u65E0\u6CD5\u5F52\u7C7B\u65F6\u7684\u673A\u5668\u7801\u3002 */\nfunction classify(fields: Fields, status: number | undefined, fallback: string): LlmError {\n const structured = classifyStructured(fields.structured);\n // \u7ED3\u6784\u5316\u5206\u7C7B\u4F18\u5148\uFF1A\u660E\u786E\u7684\u989D\u5EA6/\u4E0A\u4E0B\u6587/\u9650\u6D41/\u8D85\u65F6/\u670D\u52A1\u7AEF\u7ED3\u8BBA\u4E0D\u4F1A\u88AB HTTP \u72B6\u6001\u6539\u5199\u3002\n if (structured !== undefined && structured !== 'AUTH' && structured !== 'PERMISSION') return fail(structured, status);\n // 5xx \u662F\u660E\u786E\u7684\u670D\u52A1\u7AEF\u4E8B\u5B9E\uFF08504 \u5355\u72EC\u6309\u8D85\u65F6\u5904\u7406\uFF09\uFF1A\u6CA1\u6709\u7ED3\u6784\u5316\u4EE3\u7801\u65F6\u4E0D\u91C7\u4FE1\u6B63\u6587\u91CC\u7684\u8BA4\u8BC1\u6216\u989D\u5EA6\u63AA\u8F9E\u3002\n if (structured === undefined && status !== undefined && status >= 500 && status !== 504) return fail('SERVER', status);\n // \u4E0A\u6E38\u53EA\u7ED9\u51FA\u8BA4\u8BC1/\u6743\u9650\u8BED\u4E49\u65F6\uFF0C\u660E\u786E\u70B9\u540D Key/\u51ED\u636E\u65E0\u6548\u6216\u7F3A\u5931\u7684\u6587\u6848\u53EF\u4EE5\u5347\u7EA7\u4E3A\u51ED\u636E\u9519\u8BEF\u3002\n if (PROSE_CREDENTIAL.test(fields.prose)) return fail(INVALID_CREDENTIAL_CODE, status);\n if (structured !== undefined) return fail(structured, status);\n const prose = classifyProse(fields.prose);\n if (prose !== undefined) return fail(prose, status);\n // \u72B6\u6001\u53EA\u515C\u5E95\uFF1A\u5178\u578B\u989D\u5EA6/\u8BA4\u8BC1\u7C7B 401 \u5DF2\u7531\u4E0A\u9762\u7684\u4E13\u7528\u5206\u7C7B\u5904\u7406\uFF0C\u4E0D\u4F1A\u9000\u56DE\u6210\u8BA4\u8BC1\u6216\u9650\u6D41\u3002\n const byStatus = classifyStatus(status);\n return fail(byStatus ?? fallback, status);\n}\n\n/**\n * OpenAI \u98CE\u683C\u4FE1\u5C01\uFF1A`{ error: { code, type, message } }`\uFF08Chat Completions \u4E0E Responses \u5B9E\u6D4B\u4E00\u81F4\uFF09\u3002\n *\n * @param status \u4E0A\u6E38 HTTP \u72B6\u6001\uFF1B\u6D41\u5185\u9519\u8BEF\u4E8B\u4EF6\u6CA1\u6709\u72B6\u6001\u65F6\u7701\u7565\u3002\n * @param body \u5DF2\u89E3\u6790\u7684\u54CD\u5E94\u4F53\u6216\u6D41\u4E8B\u4EF6\u3002\n */\nexport function gatewayError(status: number | undefined, body: unknown): LlmError {\n const error = record(body) && record(body.error) ? body.error : record(body) ? body : {};\n return classify(fieldsOf(error), status, 'INVALID_REQUEST');\n}\n\n/**\n * Anthropic \u98CE\u683C\u4FE1\u5C01\uFF1A`{ type: \"error\", error: { type, message } }`\uFF08Messages \u7AEF\u70B9\u5B9E\u6D4B\uFF09\u3002\n *\n * @param status \u4E0A\u6E38 HTTP \u72B6\u6001\uFF1B\u6D41\u5185\u9519\u8BEF\u4E8B\u4EF6\u6CA1\u6709\u72B6\u6001\u65F6\u7701\u7565\u3002\n * @param body \u5DF2\u89E3\u6790\u7684\u54CD\u5E94\u4F53\u6216\u6D41\u4E8B\u4EF6\u3002\n */\nexport function anthropicError(status: number | undefined, body: unknown): LlmError {\n const error = record(body) && record(body.error) ? body.error : {};\n return classify(fieldsOf(error), status, 'INVALID_REQUEST');\n}\n\n/**\n * \u6D41\u5185\u9519\u8BEF\u4E8B\u4EF6\uFF08HTTP \u5DF2\u662F 200\uFF0C\u9519\u8BEF\u53EA\u80FD\u4F5C\u4E3A\u4E8B\u4EF6\u5230\u8FBE\uFF09\u3002\n *\n * @param error \u4E8B\u4EF6\u91CC\u7684\u9519\u8BEF\u5BF9\u8C61\uFF08\u4E24\u79CD\u4FE1\u5C01\u90FD\u53EF\uFF09\u3002\n * @param fallback \u65E0\u6CD5\u5F52\u7C7B\u65F6\u4F7F\u7528\u7684\u673A\u5668\u7801\uFF0C\u9ED8\u8BA4\u6309\u683C\u5F0F\u9519\u8BEF\u5904\u7406\u3002\n */\nexport function inBandError(error: unknown, fallback = 'INVALID_RESPONSE'): LlmError {\n return classify(fieldsOf(record(error) ? error : {}), undefined, fallback);\n}\n", "/**\n * \u534F\u8BAE\u65E0\u5173\u7684 SSE \u5206\u5E27\u3002\n *\n * \u53EA\u8D1F\u8D23\u4F20\u8F93\u5C42\uFF1A\u628A\u5B57\u8282\u6D41\u6309 SSE \u884C\u534F\u8BAE\u5207\u6210 `event:` + \u591A\u884C `data:` \u5E27\uFF0C\u5E76\u7EDF\u4E00\u5F3A\u5236\n * \u53D6\u6D88\u3001\u7A7A\u95F2\u8D85\u65F6\u4E0E\u5927\u5C0F\u4E0A\u9650\u3002\u4E8B\u4EF6\u8BED\u4E49\uFF08JSON \u7ED3\u6784\u3001\u7EC8\u6B62\u3001usage\uFF09\u7531\u5404\u534F\u8BAE\u6A21\u5757\u89E3\u91CA\u3002\n *\n * \u8FB9\u754C\u4E0E\u65E2\u6709 Chat Completions \u5B9E\u73B0\u4E00\u81F4\uFF0C\u4FBF\u4E8E\u56DE\u5F52\uFF1A\n * - CRLF \u53EF\u80FD\u88AB\u62C6\u5230\u4E24\u4E2A\u4F20\u8F93\u5757\u4E4B\u95F4\uFF0C\u4FDD\u7559\u5C3E\u90E8 CR\u3002\n * - \u5355\u4E8B\u4EF6\u7D2F\u8BA1 `data` \u4E0E\u5355\u884C\u7F13\u51B2\u90FD\u4E0D\u5F97\u8D85\u8FC7 4 MiB\uFF1B\u8D85\u9650\u6309\u683C\u5F0F\u9519\u8BEF\u62D2\u7EDD\uFF0C\u4E0D\u622A\u65AD\u89E3\u6790\u3002\n * - \u7A7A\u95F2\u8D85\u8FC7 `idleMs` \u629B TIMEOUT\uFF1B`signal` \u4E2D\u6B62\u65F6\u629B\u51FA signal \u7684\u539F\u56E0\u3002\n * - \u65E0\u8BBA\u6210\u529F\u3001\u5F02\u5E38\u8FD8\u662F\u6D88\u8D39\u65B9\u63D0\u524D `break`\uFF0C\u90FD\u4F1A cancel \u5E76\u91CA\u653E\u4E0A\u6E38 reader\u3002\n */\n\nimport { LlmError } from '@deepseek-ai/dsh-llm';\n\n/** \u4E00\u5E27 SSE \u4E8B\u4EF6\uFF1A`event:` \u540D\uFF08\u53EF\u9009\uFF09+ \u5408\u5E76\u540E\u7684 `data` \u8F7D\u8377\u3002 */\nexport interface SseFrame {\n readonly event?: string;\n readonly data: string;\n}\n\n/** \u5355\u884C / \u5355\u4E8B\u4EF6\u7684\u5B57\u7B26\u4E0A\u9650\uFF08\u4EE5 UTF-16 \u7801\u5143\u8BA1\uFF0C\u4E0E\u65E2\u6709\u5B9E\u73B0\u4FDD\u6301\u4E00\u81F4\uFF09\u3002 */\nconst MAX_FRAME_CHARS = 4 * 1024 * 1024;\n\n/**\n * \u9010\u5E27\u4EA7\u51FA SSE \u4E8B\u4EF6\u3002\n *\n * @param body \u4E0A\u6E38\u54CD\u5E94\u4F53\uFF1B\u7ED3\u675F\u65F6\u7531\u672C\u751F\u6210\u5668\u8D1F\u8D23 cancel\u3002\n * @param signal \u8C03\u7528\u65B9\u53D6\u6D88\u4FE1\u53F7\uFF08\u5DF2\u4E0E\u8D85\u65F6\u5408\u5E76\uFF09\u3002\n * @param idleMs \u4E24\u6B21\u8BFB\u5230\u6570\u636E\u4E4B\u95F4\u7684\u6700\u957F\u7B49\u5F85\u6BEB\u79D2\u6570\u3002\n */\nexport async function* sseFrames(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n idleMs: number,\n): AsyncGenerator<SseFrame> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let data: string[] = [];\n let dataSize = 0;\n let name: string | undefined;\n\n /** \u6D3E\u53D1\u5F53\u524D\u7D2F\u79EF\u7684\u4E8B\u4EF6\uFF1B\u6CA1\u6709 data \u884C\u65F6\u4E0D\u4EA7\u51FA\uFF08\u6CE8\u91CA\u3001\u7A7A\u884C\uFF09\u3002 */\n function dispatch(): SseFrame[] {\n const payload = data.join('\\n');\n const event = name;\n data = [];\n dataSize = 0;\n name = undefined;\n return payload ? [{ ...(event === undefined ? {} : { event }), data: payload }] : [];\n }\n\n function line(value: string): SseFrame[] {\n if (!value) return dispatch();\n if (value.startsWith(':')) return [];\n if (value.startsWith('data:')) {\n const part = value.slice(5).replace(/^ /u, '');\n dataSize += part.length;\n if (dataSize > MAX_FRAME_CHARS) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u4E8B\u4EF6\u8D85\u8FC7\u5927\u5C0F\u9650\u5236', 'INVALID_RESPONSE');\n data.push(part);\n return [];\n }\n if (value.startsWith('event:')) {\n const event = value.slice(6).trim();\n name = event === '' ? undefined : event;\n }\n return [];\n }\n\n async function read(): Promise<ReadableStreamReadResult<Uint8Array>> {\n signal.throwIfAborted();\n let timer: ReturnType<typeof setTimeout> | undefined;\n let abort: () => void = () => {};\n try {\n return await Promise.race([\n reader.read(),\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u54CD\u5E94\u957F\u65F6\u95F4\u6CA1\u6709\u6570\u636E', 'TIMEOUT')), idleMs);\n abort = () => reject(signal.reason);\n signal.addEventListener('abort', abort, { once: true });\n if (signal.aborted) abort();\n }),\n ]);\n } finally {\n clearTimeout(timer);\n signal.removeEventListener('abort', abort);\n }\n }\n\n try {\n while (true) {\n const result = await read();\n buffer += result.done ? decoder.decode() : decoder.decode(result.value, { stream: true });\n // CRLF \u53EF\u80FD\u88AB\u62C6\u5230\u4E24\u4E2A\u4F20\u8F93\u5757\u4E4B\u95F4\uFF1B\u4FDD\u7559\u5C3E\u90E8\u5355\u4E2A CR \u7B49\u5F85\u4E0B\u4E00\u5757\u3002\n let match: RegExpExecArray | null;\n while ((match = /\\r\\n|\\n|\\r(?!$)/u.exec(buffer))) {\n const at = match.index;\n const value = buffer.slice(0, at);\n buffer = buffer.slice(at + match[0].length);\n for (const frame of line(value)) yield frame;\n }\n if (buffer.length > MAX_FRAME_CHARS) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u884C\u8D85\u8FC7\u5927\u5C0F\u9650\u5236', 'INVALID_RESPONSE');\n if (result.done) {\n if (buffer) for (const frame of line(buffer.replace(/\\r$/u, ''))) yield frame;\n for (const frame of dispatch()) yield frame;\n break;\n }\n }\n } finally {\n await reader.cancel().catch(() => undefined); // \u6E05\u7406\u5931\u8D25\u4E0D\u5F97\u8986\u76D6\u539F\u59CB\u9519\u8BEF\n reader.releaseLock();\n }\n}\n", "// Gift-pool empty-turn guard: turn a \"markup-only stop\" into a retryable EMPTY_RESPONSE.\n//\n// A translating relay in front of the gift model can hand the model's native tool/thinking\n// markup back as plain text and still finish with `stop`. The step then carries no tool call\n// and no prose the user can use, yet `dsh-agent-loop` reads \"no tool call\" as \"the turn is\n// over\". `consumeSse` has the sibling hole: its `!count` check (src/stream.ts:160) only covers\n// streams that opened zero blocks, and one residue block already makes `count === 1`.\n//\n// This module is the adapter-callable half of that guard, modelled on FYTXY/dsh-empty-turn-guard\n// 0.4.0 (MIT) \u2014 see docs/empty-turn-evidence.md. It never edits model text, never injects a\n// message and never replays work: the only action is rewriting an eligible `finish` reason into\n// `{ kind: 'error', failure: { code: 'EMPTY_RESPONSE' } }`, which the provider's existing retry\n// policy already treats as safe to repeat.\n//\n// The decision is the reference plugin's original semantics: visible text only.\n// Three conditions must hold together \u2014 the finish is `stop`, no tool call was observed, and the\n// visible text channel is empty once protocol residue is removed. Whether the reasoning channel\n// carried a real train of thought does not rescue the turn: a model that thinks and then answers\n// with nothing is exactly the empty turn this guard exists for, so it is retried too. A real\n// answer, a partial answer, a tool step, or a truncated (`max-tokens`) reply still passes through\n// untouched, because the first two either leave visible content or open a tool call.\n//\n// The switch is a *monitor* switch: `enabled: false` only turns this rewrite off. The adapter's\n// own `count === 0` \u2192 `EMPTY_RESPONSE` path is Core behaviour and must stay outside it, so a truly\n// content-free stream is rejected whether or not the monitor is on.\n//\n// Callers decide *where* it applies: pass `enabled: false` for paid routes so their failures keep\n// their existing behaviour. Nothing here restarts, reconnects, or reroutes a provider.\nimport { EMPTY_RESPONSE_CODE, type FinishReason, type StreamChunk } from '@deepseek-ai/dsh-llm';\n\n/** Failure message a rewritten empty turn carries. */\nexport const EMPTY_TURN_MESSAGE = 'OpenDesign\uFF1A\u6A21\u578B\u56DE\u590D\u53EA\u5269\u534F\u8BAE\u6807\u8BB0\uFF0C\u672A\u4EA7\u751F\u53EF\u7528\u5185\u5BB9';\n\n/**\n * Protocol residue a relay can leak into a text or reasoning channel: DeepSeek's private\n * `\uFF5C\uFF5CDSML\uFF5C\uFF5C` tool markers (U+FF5C fullwidth bars), reasoning tags, and the model-invented\n * `\u8FD4\u749E\u5F52\u771F` tag seen in the reference measurements.\n *\n * The second pattern covers the orphan form a streamed delta leaves behind when its leading `<`\n * never arrives (`\uFF5C\uFF5CDSML\uFF5C\uFF5C calls>`). Only known protocol tokens are stripped: unknown markup is\n * content, so a reply that merely discusses a tag is never misread as empty.\n */\nconst RESIDUE_PATTERNS: readonly RegExp[] = [\n /<\\s*\\/?\\s*\uFF5C\uFF5CDSML\uFF5C\uFF5C[^>]*>/gu,\n /\uFF5C\uFF5CDSML\uFF5C\uFF5C[^\\n<>]*>?/gu,\n /<\\s*\\/?\\s*thinking\\s*>/giu,\n /<\\s*\\/?\\s*\u8FD4\u749E\u5F52\u771F\\s*>/gu,\n];\n\n/** Punctuation a truncated tag decomposes into; on its own it still counts as nothing. */\nconst ONLY_MARKUP_PUNCTUATION = /^[\\s<>/\\\\|\uFF5C=_-]*$/u;\n\n/**\n * Remove protocol residue from one assembled channel.\n * @param text - concatenated text or reasoning content.\n * @returns the remainder, trimmed; empty when nothing survives but residue punctuation.\n */\nexport function stripProtocolResidue(text: string): string {\n let rest = text;\n for (const pattern of RESIDUE_PATTERNS) rest = rest.replace(pattern, '');\n rest = rest.trim();\n return ONLY_MARKUP_PUNCTUATION.test(rest) ? '' : rest;\n}\n\n/**\n * Decide whether one channel carries nothing a user could use.\n * @param text - channel content, `undefined` when the channel never opened.\n * @returns true for absent, blank, or residue-only content.\n */\nexport function isResidueOnly(text: string | undefined): boolean {\n return text === undefined || stripProtocolResidue(text) === '';\n}\n\n/** Stream facts one attempt produced, as the adapter accumulated them. */\nexport interface EmptyTurnInput {\n /** Whether any tool-call block was opened or streamed during this attempt. */\n readonly sawToolCall: boolean;\n /** Visible text content, `undefined` when the channel never opened. */\n readonly text?: string | undefined;\n}\n\n/** Evidence that is safe to log or count: flags and lengths, never model output. */\nexport interface EmptyTurnEvidence {\n readonly sawToolCall: boolean;\n /** Visible text length after nothing is stripped \u2014 the raw channel length. */\n readonly textLength: number;\n /** Reasoning length, for cost analysis only; it never rescues an empty visible answer. */\n readonly reasoningLength: number;\n /** True when the visible text channel is empty once protocol residue is removed. */\n readonly markupOnly: boolean;\n}\n\n/**\n * Whether this finish is the empty turn the guard exists for.\n *\n * Deliberately reads the visible text channel only, matching the reference plugin: a reply whose\n * reasoning carried real thought but whose answer is empty still leaves the user with nothing, so\n * it is retried. `max-tokens` is excluded because a truncated answer is a real answer and already\n * surfaces as its own outcome.\n * @param reason - the finish reason reported by the adapter.\n * @param input - the attempt's accumulated stream facts.\n * @returns true only when the finish is `stop`, no tool call happened, and visible text is residue.\n */\nexport function isMarkupOnlyStop(reason: FinishReason, input: EmptyTurnInput): boolean {\n return reason.kind === 'stop'\n && !input.sawToolCall\n && isResidueOnly(input.text);\n}\n\n/** Options shared by {@link EmptyTurnTracker}. */\nexport interface EmptyTurnOptions {\n /**\n * Monitor switch, read per request by the caller. `false` makes every\n * {@link EmptyTurnTracker.resolve} a no-op, which is how a paid route keeps its untouched\n * behaviour. It never suppresses the adapter's own `count === 0` \u2192 `EMPTY_RESPONSE` path:\n * that is Core behaviour and stays in force either way.\n */\n readonly enabled?: boolean;\n /**\n * Optional telemetry hook, invoked once per rewrite with log-safe evidence.\n *\n * The callback receives counts only, so a counter can be incremented without model output\n * reaching a log file. Callers own the metric; nothing is retried or recorded here, and an\n * exception from the callback is swallowed so monitoring can never break a stream.\n */\n readonly onEmptyTurn?: ((evidence: EmptyTurnEvidence) => void) | undefined;\n}\n\n/**\n * Per-attempt accumulator for the empty-turn decision.\n *\n * One instance belongs to one stream: creating it per request keeps concurrent attempts from\n * sharing state, and it holds no timers, subscriptions, or references to hosts.\n */\nexport class EmptyTurnTracker {\n readonly #enabled: boolean;\n readonly #onEmptyTurn: ((evidence: EmptyTurnEvidence) => void) | undefined;\n #sawToolCall = false;\n /** Text seen as raw deltas (delta-only protocols). */\n #deltaText = '';\n /** Text seen in closed blocks (authoritative when present). */\n #blockText = '';\n /** Reasoning seen as raw deltas. */\n #deltaReasoning = '';\n /** Reasoning seen in closed blocks. */\n #blockReasoning = '';\n\n /** @param options - the monitor switch and optional telemetry hook; omitted switch means on. */\n constructor(options: EmptyTurnOptions = {}) {\n this.#enabled = options.enabled !== false;\n this.#onEmptyTurn = options.onEmptyTurn;\n }\n\n /** Whether this tracker may rewrite a finish at all. */\n get enabled(): boolean {\n return this.#enabled;\n }\n\n /** Whether any tool call reached the stream, which always protects the attempt. */\n get sawToolCall(): boolean {\n return this.#sawToolCall;\n }\n\n /**\n * Fold one stream chunk into the attempt.\n * @param chunk - any chunk the adapter yields; unknown kinds are ignored.\n */\n observe(chunk: StreamChunk): void {\n switch (chunk.type) {\n case 'tool-call-delta':\n this.#sawToolCall = true;\n return;\n case 'block-start':\n if (chunk.blockType === 'tool-call') this.#sawToolCall = true;\n return;\n case 'text-delta':\n if (typeof chunk.text === 'string') this.#deltaText += chunk.text;\n return;\n case 'reasoning-delta':\n if (typeof chunk.text === 'string') this.#deltaReasoning += chunk.text;\n return;\n case 'block-end': {\n const block = chunk.block;\n if (block.type === 'tool-call') this.#sawToolCall = true;\n else if (block.type === 'text' && typeof block.text === 'string') this.#blockText += block.text;\n else if (block.type === 'reasoning' && typeof block.text === 'string') this.#blockReasoning += block.text;\n return;\n }\n default:\n return;\n }\n }\n\n /**\n * What the attempt has produced so far, as log-safe counts.\n * @returns flags and channel lengths, never the text itself.\n */\n inspect(): EmptyTurnEvidence {\n const text = this.#text();\n const reasoning = this.#reasoning();\n return {\n sawToolCall: this.#sawToolCall,\n textLength: text.length,\n reasoningLength: reasoning.length,\n markupOnly: isResidueOnly(text),\n };\n }\n\n /**\n * Rewrite an eligible finish into the provider-neutral empty-response failure.\n *\n * The reason object is returned unchanged (same reference) whenever the monitor is off, the\n * finish is not `stop`, a tool call was observed, or the visible text carries usable content.\n * This method only decides and rewrites: the retry itself belongs to the host's provider policy.\n * @param reason - the finish reason the adapter is about to yield.\n * @returns a retryable `error` reason, or the given reason untouched.\n */\n resolve(reason: FinishReason): FinishReason {\n if (!this.#enabled || !isMarkupOnlyStop(reason, { sawToolCall: this.#sawToolCall, text: this.#text() })) {\n return reason;\n }\n this.#notify();\n return { kind: 'error', failure: { code: EMPTY_RESPONSE_CODE, message: EMPTY_TURN_MESSAGE } };\n }\n\n /** Report one rewrite to the telemetry hook; monitoring must never break the stream. */\n #notify(): void {\n try {\n this.#onEmptyTurn?.(this.inspect());\n } catch {\n // A counter or logger failure is not a model failure.\n }\n }\n\n /** Closed-block text wins over deltas, so a protocol that sends both is not double-counted. */\n #text(): string {\n return this.#blockText.length > 0 ? this.#blockText : this.#deltaText;\n }\n\n /** Same precedence rule for the reasoning channel. */\n #reasoning(): string {\n return this.#blockReasoning.length > 0 ? this.#blockReasoning : this.#deltaReasoning;\n }\n}\n", "/**\n * \u4E09\u79CD\u7EBF\u534F\u8BAE\u7684\u516C\u5F00\u5165\u53E3\u3002\n *\n * \u6A21\u578B\u53D1\u73B0\uFF08OpenAI `GET /models`\uFF09\u4E0E\u63A8\u7406\u534F\u8BAE\u89E3\u8026\uFF1A\u65E0\u8BBA\u8FD9\u91CC\u9009\u4E2D\u54EA\u79CD\u534F\u8BAE\uFF0C\n * \u76EE\u5F55\u62C9\u53D6\u59CB\u7EC8\u8D70 OpenAI \u517C\u5BB9\u7AEF\u53E3\uFF0C\u89C1 `model-discovery.ts`\u3002\n */\n\nimport { LlmError } from '@deepseek-ai/dsh-llm';\nimport type { ApiProtocol } from '../protocol-options.js';\nimport { chatCompletions } from './chat-completions.js';\nimport { messages } from './messages.js';\nimport { responses } from './responses.js';\nimport type { Protocol } from './types.js';\n\nconst PROTOCOLS: Readonly<Record<ApiProtocol, Protocol>> = {\n 'chat-completions': chatCompletions,\n responses,\n messages,\n};\n\n/**\n * \u6309\u914D\u7F6E id \u53D6\u534F\u8BAE\u5B9E\u73B0\u3002\n *\n * @param id \u8BBE\u7F6E\u91CC\u4FDD\u5B58\u7684\u534F\u8BAE id\uFF08\u6765\u81EA\u56FA\u5B9A\u4E09\u79CD\uFF09\u3002\n * @throws {LlmError} \u914D\u7F6E\u91CC\u51FA\u73B0\u672A\u77E5 id\uFF08\u4F8B\u5982\u964D\u7EA7\u5B89\u88C5\u4FDD\u7559\u4E86\u66F4\u65B0\u7248\u672C\u7684\u8BBE\u7F6E\uFF09\u3002\n */\nexport function protocolFor(id: ApiProtocol): Protocol {\n const protocol = PROTOCOLS[id];\n if (!protocol) throw new LlmError(`\u672A\u77E5\u7684\u63A8\u7406\u534F\u8BAE\uFF1A${String(id)}`, 'INVALID_REQUEST');\n return protocol;\n}\n\nexport type { Protocol, ProtocolContext, WireRequest } from './types.js';\nexport { MESSAGES_DEFAULT_MAX_TOKENS, messagesURL } from './messages.js';\n", "/**\n * OpenAI Chat Completions \u534F\u8BAE\uFF08\u65E2\u6709\u5B9E\u73B0\u7684\u552F\u4E00\u5305\u88C5\u70B9\uFF09\u3002\n *\n * \u8BF7\u6C42\u6295\u5F71\u7EE7\u7EED\u590D\u7528 `conversion.ts` \u7684 chat \u6D88\u606F/\u5DE5\u5177\u6295\u5F71\u4E0E\u601D\u8003\u56DE\u653E\u89C4\u5219\uFF1B\n * \u6D41\u5F0F\u89E3\u6790\u7EE7\u7EED\u590D\u7528 `stream.ts#consumeSse`\uFF0C\u56E0\u6B64\u8BE5\u534F\u8BAE\u7684\u884C\u4E3A\u4E0E\u62C6\u5206\u524D\u5B8C\u5168\u4E00\u81F4\u3002\n */\n\nimport { LlmError, type StreamChunk } from '@deepseek-ai/dsh-llm';\nimport { chatMessages, chatTools } from '../conversion.js';\nimport { consumeSse } from '../stream.js';\nimport { streamHeaders } from './headers.js';\nimport { inferenceEndpoint } from '../protocol-options.js';\nimport type { Protocol, ProtocolContext, WireRequest } from './types.js';\n\n/** \u6784\u9020 Chat Completions \u8BF7\u6C42\u3002 */\nexport function buildChatCompletionsRequest(ctx: ProtocolContext): WireRequest {\n const { options, model } = ctx;\n const replayReasoning = model.id.startsWith('deepseek-') || model.id.startsWith('kimi-');\n const messages = chatMessages(options, ref => ctx.images.get(ref.attachmentId), replayReasoning);\n const tools = chatTools(options);\n const body: Record<string, unknown> = { model: model.id, messages, stream: true, stream_options: { include_usage: true } };\n if (tools) body.tools = tools;\n if (options.temperature !== undefined) body.temperature = options.temperature;\n if (ctx.topP !== undefined) body.top_p = ctx.topP;\n if (options.maxTokens !== undefined) {\n if (!Number.isSafeInteger(options.maxTokens) || options.maxTokens <= 0) throw new LlmError('maxTokens \u5FC5\u987B\u662F\u6B63\u6574\u6570', 'INVALID_REQUEST');\n body.max_tokens = options.maxTokens;\n }\n if (options.reasoningEffort !== undefined) body.reasoning_effort = options.reasoningEffort;\n if (options.stop?.length) body.stop = options.stop;\n return { url: inferenceEndpoint(ctx.baseURL, 'chat-completions'), headers: streamHeaders(ctx.apiKey), body };\n}\n\nexport const chatCompletions: Protocol = {\n id: 'chat-completions',\n build: buildChatCompletionsRequest,\n stream(body: ReadableStream<Uint8Array>, signal: AbortSignal, idleMs: number): AsyncIterable<StreamChunk> {\n return consumeSse(body, signal, idleMs);\n },\n};\n", "/**\n * \u4E09\u79CD\u63A8\u7406\u534F\u8BAE\u5171\u7528\u7684\u8BF7\u6C42\u5934\u3002\n *\n * \u6BCF\u4E2A\u4E0A\u6E38\u8BF7\u6C42\u90FD\u5FC5\u987B\u643A\u5E26\u5E94\u7528\u5F52\u56E0\u5934\uFF08`attributionHeaders()`\uFF09\uFF1B\u9274\u6743\u4E00\u5F8B\u8D70\n * `Authorization: Bearer`\u2014\u2014CoRouter \u5B98\u65B9\u7AD9\u70B9\u5BF9 OpenAI \u517C\u5BB9\u8C03\u7528\u4E0E Claude Code\n * \uFF08`ANTHROPIC_AUTH_TOKEN`\uFF09\u90FD\u4F7F\u7528\u8BE5\u5934\uFF0C\u56E0\u6B64 Messages \u534F\u8BAE\u4E0D\u989D\u5916\u53D1\u9001\u7B2C\u4E8C\u4E2A\u5BC6\u94A5\u5934\u3002\n */\n\nimport { attributionHeaders } from '@deepseek-ai/dsh-llm';\n\n/**\n * \u6784\u9020\u6D41\u5F0F\u63A8\u7406\u8BF7\u6C42\u5934\u3002\n *\n * @param apiKey \u5DF2\u7531\u9002\u914D\u5668\u6821\u9A8C\u53EF\u7528\u7684\u51ED\u636E\uFF1B\u6B64\u5904\u53EA\u505A\u62FC\u63A5\uFF0C\u4E0D\u56DE\u663E\u3001\u4E0D\u8BB0\u5F55\u3002\n * @param extra \u534F\u8BAE\u4E13\u5C5E\u5934\uFF08\u5982 `anthropic-version`\uFF09\u3002\n */\nexport function streamHeaders(apiKey: string, extra: Readonly<Record<string, string>> = {}): Record<string, string> {\n return {\n ...attributionHeaders(),\n authorization: `Bearer ${apiKey}`,\n 'content-type': 'application/json',\n accept: 'text/event-stream',\n ...extra,\n };\n}\n", "/**\n * Anthropic Messages \u534F\u8BAE\u3002\n *\n * \u7AEF\u70B9\uFF1ABase URL \u53EF\u4EE5\u662F\u7F51\u5173\u6839\uFF08\u5B98\u65B9 `ANTHROPIC_BASE_URL` \u5F62\u5F0F\uFF09\u6216\u5DF2\u5E26 `/v1` \u7684\u63A8\u7406 Base\uFF0C\n * \u4E24\u79CD\u90FD\u4F1A\u8865\u6210 `<base>/v1/messages`\u3002\u9274\u6743\u6CBF\u7528 CoRouter \u5B98\u65B9 Claude Code \u914D\u7F6E\u91CC\u7684\n * `Authorization: Bearer`\uFF0C\u5916\u52A0\u6807\u51C6 `anthropic-version`\uFF1B\u4E0D\u989D\u5916\u53D1\u9001\u7B2C\u4E8C\u4E2A\u5BC6\u94A5\u5934\u3002\n *\n * \u4E0D\u652F\u6301\u9879\u6309\u663E\u5F0F\u5931\u8D25\u5904\u7406\uFF0C\u4E0D\u9759\u9ED8\u4E22\u5F03\uFF1A\n * - \u8BF7\u6C42\u65E0 `max_tokens` \u65F6\u7528\u4FDD\u5B88\u9ED8\u8BA4 4096\uFF08\u9002\u914D\u5668\u5143\u6570\u636E\u540C\u6B65\u8BE5\u9ED8\u8BA4\u503C\uFF0C\u7528\u6237\u53EF\u6309\u6A21\u578B\u8986\u76D6\uFF09\uFF1B\n * - `reasoningEffort` \u6309\u73B0\u4EE3 Messages \u6807\u51C6\u6295\u5F71\u4E3A `thinking: {type:'adaptive'}` +\n * `output_config.effort`\uFF1B`none` \u6295\u5F71\u4E3A `thinking: {type:'disabled'}`\uFF1B`minimal`/`ultra`\n * \u7B49\u6CA1\u6709\u5BF9\u5E94 effort \u7684\u6863\u4F4D\u629B UNSUPPORTED_OPTION\uFF1B\n * - `temperature`/`top_p` \u7B49\u91C7\u6837\u53C2\u6570\u539F\u6837\u900F\u4F20\uFF0C\u5176\u53D6\u503C\u9650\u5236\uFF08\u53EA\u9488\u5BF9\u7279\u5B9A Claude \u4EE3\u9645\uFF09\u4E0E\n * \u300C\u4EC5\u63A5\u53D7 enabled + budget_tokens \u7684 legacy \u6A21\u578B\u300D\u80FD\u5426\u4F7F\u7528\uFF0C\u90FD\u7531\u4E0A\u6E38\u6309\u5B9E\u9645\u6A21\u578B\u5224\u5B9A\uFF0C\n * \u672C\u6A21\u5757\u4E0D\u505A\u672C\u5730\u63A8\u65AD\uFF0C\u800C\u662F\u628A\u4E0A\u6E38\u62D2\u7EDD\u5206\u7C7B\u4E0A\u62A5\uFF1B\n * - \u5386\u53F2 assistant \u7684 reasoning \u5757\u6CA1\u6709 Anthropic \u7B7E\u540D\uFF0C**\u4E0D\u56DE\u653E**\uFF08\u4F2A\u9020\u7B7E\u540D\u4F1A\u6C61\u67D3\u4E0A\u4E0B\u6587\uFF09\uFF0C\n * \u53EA\u628A\u672C\u8F6E `thinking_delta` \u6620\u5C04\u6210 reasoning \u8F93\u51FA\u5757\u3002\n */\n\nimport {\n LlmError, ToolCallId,\n type FinishReason, type StreamChunk, type TokenUsage,\n} from '@deepseek-ai/dsh-llm';\nimport { record } from '../util.js';\nimport { anthropicError } from './errors.js';\nimport { streamHeaders } from './headers.js';\nimport { inferenceEndpoint } from '../protocol-options.js';\nimport { projectContent } from './parts.js';\nimport { sseFrames } from './sse.js';\nimport { anthropicUsage } from './usage.js';\nimport type { Protocol, ProtocolContext, WireRequest } from './types.js';\n\n/** \u672A\u663E\u5F0F\u7ED9\u51FA `max_tokens` \u65F6\u7684\u4FDD\u5B88\u9ED8\u8BA4\u503C\uFF08\u4E0E\u9002\u914D\u5668\u5143\u6570\u636E\u4E00\u81F4\uFF09\u3002 */\nexport const MESSAGES_DEFAULT_MAX_TOKENS = 4096;\n/** Anthropic \u8981\u6C42\u7684\u7248\u672C\u5934\uFF1B\u7F3A\u7701\u4F1A 400\uFF0C\u5373\u4F7F\u672C\u7F51\u5173\u6CE8\u91CA\u91CC\u672A\u51FA\u73B0\u4E5F\u5FC5\u987B\u53D1\u9001\u3002 */\nconst ANTHROPIC_VERSION = '2023-06-01';\n/**\n * \u73B0\u4EE3 Messages \u6807\u51C6\u91CC `output_config.effort` \u7684\u5408\u6CD5\u6863\u4F4D\u3002\n *\n * \u73B0\u884C\u53C2\u6570\u9875\u628A `low | medium | high | xhigh | max` \u5217\u4E3A effort \u53D6\u503C\uFF1B`minimal` \u4E0E\u76EE\u5F55\u91CC\n * \u7684\u6269\u5C55\u6863\u4F4D\uFF08\u5982 `ultra`\uFF09\u6CA1\u6709\u5BF9\u5E94\u503C\uFF0C\u6309\u4E0D\u652F\u6301\u663E\u5F0F\u62D2\u7EDD\uFF0C\u800C\u4E0D\u662F\u6620\u5C04\u5230\u522B\u7684\u6863\u4F4D\u3002\n */\nconst THINKING_EFFORTS: readonly string[] = ['low', 'medium', 'high', 'xhigh', 'max'];\n\nconst DATA_URL = /^data:([^;,]+);base64,(.*)$/su;\n\ntype ContentPart = Record<string, unknown>;\n\n/** \u7F51\u5173\u6839\u6216 `/v1` Base \u90FD\u8865\u6210 `/v1/messages`\u3002 */\nexport function messagesURL(baseURL: string): string {\n return inferenceEndpoint(baseURL, 'messages');\n}\n\nfunction imagePart(url: string): ContentPart {\n const match = DATA_URL.exec(url);\n return match?.[1] && match[2]\n ? { type: 'image', source: { type: 'base64', media_type: match[1], data: match[2] } }\n : { type: 'image', source: { type: 'url', url } };\n}\n\n/**\n * \u5386\u53F2\u5DE5\u5177\u8C03\u7528\u53C2\u6570 \u2192 `tool_use.input`\u3002\n *\n * Anthropic \u8981\u6C42\u5BF9\u8C61\u3002\u7A7A\u53C2\u6570\u6309 `{}` \u5904\u7406\uFF08\u65E0\u53C2\u6570\u8C03\u7528\u7684\u6B63\u5E38\u5F62\u6001\uFF09\uFF1B\u5B57\u7B26\u4E32\u4E0D\u662F\u5408\u6CD5 JSON \u6216\n * \u89E3\u6790\u7ED3\u679C\u4E0D\u662F\u5BF9\u8C61\u65F6**\u663E\u5F0F\u5931\u8D25**\u2014\u2014\u4F2A\u9020\u7A7A\u53C2\u6570\u4F1A\u6539\u53D8\u5386\u53F2\u8C03\u7528\u7684\u542B\u4E49\uFF0C\u6BD4\u62D2\u7EDD\u8FD9\u4E00\u8F6E\u66F4\u7CDF\u3002\n */\nfunction toolInput(argumentsText: string): Record<string, unknown> {\n if (argumentsText.trim() === '') return {};\n let parsed: unknown;\n try {\n parsed = JSON.parse(argumentsText);\n } catch {\n throw new LlmError('\u5386\u53F2\u5DE5\u5177\u8C03\u7528\u53C2\u6570\u4E0D\u662F\u5408\u6CD5 JSON\uFF0C\u65E0\u6CD5\u6295\u5F71\u4E3A Anthropic tool_use.input', 'INVALID_REQUEST');\n }\n if (!record(parsed)) throw new LlmError('\u5386\u53F2\u5DE5\u5177\u8C03\u7528\u53C2\u6570\u4E0D\u662F JSON \u5BF9\u8C61\uFF0C\u65E0\u6CD5\u6295\u5F71\u4E3A Anthropic tool_use.input', 'INVALID_REQUEST');\n return parsed;\n}\n\n/** \u6784\u9020 Messages \u8BF7\u6C42\u3002 */\nexport function buildMessagesRequest(ctx: ProtocolContext): WireRequest {\n const { options, model } = ctx;\n const maxTokens = options.maxTokens ?? MESSAGES_DEFAULT_MAX_TOKENS;\n if (!Number.isSafeInteger(maxTokens) || maxTokens <= 0) throw new LlmError('maxTokens \u5FC5\u987B\u662F\u6B63\u6574\u6570', 'INVALID_REQUEST');\n\n const system: string[] = [];\n const messages: { role: 'user' | 'assistant'; content: ContentPart[] }[] = [];\n const lookup = ctx.images.size ? (ref: { attachmentId: string }) => ctx.images.get(ref.attachmentId) : undefined;\n let results: ContentPart[] = [];\n let lifted: string[] = [];\n const flushResults = (): void => {\n if (results.length) {\n messages.push({ role: 'user', content: results });\n results = [];\n }\n };\n const flushLifted = (): void => {\n flushResults();\n if (lifted.length) {\n messages.push({\n role: 'user',\n content: [{ type: 'text', text: '(Image content from the preceding tool result.)' }, ...lifted.map(imagePart)],\n });\n lifted = [];\n }\n };\n\n for (const message of options.messages) {\n // \u6574\u6BB5\u8FDE\u7EED tool \u7ED3\u679C\u5148\u6536\u96C6\uFF0C\u7B49\u89D2\u8272\u5207\u6362\u65F6\u518D\u4E00\u6B21\u6027\u843D\u76D8\uFF1A\u8FD9\u6837\u5E76\u884C\u5DE5\u5177\u7ED3\u679C\u540C\u5C5E\u4E00\u6761 user \u6D88\u606F\uFF0C\n // \u63D0\u5347\u7684\u56FE\u7247\u4E5F\u6392\u5728\u8FD9\u4E00\u7EC4\u4E4B\u540E\uFF0C\u4E0D\u4F1A\u63D2\u8FDB\u5E76\u884C\u7ED3\u679C\u4E2D\u95F4\u3002\n if (message.role !== 'tool') flushLifted();\n const projected = projectContent(message.content, message.role === 'user' || message.role === 'tool' ? lookup : undefined);\n switch (message.role) {\n case 'system':\n case 'developer':\n if (projected.text) system.push(projected.text);\n break;\n case 'user': {\n const content: ContentPart[] = [\n ...(projected.text ? [{ type: 'text', text: projected.text }] : []),\n ...projected.images.map(imagePart),\n ];\n if (content.length) messages.push({ role: 'user', content });\n break;\n }\n case 'assistant': {\n const content: ContentPart[] = [];\n if (projected.text) content.push({ type: 'text', text: projected.text });\n for (const block of message.content) {\n if (block.type === 'tool-call') content.push({ type: 'tool_use', id: block.id, name: block.name, input: toolInput(block.arguments) });\n }\n if (content.length) messages.push({ role: 'assistant', content });\n break;\n }\n case 'tool': {\n results.push({\n type: 'tool_result',\n tool_use_id: message.toolCallId,\n content: projected.text || (projected.images.length ? '(Image content follows in the next user message.)' : ''),\n });\n lifted.push(...projected.images);\n break;\n }\n }\n }\n flushLifted();\n if (options.system?.trim()) system.unshift(options.system);\n\n const body: Record<string, unknown> = { model: model.id, max_tokens: maxTokens, messages, stream: true };\n if (system.length) body.system = system.join('\\n\\n');\n if (options.tools?.length) body.tools = options.tools.map(tool => ({ name: tool.name, description: tool.description, input_schema: tool.parameters }));\n if (options.temperature !== undefined) body.temperature = options.temperature;\n if (ctx.topP !== undefined) body.top_p = ctx.topP;\n if (options.stop?.length) body.stop_sequences = options.stop;\n if (options.reasoningEffort !== undefined) {\n // \u601D\u8003\u63A7\u5236\u6309\u73B0\u4EE3 Messages \u6807\u51C6\u6295\u5F71\uFF1A`thinking.type.adaptive` + `output_config.effort`\u3002\n const effort = String(options.reasoningEffort);\n if (effort === 'none') body.thinking = { type: 'disabled' };\n else if (THINKING_EFFORTS.includes(effort)) {\n body.thinking = { type: 'adaptive' };\n body.output_config = { effort };\n } else throw new LlmError(`Anthropic Messages \u534F\u8BAE\u4E0D\u63A5\u53D7\u601D\u8003\u6DF1\u5EA6\u300C${effort}\u300D`, 'UNSUPPORTED_OPTION');\n }\n // \u91C7\u6837\u53C2\u6570\uFF08temperature / top_p / stop_sequences\uFF09\u4E00\u5F8B\u6309\u8C03\u7528\u65B9\u7ED9\u5B9A\u503C\u900F\u4F20\uFF1A\u5B98\u65B9\u53C2\u6570\u9875\u628A\u8FD9\u4E9B\n // \u53D6\u503C\u9650\u5236\u9650\u5B9A\u5728\u300CClaude Opus 4.6 \u4E4B\u540E\u300D\u7684\u5177\u4F53\u6A21\u578B\u4E0A\uFF0C\u800C CoRouter \u662F\u8DE8\u6A21\u578B\u7F51\u5173\uFF1B\n // \u91C7\u6837\u517C\u5BB9\u6027\u4E0E\u300C\u4EC5\u652F\u6301 enabled + budget_tokens \u7684 legacy \u6A21\u578B\u300D\u662F\u5426\u53EF\u7528\uFF0C\u4E00\u5E76\u7531\u4E0A\u6E38\u6309\u5B9E\u9645\n // \u6A21\u578B\u5224\u5B9A\u5E76\u8FD4\u56DE\uFF0C\u672C\u6A21\u5757\u4E0D\u5728\u672C\u5730\u63A8\u65AD\uFF0C\u4E5F\u4ECE\u4E0D\u53D1\u9001 top_k\u3002\n return { url: messagesURL(ctx.baseURL), headers: streamHeaders(ctx.apiKey, { 'anthropic-version': ANTHROPIC_VERSION }), body };\n}\n\ninterface BlockState {\n /** DSH \u5757\u7D22\u5F15\uFF1B\u9996\u6B21\u4EA7\u51FA\u65F6\u5206\u914D\uFF0C\u4FDD\u8BC1 block-start \u4E25\u683C\u6309\u7D22\u5F15\u9012\u589E\u3002 */\n index: number;\n kind: 'text' | 'reasoning' | 'tool' | 'skip';\n text: string;\n id: string;\n name: string;\n args: string;\n started: boolean;\n}\n\nfunction num(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : undefined;\n}\n\n/** \u628A Messages \u7684 SSE \u4E8B\u4EF6\u7FFB\u8BD1\u6210 DSH \u6D41\u5F0F\u5757\u3002 */\nexport async function* streamMessages(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n idleMs: number,\n): AsyncGenerator<StreamChunk> {\n let nextIndex = 0;\n let count = 0;\n let finish: FinishReason | undefined;\n let stopReason: string | undefined;\n let sawTool = false;\n const blocks = new Map<number, BlockState>();\n const raw = { input: undefined as number | undefined, output: undefined as number | undefined,\n cacheRead: undefined as number | undefined, cacheWrite: undefined as number | undefined };\n let usage: TokenUsage | undefined;\n\n function stateAt(index: unknown): BlockState {\n const state = typeof index === 'number' ? blocks.get(index) : undefined;\n if (!state) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u5185\u5BB9\u5757\u7D22\u5F15\u65E0\u6548', 'INVALID_RESPONSE');\n return state;\n }\n\n function assign(state: BlockState): void {\n if (state.index < 0) {\n state.index = nextIndex++;\n count++;\n }\n }\n\n function close(): StreamChunk[] {\n const out: StreamChunk[] = [];\n for (const state of blocks.values()) {\n if (!state.started) continue;\n if (state.kind === 'text') out.push({ type: 'block-end', index: state.index, block: { type: 'text', text: state.text } });\n else if (state.kind === 'reasoning') out.push({ type: 'block-end', index: state.index, block: { type: 'reasoning', text: state.text } });\n else if (state.kind === 'tool') {\n if (!state.id || !state.name) throw new LlmError('OpenDesign\uFF1A\u5DE5\u5177\u8C03\u7528\u7F3A\u5C11\u6807\u8BC6\u6216\u540D\u79F0', 'INVALID_RESPONSE');\n out.push({ type: 'block-end', index: state.index, block: { type: 'tool-call', id: ToolCallId(state.id), name: state.name, arguments: state.args } });\n }\n }\n return out.sort((a, b) => ('index' in a ? a.index : 0) - ('index' in b ? b.index : 0));\n }\n\n function reasonFromStop(stop: string | undefined): FinishReason {\n switch (stop) {\n case 'end_turn':\n case 'stop_sequence':\n return { kind: 'stop' };\n case 'max_tokens':\n case 'model_context_window_exceeded':\n // \u4E0A\u4E0B\u6587\u7A97\u53E3\u8017\u5C3D\u540C\u6837\u662F\u622A\u65AD\uFF1A\u4FDD\u7559\u5DF2\u4EA7\u51FA\u5185\u5BB9\uFF0C\u4F46\u7EDD\u4E0D\u5F53\u4F5C\u5B8C\u6574\u56DE\u7B54\u3002\n return { kind: 'max-tokens' };\n case 'tool_use':\n return { kind: 'tool-calls' };\n case 'refusal':\n throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u62D2\u7EDD\u56DE\u7B54\uFF08refusal\uFF09', 'INVALID_RESPONSE');\n case 'pause_turn':\n throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u6682\u505C\u8F6E\u6B21\uFF0C\u9700\u91CD\u65B0\u53D1\u8D77\u8BF7\u6C42', 'INVALID_RESPONSE');\n default:\n throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u54CD\u5E94\u88AB\u8FC7\u6EE4\u6216\u5F02\u5E38\u7EC8\u6B62', 'INVALID_RESPONSE');\n }\n }\n\n for await (const frame of sseFrames(body, signal, idleMs)) {\n let value: unknown;\n try {\n value = JSON.parse(frame.data);\n } catch {\n throw new LlmError('OpenDesign\uFF1A\u65E0\u6548\u7684\u6D41\u5F0F JSON', 'INVALID_RESPONSE');\n }\n if (!record(value)) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u4E8B\u4EF6\u4E0D\u662F\u5BF9\u8C61', 'INVALID_RESPONSE');\n const type = typeof value.type === 'string' && value.type !== '' ? value.type : frame.event;\n if (!type) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u4E8B\u4EF6\u7F3A\u5C11\u7C7B\u578B', 'INVALID_RESPONSE');\n const out: StreamChunk[] = [];\n\n switch (type) {\n case 'message_start': {\n const message = record(value.message) ? value.message : {};\n const counters = record(message.usage) ? message.usage : {};\n raw.input = num(counters.input_tokens) ?? raw.input;\n raw.output = num(counters.output_tokens) ?? raw.output;\n raw.cacheRead = num(counters.cache_read_input_tokens) ?? raw.cacheRead;\n raw.cacheWrite = num(counters.cache_creation_input_tokens) ?? raw.cacheWrite;\n break;\n }\n case 'content_block_start': {\n const index = value.index;\n if (typeof index !== 'number' || !Number.isSafeInteger(index) || index < 0) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u5185\u5BB9\u5757\u7D22\u5F15\u65E0\u6548', 'INVALID_RESPONSE');\n const block = record(value.content_block) ? value.content_block : {};\n const kind = typeof block.type === 'string' ? block.type : '';\n const state: BlockState = { index: -1, kind: 'skip', text: '', id: '', name: '', args: '', started: false };\n if (kind === 'text') state.kind = 'text';\n else if (kind === 'thinking') state.kind = 'reasoning';\n else if (kind === 'tool_use') state.kind = 'tool';\n if (state.kind === 'tool') {\n state.id = typeof block.id === 'string' ? block.id : '';\n state.name = typeof block.name === 'string' ? block.name : '';\n sawTool = true;\n }\n if (state.kind === 'text' && typeof block.text === 'string' && block.text !== '') state.text = block.text;\n if (state.kind === 'reasoning' && typeof block.thinking === 'string' && block.thinking !== '') state.text = block.thinking;\n blocks.set(index, state);\n // \u5DE5\u5177\u5757\u4E00\u5F00\u59CB\u5C31\u6709 id/name\uFF0C\u5148\u53D1 block-start \u4E0E\u7A7A\u589E\u91CF\uFF0C\u540E\u7EED\u53EA\u8FFD\u52A0\u53C2\u6570\u5206\u7247\u3002\n if (state.kind === 'tool') {\n assign(state);\n state.started = true;\n out.push({ type: 'block-start', index: state.index, blockType: 'tool-call' });\n if (state.id) out.push({ type: 'tool-call-delta', index: state.index, id: ToolCallId(state.id), ...(state.name ? { name: state.name } : {}), argumentsDelta: '' });\n } else if ((state.kind === 'text' || state.kind === 'reasoning') && state.text !== '') {\n // \u5C11\u6570\u7F51\u5173\u628A\u9996\u6BB5\u5185\u5BB9\u76F4\u63A5\u653E\u8FDB content_block_start\uFF0C\u540E\u7EED\u6CA1\u6709 delta\uFF1A\n // \u8FD9\u91CC\u7ACB\u5373\u5F00\u5757\u5E76\u53D1\u51FA\u9996\u6BB5\u589E\u91CF\uFF0C\u907F\u514D\u201C\u6709\u5185\u5BB9\u5374\u6309\u7A7A\u54CD\u5E94\u5904\u7406\u201D\u3002\n assign(state);\n state.started = true;\n out.push({ type: 'block-start', index: state.index, blockType: state.kind === 'text' ? 'text' : 'reasoning' });\n out.push(state.kind === 'text'\n ? { type: 'text-delta', index: state.index, text: state.text }\n : { type: 'reasoning-delta', index: state.index, text: state.text });\n }\n break;\n }\n case 'content_block_delta': {\n const state = stateAt(value.index);\n const delta = record(value.delta) ? value.delta : {};\n const deltaType = typeof delta.type === 'string' ? delta.type : '';\n if (deltaType === 'text_delta') {\n const text = typeof delta.text === 'string' ? delta.text : '';\n if (!text) break;\n assign(state);\n if (!state.started) {\n state.started = true;\n out.push({ type: 'block-start', index: state.index, blockType: 'text' });\n }\n state.text += text;\n out.push({ type: 'text-delta', index: state.index, text });\n break;\n }\n if (deltaType === 'thinking_delta') {\n const text = typeof delta.thinking === 'string' ? delta.thinking : '';\n if (!text) break;\n assign(state);\n if (!state.started) {\n state.started = true;\n out.push({ type: 'block-start', index: state.index, blockType: 'reasoning' });\n }\n state.text += text;\n out.push({ type: 'reasoning-delta', index: state.index, text });\n break;\n }\n if (deltaType === 'input_json_delta') {\n if (state.kind !== 'tool') throw new LlmError('OpenDesign\uFF1A\u5DE5\u5177\u53C2\u6570\u5206\u7247\u843D\u5728\u975E\u5DE5\u5177\u5757\u4E0A', 'INVALID_RESPONSE');\n const part = typeof delta.partial_json === 'string' ? delta.partial_json : '';\n state.args += part;\n if (state.id) out.push({ type: 'tool-call-delta', index: state.index, id: ToolCallId(state.id), ...(state.name ? { name: state.name } : {}), argumentsDelta: part });\n break;\n }\n // signature_delta / citations_delta \u4E0D\u8FDB\u5165 DSH \u5757\uFF1A\u7B7E\u540D\u4E0D\u53EF\u56DE\u653E\uFF0C\u5F15\u7528\u5757\u65E0\u5BF9\u5E94\u5185\u5BB9\u7C7B\u578B\u3002\n break;\n }\n case 'message_delta': {\n const delta = record(value.delta) ? value.delta : {};\n if (typeof delta.stop_reason === 'string') stopReason = delta.stop_reason;\n const counters = record(value.usage) ? value.usage : {};\n raw.output = num(counters.output_tokens) ?? raw.output;\n raw.input = num(counters.input_tokens) ?? raw.input;\n raw.cacheRead = num(counters.cache_read_input_tokens) ?? raw.cacheRead;\n raw.cacheWrite = num(counters.cache_creation_input_tokens) ?? raw.cacheWrite;\n break;\n }\n case 'message_stop': {\n const reason = reasonFromStop(stopReason);\n // \u6240\u6709\u6709\u6548\u6027\u68C0\u67E5\u90FD\u5FC5\u987B\u5728 finish \u4E4B\u524D\uFF1A\u6D88\u8D39\u8005\u770B\u5230 finish \u5F80\u5F80\u7ACB\u5373 return\uFF0C\n // \u653E\u5728\u5FAA\u73AF\u4E4B\u540E\u7684\u6821\u9A8C\u6C38\u8FDC\u4E0D\u4F1A\u6267\u884C\uFF0C\u7A7A\u54CD\u5E94/\u7F3A\u5DE5\u5177\u5757\u5C31\u4F1A\u88AB\u5F53\u6210\u6210\u529F\u3002\n if (reason.kind === 'tool-calls' && !sawTool) throw new LlmError('OpenDesign\uFF1A\u54CD\u5E94\u58F0\u660E\u5DE5\u5177\u8C03\u7528\uFF0C\u4F46\u672A\u8FD4\u56DE\u4EFB\u4F55\u5DE5\u5177\u5757', 'INVALID_RESPONSE');\n if (!count) throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u8FD4\u56DE\u7A7A\u54CD\u5E94', 'EMPTY_RESPONSE');\n usage = anthropicUsage(raw) ?? usage;\n out.push(...close());\n if (usage) out.push({ type: 'usage', usage });\n finish = reason;\n out.push({ type: 'finish', reason });\n break;\n }\n case 'error':\n throw anthropicError(undefined, value);\n case 'ping':\n default:\n break;\n }\n\n for (const chunk of out) yield chunk;\n if (finish) break;\n }\n\n signal.throwIfAborted();\n if (!finish) throw new LlmError('OpenDesign\uFF1A\u54CD\u5E94\u6D41\u63D0\u524D\u4E2D\u65AD\uFF0C\u672A\u6536\u5230\u7ED3\u675F\u4E8B\u4EF6', 'INVALID_RESPONSE');\n}\n\nexport const messages: Protocol = {\n id: 'messages',\n build: buildMessagesRequest,\n stream: streamMessages,\n};\n", "/**\n * \u6D88\u606F\u5185\u5BB9\u7684\u6A21\u6001\u6295\u5F71\uFF08Responses / Messages \u5171\u7528\uFF09\u3002\n *\n * \u4E0E Chat Completions \u7684 `conversion.ts#parts` \u4FDD\u6301\u540C\u4E00\u8BED\u4E49\uFF1A\u6587\u672C\u76F4\u51FA\uFF0C\u53EF\u89E3\u6790\u7684\u56FE\u7247\u53D8\u6210\n * \u56FE\u7247 URL\uFF0C\u65E0\u6CD5\u89E3\u6790\u6216\u5DF2 offload \u7684\u56FE\u7247\u9000\u5316\u4E3A\u547D\u540D\u5360\u4F4D\u6587\u672C\uFF0C\u539F\u59CB\u6587\u4EF6\u53E5\u67C4\u76F4\u63A5\u62D2\u7EDD\u3002\n */\n\nimport { LlmError, textOnlyImageText, type ContentBlock } from '@deepseek-ai/dsh-llm';\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';\n\n/** \u56FE\u7247\u9644\u4EF6 \u2192 \u8BF7\u6C42\u4F53\u53EF\u7528\u7684 URL\uFF08\u901A\u5E38\u662F data URL\uFF09\u3002 */\nexport type ImageLookup = (ref: ImageAttachmentRef) => string | undefined;\n\n/** \u4E00\u6BB5\u6D88\u606F\u6295\u5F71\u540E\u7684\u6587\u672C\u4E0E\u56FE\u7247\u3002 */\nexport interface ProjectedContent {\n text: string;\n images: string[];\n}\n\n/**\n * \u6295\u5F71\u4E00\u4E2A\u6D88\u606F\u7684\u6587\u672C\u4E0E\u56FE\u7247\u3002\n *\n * @param blocks \u6D88\u606F\u5185\u5BB9\u5757\u3002\n * @param image \u56FE\u7247\u89E3\u6790\u5668\uFF1B\u672A\u63D0\u4F9B\u65F6\u6240\u6709\u56FE\u7247\u9000\u5316\u4E3A\u5360\u4F4D\u6587\u672C\u3002\n */\nexport function projectContent(blocks: readonly ContentBlock[], image?: ImageLookup): ProjectedContent {\n let text = '';\n const images: string[] = [];\n for (const block of blocks) {\n switch (block.type) {\n case 'text':\n text += block.text;\n break;\n case 'image': {\n const url = block.offloaded ? undefined : image?.(block.attachment);\n if (url) images.push(url);\n else text += `${text ? '\\n' : ''}${textOnlyImageText(block.attachment)}`;\n break;\n }\n case 'file':\n throw new LlmError('\u539F\u59CB\u6587\u4EF6\u672A\u88AB\u5BBF\u4E3B\u6295\u5F71\u4E3A\u6587\u672C\u53E5\u67C4', 'UNSUPPORTED_OPTION');\n // \u5DE5\u5177\u5B9A\u4E49\u5DF2\u7531 Core \u7269\u5316\u8FDB options.tools\uFF1B\u5DE5\u5177\u66F4\u65B0\u5757\u53EA\u5BF9\u58F0\u660E in-history \u7684\u8DEF\u7531\u6709\u610F\u4E49\u3002\n default:\n break;\n }\n }\n return { text, images };\n}\n", "/**\n * usage \u5F52\u4E00\u5316\uFF1A\u628A\u4E0A\u6E38\u8BA1\u6570\u6298\u7B97\u6210 DSH \u7684**\u4E0D\u76F8\u4EA4**\u53E3\u5F84\u3002\n *\n * `TokenUsage.inputTokens` \u53EA\u8BA1\u672A\u7F13\u5B58\u8F93\u5165\uFF1B\u7F13\u5B58\u8BFB\u53D6/\u5199\u5165\u5355\u72EC\u4E0A\u62A5\uFF0C\u4E09\u8005\u76F8\u52A0\u624D\u662F\u8BA1\u8D39\u8F93\u5165\u3002\n * \u4E24\u5957\u4E0A\u6E38\u53E3\u5F84\u4E0D\u540C\uFF0C\u5FC5\u987B\u5206\u5F00\u5904\u7406\uFF1A\n * - OpenAI\uFF08Chat / Responses\uFF09\u7684\u8F93\u5165\u603B\u6570**\u5305\u542B**\u7F13\u5B58\u547D\u4E2D\uFF0C\u9700\u8981\u51CF\u51FA\u6765\uFF1B\n * - Anthropic Messages \u7684 `input_tokens` **\u4E0D\u542B**\u7F13\u5B58\u8BFB\u53D6\u4E0E\u7F13\u5B58\u5199\u5165\uFF0C\u76F4\u63A5\u5BF9\u5E94\u3002\n *\n * \u4EFB\u4F55\u975E\u6CD5\u6216\u81EA\u76F8\u77DB\u76FE\u7684\u7F13\u5B58\u8BA1\u6570\u90FD\u4F1A\u88AB\u4E22\u5F03\uFF0C\u800C\u4E0D\u662F\u4EA7\u751F\u8D1F\u6570\u6216\u51ED\u7A7A\u7684\u8F93\u5165\u91CF\u3002\n */\n\nimport type { TokenUsage } from '@deepseek-ai/dsh-llm';\n\n/** \u4E0A\u6E38\u539F\u59CB\u8BA1\u6570\uFF08\u7F3A\u7701\u6216\u975E\u6CD5\u4E00\u5F8B\u89C6\u4E3A\u672A\u77E5\uFF09\u3002 */\nexport interface RawUsage {\n input?: number | undefined;\n output?: number | undefined;\n cacheRead?: number | undefined;\n cacheWrite?: number | undefined;\n reasoning?: number | undefined;\n total?: number | undefined;\n}\n\nfunction valid(value: number | undefined): value is number {\n return value !== undefined && Number.isFinite(value) && value >= 0;\n}\n\n/**\n * OpenAI \u53E3\u5F84\uFF1A`input` \u542B\u7F13\u5B58\u547D\u4E2D\u3002\n *\n * @param raw \u4E0A\u6E38\u8BA1\u6570\u3002\n * @returns \u5F52\u4E00\u5316 usage\uFF1B\u8F93\u5165\u6216\u8F93\u51FA\u7F3A\u5931\u3001\u4E3A\u8D1F\u65F6\u8FD4\u56DE undefined\u3002\n */\nexport function openAiUsage(raw: RawUsage): TokenUsage | undefined {\n const input = raw.input, output = raw.output;\n if (!valid(input) || !valid(output)) return undefined;\n const read = valid(raw.cacheRead) ? raw.cacheRead : 0;\n const write = valid(raw.cacheWrite) ? raw.cacheWrite : 0;\n const cached = read + write <= input;\n const reasoning = valid(raw.reasoning) && raw.reasoning <= output ? raw.reasoning : undefined;\n return {\n inputTokens: cached ? input - read - write : input,\n outputTokens: output,\n totalTokens: input + output,\n ...(cached && read > 0 ? { cacheReadTokens: read } : {}),\n ...(cached && write > 0 ? { cacheWriteTokens: write } : {}),\n ...(reasoning !== undefined ? { reasoningTokens: reasoning } : {}),\n };\n}\n\n/**\n * Anthropic \u53E3\u5F84\uFF1A`input` \u4E0D\u542B\u7F13\u5B58\uFF0C\u7F13\u5B58\u8BFB\u53D6/\u5199\u5165\u662F\u72EC\u7ACB\u8BA1\u6570\u3002\n *\n * @param raw \u4E0A\u6E38\u8BA1\u6570\u3002\n * @returns \u5F52\u4E00\u5316 usage\uFF1B\u8F93\u5165\u6216\u8F93\u51FA\u7F3A\u5931\u3001\u4E3A\u8D1F\u65F6\u8FD4\u56DE undefined\u3002\n */\nexport function anthropicUsage(raw: RawUsage): TokenUsage | undefined {\n const input = raw.input, output = raw.output;\n if (!valid(input) || !valid(output)) return undefined;\n const read = valid(raw.cacheRead) ? raw.cacheRead : undefined;\n const write = valid(raw.cacheWrite) ? raw.cacheWrite : undefined;\n const reasoning = valid(raw.reasoning) && raw.reasoning <= output ? raw.reasoning : undefined;\n const total = valid(raw.total) ? raw.total : input + (read ?? 0) + (write ?? 0) + output;\n return {\n inputTokens: input,\n outputTokens: output,\n totalTokens: total,\n ...(read !== undefined && read > 0 ? { cacheReadTokens: read } : {}),\n ...(write !== undefined && write > 0 ? { cacheWriteTokens: write } : {}),\n ...(reasoning !== undefined ? { reasoningTokens: reasoning } : {}),\n };\n}\n", "/**\n * OpenAI Responses \u534F\u8BAE\uFF08\u65E0\u72B6\u6001\uFF1A`store: false` + \u6BCF\u6B21\u53D1\u9001\u5B8C\u6574 `input`\uFF09\u3002\n *\n * \u4E3A\u4EC0\u4E48\u575A\u6301\u65E0\u72B6\u6001\uFF1ADSH \u7684\u8BF7\u6C42\u662F\u4F1A\u8BDD\u65E5\u5FD7\u7684\u7EAF\u51FD\u6570\uFF0C\u9002\u914D\u5668\u4E0D\u6301\u4E45\u5316 `previous_response_id`\uFF0C\n * \u56E0\u6B64\u91CD\u653E\u3001\u91CD\u8BD5\u4E0E\u5E76\u884C\u5206\u652F\u90FD\u4E0D\u4F1A\u4F9D\u8D56\u670D\u52A1\u7AEF\u4F1A\u8BDD\uFF1B\u4EE3\u4EF7\u662F reasoning \u9879\u65E0\u6CD5\u56DE\u653E\u2014\u2014Responses\n * \u53EA\u5728\u5E26 `encrypted_content` \u65F6\u5141\u8BB8\u8DE8\u8F6E\u91CD\u653E\u63A8\u7406\u9879\uFF0C\u672C\u63D2\u4EF6\u4E0D\u4FDD\u5B58\u8BE5\u5185\u5BB9\uFF0C\u6240\u4EE5\u5386\u53F2\u63A8\u7406\u53EA\u6620\u5C04\n * \u4E3A\u672C\u8F6E\u53EF\u89C1\u7684 reasoning \u5757\uFF0C\u518D\u6B21\u8BF7\u6C42\u65F6\u4E0D\u4F1A\u4F2A\u88C5\u6210\u5DF2\u7B7E\u540D\u7684\u4E0A\u4E0B\u6587\u3002\n *\n * \u7EC8\u6B62\u8BED\u4E49\uFF08\u5B98\u65B9 `response.completed` / `response.incomplete` / `response.failed`\uFF09\uFF1A\n * - `completed`\uFF1A\u6709 `function_call` \u9879 \u2192 tool-calls\uFF0C\u5426\u5219 stop\uFF1B\n * - `incomplete`\uFF1A`max_tokens`/`max_output_tokens` \u2192 max-tokens\uFF08\u622A\u65AD**\u4E0D**\u5F53\u6210\u529F\u5168\u6587\uFF09\uFF0C\n * `content_filter` \u4E0E\u5176\u5B83\u539F\u56E0 \u2192 \u76F4\u63A5\u5931\u8D25\uFF0C\u7EDD\u4E0D\u4EA7\u51FA finish\uFF1B\n * - `failed` \u6216\u6D41\u5185 `error` \u4E8B\u4EF6 \u2192 \u6309\u56FA\u5B9A\u5206\u7C7B\u629B\u9519\uFF0C\u4E0D\u56DE\u663E\u4E0A\u6E38\u6B63\u6587\u3002\n */\n\nimport {\n LlmError, ToolCallId,\n type FinishReason, type StreamChunk, type TokenUsage,\n} from '@deepseek-ai/dsh-llm';\nimport { record } from '../util.js';\nimport { inBandError } from './errors.js';\nimport { streamHeaders } from './headers.js';\nimport { inferenceEndpoint } from '../protocol-options.js';\nimport { projectContent, type ImageLookup } from './parts.js';\nimport { sseFrames } from './sse.js';\nimport { openAiUsage } from './usage.js';\nimport type { Protocol, ProtocolContext, WireRequest } from './types.js';\n\n/**\n * Responses \u7684 `reasoning.effort` \u5B98\u65B9\u53D6\u503C\u3002\n *\n * \u6765\u6E90\uFF1AOpenAI OpenAPI \u89C4\u8303 `ReasoningEffort` \u679A\u4E3E\uFF082026-10-26 \u53D6\u81EA\n * `raw.githubusercontent.com/openai/openai-openapi/master/openapi.yaml`\uFF09\uFF1A\n * `none | minimal | low | medium | high | xhigh | max`\u3002\n * \u672C\u5730\u76EE\u5F55\u91CC\u7684\u6269\u5C55\u6863\u4F4D\uFF08\u5982 `ultra`\uFF09\u4E0D\u5728\u5176\u4E2D\uFF0C\u6309\u4E0D\u652F\u6301\u5904\u7406\u800C\u4E0D\u662F\u539F\u6837\u900F\u4F20\u3002\n */\nconst REASONING_EFFORTS: readonly string[] = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'];\n\ntype InputPart = { type: 'input_text'; text: string } | { type: 'input_image'; image_url: string; detail: 'auto' };\n\nfunction userContent(text: string, images: readonly string[]): string | InputPart[] {\n if (!images.length) return text;\n return [\n ...(text ? [{ type: 'input_text' as const, text }] : []),\n ...images.map(url => ({ type: 'input_image' as const, image_url: url, detail: 'auto' as const })),\n ];\n}\n\n/**\n * \u6784\u9020 Responses \u8BF7\u6C42\u3002\n *\n * \u6D88\u606F\u6295\u5F71\uFF1Asystem/developer \u6587\u672C\u8FDB `instructions`\uFF08DSH \u672A\u58F0\u660E in-history \u7CFB\u7EDF\u63D0\u793A\u66F4\u65B0\uFF0C\n * \u5B8C\u6574\u7CFB\u7EDF\u63D0\u793A\u6BCF\u8F6E\u90FD\u5728\u5F00\u5934\uFF0C\u5408\u5E76\u540E\u8BED\u4E49\u4E0D\u53D8\uFF09\uFF1Bassistant \u6587\u672C + `function_call` \u9879\uFF1B\n * tool \u7ED3\u679C\u53D8 `function_call_output`\uFF0C\u5176\u4E2D\u7684\u56FE\u7247\u63D0\u5347\u5230\u7D27\u968F\u5176\u540E\u7684 user \u8F93\u5165\u9879\u3002\n */\nexport function buildResponsesRequest(ctx: ProtocolContext): WireRequest {\n const { options, model } = ctx;\n const instructions: string[] = [];\n const input: Record<string, unknown>[] = [];\n const lookup: ImageLookup | undefined = ctx.images.size ? ref => ctx.images.get(ref.attachmentId) : undefined;\n let lifted: string[] = [];\n const flushLifted = (): void => {\n if (!lifted.length) return;\n input.push({ role: 'user', content: userContent('(Image content from the preceding tool result.)', lifted) });\n lifted = [];\n };\n\n for (const message of options.messages) {\n if (message.role !== 'tool') flushLifted();\n const projected = projectContent(message.content, message.role === 'user' || message.role === 'tool' ? lookup : undefined);\n switch (message.role) {\n case 'system':\n case 'developer':\n if (projected.text) instructions.push(projected.text);\n break;\n case 'user':\n if (projected.text || projected.images.length) input.push({ role: 'user', content: userContent(projected.text, projected.images) });\n break;\n case 'assistant': {\n if (projected.text) input.push({ role: 'assistant', content: projected.text });\n for (const block of message.content) {\n if (block.type === 'tool-call') input.push({ type: 'function_call', call_id: block.id, name: block.name, arguments: block.arguments });\n }\n break;\n }\n case 'tool': {\n input.push({\n type: 'function_call_output',\n call_id: message.toolCallId,\n output: projected.text || (projected.images.length ? '(Image content follows in the next user message.)' : ''),\n });\n lifted.push(...projected.images);\n break;\n }\n }\n }\n flushLifted();\n if (options.system?.trim()) instructions.unshift(options.system);\n\n const body: Record<string, unknown> = { model: model.id, input, stream: true, store: false };\n if (instructions.length) body.instructions = instructions.join('\\n\\n');\n if (options.tools?.length) body.tools = options.tools.map(tool => ({ type: 'function', name: tool.name, description: tool.description, parameters: tool.parameters }));\n if (options.temperature !== undefined) body.temperature = options.temperature;\n if (ctx.topP !== undefined) body.top_p = ctx.topP;\n if (options.maxTokens !== undefined) {\n if (!Number.isSafeInteger(options.maxTokens) || options.maxTokens <= 0) throw new LlmError('maxTokens \u5FC5\u987B\u662F\u6B63\u6574\u6570', 'INVALID_REQUEST');\n body.max_output_tokens = options.maxTokens;\n }\n if (options.reasoningEffort !== undefined) {\n const effort = String(options.reasoningEffort);\n if (!REASONING_EFFORTS.includes(effort)) throw new LlmError(`Responses \u534F\u8BAE\u4E0D\u63A5\u53D7\u601D\u8003\u6DF1\u5EA6\u300C${effort}\u300D`, 'UNSUPPORTED_OPTION');\n // \u540C\u65F6\u8BF7\u6C42\u6458\u8981\uFF0C\u624D\u80FD\u628A\u63A8\u7406\u6620\u5C04\u6210 reasoning \u5757\uFF1B\u5426\u5219\u63A8\u7406\u4E0D\u53EF\u89C1\u3002\n body.reasoning = { effort, summary: 'auto' };\n }\n if (options.stop?.length) throw new LlmError('Responses \u534F\u8BAE\u4E0D\u652F\u6301 stop \u5E8F\u5217', 'UNSUPPORTED_OPTION');\n return { url: inferenceEndpoint(ctx.baseURL, 'responses'), headers: streamHeaders(ctx.apiKey), body };\n}\n\ninterface TextState { index: number; text: string; started: boolean }\ninterface CallState { index: number; id: string; name: string; args: string; started: boolean }\n\nfunction str(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\nfunction int(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : undefined;\n}\n\n/** \u4ECE\u7EC8\u6001 Response \u5BF9\u8C61\u91CC\u8BFB\u51FA usage\uFF08`input_tokens` \u542B\u7F13\u5B58\uFF0C\u6309 OpenAI \u53E3\u5F84\u6298\u6210\u4E0D\u76F8\u4EA4\u8BA1\u6570\uFF09\u3002 */\nfunction responseUsage(response: Record<string, unknown>): TokenUsage | undefined {\n if (!record(response.usage)) return undefined;\n const usage = response.usage;\n const input = record(usage.input_tokens_details) ? usage.input_tokens_details : {};\n const output = record(usage.output_tokens_details) ? usage.output_tokens_details : {};\n return openAiUsage({\n input: typeof usage.input_tokens === 'number' ? usage.input_tokens : undefined,\n output: typeof usage.output_tokens === 'number' ? usage.output_tokens : undefined,\n cacheRead: typeof input.cached_tokens === 'number' ? input.cached_tokens : undefined,\n cacheWrite: typeof input.cache_write_tokens === 'number' ? input.cache_write_tokens : undefined,\n reasoning: typeof output.reasoning_tokens === 'number' ? output.reasoning_tokens : undefined,\n });\n}\n\n/**\n * \u628A Responses \u7684 SSE \u4E8B\u4EF6\u7FFB\u8BD1\u6210 DSH \u6D41\u5F0F\u5757\u3002\n *\n * \u652F\u6301\u4EA4\u9519\u8F93\u51FA\u9879\uFF08\u6587\u672C / \u5DE5\u5177\u8C03\u7528 / \u63A8\u7406\uFF09\uFF0C\u6309\u9996\u6B21\u51FA\u73B0\u987A\u5E8F\u5206\u914D\u5757\u7D22\u5F15\uFF1B\n * \u53EA\u51FA\u73B0\u5728\u7EC8\u6001 `output` \u91CC\u7684\u9879\u4E5F\u4F1A\u8865\u6210\u5757\uFF0C\u907F\u514D\u201C\u7EC8\u6001\u624D\u7ED9\u5185\u5BB9\u201D\u7684\u7F51\u5173\u88AB\u8BEF\u5224\u4E3A\u7A7A\u54CD\u5E94\u3002\n */\nexport async function* streamResponses(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n idleMs: number,\n): AsyncGenerator<StreamChunk> {\n let nextIndex = 0;\n let count = 0;\n let usage: TokenUsage | undefined;\n let finish: FinishReason | undefined;\n const texts = new Map<string, TextState>();\n const reasonings = new Map<string, TextState>();\n const calls = new Map<string, CallState>();\n const keyByOutput = new Map<number, string>();\n\n function textState(key: string): TextState {\n let state = texts.get(key);\n if (!state) {\n state = { index: nextIndex++, text: '', started: false };\n texts.set(key, state);\n count++;\n }\n return state;\n }\n\n function reasoningState(key: string): TextState {\n let state = reasonings.get(key);\n if (!state) {\n state = { index: nextIndex++, text: '', started: false };\n reasonings.set(key, state);\n count++;\n }\n return state;\n }\n\n function appendText(state: TextState, delta: string, out: StreamChunk[]): void {\n if (!state.started) {\n state.started = true;\n out.push({ type: 'block-start', index: state.index, blockType: 'text' });\n }\n state.text += delta;\n out.push({ type: 'text-delta', index: state.index, text: delta });\n }\n\n function appendReasoning(state: TextState, delta: string, out: StreamChunk[]): void {\n if (!state.started) {\n state.started = true;\n out.push({ type: 'block-start', index: state.index, blockType: 'reasoning' });\n }\n state.text += delta;\n out.push({ type: 'reasoning-delta', index: state.index, text: delta });\n }\n\n function callState(key: string, item?: Record<string, unknown>, out?: StreamChunk[]): CallState {\n let call = calls.get(key);\n if (!call) {\n call = { index: nextIndex++, id: '', name: '', args: '', started: false };\n calls.set(key, call);\n count++;\n out?.push({ type: 'block-start', index: call.index, blockType: 'tool-call' });\n }\n if (item) {\n const id = str(item.call_id) ?? str(item.id);\n if (id && !call.id) call.id = id;\n const name = str(item.name);\n if (name) call.name = name;\n }\n return call;\n }\n\n /** \u53EA\u5728 id \u5DF2\u77E5\u65F6\u6295\u9012\u5DE5\u5177\u8C03\u7528\u589E\u91CF\uFF1Bid \u8FDF\u5230\u65F6\u4E00\u6B21\u6027\u8865\u4E0A\u5DF2\u7D2F\u79EF\u53C2\u6570\u3002 */\n function flushCall(call: CallState, delta: string, out: StreamChunk[]): void {\n if (!call.id) return;\n const name = call.name ? { name: call.name } : {};\n if (!call.started) {\n call.started = true;\n out.push({ type: 'tool-call-delta', index: call.index, id: ToolCallId(call.id), ...name, argumentsDelta: call.args });\n return;\n }\n out.push({ type: 'tool-call-delta', index: call.index, id: ToolCallId(call.id), ...name, argumentsDelta: delta });\n }\n\n function keyFor(value: Record<string, unknown>, kind: string, outputIndex?: number): string {\n const itemId = str(value.item_id) ?? (outputIndex === undefined ? undefined : keyByOutput.get(outputIndex));\n return `${kind}:${itemId ?? `idx:${outputIndex ?? -1}`}`;\n }\n\n /** \u53EA\u51FA\u73B0\u5728\u7EC8\u6001 `output` \u91CC\u7684\u8F93\u51FA\u9879\u8865\u6210\u5757\u3002 */\n function hydrate(output: unknown, out: StreamChunk[]): void {\n if (!Array.isArray(output)) return;\n for (const item of output) {\n if (!record(item)) continue;\n if (item.type === 'function_call') {\n const itemId = str(item.id) ?? str(item.call_id);\n const callId = str(item.call_id) ?? itemId;\n if (!callId || [...calls.values()].some(call => call.id === callId)) continue;\n const call = callState(`call:${itemId ?? callId}`, item, out);\n call.args = str(item.arguments) ?? call.args;\n flushCall(call, call.args, out);\n continue;\n }\n if (item.type === 'message') {\n const key = `text:${str(item.id) ?? 'unknown'}:0`;\n if (texts.has(key)) continue;\n const content = Array.isArray(item.content) ? item.content : [];\n const text = content\n .map(part => record(part) && (part.type === 'output_text' || part.type === 'refusal') ? str(part.text) ?? '' : '')\n .join('');\n if (!text) continue;\n appendText(textState(key), text, out);\n continue;\n }\n if (item.type === 'reasoning') {\n const key = `reasoning:${str(item.id) ?? 'unknown'}:s0`;\n if (reasonings.has(key)) continue;\n const summary = Array.isArray(item.summary) ? item.summary : [];\n const text = summary.map(part => record(part) ? str(part.text) ?? '' : '').join('');\n if (!text) continue;\n appendReasoning(reasoningState(key), text, out);\n }\n }\n }\n\n function close(): StreamChunk[] {\n const out: StreamChunk[] = [];\n for (const state of texts.values()) if (state.started) out.push({ type: 'block-end', index: state.index, block: { type: 'text', text: state.text } });\n for (const state of reasonings.values()) if (state.started) out.push({ type: 'block-end', index: state.index, block: { type: 'reasoning', text: state.text } });\n for (const call of calls.values()) {\n if (!call.id || !call.name) throw new LlmError('OpenDesign\uFF1A\u5DE5\u5177\u8C03\u7528\u7F3A\u5C11\u6807\u8BC6\u6216\u540D\u79F0', 'INVALID_RESPONSE');\n out.push({ type: 'block-end', index: call.index, block: { type: 'tool-call', id: ToolCallId(call.id), name: call.name, arguments: call.args } });\n }\n return out.sort((a, b) => ('index' in a ? a.index : 0) - ('index' in b ? b.index : 0));\n }\n\n function reasonOf(type: string, response: Record<string, unknown>): FinishReason {\n if (type === 'response.incomplete') {\n const details = record(response.incomplete_details) ? response.incomplete_details : {};\n const why = str(details.reason) ?? '';\n if (why === 'max_tokens' || why === 'max_output_tokens') return { kind: 'max-tokens' };\n if (why === 'content_filter') throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u54CD\u5E94\u88AB\u5185\u5BB9\u8FC7\u6EE4', 'INVALID_RESPONSE');\n throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u54CD\u5E94\u672A\u5B8C\u6210\uFF0C\u4E0A\u6E38\u4E2D\u65AD', 'SERVER');\n }\n const output = Array.isArray(response.output) ? response.output : [];\n return output.some(item => record(item) && item.type === 'function_call') || calls.size > 0\n ? { kind: 'tool-calls' }\n : { kind: 'stop' };\n }\n\n for await (const frame of sseFrames(body, signal, idleMs)) {\n if (frame.data.trim() === '[DONE]') break; // Responses \u4E0D\u8981\u6C42\u8BE5\u54E8\u5175\uFF0C\u5BB9\u5FCD\u7F51\u5173\u8865\u9F50\n let value: unknown;\n try {\n value = JSON.parse(frame.data);\n } catch {\n throw new LlmError('OpenDesign\uFF1A\u65E0\u6548\u7684\u6D41\u5F0F JSON', 'INVALID_RESPONSE');\n }\n if (!record(value)) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u4E8B\u4EF6\u4E0D\u662F\u5BF9\u8C61', 'INVALID_RESPONSE');\n const type = str(value.type) ?? frame.event;\n if (!type) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u4E8B\u4EF6\u7F3A\u5C11\u7C7B\u578B', 'INVALID_RESPONSE');\n const out: StreamChunk[] = [];\n\n switch (type) {\n case 'response.output_item.added': {\n const outputIndex = int(value.output_index);\n const item = record(value.item) ? value.item : undefined;\n if (item && outputIndex !== undefined) {\n // \u4E8B\u4EF6\u91CC\u7684 `item_id` \u662F\u8F93\u51FA\u9879\u81EA\u8EAB id\uFF08fc_/msg_/rs_\uFF09\uFF0C\u6240\u4EE5\u8FD9\u91CC\u4E5F\u6309 item.id \u5EFA\u7D22\u5F15\uFF1B\n // DSH \u7684\u5DE5\u5177\u8C03\u7528 id \u4ECD\u53D6 `call_id`\uFF0C\u4E24\u8005\u4E0D\u6DF7\u7528\u3002\n const itemId = str(item.id) ?? str(item.call_id);\n if (itemId) keyByOutput.set(outputIndex, itemId);\n }\n if (item?.type === 'function_call') callState(keyFor({ item: value.item }, 'call', outputIndex), item, out);\n break;\n }\n case 'response.output_text.delta':\n case 'response.output_text.done': {\n if (type.endsWith('.done')) break; // \u589E\u91CF\u5DF2\u5B8C\u6574\u91CD\u5EFA\uFF0Cdone \u53EA\u7528\u4E8E\u6821\u9A8C\n const delta = str(value.delta);\n if (!delta) break;\n const outputIndex = int(value.output_index);\n const contentIndex = int(value.content_index) ?? 0;\n const itemId = str(value.item_id) ?? (outputIndex === undefined ? undefined : keyByOutput.get(outputIndex));\n appendText(textState(`text:${itemId ?? `idx:${outputIndex ?? -1}`}:${contentIndex}`), delta, out);\n break;\n }\n case 'response.refusal.delta': {\n const delta = str(value.delta);\n if (!delta) break;\n const outputIndex = int(value.output_index);\n const contentIndex = int(value.content_index) ?? 0;\n const itemId = str(value.item_id) ?? (outputIndex === undefined ? undefined : keyByOutput.get(outputIndex));\n appendText(textState(`text:${itemId ?? `idx:${outputIndex ?? -1}`}:${contentIndex}`), delta, out);\n break;\n }\n case 'response.reasoning_summary_text.delta': {\n const delta = str(value.delta);\n if (!delta) break;\n const key = keyFor(value, 'reasoning', int(value.output_index));\n appendReasoning(reasoningState(`${key}:s${int(value.summary_index) ?? 0}`), delta, out);\n break;\n }\n case 'response.reasoning_text.delta': {\n const delta = str(value.delta);\n if (!delta) break;\n const key = keyFor(value, 'reasoning', int(value.output_index));\n appendReasoning(reasoningState(`${key}:t`), delta, out);\n break;\n }\n case 'response.function_call_arguments.delta': {\n const call = callState(keyFor(value, 'call', int(value.output_index)), undefined, out);\n const delta = str(value.delta) ?? '';\n call.args += delta;\n flushCall(call, delta, out);\n break;\n }\n case 'response.output_item.done': {\n const item = record(value.item) ? value.item : undefined;\n if (!item) break;\n const outputIndex = int(value.output_index);\n if (item.type === 'function_call') {\n const call = callState(keyFor(value, 'call', outputIndex), item, out);\n const args = str(item.arguments);\n if (args !== undefined && call.args === '') {\n call.args = args;\n flushCall(call, args, out);\n } else flushCall(call, '', out);\n } else if (item.type === 'message') {\n const key = `text:${str(item.id) ?? `idx:${outputIndex ?? -1}`}:0`;\n if (!texts.has(key)) {\n const content = Array.isArray(item.content) ? item.content : [];\n const text = content.map(part => record(part) && (part.type === 'output_text' || part.type === 'refusal') ? str(part.text) ?? '' : '').join('');\n if (text) appendText(textState(key), text, out);\n }\n } else if (item.type === 'reasoning') {\n const key = `reasoning:${str(item.id) ?? `idx:${outputIndex ?? -1}`}:s0`;\n if (!reasonings.has(key)) {\n const summary = Array.isArray(item.summary) ? item.summary : [];\n const text = summary.map(part => record(part) ? str(part.text) ?? '' : '').join('');\n if (text) appendReasoning(reasoningState(key), text, out);\n }\n }\n break;\n }\n case 'response.completed':\n case 'response.incomplete':\n case 'response.failed': {\n const response = record(value.response) ? value.response : {};\n if (type === 'response.failed') throw inBandError(record(response.error) ? response.error : {}, 'SERVER');\n usage = responseUsage(response) ?? usage;\n hydrate(response.output, out);\n const reason = reasonOf(type, response);\n // finish \u4E4B\u524D\u5B8C\u6210\u5168\u90E8\u6821\u9A8C\uFF1A\u6D88\u8D39\u8005\u6536\u5230 finish \u53EF\u80FD\u7ACB\u5373 return\uFF0C\u4E4B\u540E\u7684\u68C0\u67E5\u4E0D\u4F1A\u6267\u884C\u3002\n if (reason.kind === 'tool-calls' && calls.size === 0) throw new LlmError('OpenDesign\uFF1A\u54CD\u5E94\u58F0\u660E\u5DE5\u5177\u8C03\u7528\uFF0C\u4F46\u672A\u8FD4\u56DE\u4EFB\u4F55\u5DE5\u5177\u5757', 'INVALID_RESPONSE');\n if (!count) throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u8FD4\u56DE\u7A7A\u54CD\u5E94', 'EMPTY_RESPONSE');\n out.push(...close());\n if (usage) out.push({ type: 'usage', usage });\n finish = reason;\n out.push({ type: 'finish', reason });\n break;\n }\n case 'error':\n throw inBandError(value);\n default:\n // \u5176\u5B83\u4E8B\u4EF6\uFF08created/in_progress/content_part.*/annotation.* \u7B49\uFF09\u4E0D\u5F71\u54CD\u5757\u8BED\u4E49\u3002\n break;\n }\n\n for (const chunk of out) yield chunk;\n if (finish) break;\n }\n\n signal.throwIfAborted();\n if (!finish) throw new LlmError('OpenDesign\uFF1A\u54CD\u5E94\u6D41\u63D0\u524D\u4E2D\u65AD\uFF0C\u672A\u6536\u5230\u7ED3\u675F\u4E8B\u4EF6', 'INVALID_RESPONSE');\n}\n\nexport const responses: Protocol = {\n id: 'responses',\n build: buildResponsesRequest,\n stream: streamResponses,\n};\n", "/**\n * OpenAI \u517C\u5BB9 `GET /models` \u6A21\u578B\u53D1\u73B0\uFF08\u4E0E\u9009\u5B9A\u63A8\u7406\u534F\u8BAE\u65E0\u5173\uFF09\u3002\n *\n * \u5951\u7EA6\uFF1A\n * - \u53EA\u8BF7\u6C42 OpenAI \u517C\u5BB9 API \u7684 `/models`\uFF1B\u88F8\u7F51\u5173 origin \u81EA\u52A8\u8865 `/v1`\uFF0C\u663E\u5F0F\u524D\u7F00\u4FDD\u7559\u3002\u4F7F\u7528 `Bearer` \u9274\u6743 + \u5E94\u7528\u5F52\u56E0\u5934\uFF0C\n * `redirect: 'error'`\uFF0C20 \u79D2\u4E0A\u9650\uFF0C\u54CD\u5E94\u4F53\u4E0A\u9650 2 MiB\u3002\n * - \u4E0E\u63A8\u7406\u534F\u8BAE\u89E3\u8026\uFF1A\u672C\u51FD\u6570\u4E0D\u63A5\u53D7 protocol \u53C2\u6570\uFF0C\u4E5F\u4E0D\u6839\u636E\u534F\u8BAE\u6311\u9009\u8DEF\u5F84\u3002\n * - \u5F52\u4E00\u5316\u53EA\u63A5\u53D7 `data[]` \u4E2D\u53EF\u7528\u4E14\u6709\u754C\u7684 id\uFF1B\u5DF2\u77E5 id \u7EE7\u627F catalog \u7684\u5206\u7EC4\u4E0E\u80FD\u529B\uFF0C\n * \u65B0 id \u4E00\u5F8B\u5F52 `paid` \u4E14**\u4E0D**\u51ED\u540D\u79F0\u63A8\u65AD\u80FD\u529B\uFF08\u672A\u8BC6\u522B\u7684\u4E0A\u6E38\u80FD\u529B\u5B57\u6BB5\u76F4\u63A5\u5FFD\u7565\uFF09\u3002\n * - \u5A92\u4F53\u8F93\u51FA\u6A21\u578B\uFF08\u56FE\u50CF/\u89C6\u9891/\u8BED\u97F3\uFF0C\u8D70 `/api/v1/media/*`\uFF09\u4E0D\u8FDB\u5BF9\u8BDD\u76EE\u5F55\u3002\n * - \u6240\u6709\u5931\u8D25\u6298\u53E0\u4E3A `ModelDiscoveryError` \u7684\u56FA\u5B9A\u5206\u7C7B\u4E0E\u56FA\u5B9A\u6587\u5B57\uFF0C\u4E0D\u56DE\u663E\u51ED\u636E\u3001\n * \u8BF7\u6C42\u5934\u6216\u54CD\u5E94\u4F53\u3002\n */\n\nimport { attributionHeaders } from '@deepseek-ai/dsh-llm';\nimport { findModel, type CatalogModel } from './catalog.js';\nimport { assertBaseURL } from './config.js';\nimport { openAiBaseURL as normalizeOpenAiBase } from './protocol-options.js';\nimport { combinedSignal, record, safeSecret } from './util.js';\n\n/** \u53D1\u73B0\u8BF7\u6C42\u7684\u603B\u65F6\u9650\uFF08\u6BEB\u79D2\uFF09\u3002 */\nexport const DISCOVERY_TIMEOUT_MS = 20_000;\n/** \u54CD\u5E94\u4F53\u4E0A\u9650\uFF08\u5B57\u8282\uFF09\uFF1B\u8D85\u51FA\u5373\u6309\u683C\u5F0F\u9519\u8BEF\u62D2\u7EDD\uFF0C\u4E0D\u89E3\u6790\u90E8\u5206 JSON\u3002 */\nexport const MAX_DISCOVERY_BODY_BYTES = 2 * 1024 * 1024;\n/** \u5355\u6B21\u53D1\u73B0\u7684\u6A21\u578B\u6761\u6570\u4E0A\u9650\u3002 */\nconst MAX_MODELS = 512;\nconst MAX_MODEL_ID_LENGTH = 128;\nconst MAX_MODEL_NAME_LENGTH = 128;\nconst MODEL_ID = /^[A-Za-z0-9._:/-]{1,128}$/u;\n/**\n * \u663E\u5F0F\u5A92\u4F53\u8F93\u51FA\u6A21\u578B\u7684 id \u524D\u7F00\uFF1A\u5B98\u7F51\u8BC1\u636E\u91CC\u8FD9\u4E9B\u6A21\u578B\u8D70 `/api/v1/media/*`\uFF0C\n * \u9009\u4E2D\u540E chat \u8BF7\u6C42\u5FC5\u8D25\u3002\u53EA\u6309 id \u524D\u7F00\u6392\u9664\uFF0C\u4E0D\u4ECE\u540D\u79F0\u6216\u672A\u77E5\u80FD\u529B\u5B57\u6BB5\u63A8\u65AD\u3002\n */\nconst MEDIA_MODEL_ID = /^(?:gpt-image-|nano-banana-|seedream-|imagen-|veo-|doubao-seedance-|sora-)/u;\n\n/** Failure taxonomy; `status` is the HTTP status when one was received. */\nexport type ModelDiscoveryErrorKind = 'url' | 'credential' | 'network' | 'timeout' | 'aborted' | 'auth' | 'permission' | 'rate-limit' | 'server' | 'response';\n\nconst MESSAGES: Record<ModelDiscoveryErrorKind, string> = {\n url: '\u6A21\u578B\u53D1\u73B0\u5730\u5740\u65E0\u6548\uFF1A\u5FC5\u987B\u662F\u7EDD\u5BF9 HTTP(S) \u5730\u5740\uFF0C\u4E14\u4E0D\u542B\u51ED\u636E\u3001\u67E5\u8BE2\u4E32\u6216\u7247\u6BB5',\n credential: '\u6A21\u578B\u53D1\u73B0\u51ED\u636E\u7F3A\u5931\uFF0C\u6216\u542B\u6709\u4E0D\u53EF\u7528\u4E8E HTTP \u8BF7\u6C42\u5934\u7684\u5B57\u7B26',\n network: '\u65E0\u6CD5\u8FDE\u63A5\u6A21\u578B\u53D1\u73B0\u670D\u52A1',\n timeout: '\u6A21\u578B\u53D1\u73B0\u8BF7\u6C42\u8D85\u8FC7 20 \u79D2\u65F6\u9650',\n aborted: '\u6A21\u578B\u53D1\u73B0\u8BF7\u6C42\u5DF2\u53D6\u6D88',\n auth: '\u6A21\u578B\u53D1\u73B0\u8BA4\u8BC1\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u51ED\u636E',\n permission: '\u6A21\u578B\u53D1\u73B0\u51ED\u636E\u65E0\u6743\u8BFB\u53D6\u6A21\u578B\u5217\u8868',\n 'rate-limit': '\u6A21\u578B\u53D1\u73B0\u8BF7\u6C42\u88AB\u9650\u6D41\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5',\n server: '\u6A21\u578B\u53D1\u73B0\u670D\u52A1\u6682\u65F6\u4E0D\u53EF\u7528',\n response: '\u6A21\u578B\u53D1\u73B0\u54CD\u5E94\u4E0D\u7B26\u5408 OpenAI \u6A21\u578B\u5217\u8868\u683C\u5F0F',\n};\n\n/**\n * Fixed-text discovery failure. The message is one of the constants above, so callers may\n * log it verbatim: no credential, header, URL or upstream body is ever interpolated.\n */\nexport class ModelDiscoveryError extends Error {\n constructor(readonly kind: ModelDiscoveryErrorKind, readonly status?: number) {\n super(MESSAGES[kind]);\n this.name = 'ModelDiscoveryError';\n }\n}\n\nfunction statusKind(status: number): ModelDiscoveryErrorKind {\n if (status === 401) return 'auth';\n if (status === 403) return 'permission';\n if (status === 429) return 'rate-limit';\n if (status === 408 || status === 504) return 'timeout';\n if (status >= 500) return 'server';\n return 'response';\n}\n\n/**\n * Read at most `MAX_DISCOVERY_BODY_BYTES` and decode once; partial bodies are refused.\n * A body cut off by the caller's cancellation or the deadline is classified as such instead\n * of being reported as a format problem.\n */\nasync function boundedJson(response: Response, signal: AbortSignal | undefined, deadline: AbortSignal): Promise<unknown> {\n const reader = response.body?.getReader();\n if (!reader) throw new ModelDiscoveryError('response');\n const declared = Number(response.headers.get('content-length'));\n if (Number.isFinite(declared) && declared > MAX_DISCOVERY_BODY_BYTES) {\n await reader.cancel().catch(() => undefined);\n reader.releaseLock();\n throw new ModelDiscoveryError('response');\n }\n let size = 0;\n let raw = '';\n const decoder = new TextDecoder();\n try {\n while (true) {\n const chunk = await reader.read();\n if (chunk.done) break;\n size += chunk.value.byteLength;\n if (size > MAX_DISCOVERY_BODY_BYTES) throw new ModelDiscoveryError('response');\n raw += decoder.decode(chunk.value, { stream: true });\n }\n raw += decoder.decode();\n } catch (error) {\n if (signal?.aborted) throw new ModelDiscoveryError('aborted');\n if (deadline.aborted) throw new ModelDiscoveryError('timeout');\n if (error instanceof ModelDiscoveryError) throw error;\n throw new ModelDiscoveryError('response');\n } finally {\n await reader.cancel().catch(() => undefined);\n reader.releaseLock();\n }\n try { return JSON.parse(raw); } catch { throw new ModelDiscoveryError('response'); }\n}\n\n/**\n * Normalize an OpenAI list body. Rows without a usable id are dropped, duplicates keep\n * their first occurrence, and no capability is invented: a known id is copied from the\n * catalog, an unknown id becomes a `paid` row with only its id and name.\n */\nfunction normalize(body: unknown): readonly CatalogModel[] {\n if (!record(body) || !Array.isArray(body.data)) throw new ModelDiscoveryError('response');\n if (body.data.length > MAX_MODELS) throw new ModelDiscoveryError('response');\n const seen = new Set<string>();\n const rows: CatalogModel[] = [];\n for (const value of body.data) {\n if (!record(value) || typeof value.id !== 'string' || !MODEL_ID.test(value.id) || ['__proto__', 'constructor', 'prototype'].includes(value.id)) continue;\n if (MEDIA_MODEL_ID.test(value.id) || seen.has(value.id)) continue;\n seen.add(value.id);\n const known = findModel(value.id);\n if (known) { rows.push({ ...known }); continue; }\n const offered = typeof value.name === 'string' ? value.name.trim() : '';\n const name = offered !== '' && offered.length <= MAX_MODEL_NAME_LENGTH ? offered : value.id;\n rows.push({ id: value.id, name, group: 'paid' });\n }\n return rows;\n}\n\n/**\n * Discover the chat models an OpenAI-compatible endpoint advertises.\n *\n * @param openAiBaseURL Absolute HTTP(S) base URL without credentials/query/fragment.\n * @param key Bearer credential; trimmed once, never echoed or persisted here.\n * @param signal Caller cancellation, combined with the internal 20 s deadline.\n * @param fetcher Optional `fetch` replacement (tests, hosts with a custom transport).\n * @throws {ModelDiscoveryError} Fixed classification and fixed message for every failure.\n */\nexport async function fetchModelCatalog(openAiBaseURL: string, key: string, signal?: AbortSignal, fetcher?: typeof fetch): Promise<readonly CatalogModel[]> {\n let base: string;\n try { base = normalizeOpenAiBase(assertBaseURL(openAiBaseURL)); } catch { throw new ModelDiscoveryError('url'); }\n let credential: string;\n try { credential = safeSecret(key); } catch { throw new ModelDiscoveryError('credential'); }\n const request = fetcher ?? fetch;\n const deadline = combinedSignal(signal, DISCOVERY_TIMEOUT_MS);\n let response: Response;\n try {\n response = await request(`${base}/models`, {\n method: 'GET',\n headers: { ...attributionHeaders(), authorization: `Bearer ${credential}`, accept: 'application/json' },\n signal: deadline,\n redirect: 'error',\n });\n } catch {\n if (signal?.aborted) throw new ModelDiscoveryError('aborted');\n if (deadline.aborted) throw new ModelDiscoveryError('timeout');\n throw new ModelDiscoveryError('network');\n }\n if (!response.ok) {\n await response.body?.cancel().catch(() => undefined);\n throw new ModelDiscoveryError(statusKind(response.status), response.status);\n }\n return normalize(await boundedJson(response, signal, deadline));\n}\n", "// OpenDesign CoRouter \u2014 desktop login state and session resolution.\n//\n// Contract source: OpenDesign desktop daemon (`resources/app/prebundled/daemon/chunks/*.mjs`,\n// `configDir()` / `amrConfigPath()` / `readRawVelaControlApiContext()` / `readVelaProfileConfigSnapshot()`)\n// and `vela.exe` (profile struct tags). See docs/quota-evidence.md \u00A71.\n//\n// This module never prints, logs or echoes credential material. Every failure path\n// reports a *reason code*, never the offending text, so an unreadable or hostile\n// config can never leak its contents through an error message.\nimport { readFile as fsReadFile } from 'node:fs/promises';\nimport { homedir as osHomedir } from 'node:os';\nimport { join } from 'node:path';\nimport type { Session, SessionSource } from './quota.js';\nimport { record, safeSecret } from './util.js';\n\n/** Control-plane origin the desktop build ships with (open-design-config.json / daemon default). */\nexport const DEFAULT_API_URL = 'https://amr-api.open-design.ai';\n/** The one host this plugin is willing to send an account token to. */\nexport const API_HOST = 'amr-api.open-design.ai';\n\n/** Profiles the official client recognizes; anything else falls back to `prod`. */\nexport const DESKTOP_PROFILES = ['prod', 'test', 'feature-test', 'local'] as const;\nexport type DesktopProfile = (typeof DESKTOP_PROFILES)[number];\nexport const DEFAULT_PROFILE: DesktopProfile = 'prod';\n\n/** Reference names holding a console session cookie, read through the credential seam. */\nexport const COOKIE_ENV_REFS = ['OPEN_DESIGN_COOKIE', 'OPEN_DESIGN_SESSION'] as const;\n\n/**\n * Exactly one accepted origin. `apiUrl` comes from a file this plugin does not own, so an\n * edited or attacker-supplied value must never receive the account token: without this gate,\n * pointing `apiUrl` anywhere would exfiltrate the desktop `controlKey`. A sibling subdomain is\n * not accepted either \u2014 no widening \"just in case\" (`*.open-design.ai` would already be wrong).\n */\nexport function isOfficialApiUrl(raw: string): boolean {\n let url: URL;\n try { url = new URL(raw); } catch { return false; }\n if (url.protocol !== 'https:') return false;\n if (url.username || url.password) return false;\n if (url.search || url.hash) return false;\n if (url.pathname !== '/' && url.pathname !== '') return false;\n return url.hostname.toLowerCase() === API_HOST;\n}\n\n/** Canonical `https://host` form, or `undefined` when the value is not an official origin. */\nexport function normalizeApiUrl(raw: string | undefined): string | undefined {\n const value = typeof raw === 'string' ? raw.trim() : '';\n if (!value) return undefined;\n if (!isOfficialApiUrl(value)) return undefined;\n const url = new URL(value);\n return `https://${url.hostname.toLowerCase()}`;\n}\n\n/** Profile selection matches the client: `OPEN_DESIGN_AMR_PROFILE` wins over `VELA_PROFILE`. */\nexport function resolveProfile(env: NodeJS.ProcessEnv = process.env): DesktopProfile {\n const raw = (env.OPEN_DESIGN_AMR_PROFILE ?? env.VELA_PROFILE ?? '').trim();\n return (DESKTOP_PROFILES as readonly string[]).includes(raw) ? raw as DesktopProfile : DEFAULT_PROFILE;\n}\n\n/** `AMR_HOME` (with `~` / `~/x` expansion), else `<home>/.amr` \u2014 the client's `configDir()`. */\nexport function desktopConfigDir(env: NodeJS.ProcessEnv = process.env, home = osHomedir()): string {\n const raw = (env.AMR_HOME ?? '').trim();\n if (!raw) return join(home, '.amr');\n if (raw === '~') return home;\n if (raw.startsWith('~/') || raw.startsWith('~\\\\')) return join(home, raw.slice(2));\n return raw;\n}\n\n/** Full path of the desktop credential file. */\nexport function desktopConfigPath(env: NodeJS.ProcessEnv = process.env, home = osHomedir()): string {\n return join(desktopConfigDir(env, home), 'config.json');\n}\n\n/** What the desktop file says about one profile. Values are held in memory only. */\nexport interface DesktopCredential {\n profile: DesktopProfile;\n controlKey: string;\n /** Present only when the profile carries an official origin. */\n apiUrl?: string;\n plan?: string;\n /** `runtimeKey` present means the desktop considers itself signed in. */\n signedIn: boolean;\n}\n\nexport type DesktopRead =\n | { state: 'missing' }\n | { state: 'unreadable' }\n | { state: 'invalid' }\n | { state: 'incomplete'; profile: DesktopProfile }\n /** The profile's `apiUrl` is not the one accepted origin: never used, and never retried elsewhere. */\n | { state: 'unsafe-api-url'; profile: DesktopProfile }\n /** A non-`prod` profile: its token belongs to another environment, so it is not sent to prod. */\n | { state: 'unsupported-profile'; profile: DesktopProfile }\n | { state: 'credential'; credential: DesktopCredential };\n\n/**\n * Parse `config.json` text. Never throws and never returns the raw text, so callers can\n * treat a hostile file as \"absent\" without risking a leak. `state: 'invalid'` means the\n * JSON or its shape was not what the client writes.\n */\nexport function parseDesktopConfigText(text: string, profile: DesktopProfile = DEFAULT_PROFILE): DesktopRead {\n let parsed: unknown;\n try { parsed = JSON.parse(text); } catch { return { state: 'invalid' }; }\n if (!record(parsed)) return { state: 'invalid' };\n const profiles = parsed['profiles'];\n if (!record(profiles)) return { state: 'invalid' };\n const entry = profiles[profile];\n // A config for other profiles only is \"no credential here\", not \"invalid\".\n if (entry === undefined) return { state: 'incomplete', profile };\n if (!record(entry)) return { state: 'invalid' };\n const controlKey = typeof entry['controlKey'] === 'string' ? entry['controlKey'].trim() : '';\n const runtimeKey = typeof entry['runtimeKey'] === 'string' ? entry['runtimeKey'].trim() : '';\n const rawApiUrl = typeof entry['apiUrl'] === 'string' ? entry['apiUrl'].trim() : '';\n const user = record(entry['user']) ? entry['user'] : undefined;\n const plan = typeof user?.['plan'] === 'string' ? user['plan'].trim() : '';\n if (!controlKey) return { state: 'incomplete', profile };\n try { safeSecret(controlKey); } catch { return { state: 'invalid' }; }\n const apiUrl = normalizeApiUrl(rawApiUrl);\n // A stored origin that is not the accepted one is reported, not discarded: silently falling\n // back to the default host is exactly how one environment's token would end up at another\n // environment's endpoint.\n if (rawApiUrl && !apiUrl) return { state: 'unsafe-api-url', profile };\n // Only `prod` is supported. Sending another profile's token to the prod endpoint (or the\n // reverse) would mix accounts, so the mismatch stops here.\n if (profile !== DEFAULT_PROFILE) return { state: 'unsupported-profile', profile };\n return {\n state: 'credential',\n credential: {\n profile,\n controlKey,\n ...(apiUrl === undefined ? {} : { apiUrl }),\n ...(plan ? { plan } : {}),\n signedIn: runtimeKey.length > 0,\n },\n };\n}\n\nexport interface DesktopDeps {\n env?: NodeJS.ProcessEnv;\n home?: string;\n profile?: DesktopProfile;\n readFile?: (path: string) => Promise<string>;\n}\n\n/**\n * Read the desktop credential, distinguishing \"no desktop installed or signed out\"\n * (`missing` / `incomplete`) from \"there is a file but it cannot be used\"\n * (`unreadable` / `invalid`). The two must not be conflated: the first is normal for\n * users without the desktop app, the second deserves a different hint.\n */\nexport async function readDesktopCredential(deps: DesktopDeps = {}): Promise<DesktopRead> {\n const env = deps.env ?? process.env;\n const profile = deps.profile ?? resolveProfile(env);\n const path = desktopConfigPath(env, deps.home ?? osHomedir());\n const readFile = deps.readFile ?? ((file: string) => fsReadFile(file, 'utf8'));\n let text: string;\n try { text = await readFile(path); }\n catch (error) {\n const code = record(error) && typeof error['code'] === 'string' ? error['code'] : '';\n return code === 'ENOENT' || code === 'ENOTDIR' ? { state: 'missing' } : { state: 'unreadable' };\n }\n return parseDesktopConfigText(text, profile);\n}\n\n/** Cookie payload persisted through the credential seam as a `grant` record. */\nexport interface LoginGrant {\n cookie: string;\n /** Epoch ms; `0`/absent means the console declared no expiry. */\n expiresAt?: number;\n}\n\nexport type AuthSource = 'desktop' | 'login' | 'environment';\n\nexport interface AuthSession extends Session {\n source: SessionSource;\n via: AuthSource;\n apiUrl: string;\n /** Desktop profile name, when the session came from the desktop file. */\n profile?: string;\n plan?: string;\n}\n\nexport type AuthReason =\n | 'no-credential'\n | 'desktop-incomplete'\n | 'desktop-unreadable'\n | 'unsafe-api-url'\n | 'unsupported-profile';\n\nexport type AuthOutcome =\n | { state: 'ready'; session: AuthSession; warnings: AuthReason[] }\n | { state: 'need-login'; reason: AuthReason; warnings: AuthReason[] };\n\nexport interface AuthDeps extends DesktopDeps {\n /** Allow reading the desktop login state; `false` for users who only use this plugin's login. */\n useDesktop?: boolean;\n /** Read the persisted login grant (Host-owned credential store). */\n readGrant?: () => Promise<LoginGrant | undefined>;\n /** Resolve an environment-variable reference (Host-owned credential seam). */\n resolveRef?: (ref: string) => Promise<string | undefined>;\n now?: () => number;\n}\n\nfunction cookieHeader(raw: string): string | undefined {\n const value = raw.trim();\n if (!value || !value.includes('=')) return undefined;\n try { return safeSecret(value); } catch { return undefined; }\n}\n\n/** Desktop `controlKey` as a Bearer header (daemon evidence: `/api/v1/wallet/balance`). */\nexport function desktopSession(credential: DesktopCredential, apiUrl = credential.apiUrl ?? DEFAULT_API_URL): AuthSession {\n const base = normalizeApiUrl(apiUrl) ?? DEFAULT_API_URL;\n return {\n headers: { authorization: `Bearer ${safeSecret(credential.controlKey)}` },\n source: 'desktop',\n via: 'desktop',\n apiUrl: base,\n profile: credential.profile,\n ...(credential.plan ? { plan: credential.plan } : {}),\n };\n}\n\n/** A persisted or environment-supplied console cookie as a `cookie` header. */\nexport function cookieSession(cookie: string, source: SessionSource, apiUrl = DEFAULT_API_URL): AuthSession | undefined {\n const header = cookieHeader(cookie);\n if (!header) return undefined;\n return {\n headers: { cookie: header },\n source,\n via: source === 'environment' ? 'environment' : 'login',\n apiUrl: normalizeApiUrl(apiUrl) ?? DEFAULT_API_URL,\n };\n}\n\n/**\n * Resolve the session in the order the user asked for: **desktop first**, then the\n * cookie saved by this plugin's own login, then environment references.\n *\n * A desktop config whose `apiUrl` is not an official origin is *skipped*, not used: the\n * token must not travel to a host the plugin cannot vouch for. The skip is reported as a\n * warning so a UI can explain why the desktop session was ignored.\n */\nexport async function resolveSession(deps: AuthDeps = {}): Promise<AuthOutcome> {\n const env = deps.env ?? process.env;\n const warnings: AuthReason[] = [];\n const now = deps.now ?? Date.now;\n\n if (deps.useDesktop !== false) {\n const desktop = await readDesktopCredential(deps);\n if (desktop.state === 'credential') {\n const envApiUrl = (env.VELA_API_URL ?? '').trim();\n // An environment-supplied origin passes through the same single-host gate. A rejected\n // value means \"desktop off\", not \"use the token on the default host\": that substitution\n // is precisely the cross-environment leak this check exists to prevent.\n if (envApiUrl && !normalizeApiUrl(envApiUrl)) {\n warnings.push('unsafe-api-url');\n } else {\n return { state: 'ready', session: desktopSession(desktop.credential, envApiUrl || DEFAULT_API_URL), warnings };\n }\n } else if (desktop.state === 'unsafe-api-url') {\n warnings.push('unsafe-api-url');\n } else if (desktop.state === 'unsupported-profile') {\n warnings.push('unsupported-profile');\n } else if (desktop.state === 'incomplete') {\n warnings.push('desktop-incomplete');\n } else if (desktop.state === 'unreadable' || desktop.state === 'invalid') {\n warnings.push('desktop-unreadable');\n }\n }\n\n if (deps.readGrant) {\n let grant: LoginGrant | undefined;\n try { grant = await deps.readGrant(); } catch { grant = undefined; }\n const expiry = typeof grant?.expiresAt === 'number' && Number.isFinite(grant.expiresAt) ? grant.expiresAt : 0;\n if (grant && (expiry === 0 || expiry > now())) {\n const session = cookieSession(grant.cookie, 'login');\n if (session) return { state: 'ready', session, warnings };\n }\n }\n\n if (deps.resolveRef) {\n for (const ref of COOKIE_ENV_REFS) {\n let value: string | undefined;\n try { value = await deps.resolveRef(ref); } catch { value = undefined; }\n if (!value) continue;\n const session = cookieSession(value, 'environment');\n if (session) return { state: 'ready', session, warnings };\n }\n }\n\n return { state: 'need-login', reason: warnings[0] ?? 'no-credential', warnings };\n}\n\n/** Endpoint builders for a resolved origin, mirroring `quota.ts` for non-default hosts. */\nexport function endpoints(apiUrl: string) {\n const base = `${apiUrl}/api/v1`;\n return {\n base,\n current: `${base}/workspaces/current`,\n summary: `${base}/billing/summary`,\n usage: (workspaceId: string) => `${base}/workspaces/${encodeURIComponent(workspaceId)}/billing/coding-plan-usage`,\n };\n}\n", "// OpenDesign CoRouter \u2014 independent console login.\n//\n// Browser-lifecycle skeleton adapted from `dsh-subusage` 0.16.2 `lib/cookie-login.js` (MIT,\n// Copyright (c) 2026 KouzakiUmi). Flow and state machine are the same as that module: the\n// button that starts the login says \"\u767B\u5F55\u5E76\u4FDD\u5B58\u4F1A\u8BDD\", so a successful verification commits\n// without a second confirmation step.\n//\n// Guarantees this module owns:\n// - no credential ever appears in `status()` output;\n// - nothing is written while the attempt is in `launching`/`waiting`;\n// - `commit` is called at most once per attempt, and never after a terminal state;\n// - `commit` **success is the linearization point**: once the Host's atomic store has\n// accepted the write, a cancel that arrived earlier cannot retract it, and the attempt\n// reports `success`. A cancel that arrives before the store accepts the write aborts the\n// signal the store re-checks, and the attempt reports `cancelled`;\n// - the browser is closed on every terminal path.\nimport { randomUUID } from 'node:crypto';\nimport { sleep } from './util.js';\n\n/** Console origin and dashboard entry the official desktop uses. */\nexport const CONSOLE_ORIGIN = 'https://open-design.ai';\nexport const CONSOLE_DASHBOARD_URL = `${CONSOLE_ORIGIN}/cloud/dashboard`;\n/** The API host whose cookies matter; `context.cookies()` uses it to pick the right ones. */\nexport const API_COOKIE_URL = 'https://amr-api.open-design.ai/api/v1/workspaces/current';\n\nexport interface RawCookie { name?: string; value?: string; expires?: number }\n\n/** One usable console session: the exact `Cookie` header a browser would send. */\nexport interface ExtractedCookie { cookie: string; expiresAt: number }\n\n/**\n * Pick the session cookies by **URL scope**, never by name. The real cookie is\n * better-auth's `__Secure-better-auth.session_token` today, but it can be renamed at any\n * time and no third party can enumerate the alternatives; joining every unexpired cookie\n * that applies to the API URL reproduces exactly what the browser itself sends. Before\n * login completes this may also collect non-auth cookies (`od_attr`, `__cf_bm`), which is\n * harmless: such a bundle fails `verify` and is therefore never saved.\n */\nexport function extractConsoleSession(cookies: readonly RawCookie[], now = Date.now()): ExtractedCookie | null {\n const usable = cookies.filter(c =>\n typeof c.name === 'string' && c.name.length > 0 &&\n typeof c.value === 'string' && c.value.length > 0 &&\n (c.expires === undefined || c.expires === -1 || c.expires * 1000 > now));\n if (!usable.length) return null;\n const declared = usable\n .map(c => c.expires)\n .filter((expires): expires is number => typeof expires === 'number' && Number.isFinite(expires) && expires > 0);\n return {\n cookie: usable.map(c => `${c.name}=${c.value}`).join('; '),\n expiresAt: declared.length ? Math.min(...declared) * 1000 : 0,\n };\n}\n\nexport interface LoginSite {\n origin: string;\n loginUrl: string;\n cookieUrls: readonly string[];\n extract(cookies: readonly RawCookie[], now: number): ExtractedCookie | null;\n}\n\n/** Site parameters, overridable so a rebrand (for example a new console origin) needs no code fork. */\nexport function consoleSite(overrides: { origin?: string; loginUrl?: string; cookieUrls?: readonly string[] } = {}): LoginSite {\n const origin = overrides.origin ?? CONSOLE_ORIGIN;\n return {\n origin,\n loginUrl: overrides.loginUrl ?? (origin === CONSOLE_ORIGIN ? CONSOLE_DASHBOARD_URL : `${origin}/cloud/dashboard`),\n cookieUrls: overrides.cookieUrls ?? [API_COOKIE_URL],\n extract: extractConsoleSession,\n };\n}\n\nexport interface VerifyResult {\n /** Whether the account was read at all; a read-but-quota-unknown result still verifies. */\n balanceOk: boolean;\n /** Set when the quota endpoint failed; the cookie itself is still valid, so the host may still save it. */\n usageError?: { code: string } | undefined;\n /**\n * Caller-supplied context, echoed nowhere and used only for the success message. The Host\n * re-reads the real quota after commit, so these are never trusted as state.\n */\n coverage?: string | undefined;\n windows?: readonly unknown[] | undefined;\n}\n\n/** Host-supplied operations. No Host type is imported: the caller wires these. */\nexport interface LoginCallbacks {\n /** Snapshot the state a commit must not overwrite, keyed by the revision the caller saw. */\n capture(expectedRevision: string): unknown | Promise<unknown>;\n /** Prove the cookie works. Any throw means \"not usable yet\"; abort is a cancel. */\n verify(cookie: string, signal: AbortSignal): Promise<VerifyResult>;\n /**\n * Persist the verified cookie. The Host's store must run its write inside a mutex and call\n * `signal.throwIfAborted()` there, so a cancel that landed before the mutex was acquired\n * wins, and one that lands afterwards does not.\n *\n * `expiresAt` is the cookie bundle's earliest declared expiry in epoch ms, or `0` when the\n * console declared none (a session cookie). It is passed through so the Host can store it and\n * let `resolveSession` expire a stale grant proactively instead of waiting for a 401.\n */\n commit(cookie: string, captured: unknown, signal: AbortSignal, expiresAt: number): Promise<unknown>;\n}\n\n/**\n * Attempt phases, matching the shared wire contract (`LoginPhase` in `remote.ts`) exactly;\n * `success`/`cancelled`/`error` are terminal. The Host maps `status()` onto the wire type.\n */\nexport type LoginPhase = 'idle' | 'launching' | 'waiting' | 'verifying' | 'success' | 'cancelled' | 'error';\n\nexport interface LoginStatus {\n jobId: string | null;\n state: LoginPhase;\n startedAt?: string;\n finishedAt?: string;\n message?: string;\n errorCode?: string;\n /** The page could not be opened; the UI may offer the URL instead. */\n browserOpenFailed?: boolean;\n}\n\nexport interface LoginStartRequest { expectedRevision: string }\nexport interface LoginJobRequest { jobId: string }\n\n/** Minimal structural browser surface, so tests need no Playwright and Host wiring stays loose. */\nexport interface BrowserLike {\n on?(event: 'disconnected', listener: () => void): void;\n newContext(): Promise<ContextLike>;\n close(): Promise<void>;\n}\nexport interface ContextLike {\n newPage(): Promise<PageLike>;\n cookies(urls: readonly string[]): Promise<readonly RawCookie[]>;\n}\nexport interface PageLike {\n on?(event: 'close', listener: () => void): void;\n goto(url: string, options?: { waitUntil?: string; timeout?: number }): Promise<unknown>;\n}\n\nexport type Launcher = (signal: AbortSignal) => Promise<BrowserLike | null>;\n\nexport interface LoginOptions {\n site?: LoginSite;\n /** Total life of one login attempt. Default five minutes. */\n timeoutMs?: number;\n pollMs?: number;\n now?: () => number;\n /** Injected browser launcher; the default uses `playwright-core` and a real Chrome window. */\n launch?: Launcher;\n /** Injected sleep, for tests. */\n delay?: (ms: number, signal: AbortSignal) => Promise<void>;\n}\n\nexport class LoginError extends Error {\n constructor(readonly code: 'opendesign/login-state' | 'opendesign/login-disposed' | 'opendesign/login-capture') {\n super(code === 'opendesign/login-state' ? '\u767B\u5F55\u4EFB\u52A1\u4E0D\u5B58\u5728\u6216\u72B6\u6001\u5DF2\u6539\u53D8' : code === 'opendesign/login-disposed' ? '\u767B\u5F55\u670D\u52A1\u5DF2\u5378\u8F7D' : '\u65E0\u6CD5\u6355\u83B7\u5F53\u524D\u8BBE\u7F6E\u72B6\u6001\uFF0C\u767B\u5F55\u5DF2\u53D6\u6D88');\n }\n}\n\nconst ACTIVE = new Set<LoginPhase>(['launching', 'waiting', 'verifying']);\nconst DEFAULT_TIMEOUT_MS = 300_000;\nconst DEFAULT_POLL_MS = 1_000;\n/** Codes that mean \"the environment changed under us\": retrying would only repeat the failure. */\nconst FATAL_COMMIT_CODES = new Set(['opendesign/revision-conflict', 'opendesign/invalid-request', 'opendesign/config', 'opendesign/login-disposed']);\n\n/**\n * Chrome flags that let a *human* pass the console's bot check. The console looks at\n * `navigator.webdriver` when its Cloudflare challenge is submitted; `headless: false` alone\n * leaves it `true`, and this blink switch is what the official Playwright browser tool\n * appends for chromium. This is not a challenge bypass \u2014 the user still solves it \u2014 it only\n * avoids announcing automation before they can act. `ignoreDefaultArgs` is a no-op on\n * 1.63.0 and stays for forward compatibility.\n */\nexport const CHROME_LAUNCH_OPTIONS = {\n channel: 'chrome',\n headless: false,\n ignoreDefaultArgs: ['--enable-automation'],\n args: ['--disable-blink-features=AutomationControlled'],\n} as const;\n\ninterface Job {\n readonly id: string;\n readonly startedAt: string;\n readonly controller: AbortController;\n readonly expectedRevision: string;\n readonly status: LoginStatus;\n timer?: NodeJS.Timeout | undefined;\n browser?: BrowserLike | undefined;\n /** In memory only; never copied into `status`. */\n secret?: ExtractedCookie | undefined;\n captured: unknown;\n capturedAt?: Promise<unknown> | undefined;\n verifying: boolean;\n committing: boolean;\n /** A cancel arrived while `commit` was in flight: only the store's own abort check decides. */\n cancelRequested: boolean;\n}\n\nexport class ConsoleLogin {\n private job: Job | null = null;\n private disposed = false;\n private readonly callbacks: LoginCallbacks;\n private readonly options: LoginOptions;\n private readonly now: () => number;\n private readonly delay: (ms: number, signal: AbortSignal) => Promise<void>;\n\n constructor(callbacks: LoginCallbacks, options: LoginOptions = {}) {\n this.callbacks = callbacks;\n this.options = options;\n this.now = options.now ?? Date.now;\n this.delay = options.delay ?? sleep;\n }\n\n /** Idempotent, credential-free view of the current attempt. */\n status(): LoginStatus {\n if (!this.job) return { jobId: null, state: 'idle' };\n // Explicit allowlist: an added field cannot start leaking a secret by accident.\n const s = this.job.status;\n return {\n jobId: s.jobId,\n state: s.state,\n ...(s.startedAt ? { startedAt: s.startedAt } : {}),\n ...(s.finishedAt ? { finishedAt: s.finishedAt } : {}),\n ...(s.message ? { message: s.message } : {}),\n ...(s.errorCode ? { errorCode: s.errorCode } : {}),\n ...(s.browserOpenFailed ? { browserOpenFailed: true } : {}),\n };\n }\n\n /**\n * Queue one attempt and return immediately: the RPC that starts a login must not wait on a\n * browser window or on a human. Re-entrant calls while an attempt is live return that\n * attempt's status instead of opening a second browser.\n */\n start(request: LoginStartRequest): LoginStatus {\n if (this.disposed) throw new LoginError('opendesign/login-disposed');\n if (this.job && ACTIVE.has(this.job.status.state)) return this.status();\n const job: Job = {\n id: randomUUID(),\n startedAt: new Date(this.now()).toISOString(),\n controller: new AbortController(),\n expectedRevision: request.expectedRevision,\n status: { jobId: '', state: 'launching', message: '\u6B63\u5728\u6253\u5F00\u4E34\u65F6 Chrome \u767B\u5F55\u7A97\u53E3' },\n captured: undefined,\n capturedAt: undefined,\n verifying: false,\n committing: false,\n cancelRequested: false,\n };\n job.status.jobId = job.id;\n job.status.startedAt = job.startedAt;\n this.job = job;\n job.timer = setTimeout(() => this.finish(job, 'cancelled', '\u767B\u5F55\u5DF2\u8D85\u8FC7\u4E94\u5206\u949F\uFF0C\u8BF7\u91CD\u65B0\u5F00\u59CB'), this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n job.timer.unref?.();\n // The capture runs before the browser opens, so a revision conflict is discovered while\n // nothing is on screen yet.\n job.capturedAt = Promise.resolve()\n .then(() => this.callbacks.capture(job.expectedRevision))\n .then(captured => { job.captured = captured; return captured; });\n void job.capturedAt\n .then(() => this.run(job))\n .catch(error => { if (this.alive(job)) this.finish(job, 'error', '\u767B\u5F55\u65E0\u6CD5\u5F00\u59CB\uFF0C\u8BF7\u91CD\u8BD5', errorCode(error) ?? 'opendesign/login-capture'); });\n return this.status();\n }\n\n /**\n * Abandon the attempt. While `commit` is in flight this only aborts the signal and records\n * the request: the Host's atomic store decides, because the commit is the linearization\n * point. A cancel that wins that race reports `cancelled`; one that loses reports `success`\n * and the cookie really is stored.\n */\n cancel(request: LoginJobRequest): LoginStatus {\n const job = this.job;\n if (!job || job.status.jobId !== request.jobId) return this.status();\n if (job.committing) {\n job.cancelRequested = true;\n job.controller.abort();\n return this.status();\n }\n if (ACTIVE.has(job.status.state)) this.finish(job, 'cancelled', '\u767B\u5F55\u5DF2\u53D6\u6D88\uFF0C\u672A\u4FDD\u5B58 Cookie');\n return this.status();\n }\n\n /** Plugin teardown: abort the attempt and close the browser. */\n dispose(): void {\n const job = this.job;\n if (job && job.committing) {\n job.cancelRequested = true;\n job.controller.abort();\n } else if (job && ACTIVE.has(job.status.state)) {\n this.finish(job, 'cancelled', '\u670D\u52A1\u5DF2\u5378\u8F7D\uFF0C\u767B\u5F55\u5DF2\u53D6\u6D88');\n }\n this.disposed = true;\n }\n\n private alive(job: Job): boolean {\n if (this.disposed || this.job !== job) return false;\n if (job.controller.signal.aborted && !job.committing) return false;\n return job.status.state !== 'success' && job.status.state !== 'cancelled' && job.status.state !== 'error';\n }\n\n private stopTimer(job: Job): void {\n if (job.timer) { clearTimeout(job.timer); job.timer = undefined; }\n }\n\n private async close(job: Job): Promise<void> {\n const browser = job.browser;\n job.browser = undefined;\n try { await browser?.close(); } catch { /* closing a dead browser is not an error worth surfacing */ }\n }\n\n private finish(job: Job, state: 'success' | 'cancelled' | 'error', message: string, errorCode?: string): void {\n if (this.job !== job) return;\n if (job.status.state === 'success' || job.status.state === 'cancelled' || job.status.state === 'error') return;\n job.status.state = state;\n job.status.finishedAt = new Date(this.now()).toISOString();\n job.status.message = message;\n if (errorCode) job.status.errorCode = errorCode;\n job.secret = undefined;\n this.stopTimer(job);\n job.controller.abort();\n void this.close(job);\n }\n\n private async resolveBrowser(job: Job): Promise<BrowserLike | null> {\n if (!this.alive(job)) return null;\n const launch = this.options.launch ?? defaultLaunch;\n const browser = await launch(job.controller.signal);\n if (!browser) return null;\n job.browser = browser;\n browser.on?.('disconnected', () => this.finish(job, 'cancelled', '\u767B\u5F55\u7A97\u53E3\u5DF2\u5173\u95ED\uFF0C\u672A\u4FDD\u5B58 Cookie'));\n return browser;\n }\n\n private async run(job: Job): Promise<void> {\n const site = this.options.site ?? consoleSite();\n const browser = await this.resolveBrowser(job);\n if (!browser) return;\n if (!this.alive(job)) { await this.close(job); return; }\n const context = await browser.newContext();\n if (!this.alive(job)) { await this.close(job); return; }\n const page = await context.newPage();\n page.on?.('close', () => this.finish(job, 'cancelled', '\u767B\u5F55\u7A97\u53E3\u5DF2\u5173\u95ED\uFF0C\u672A\u4FDD\u5B58 Cookie'));\n if (!this.alive(job)) { await this.close(job); return; }\n // Navigate to the page that actually triggers sign-in; the site home is only a fallback\n // for the times the dashboard is down, so the user can still navigate somewhere useful.\n try { await page.goto(site.loginUrl, { waitUntil: 'domcontentloaded', timeout: 30_000 }); }\n catch {\n if (!this.alive(job)) return;\n try { await page.goto(site.origin, { waitUntil: 'domcontentloaded', timeout: 30_000 }); }\n catch { job.status.browserOpenFailed = true; }\n }\n if (!this.alive(job)) return;\n job.status.state = 'waiting';\n job.status.message = '\u8BF7\u5728\u5B98\u65B9\u7A97\u53E3\u81EA\u884C\u5B8C\u6210\u767B\u5F55\uFF1B\u8D26\u6237\u9A8C\u8BC1\u901A\u8FC7\u540E\u4FDD\u5B58\uFF0C\u989D\u5EA6\u72B6\u6001\u53E6\u884C\u663E\u793A';\n let nextAttempt = 0;\n let failures = 0;\n const pollMs = this.options.pollMs ?? DEFAULT_POLL_MS;\n while (this.alive(job)) {\n if (!job.verifying) {\n const session = site.extract(await context.cookies(site.cookieUrls), this.now());\n if (!this.alive(job)) return;\n if (session && this.now() >= nextAttempt) {\n job.verifying = true;\n job.status.state = 'verifying';\n job.status.message = '\u6B63\u5728\u9A8C\u8BC1\u767B\u5F55\u548C\u8BA2\u9605\u989D\u5EA6\uFF08\u5C1A\u672A\u4FDD\u5B58\uFF09';\n try {\n const verified = await this.callbacks.verify(session.cookie, job.controller.signal);\n if (!this.alive(job)) return;\n if (verified.usageError || !verified.balanceOk) {\n // \"Logged in but the quota is not fully readable\" is not a failed login: the\n // cookie is real. Keep waiting and re-check, but do not save yet.\n job.status.state = 'waiting';\n job.status.message = '\u5DF2\u8BFB\u53D6\u8D26\u6237\uFF0C\u4F46\u8BA2\u9605\u989D\u5EA6\u5C1A\u672A\u5B8C\u6574\u9A8C\u8BC1\uFF1B\u5C1A\u672A\u4FDD\u5B58\uFF0C\u8BF7\u786E\u8BA4\u5957\u9910\u6216\u7EE7\u7EED\u767B\u5F55';\n nextAttempt = this.now() + 15_000;\n } else {\n const outcome = await this.commit(job, session);\n if (outcome !== 'retry') return;\n // The store rejected the write transiently: back off and verify again rather than\n // reporting success that did not happen.\n failures += 1;\n nextAttempt = this.now() + Math.max(5_000, Math.min(60_000, 2_000 * 2 ** Math.min(failures, 5)));\n }\n } catch (error) {\n if (!this.alive(job)) return;\n failures += 1;\n nextAttempt = this.now() + Math.max(5_000, Math.min(60_000, 2_000 * 2 ** Math.min(failures, 5)), retryAfterMs(error));\n job.status.state = 'waiting';\n job.status.message = errorCode(error) === 'opendesign/auth'\n ? '\u767B\u5F55\u5C1A\u672A\u751F\u6548\uFF0C\u8BF7\u7EE7\u7EED\u5728\u5B98\u65B9\u7A97\u53E3\u5B8C\u6210\u767B\u5F55\uFF1B\u672A\u4FDD\u5B58'\n : '\u989D\u5EA6\u9A8C\u8BC1\u6682\u672A\u6210\u529F\uFF0C\u5C06\u9650\u9891\u91CD\u8BD5\uFF1B\u672A\u4FDD\u5B58';\n } finally {\n job.verifying = false;\n }\n }\n }\n await this.delay(pollMs, job.controller.signal);\n }\n }\n\n /**\n * Persist the verified session; `commit` resolving is the linearization point. Returns\n * `retry` when the store rejected the write transiently, so the caller decides when to try\n * again instead of claiming a success that did not happen.\n */\n private async commit(job: Job, session: ExtractedCookie): Promise<'success' | 'cancelled' | 'error' | 'retry'> {\n if (job.committing || !this.alive(job)) return 'cancelled';\n job.committing = true;\n job.status.state = 'verifying';\n job.status.message = '\u767B\u5F55\u5DF2\u9A8C\u8BC1\uFF0C\u6B63\u5728\u4FDD\u5B58\u4F1A\u8BDD';\n try {\n await this.callbacks.commit(session.cookie, job.captured, job.controller.signal, session.expiresAt);\n job.committing = false;\n // The store accepted the write. A cancel that arrived earlier cannot retract it, so the\n // honest report is success \u2014 this is the linearization boundary.\n this.finish(job, 'success', '\u767B\u5F55\u53CA\u8BA2\u9605\u989D\u5EA6\u5DF2\u9A8C\u8BC1\uFF0CCookie \u5DF2\u4FDD\u5B58');\n return 'success';\n } catch (error) {\n job.committing = false;\n if (job.cancelRequested || job.controller.signal.aborted) {\n this.finish(job, 'cancelled', '\u767B\u5F55\u5DF2\u53D6\u6D88\uFF0C\u672A\u4FDD\u5B58 Cookie');\n return 'cancelled';\n }\n if (FATAL_COMMIT_CODES.has(errorCode(error) ?? '')) {\n this.finish(job, 'error', '\u8BBE\u7F6E\u5DF2\u6539\u53D8\u6216\u65E0\u6CD5\u4FDD\u5B58\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\u540E\u91CD\u8BD5', errorCode(error));\n return 'error';\n }\n job.status.state = 'waiting';\n job.status.message = '\u767B\u5F55\u5DF2\u9A8C\u8BC1\uFF0C\u4F46\u4FDD\u5B58\u6682\u672A\u6210\u529F\uFF0C\u5C06\u9650\u9891\u91CD\u8BD5\uFF1B\u5C1A\u672A\u4FDD\u5B58';\n return 'retry';\n }\n }\n}\n\nfunction errorCode(error: unknown): string | undefined {\n if (error && typeof error === 'object' && 'code' in error && typeof (error as { code?: unknown }).code === 'string') return (error as { code: string }).code;\n return undefined;\n}\n\nfunction retryAfterMs(error: unknown): number {\n if (!error || typeof error !== 'object') return 0;\n const details = (error as { details?: unknown }).details;\n if (!details || typeof details !== 'object') return 0;\n const value = (details as { retryAfterMs?: unknown }).retryAfterMs;\n return typeof value === 'number' && Number.isFinite(value) && value > 0 ? Math.min(300_000, value) : 0;\n}\n\n/** Default launcher: a real, visible Chrome via `playwright-core` (a declared dependency). */\nasync function defaultLaunch(signal: AbortSignal): Promise<BrowserLike | null> {\n if (signal.aborted) return null;\n const { chromium } = await import('playwright-core');\n if (signal.aborted) return null;\n return await chromium.launch({\n channel: CHROME_LAUNCH_OPTIONS.channel,\n headless: CHROME_LAUNCH_OPTIONS.headless,\n // Copied so Playwright, which wants mutable arrays, cannot freeze on the readonly literals.\n ignoreDefaultArgs: [...CHROME_LAUNCH_OPTIONS.ignoreDefaultArgs],\n args: [...CHROME_LAUNCH_OPTIONS.args],\n }) as unknown as BrowserLike;\n}\n", "// OpenDesign normalization and independent-pool degradation adapted from dsh-subusage 0.16.2 (MIT).\nimport { attributionHeaders } from '@deepseek-ai/dsh-llm';\nimport { record, combinedSignal } from './util.js';\n\nexport const API_BASE = 'https://amr-api.open-design.ai/api/v1';\nexport const CURRENT_URL = `${API_BASE}/workspaces/current`;\nexport const SUMMARY_URL = `${API_BASE}/billing/summary`;\nexport const usageUrl = (workspace: string) => `${API_BASE}/workspaces/${encodeURIComponent(workspace)}/billing/coding-plan-usage`;\nexport type SessionSource = 'desktop' | 'login' | 'environment';\nexport interface Session { headers: Record<string, string>; source: SessionSource }\nexport interface QuotaWindow {\n durationSeconds: number; used: number; limit: number; remaining?: number; percent: number; resetsAt?: string;\n /** Window start as reported by coding-plan-usage (ISO-8601); never derived from the reset time. */\n windowStart?: string;\n /** Service-side window policy (`activity_triggered`, `anchored_recurring`, ...), when reported. */\n resetMode?: string;\n}\nexport interface QuotaSnapshot {\n state: 'ok' | 'partial' | 'need-login' | 'error';\n source?: SessionSource;\n updatedAt: string;\n tier?: string;\n eligible?: boolean;\n windows: QuotaWindow[];\n balances: { subscriptionUsd?: number; rechargeUsd?: number; totalUsd?: number };\n /**\n * Billing-period boundaries of the subscription pool (ISO-8601), from\n * `billing/summary`'s `subscriptionCurrentPeriodStart/End`. `End` is when the\n * plan model credits refresh \u2014 distinct from a rolling window's `resetsAt`.\n */\n subscriptionPeriodStart?: string;\n subscriptionPeriodEnd?: string;\n /** Next client-side read, owned by the host cache policy; this module never invents it. */\n nextRefreshAt?: string;\n /** A failed non-auth refresh retained the previous successful readings. */\n stale?: boolean;\n /** Consecutive failed automatic reads; manual refresh starts a new bounded sequence. */\n refreshFailures?: number;\n autoRefreshPaused?: boolean;\n note?: string;\n}\nexport class ConsoleError extends Error {\n constructor(readonly kind: 'auth' | 'permission' | 'network' | 'response' | 'rate-limit', readonly status?: number) {\n super(kind === 'auth' ? 'OpenDesign \u767B\u5F55\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55' : kind === 'permission' ? 'OpenDesign \u5F53\u524D\u767B\u5F55\u6001\u65E0\u6743\u8BFB\u53D6\u8BE5\u989D\u5EA6\u5C42' : kind === 'rate-limit' ? 'OpenDesign \u989D\u5EA6\u63A5\u53E3\u9650\u6D41\uFF0C\u8BF7\u7A0D\u540E\u5237\u65B0' : kind === 'response' ? 'OpenDesign \u989D\u5EA6\u63A5\u53E3\u8FD4\u56DE\u683C\u5F0F\u53D1\u751F\u53D8\u5316' : 'OpenDesign \u989D\u5EA6\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6');\n }\n}\nexport async function consoleJson(url: string, session: Session, signal?: AbortSignal, fetcher = fetch): Promise<unknown> {\n let response: Response;\n try {\n response = await fetcher(url, { headers: { ...attributionHeaders(), accept: 'application/json', ...session.headers }, signal: combinedSignal(signal, 20000), redirect: 'error' });\n } catch { throw new ConsoleError('network'); }\n if (response.status === 401 || response.status === 403) { await response.body?.cancel(); throw new ConsoleError(response.status === 401 ? 'auth' : 'permission', response.status); }\n if (!response.ok) { await response.body?.cancel(); throw new ConsoleError(response.status === 429 ? 'rate-limit' : 'network', response.status); }\n // Console responses are small; reject unexpected HTML/downloads without echoing it.\n const reader = response.body?.getReader();\n if (!reader) throw new ConsoleError('response');\n let size = 0, raw = '';\n const decoder = new TextDecoder();\n try {\n while (true) {\n const chunk = await reader.read();\n if (chunk.done) break;\n size += chunk.value.byteLength;\n if (size > 2 * 1024 * 1024) throw new ConsoleError('response');\n raw += decoder.decode(chunk.value, { stream: true });\n }\n raw += decoder.decode();\n } finally { await reader.cancel().catch(() => undefined); reader.releaseLock(); }\n let body: unknown;\n try { body = JSON.parse(raw); } catch { throw new ConsoleError('response'); }\n if (record(body) && (body.code === 401 || body.code === '401')) throw new ConsoleError('auth', 401);\n if (record(body) && (body.code === 403 || body.code === '403')) throw new ConsoleError('permission', 403);\n return body;\n}\nfunction number(value: unknown, negative = false): number | undefined {\n const n = typeof value === 'number' ? value : typeof value === 'string' && /^-?\\d+(\\.\\d+)?$/u.test(value.trim()) ? Number(value) : NaN;\n return Number.isFinite(n) && (negative || n >= 0) ? n : undefined;\n}\n/** Normalize a reported timestamp to ISO-8601; anything unparsable stays unknown. */\nfunction iso(value: unknown): string | undefined {\n return typeof value === 'string' && Number.isFinite(Date.parse(value)) ? new Date(value).toISOString() : undefined;\n}\nexport function normalizeQuota(body: unknown, summary?: unknown): Pick<QuotaSnapshot, 'windows' | 'balances' | 'tier' | 'eligible' | 'subscriptionPeriodStart' | 'subscriptionPeriodEnd'> {\n if (!record(body) || !(typeof body.eligible === 'boolean' || typeof body.tier === 'string' || body.tier === null || Array.isArray(body.windows))) throw new ConsoleError('response');\n const windows: QuotaWindow[] = [];\n for (const row of Array.isArray(body.windows) ? body.windows : []) {\n if (!record(row)) continue;\n const seconds = number(row.durationSeconds), used = number(row.usedCredits), limit = number(row.limitCredits), remaining = number(row.remainingCredits);\n if (seconds === undefined || seconds <= 0 || used === undefined || limit === undefined || limit <= 0) continue;\n const resetsAt = iso(row.resetsAt), windowStart = iso(row.windowStart);\n const resetMode = typeof row.resetMode === 'string' && row.resetMode.trim() ? row.resetMode.trim() : undefined;\n windows.push({ durationSeconds: seconds, used, limit, percent: Math.min(100, used / limit * 100), ...(remaining === undefined ? {} : { remaining }), ...(resetsAt === undefined ? {} : { resetsAt }), ...(windowStart === undefined ? {} : { windowStart }), ...(resetMode === undefined ? {} : { resetMode }) });\n }\n const membershipTier = record(summary) && typeof summary.membershipTier === 'string' ? summary.membershipTier.trim() : '';\n const tier = typeof body.tier === 'string' ? body.tier.trim() : body.tier === undefined && body.eligible !== false ? membershipTier : '';\n const eligible = typeof body.eligible === 'boolean' ? body.eligible : body.tier === null ? false : undefined;\n return { windows, balances: normalizeBalances(summary), ...normalizeSubscription(summary), ...(tier ? { tier } : {}), ...(eligible === undefined ? {} : { eligible }) };\n}\n/** Billing period of the subscription pool; absent fields stay unknown, never derived. */\nexport function normalizeSubscription(summary: unknown): Pick<QuotaSnapshot, 'subscriptionPeriodStart' | 'subscriptionPeriodEnd'> {\n if (!record(summary)) return {};\n const start = iso(summary.subscriptionCurrentPeriodStart), end = iso(summary.subscriptionCurrentPeriodEnd);\n return { ...(start === undefined ? {} : { subscriptionPeriodStart: start }), ...(end === undefined ? {} : { subscriptionPeriodEnd: end }) };\n}\nexport function normalizeBalances(summary: unknown): QuotaSnapshot['balances'] {\n if (!record(summary)) return {};\n const perUsd = number(summary.creditsPerUsd), balances = record(summary.balances) ? summary.balances : {};\n const subscription = number(balances.subscriptionCredits), recharge = number(balances.rechargeCredits), total = number(balances.totalAvailableCredits, true);\n const divisor = perUsd !== undefined && perUsd > 0 ? perUsd : undefined;\n const totalUsd = number(summary.balanceUsd, true) ?? number(summary.totalAvailableCreditsUsd, true) ?? (divisor !== undefined && total !== undefined ? total / divisor : undefined);\n return { ...(divisor !== undefined && subscription !== undefined ? { subscriptionUsd: subscription / divisor } : {}), ...(divisor !== undefined && recharge !== undefined ? { rechargeUsd: recharge / divisor } : {}), ...(totalUsd !== undefined ? { totalUsd } : {}) };\n}\nexport async function readQuota(session: Session, signal?: AbortSignal, fetcher = fetch): Promise<QuotaSnapshot> {\n const current = await consoleJson(CURRENT_URL, session, signal, fetcher);\n if (!record(current) || typeof current.workspaceId !== 'string' || !/^[A-Za-z0-9_-]{1,64}$/u.test(current.workspaceId)) throw new ConsoleError('response');\n const personal = current.workspaceType === 'personal';\n const [usage, billing] = await Promise.allSettled([\n consoleJson(usageUrl(current.workspaceId), session, signal, fetcher),\n personal ? consoleJson(SUMMARY_URL, session, signal, fetcher) : Promise.resolve(undefined),\n ]);\n // Never hide an authentication failure behind success from the other pool.\n for (const item of [usage, billing]) if (item.status === 'rejected' && item.reason instanceof ConsoleError && item.reason.kind === 'auth') throw item.reason;\n const summary = billing.status === 'fulfilled' ? billing.value : undefined;\n const common = { source: session.source, updatedAt: new Date().toISOString() };\n let normalized: ReturnType<typeof normalizeQuota>;\n try {\n if (usage.status === 'rejected') throw usage.reason;\n normalized = normalizeQuota(usage.value, summary);\n } catch (error) {\n const balances = normalizeBalances(summary);\n if (!Object.keys(balances).length) throw error;\n return { ...common, state: 'partial', windows: [], balances, ...normalizeSubscription(summary), note: '\u94B1\u5305\u5DF2\u8BFB\u53D6\uFF1B\u5957\u9910\u8D60\u9001\u989D\u5EA6\u6682\u4E0D\u53EF\u786E\u8BA4' };\n }\n const missingWindows = normalized.eligible !== false && !normalized.windows.length;\n const noSubscription = normalized.eligible === false && !normalized.windows.length;\n const missingBalances = personal && Object.keys(normalized.balances).length < 3;\n const partial = missingWindows || missingBalances || !personal;\n const note = !personal ? '\u56E2\u961F\u6216\u672A\u77E5\u5DE5\u4F5C\u533A\uFF1A\u8D26\u53F7\u94B1\u5305\u53E3\u5F84\u672A\u6838\u5B9E\uFF0C\u6682\u4E0D\u663E\u793A'\n : missingWindows ? '\u5957\u9910\u989D\u5EA6\u7A97\u53E3\u6682\u4E0D\u53EF\u786E\u8BA4'\n : noSubscription ? '\u8BE5\u8D26\u53F7\u6CA1\u6709 Design Plan \u8BA2\u9605\uFF1B\u94B1\u5305\u4F59\u989D\u7167\u5E38\u663E\u793A'\n : missingBalances ? '\u90E8\u5206\u94B1\u5305\u4F59\u989D\u6682\u4E0D\u53EF\u786E\u8BA4' : undefined;\n return { ...common, ...normalized, state: partial ? 'partial' : 'ok', ...(note === undefined ? {} : { note }) };\n}\n", "import { execFile } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { isAbsolute, join } from 'node:path';\nimport type { AuthSession } from './auth.js';\nimport { normalizeQuota, normalizeBalances, consoleJson, ConsoleError, type QuotaSnapshot } from './quota.js';\nimport { record, combinedSignal } from './util.js';\n\nexport type VelaRunner = (args: readonly string[], signal: AbortSignal, profile?: string) => Promise<unknown>;\nexport function locateVela(env: NodeJS.ProcessEnv = process.env, platform = process.platform): string | undefined {\n const explicit = env.OPENDESIGN_VELA_PATH?.trim();\n if (explicit && isAbsolute(explicit) && existsSync(explicit)) return explicit;\n if (platform !== 'win32' || !env.LOCALAPPDATA) return;\n const path = join(env.LOCALAPPDATA, 'Programs', 'Open Design', 'resources', 'open-design', 'bin', 'vela.exe');\n return existsSync(path) ? path : undefined;\n}\n/** Read-only official CLI, fixed argv and bounded output; stderr is never projected. */\nexport const runVela: VelaRunner = (args, signal, profile) => new Promise((resolve, reject) => {\n const binary = locateVela();\n if (!binary) return reject(new ConsoleError('network'));\n execFile(binary, [...args], { timeout: 8000, maxBuffer: 2 * 1024 * 1024, windowsHide: true, signal, encoding: 'utf8', env: { ...process.env, ...(profile ? { VELA_PROFILE: profile, OPEN_DESIGN_AMR_PROFILE: profile } : {}) } }, (error, stdout) => {\n if (error) return reject(new ConsoleError('network'));\n try { resolve(JSON.parse(stdout)); } catch { reject(new ConsoleError('response')); }\n });\n});\n/** Desktop tokens can have narrower scopes than console cookies; never invent an HTTP funding-check. */\nexport async function readDesktopQuota(session: AuthSession, signal?: AbortSignal, runner: VelaRunner = runVela, fetcher = fetch): Promise<QuotaSnapshot> {\n const deadline = combinedSignal(signal, 18000);\n const cli = (async () => {\n const workspace = await runner(['team-projects', 'list'], deadline, session.profile);\n if (!record(workspace) || typeof workspace.workspaceId !== 'string' || !/^[A-Za-z0-9_-]{1,64}$/u.test(workspace.workspaceId)) throw new ConsoleError('response');\n const funding = await runner(['billing', 'funding-check', '--workspace-id', workspace.workspaceId, '--format', 'json'], deadline, session.profile);\n if (!record(funding) || !record(funding.codingPlan)) throw new ConsoleError('response');\n // `generatedAt` is the server-side reading time; only an ISO value is kept.\n const generatedAt = typeof funding.generatedAt === 'string' && Number.isFinite(Date.parse(funding.generatedAt)) ? new Date(funding.generatedAt).toISOString() : undefined;\n return { ...normalizeQuota(funding.codingPlan), ...(typeof funding.balanceUsd === 'string' ? { balance: funding.balanceUsd } : {}), ...(generatedAt === undefined ? {} : { generatedAt }) };\n })();\n const [wallet, funding] = await Promise.allSettled([\n consoleJson(`${session.apiUrl}/api/v1/wallet/balance`, session, deadline, fetcher),\n cli,\n ]);\n const walletBalances = wallet.status === 'fulfilled' ? normalizeBalances(wallet.value) : {};\n const cliBalances = funding.status === 'fulfilled' && 'balance' in funding.value ? normalizeBalances({ balanceUsd: funding.value.balance }) : {};\n const windows = funding.status === 'fulfilled' ? funding.value.windows : [];\n const balances = { ...cliBalances, ...walletBalances };\n const eligible = funding.status === 'fulfilled' ? funding.value.eligible : undefined;\n // A recognised `eligible: false` with no windows is a definite answer (\"no Design Plan\"), not a\n // failed read: it must not be thrown away, nor turned into a fabricated 0% window.\n const noSubscription = funding.status === 'fulfilled' && eligible === false && windows.length === 0;\n if (!windows.length && !Object.keys(balances).length && !noSubscription) {\n if (wallet.status === 'rejected' && wallet.reason instanceof ConsoleError && (wallet.reason.kind === 'auth' || wallet.reason.kind === 'permission')) throw wallet.reason;\n throw new ConsoleError('network');\n }\n const tier = (funding.status === 'fulfilled' ? funding.value.tier : undefined) ?? session.plan;\n const updatedAt = (funding.status === 'fulfilled' && funding.value.generatedAt) || new Date().toISOString();\n // The subscription pool and its billing period are only evidenced on the console-cookie channel\n // (`billing/summary`); `vela` has no command that reports them. Leave both unknown instead of\n // inferring them, and say which half is missing so the host can fall back deliberately.\n const note = noSubscription\n ? '\u684C\u9762\u767B\u5F55\u6001\u663E\u793A\u8BE5\u8D26\u53F7\u6CA1\u6709 Design Plan \u8BA2\u9605\uFF1B\u672A\u8BFB\u5230\u7684\u5206\u6C60\u4FDD\u6301\u672A\u77E5\u3002\u5982\u9700\u5B8C\u6574\u5206\u6C60\uFF0C\u8BF7\u5728\u8FDE\u63A5\u9875\u767B\u5F55\u5E76\u5173\u95ED\u201C\u4F18\u5148\u684C\u9762\u767B\u5F55\u6001\u201D\u3002'\n : !windows.length\n ? '\u684C\u9762\u767B\u5F55\u6001\u672A\u8FD4\u56DE\u5957\u9910\u7A97\u53E3\uFF1B\u5DF2\u8BFB\u5230\u7684\u94B1\u5305\u4F59\u989D\u7167\u5E38\u663E\u793A\uFF0C\u672A\u8BFB\u5230\u7684\u5206\u6C60\u4FDD\u6301\u672A\u77E5\u3002\u5982\u9700\u5B8C\u6574\u5206\u6C60\uFF0C\u8BF7\u5728\u8FDE\u63A5\u9875\u767B\u5F55\u5E76\u5173\u95ED\u201C\u4F18\u5148\u684C\u9762\u767B\u5F55\u6001\u201D\u3002'\n : '\u684C\u9762\u767B\u5F55\u6001\u90E8\u5206\u63A5\u53E3\u6743\u9650\u53D7\u9650\uFF1B\u672A\u8BFB\u5230\u7684\u5206\u6C60\u663E\u793A\u672A\u77E5\u3002\u5982\u9700\u5B8C\u6574\u5206\u6C60\uFF0C\u8BF7\u5728\u8FDE\u63A5\u9875\u767B\u5F55\u5E76\u5173\u95ED\u201C\u4F18\u5148\u684C\u9762\u767B\u5F55\u6001\u201D\u3002';\n return { state: 'partial', source: 'desktop', updatedAt, windows, balances,\n ...(tier ? { tier } : {}), ...(eligible === undefined ? {} : { eligible }),\n note,\n };\n}\n", "/** Shared JSON value types and allowlist parsers; no credential or opaque Host state is returned. */\n\nimport type { QuotaSnapshot, QuotaWindow, SessionSource } from './quota.js';\nimport { record } from './util.js';\nimport { API_PROTOCOL_IDS, type ApiProtocol } from './protocol-options.js';\nimport { parseModelSettingsMap, type ModelSettingsMap } from './model-settings.js';\n\n// Type-only: browser imports must not pull in quota.ts runtime dependencies.\nexport type { QuotaSnapshot, QuotaWindow, SessionSource } from './quota.js';\n\n/** npm package that owns the Remote methods; must satisfy typert's segment rules. */\nexport const REMOTE_PACKAGE = 'dsh-opendesign-corouter';\n/** Cordis service key and wire namespace. The Client resolves `remote.<this>`. */\nexport const REMOTE_SERVICE = 'openDesignCoRouter';\n\n/** Upper bounds on every accepted string, so an oversized Host value fails here. */\nconst MAX_REVISION = 256;\nconst MAX_JOB_ID = 128;\nconst MAX_BASE_URL = 2048;\nconst MAX_ENV_REF = 128;\nconst MAX_TEXT = 4096;\nconst MAX_MESSAGE = 1024;\nconst MAX_TIER = 256;\nconst MAX_MODELS = 512;\nconst MAX_WINDOWS = 64;\n/** Printable ASCII only: what an HTTP header field can carry verbatim. */\nconst MAX_API_KEY = 16_384;\nconst HTTP_ASCII = /^[\\x21-\\x7e]+$/u;\nconst ENV_REF = /^[A-Za-z_][A-Za-z0-9_]*$/u;\nconst MODEL_ID = /^[A-Za-z0-9._:/-]{1,128}$/u;\n\n/** Live switches of this plugin, mirrored for a settings page that only has this RPC. */\nexport interface StatusConfig {\n emptyTurnGuard: boolean;\n useDesktopCredential: boolean;\n baseURL: string;\n /** Credential reference name (an env var or a DSH credential ref), never the value. */\n apiKeyEnv: string;\n apiProtocol?: ApiProtocol;\n modelSettings?: ModelSettingsMap;\n requestTimeoutMs?: number;\n streamIdleTimeoutMs?: number;\n quotaRefreshSeconds?: number;\n}\n\n/** One selectable model; `group` selects which of the two Providers owns it. */\nexport interface StatusModel {\n id: string;\n name: string;\n group: 'plan' | 'paid';\n enabled?: boolean;\n contextWindow?: number;\n maxOutputTokens?: number;\n reasoningEfforts?: readonly string[];\n}\n\n/** Terminal-or-in-flight phases a login job may report. */\nexport type LoginPhase = 'idle' | 'launching' | 'waiting' | 'verifying' | 'success' | 'cancelled' | 'error';\n\n/** Credential-free view of the independent console login. */\nexport interface LoginState {\n jobId: string | null;\n state: LoginPhase;\n message?: string;\n startedAt?: string;\n finishedAt?: string;\n}\n\n/** Everything the settings/usage surface may read; no field is derived from a secret. */\nexport interface Status {\n /** Opaque Host revision of the credential record; passed back on every write. */\n revision: string;\n apiKeyConfigured: boolean;\n sessionSource?: SessionSource;\n quota: QuotaSnapshot;\n login: LoginState;\n config: StatusConfig;\n /** Turns the empty-turn guard actually intercepted since process start. */\n guardedTurns: number;\n models: readonly StatusModel[];\n modelsSource?: 'builtin' | 'openai';\n modelsUpdatedAt?: string;\n modelsError?: string;\n}\n\nexport interface StartLoginRequest {\n expectedRevision: string;\n}\n\nexport interface CancelLoginRequest {\n jobId: string;\n}\n\nexport interface SaveApiKeyRequest {\n value: string;\n expectedRevision: string;\n}\n\nconst LOGIN_PHASES: readonly LoginPhase[] = ['idle', 'launching', 'waiting', 'verifying', 'success', 'cancelled', 'error'];\nconst QUOTA_STATES: readonly QuotaSnapshot['state'][] = ['ok', 'partial', 'need-login', 'error'];\nconst SESSION_SOURCES: readonly SessionSource[] = ['desktop', 'login', 'environment'];\nconst MODEL_GROUPS: readonly StatusModel['group'][] = ['plan', 'paid'];\n\nfunction text(value: unknown, label: string, max: number): string {\n if (typeof value !== 'string' || value.length === 0 || value.length > max) throw new Error(`${label} \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32\uFF08\u6700\u591A ${max} \u5B57\u7B26\uFF09`);\n return value;\n}\n\nfunction isoTime(value: unknown, label: string): string {\n const time = text(value, label, 64);\n if (!Number.isFinite(Date.parse(time))) throw new Error(`${label} \u5FC5\u987B\u662F ISO \u65F6\u95F4\u5B57\u7B26\u4E32`);\n return time;\n}\n\nfunction flag(value: unknown, label: string): boolean {\n if (typeof value !== 'boolean') throw new Error(`${label} \u5FC5\u987B\u662F\u5E03\u5C14\u503C`);\n return value;\n}\n\nfunction count(value: unknown, label: string): number {\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) throw new Error(`${label} \u5FC5\u987B\u662F\u975E\u8D1F\u6574\u6570`);\n return value;\n}\n\n/** A finite number, optionally non-negative. */\nfunction amount(value: unknown, label: string, negative = false): number {\n if (typeof value !== 'number' || !Number.isFinite(value) || (!negative && value < 0)) throw new Error(`${label} \u5FC5\u987B\u662F${negative ? '' : '\u975E\u8D1F'}\u6709\u9650\u6570\u5B57`);\n return value;\n}\n\nfunction positiveInteger(value: unknown, label: string, max: number): number {\n const result = count(value, label);\n if (result === 0 || result > max) throw new Error(`${label} \u8D85\u51FA\u8303\u56F4`);\n return result;\n}\nfunction parseEfforts(value: unknown): string[] {\n if (!Array.isArray(value) || value.length > 16) throw new Error('\u6A21\u578B\u601D\u8003\u6863\u4F4D\u683C\u5F0F\u65E0\u6548');\n return value.map(item => text(item, '\u601D\u8003\u6863\u4F4D', 32));\n}\nfunction member<T extends string>(value: unknown, allowed: readonly T[], label: string): T {\n const hit = allowed.find(candidate => candidate === value);\n if (hit === undefined) throw new Error(`${label} \u4E0D\u5728\u5141\u8BB8\u7684\u53D6\u503C\u5185`);\n return hit;\n}\n\nfunction parseQuotaWindow(value: unknown): QuotaWindow {\n if (!record(value)) throw new Error('\u989D\u5EA6\u7A97\u53E3\u5FC5\u987B\u662F\u5BF9\u8C61');\n const durationSeconds = amount(value.durationSeconds, '\u989D\u5EA6\u7A97\u53E3\u65F6\u957F');\n if (durationSeconds <= 0) throw new Error('\u989D\u5EA6\u7A97\u53E3\u65F6\u957F\u5FC5\u987B\u5927\u4E8E 0');\n const limit = amount(value.limit, '\u989D\u5EA6\u4E0A\u9650');\n if (limit <= 0) throw new Error('\u989D\u5EA6\u4E0A\u9650\u5FC5\u987B\u5927\u4E8E 0');\n return {\n durationSeconds,\n used: amount(value.used, '\u5DF2\u7528\u989D\u5EA6'),\n limit,\n ...(value.remaining === undefined ? {} : { remaining: amount(value.remaining, '\u5269\u4F59\u989D\u5EA6') }),\n percent: Math.min(100, Math.max(0, amount(value.percent, '\u5DF2\u7528\u767E\u5206\u6BD4'))),\n ...(value.resetsAt === undefined ? {} : { resetsAt: isoTime(value.resetsAt, '\u989D\u5EA6\u91CD\u7F6E\u65F6\u95F4') }),\n ...(value.windowStart === undefined ? {} : { windowStart: isoTime(value.windowStart, '\u989D\u5EA6\u7A97\u53E3\u5F00\u59CB\u65F6\u95F4') }),\n ...(value.resetMode === undefined ? {} : { resetMode: text(value.resetMode, '\u989D\u5EA6\u5237\u65B0\u65B9\u5F0F', 128) }),\n };\n}\n\n/** Rebuild a `QuotaSnapshot` from an allowlist; unknown keys are dropped. */\nexport function parseQuotaSnapshot(value: unknown): QuotaSnapshot {\n if (!record(value)) throw new Error('\u989D\u5EA6\u5FEB\u7167\u5FC5\u987B\u662F\u5BF9\u8C61');\n const windows = value.windows;\n if (!Array.isArray(windows) || windows.length > MAX_WINDOWS) throw new Error(`\u989D\u5EA6\u7A97\u53E3\u5FC5\u987B\u662F\u6570\u7EC4\uFF08\u6700\u591A ${MAX_WINDOWS} \u9879\uFF09`);\n const balances = value.balances === undefined ? {} : value.balances;\n if (!record(balances)) throw new Error('\u989D\u5EA6\u4F59\u989D\u5FC5\u987B\u662F\u5BF9\u8C61');\n return {\n state: member(value.state, QUOTA_STATES, '\u989D\u5EA6\u72B6\u6001'),\n ...(value.source === undefined ? {} : { source: member(value.source, SESSION_SOURCES, '\u989D\u5EA6\u6765\u6E90') }),\n updatedAt: isoTime(value.updatedAt, '\u989D\u5EA6\u66F4\u65B0\u65F6\u95F4'),\n ...(value.subscriptionPeriodStart === undefined ? {} : { subscriptionPeriodStart: isoTime(value.subscriptionPeriodStart, '\u8BA2\u9605\u5468\u671F\u5F00\u59CB\u65F6\u95F4') }),\n ...(value.subscriptionPeriodEnd === undefined ? {} : { subscriptionPeriodEnd: isoTime(value.subscriptionPeriodEnd, '\u8BA2\u9605\u5468\u671F\u7ED3\u675F\u65F6\u95F4') }),\n ...(value.nextRefreshAt === undefined ? {} : { nextRefreshAt: isoTime(value.nextRefreshAt, '\u4E0B\u6B21\u81EA\u52A8\u5237\u65B0\u65F6\u95F4') }),\n ...(value.stale === undefined ? {} : { stale: flag(value.stale, '\u5386\u53F2\u989D\u5EA6\u8BFB\u6570') }),\n ...(value.refreshFailures === undefined ? {} : { refreshFailures: count(value.refreshFailures, '\u8FDE\u7EED\u5237\u65B0\u5931\u8D25\u6B21\u6570') }),\n ...(value.autoRefreshPaused === undefined ? {} : { autoRefreshPaused: flag(value.autoRefreshPaused, '\u81EA\u52A8\u5237\u65B0\u6682\u505C\u72B6\u6001') }),\n ...(value.tier === undefined ? {} : { tier: text(value.tier, '\u5957\u9910\u540D', MAX_TIER) }),\n ...(value.eligible === undefined ? {} : { eligible: flag(value.eligible, '\u5957\u9910\u8D44\u683C') }),\n windows: windows.map(parseQuotaWindow),\n balances: {\n ...(balances.subscriptionUsd === undefined ? {} : { subscriptionUsd: amount(balances.subscriptionUsd, '\u8BA2\u9605\u4F59\u989D') }),\n ...(balances.rechargeUsd === undefined ? {} : { rechargeUsd: amount(balances.rechargeUsd, '\u5145\u503C\u4F59\u989D') }),\n ...(balances.totalUsd === undefined ? {} : { totalUsd: amount(balances.totalUsd, '\u53EF\u7528\u4F59\u989D', true) }),\n },\n ...(value.note === undefined ? {} : { note: text(value.note, '\u989D\u5EA6\u8BF4\u660E', MAX_TEXT) }),\n };\n}\n\n/** Rebuild a `LoginState` from an allowlist; the job's secret material never had a field here. */\nexport function parseLoginState(value: unknown): LoginState {\n if (!record(value)) throw new Error('\u767B\u5F55\u72B6\u6001\u5FC5\u987B\u662F\u5BF9\u8C61');\n const jobId = value.jobId;\n if (jobId !== null && jobId !== undefined && typeof jobId !== 'string') throw new Error('\u767B\u5F55\u4EFB\u52A1 id \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6216 null');\n return {\n jobId: typeof jobId === 'string' && jobId.length > 0 ? text(jobId, '\u767B\u5F55\u4EFB\u52A1 id', MAX_JOB_ID) : null,\n state: member(value.state, LOGIN_PHASES, '\u767B\u5F55\u9636\u6BB5'),\n ...(value.message === undefined ? {} : { message: text(value.message, '\u767B\u5F55\u8BF4\u660E', MAX_MESSAGE) }),\n ...(value.startedAt === undefined ? {} : { startedAt: isoTime(value.startedAt, '\u767B\u5F55\u5F00\u59CB\u65F6\u95F4') }),\n ...(value.finishedAt === undefined ? {} : { finishedAt: isoTime(value.finishedAt, '\u767B\u5F55\u7ED3\u675F\u65F6\u95F4') }),\n };\n}\n\nfunction parseStatusModel(value: unknown): StatusModel {\n if (!record(value)) throw new Error('\u6A21\u578B\u6761\u76EE\u5FC5\u987B\u662F\u5BF9\u8C61');\n const id = text(value.id, '\u6A21\u578B id', 128);\n if (!MODEL_ID.test(id)) throw new Error('\u6A21\u578B id \u542B\u4E0D\u5141\u8BB8\u7684\u5B57\u7B26');\n return {\n id,\n name: text(value.name, '\u6A21\u578B\u540D', 128),\n group: member(value.group, MODEL_GROUPS, '\u6A21\u578B\u5206\u7EC4'),\n ...(value.enabled === undefined ? {} : { enabled: flag(value.enabled, '\u6A21\u578B\u542F\u7528\u72B6\u6001') }),\n ...(value.contextWindow === undefined ? {} : { contextWindow: positiveInteger(value.contextWindow, '\u4E0A\u4E0B\u6587\u9884\u7B97', 100_000_000) }),\n ...(value.maxOutputTokens === undefined ? {} : { maxOutputTokens: positiveInteger(value.maxOutputTokens, '\u6700\u5927\u8F93\u51FA', 10_000_000) }),\n ...(value.reasoningEfforts === undefined ? {} : { reasoningEfforts: parseEfforts(value.reasoningEfforts) }),\n };\n}\n\nfunction parseStatusConfig(value: unknown): StatusConfig {\n if (!record(value)) throw new Error('\u914D\u7F6E\u89C6\u56FE\u5FC5\u987B\u662F\u5BF9\u8C61');\n const apiKeyEnv = text(value.apiKeyEnv, '\u51ED\u636E\u5F15\u7528\u540D', MAX_ENV_REF);\n if (!ENV_REF.test(apiKeyEnv)) throw new Error('\u51ED\u636E\u5F15\u7528\u540D\u5FC5\u987B\u662F\u5408\u6CD5\u6807\u8BC6\u7B26');\n return {\n emptyTurnGuard: flag(value.emptyTurnGuard, '\u7A7A\u8F6E\u4FDD\u62A4\u5F00\u5173'),\n useDesktopCredential: flag(value.useDesktopCredential, '\u684C\u9762\u767B\u5F55\u6001\u5F00\u5173'),\n baseURL: text(value.baseURL, '\u63A8\u7406\u5730\u5740', MAX_BASE_URL),\n apiKeyEnv,\n ...(value.apiProtocol === undefined ? {} : { apiProtocol: member(value.apiProtocol, API_PROTOCOL_IDS, '\u63A8\u7406\u534F\u8BAE') }),\n ...(value.modelSettings === undefined ? {} : { modelSettings: parseModelSettingsMap(value.modelSettings) }),\n ...(value.requestTimeoutMs === undefined ? {} : { requestTimeoutMs: positiveInteger(value.requestTimeoutMs, '\u8BF7\u6C42\u8D85\u65F6', 3_600_000) }),\n ...(value.streamIdleTimeoutMs === undefined ? {} : { streamIdleTimeoutMs: positiveInteger(value.streamIdleTimeoutMs, '\u6D41\u7A7A\u95F2\u8D85\u65F6', 1_800_000) }),\n ...(value.quotaRefreshSeconds === undefined ? {} : { quotaRefreshSeconds: positiveInteger(value.quotaRefreshSeconds, '\u81EA\u52A8\u5237\u65B0\u95F4\u9694', 3600) }),\n };\n}\n\n/** Rebuild a `Status` from an allowlist; the credential itself has no field here. */\nexport function parseStatus(value: unknown): Status {\n if (!record(value)) throw new Error('\u72B6\u6001\u5FC5\u987B\u662F\u5BF9\u8C61');\n const models = value.models;\n if (!Array.isArray(models) || models.length > MAX_MODELS) throw new Error(`\u6A21\u578B\u5217\u8868\u5FC5\u987B\u662F\u6570\u7EC4\uFF08\u6700\u591A ${MAX_MODELS} \u9879\uFF09`);\n const ids = new Set<string>();\n const parsed = models.map(parseStatusModel);\n for (const model of parsed) {\n if (ids.has(model.id)) throw new Error(`\u6A21\u578B\u5217\u8868\u91CD\u590D\u4E86 id \"${model.id}\"`);\n ids.add(model.id);\n }\n return {\n revision: text(value.revision, '\u914D\u7F6E\u7248\u672C', MAX_REVISION),\n apiKeyConfigured: flag(value.apiKeyConfigured, '\u51ED\u636E\u662F\u5426\u5C31\u7EEA'),\n ...(value.sessionSource === undefined ? {} : { sessionSource: member(value.sessionSource, SESSION_SOURCES, '\u767B\u5F55\u6001\u6765\u6E90') }),\n quota: parseQuotaSnapshot(value.quota),\n login: parseLoginState(value.login),\n config: parseStatusConfig(value.config),\n guardedTurns: count(value.guardedTurns, '\u5DF2\u62E6\u622A\u7A7A\u8F6E\u6570'),\n models: parsed,\n ...(value.modelsSource === undefined ? {} : { modelsSource: member(value.modelsSource, ['builtin', 'openai'] as const, '\u6A21\u578B\u76EE\u5F55\u6765\u6E90') }),\n ...(value.modelsUpdatedAt === undefined ? {} : { modelsUpdatedAt: isoTime(value.modelsUpdatedAt, '\u6A21\u578B\u66F4\u65B0\u65F6\u95F4') }),\n ...(value.modelsError === undefined ? {} : { modelsError: text(value.modelsError, '\u6A21\u578B\u66F4\u65B0\u63D0\u793A', MAX_MESSAGE) }),\n };\n}\n\n/** `{ expectedRevision }`: the revision the UI saw before the user started a login. */\nexport function parseStartLoginRequest(value: unknown): StartLoginRequest {\n if (!record(value)) throw new Error('\u767B\u5F55\u8BF7\u6C42\u5FC5\u987B\u662F\u5BF9\u8C61');\n return { expectedRevision: text(value.expectedRevision, '\u914D\u7F6E\u7248\u672C', MAX_REVISION) };\n}\n\n/** `{ jobId }`: the attempt to cancel; a stale id is the Host's call to refuse. */\nexport function parseCancelLoginRequest(value: unknown): CancelLoginRequest {\n if (!record(value)) throw new Error('\u53D6\u6D88\u8BF7\u6C42\u5FC5\u987B\u662F\u5BF9\u8C61');\n return { jobId: text(value.jobId, '\u767B\u5F55\u4EFB\u52A1 id', MAX_JOB_ID) };\n}\n\n/**\n * `{ value, expectedRevision }`: the raw key plus the revision it replaces.\n *\n * The key is trimmed exactly once, here, because every real source (settings field,\n * `.env` line, shell export) carries surrounding whitespace. Anything outside\n * printable ASCII is refused rather than handed to `fetch`, whose ByteString error\n * names a UTF-16 code point instead of the setting to fix.\n */\nexport function parseSaveApiKeyRequest(value: unknown): SaveApiKeyRequest {\n if (!record(value)) throw new Error('\u4FDD\u5B58\u8BF7\u6C42\u5FC5\u987B\u662F\u5BF9\u8C61');\n if (typeof value.value !== 'string') throw new Error('API Key \u5FC5\u987B\u662F\u5B57\u7B26\u4E32');\n const key = value.value.trim();\n if (!HTTP_ASCII.test(key)) throw new Error('API Key \u4E3A\u7A7A\u6216\u542B\u6709\u4E0D\u53EF\u7528\u4E8E HTTP \u8BF7\u6C42\u5934\u7684\u5B57\u7B26');\n if (key.length > MAX_API_KEY) throw new Error(`API Key \u4E0D\u80FD\u8D85\u8FC7 ${MAX_API_KEY} \u5B57\u7B26`);\n return { value: key, expectedRevision: text(value.expectedRevision, '\u914D\u7F6E\u7248\u672C', MAX_REVISION) };\n}\n"],
5
- "mappings": "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",
6
- "names": ["randomUUID", "LlmError", "LlmError", "text", "LlmError", "LlmError", "LlmError", "LlmError", "name", "count", "text", "LlmError", "text", "LlmError", "LlmError", "messages", "LlmError", "LlmError", "ToolCallId", "LlmError", "textOnlyImageText", "text", "LlmError", "messages", "content", "effort", "count", "ToolCallId", "text", "LlmError", "ToolCallId", "REASONING_EFFORTS", "text", "LlmError", "effort", "count", "name", "ToolCallId", "call", "content", "LlmError", "LlmError", "messages", "effort", "raw", "attributionHeaders", "MODEL_ID", "MESSAGES", "name", "openAiBaseURL", "attributionHeaders", "text", "errorCode", "attributionHeaders", "attributionHeaders", "join", "join", "funding", "MAX_MODELS", "MODEL_ID", "flag", "randomUUID", "name", "group", "count", "LlmError", "config"]
3
+ "sources": ["../src/index.ts", "../src/adapter.ts", "../src/catalog.ts", "../src/config.ts", "../src/protocol-options.ts", "../src/model-settings.ts", "../src/conversion.ts", "../src/stream.ts", "../src/util.ts", "../src/protocols/errors.ts", "../src/protocols/sse.ts", "../src/empty-turn.ts", "../src/protocols/index.ts", "../src/protocols/chat-completions.ts", "../src/protocols/headers.ts", "../src/protocols/messages.ts", "../src/protocols/parts.ts", "../src/protocols/usage.ts", "../src/protocols/responses.ts", "../src/model-discovery.ts", "../src/auth.ts", "../src/login.ts", "../src/quota.ts", "../src/desktop-quota.ts", "../src/remote.ts"],
4
+ "sourcesContent": ["import { randomUUID, createHash } from 'node:crypto';\nimport type { Context } from '@deepseek-ai/cordis';\nimport { credentialKey, credentialRef, type CredentialRecord, type CredentialProvider } from '@deepseek-ai/dsh-credentials';\nimport { launchEnvironmentOf } from '@deepseek-ai/dsh-launch-environment';\nimport { Remote, RemoteError, TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';\nimport type {} from '@deepseek-ai/dsh-typert-registry';\nimport type {} from '@deepseek-ai/dsh-attachment';\nimport type {} from '@deepseek-ai/dsh-settings';\nimport type {} from '@deepseek-ai/cordis-plugin-loader';\nimport { LlmError } from '@deepseek-ai/dsh-llm';\nimport { CoRouterAdapter } from './adapter.js';\nimport { fetchModelCatalog, ModelDiscoveryError } from './model-discovery.js';\nimport { isModelEnabled } from './model-settings.js';\nimport type { CatalogModel } from './catalog.js';\nimport { Config, SETTINGS_NS, PLAN_PROVIDER, PAID_PROVIDER, readConfig, type LiveConfig } from './config.js';\nimport { MODELS } from './catalog.js';\nimport { resolveSession, cookieSession, type LoginGrant } from './auth.js';\nimport { ConsoleLogin } from './login.js';\nimport { readQuota, ConsoleError, type QuotaSnapshot } from './quota.js';\nimport { readDesktopQuota } from './desktop-quota.js';\nimport { record } from './util.js';\nimport { parseStatus, parseLoginState, parseStartLoginRequest as parseStartLogin, parseCancelLoginRequest as parseCancelLogin, parseSaveApiKeyRequest as parseSaveApiKey,\n type Status, type LoginState, type StartLoginRequest, type CancelLoginRequest, type SaveApiKeyRequest } from './remote.js';\n\nexport { Config } from './config.js';\nexport { CoRouterAdapter } from './adapter.js';\nexport { MODELS } from './catalog.js';\nexport const name = 'llm-opendesign-corouter';\nexport const inject = ['llm'];\nconst API_KEY = credentialKey(name, 'api-key');\nconst SESSION = credentialKey(name, 'console');\nconst hash = (value: unknown) => createHash('sha256').update(JSON.stringify(value) ?? '').digest('hex');\nconst needLogin = (): QuotaSnapshot => ({ state: 'need-login', updatedAt: new Date().toISOString(), windows: [], balances: {}, note: '\u5C1A\u672A\u8BFB\u53D6\u989D\u5EA6\uFF1B\u53EF\u4F7F\u7528\u684C\u9762\u767B\u5F55\u6001\u6216\u5728\u8FDE\u63A5\u9875\u767B\u5F55' });\ninterface CapturedState {\n apiRecord: CredentialRecord | undefined; sessionRecord: CredentialRecord | undefined;\n key: string | undefined; config: ReturnType<typeof readConfig>;\n}\ninterface LoginCapture { revision: string; sessionHash: string; configHash: string }\nexport interface HostDependencies {\n resolveSession: typeof resolveSession;\n readQuota: typeof readQuota;\n readDesktopQuota: typeof readDesktopQuota;\n fetchModels?: typeof fetchModelCatalog;\n modelsChanged?: () => void;\n}\nfunction grantOf(value: CredentialRecord | undefined): LoginGrant | undefined {\n if (value?.kind !== 'grant' || !record(value.payload) || typeof value.payload.cookie !== 'string') return;\n return { cookie: value.payload.cookie, ...(typeof value.payload.expiresAt === 'number' ? { expiresAt: value.payload.expiresAt } : {}) };\n}\nexport class OpenDesignCoRouterService extends TypertRemoteService {\n private readonly _config: () => ReturnType<typeof readConfig>;\n private readonly _login: ConsoleLogin;\n private readonly _lifetime = new AbortController();\n private _revision = randomUUID();\n private _fingerprint = '';\n private _quota = needLogin();\n private _quotaAt = 0;\n private _quotaConfig = '';\n private _quotaIdentity: string | undefined;\n private _quotaEpoch = 0;\n private _quotaPending: Promise<QuotaSnapshot> | undefined;\n private _quotaController: AbortController | undefined;\n guardedTurns: number = 0;\n private _models: readonly CatalogModel[] = MODELS;\n private _modelsUpdatedAt: string | undefined;\n private _modelsError: string | undefined;\n private _modelsFingerprint = '';\n private _modelsEpoch = 0;\n private _modelsPending: Promise<Status> | undefined;\n private _modelsController: AbortController | undefined;\n modelCatalog(): readonly CatalogModel[] { return this._models; }\n constructor(ctx: Context, config: () => ReturnType<typeof readConfig>, readonly dependencies: HostDependencies = { resolveSession, readQuota, readDesktopQuota }) {\n super(ctx, 'openDesignCoRouter');\n this._config = config;\n this._login = new ConsoleLogin({\n capture: async expectedRevision => {\n const state = await this._state();\n this._expect(expectedRevision);\n this._credentials();\n return { revision: expectedRevision, sessionHash: hash(state.sessionRecord), configHash: hash(state.config) } satisfies LoginCapture;\n },\n verify: async (cookie, signal) => {\n const session = cookieSession(cookie, 'login');\n if (!session) throw new ConsoleError('auth');\n const quota = await this.dependencies.readQuota(session, signal);\n return { balanceOk: true, coverage: quota.state === 'ok' ? 'complete' : 'partial', windows: quota.windows };\n },\n commit: async (cookie, captured, signal, expiresAt) => {\n if (!record(captured) || typeof captured.revision !== 'string' || typeof captured.sessionHash !== 'string' || typeof captured.configHash !== 'string') throw this._conflict();\n await this._state();\n this._expect(captured.revision);\n signal.throwIfAborted();\n await this._credentials().modifyRecord(SESSION, async current => {\n signal.throwIfAborted();\n if (hash(current) !== captured.sessionHash || hash(this._config()) !== captured.configHash) throw this._conflict();\n return { kind: 'grant', payload: { cookie, expiresAt, savedAt: new Date().toISOString() } };\n });\n this._invalidateQuota();\n },\n });\n ctx.effect(() => () => { this._lifetime.abort(); this._login.dispose(); });\n }\n private _credentials(): CredentialProvider {\n const service = this.ctx.get('credentials');\n if (!service) throw new RemoteError('opendesign/credentials-unavailable', 'DSH \u51ED\u636E\u670D\u52A1\u4E0D\u53EF\u7528\uFF1B\u53EF\u5148\u4F7F\u7528\u542F\u52A8\u73AF\u5883\u53D8\u91CF', undefined);\n return service;\n }\n async resolveApiKey(ref: string): Promise<string | undefined> {\n const credentials = this.ctx.get('credentials');\n const ambient = credentials ? (await credentials.resolve(credentialRef(ref)))?.value : launchEnvironmentOf(this.ctx).get(ref)?.value;\n if (ambient?.trim()) return ambient;\n const saved = await credentials?.readRecord(API_KEY);\n return saved?.kind === 'api-key' ? saved.key : undefined;\n }\n private async _state(): Promise<CapturedState> {\n const credentials = this.ctx.get('credentials'), config = this._config();\n const [apiRecord, sessionRecord, key] = await Promise.all([credentials?.readRecord(API_KEY), credentials?.readRecord(SESSION), this.resolveApiKey(config.apiKeyEnv)]);\n const state = { apiRecord, sessionRecord, key, config };\n const modelsFingerprint = hash({ key, baseURL: config.baseURL });\n if (modelsFingerprint !== this._modelsFingerprint) {\n const changed = this._modelsUpdatedAt !== undefined;\n this._modelsFingerprint = modelsFingerprint;\n this._modelsEpoch++;\n this._modelsController?.abort();\n this._modelsPending = undefined;\n this._models = MODELS;\n this._modelsUpdatedAt = undefined;\n this._modelsError = undefined;\n if (changed) this.dependencies.modelsChanged?.();\n }\n const fingerprint = hash(state);\n if (fingerprint !== this._fingerprint) { this._fingerprint = fingerprint; this._revision = randomUUID(); }\n return state;\n }\n private _conflict() { return new RemoteError('opendesign/revision-conflict', '\u8FDE\u63A5\u6216\u51ED\u636E\u5DF2\u6539\u53D8\uFF0C\u8BF7\u5237\u65B0\u9875\u9762\u540E\u91CD\u8BD5', undefined); }\n private _expect(revision: string) { if (revision !== this._revision) throw this._conflict(); }\n private _invalidateQuota(): void { this._quotaAt = 0; this._quotaEpoch++; this._quota = needLogin(); this._quotaIdentity = undefined; this._quotaController?.abort(); this._quotaPending = undefined; }\n @Remote('status')\n async status(): Promise<Status> {\n const state = await this._state();\n const quotaConfig = hash({ desktop: state.config.useDesktopCredential, session: state.sessionRecord, refreshSeconds: state.config.quotaRefreshSeconds });\n if (this._quotaConfig !== quotaConfig) { this._quotaConfig = quotaConfig; this._invalidateQuota(); }\n return parseStatus({\n revision: this._revision, apiKeyConfigured: Boolean(state.key?.trim()), ...(this._quota.source ? { sessionSource: this._quota.source } : {}),\n quota: this._quota, login: this._login.status(), config: state.config, guardedTurns: this.guardedTurns,\n models: this._models.map(({ id, name, group, contextWindow, maxOutputTokens, reasoningEfforts }) => ({\n id, name, group, enabled: isModelEnabled(id, state.config.modelSettings),\n ...(contextWindow === undefined ? {} : { contextWindow }),\n ...(maxOutputTokens === undefined ? {} : { maxOutputTokens }),\n ...(reasoningEfforts === undefined ? {} : { reasoningEfforts }),\n })),\n modelsSource: this._modelsUpdatedAt ? 'openai' : 'builtin',\n ...(this._modelsUpdatedAt ? { modelsUpdatedAt: this._modelsUpdatedAt } : {}),\n ...(this._modelsError ? { modelsError: this._modelsError } : {}),\n });\n }\n @Remote('refreshModels')\n async refreshModels(): Promise<Status> {\n const state = await this._state();\n if (this._modelsPending) return this._modelsPending;\n const key = state.key;\n if (!key?.trim()) {\n this._modelsError = '\u8BF7\u5148\u914D\u7F6E API Key\uFF0C\u518D\u4ECE OpenAI \u7AEF\u53E3\u62C9\u53D6\u6A21\u578B\u3002';\n return this.status();\n }\n const epoch = this._modelsEpoch;\n const controller = new AbortController();\n this._modelsController = controller;\n const signal = AbortSignal.any([controller.signal, this._lifetime.signal]);\n const run = (async () => {\n try {\n const models = await (this.dependencies.fetchModels ?? fetchModelCatalog)(state.config.baseURL, key, signal);\n await this._state();\n if (signal.aborted || epoch !== this._modelsEpoch) return this.status();\n this._models = models;\n this._modelsUpdatedAt = new Date().toISOString();\n this._modelsError = undefined;\n this.dependencies.modelsChanged?.();\n } catch (error) {\n if (!signal.aborted && epoch === this._modelsEpoch) this._modelsError = error instanceof ModelDiscoveryError ? error.message : '\u6A21\u578B\u5217\u8868\u66F4\u65B0\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002';\n }\n return this.status();\n })();\n this._modelsPending = run;\n try { return await run; }\n finally { if (this._modelsPending === run) this._modelsPending = undefined; }\n }\n @Remote('refreshQuota')\n async refreshQuota(): Promise<QuotaSnapshot> { return this._refreshQuota(false); }\n @Remote('refreshQuotaNow')\n async refreshQuotaNow(): Promise<QuotaSnapshot> { return this._refreshQuota(true); }\n private async _refreshQuota(force: boolean): Promise<QuotaSnapshot> {\n const state = await this._state();\n const fingerprint = hash({ desktop: state.config.useDesktopCredential, session: state.sessionRecord, refreshSeconds: state.config.quotaRefreshSeconds });\n if (fingerprint !== this._quotaConfig) { this._quotaConfig = fingerprint; this._invalidateQuota(); }\n if (this._quotaPending) return this._quotaPending;\n if (!force) {\n if (this._quota.autoRefreshPaused) return this._quota;\n const next = this._quota.nextRefreshAt ? Date.parse(this._quota.nextRefreshAt) : this._quotaAt + 5000;\n if (Date.now() < next) return this._quota;\n }\n const epoch = this._quotaEpoch;\n const controller = new AbortController(); this._quotaController = controller;\n const signal = AbortSignal.any([controller.signal, this._lifetime.signal]);\n const failures = force ? 0 : this._quota.refreshFailures ?? 0;\n const run = this._readQuota(epoch, signal, failures);\n this._quotaPending = run;\n void run.finally(() => { if (this._quotaPending === run) this._quotaPending = undefined; }).catch(() => {});\n return run;\n }\n private async _readQuota(epoch: number, signal: AbortSignal, failures: number): Promise<QuotaSnapshot> {\n const config = this._config();\n let result: QuotaSnapshot;\n let identity: string | undefined;\n let refreshFailed = false;\n try {\n const authDeps = {\n useDesktop: config.useDesktopCredential,\n readGrant: async () => grantOf(await this.ctx.get('credentials')?.readRecord(SESSION)),\n resolveRef: async (ref: string) => {\n const credentials = this.ctx.get('credentials');\n return credentials ? (await credentials.resolve(credentialRef(ref)))?.value : launchEnvironmentOf(this.ctx).get(ref)?.value;\n },\n };\n const auth = await this.dependencies.resolveSession(authDeps);\n if (auth.state === 'ready') identity = hash(auth.session);\n if (auth.state === 'need-login') result = needLogin();\n else if (auth.session.source !== 'desktop') result = await this.dependencies.readQuota(auth.session, signal);\n else {\n try {\n result = await this.dependencies.readDesktopQuota(auth.session, signal);\n if (result.state === 'partial') {\n const fallback = await this.dependencies.resolveSession({ ...authDeps, useDesktop: false });\n if (fallback.state === 'ready') {\n try {\n const complete = await this.dependencies.readQuota(fallback.session, signal);\n if (complete.state === 'ok' && (complete.windows.length > 0 || complete.eligible === false)) result = { ...complete, note: `\u684C\u9762\u767B\u5F55\u6001\u4EC5\u63D0\u4F9B\u90E8\u5206\u989D\u5EA6\uFF1B\u5F53\u524D\u663E\u793A\u72EC\u7ACB\u767B\u5F55\u8D26\u53F7\u7684\u5B8C\u6574\u989D\u5EA6\u3002${complete.note ? ` ${complete.note}` : ''}` };\n } catch (error) {\n if (signal.aborted) throw error;\n // A failed optional fallback does not discard the usable desktop snapshot.\n }\n }\n }\n }\n catch (error) {\n // An expired desktop credential must not permanently shadow a valid console login.\n if (!(error instanceof ConsoleError) || !['auth', 'permission'].includes(error.kind)) throw error;\n const fallback = await this.dependencies.resolveSession({ ...authDeps, useDesktop: false });\n if (fallback.state !== 'ready') throw new ConsoleError('auth');\n result = await this.dependencies.readQuota(fallback.session, signal);\n }\n }\n } catch (error) {\n const authFailure = error instanceof ConsoleError && error.kind === 'auth';\n refreshFailed = !authFailure;\n const hasReadings = this._quota.windows.length > 0 || Object.keys(this._quota.balances).length > 0;\n if (!authFailure && identity !== undefined && identity === this._quotaIdentity && hasReadings) {\n result = { ...this._quota, state: 'partial', stale: true, note: '\u989D\u5EA6\u5237\u65B0\u5931\u8D25\uFF0C\u5F53\u524D\u663E\u793A\u4E0A\u6B21\u6210\u529F\u8BFB\u6570\u3002' };\n } else {\n result = { ...needLogin(), state: authFailure ? 'need-login' : 'error', note: error instanceof ConsoleError ? error.message : '\u989D\u5EA6\u8BFB\u53D6\u6682\u65F6\u5931\u8D25\uFF1B\u8BF7\u68C0\u67E5\u8FDE\u63A5\u6216\u91CD\u65B0\u767B\u5F55' };\n }\n }\n if (!signal.aborted && epoch === this._quotaEpoch) {\n this._quotaAt = Date.now();\n if (refreshFailed) {\n const count = failures + 1;\n const paused = count >= 6;\n const { nextRefreshAt: _previousPlan, ...previous } = result;\n result = { ...previous, refreshFailures: count, autoRefreshPaused: paused,\n ...(paused ? { note: `${result.note ?? '\u989D\u5EA6\u5237\u65B0\u5931\u8D25'} \u81EA\u52A8\u91CD\u8BD5\u5DF2\u6682\u505C\uFF0C\u8BF7\u70B9\u51FB\u5237\u65B0\u989D\u5EA6\u91CD\u8BD5\u3002` } : { nextRefreshAt: new Date(this._quotaAt + Math.min(60_000, 5000 * 2 ** (count - 1))).toISOString() }),\n };\n } else if (result.state !== 'need-login') {\n result = { ...result, nextRefreshAt: new Date(this._quotaAt + (config.quotaRefreshSeconds ?? 60) * 1000).toISOString() };\n }\n this._quota = result;\n this._quotaIdentity = identity;\n }\n return epoch === this._quotaEpoch ? result : this._quota;\n }\n @Remote('startLogin')\n async startLogin(input: StartLoginRequest): Promise<LoginState> {\n const request = parseStartLogin(input);\n await this._state(); this._expect(request.expectedRevision); this._credentials();\n return parseLoginState(this._login.start(request));\n }\n @Remote('loginStatus')\n loginStatus(): LoginState { return parseLoginState(this._login.status()); }\n @Remote('cancelLogin')\n cancelLogin(input: CancelLoginRequest): LoginState { return parseLoginState(this._login.cancel(parseCancelLogin(input))); }\n @Remote('saveApiKey')\n async saveApiKey(input: SaveApiKeyRequest): Promise<Status> {\n const request = parseSaveApiKey(input), state = await this._state();\n this._expect(request.expectedRevision);\n const expected = hash(state.apiRecord);\n await this._credentials().modifyRecord(API_KEY, async current => {\n if (hash(current) !== expected || hash(this._config()) !== hash(state.config)) throw this._conflict();\n return { kind: 'api-key', key: request.value };\n });\n return this.status();\n }\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context { openDesignCoRouter: OpenDesignCoRouterService }\n}\ndeclare module '@deepseek-ai/dsh-typert-protocol' {\n interface RemoteErrorDetailsMap {\n 'opendesign/credentials-unavailable': undefined;\n 'opendesign/revision-conflict': undefined;\n }\n}\nexport function apply(ctx: Context, config: LiveConfig): void {\n const current = () => readConfig(config);\n current();\n ctx.inject(['settings'], scope => scope.effect(() => scope.settings.configure({ auto: false }, ctx.fiber)));\n let modelsChanged = () => {};\n const service = new OpenDesignCoRouterService(ctx, current, { resolveSession, readQuota, readDesktopQuota, modelsChanged: () => modelsChanged() });\n const adapter = new CoRouterAdapter({\n config: current, models: () => service.modelCatalog(), apiKey: ref => service.resolveApiKey(ref), onEmptyTurn: () => { service.guardedTurns++; },\n imageDataUrl: async (ref, signal) => {\n const attachments = ctx.get('attachments');\n if (!attachments) return undefined;\n const image = await attachments.readImage(ref, signal);\n return `data:${image.ref.mediaType};base64,${Buffer.from(image.data).toString('base64')}`;\n },\n });\n const registration = ctx.llm.registerAdapter([PLAN_PROVIDER, PAID_PROVIDER], adapter);\n modelsChanged = () => registration.replace([PLAN_PROVIDER, PAID_PROVIDER]);\n let configFingerprint = hash(current());\n ctx.on('loader/volatile-update', () => {\n const next = hash(current());\n if (next === configFingerprint) return;\n configFingerprint = next;\n modelsChanged();\n });\n ctx.llm.registerModelDiscovery(SETTINGS_NS, async (request, signal) => {\n if (request.provider !== undefined && ![PLAN_PROVIDER, PAID_PROVIDER].includes(request.provider)) throw new LlmError('\u4E0D\u662F\u672C\u63D2\u4EF6\u7684\u6A21\u578B\u901A\u9053', 'INVALID_REQUEST');\n const config = current();\n const key = request.apiKey ?? await service.resolveApiKey(config.apiKeyEnv);\n if (!key) throw new LlmError('\u8BF7\u5148\u914D\u7F6E CoRouter API Key', 'MISSING_CREDENTIAL');\n // Model discovery is always OpenAI-compatible, irrespective of request.api or inference protocol.\n const models = await fetchModelCatalog(config.baseURL, key, signal);\n return models.map(row => ({ id: row.id, name: row.name, ...(row.contextWindow === undefined ? {} : { contextWindow: row.contextWindow }), ...(row.maxOutputTokens === undefined ? {} : { maxTokens: row.maxOutputTokens }), ...(row.inputModalities ? { inputModalities: row.inputModalities } : {}) }));\n });\n ctx.llm.registerConfigurableProviders([\n { provider: PLAN_PROVIDER, displayName: 'OpenDesign CoRouter \u00B7 \u5957\u9910\u8D60\u9001', settingsNs: SETTINGS_NS, settingsPath: [], defaultBaseURL: current().baseURL },\n { provider: PAID_PROVIDER, displayName: 'OpenDesign CoRouter \u00B7 \u4ED8\u8D39\u6A21\u578B', settingsNs: SETTINGS_NS, settingsPath: [], defaultBaseURL: current().baseURL },\n ]);\n ctx.effect(() => () => adapter.dispose());\n}\n", "import {\n LlmAdapter, LlmError, ReasoningEffortId, assertUsableApiKey,\n type GenerateOptions, type LlmModelInfo, type LlmResolvedModelInfo, type PreparedAdapterCall, type StreamChunk,\n} from '@deepseek-ai/dsh-llm';\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';\nimport { MODELS, type CatalogModel } from './catalog.js';\nimport { PLAN_PROVIDER, PAID_PROVIDER, type RuntimeConfig } from './config.js';\nimport { chatMessages, chatTools, estimateTokens } from './conversion.js';\nimport { gatewayError } from './stream.js';\nimport { combinedSignal } from './util.js';\nimport { EmptyTurnTracker } from './empty-turn.js';\nimport { applyModelSettings, isModelEnabled, type ModelSettings } from './model-settings.js';\nimport { protocolFor } from './protocols/index.js';\nimport type { ApiProtocol } from './protocol-options.js';\n\nexport interface AdapterOptions {\n config(): RuntimeConfig;\n models?(): readonly CatalogModel[];\n apiKey(ref: string): Promise<string | undefined>;\n imageDataUrl?(image: ImageAttachmentRef, signal: AbortSignal): Promise<string | undefined>;\n onEmptyTurn?(): void;\n fetch?: typeof fetch;\n}\nfunction group(provider: string): 'plan' | 'paid' {\n if (provider === PLAN_PROVIDER) return 'plan';\n if (provider === PAID_PROVIDER) return 'paid';\n throw new LlmError('\u672A\u77E5\u7684 CoRouter Provider', 'INVALID_REQUEST');\n}\nfunction outputReserve(model: CatalogModel, protocol: ApiProtocol): number | undefined {\n const limit = model.maxOutputTokens ?? (protocol === 'messages' ? 4096 : undefined);\n return limit === undefined ? undefined : model.contextWindow === undefined ? limit : Math.min(limit, Math.floor(model.contextWindow / 4));\n}\nfunction metadata(provider: string, row: CatalogModel, config: RuntimeConfig): LlmResolvedModelInfo {\n const setting = config.modelSettings?.[row.id];\n const reserve = setting?.maxTokens ?? outputReserve(row, config.apiProtocol ?? 'chat-completions');\n const efforts = row.reasoningEfforts ?? (setting?.reasoningEffort ? [setting.reasoningEffort] : undefined);\n return {\n provider, id: row.id, name: row.name,\n ...(row.inputModalities ? { inputModalities: row.inputModalities } : {}),\n ...(row.contextWindow === undefined ? {} : { context: { contextWindow: row.contextWindow - (reserve ?? 0) } }),\n ...(reserve === undefined ? {} : { defaultMaxTokens: reserve }),\n ...(efforts?.length ? { reasoning: {\n efforts: efforts.map(id => ({ id: ReasoningEffortId(id), name: ({ none: '\u5173\u95ED', minimal: '\u6700\u4F4E', low: '\u4F4E', medium: '\u4E2D', high: '\u9AD8', xhigh: '\u8F83\u9AD8', ultra: '\u6781\u9AD8', max: '\u6700\u9AD8' } as Record<string, string>)[id] ?? id })),\n ...(setting?.reasoningEffort ? { defaultEffort: ReasoningEffortId(setting.reasoningEffort) } : {}),\n } } : {}),\n };\n}\nexport class CoRouterAdapter extends LlmAdapter {\n readonly #lifetime = new AbortController();\n constructor(readonly options: AdapterOptions) { super(); }\n dispose(): void { this.#lifetime.abort(new LlmError('CoRouter \u63D2\u4EF6\u5DF2\u5378\u8F7D', 'ABORTED')); }\n override providerInfo(provider: string) {\n return { id: provider, name: group(provider) === 'plan' ? 'OpenDesign CoRouter \u00B7 \u5957\u9910\u8D60\u9001' : 'OpenDesign CoRouter \u00B7 \u4ED8\u8D39\u6A21\u578B' };\n }\n private modelOf(provider: string, id: string, config: RuntimeConfig): CatalogModel {\n const row = (this.options.models?.() ?? MODELS).find(candidate => candidate.id === id);\n if (!row || row.group !== group(provider)) throw new LlmError('\u8BE5\u6A21\u578B\u4E0D\u5C5E\u4E8E\u5F53\u524D CoRouter Provider\uFF1B\u8BF7\u5237\u65B0\u6A21\u578B\u5217\u8868\u5E76\u9009\u62E9\u5BF9\u5E94\u901A\u9053', 'INVALID_REQUEST');\n if (!isModelEnabled(id, config.modelSettings)) throw new LlmError('\u8BE5\u6A21\u578B\u5DF2\u5728 CoRouter \u8BBE\u7F6E\u4E2D\u505C\u7528', 'MODEL_DISABLED');\n const configured = applyModelSettings(row, config.modelSettings?.[id]);\n const output = config.modelSettings?.[id]?.maxTokens;\n if (output !== undefined && configured.contextWindow !== undefined && output >= configured.contextWindow) throw new LlmError('\u6A21\u578B\u6700\u5927\u8F93\u51FA\u5FC5\u987B\u5C0F\u4E8E\u4E0A\u4E0B\u6587\u9884\u7B97\uFF0C\u8BF7\u8C03\u6574\u6A21\u578B\u53C2\u6570', 'INVALID_REQUEST');\n return configured;\n }\n override async listModels(provider: string): Promise<readonly LlmModelInfo[]> {\n const config = this.options.config(), selectedGroup = group(provider);\n return (this.options.models?.() ?? MODELS).filter(row => row.group === selectedGroup && isModelEnabled(row.id, config.modelSettings))\n .map(row => ({ provider, id: row.id, name: row.name, ...(row.inputModalities ? { inputModalities: row.inputModalities } : {}) }));\n }\n override async resolveModel(provider: string, model: string, signal?: AbortSignal): Promise<LlmResolvedModelInfo> {\n signal?.throwIfAborted();\n const config = this.options.config();\n return metadata(provider, this.modelOf(provider, model, config), config);\n }\n override async prepareCall(provider: string, model: string, signal?: AbortSignal): Promise<PreparedAdapterCall> {\n signal?.throwIfAborted();\n const config = this.options.config(), row = this.modelOf(provider, model, config);\n return { model: metadata(provider, row, config), stream: options => this.#stream(options, config, row) };\n }\n override stream(options: GenerateOptions): AsyncIterable<StreamChunk> {\n const config = this.options.config();\n return this.#stream(options, config, this.modelOf(options.provider, options.model, config));\n }\n async *#stream(options: GenerateOptions, config: RuntimeConfig, row: CatalogModel): AsyncGenerator<StreamChunk> {\n const signal = AbortSignal.any([combinedSignal(options.signal, config.requestTimeoutMs), this.#lifetime.signal]);\n signal.throwIfAborted();\n const raw = await this.options.apiKey(config.apiKeyEnv);\n if (!raw) throw new LlmError('\u672A\u914D\u7F6E CoRouter API Key\uFF1B\u8BF7\u5728\u63D2\u4EF6\u8BBE\u7F6E\u4E2D\u4FDD\u5B58\u6216\u8BBE\u7F6E\u5BF9\u5E94\u73AF\u5883\u53D8\u91CF', 'MISSING_CREDENTIAL');\n const key = assertUsableApiKey(raw, 'dsh-opendesign-corouter', config.apiKeyEnv);\n const setting: ModelSettings = config.modelSettings?.[row.id] ?? {};\n const protocolId = config.apiProtocol ?? 'chat-completions';\n const images = new Map<string, string>();\n const attemptedImages = new Set<string>();\n const unreadableImages = new Set<string>();\n if (row.inputModalities?.includes('image') && this.options.imageDataUrl) for (const message of options.messages.filter(item => item.role === 'user' || item.role === 'tool')) for (const block of message.content) {\n if (block.type !== 'image' || block.offloaded || attemptedImages.has(block.attachment.attachmentId)) continue;\n attemptedImages.add(block.attachment.attachmentId);\n try {\n const url = await this.options.imageDataUrl(block.attachment, signal);\n signal.throwIfAborted();\n if (url) images.set(block.attachment.attachmentId, url);\n else unreadableImages.add(block.attachment.attachmentId);\n } catch {\n // A missing image becomes the named placeholder; cancellation must still stop the call.\n signal.throwIfAborted();\n unreadableImages.add(block.attachment.attachmentId);\n }\n }\n const projectedOptions: GenerateOptions = unreadableImages.size === 0 ? options : {\n ...options,\n messages: options.messages.map(message => message.role !== 'user' && message.role !== 'tool' ? message : {\n ...message,\n content: message.content.map(block => block.type === 'image' && !block.offloaded && unreadableImages.has(block.attachment.attachmentId)\n ? { type: 'text' as const, text: `[Image ${JSON.stringify(block.attachment.name ?? 'attachment')} could not be read; attachment ${block.attachment.attachmentId}. The model's image capability has not changed.]` }\n : block),\n }),\n };\n const messages = chatMessages(projectedOptions, ref => images.get(ref.attachmentId), row.id.startsWith('deepseek-') || row.id.startsWith('kimi-'));\n const tools = chatTools(options);\n let maxTokens = options.maxTokens ?? setting.maxTokens ?? outputReserve(row, protocolId);\n if (maxTokens !== undefined) {\n if (!Number.isSafeInteger(maxTokens) || maxTokens <= 0) throw new LlmError('maxTokens \u5FC5\u987B\u662F\u6B63\u6574\u6570', 'INVALID_REQUEST');\n const capped = Math.min(maxTokens, row.maxOutputTokens ?? maxTokens);\n const room = row.contextWindow === undefined ? capped : row.contextWindow - estimateTokens({ messages, tools });\n if (room < 1) throw new LlmError('\u5F53\u524D\u8F93\u5165\u6CA1\u6709\u4E3A\u8F93\u51FA\u7559\u4E0B\u4E0A\u4E0B\u6587\u7A7A\u95F4', 'CONTEXT_WINDOW_EXCEEDED');\n maxTokens = Math.min(capped, Math.floor(room));\n }\n const effort = options.reasoningEffort ?? (setting.reasoningEffort ? ReasoningEffortId(setting.reasoningEffort) : undefined);\n if (effort !== undefined && row.reasoningEfforts && !row.reasoningEfforts.includes(effort)) throw new LlmError('\u8BE5\u6A21\u578B\u4E0D\u652F\u6301\u6240\u9009\u601D\u8003\u6DF1\u5EA6', 'UNSUPPORTED_OPTION');\n const effective: GenerateOptions = {\n ...projectedOptions,\n ...((options.temperature ?? setting.temperature) === undefined ? {} : { temperature: options.temperature ?? setting.temperature }),\n ...(maxTokens === undefined ? {} : { maxTokens }),\n ...(effort === undefined ? {} : { reasoningEffort: effort }),\n };\n const protocol = protocolFor(protocolId);\n const request = protocol.build({ baseURL: config.baseURL, apiKey: key, model: row, options: effective, images, ...(setting.topP === undefined ? {} : { topP: setting.topP }) });\n let response: Response;\n try {\n response = await (this.options.fetch ?? fetch)(request.url, {\n method: 'POST', headers: request.headers, body: JSON.stringify(request.body), signal, redirect: 'error',\n });\n } catch {\n if (options.signal?.aborted || this.#lifetime.signal.aborted) signal.throwIfAborted();\n throw new LlmError(signal.aborted ? 'CoRouter \u8BF7\u6C42\u8D85\u8FC7\u603B\u8D85\u65F6' : '\u65E0\u6CD5\u8FDE\u63A5 CoRouter \u63A8\u7406\u670D\u52A1', signal.aborted ? 'TIMEOUT' : 'SERVER');\n }\n if (!response.ok) {\n let error: unknown = {};\n const reader = response.body?.getReader();\n if (reader) {\n let size = 0, raw = '';\n const decoder = new TextDecoder();\n try {\n while (true) {\n const chunk = await reader.read();\n if (chunk.done) break;\n size += chunk.value.byteLength;\n if (size > 65536) { raw = ''; break; }\n raw += decoder.decode(chunk.value, { stream: true });\n }\n if (raw) error = JSON.parse(raw + decoder.decode());\n } catch { /* Untrusted non-JSON errors are not projected. */ }\n finally { await reader.cancel().catch(() => undefined); reader.releaseLock(); }\n }\n throw gatewayError(response.status, error);\n }\n if (!response.body) throw new LlmError('CoRouter \u8FD4\u56DE\u7A7A\u54CD\u5E94', 'EMPTY_RESPONSE');\n const tracker = new EmptyTurnTracker({ enabled: row.group === 'plan' && config.emptyTurnGuard && Boolean(options.tools?.length), onEmptyTurn: () => this.options.onEmptyTurn?.() });\n try {\n for await (const chunk of protocol.stream(response.body, signal, config.streamIdleTimeoutMs)) {\n tracker.observe(chunk);\n if (chunk.type === 'finish' && row.group === 'plan' && config.emptyTurnGuard) yield { ...chunk, reason: tracker.resolve(chunk.reason) };\n else yield chunk;\n }\n } catch (error) {\n if (options.signal?.aborted || this.#lifetime.signal.aborted) signal.throwIfAborted();\n if (signal.aborted) throw new LlmError('CoRouter \u8BF7\u6C42\u8D85\u8FC7\u603B\u8D85\u65F6', 'TIMEOUT');\n if (error instanceof LlmError) throw error;\n throw new LlmError('CoRouter \u54CD\u5E94\u6D41\u8FDE\u63A5\u4E2D\u65AD', 'SERVER');\n }\n }\n}\n", "/**\n * CoRouter \u6A21\u578B\u76EE\u5F55\uFF08\u4EC5\u5BF9\u8BDD\u6A21\u578B\uFF0C\u4F9B llm \u9002\u914D\u5668\u7684\u6A21\u578B\u9009\u62E9\u5668\u4F7F\u7528\uFF09\u3002\n *\n * \u53D6\u8BC1\u6765\u6E90\uFF1A\n * - \u6A21\u578B ID / \u663E\u793A\u540D / \u4F9B\u5E94\u5546 / \u5355\u4EF7\uFF1A`https://corouter.open-design.ai/zh/models/<slug>/`\n * \u8BE6\u60C5\u9875\u5185\u8054 `data-model=\"{...}\"` JSON\uFF08\u516C\u5F00\u9875\u9762\uFF0C2026-10-26\uFF09\u3002\n * - group\uFF1A\u5B98\u7F51\u9996\u9875\u5957\u9910\u5361 `https://corouter.open-design.ai/zh/` \u7684\n * `data-model-module=\"design-plan\"` 12 \u6B3E\u5F52 `plan`\uFF1B\u5176\u4F59\u5728\u552E\u5BF9\u8BDD\u6A21\u578B\u5F52 `paid`\u3002\n * - `plan` 12 \u6B3E\u7684 contextWindow / maxOutputTokens / inputModalities / reasoningEfforts\n * \u6765\u81EA Go \u4FA7 `dsh-opendesign-go` 0.1.9 \u7684 MODEL_DEFAULTS\uFF08\u540C\u4E00 `amr-link` endpoint \u90E8\u7F72\u8D44\u6599\uFF09\uFF0C\n * \u7531\u7236\u4F1A\u8BDD\u79FB\u690D\uFF0C**\u672A\u7ECF\u5B98\u7F51\u72EC\u7ACB\u590D\u6838**\uFF1B\u53EA\u7528\u4E8E plan \u901A\u9053\u3002\n * - \u5BA2\u6237\u7AEF\u684C\u9762\u5B89\u88C5\uFF08Open Design 0.26.1\uFF09\u4E0D\u5185\u8054 CoRouter \u76EE\u5F55\uFF1B\u5176\n * `vela model preset --format json` \u53EA\u6709 11 \u4E2A\u65E7\u9884\u8BBE id\uFF08\u89C1 docs/client-evidence.md\uFF09\uFF0C\n * \u4E0E\u672C\u8868\u4E0D\u540C\u4EE3\uFF0C\u6545\u4E0D\u7528\u4E8E\u672C\u76EE\u5F55\u3002\n *\n * \u5206\u7EC4\u8BED\u4E49\uFF08\u91CD\u8981\uFF09\uFF1A`plan`/`paid` \u662F**\u672C\u63D2\u4EF6\u672C\u5730\u76EE\u5F55\u5206\u7C7B**\uFF0C\u7528\u4E8E\u628A\u201C\u5957\u9910\u8D60\u9001\u901A\u9053\u201D\u4E0E\n * \u201C\u5176\u4F59\u4ED8\u8D39\u901A\u9053\u201D\u62C6\u6210\u4E24\u4E2A Provider\uFF0C\u4E0D\u662F\u4E0A\u6E38\u5F3A\u5236\u8BA1\u8D39\u5951\u7EA6\u3002\u6700\u7EC8\u53EF\u7528\u6027\u3001\u6263\u54EA\u4E2A\u989D\u5EA6\u6C60\u3001\n * \u662F\u5426\u5148\u6263 Design Plan \u989D\u5EA6\u518D\u7528\u5957\u9910\u6A21\u578B/\u94B1\u5305\u989D\u5EA6\uFF0C\u5168\u90E8\u7531\u670D\u52A1\u7AEF\u6309\u8D26\u53F7\u5957\u9910\u51B3\u5B9A\u3002\n * `paid` 21 \u6B3E\u91CC\u53EA\u6709 8 \u6B3E\u51FA\u73B0\u5728\u5B98\u7F51\u5957\u9910\u53EF\u62B5\u6263\u540D\u5355\uFF0C\u5176\u4F59 13 \u6B3E\u540C\u6837\u53EF\u7ECF\u94B1\u5305/\u6309\u91CF\u4ED8\u8D39\u8C03\u7528\uFF0C\n * \u56E0\u6B64 `paid` \u6536\u5F55 21 \u6B3E\u800C\u4E0D\u662F 13 \u6B3E\u3002\n *\n * \u672A\u6536\u5F55\uFF08\u8BC1\u636E\u4E0D\u8DB3\uFF0C\u4E0D\u731C\u6D4B\uFF09\uFF1A\n * - \u5957\u9910\u6A21\u578B\u7EC4\u4E2D\u5C1A\u672A\u516C\u5F00\u7CBE\u786E ID \u7684 `Muse Spark 1.3`\u3001`Gemini 4 Argon`\uFF1A\n * \u524D\u8005\u8BE6\u60C5\u9875\u6CA1\u6709 `data-model`/\u6A21\u578B ID\uFF0C\u540E\u8005\u5728\u6A21\u578B\u76EE\u5F55\u91CC\u6CA1\u6709\u8BE6\u60C5\u9875\u3002\n * - \u5A92\u4F53\u6A21\u578B `GPT Image 2`\u3001`Nano Banana 2`\u3001`Seedream 5 Lite / Pro`\uFF1A\n * \u8D70 `/api/v1/media/*`\uFF0C\u4E0D\u5E94\u51FA\u73B0\u5728\u5BF9\u8BDD\u6A21\u578B\u5217\u8868\u91CC\uFF0C\u907F\u514D\u9009\u4E2D\u540E chat \u8BF7\u6C42\u5FC5\u8D25\u3002\n *\n * `paid` 21 \u6B3E\u7684\u80FD\u529B\u5B57\u6BB5\u4E00\u5F8B\u7F3A\u7701\uFF1A\u65E2\u6CA1\u6709\u5B98\u7F51\u6570\u503C\uFF0C\u4E5F\u6CA1\u6709\u53EF\u4FE1\u9ED8\u8BA4\u8868\uFF0C\n * \u4E0D\u6309\u540D\u79F0\u63A8\u65AD\u56FE\u50CF\u80FD\u529B\uFF0C\u4E5F\u4E0D\u7ED9\u672A\u77E5\u9879\u586B `['text']` \u8C0E\u79F0\u4E0D\u652F\u6301\u56FE\u50CF\u3002\n */\nexport interface CatalogModel {\n id: string;\n name: string;\n group: 'plan' | 'paid';\n contextWindow?: number;\n maxOutputTokens?: number;\n inputModalities?: readonly ('text' | 'image')[];\n reasoningEfforts?: readonly string[];\n}\n\nconst TEXT_ONLY = ['text'] as const;\nconst TEXT_AND_IMAGE = ['text', 'image'] as const;\n\n/** Go 0.1.9 MODEL_DEFAULTS \u91CC\u7684\u601D\u8003\u6863\u4F4D\u96C6\u5408\uFF08\u540C amr-link endpoint \u90E8\u7F72\u8D44\u6599\uFF09\u3002 */\nconst EFFORTS_FULL = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'ultra', 'max'] as const;\nconst EFFORTS_STD = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'] as const;\nconst EFFORTS_LOW_HIGH = ['low', 'high', 'max'] as const;\n\n/**\n * \u987A\u5E8F\u6309\u4F9B\u5E94\u5546\u5206\u7EC4\uFF08\u4E0E\u5B98\u7F51\u6A21\u578B\u76EE\u5F55\u5BFC\u822A\u4E00\u81F4\uFF09\uFF1B`plan` \u4E3A Design Plan \u989D\u5EA6\u8986\u76D6\u7684 12 \u6B3E\uFF0C\n * \u5176\u4F59 21 \u6B3E\u516C\u5F00\u5BF9\u8BDD\u6A21\u578B\u5F52 `paid`\u3002\n */\nexport const MODELS: readonly CatalogModel[] = [\n // \u2500\u2500 OpenAI\uFF087\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n { id: 'gpt-6.1-sol', name: 'GPT-6.1 Sol', group: 'paid' },\n { id: 'gpt-6-astra', name: 'GPT-6 Astra', group: 'paid' },\n {\n id: 'gpt-6-luna',\n name: 'GPT-6 Luna',\n group: 'plan',\n contextWindow: 1_050_000,\n maxOutputTokens: 128_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_FULL,\n },\n { id: 'gpt-6-sol', name: 'GPT-6 Sol', group: 'paid' },\n { id: 'gpt-5.6-luna', name: 'GPT-5.6 Luna', group: 'paid' },\n { id: 'gpt-5.6-sol', name: 'GPT-5.6 Sol', group: 'paid' },\n { id: 'gpt-5.6-terra', name: 'GPT-5.6 Terra', group: 'paid' },\n\n // \u2500\u2500 Anthropic\uFF088\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n { id: 'claude-fable-5.1', name: 'Claude Fable 5.1', group: 'paid' },\n { id: 'claude-fable-5', name: 'Claude Fable 5', group: 'paid' },\n { id: 'claude-opus-5.5', name: 'Claude Opus 5.5', group: 'paid' },\n { id: 'claude-opus-5', name: 'Claude Opus 5', group: 'paid' },\n { id: 'claude-opus-4.8', name: 'Claude Opus 4.8', group: 'paid' },\n { id: 'claude-sonnet-5.5', name: 'Claude Sonnet 5.5', group: 'paid' },\n { id: 'claude-sonnet-5', name: 'Claude Sonnet 5', group: 'paid' },\n {\n id: 'claude-haiku-5.5',\n name: 'Claude Haiku 5.5',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 128_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_STD,\n },\n\n // \u2500\u2500 DeepSeek\uFF084\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n {\n id: 'deepseek-v4.1-flash',\n name: 'DeepSeek V4.1 Flash',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 384_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_FULL,\n },\n {\n id: 'deepseek-v4-pro',\n name: 'DeepSeek V4 Pro',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 384_000,\n inputModalities: TEXT_ONLY,\n reasoningEfforts: EFFORTS_FULL,\n },\n {\n id: 'deepseek-v4-flash',\n name: 'DeepSeek V4 Flash',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 384_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_FULL,\n },\n {\n id: 'deepseek-v4-flash-vision-exp',\n name: 'DeepSeek V4 Flash Vision Exp',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 384_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_FULL,\n },\n\n // \u2500\u2500 Z.ai\uFF083\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n {\n id: 'glm-5.3-flashx',\n name: 'GLM-5.3 Flash-X',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 128_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_LOW_HIGH,\n },\n {\n id: 'glm-5.3-flash',\n name: 'GLM-5.3 Flash',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 128_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_LOW_HIGH,\n },\n { id: 'glm-5.2', name: 'GLM-5.2', group: 'paid' },\n\n // \u2500\u2500 Moonshot\uFF082\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n {\n id: 'kimi-k2.7-code',\n name: 'Kimi K2.7 Code',\n group: 'plan',\n contextWindow: 262_144,\n maxOutputTokens: 262_144,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_STD,\n },\n { id: 'kimi-k3', name: 'Kimi K3', group: 'paid' },\n\n // \u2500\u2500 Google\uFF082\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n { id: 'gemini-3.8-flash', name: 'Gemini 3.8 Flash', group: 'paid' },\n { id: 'gemini-3.7-flash', name: 'Gemini 3.7 Flash', group: 'paid' },\n\n // \u2500\u2500 xAI\uFF083\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n { id: 'grok-4.7', name: 'Grok 4.7', group: 'paid' },\n { id: 'grok-4.6', name: 'Grok 4.6', group: 'paid' },\n { id: 'grok-4.5', name: 'Grok 4.5', group: 'paid' },\n\n // \u2500\u2500 Xiaomi\uFF082\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n {\n id: 'mimo-v2.6-pro',\n name: 'MiMo V2.6 Pro',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 128_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_STD,\n },\n {\n id: 'mimo-v2.6-flash',\n name: 'MiMo V2.6 Flash',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 128_000,\n inputModalities: TEXT_AND_IMAGE,\n reasoningEfforts: EFFORTS_STD,\n },\n\n // \u2500\u2500 Tencent\uFF081\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n {\n id: 'hy4-preview',\n name: 'Hunyuan H4 Preview',\n group: 'plan',\n contextWindow: 1_000_000,\n maxOutputTokens: 64_000,\n inputModalities: TEXT_ONLY,\n reasoningEfforts: EFFORTS_STD,\n },\n\n // \u2500\u2500 Alibaba\uFF081\uFF09 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n { id: 'qwen3.7-max', name: 'Qwen3.7 Max', group: 'paid' },\n];\n\nconst BY_ID = new Map(MODELS.map(model => [model.id, model] as const));\n\nexport function modelsFor(group: 'plan' | 'paid'): readonly CatalogModel[] {\n return MODELS.filter(model => model.group === group);\n}\n\nexport function findModel(id: string): CatalogModel | undefined {\n return BY_ID.get(id);\n}\n", "import Schema from '@deepseek-ai/schemastery';\nimport { API_PROTOCOL_IDS, type ApiProtocol } from './protocol-options.js';\nimport { parseModelSettingsMap, type ModelSettingsMap } from './model-settings.js';\nexport const SETTINGS_NS = 'llm-opendesign-corouter';\nexport const PLAN_PROVIDER = 'opendesign-corouter-plan';\nexport const PAID_PROVIDER = 'opendesign-corouter-paid';\nexport const DEFAULT_BASE_URL = 'https://amr-link.open-design.ai/v1';\nexport const Config = Schema.object({\n apiKeyEnv: Schema.string().max(128).pattern(/^[A-Za-z_][A-Za-z0-9_]*$/u).default('COROUTER_API_KEY').description('CoRouter API Key \u7684\u73AF\u5883\u53D8\u91CF\u6216 DSH \u51ED\u636E\u5F15\u7528\u540D').volatile(),\n baseURL: Schema.transform(Schema.string(), assertBaseURL).default(DEFAULT_BASE_URL).description('CoRouter \u7F51\u5173\u5730\u5740\uFF1B\u4E0D\u7528\u4E8E\u63A7\u5236\u53F0\u767B\u5F55\u6216\u989D\u5EA6\u67E5\u8BE2').volatile(),\n apiProtocol: Schema.union(API_PROTOCOL_IDS).default('chat-completions').description('\u63A8\u7406 API \u534F\u8BAE\uFF1B\u6A21\u578B\u53D1\u73B0\u59CB\u7EC8\u4F7F\u7528 OpenAI models \u63A5\u53E3').volatile(),\n modelSettings: Schema.transform(Schema.dict(Schema.any<unknown>()), parseModelSettingsMap).default({}).description('\u9010\u6A21\u578B\u542F\u7528\u72B6\u6001\u548C\u8BF7\u6C42\u53C2\u6570').volatile(),\n useDesktopCredential: Schema.boolean().default(true).description('\u4F18\u5148\u8BFB\u53D6 OpenDesign \u684C\u9762\u7AEF\u767B\u5F55\u6001\u67E5\u8BE2\u989D\u5EA6').volatile(),\n emptyTurnGuard: Schema.boolean().default(true).description('\u76D1\u63A7\u5957\u9910\u8D60\u9001\u6A21\u578B\u7684\u7A7A\u8F6E/\u534F\u8BAE\u6B8B\u6E23\uFF1B\u7531\u5BBF\u4E3B\u91CD\u8BD5\u7B56\u7565\u5904\u7406\uFF0C\u53EF\u80FD\u989D\u5916\u6D88\u8017\u8D60\u9001\u989D\u5EA6').volatile(),\n quotaRefreshSeconds: Schema.natural().min(5).max(3600).default(60).description('\u989D\u5EA6\u81EA\u52A8\u5237\u65B0\u95F4\u9694\uFF08\u79D2\uFF09').volatile(),\n requestTimeoutMs: Schema.natural().min(1000).max(3600000).default(1800000).description('\u63A8\u7406\u8BF7\u6C42\u603B\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09').volatile(),\n streamIdleTimeoutMs: Schema.natural().min(1000).max(1800000).default(300000).description('\u6D41\u5F0F\u54CD\u5E94\u65E0\u6570\u636E\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09').volatile(),\n});\nexport type LiveConfig = ReturnType<typeof Config>;\nexport interface RuntimeConfig {\n apiKeyEnv: string; baseURL: string; useDesktopCredential: boolean; emptyTurnGuard: boolean; requestTimeoutMs: number; streamIdleTimeoutMs: number;\n apiProtocol?: ApiProtocol;\n modelSettings?: ModelSettingsMap;\n quotaRefreshSeconds?: number;\n}\n// Schemastery serializes transform callbacks as source; keep this function closure-free.\nexport function assertBaseURL(raw: string): string {\n if (raw.length > 2048) throw new Error('\u63A8\u7406 Base URL \u6700\u591A\u5141\u8BB8 2048 \u5B57\u7B26');\n let url: URL;\n try { url = new URL(raw); } catch { throw new Error('\u63A8\u7406 Base URL \u5FC5\u987B\u662F\u7EDD\u5BF9 URL'); }\n if (!['https:', 'http:'].includes(url.protocol) || url.username || url.password || url.search || url.hash) throw new Error('\u63A8\u7406 Base URL \u4E0D\u53EF\u5305\u542B\u51ED\u636E\u3001\u67E5\u8BE2\u4E32\u6216\u7247\u6BB5');\n if (url.protocol === 'http:' && !['localhost', '127.0.0.1', '[::1]'].includes(url.hostname)) throw new Error('\u975E\u672C\u673A\u63A8\u7406\u5730\u5740\u5FC5\u987B\u4F7F\u7528 HTTPS');\n const normalized = url.href.replace(/\\/+$/u, '');\n if (normalized.length > 2048) throw new Error('\u63A8\u7406 Base URL \u6700\u591A\u5141\u8BB8 2048 \u5B57\u7B26');\n return normalized;\n}\nexport function readConfig(config: LiveConfig): RuntimeConfig {\n return {\n apiKeyEnv: config.apiKeyEnv.get(), baseURL: assertBaseURL(config.baseURL.get()),\n apiProtocol: config.apiProtocol.get(), modelSettings: parseModelSettingsMap(config.modelSettings.get()),\n quotaRefreshSeconds: config.quotaRefreshSeconds.get(),\n useDesktopCredential: config.useDesktopCredential.get(), emptyTurnGuard: config.emptyTurnGuard.get(),\n requestTimeoutMs: config.requestTimeoutMs.get(), streamIdleTimeoutMs: config.streamIdleTimeoutMs.get(),\n };\n}\n", "export const API_PROTOCOL_IDS = ['chat-completions', 'responses', 'messages'] as const;\nexport type ApiProtocol = typeof API_PROTOCOL_IDS[number];\n\n/** The public gateway origin and an explicit versioned API base are both accepted. */\nexport function openAiBaseURL(baseURL: string): string {\n const base = baseURL.replace(/\\/+$/u, '');\n return new URL(base).pathname === '/' ? `${base}/v1` : base;\n}\n\n/** Shared by request builders and the settings preview so their paths cannot diverge. */\nexport function inferenceEndpoint(baseURL: string, protocol: ApiProtocol): string {\n const suffix = protocol === 'responses' ? '/responses' : protocol === 'messages' ? '/messages' : '/chat/completions';\n return baseURL.trim() === '' ? suffix : `${openAiBaseURL(baseURL.trim())}${suffix}`;\n}\n\nexport const API_PROTOCOL_OPTIONS: readonly { id: ApiProtocol; name: string; description: string }[] = [\n { id: 'chat-completions', name: 'OpenAI Chat Completions', description: '\u4F7F\u7528 Chat Completions \u8BF7\u6C42\u4E0E\u6D41\u5F0F\u54CD\u5E94\u3002' },\n { id: 'responses', name: 'OpenAI Responses', description: '\u4F7F\u7528 Responses \u8BF7\u6C42\u4E0E\u6D41\u5F0F\u54CD\u5E94\u3002' },\n { id: 'messages', name: 'Anthropic Messages', description: '\u4F7F\u7528 Messages \u8BF7\u6C42\u4E0E\u6D41\u5F0F\u54CD\u5E94\u3002' },\n];\n", "/**\n * \u9010\u6A21\u578B\u8BBE\u7F6E\uFF1A\u7528\u6237\u5728\u76EE\u5F55\u884C\u4E4B\u4E0A\u663E\u5F0F\u8986\u76D6\u7684\u53D1\u9001\u53C2\u6570\u4E0E\u5BB9\u91CF\u3002\n *\n * \u72EC\u7ACB\u4E8E\u6A21\u578B\u53D1\u73B0\u4E0E\u63A8\u7406\u534F\u8BAE\uFF1A\u8FD9\u91CC\u53EA\u505A\u5F62\u72B6\u6821\u9A8C\u4E0E\u526F\u672C\u5408\u6210\uFF0C\u4E0D\u8BFB\u51ED\u636E\u3001\u4E0D\u8054\u7F51\u3001\n * \u4E5F\u4E0D\u5224\u65AD\u67D0\u4E2A\u63A8\u7406\u534F\u8BAE\u662F\u5426\u652F\u6301\u8FD9\u4E9B\u5B57\u6BB5\uFF08\u517C\u5BB9\u6027\u7531\u9002\u914D\u5668\u5728\u7EC4\u88C5\u8BF7\u6C42\u65F6\u51B3\u5B9A\uFF09\u3002\n *\n * \u5B89\u5168\u7EA6\u5B9A\uFF1A\n * - \u91C7\u7528\u5B57\u6BB5\u767D\u540D\u5355\uFF0C\u4EFB\u4F55\u672A\u77E5\u5B57\u6BB5\u4E00\u5F8B\u62D2\u7EDD\uFF0C\u907F\u514D `apiKey`/`headers` \u4E4B\u7C7B\u79D8\u5BC6\u6216\n * \u4E0D\u53EF\u5E8F\u5217\u5316\u503C\u501F\u9053\u8BBE\u7F6E\u5BF9\u8C61\u8FDB\u5165\u6301\u4E45\u5316\u3002\n * - \u62D2\u7EDD `__proto__` / `constructor` / `prototype` \u4F5C\u4E3A\u6A21\u578B ID\uFF0C\u9632\u539F\u578B\u6C61\u67D3\u3002\n * - \u53EA\u8FD4\u56DE\u65B0\u5BF9\u8C61\uFF1A\u4E0D\u628A\u5916\u90E8\u5F15\u7528\uFF08\u6570\u7EC4\u3001\u5D4C\u5957\u5BF9\u8C61\u3001\u76EE\u5F55\u884C\uFF09\u4EA4\u7ED9\u8C03\u7528\u65B9\uFF0C\u4E5F\u4E0D\u6539\u5165\u53C2\u3002\n * - \u9519\u8BEF\u6587\u5B57\u56FA\u5B9A\uFF0C\u4E0D\u56DE\u663E\u8BBE\u7F6E\u503C\u6216\u6A21\u578B ID\u3002\n */\n\nimport type { CatalogModel } from './catalog.js';\n\n/** One model's optional overrides; every field absent means \"inherit the catalog row\". */\nexport interface ModelSettings {\n /** \u662F\u5426\u51FA\u73B0\u5728\u6A21\u578B\u9009\u62E9\u5668\uFF1B\u7F3A\u7701\u89C6\u4E3A\u542F\u7528\u3002 */\n enabled?: boolean;\n /** \u91C7\u6837\u6E29\u5EA6\uFF0C0\u20132\u3002 */\n temperature?: number;\n /** \u6838\u91C7\u6837\uFF0C0\u20131\u3002 */\n topP?: number;\n /** \u5355\u6B21\u8F93\u51FA\u4E0A\u9650\uFF1B\u8986\u76D6\u76EE\u5F55\u884C\u7684 maxOutputTokens\u3002 */\n maxTokens?: number;\n /** \u4E0A\u4E0B\u6587\u7A97\u53E3\uFF1B\u8986\u76D6\u76EE\u5F55\u884C\u7684 contextWindow\u3002 */\n contextWindow?: number;\n /** \u601D\u8003\u6DF1\u5EA6\uFF1B\u53EA\u5141\u8BB8\u76EE\u5F55\u540C\u4E00\u5957\u6863\u4F4D\u3002 */\n reasoningEffort?: string;\n}\n\n/** Model id \u2192 settings. Keys are model ids, never provider-scoped. */\nexport type ModelSettingsMap = Record<string, ModelSettings>;\n\n/** Never accepted as a model id: they would reach `Object.prototype` through a plain copy. */\nconst RESERVED_KEYS: ReadonlySet<string> = new Set(['__proto__', 'constructor', 'prototype']);\n\n/**\n * Validate an untrusted settings payload into a fresh, allowlisted map.\n * This is also a Schemastery transform: all runtime dependencies must live inside\n * the function so JSON serialization and fresh-realm rehydration preserve validation.\n */\nexport function parseModelSettingsMap(value: unknown): ModelSettingsMap {\n // Match the Host record check without importing a closure dependency.\n if (value === null || typeof value !== 'object' || Array.isArray(value)) throw new Error('\u6A21\u578B\u8BBE\u7F6E\u5FC5\u987B\u662F\u5BF9\u8C61');\n const keys = Object.keys(value);\n if (keys.length > 512) throw new Error('\u6A21\u578B\u8BBE\u7F6E\u6700\u591A\u5141\u8BB8 512 \u4E2A\u6A21\u578B');\n const fields = new Set(['enabled', 'temperature', 'topP', 'maxTokens', 'contextWindow', 'reasoningEffort']);\n const efforts: readonly unknown[] = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'ultra', 'max'];\n const out: ModelSettingsMap = {};\n for (const id of keys) {\n if (['__proto__', 'constructor', 'prototype'].includes(id)) throw new Error('\u6A21\u578B\u8BBE\u7F6E\u4E0D\u5141\u8BB8\u4FDD\u7559\u5B57\u6BB5\u540D');\n if (!/^[A-Za-z0-9._:/-]{1,128}$/u.test(id)) throw new Error('\u6A21\u578B ID \u5FC5\u987B\u662F 1\u2013128 \u4F4D\u5B57\u6BCD\u3001\u6570\u5B57\u6216 . _ : / -');\n const entry: unknown = (value as Record<string, unknown>)[id];\n if (entry === null || typeof entry !== 'object' || Array.isArray(entry)) throw new Error('\u6BCF\u4E2A\u6A21\u578B\u7684\u8BBE\u7F6E\u5FC5\u987B\u662F\u5BF9\u8C61');\n const settings = entry as Record<string, unknown>;\n for (const field of Object.keys(settings)) {\n if (!fields.has(field)) throw new Error('\u6A21\u578B\u8BBE\u7F6E\u542B\u6709\u4E0D\u652F\u6301\u7684\u5B57\u6BB5');\n }\n const parsed: ModelSettings = {};\n if (settings.enabled !== undefined) {\n if (typeof settings.enabled !== 'boolean') throw new Error('\u6A21\u578B\u8BBE\u7F6E\u7684 enabled \u5FC5\u987B\u662F\u5E03\u5C14\u503C');\n parsed.enabled = settings.enabled;\n }\n for (const [field, max] of [['temperature', 2], ['topP', 1]] as const) {\n const item = settings[field];\n if (item === undefined) continue;\n if (typeof item !== 'number' || !Number.isFinite(item) || item < 0 || item > max) throw new Error(`\u6A21\u578B\u8BBE\u7F6E\u7684 ${field} \u5FC5\u987B\u662F 0 \u5230 ${max} \u4E4B\u95F4\u7684\u6709\u9650\u6570\u5B57`);\n parsed[field] = item;\n }\n for (const [field, max] of [['maxTokens', 10_000_000], ['contextWindow', 100_000_000]] as const) {\n const item = settings[field];\n if (item === undefined) continue;\n if (typeof item !== 'number' || !Number.isSafeInteger(item) || item < 1 || item > max) throw new Error(`\u6A21\u578B\u8BBE\u7F6E\u7684 ${field} \u5FC5\u987B\u662F 1 \u5230 ${max} \u4E4B\u95F4\u7684\u6574\u6570`);\n parsed[field] = item;\n }\n if (settings.reasoningEffort !== undefined) {\n if (typeof settings.reasoningEffort !== 'string' || !efforts.includes(settings.reasoningEffort)) throw new Error('\u6A21\u578B\u8BBE\u7F6E\u7684 reasoningEffort \u4E0D\u5728\u5141\u8BB8\u7684\u53D6\u503C\u5185');\n parsed.reasoningEffort = settings.reasoningEffort;\n }\n if (parsed.maxTokens !== undefined && parsed.contextWindow !== undefined && parsed.maxTokens >= parsed.contextWindow) throw new Error('\u6A21\u578B\u8BBE\u7F6E\u7684 maxTokens \u5FC5\u987B\u5C0F\u4E8E contextWindow');\n out[id] = parsed;\n }\n return out;\n}\n\n/**\n * Copy a catalog row and apply the user's explicit capacity overrides. The input row and\n * its arrays are never mutated; other overrides (sampling, effort) belong to the request,\n * not to the catalog row, so they are not folded in here.\n */\nexport function applyModelSettings(row: CatalogModel, settings?: ModelSettings): CatalogModel {\n const { contextWindow, maxTokens } = settings ?? {};\n if (contextWindow === undefined && maxTokens === undefined) return { ...row };\n // Validate each override independently; the adapter owns effective-capacity errors\n // (including inherited catalog values) and reports them through its LlmError contract.\n if (contextWindow !== undefined) parseModelSettingsMap({ model: { contextWindow } });\n if (maxTokens !== undefined) parseModelSettingsMap({ model: { maxTokens } });\n return {\n ...row,\n ...(contextWindow === undefined ? {} : { contextWindow }),\n ...(maxTokens === undefined ? {} : { maxOutputTokens: maxTokens }),\n };\n}\n\n/** A model is selectable unless the map explicitly disables it; unknown ids and an absent map stay enabled. */\nexport function isModelEnabled(id: string, settings: ModelSettingsMap = {}): boolean {\n if (RESERVED_KEYS.has(id) || !Object.hasOwn(settings, id)) return true;\n return settings[id]?.enabled !== false;\n}\n", "// Adapted from dsh-opendesign-go message/image compatibility handling (MIT).\nimport { LlmError, textOnlyImageText, type ContentBlock, type GenerateOptions } from '@deepseek-ai/dsh-llm';\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';\n\nexport type ImageResolver = (ref: ImageAttachmentRef) => string | undefined;\ntype Part = { type: 'text'; text: string } | { type: 'image_url'; image_url: { url: string } };\nexport interface WireMessage {\n role: 'system' | 'user' | 'assistant' | 'tool';\n content: string | Part[];\n tool_call_id?: string;\n tool_calls?: { id: string; type: 'function'; function: { name: string; arguments: string } }[];\n reasoning_content?: string;\n}\nfunction parts(blocks: readonly ContentBlock[], image?: ImageResolver): { text: string; images: string[] } {\n let text = '';\n const images: string[] = [];\n for (const block of blocks) {\n switch (block.type) {\n case 'text': text += block.text; break;\n case 'image': {\n const url = block.offloaded ? undefined : image?.(block.attachment);\n if (url) images.push(url);\n else text += `${text ? '\\n' : ''}${textOnlyImageText(block.attachment)}`;\n break;\n }\n case 'file': throw new LlmError('\u539F\u59CB\u6587\u4EF6\u672A\u88AB\u5BBF\u4E3B\u6295\u5F71\u4E3A\u6587\u672C\u53E5\u67C4', 'UNSUPPORTED_OPTION');\n // Tool definitions are already materialized in options.tools by Core.\n default: break;\n }\n }\n return { text, images };\n}\nfunction content(text: string, images: string[]): string | Part[] {\n return images.length ? [...(text ? [{ type: 'text' as const, text }] : []), ...images.map(url => ({ type: 'image_url' as const, image_url: { url } }))] : text;\n}\nexport function chatMessages(options: GenerateOptions, image?: ImageResolver, replayReasoning = false): WireMessage[] {\n const out: WireMessage[] = [];\n let lifted: string[] = [];\n function flush() {\n if (!lifted.length) return;\n out.push({ role: 'user', content: content('(Image content from the preceding tool result.)', lifted) });\n lifted = [];\n }\n for (const message of options.messages) {\n if (message.role !== 'tool') flush();\n const parsed = parts(message.content, message.role === 'user' || message.role === 'tool' ? image : undefined);\n switch (message.role) {\n case 'system': case 'developer':\n if (parsed.text) out.push({ role: 'system', content: parsed.text });\n break;\n case 'user':\n if (parsed.text || parsed.images.length) out.push({ role: 'user', content: content(parsed.text, parsed.images) });\n break;\n case 'assistant': {\n const calls = message.content.filter(block => block.type === 'tool-call').map(block => ({ id: block.id, type: 'function' as const, function: { name: block.name, arguments: block.arguments } }));\n const reasoning = message.content.filter(block => block.type === 'reasoning').map(block => block.text).join('');\n if (parsed.text || calls.length || parsed.images.length) out.push({ role: 'assistant', content: content(parsed.text, parsed.images), ...(calls.length ? { tool_calls: calls } : {}), ...(replayReasoning && reasoning ? { reasoning_content: reasoning } : {}) });\n break;\n }\n case 'tool':\n out.push({ role: 'tool', tool_call_id: message.toolCallId, content: parsed.text || (parsed.images.length ? '(Image content follows in the next user message.)' : '') });\n lifted.push(...parsed.images);\n break;\n }\n }\n flush();\n if (options.system?.trim()) {\n const first = out[0];\n if (first?.role === 'system' && typeof first.content === 'string') first.content = `${options.system}\\n\\n${first.content}`;\n else out.unshift({ role: 'system', content: options.system });\n }\n return out;\n}\nexport function chatTools(options: GenerateOptions) {\n return options.tools?.length ? options.tools.map(tool => ({ type: 'function' as const, function: { name: tool.name, description: tool.description, parameters: tool.parameters } })) : undefined;\n}\nexport function estimateTokens(value: unknown): number {\n let ascii = 0, wide = 0, images = 0;\n function walk(x: unknown): void {\n if (typeof x === 'string') { for (const c of x) { if ((c.codePointAt(0) ?? 0) < 128) ascii++; else wide++; } }\n else if (Array.isArray(x)) for (const item of x) walk(item);\n else if (x && typeof x === 'object') {\n if ('type' in x && x.type === 'image_url') { images++; return; }\n for (const item of Object.values(x)) walk(item);\n }\n }\n walk(value);\n return Math.ceil(ascii / 3.5 + wide / 2) + images * 1024;\n}\n", "/**\n * Chat Completions \u7684\u6D41\u5F0F\u6295\u5F71\u4E0E\u5171\u4EAB\u9519\u8BEF\u5206\u7C7B\u3002\n *\n * \u5206\u5E27\u5DF2\u62BD\u5230 `protocols/sse.ts`\uFF08\u4E09\u79CD\u534F\u8BAE\u5171\u7528\u540C\u4E00\u5957\u53D6\u6D88/\u7A7A\u95F2/\u5927\u5C0F\u8FB9\u754C\uFF09\uFF0C\u8FD9\u91CC\u53EA\u4FDD\u7559\n * Chat Completions \u7684\u4E8B\u4EF6\u8BED\u4E49\uFF1B`gatewayError` \u4E5F\u4ECE `protocols/errors.ts` \u7EDF\u4E00\u63D0\u4F9B\uFF0C\n * \u4EE5\u4FDD\u6301\u65E2\u6709 `import { gatewayError } from './stream.js'` \u7684\u8C03\u7528\u70B9\u4E0D\u53D8\u3002\n */\n\nimport { LlmError, ToolCallId, type StreamChunk, type TokenUsage, type FinishReason } from '@deepseek-ai/dsh-llm';\nimport { record, finite } from './util.js';\nimport { gatewayError } from './protocols/errors.js';\nimport { sseFrames } from './protocols/sse.js';\n\nexport { gatewayError } from './protocols/errors.js';\n\n/** Chat Completions \u7684 `usage` \u6298\u7B97\uFF08`prompt_tokens` \u542B\u7F13\u5B58\uFF0C\u6309\u4E0D\u76F8\u4EA4\u53E3\u5F84\u51CF\u51FA\uFF09\u3002 */\nexport function tokenUsage(value: Record<string, unknown>): TokenUsage | undefined {\n const prompt = finite(value.prompt_tokens), output = finite(value.completion_tokens);\n if (prompt === undefined || output === undefined || prompt < 0 || output < 0) return;\n const pd = record(value.prompt_tokens_details) ? value.prompt_tokens_details : {};\n const cd = record(value.completion_tokens_details) ? value.completion_tokens_details : {};\n const read = finite(pd.cached_tokens) ?? finite(value.prompt_cache_hit_tokens) ?? 0;\n const write = finite(pd.cache_write_tokens) ?? finite(value.prompt_cache_write_tokens) ?? finite(value.cache_creation_input_tokens) ?? 0;\n // Invalid cache counters cannot become negative or invent input usage.\n const validCache = read >= 0 && write >= 0 && read + write <= prompt;\n const reasoning = finite(cd.reasoning_tokens);\n return {\n inputTokens: validCache ? prompt - read - write : prompt,\n outputTokens: output, totalTokens: prompt + output,\n ...(validCache && read > 0 ? { cacheReadTokens: read } : {}),\n ...(validCache && write > 0 ? { cacheWriteTokens: write } : {}),\n ...(reasoning !== undefined && reasoning >= 0 && reasoning <= output ? { reasoningTokens: reasoning } : {}),\n };\n}\n\ninterface OpenText { index: number; text: string }\ninterface OpenTool { index: number; id: string; name: string; arguments: string; started: boolean }\n\n/** Bounded SSE projection for Chat Completions; a broken/truncated response is never reported as success. */\nexport async function* consumeSse(body: ReadableStream<Uint8Array>, signal: AbortSignal, idleMs: number): AsyncGenerator<StreamChunk> {\n let nextIndex = 0, count = 0, sawTool = false, done = false;\n let text: OpenText | undefined, reasoning: OpenText | undefined;\n const tools = new Map<number, OpenTool>();\n let finish: FinishReason | undefined, usage: TokenUsage | undefined;\n function close(): StreamChunk[] {\n const out: StreamChunk[] = [];\n if (text) out.push({ type: 'block-end', index: text.index, block: { type: 'text', text: text.text } });\n if (reasoning) out.push({ type: 'block-end', index: reasoning.index, block: { type: 'reasoning', text: reasoning.text } });\n for (const call of tools.values()) {\n if (!call.id || !call.name) throw new LlmError('OpenDesign\uFF1A\u5DE5\u5177\u8C03\u7528\u7F3A\u5C11\u6807\u8BC6\u6216\u540D\u79F0', 'INVALID_RESPONSE');\n out.push({ type: 'block-end', index: call.index, block: { type: 'tool-call', id: ToolCallId(call.id), name: call.name, arguments: call.arguments } });\n }\n text = reasoning = undefined; tools.clear();\n return out.sort((a, b) => ('index' in a ? a.index : 0) - ('index' in b ? b.index : 0));\n }\n function event(payload: string): StreamChunk[] {\n if (!payload) return [];\n if (payload.trim() === '[DONE]') { done = true; return []; }\n let value: unknown;\n try { value = JSON.parse(payload); } catch { throw new LlmError('OpenDesign\uFF1A\u65E0\u6548\u7684\u6D41\u5F0F JSON', 'INVALID_RESPONSE'); }\n if (!record(value)) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u4E8B\u4EF6\u4E0D\u662F\u5BF9\u8C61', 'INVALID_RESPONSE');\n if (record(value.error)) throw gatewayError(undefined, value);\n if (record(value.usage)) usage = tokenUsage(value.usage) ?? usage;\n if (!Array.isArray(value.choices) || !value.choices.length) return [];\n const choice = value.choices[0];\n if (!record(choice)) throw new LlmError('OpenDesign\uFF1A\u65E0\u6548\u7684\u6D41\u5F0F\u9009\u9879', 'INVALID_RESPONSE');\n const delta = record(choice.delta) ? choice.delta : {};\n const out: StreamChunk[] = [];\n const hasDelta = typeof delta.content === 'string' && delta.content !== '' || typeof delta.reasoning_content === 'string' && delta.reasoning_content !== '' || Array.isArray(delta.tool_calls) && delta.tool_calls.length > 0;\n if (finish && hasDelta) throw new LlmError('OpenDesign\uFF1A\u54CD\u5E94\u7ED3\u675F\u540E\u4ECD\u6536\u5230\u5185\u5BB9', 'INVALID_RESPONSE');\n const thinking = typeof delta.reasoning_content === 'string' ? delta.reasoning_content : typeof delta.reasoning === 'string' ? delta.reasoning : '';\n if (thinking) {\n if (!reasoning) { reasoning = { index: nextIndex++, text: '' }; count++; out.push({ type: 'block-start', index: reasoning.index, blockType: 'reasoning' }); }\n reasoning.text += thinking;\n out.push({ type: 'reasoning-delta', index: reasoning.index, text: thinking });\n }\n if (typeof delta.content === 'string' && delta.content) {\n if (!text) { text = { index: nextIndex++, text: '' }; count++; out.push({ type: 'block-start', index: text.index, blockType: 'text' }); }\n text.text += delta.content;\n out.push({ type: 'text-delta', index: text.index, text: delta.content });\n }\n if (Array.isArray(delta.tool_calls)) for (const item of delta.tool_calls) {\n if (!record(item) || typeof item.index !== 'number' || !Number.isInteger(item.index) || item.index < 0) throw new LlmError('OpenDesign\uFF1A\u65E0\u6548\u7684\u5DE5\u5177\u8C03\u7528\u7D22\u5F15', 'INVALID_RESPONSE');\n let call = tools.get(item.index);\n if (!call) { call = { index: nextIndex++, id: '', name: '', arguments: '', started: false }; tools.set(item.index, call); count++; sawTool = true; }\n const fn = record(item.function) ? item.function : {};\n if (typeof item.id === 'string' && item.id) {\n if (call.id && call.id !== item.id) throw new LlmError('OpenDesign\uFF1A\u5DE5\u5177\u8C03\u7528\u6807\u8BC6\u53D1\u751F\u53D8\u5316', 'INVALID_RESPONSE');\n call.id = item.id;\n }\n if (typeof fn.name === 'string' && fn.name) call.name = fn.name; // gateway may repeat the complete name; only arguments are deltas\n if (typeof fn.arguments === 'string') call.arguments += fn.arguments;\n // A few gateways deliver the id after the first argument fragment.\n if (call.id) {\n const first = !call.started;\n if (first) { out.push({ type: 'block-start', index: call.index, blockType: 'tool-call' }); call.started = true; }\n out.push({ type: 'tool-call-delta', index: call.index, id: ToolCallId(call.id), ...(call.name ? { name: call.name } : {}), argumentsDelta: first ? call.arguments : typeof fn.arguments === 'string' ? fn.arguments : '' });\n }\n }\n if (typeof choice.finish_reason === 'string' && choice.finish_reason) {\n if (finish) throw new LlmError('OpenDesign\uFF1A\u91CD\u590D\u7684\u54CD\u5E94\u7EC8\u6B62\u4E8B\u4EF6', 'INVALID_RESPONSE');\n switch (choice.finish_reason) {\n case 'length': finish = { kind: 'max-tokens' }; break;\n case 'tool_calls': case 'function_call': finish = { kind: 'tool-calls' }; break;\n case 'stop': finish = { kind: 'stop' }; break;\n default: throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u54CD\u5E94\u88AB\u8FC7\u6EE4\u6216\u5F02\u5E38\u7EC8\u6B62', 'INVALID_RESPONSE');\n }\n out.push(...close());\n }\n return out;\n }\n\n for await (const frame of sseFrames(body, signal, idleMs)) {\n for (const chunk of event(frame.data)) yield chunk;\n if (done) break;\n }\n\n signal.throwIfAborted();\n if (!finish) throw new LlmError('OpenDesign\uFF1A\u54CD\u5E94\u6D41\u63D0\u524D\u4E2D\u65AD\uFF0C\u672A\u6536\u5230\u7ED3\u675F\u539F\u56E0', 'INVALID_RESPONSE');\n if (!count) throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u8FD4\u56DE\u7A7A\u54CD\u5E94', 'EMPTY_RESPONSE');\n if (finish.kind === 'tool-calls' && !sawTool) throw new LlmError('OpenDesign\uFF1A\u54CD\u5E94\u58F0\u660E\u5DE5\u5177\u8C03\u7528\uFF0C\u4F46\u672A\u8FD4\u56DE\u4EFB\u4F55\u5DE5\u5177\u5757', 'INVALID_RESPONSE');\n if (usage) yield { type: 'usage', usage };\n yield { type: 'finish', reason: finish };\n}\n", "export function record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\nexport function finite(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\nexport function positive(value: unknown): number | undefined {\n const n = finite(value);\n return n !== undefined && n > 0 ? n : undefined;\n}\nexport function safeSecret(raw: string): string {\n const value = raw.trim();\n if (!value || /[^\\x20-\\x7e]/u.test(value)) throw new Error('\u51ED\u636E\u4E3A\u7A7A\u6216\u542B\u6709\u4E0D\u53EF\u7528\u4E8E HTTP \u8BF7\u6C42\u5934\u7684\u5B57\u7B26');\n return value;\n}\nexport function combinedSignal(signal: AbortSignal | undefined, timeoutMs: number): AbortSignal {\n const deadline = AbortSignal.timeout(timeoutMs);\n return signal ? AbortSignal.any([signal, deadline]) : deadline;\n}\nexport function sleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise(resolve => {\n if (signal.aborted) return resolve();\n const done = () => { clearTimeout(timer); signal.removeEventListener('abort', done); resolve(); };\n const timer = setTimeout(done, ms);\n signal.addEventListener('abort', done, { once: true });\n });\n}\n", "/**\n * \u4E0A\u6E38\u5931\u8D25\u7684\u7A33\u5B9A\u5206\u7C7B\u3002\n *\n * \u4E09\u79CD\u534F\u8BAE\u7684\u4FE1\u5C01\u4E0D\u540C\uFF0C\u4F46\u5BF9\u5916\u53EA\u66B4\u9732\u56FA\u5B9A\u7684\u4E2D\u6587\u6587\u5B57\u4E0E\u673A\u5668\u7801\uFF1B\u4E0A\u6E38 `message`\u3001\u8BF7\u6C42\u5934\u3001\n * \u51ED\u636E\u4E0E\u54CD\u5E94\u4F53\u4E00\u5F8B\u4E0D\u8FDB\u5165\u9519\u8BEF\u6587\u5B57\uFF0C\u907F\u514D\u5BC6\u94A5\u6216\u7B2C\u4E09\u65B9\u5185\u5BB9\u8FDB\u5165\u65E5\u5FD7\u4E0E UI\u3002\n *\n * \u5224\u5B9A\u987A\u5E8F\uFF08\u524D\u8005\u4F18\u5148\uFF09\uFF1A\n * 1. \u4FE1\u5C01\u5185\u7ED3\u6784\u5316\u7684 `code` / `type`\uFF1A\u53EA\u8BA4\u660E\u786E\u7684\u679A\u4E3E\u5F0F\u5199\u6CD5\uFF1B\n * 2. \u4E3B\u9898\u660E\u786E\u7684 `message`\uFF1A\u4E0A\u4E0B\u6587\u6EA2\u51FA\u3001\u989D\u5EA6\u8017\u5C3D\u3001\u9650\u6D41\u3001\u8D85\u65F6\u3001\u670D\u52A1\u7AEF\u3001\u8BA4\u8BC1/\u6743\u9650\uFF1B\n * 3. HTTP \u72B6\u6001\uFF1A\u4EC5\u4F5C\u4E3A\u8865\u5145\u4E8B\u5B9E\uFF0C\u4E0D\u8986\u76D6\u4E0A\u9762\u66F4\u5177\u4F53\u7684\u5206\u7C7B\uFF1B\u552F\u4E00\u4F8B\u5916\u662F 5xx\u2014\u2014\n * \u6CA1\u6709\u7ED3\u6784\u5316\u4EE3\u7801\u65F6\u76F4\u63A5\u6309\u670D\u52A1\u7AEF\u5904\u7406\uFF08504 \u4ECD\u6309\u8D85\u65F6\uFF09\uFF0C\u4E0D\u56E0\u6B63\u6587\u63AA\u8F9E\u6539\u5224\u3002\n *\n * \u5173\u952E\u53D6\u820D\uFF1A\n * - \u989D\u5EA6\u5206\u4E24\u6C60\uFF1A\u5957\u9910/\u8BA2\u9605/\u8D26\u6237\u989D\u5EA6 \u2192 `ACCOUNT_QUOTA`\uFF1B\u94B1\u5305/\u5145\u503C/\u79EF\u5206/\u4F59\u989D \u2192 `QUOTA`\u3002\n * \u53EA\u6709\u201C\u989D\u5EA6\u4E0D\u8DB3\u201D\u800C\u6CA1\u6709\u6C60\u4FE1\u606F\u65F6\u6309\u8D26\u6237\u989D\u5EA6\u5904\u7406\u3002\n * - \u666E\u901A 401/403 \u53EA\u8868\u8FBE\u8BA4\u8BC1\u6216\u6743\u9650\u8BED\u4E49\uFF08`AUTH` / `PERMISSION`\uFF09\uFF0C\u4E0D\u63A8\u65AD API Key \u65E0\u6548\uFF1B\n * \u53EA\u6709\u4E0A\u6E38\u660E\u786E\u70B9\u540D Key/\u51ED\u636E\u65E0\u6548\u6216\u7F3A\u5931\uFF08\u7ED3\u6784\u5316 code \u6216\u660E\u786E\u6587\u6848\uFF09\u624D\u662F `INVALID_CREDENTIAL`\u3002\n * \u7ED3\u6784\u5316\u53EA\u7ED9\u51FA\u8BA4\u8BC1/\u6743\u9650\u8BED\u4E49\u65F6\uFF0C\u70B9\u540D Key \u7684\u660E\u786E\u6587\u6848\u53EF\u4EE5\u628A\u7ED3\u8BBA\u7EC6\u5316\u4E3A\u51ED\u636E\u9519\u8BEF\u3002\n * - `quota` / `context` \u5355\u72EC\u51FA\u73B0\u53EA\u662F\u80CC\u666F\u8BCD\uFF1B\u5FC5\u987B\u540C\u65F6\u51FA\u73B0\u201C\u8017\u5C3D/\u8D85\u51FA\u201D\u7B49\u8BED\u4E49\u624D\u7B97\u6570\uFF0C\n * \u56E0\u6B64 `rate_limit_exceeded` \u4E0D\u4F1A\u88AB\u6CDB\u5316\u6210\u989D\u5EA6\u4E0D\u8DB3\uFF0C\u4E5F\u4E0D\u4F1A\u56E0\u4E3A\u6B63\u6587\u63D0\u5230\u201C\u4E0A\u4E0B\u6587\u7F13\u5B58\u201D\u800C\u8BEF\u5224\u3002\n * - HTTP \u72B6\u6001\u4E0E\u7ED3\u6784\u5316\u9519\u8BEF\u51B2\u7A81\u65F6\u4EE5\u7ED3\u6784\u5316\u9519\u8BEF\u4E3A\u51C6\uFF1A\u5178\u578B\u7684 429 + `insufficient_quota`\n * \u5F52\u5165\u989D\u5EA6\u800C\u4E0D\u662F\u9650\u6D41\uFF0C401 + \u989D\u5EA6\u8BC1\u636E\u5F52\u5165\u989D\u5EA6\u800C\u4E0D\u662F\u8BA4\u8BC1\u3002\n */\n\nimport {\n ACCOUNT_QUOTA_EXCEEDED_CODE,\n CONTEXT_WINDOW_EXCEEDED_CODE,\n INVALID_CREDENTIAL_CODE,\n LlmError,\n QUOTA_EXCEEDED_CODE,\n isContextWindowExceededError,\n isQuotaExceededError,\n} from '@deepseek-ai/dsh-llm';\nimport { record } from '../util.js';\n\n/** \u56FA\u5B9A\u6587\u6848\uFF1A\u53EA\u8BF4\u660E\u5206\u7C7B\u4E0E\u4E0B\u4E00\u6B65\uFF0C\u7EDD\u4E0D\u62FC\u63A5\u4E0A\u6E38\u6587\u5B57\u3001\u72B6\u6001\u4EE5\u5916\u7684\u54CD\u5E94\u4E8B\u5B9E\u6216\u51ED\u636E\u3002 */\nconst MESSAGES: Readonly<Record<string, string>> = {\n [CONTEXT_WINDOW_EXCEEDED_CODE]: 'OpenDesign\uFF1A\u8BF7\u6C42\u8D85\u51FA\u6A21\u578B\u4E0A\u4E0B\u6587\u957F\u5EA6\uFF0C\u8BF7\u7F29\u77ED\u8F93\u5165\u540E\u91CD\u8BD5',\n [ACCOUNT_QUOTA_EXCEEDED_CODE]: 'OpenDesign\uFF1A\u5957\u9910\u6216\u8D26\u6237\u989D\u5EA6\u4E0D\u8DB3\uFF0C\u8BF7\u68C0\u67E5\u5957\u9910\u989D\u5EA6\u540E\u91CD\u8BD5',\n [QUOTA_EXCEEDED_CODE]: 'OpenDesign\uFF1A\u94B1\u5305\u6216\u79EF\u5206\u4F59\u989D\u4E0D\u8DB3\uFF0C\u8BF7\u5145\u503C\u540E\u91CD\u8BD5',\n [INVALID_CREDENTIAL_CODE]: 'OpenDesign\uFF1AAPI Key \u65E0\u6548\u6216\u7F3A\u5931\uFF0C\u8BF7\u5728\u8BBE\u7F6E\u4E2D\u66F4\u65B0\u51ED\u636E',\n AUTH: 'OpenDesign\uFF1A\u8BA4\u8BC1\u672A\u901A\u8FC7\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55\u540E\u91CD\u8BD5',\n PERMISSION: 'OpenDesign\uFF1A\u5F53\u524D\u8D26\u6237\u65E0\u6743\u8BBF\u95EE\u8BE5\u6A21\u578B',\n RATE_LIMIT: 'OpenDesign\uFF1A\u8BF7\u6C42\u8FC7\u4E8E\u9891\u7E41\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5',\n TIMEOUT: 'OpenDesign\uFF1A\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5',\n SERVER: 'OpenDesign\uFF1A\u4E0A\u6E38\u670D\u52A1\u6682\u4E0D\u53EF\u7528\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5',\n INVALID_REQUEST: 'OpenDesign\uFF1A\u8BF7\u6C42\u88AB\u4E0A\u6E38\u62D2\u7EDD',\n INVALID_RESPONSE: 'OpenDesign\uFF1A\u4E0A\u6E38\u54CD\u5E94\u683C\u5F0F\u65E0\u6548',\n};\nconst UNKNOWN_MESSAGE = 'OpenDesign\uFF1A\u8BF7\u6C42\u5931\u8D25';\n\n/* \u2500\u2500 \u7ED3\u6784\u5316 code/type\uFF1A\u53EA\u8BA4\u679A\u4E3E\u5F0F\u5199\u6CD5\uFF0C\u907F\u514D\u628A\u666E\u901A\u5355\u8BCD\u5F53\u5206\u7C7B\u4F9D\u636E \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\nconst STRUCTURED_CREDENTIAL =\n /invalid[_-]?(?:x[_-]?)?api[_-]?key|missing[_-]?(?:x[_-]?)?api[_-]?key|incorrect[_-]?(?:x[_-]?)?api[_-]?key|api[_-]?key[_-]?(?:invalid|missing|incorrect)|invalid[_-]?credentials?|credentials?[_-]?(?:invalid|missing)/u;\nconst STRUCTURED_CONTEXT =\n /context[_-]?(?:length|window)[_-]?(?:exceeded|exceed|overflow)|context[_-]?overflow|(?:prompt|input)[_-]?too[_-]?long/u;\nconst STRUCTURED_WALLET =\n /(?:insufficient|low|exhausted|depleted|empty|zero)[_-]?(?:credits?|balance|funds)|(?:credits?|balance|wallet|funds)[_-]?(?:insufficient|exhausted|depleted|low|empty)|(?:credit|wallet)[_-]balance[_-](?:too[_-]low|insufficient|exhausted)/u;\nconst STRUCTURED_PLAN =\n /(?:insufficient|exceeded|exhausted|reached|over)[_-]?(?:quota|plan|usage[_-]?limit)|quota[_-]?(?:exceeded|exhausted|reached)|billing[_-]?hard[_-]?limit|usage[_-]?limit[_-]?(?:exceeded|reached)|(?:subscription|membership|plan)(?:[_-](?:quota|credits?|limit))?[_-](?:exceeded|exhausted|insufficient|reached)/u;\nconst STRUCTURED_RATE =\n /rate[_-]?limit|too[_-]?many[_-]?requests|resource[_-]?exhausted|(?:requests?|tokens?)[_-]?per[_-]?(?:minute|second)/u;\nconst STRUCTURED_TIMEOUT = /timeout|timed[_-]?out|deadline[_-]?exceeded/u;\nconst STRUCTURED_SERVER =\n /server[_-]?error|api[_-]?error|internal[_-]?(?:server[_-]?)?error|service[_-]?unavailable|unavailable|overloaded|bad[_-]?gateway|gateway[_-]?error/u;\nconst STRUCTURED_AUTH = /authentication|unauthorized|not[_-]?authenticated/u;\nconst STRUCTURED_PERMISSION = /permission|forbidden|access[_-]?denied|insufficient[_-]?scope/u;\n\n/* \u2500\u2500 message \u6587\u6848\uFF1A\u6BCF\u6761\u90FD\u5FC5\u987B\u5E26\u660E\u786E\u7684\u5931\u8D25\u8BED\u4E49\uFF0C\u5355\u7EAF\u7684\u4E3B\u9898\u8BCD\u4E0D\u7B97 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/** \u53EA\u6709\u660E\u786E\u70B9\u540D Key/\u51ED\u636E\u65E0\u6548\u6216\u7F3A\u5931\u624D\u7B97\u51ED\u636E\u9519\u8BEF\uFF1B\u5173\u952E\u8BCD\u672C\u8EAB\u4E0D\u63A8\u65AD\u3002 */\nconst PROSE_CREDENTIAL =\n /invalid[ _-]?(?:x[ _-]?)?api[ _-]?key|(?:x[ _-]?)?api[ _-]?key[ _-]?(?:is[ _-]?)?(?:invalid|missing|incorrect|not[ _-]?valid)|missing[ _-]?(?:x[ _-]?)?api[ _-]?key|incorrect[ _-]?(?:x[ _-]?)?api[ _-]?key|invalid[ _-]?credentials?\\b|api[ _-]?key\\s*(?:\u65E0\u6548|\u7F3A\u5931|\u9519\u8BEF)|\u5BC6\u94A5(?:\u65E0\u6548|\u7F3A\u5931|\u9519\u8BEF)/u;\nconst PROSE_CONTEXT_EN =\n /\\b(?:prompt|input|messages?)\\s+(?:is\\s+|are\\s+)?too\\s+(?:long|large)\\b|\\bmaximum context\\b|\\btokens? > \\d+ maximum\\b/u;\nconst PROSE_CONTEXT_ZH =\n /\u8D85\u51FA[^\u3002]{0,8}\u4E0A\u4E0B\u6587|\u4E0A\u4E0B\u6587[^\u3002]{0,16}(?:\u8D85\u51FA|\u8D85\u8FC7|\u8D85\u9650|\u8FC7\u957F|\u5DF2\u6EE1)|(?:\u8F93\u5165|\u8BF7\u6C42|\u63D0\u793A\u8BCD)[^\u3002]{0,8}(?:\u8FC7\u957F|\u592A\u957F)|\u8D85\u8FC7[^\u3002]{0,8}\u4E0A\u4E0B\u6587/u;\nconst PROSE_QUOTA_EN =\n /\\b(?:credits?|balance|quota|funds|wallet)\\b[^.;]{0,24}\\b(?:insufficient|exhausted|depleted|used[ _-]?up|too[ _-]?low|empty|zero|exceeded)\\b|\\b(?:insufficient|exhausted|depleted|empty|zero)\\b[^.;]{0,24}\\b(?:credits?|balance|quota|funds|wallet)\\b/u;\nconst PROSE_QUOTA_ZH =\n /(?:\u4F59\u989D|\u79EF\u5206|\u989D\u5EA6|\u914D\u989D|\u94B1\u5305)[^\u3002]{0,12}(?:\u4E0D\u8DB3|\u7528\u5C3D|\u8017\u5C3D|\u7528\u5B8C|\u8D85\u9650|\u8D85\u51FA|\u5DF2\u8FBE\u4E0A\u9650|\u8D85\u8FC7\u4E0A\u9650)|(?:\u4E0D\u8DB3|\u7528\u5C3D|\u8017\u5C3D)[^\u3002]{0,6}(?:\u4F59\u989D|\u989D\u5EA6|\u914D\u989D|\u79EF\u5206)/u;\nconst PROSE_QUOTA_PLAN =\n /\u5957\u9910|\u8BA2\u9605|\u4F1A\u5458|\u8D26\u6237\u989D\u5EA6|\u8D26\u6237\u914D\u989D|\u7528\u91CF\u4E0A\u9650|\u4F7F\u7528\u4E0A\u9650|\\bplan\\b|\\bsubscription\\b|\\bmembership\\b|\\bbilling\\b|hard[ _-]?limit|usage[ _-]?limit/u;\nconst PROSE_QUOTA_WALLET =\n /\u94B1\u5305|\u5145\u503C|\u4F59\u989D|\u79EF\u5206|\\bwallet\\b|\\brecharge\\b|top[ _-]?up|\\bbalance\\b|\\bcredits?\\b|\\bfunds?\\b/u;\nconst PROSE_RATE = /rate[ _-]?limit|\\btoo many requests\\b|\\bresource[ _-]?exhausted\\b|\u8BF7\u6C42\u8FC7\u4E8E\u9891\u7E41|\u9891\u7387\u8D85\u9650|\u89E6\u53D1\u9650\u6D41|\u63A5\u53E3\u9650\u6D41/u;\nconst PROSE_TIMEOUT = /\\btimeout\\b|\\btimed out\\b|\\bdeadline exceeded\\b|\u8BF7\u6C42\u8D85\u65F6|\u8D85\u65F6/u;\nconst PROSE_SERVER =\n /\\bserver error\\b|\\bapi error\\b|\\binternal (?:server )?error\\b|\\bservice unavailable\\b|\\boverloaded\\b|\\bbad gateway\\b|\u670D\u52A1\u6682\u4E0D\u53EF\u7528|\u670D\u52A1\u4E0D\u53EF\u7528|\u670D\u52A1\u5668\u9519\u8BEF|\u670D\u52A1\u5668\u7E41\u5FD9|\u5185\u90E8\u9519\u8BEF/u;\nconst PROSE_AUTH = /\\bauthentication\\b|\\bunauthorized\\b|\\bnot authenticated\\b|\u8BA4\u8BC1\u5931\u8D25|\u767B\u5F55\u5DF2\u5931\u6548|\u672A\u767B\u5F55/u;\nconst PROSE_PERMISSION =\n /\\bpermission\\b|\\bforbidden\\b|\\baccess denied\\b|\\bnot authorized\\b|\\binsufficient (?:permissions?|scope)\\b|\u6743\u9650\u4E0D\u8DB3|\u65E0\u6743\u9650|\u65E0\u6743\u8BBF\u95EE/u;\n\n/** \u6784\u9020\u56FA\u5B9A\u6587\u6848\u7684\u9519\u8BEF\uFF1BHTTP \u72B6\u6001\u53EA\u4F5C\u4E3A\u7ED3\u6784\u5316\u4E8B\u5B9E\u4FDD\u7559\uFF0C\u4E0D\u62FC\u8FDB\u6587\u5B57\u3002 */\nfunction fail(code: string, status: number | undefined): LlmError {\n const options = status === undefined ? {} : { status };\n return new LlmError(MESSAGES[code] ?? UNKNOWN_MESSAGE, code, options);\n}\n\nfunction matches(fields: readonly string[], pattern: RegExp): boolean {\n return fields.some(field => pattern.test(field));\n}\n\n/** \u7ED3\u6784\u5316\u989D\u5EA6\u6309\u6C60\u62C6\u5206\uFF1A\u94B1\u5305/\u79EF\u5206\u4F18\u5148\uFF0C\u5176\u4F59\u89C6\u4E3A\u5957\u9910\u6216\u8D26\u6237\u989D\u5EA6\u3002 */\nfunction structuredQuota(fields: readonly string[]): string | undefined {\n if (matches(fields, STRUCTURED_WALLET)) return QUOTA_EXCEEDED_CODE;\n if (matches(fields, STRUCTURED_PLAN)) return ACCOUNT_QUOTA_EXCEEDED_CODE;\n return undefined;\n}\n\n/** \u6587\u6848\u989D\u5EA6\u540C\u6837\u6309\u6C60\u62C6\u5206\uFF1A\u5957\u9910/\u8BA2\u9605\u4F18\u5148\uFF0C\u5176\u6B21\u94B1\u5305/\u79EF\u5206\uFF0C\u672A\u6307\u660E\u6C60\u65F6\u6309\u8D26\u6237\u989D\u5EA6\u3002 */\nfunction proseQuota(detail: string): string {\n if (PROSE_QUOTA_PLAN.test(detail)) return ACCOUNT_QUOTA_EXCEEDED_CODE;\n if (PROSE_QUOTA_WALLET.test(detail)) return QUOTA_EXCEEDED_CODE;\n return ACCOUNT_QUOTA_EXCEEDED_CODE;\n}\n\nfunction classifyStructured(fields: readonly string[]): string | undefined {\n if (matches(fields, STRUCTURED_CREDENTIAL)) return INVALID_CREDENTIAL_CODE;\n if (matches(fields, STRUCTURED_CONTEXT)) return CONTEXT_WINDOW_EXCEEDED_CODE;\n const quota = structuredQuota(fields);\n if (quota !== undefined) return quota;\n if (matches(fields, STRUCTURED_RATE)) return 'RATE_LIMIT';\n if (matches(fields, STRUCTURED_TIMEOUT)) return 'TIMEOUT';\n if (matches(fields, STRUCTURED_SERVER)) return 'SERVER';\n if (matches(fields, STRUCTURED_AUTH)) return 'AUTH';\n if (matches(fields, STRUCTURED_PERMISSION)) return 'PERMISSION';\n return undefined;\n}\n\nfunction classifyProse(detail: string): string | undefined {\n if (detail === '') return undefined;\n if (isContextWindowExceededError(detail) || PROSE_CONTEXT_EN.test(detail) || PROSE_CONTEXT_ZH.test(detail)) return CONTEXT_WINDOW_EXCEEDED_CODE;\n if (isQuotaExceededError(detail) || PROSE_QUOTA_EN.test(detail) || PROSE_QUOTA_ZH.test(detail)) return proseQuota(detail);\n if (PROSE_RATE.test(detail)) return 'RATE_LIMIT';\n if (PROSE_TIMEOUT.test(detail)) return 'TIMEOUT';\n if (PROSE_SERVER.test(detail)) return 'SERVER';\n if (PROSE_AUTH.test(detail)) return 'AUTH';\n if (PROSE_PERMISSION.test(detail)) return 'PERMISSION';\n return undefined;\n}\n\n/** HTTP \u72B6\u6001\u53EA\u8865\u8DB3\u7ED3\u6784\u5316\u4E0E\u6587\u6848\u90FD\u6CA1\u6709\u7ED9\u51FA\u7684\u7C7B\u522B\uFF1B5xx \u4E00\u5F8B\u6309\u670D\u52A1\u7AEF\u5904\u7406\u3002 */\nfunction classifyStatus(status: number | undefined): string | undefined {\n if (status === undefined) return undefined;\n if (status === 401) return 'AUTH';\n if (status === 403) return 'PERMISSION';\n if (status === 402) return QUOTA_EXCEEDED_CODE;\n if (status === 429) return 'RATE_LIMIT';\n if (status === 408 || status === 504) return 'TIMEOUT';\n if (status >= 500) return 'SERVER';\n return undefined;\n}\n\ninterface Fields {\n /** `code` \u4E0E `type` \u5206\u5F00\u4FDD\u5B58\uFF0C\u907F\u514D\u8DE8\u5B57\u6BB5\u62FC\u51FA\u5E76\u4E0D\u5B58\u5728\u7684\u77ED\u8BED\u3002 */\n readonly structured: readonly string[];\n readonly prose: string;\n}\n\nfunction fieldsOf(error: Record<string, unknown>): Fields {\n const structured: string[] = [];\n for (const value of [error.code, error.type]) {\n if (typeof value !== 'string') continue;\n const normalized = value.trim().toLowerCase();\n if (normalized !== '') structured.push(normalized);\n }\n return { structured, prose: typeof error.message === 'string' ? error.message.toLowerCase() : '' };\n}\n\n/** \u4F9D\u636E\u7ED3\u6784\u5316\u5B57\u6BB5\u3001\u6587\u6848\u4E0E HTTP \u72B6\u6001\u7ED9\u51FA\u7A33\u5B9A\u7684 LlmError\uFF1B`fallback` \u51B3\u5B9A\u65E0\u6CD5\u5F52\u7C7B\u65F6\u7684\u673A\u5668\u7801\u3002 */\nfunction classify(fields: Fields, status: number | undefined, fallback: string): LlmError {\n const structured = classifyStructured(fields.structured);\n // \u7ED3\u6784\u5316\u5206\u7C7B\u4F18\u5148\uFF1A\u660E\u786E\u7684\u989D\u5EA6/\u4E0A\u4E0B\u6587/\u9650\u6D41/\u8D85\u65F6/\u670D\u52A1\u7AEF\u7ED3\u8BBA\u4E0D\u4F1A\u88AB HTTP \u72B6\u6001\u6539\u5199\u3002\n if (structured !== undefined && structured !== 'AUTH' && structured !== 'PERMISSION') return fail(structured, status);\n // 5xx \u662F\u660E\u786E\u7684\u670D\u52A1\u7AEF\u4E8B\u5B9E\uFF08504 \u5355\u72EC\u6309\u8D85\u65F6\u5904\u7406\uFF09\uFF1A\u6CA1\u6709\u7ED3\u6784\u5316\u4EE3\u7801\u65F6\u4E0D\u91C7\u4FE1\u6B63\u6587\u91CC\u7684\u8BA4\u8BC1\u6216\u989D\u5EA6\u63AA\u8F9E\u3002\n if (structured === undefined && status !== undefined && status >= 500 && status !== 504) return fail('SERVER', status);\n // \u4E0A\u6E38\u53EA\u7ED9\u51FA\u8BA4\u8BC1/\u6743\u9650\u8BED\u4E49\u65F6\uFF0C\u660E\u786E\u70B9\u540D Key/\u51ED\u636E\u65E0\u6548\u6216\u7F3A\u5931\u7684\u6587\u6848\u53EF\u4EE5\u5347\u7EA7\u4E3A\u51ED\u636E\u9519\u8BEF\u3002\n if (PROSE_CREDENTIAL.test(fields.prose)) return fail(INVALID_CREDENTIAL_CODE, status);\n if (structured !== undefined) return fail(structured, status);\n const prose = classifyProse(fields.prose);\n if (prose !== undefined) return fail(prose, status);\n // \u72B6\u6001\u53EA\u515C\u5E95\uFF1A\u5178\u578B\u989D\u5EA6/\u8BA4\u8BC1\u7C7B 401 \u5DF2\u7531\u4E0A\u9762\u7684\u4E13\u7528\u5206\u7C7B\u5904\u7406\uFF0C\u4E0D\u4F1A\u9000\u56DE\u6210\u8BA4\u8BC1\u6216\u9650\u6D41\u3002\n const byStatus = classifyStatus(status);\n return fail(byStatus ?? fallback, status);\n}\n\n/**\n * OpenAI \u98CE\u683C\u4FE1\u5C01\uFF1A`{ error: { code, type, message } }`\uFF08Chat Completions \u4E0E Responses \u5B9E\u6D4B\u4E00\u81F4\uFF09\u3002\n *\n * @param status \u4E0A\u6E38 HTTP \u72B6\u6001\uFF1B\u6D41\u5185\u9519\u8BEF\u4E8B\u4EF6\u6CA1\u6709\u72B6\u6001\u65F6\u7701\u7565\u3002\n * @param body \u5DF2\u89E3\u6790\u7684\u54CD\u5E94\u4F53\u6216\u6D41\u4E8B\u4EF6\u3002\n */\nexport function gatewayError(status: number | undefined, body: unknown): LlmError {\n const error = record(body) && record(body.error) ? body.error : record(body) ? body : {};\n return classify(fieldsOf(error), status, 'INVALID_REQUEST');\n}\n\n/**\n * Anthropic \u98CE\u683C\u4FE1\u5C01\uFF1A`{ type: \"error\", error: { type, message } }`\uFF08Messages \u7AEF\u70B9\u5B9E\u6D4B\uFF09\u3002\n *\n * @param status \u4E0A\u6E38 HTTP \u72B6\u6001\uFF1B\u6D41\u5185\u9519\u8BEF\u4E8B\u4EF6\u6CA1\u6709\u72B6\u6001\u65F6\u7701\u7565\u3002\n * @param body \u5DF2\u89E3\u6790\u7684\u54CD\u5E94\u4F53\u6216\u6D41\u4E8B\u4EF6\u3002\n */\nexport function anthropicError(status: number | undefined, body: unknown): LlmError {\n const error = record(body) && record(body.error) ? body.error : {};\n return classify(fieldsOf(error), status, 'INVALID_REQUEST');\n}\n\n/**\n * \u6D41\u5185\u9519\u8BEF\u4E8B\u4EF6\uFF08HTTP \u5DF2\u662F 200\uFF0C\u9519\u8BEF\u53EA\u80FD\u4F5C\u4E3A\u4E8B\u4EF6\u5230\u8FBE\uFF09\u3002\n *\n * @param error \u4E8B\u4EF6\u91CC\u7684\u9519\u8BEF\u5BF9\u8C61\uFF08\u4E24\u79CD\u4FE1\u5C01\u90FD\u53EF\uFF09\u3002\n * @param fallback \u65E0\u6CD5\u5F52\u7C7B\u65F6\u4F7F\u7528\u7684\u673A\u5668\u7801\uFF0C\u9ED8\u8BA4\u6309\u683C\u5F0F\u9519\u8BEF\u5904\u7406\u3002\n */\nexport function inBandError(error: unknown, fallback = 'INVALID_RESPONSE'): LlmError {\n return classify(fieldsOf(record(error) ? error : {}), undefined, fallback);\n}\n", "/**\n * \u534F\u8BAE\u65E0\u5173\u7684 SSE \u5206\u5E27\u3002\n *\n * \u53EA\u8D1F\u8D23\u4F20\u8F93\u5C42\uFF1A\u628A\u5B57\u8282\u6D41\u6309 SSE \u884C\u534F\u8BAE\u5207\u6210 `event:` + \u591A\u884C `data:` \u5E27\uFF0C\u5E76\u7EDF\u4E00\u5F3A\u5236\n * \u53D6\u6D88\u3001\u7A7A\u95F2\u8D85\u65F6\u4E0E\u5927\u5C0F\u4E0A\u9650\u3002\u4E8B\u4EF6\u8BED\u4E49\uFF08JSON \u7ED3\u6784\u3001\u7EC8\u6B62\u3001usage\uFF09\u7531\u5404\u534F\u8BAE\u6A21\u5757\u89E3\u91CA\u3002\n *\n * \u8FB9\u754C\u4E0E\u65E2\u6709 Chat Completions \u5B9E\u73B0\u4E00\u81F4\uFF0C\u4FBF\u4E8E\u56DE\u5F52\uFF1A\n * - CRLF \u53EF\u80FD\u88AB\u62C6\u5230\u4E24\u4E2A\u4F20\u8F93\u5757\u4E4B\u95F4\uFF0C\u4FDD\u7559\u5C3E\u90E8 CR\u3002\n * - \u5355\u4E8B\u4EF6\u7D2F\u8BA1 `data` \u4E0E\u5355\u884C\u7F13\u51B2\u90FD\u4E0D\u5F97\u8D85\u8FC7 4 MiB\uFF1B\u8D85\u9650\u6309\u683C\u5F0F\u9519\u8BEF\u62D2\u7EDD\uFF0C\u4E0D\u622A\u65AD\u89E3\u6790\u3002\n * - \u7A7A\u95F2\u8D85\u8FC7 `idleMs` \u629B TIMEOUT\uFF1B`signal` \u4E2D\u6B62\u65F6\u629B\u51FA signal \u7684\u539F\u56E0\u3002\n * - \u65E0\u8BBA\u6210\u529F\u3001\u5F02\u5E38\u8FD8\u662F\u6D88\u8D39\u65B9\u63D0\u524D `break`\uFF0C\u90FD\u4F1A cancel \u5E76\u91CA\u653E\u4E0A\u6E38 reader\u3002\n */\n\nimport { LlmError } from '@deepseek-ai/dsh-llm';\n\n/** \u4E00\u5E27 SSE \u4E8B\u4EF6\uFF1A`event:` \u540D\uFF08\u53EF\u9009\uFF09+ \u5408\u5E76\u540E\u7684 `data` \u8F7D\u8377\u3002 */\nexport interface SseFrame {\n readonly event?: string;\n readonly data: string;\n}\n\n/** \u5355\u884C / \u5355\u4E8B\u4EF6\u7684\u5B57\u7B26\u4E0A\u9650\uFF08\u4EE5 UTF-16 \u7801\u5143\u8BA1\uFF0C\u4E0E\u65E2\u6709\u5B9E\u73B0\u4FDD\u6301\u4E00\u81F4\uFF09\u3002 */\nconst MAX_FRAME_CHARS = 4 * 1024 * 1024;\n\n/**\n * \u9010\u5E27\u4EA7\u51FA SSE \u4E8B\u4EF6\u3002\n *\n * @param body \u4E0A\u6E38\u54CD\u5E94\u4F53\uFF1B\u7ED3\u675F\u65F6\u7531\u672C\u751F\u6210\u5668\u8D1F\u8D23 cancel\u3002\n * @param signal \u8C03\u7528\u65B9\u53D6\u6D88\u4FE1\u53F7\uFF08\u5DF2\u4E0E\u8D85\u65F6\u5408\u5E76\uFF09\u3002\n * @param idleMs \u4E24\u6B21\u8BFB\u5230\u6570\u636E\u4E4B\u95F4\u7684\u6700\u957F\u7B49\u5F85\u6BEB\u79D2\u6570\u3002\n */\nexport async function* sseFrames(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n idleMs: number,\n): AsyncGenerator<SseFrame> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let data: string[] = [];\n let dataSize = 0;\n let name: string | undefined;\n\n /** \u6D3E\u53D1\u5F53\u524D\u7D2F\u79EF\u7684\u4E8B\u4EF6\uFF1B\u6CA1\u6709 data \u884C\u65F6\u4E0D\u4EA7\u51FA\uFF08\u6CE8\u91CA\u3001\u7A7A\u884C\uFF09\u3002 */\n function dispatch(): SseFrame[] {\n const payload = data.join('\\n');\n const event = name;\n data = [];\n dataSize = 0;\n name = undefined;\n return payload ? [{ ...(event === undefined ? {} : { event }), data: payload }] : [];\n }\n\n function line(value: string): SseFrame[] {\n if (!value) return dispatch();\n if (value.startsWith(':')) return [];\n if (value.startsWith('data:')) {\n const part = value.slice(5).replace(/^ /u, '');\n dataSize += part.length;\n if (dataSize > MAX_FRAME_CHARS) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u4E8B\u4EF6\u8D85\u8FC7\u5927\u5C0F\u9650\u5236', 'INVALID_RESPONSE');\n data.push(part);\n return [];\n }\n if (value.startsWith('event:')) {\n const event = value.slice(6).trim();\n name = event === '' ? undefined : event;\n }\n return [];\n }\n\n async function read(): Promise<ReadableStreamReadResult<Uint8Array>> {\n signal.throwIfAborted();\n let timer: ReturnType<typeof setTimeout> | undefined;\n let abort: () => void = () => {};\n try {\n return await Promise.race([\n reader.read(),\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u54CD\u5E94\u957F\u65F6\u95F4\u6CA1\u6709\u6570\u636E', 'TIMEOUT')), idleMs);\n abort = () => reject(signal.reason);\n signal.addEventListener('abort', abort, { once: true });\n if (signal.aborted) abort();\n }),\n ]);\n } finally {\n clearTimeout(timer);\n signal.removeEventListener('abort', abort);\n }\n }\n\n try {\n while (true) {\n const result = await read();\n buffer += result.done ? decoder.decode() : decoder.decode(result.value, { stream: true });\n // CRLF \u53EF\u80FD\u88AB\u62C6\u5230\u4E24\u4E2A\u4F20\u8F93\u5757\u4E4B\u95F4\uFF1B\u4FDD\u7559\u5C3E\u90E8\u5355\u4E2A CR \u7B49\u5F85\u4E0B\u4E00\u5757\u3002\n let match: RegExpExecArray | null;\n while ((match = /\\r\\n|\\n|\\r(?!$)/u.exec(buffer))) {\n const at = match.index;\n const value = buffer.slice(0, at);\n buffer = buffer.slice(at + match[0].length);\n for (const frame of line(value)) yield frame;\n }\n if (buffer.length > MAX_FRAME_CHARS) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u884C\u8D85\u8FC7\u5927\u5C0F\u9650\u5236', 'INVALID_RESPONSE');\n if (result.done) {\n if (buffer) for (const frame of line(buffer.replace(/\\r$/u, ''))) yield frame;\n for (const frame of dispatch()) yield frame;\n break;\n }\n }\n } finally {\n await reader.cancel().catch(() => undefined); // \u6E05\u7406\u5931\u8D25\u4E0D\u5F97\u8986\u76D6\u539F\u59CB\u9519\u8BEF\n reader.releaseLock();\n }\n}\n", "// Gift-pool empty-turn guard: turn a \"markup-only stop\" into a retryable EMPTY_RESPONSE.\n//\n// A translating relay in front of the gift model can hand the model's native tool/thinking\n// markup back as plain text and still finish with `stop`. The step then carries no tool call\n// and no prose the user can use, yet `dsh-agent-loop` reads \"no tool call\" as \"the turn is\n// over\". `consumeSse` has the sibling hole: its `!count` check (src/stream.ts:160) only covers\n// streams that opened zero blocks, and one residue block already makes `count === 1`.\n//\n// This module is the adapter-callable half of that guard, modelled on FYTXY/dsh-empty-turn-guard\n// 0.4.0 (MIT) \u2014 see docs/empty-turn-evidence.md. It never edits model text, never injects a\n// message and never replays work: the only action is rewriting an eligible `finish` reason into\n// `{ kind: 'error', failure: { code: 'EMPTY_RESPONSE' } }`, which the provider's existing retry\n// policy already treats as safe to repeat.\n//\n// The decision is the reference plugin's original semantics: visible text only.\n// Three conditions must hold together \u2014 the finish is `stop`, no tool call was observed, and the\n// visible text channel is empty once protocol residue is removed. Whether the reasoning channel\n// carried a real train of thought does not rescue the turn: a model that thinks and then answers\n// with nothing is exactly the empty turn this guard exists for, so it is retried too. A real\n// answer, a partial answer, a tool step, or a truncated (`max-tokens`) reply still passes through\n// untouched, because the first two either leave visible content or open a tool call.\n//\n// The switch is a *monitor* switch: `enabled: false` only turns this rewrite off. The adapter's\n// own `count === 0` \u2192 `EMPTY_RESPONSE` path is Core behaviour and must stay outside it, so a truly\n// content-free stream is rejected whether or not the monitor is on.\n//\n// Callers decide *where* it applies: pass `enabled: false` for paid routes so their failures keep\n// their existing behaviour. Nothing here restarts, reconnects, or reroutes a provider.\nimport { EMPTY_RESPONSE_CODE, type FinishReason, type StreamChunk } from '@deepseek-ai/dsh-llm';\n\n/** Failure message a rewritten empty turn carries. */\nexport const EMPTY_TURN_MESSAGE = 'OpenDesign\uFF1A\u6A21\u578B\u56DE\u590D\u53EA\u5269\u534F\u8BAE\u6807\u8BB0\uFF0C\u672A\u4EA7\u751F\u53EF\u7528\u5185\u5BB9';\n\n/**\n * Protocol residue a relay can leak into a text or reasoning channel: DeepSeek's private\n * `\uFF5C\uFF5CDSML\uFF5C\uFF5C` tool markers (U+FF5C fullwidth bars), reasoning tags, and the model-invented\n * `\u8FD4\u749E\u5F52\u771F` tag seen in the reference measurements.\n *\n * The second pattern covers the orphan form a streamed delta leaves behind when its leading `<`\n * never arrives (`\uFF5C\uFF5CDSML\uFF5C\uFF5C calls>`). Only known protocol tokens are stripped: unknown markup is\n * content, so a reply that merely discusses a tag is never misread as empty.\n */\nconst RESIDUE_PATTERNS: readonly RegExp[] = [\n /<\\s*\\/?\\s*\uFF5C\uFF5CDSML\uFF5C\uFF5C[^>]*>/gu,\n /\uFF5C\uFF5CDSML\uFF5C\uFF5C[^\\n<>]*>?/gu,\n /<\\s*\\/?\\s*thinking\\s*>/giu,\n /<\\s*\\/?\\s*\u8FD4\u749E\u5F52\u771F\\s*>/gu,\n];\n\n/** Punctuation a truncated tag decomposes into; on its own it still counts as nothing. */\nconst ONLY_MARKUP_PUNCTUATION = /^[\\s<>/\\\\|\uFF5C=_-]*$/u;\n\n/**\n * Remove protocol residue from one assembled channel.\n * @param text - concatenated text or reasoning content.\n * @returns the remainder, trimmed; empty when nothing survives but residue punctuation.\n */\nexport function stripProtocolResidue(text: string): string {\n let rest = text;\n for (const pattern of RESIDUE_PATTERNS) rest = rest.replace(pattern, '');\n rest = rest.trim();\n return ONLY_MARKUP_PUNCTUATION.test(rest) ? '' : rest;\n}\n\n/**\n * Decide whether one channel carries nothing a user could use.\n * @param text - channel content, `undefined` when the channel never opened.\n * @returns true for absent, blank, or residue-only content.\n */\nexport function isResidueOnly(text: string | undefined): boolean {\n return text === undefined || stripProtocolResidue(text) === '';\n}\n\n/** Stream facts one attempt produced, as the adapter accumulated them. */\nexport interface EmptyTurnInput {\n /** Whether any tool-call block was opened or streamed during this attempt. */\n readonly sawToolCall: boolean;\n /** Visible text content, `undefined` when the channel never opened. */\n readonly text?: string | undefined;\n}\n\n/** Evidence that is safe to log or count: flags and lengths, never model output. */\nexport interface EmptyTurnEvidence {\n readonly sawToolCall: boolean;\n /** Visible text length after nothing is stripped \u2014 the raw channel length. */\n readonly textLength: number;\n /** Reasoning length, for cost analysis only; it never rescues an empty visible answer. */\n readonly reasoningLength: number;\n /** True when the visible text channel is empty once protocol residue is removed. */\n readonly markupOnly: boolean;\n}\n\n/**\n * Whether this finish is the empty turn the guard exists for.\n *\n * Deliberately reads the visible text channel only, matching the reference plugin: a reply whose\n * reasoning carried real thought but whose answer is empty still leaves the user with nothing, so\n * it is retried. `max-tokens` is excluded because a truncated answer is a real answer and already\n * surfaces as its own outcome.\n * @param reason - the finish reason reported by the adapter.\n * @param input - the attempt's accumulated stream facts.\n * @returns true only when the finish is `stop`, no tool call happened, and visible text is residue.\n */\nexport function isMarkupOnlyStop(reason: FinishReason, input: EmptyTurnInput): boolean {\n return reason.kind === 'stop'\n && !input.sawToolCall\n && isResidueOnly(input.text);\n}\n\n/** Options shared by {@link EmptyTurnTracker}. */\nexport interface EmptyTurnOptions {\n /**\n * Monitor switch, read per request by the caller. `false` makes every\n * {@link EmptyTurnTracker.resolve} a no-op, which is how a paid route keeps its untouched\n * behaviour. It never suppresses the adapter's own `count === 0` \u2192 `EMPTY_RESPONSE` path:\n * that is Core behaviour and stays in force either way.\n */\n readonly enabled?: boolean;\n /**\n * Optional telemetry hook, invoked once per rewrite with log-safe evidence.\n *\n * The callback receives counts only, so a counter can be incremented without model output\n * reaching a log file. Callers own the metric; nothing is retried or recorded here, and an\n * exception from the callback is swallowed so monitoring can never break a stream.\n */\n readonly onEmptyTurn?: ((evidence: EmptyTurnEvidence) => void) | undefined;\n}\n\n/**\n * Per-attempt accumulator for the empty-turn decision.\n *\n * One instance belongs to one stream: creating it per request keeps concurrent attempts from\n * sharing state, and it holds no timers, subscriptions, or references to hosts.\n */\nexport class EmptyTurnTracker {\n readonly #enabled: boolean;\n readonly #onEmptyTurn: ((evidence: EmptyTurnEvidence) => void) | undefined;\n #sawToolCall = false;\n /** Text seen as raw deltas (delta-only protocols). */\n #deltaText = '';\n /** Text seen in closed blocks (authoritative when present). */\n #blockText = '';\n /** Reasoning seen as raw deltas. */\n #deltaReasoning = '';\n /** Reasoning seen in closed blocks. */\n #blockReasoning = '';\n\n /** @param options - the monitor switch and optional telemetry hook; omitted switch means on. */\n constructor(options: EmptyTurnOptions = {}) {\n this.#enabled = options.enabled !== false;\n this.#onEmptyTurn = options.onEmptyTurn;\n }\n\n /** Whether this tracker may rewrite a finish at all. */\n get enabled(): boolean {\n return this.#enabled;\n }\n\n /** Whether any tool call reached the stream, which always protects the attempt. */\n get sawToolCall(): boolean {\n return this.#sawToolCall;\n }\n\n /**\n * Fold one stream chunk into the attempt.\n * @param chunk - any chunk the adapter yields; unknown kinds are ignored.\n */\n observe(chunk: StreamChunk): void {\n switch (chunk.type) {\n case 'tool-call-delta':\n this.#sawToolCall = true;\n return;\n case 'block-start':\n if (chunk.blockType === 'tool-call') this.#sawToolCall = true;\n return;\n case 'text-delta':\n if (typeof chunk.text === 'string') this.#deltaText += chunk.text;\n return;\n case 'reasoning-delta':\n if (typeof chunk.text === 'string') this.#deltaReasoning += chunk.text;\n return;\n case 'block-end': {\n const block = chunk.block;\n if (block.type === 'tool-call') this.#sawToolCall = true;\n else if (block.type === 'text' && typeof block.text === 'string') this.#blockText += block.text;\n else if (block.type === 'reasoning' && typeof block.text === 'string') this.#blockReasoning += block.text;\n return;\n }\n default:\n return;\n }\n }\n\n /**\n * What the attempt has produced so far, as log-safe counts.\n * @returns flags and channel lengths, never the text itself.\n */\n inspect(): EmptyTurnEvidence {\n const text = this.#text();\n const reasoning = this.#reasoning();\n return {\n sawToolCall: this.#sawToolCall,\n textLength: text.length,\n reasoningLength: reasoning.length,\n markupOnly: isResidueOnly(text),\n };\n }\n\n /**\n * Rewrite an eligible finish into the provider-neutral empty-response failure.\n *\n * The reason object is returned unchanged (same reference) whenever the monitor is off, the\n * finish is not `stop`, a tool call was observed, or the visible text carries usable content.\n * This method only decides and rewrites: the retry itself belongs to the host's provider policy.\n * @param reason - the finish reason the adapter is about to yield.\n * @returns a retryable `error` reason, or the given reason untouched.\n */\n resolve(reason: FinishReason): FinishReason {\n if (!this.#enabled || !isMarkupOnlyStop(reason, { sawToolCall: this.#sawToolCall, text: this.#text() })) {\n return reason;\n }\n this.#notify();\n return { kind: 'error', failure: { code: EMPTY_RESPONSE_CODE, message: EMPTY_TURN_MESSAGE } };\n }\n\n /** Report one rewrite to the telemetry hook; monitoring must never break the stream. */\n #notify(): void {\n try {\n this.#onEmptyTurn?.(this.inspect());\n } catch {\n // A counter or logger failure is not a model failure.\n }\n }\n\n /** Closed-block text wins over deltas, so a protocol that sends both is not double-counted. */\n #text(): string {\n return this.#blockText.length > 0 ? this.#blockText : this.#deltaText;\n }\n\n /** Same precedence rule for the reasoning channel. */\n #reasoning(): string {\n return this.#blockReasoning.length > 0 ? this.#blockReasoning : this.#deltaReasoning;\n }\n}\n", "/**\n * \u4E09\u79CD\u7EBF\u534F\u8BAE\u7684\u516C\u5F00\u5165\u53E3\u3002\n *\n * \u6A21\u578B\u53D1\u73B0\uFF08OpenAI `GET /models`\uFF09\u4E0E\u63A8\u7406\u534F\u8BAE\u89E3\u8026\uFF1A\u65E0\u8BBA\u8FD9\u91CC\u9009\u4E2D\u54EA\u79CD\u534F\u8BAE\uFF0C\n * \u76EE\u5F55\u62C9\u53D6\u59CB\u7EC8\u8D70 OpenAI \u517C\u5BB9\u7AEF\u53E3\uFF0C\u89C1 `model-discovery.ts`\u3002\n */\n\nimport { LlmError } from '@deepseek-ai/dsh-llm';\nimport type { ApiProtocol } from '../protocol-options.js';\nimport { chatCompletions } from './chat-completions.js';\nimport { messages } from './messages.js';\nimport { responses } from './responses.js';\nimport type { Protocol } from './types.js';\n\nconst PROTOCOLS: Readonly<Record<ApiProtocol, Protocol>> = {\n 'chat-completions': chatCompletions,\n responses,\n messages,\n};\n\n/**\n * \u6309\u914D\u7F6E id \u53D6\u534F\u8BAE\u5B9E\u73B0\u3002\n *\n * @param id \u8BBE\u7F6E\u91CC\u4FDD\u5B58\u7684\u534F\u8BAE id\uFF08\u6765\u81EA\u56FA\u5B9A\u4E09\u79CD\uFF09\u3002\n * @throws {LlmError} \u914D\u7F6E\u91CC\u51FA\u73B0\u672A\u77E5 id\uFF08\u4F8B\u5982\u964D\u7EA7\u5B89\u88C5\u4FDD\u7559\u4E86\u66F4\u65B0\u7248\u672C\u7684\u8BBE\u7F6E\uFF09\u3002\n */\nexport function protocolFor(id: ApiProtocol): Protocol {\n const protocol = PROTOCOLS[id];\n if (!protocol) throw new LlmError(`\u672A\u77E5\u7684\u63A8\u7406\u534F\u8BAE\uFF1A${String(id)}`, 'INVALID_REQUEST');\n return protocol;\n}\n\nexport type { Protocol, ProtocolContext, WireRequest } from './types.js';\nexport { MESSAGES_DEFAULT_MAX_TOKENS, messagesURL } from './messages.js';\n", "/**\n * OpenAI Chat Completions \u534F\u8BAE\uFF08\u65E2\u6709\u5B9E\u73B0\u7684\u552F\u4E00\u5305\u88C5\u70B9\uFF09\u3002\n *\n * \u8BF7\u6C42\u6295\u5F71\u7EE7\u7EED\u590D\u7528 `conversion.ts` \u7684 chat \u6D88\u606F/\u5DE5\u5177\u6295\u5F71\u4E0E\u601D\u8003\u56DE\u653E\u89C4\u5219\uFF1B\n * \u6D41\u5F0F\u89E3\u6790\u7EE7\u7EED\u590D\u7528 `stream.ts#consumeSse`\uFF0C\u56E0\u6B64\u8BE5\u534F\u8BAE\u7684\u884C\u4E3A\u4E0E\u62C6\u5206\u524D\u5B8C\u5168\u4E00\u81F4\u3002\n */\n\nimport { LlmError, type StreamChunk } from '@deepseek-ai/dsh-llm';\nimport { chatMessages, chatTools } from '../conversion.js';\nimport { consumeSse } from '../stream.js';\nimport { streamHeaders } from './headers.js';\nimport { inferenceEndpoint } from '../protocol-options.js';\nimport type { Protocol, ProtocolContext, WireRequest } from './types.js';\n\n/** \u6784\u9020 Chat Completions \u8BF7\u6C42\u3002 */\nexport function buildChatCompletionsRequest(ctx: ProtocolContext): WireRequest {\n const { options, model } = ctx;\n const replayReasoning = model.id.startsWith('deepseek-') || model.id.startsWith('kimi-');\n const messages = chatMessages(options, ref => ctx.images.get(ref.attachmentId), replayReasoning);\n const tools = chatTools(options);\n const body: Record<string, unknown> = { model: model.id, messages, stream: true, stream_options: { include_usage: true } };\n if (tools) body.tools = tools;\n if (options.temperature !== undefined) body.temperature = options.temperature;\n if (ctx.topP !== undefined) body.top_p = ctx.topP;\n if (options.maxTokens !== undefined) {\n if (!Number.isSafeInteger(options.maxTokens) || options.maxTokens <= 0) throw new LlmError('maxTokens \u5FC5\u987B\u662F\u6B63\u6574\u6570', 'INVALID_REQUEST');\n body.max_tokens = options.maxTokens;\n }\n if (options.reasoningEffort !== undefined) body.reasoning_effort = options.reasoningEffort;\n if (options.stop?.length) body.stop = options.stop;\n return { url: inferenceEndpoint(ctx.baseURL, 'chat-completions'), headers: streamHeaders(ctx.apiKey), body };\n}\n\nexport const chatCompletions: Protocol = {\n id: 'chat-completions',\n build: buildChatCompletionsRequest,\n stream(body: ReadableStream<Uint8Array>, signal: AbortSignal, idleMs: number): AsyncIterable<StreamChunk> {\n return consumeSse(body, signal, idleMs);\n },\n};\n", "/**\n * \u4E09\u79CD\u63A8\u7406\u534F\u8BAE\u5171\u7528\u7684\u8BF7\u6C42\u5934\u3002\n *\n * \u6BCF\u4E2A\u4E0A\u6E38\u8BF7\u6C42\u90FD\u5FC5\u987B\u643A\u5E26\u5E94\u7528\u5F52\u56E0\u5934\uFF08`attributionHeaders()`\uFF09\uFF1B\u9274\u6743\u4E00\u5F8B\u8D70\n * `Authorization: Bearer`\u2014\u2014CoRouter \u5B98\u65B9\u7AD9\u70B9\u5BF9 OpenAI \u517C\u5BB9\u8C03\u7528\u4E0E Claude Code\n * \uFF08`ANTHROPIC_AUTH_TOKEN`\uFF09\u90FD\u4F7F\u7528\u8BE5\u5934\uFF0C\u56E0\u6B64 Messages \u534F\u8BAE\u4E0D\u989D\u5916\u53D1\u9001\u7B2C\u4E8C\u4E2A\u5BC6\u94A5\u5934\u3002\n */\n\nimport { attributionHeaders } from '@deepseek-ai/dsh-llm';\n\n/**\n * \u6784\u9020\u6D41\u5F0F\u63A8\u7406\u8BF7\u6C42\u5934\u3002\n *\n * @param apiKey \u5DF2\u7531\u9002\u914D\u5668\u6821\u9A8C\u53EF\u7528\u7684\u51ED\u636E\uFF1B\u6B64\u5904\u53EA\u505A\u62FC\u63A5\uFF0C\u4E0D\u56DE\u663E\u3001\u4E0D\u8BB0\u5F55\u3002\n * @param extra \u534F\u8BAE\u4E13\u5C5E\u5934\uFF08\u5982 `anthropic-version`\uFF09\u3002\n */\nexport function streamHeaders(apiKey: string, extra: Readonly<Record<string, string>> = {}): Record<string, string> {\n return {\n ...attributionHeaders(),\n authorization: `Bearer ${apiKey}`,\n 'content-type': 'application/json',\n accept: 'text/event-stream',\n ...extra,\n };\n}\n", "/**\n * Anthropic Messages \u534F\u8BAE\u3002\n *\n * \u7AEF\u70B9\uFF1ABase URL \u53EF\u4EE5\u662F\u7F51\u5173\u6839\uFF08\u5B98\u65B9 `ANTHROPIC_BASE_URL` \u5F62\u5F0F\uFF09\u6216\u5DF2\u5E26 `/v1` \u7684\u63A8\u7406 Base\uFF0C\n * \u4E24\u79CD\u90FD\u4F1A\u8865\u6210 `<base>/v1/messages`\u3002\u9274\u6743\u6CBF\u7528 CoRouter \u5B98\u65B9 Claude Code \u914D\u7F6E\u91CC\u7684\n * `Authorization: Bearer`\uFF0C\u5916\u52A0\u6807\u51C6 `anthropic-version`\uFF1B\u4E0D\u989D\u5916\u53D1\u9001\u7B2C\u4E8C\u4E2A\u5BC6\u94A5\u5934\u3002\n *\n * \u4E0D\u652F\u6301\u9879\u6309\u663E\u5F0F\u5931\u8D25\u5904\u7406\uFF0C\u4E0D\u9759\u9ED8\u4E22\u5F03\uFF1A\n * - \u8BF7\u6C42\u65E0 `max_tokens` \u65F6\u7528\u4FDD\u5B88\u9ED8\u8BA4 4096\uFF08\u9002\u914D\u5668\u5143\u6570\u636E\u540C\u6B65\u8BE5\u9ED8\u8BA4\u503C\uFF0C\u7528\u6237\u53EF\u6309\u6A21\u578B\u8986\u76D6\uFF09\uFF1B\n * - `reasoningEffort` \u6309\u73B0\u4EE3 Messages \u6807\u51C6\u6295\u5F71\u4E3A `thinking: {type:'adaptive'}` +\n * `output_config.effort`\uFF1B`none` \u6295\u5F71\u4E3A `thinking: {type:'disabled'}`\uFF1B`minimal`/`ultra`\n * \u7B49\u6CA1\u6709\u5BF9\u5E94 effort \u7684\u6863\u4F4D\u629B UNSUPPORTED_OPTION\uFF1B\n * - `temperature`/`top_p` \u7B49\u91C7\u6837\u53C2\u6570\u539F\u6837\u900F\u4F20\uFF0C\u5176\u53D6\u503C\u9650\u5236\uFF08\u53EA\u9488\u5BF9\u7279\u5B9A Claude \u4EE3\u9645\uFF09\u4E0E\n * \u300C\u4EC5\u63A5\u53D7 enabled + budget_tokens \u7684 legacy \u6A21\u578B\u300D\u80FD\u5426\u4F7F\u7528\uFF0C\u90FD\u7531\u4E0A\u6E38\u6309\u5B9E\u9645\u6A21\u578B\u5224\u5B9A\uFF0C\n * \u672C\u6A21\u5757\u4E0D\u505A\u672C\u5730\u63A8\u65AD\uFF0C\u800C\u662F\u628A\u4E0A\u6E38\u62D2\u7EDD\u5206\u7C7B\u4E0A\u62A5\uFF1B\n * - \u5386\u53F2 assistant \u7684 reasoning \u5757\u6CA1\u6709 Anthropic \u7B7E\u540D\uFF0C**\u4E0D\u56DE\u653E**\uFF08\u4F2A\u9020\u7B7E\u540D\u4F1A\u6C61\u67D3\u4E0A\u4E0B\u6587\uFF09\uFF0C\n * \u53EA\u628A\u672C\u8F6E `thinking_delta` \u6620\u5C04\u6210 reasoning \u8F93\u51FA\u5757\u3002\n */\n\nimport {\n LlmError, ToolCallId,\n type FinishReason, type StreamChunk, type TokenUsage,\n} from '@deepseek-ai/dsh-llm';\nimport { record } from '../util.js';\nimport { anthropicError } from './errors.js';\nimport { streamHeaders } from './headers.js';\nimport { inferenceEndpoint } from '../protocol-options.js';\nimport { projectContent } from './parts.js';\nimport { sseFrames } from './sse.js';\nimport { anthropicUsage } from './usage.js';\nimport type { Protocol, ProtocolContext, WireRequest } from './types.js';\n\n/** \u672A\u663E\u5F0F\u7ED9\u51FA `max_tokens` \u65F6\u7684\u4FDD\u5B88\u9ED8\u8BA4\u503C\uFF08\u4E0E\u9002\u914D\u5668\u5143\u6570\u636E\u4E00\u81F4\uFF09\u3002 */\nexport const MESSAGES_DEFAULT_MAX_TOKENS = 4096;\n/** Anthropic \u8981\u6C42\u7684\u7248\u672C\u5934\uFF1B\u7F3A\u7701\u4F1A 400\uFF0C\u5373\u4F7F\u672C\u7F51\u5173\u6CE8\u91CA\u91CC\u672A\u51FA\u73B0\u4E5F\u5FC5\u987B\u53D1\u9001\u3002 */\nconst ANTHROPIC_VERSION = '2023-06-01';\n/**\n * \u73B0\u4EE3 Messages \u6807\u51C6\u91CC `output_config.effort` \u7684\u5408\u6CD5\u6863\u4F4D\u3002\n *\n * \u73B0\u884C\u53C2\u6570\u9875\u628A `low | medium | high | xhigh | max` \u5217\u4E3A effort \u53D6\u503C\uFF1B`minimal` \u4E0E\u76EE\u5F55\u91CC\n * \u7684\u6269\u5C55\u6863\u4F4D\uFF08\u5982 `ultra`\uFF09\u6CA1\u6709\u5BF9\u5E94\u503C\uFF0C\u6309\u4E0D\u652F\u6301\u663E\u5F0F\u62D2\u7EDD\uFF0C\u800C\u4E0D\u662F\u6620\u5C04\u5230\u522B\u7684\u6863\u4F4D\u3002\n */\nconst THINKING_EFFORTS: readonly string[] = ['low', 'medium', 'high', 'xhigh', 'max'];\n\nconst DATA_URL = /^data:([^;,]+);base64,(.*)$/su;\n\ntype ContentPart = Record<string, unknown>;\n\n/** \u7F51\u5173\u6839\u6216 `/v1` Base \u90FD\u8865\u6210 `/v1/messages`\u3002 */\nexport function messagesURL(baseURL: string): string {\n return inferenceEndpoint(baseURL, 'messages');\n}\n\nfunction imagePart(url: string): ContentPart {\n const match = DATA_URL.exec(url);\n return match?.[1] && match[2]\n ? { type: 'image', source: { type: 'base64', media_type: match[1], data: match[2] } }\n : { type: 'image', source: { type: 'url', url } };\n}\n\n/**\n * \u5386\u53F2\u5DE5\u5177\u8C03\u7528\u53C2\u6570 \u2192 `tool_use.input`\u3002\n *\n * Anthropic \u8981\u6C42\u5BF9\u8C61\u3002\u7A7A\u53C2\u6570\u6309 `{}` \u5904\u7406\uFF08\u65E0\u53C2\u6570\u8C03\u7528\u7684\u6B63\u5E38\u5F62\u6001\uFF09\uFF1B\u5B57\u7B26\u4E32\u4E0D\u662F\u5408\u6CD5 JSON \u6216\n * \u89E3\u6790\u7ED3\u679C\u4E0D\u662F\u5BF9\u8C61\u65F6**\u663E\u5F0F\u5931\u8D25**\u2014\u2014\u4F2A\u9020\u7A7A\u53C2\u6570\u4F1A\u6539\u53D8\u5386\u53F2\u8C03\u7528\u7684\u542B\u4E49\uFF0C\u6BD4\u62D2\u7EDD\u8FD9\u4E00\u8F6E\u66F4\u7CDF\u3002\n */\nfunction toolInput(argumentsText: string): Record<string, unknown> {\n if (argumentsText.trim() === '') return {};\n let parsed: unknown;\n try {\n parsed = JSON.parse(argumentsText);\n } catch {\n throw new LlmError('\u5386\u53F2\u5DE5\u5177\u8C03\u7528\u53C2\u6570\u4E0D\u662F\u5408\u6CD5 JSON\uFF0C\u65E0\u6CD5\u6295\u5F71\u4E3A Anthropic tool_use.input', 'INVALID_REQUEST');\n }\n if (!record(parsed)) throw new LlmError('\u5386\u53F2\u5DE5\u5177\u8C03\u7528\u53C2\u6570\u4E0D\u662F JSON \u5BF9\u8C61\uFF0C\u65E0\u6CD5\u6295\u5F71\u4E3A Anthropic tool_use.input', 'INVALID_REQUEST');\n return parsed;\n}\n\n/** \u6784\u9020 Messages \u8BF7\u6C42\u3002 */\nexport function buildMessagesRequest(ctx: ProtocolContext): WireRequest {\n const { options, model } = ctx;\n const maxTokens = options.maxTokens ?? MESSAGES_DEFAULT_MAX_TOKENS;\n if (!Number.isSafeInteger(maxTokens) || maxTokens <= 0) throw new LlmError('maxTokens \u5FC5\u987B\u662F\u6B63\u6574\u6570', 'INVALID_REQUEST');\n\n const system: string[] = [];\n const messages: { role: 'user' | 'assistant'; content: ContentPart[] }[] = [];\n const lookup = ctx.images.size ? (ref: { attachmentId: string }) => ctx.images.get(ref.attachmentId) : undefined;\n let results: ContentPart[] = [];\n let lifted: string[] = [];\n const flushResults = (): void => {\n if (results.length) {\n messages.push({ role: 'user', content: results });\n results = [];\n }\n };\n const flushLifted = (): void => {\n flushResults();\n if (lifted.length) {\n messages.push({\n role: 'user',\n content: [{ type: 'text', text: '(Image content from the preceding tool result.)' }, ...lifted.map(imagePart)],\n });\n lifted = [];\n }\n };\n\n for (const message of options.messages) {\n // \u6574\u6BB5\u8FDE\u7EED tool \u7ED3\u679C\u5148\u6536\u96C6\uFF0C\u7B49\u89D2\u8272\u5207\u6362\u65F6\u518D\u4E00\u6B21\u6027\u843D\u76D8\uFF1A\u8FD9\u6837\u5E76\u884C\u5DE5\u5177\u7ED3\u679C\u540C\u5C5E\u4E00\u6761 user \u6D88\u606F\uFF0C\n // \u63D0\u5347\u7684\u56FE\u7247\u4E5F\u6392\u5728\u8FD9\u4E00\u7EC4\u4E4B\u540E\uFF0C\u4E0D\u4F1A\u63D2\u8FDB\u5E76\u884C\u7ED3\u679C\u4E2D\u95F4\u3002\n if (message.role !== 'tool') flushLifted();\n const projected = projectContent(message.content, message.role === 'user' || message.role === 'tool' ? lookup : undefined);\n switch (message.role) {\n case 'system':\n case 'developer':\n if (projected.text) system.push(projected.text);\n break;\n case 'user': {\n const content: ContentPart[] = [\n ...(projected.text ? [{ type: 'text', text: projected.text }] : []),\n ...projected.images.map(imagePart),\n ];\n if (content.length) messages.push({ role: 'user', content });\n break;\n }\n case 'assistant': {\n const content: ContentPart[] = [];\n if (projected.text) content.push({ type: 'text', text: projected.text });\n for (const block of message.content) {\n if (block.type === 'tool-call') content.push({ type: 'tool_use', id: block.id, name: block.name, input: toolInput(block.arguments) });\n }\n if (content.length) messages.push({ role: 'assistant', content });\n break;\n }\n case 'tool': {\n results.push({\n type: 'tool_result',\n tool_use_id: message.toolCallId,\n content: projected.text || (projected.images.length ? '(Image content follows in the next user message.)' : ''),\n });\n lifted.push(...projected.images);\n break;\n }\n }\n }\n flushLifted();\n if (options.system?.trim()) system.unshift(options.system);\n\n const body: Record<string, unknown> = { model: model.id, max_tokens: maxTokens, messages, stream: true };\n if (system.length) body.system = system.join('\\n\\n');\n if (options.tools?.length) body.tools = options.tools.map(tool => ({ name: tool.name, description: tool.description, input_schema: tool.parameters }));\n if (options.temperature !== undefined) body.temperature = options.temperature;\n if (ctx.topP !== undefined) body.top_p = ctx.topP;\n if (options.stop?.length) body.stop_sequences = options.stop;\n if (options.reasoningEffort !== undefined) {\n // \u601D\u8003\u63A7\u5236\u6309\u73B0\u4EE3 Messages \u6807\u51C6\u6295\u5F71\uFF1A`thinking.type.adaptive` + `output_config.effort`\u3002\n const effort = String(options.reasoningEffort);\n if (effort === 'none') body.thinking = { type: 'disabled' };\n else if (THINKING_EFFORTS.includes(effort)) {\n body.thinking = { type: 'adaptive' };\n body.output_config = { effort };\n } else throw new LlmError(`Anthropic Messages \u534F\u8BAE\u4E0D\u63A5\u53D7\u601D\u8003\u6DF1\u5EA6\u300C${effort}\u300D`, 'UNSUPPORTED_OPTION');\n }\n // \u91C7\u6837\u53C2\u6570\uFF08temperature / top_p / stop_sequences\uFF09\u4E00\u5F8B\u6309\u8C03\u7528\u65B9\u7ED9\u5B9A\u503C\u900F\u4F20\uFF1A\u5B98\u65B9\u53C2\u6570\u9875\u628A\u8FD9\u4E9B\n // \u53D6\u503C\u9650\u5236\u9650\u5B9A\u5728\u300CClaude Opus 4.6 \u4E4B\u540E\u300D\u7684\u5177\u4F53\u6A21\u578B\u4E0A\uFF0C\u800C CoRouter \u662F\u8DE8\u6A21\u578B\u7F51\u5173\uFF1B\n // \u91C7\u6837\u517C\u5BB9\u6027\u4E0E\u300C\u4EC5\u652F\u6301 enabled + budget_tokens \u7684 legacy \u6A21\u578B\u300D\u662F\u5426\u53EF\u7528\uFF0C\u4E00\u5E76\u7531\u4E0A\u6E38\u6309\u5B9E\u9645\n // \u6A21\u578B\u5224\u5B9A\u5E76\u8FD4\u56DE\uFF0C\u672C\u6A21\u5757\u4E0D\u5728\u672C\u5730\u63A8\u65AD\uFF0C\u4E5F\u4ECE\u4E0D\u53D1\u9001 top_k\u3002\n return { url: messagesURL(ctx.baseURL), headers: streamHeaders(ctx.apiKey, { 'anthropic-version': ANTHROPIC_VERSION }), body };\n}\n\ninterface BlockState {\n /** DSH \u5757\u7D22\u5F15\uFF1B\u9996\u6B21\u4EA7\u51FA\u65F6\u5206\u914D\uFF0C\u4FDD\u8BC1 block-start \u4E25\u683C\u6309\u7D22\u5F15\u9012\u589E\u3002 */\n index: number;\n kind: 'text' | 'reasoning' | 'tool' | 'skip';\n text: string;\n id: string;\n name: string;\n args: string;\n started: boolean;\n}\n\nfunction num(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : undefined;\n}\n\n/** \u628A Messages \u7684 SSE \u4E8B\u4EF6\u7FFB\u8BD1\u6210 DSH \u6D41\u5F0F\u5757\u3002 */\nexport async function* streamMessages(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n idleMs: number,\n): AsyncGenerator<StreamChunk> {\n let nextIndex = 0;\n let count = 0;\n let finish: FinishReason | undefined;\n let stopReason: string | undefined;\n let sawTool = false;\n const blocks = new Map<number, BlockState>();\n const raw = { input: undefined as number | undefined, output: undefined as number | undefined,\n cacheRead: undefined as number | undefined, cacheWrite: undefined as number | undefined };\n let usage: TokenUsage | undefined;\n\n function stateAt(index: unknown): BlockState {\n const state = typeof index === 'number' ? blocks.get(index) : undefined;\n if (!state) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u5185\u5BB9\u5757\u7D22\u5F15\u65E0\u6548', 'INVALID_RESPONSE');\n return state;\n }\n\n function assign(state: BlockState): void {\n if (state.index < 0) {\n state.index = nextIndex++;\n count++;\n }\n }\n\n function close(): StreamChunk[] {\n const out: StreamChunk[] = [];\n for (const state of blocks.values()) {\n if (!state.started) continue;\n if (state.kind === 'text') out.push({ type: 'block-end', index: state.index, block: { type: 'text', text: state.text } });\n else if (state.kind === 'reasoning') out.push({ type: 'block-end', index: state.index, block: { type: 'reasoning', text: state.text } });\n else if (state.kind === 'tool') {\n if (!state.id || !state.name) throw new LlmError('OpenDesign\uFF1A\u5DE5\u5177\u8C03\u7528\u7F3A\u5C11\u6807\u8BC6\u6216\u540D\u79F0', 'INVALID_RESPONSE');\n out.push({ type: 'block-end', index: state.index, block: { type: 'tool-call', id: ToolCallId(state.id), name: state.name, arguments: state.args } });\n }\n }\n return out.sort((a, b) => ('index' in a ? a.index : 0) - ('index' in b ? b.index : 0));\n }\n\n function reasonFromStop(stop: string | undefined): FinishReason {\n switch (stop) {\n case 'end_turn':\n case 'stop_sequence':\n return { kind: 'stop' };\n case 'max_tokens':\n case 'model_context_window_exceeded':\n // \u4E0A\u4E0B\u6587\u7A97\u53E3\u8017\u5C3D\u540C\u6837\u662F\u622A\u65AD\uFF1A\u4FDD\u7559\u5DF2\u4EA7\u51FA\u5185\u5BB9\uFF0C\u4F46\u7EDD\u4E0D\u5F53\u4F5C\u5B8C\u6574\u56DE\u7B54\u3002\n return { kind: 'max-tokens' };\n case 'tool_use':\n return { kind: 'tool-calls' };\n case 'refusal':\n throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u62D2\u7EDD\u56DE\u7B54\uFF08refusal\uFF09', 'INVALID_RESPONSE');\n case 'pause_turn':\n throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u6682\u505C\u8F6E\u6B21\uFF0C\u9700\u91CD\u65B0\u53D1\u8D77\u8BF7\u6C42', 'INVALID_RESPONSE');\n default:\n throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u54CD\u5E94\u88AB\u8FC7\u6EE4\u6216\u5F02\u5E38\u7EC8\u6B62', 'INVALID_RESPONSE');\n }\n }\n\n for await (const frame of sseFrames(body, signal, idleMs)) {\n let value: unknown;\n try {\n value = JSON.parse(frame.data);\n } catch {\n throw new LlmError('OpenDesign\uFF1A\u65E0\u6548\u7684\u6D41\u5F0F JSON', 'INVALID_RESPONSE');\n }\n if (!record(value)) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u4E8B\u4EF6\u4E0D\u662F\u5BF9\u8C61', 'INVALID_RESPONSE');\n const type = typeof value.type === 'string' && value.type !== '' ? value.type : frame.event;\n if (!type) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u4E8B\u4EF6\u7F3A\u5C11\u7C7B\u578B', 'INVALID_RESPONSE');\n const out: StreamChunk[] = [];\n\n switch (type) {\n case 'message_start': {\n const message = record(value.message) ? value.message : {};\n const counters = record(message.usage) ? message.usage : {};\n raw.input = num(counters.input_tokens) ?? raw.input;\n raw.output = num(counters.output_tokens) ?? raw.output;\n raw.cacheRead = num(counters.cache_read_input_tokens) ?? raw.cacheRead;\n raw.cacheWrite = num(counters.cache_creation_input_tokens) ?? raw.cacheWrite;\n break;\n }\n case 'content_block_start': {\n const index = value.index;\n if (typeof index !== 'number' || !Number.isSafeInteger(index) || index < 0) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u5185\u5BB9\u5757\u7D22\u5F15\u65E0\u6548', 'INVALID_RESPONSE');\n const block = record(value.content_block) ? value.content_block : {};\n const kind = typeof block.type === 'string' ? block.type : '';\n const state: BlockState = { index: -1, kind: 'skip', text: '', id: '', name: '', args: '', started: false };\n if (kind === 'text') state.kind = 'text';\n else if (kind === 'thinking') state.kind = 'reasoning';\n else if (kind === 'tool_use') state.kind = 'tool';\n if (state.kind === 'tool') {\n state.id = typeof block.id === 'string' ? block.id : '';\n state.name = typeof block.name === 'string' ? block.name : '';\n sawTool = true;\n }\n if (state.kind === 'text' && typeof block.text === 'string' && block.text !== '') state.text = block.text;\n if (state.kind === 'reasoning' && typeof block.thinking === 'string' && block.thinking !== '') state.text = block.thinking;\n blocks.set(index, state);\n // \u5DE5\u5177\u5757\u4E00\u5F00\u59CB\u5C31\u6709 id/name\uFF0C\u5148\u53D1 block-start \u4E0E\u7A7A\u589E\u91CF\uFF0C\u540E\u7EED\u53EA\u8FFD\u52A0\u53C2\u6570\u5206\u7247\u3002\n if (state.kind === 'tool') {\n assign(state);\n state.started = true;\n out.push({ type: 'block-start', index: state.index, blockType: 'tool-call' });\n if (state.id) out.push({ type: 'tool-call-delta', index: state.index, id: ToolCallId(state.id), ...(state.name ? { name: state.name } : {}), argumentsDelta: '' });\n } else if ((state.kind === 'text' || state.kind === 'reasoning') && state.text !== '') {\n // \u5C11\u6570\u7F51\u5173\u628A\u9996\u6BB5\u5185\u5BB9\u76F4\u63A5\u653E\u8FDB content_block_start\uFF0C\u540E\u7EED\u6CA1\u6709 delta\uFF1A\n // \u8FD9\u91CC\u7ACB\u5373\u5F00\u5757\u5E76\u53D1\u51FA\u9996\u6BB5\u589E\u91CF\uFF0C\u907F\u514D\u201C\u6709\u5185\u5BB9\u5374\u6309\u7A7A\u54CD\u5E94\u5904\u7406\u201D\u3002\n assign(state);\n state.started = true;\n out.push({ type: 'block-start', index: state.index, blockType: state.kind === 'text' ? 'text' : 'reasoning' });\n out.push(state.kind === 'text'\n ? { type: 'text-delta', index: state.index, text: state.text }\n : { type: 'reasoning-delta', index: state.index, text: state.text });\n }\n break;\n }\n case 'content_block_delta': {\n const state = stateAt(value.index);\n const delta = record(value.delta) ? value.delta : {};\n const deltaType = typeof delta.type === 'string' ? delta.type : '';\n if (deltaType === 'text_delta') {\n const text = typeof delta.text === 'string' ? delta.text : '';\n if (!text) break;\n assign(state);\n if (!state.started) {\n state.started = true;\n out.push({ type: 'block-start', index: state.index, blockType: 'text' });\n }\n state.text += text;\n out.push({ type: 'text-delta', index: state.index, text });\n break;\n }\n if (deltaType === 'thinking_delta') {\n const text = typeof delta.thinking === 'string' ? delta.thinking : '';\n if (!text) break;\n assign(state);\n if (!state.started) {\n state.started = true;\n out.push({ type: 'block-start', index: state.index, blockType: 'reasoning' });\n }\n state.text += text;\n out.push({ type: 'reasoning-delta', index: state.index, text });\n break;\n }\n if (deltaType === 'input_json_delta') {\n if (state.kind !== 'tool') throw new LlmError('OpenDesign\uFF1A\u5DE5\u5177\u53C2\u6570\u5206\u7247\u843D\u5728\u975E\u5DE5\u5177\u5757\u4E0A', 'INVALID_RESPONSE');\n const part = typeof delta.partial_json === 'string' ? delta.partial_json : '';\n state.args += part;\n if (state.id) out.push({ type: 'tool-call-delta', index: state.index, id: ToolCallId(state.id), ...(state.name ? { name: state.name } : {}), argumentsDelta: part });\n break;\n }\n // signature_delta / citations_delta \u4E0D\u8FDB\u5165 DSH \u5757\uFF1A\u7B7E\u540D\u4E0D\u53EF\u56DE\u653E\uFF0C\u5F15\u7528\u5757\u65E0\u5BF9\u5E94\u5185\u5BB9\u7C7B\u578B\u3002\n break;\n }\n case 'message_delta': {\n const delta = record(value.delta) ? value.delta : {};\n if (typeof delta.stop_reason === 'string') stopReason = delta.stop_reason;\n const counters = record(value.usage) ? value.usage : {};\n raw.output = num(counters.output_tokens) ?? raw.output;\n raw.input = num(counters.input_tokens) ?? raw.input;\n raw.cacheRead = num(counters.cache_read_input_tokens) ?? raw.cacheRead;\n raw.cacheWrite = num(counters.cache_creation_input_tokens) ?? raw.cacheWrite;\n break;\n }\n case 'message_stop': {\n const reason = reasonFromStop(stopReason);\n // \u6240\u6709\u6709\u6548\u6027\u68C0\u67E5\u90FD\u5FC5\u987B\u5728 finish \u4E4B\u524D\uFF1A\u6D88\u8D39\u8005\u770B\u5230 finish \u5F80\u5F80\u7ACB\u5373 return\uFF0C\n // \u653E\u5728\u5FAA\u73AF\u4E4B\u540E\u7684\u6821\u9A8C\u6C38\u8FDC\u4E0D\u4F1A\u6267\u884C\uFF0C\u7A7A\u54CD\u5E94/\u7F3A\u5DE5\u5177\u5757\u5C31\u4F1A\u88AB\u5F53\u6210\u6210\u529F\u3002\n if (reason.kind === 'tool-calls' && !sawTool) throw new LlmError('OpenDesign\uFF1A\u54CD\u5E94\u58F0\u660E\u5DE5\u5177\u8C03\u7528\uFF0C\u4F46\u672A\u8FD4\u56DE\u4EFB\u4F55\u5DE5\u5177\u5757', 'INVALID_RESPONSE');\n if (!count) throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u8FD4\u56DE\u7A7A\u54CD\u5E94', 'EMPTY_RESPONSE');\n usage = anthropicUsage(raw) ?? usage;\n out.push(...close());\n if (usage) out.push({ type: 'usage', usage });\n finish = reason;\n out.push({ type: 'finish', reason });\n break;\n }\n case 'error':\n throw anthropicError(undefined, value);\n case 'ping':\n default:\n break;\n }\n\n for (const chunk of out) yield chunk;\n if (finish) break;\n }\n\n signal.throwIfAborted();\n if (!finish) throw new LlmError('OpenDesign\uFF1A\u54CD\u5E94\u6D41\u63D0\u524D\u4E2D\u65AD\uFF0C\u672A\u6536\u5230\u7ED3\u675F\u4E8B\u4EF6', 'INVALID_RESPONSE');\n}\n\nexport const messages: Protocol = {\n id: 'messages',\n build: buildMessagesRequest,\n stream: streamMessages,\n};\n", "/**\n * \u6D88\u606F\u5185\u5BB9\u7684\u6A21\u6001\u6295\u5F71\uFF08Responses / Messages \u5171\u7528\uFF09\u3002\n *\n * \u4E0E Chat Completions \u7684 `conversion.ts#parts` \u4FDD\u6301\u540C\u4E00\u8BED\u4E49\uFF1A\u6587\u672C\u76F4\u51FA\uFF0C\u53EF\u89E3\u6790\u7684\u56FE\u7247\u53D8\u6210\n * \u56FE\u7247 URL\uFF0C\u65E0\u6CD5\u89E3\u6790\u6216\u5DF2 offload \u7684\u56FE\u7247\u9000\u5316\u4E3A\u547D\u540D\u5360\u4F4D\u6587\u672C\uFF0C\u539F\u59CB\u6587\u4EF6\u53E5\u67C4\u76F4\u63A5\u62D2\u7EDD\u3002\n */\n\nimport { LlmError, textOnlyImageText, type ContentBlock } from '@deepseek-ai/dsh-llm';\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';\n\n/** \u56FE\u7247\u9644\u4EF6 \u2192 \u8BF7\u6C42\u4F53\u53EF\u7528\u7684 URL\uFF08\u901A\u5E38\u662F data URL\uFF09\u3002 */\nexport type ImageLookup = (ref: ImageAttachmentRef) => string | undefined;\n\n/** \u4E00\u6BB5\u6D88\u606F\u6295\u5F71\u540E\u7684\u6587\u672C\u4E0E\u56FE\u7247\u3002 */\nexport interface ProjectedContent {\n text: string;\n images: string[];\n}\n\n/**\n * \u6295\u5F71\u4E00\u4E2A\u6D88\u606F\u7684\u6587\u672C\u4E0E\u56FE\u7247\u3002\n *\n * @param blocks \u6D88\u606F\u5185\u5BB9\u5757\u3002\n * @param image \u56FE\u7247\u89E3\u6790\u5668\uFF1B\u672A\u63D0\u4F9B\u65F6\u6240\u6709\u56FE\u7247\u9000\u5316\u4E3A\u5360\u4F4D\u6587\u672C\u3002\n */\nexport function projectContent(blocks: readonly ContentBlock[], image?: ImageLookup): ProjectedContent {\n let text = '';\n const images: string[] = [];\n for (const block of blocks) {\n switch (block.type) {\n case 'text':\n text += block.text;\n break;\n case 'image': {\n const url = block.offloaded ? undefined : image?.(block.attachment);\n if (url) images.push(url);\n else text += `${text ? '\\n' : ''}${textOnlyImageText(block.attachment)}`;\n break;\n }\n case 'file':\n throw new LlmError('\u539F\u59CB\u6587\u4EF6\u672A\u88AB\u5BBF\u4E3B\u6295\u5F71\u4E3A\u6587\u672C\u53E5\u67C4', 'UNSUPPORTED_OPTION');\n // \u5DE5\u5177\u5B9A\u4E49\u5DF2\u7531 Core \u7269\u5316\u8FDB options.tools\uFF1B\u5DE5\u5177\u66F4\u65B0\u5757\u53EA\u5BF9\u58F0\u660E in-history \u7684\u8DEF\u7531\u6709\u610F\u4E49\u3002\n default:\n break;\n }\n }\n return { text, images };\n}\n", "/**\n * usage \u5F52\u4E00\u5316\uFF1A\u628A\u4E0A\u6E38\u8BA1\u6570\u6298\u7B97\u6210 DSH \u7684**\u4E0D\u76F8\u4EA4**\u53E3\u5F84\u3002\n *\n * `TokenUsage.inputTokens` \u53EA\u8BA1\u672A\u7F13\u5B58\u8F93\u5165\uFF1B\u7F13\u5B58\u8BFB\u53D6/\u5199\u5165\u5355\u72EC\u4E0A\u62A5\uFF0C\u4E09\u8005\u76F8\u52A0\u624D\u662F\u8BA1\u8D39\u8F93\u5165\u3002\n * \u4E24\u5957\u4E0A\u6E38\u53E3\u5F84\u4E0D\u540C\uFF0C\u5FC5\u987B\u5206\u5F00\u5904\u7406\uFF1A\n * - OpenAI\uFF08Chat / Responses\uFF09\u7684\u8F93\u5165\u603B\u6570**\u5305\u542B**\u7F13\u5B58\u547D\u4E2D\uFF0C\u9700\u8981\u51CF\u51FA\u6765\uFF1B\n * - Anthropic Messages \u7684 `input_tokens` **\u4E0D\u542B**\u7F13\u5B58\u8BFB\u53D6\u4E0E\u7F13\u5B58\u5199\u5165\uFF0C\u76F4\u63A5\u5BF9\u5E94\u3002\n *\n * \u4EFB\u4F55\u975E\u6CD5\u6216\u81EA\u76F8\u77DB\u76FE\u7684\u7F13\u5B58\u8BA1\u6570\u90FD\u4F1A\u88AB\u4E22\u5F03\uFF0C\u800C\u4E0D\u662F\u4EA7\u751F\u8D1F\u6570\u6216\u51ED\u7A7A\u7684\u8F93\u5165\u91CF\u3002\n */\n\nimport type { TokenUsage } from '@deepseek-ai/dsh-llm';\n\n/** \u4E0A\u6E38\u539F\u59CB\u8BA1\u6570\uFF08\u7F3A\u7701\u6216\u975E\u6CD5\u4E00\u5F8B\u89C6\u4E3A\u672A\u77E5\uFF09\u3002 */\nexport interface RawUsage {\n input?: number | undefined;\n output?: number | undefined;\n cacheRead?: number | undefined;\n cacheWrite?: number | undefined;\n reasoning?: number | undefined;\n total?: number | undefined;\n}\n\nfunction valid(value: number | undefined): value is number {\n return value !== undefined && Number.isFinite(value) && value >= 0;\n}\n\n/**\n * OpenAI \u53E3\u5F84\uFF1A`input` \u542B\u7F13\u5B58\u547D\u4E2D\u3002\n *\n * @param raw \u4E0A\u6E38\u8BA1\u6570\u3002\n * @returns \u5F52\u4E00\u5316 usage\uFF1B\u8F93\u5165\u6216\u8F93\u51FA\u7F3A\u5931\u3001\u4E3A\u8D1F\u65F6\u8FD4\u56DE undefined\u3002\n */\nexport function openAiUsage(raw: RawUsage): TokenUsage | undefined {\n const input = raw.input, output = raw.output;\n if (!valid(input) || !valid(output)) return undefined;\n const read = valid(raw.cacheRead) ? raw.cacheRead : 0;\n const write = valid(raw.cacheWrite) ? raw.cacheWrite : 0;\n const cached = read + write <= input;\n const reasoning = valid(raw.reasoning) && raw.reasoning <= output ? raw.reasoning : undefined;\n return {\n inputTokens: cached ? input - read - write : input,\n outputTokens: output,\n totalTokens: input + output,\n ...(cached && read > 0 ? { cacheReadTokens: read } : {}),\n ...(cached && write > 0 ? { cacheWriteTokens: write } : {}),\n ...(reasoning !== undefined ? { reasoningTokens: reasoning } : {}),\n };\n}\n\n/**\n * Anthropic \u53E3\u5F84\uFF1A`input` \u4E0D\u542B\u7F13\u5B58\uFF0C\u7F13\u5B58\u8BFB\u53D6/\u5199\u5165\u662F\u72EC\u7ACB\u8BA1\u6570\u3002\n *\n * @param raw \u4E0A\u6E38\u8BA1\u6570\u3002\n * @returns \u5F52\u4E00\u5316 usage\uFF1B\u8F93\u5165\u6216\u8F93\u51FA\u7F3A\u5931\u3001\u4E3A\u8D1F\u65F6\u8FD4\u56DE undefined\u3002\n */\nexport function anthropicUsage(raw: RawUsage): TokenUsage | undefined {\n const input = raw.input, output = raw.output;\n if (!valid(input) || !valid(output)) return undefined;\n const read = valid(raw.cacheRead) ? raw.cacheRead : undefined;\n const write = valid(raw.cacheWrite) ? raw.cacheWrite : undefined;\n const reasoning = valid(raw.reasoning) && raw.reasoning <= output ? raw.reasoning : undefined;\n const total = valid(raw.total) ? raw.total : input + (read ?? 0) + (write ?? 0) + output;\n return {\n inputTokens: input,\n outputTokens: output,\n totalTokens: total,\n ...(read !== undefined && read > 0 ? { cacheReadTokens: read } : {}),\n ...(write !== undefined && write > 0 ? { cacheWriteTokens: write } : {}),\n ...(reasoning !== undefined ? { reasoningTokens: reasoning } : {}),\n };\n}\n", "/**\n * OpenAI Responses \u534F\u8BAE\uFF08\u65E0\u72B6\u6001\uFF1A`store: false` + \u6BCF\u6B21\u53D1\u9001\u5B8C\u6574 `input`\uFF09\u3002\n *\n * \u4E3A\u4EC0\u4E48\u575A\u6301\u65E0\u72B6\u6001\uFF1ADSH \u7684\u8BF7\u6C42\u662F\u4F1A\u8BDD\u65E5\u5FD7\u7684\u7EAF\u51FD\u6570\uFF0C\u9002\u914D\u5668\u4E0D\u6301\u4E45\u5316 `previous_response_id`\uFF0C\n * \u56E0\u6B64\u91CD\u653E\u3001\u91CD\u8BD5\u4E0E\u5E76\u884C\u5206\u652F\u90FD\u4E0D\u4F1A\u4F9D\u8D56\u670D\u52A1\u7AEF\u4F1A\u8BDD\uFF1B\u4EE3\u4EF7\u662F reasoning \u9879\u65E0\u6CD5\u56DE\u653E\u2014\u2014Responses\n * \u53EA\u5728\u5E26 `encrypted_content` \u65F6\u5141\u8BB8\u8DE8\u8F6E\u91CD\u653E\u63A8\u7406\u9879\uFF0C\u672C\u63D2\u4EF6\u4E0D\u4FDD\u5B58\u8BE5\u5185\u5BB9\uFF0C\u6240\u4EE5\u5386\u53F2\u63A8\u7406\u53EA\u6620\u5C04\n * \u4E3A\u672C\u8F6E\u53EF\u89C1\u7684 reasoning \u5757\uFF0C\u518D\u6B21\u8BF7\u6C42\u65F6\u4E0D\u4F1A\u4F2A\u88C5\u6210\u5DF2\u7B7E\u540D\u7684\u4E0A\u4E0B\u6587\u3002\n *\n * \u7EC8\u6B62\u8BED\u4E49\uFF08\u5B98\u65B9 `response.completed` / `response.incomplete` / `response.failed`\uFF09\uFF1A\n * - `completed`\uFF1A\u6709 `function_call` \u9879 \u2192 tool-calls\uFF0C\u5426\u5219 stop\uFF1B\n * - `incomplete`\uFF1A`max_tokens`/`max_output_tokens` \u2192 max-tokens\uFF08\u622A\u65AD**\u4E0D**\u5F53\u6210\u529F\u5168\u6587\uFF09\uFF0C\n * `content_filter` \u4E0E\u5176\u5B83\u539F\u56E0 \u2192 \u76F4\u63A5\u5931\u8D25\uFF0C\u7EDD\u4E0D\u4EA7\u51FA finish\uFF1B\n * - `failed` \u6216\u6D41\u5185 `error` \u4E8B\u4EF6 \u2192 \u6309\u56FA\u5B9A\u5206\u7C7B\u629B\u9519\uFF0C\u4E0D\u56DE\u663E\u4E0A\u6E38\u6B63\u6587\u3002\n */\n\nimport {\n LlmError, ToolCallId,\n type FinishReason, type StreamChunk, type TokenUsage,\n} from '@deepseek-ai/dsh-llm';\nimport { record } from '../util.js';\nimport { inBandError } from './errors.js';\nimport { streamHeaders } from './headers.js';\nimport { inferenceEndpoint } from '../protocol-options.js';\nimport { projectContent, type ImageLookup } from './parts.js';\nimport { sseFrames } from './sse.js';\nimport { openAiUsage } from './usage.js';\nimport type { Protocol, ProtocolContext, WireRequest } from './types.js';\n\n/**\n * Responses \u7684 `reasoning.effort` \u5B98\u65B9\u53D6\u503C\u3002\n *\n * \u6765\u6E90\uFF1AOpenAI OpenAPI \u89C4\u8303 `ReasoningEffort` \u679A\u4E3E\uFF082026-10-26 \u53D6\u81EA\n * `raw.githubusercontent.com/openai/openai-openapi/master/openapi.yaml`\uFF09\uFF1A\n * `none | minimal | low | medium | high | xhigh | max`\u3002\n * \u672C\u5730\u76EE\u5F55\u91CC\u7684\u6269\u5C55\u6863\u4F4D\uFF08\u5982 `ultra`\uFF09\u4E0D\u5728\u5176\u4E2D\uFF0C\u6309\u4E0D\u652F\u6301\u5904\u7406\u800C\u4E0D\u662F\u539F\u6837\u900F\u4F20\u3002\n */\nconst REASONING_EFFORTS: readonly string[] = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'];\n\ntype InputPart = { type: 'input_text'; text: string } | { type: 'input_image'; image_url: string; detail: 'auto' };\n\nfunction userContent(text: string, images: readonly string[]): string | InputPart[] {\n if (!images.length) return text;\n return [\n ...(text ? [{ type: 'input_text' as const, text }] : []),\n ...images.map(url => ({ type: 'input_image' as const, image_url: url, detail: 'auto' as const })),\n ];\n}\n\n/**\n * \u6784\u9020 Responses \u8BF7\u6C42\u3002\n *\n * \u6D88\u606F\u6295\u5F71\uFF1Asystem/developer \u6587\u672C\u8FDB `instructions`\uFF08DSH \u672A\u58F0\u660E in-history \u7CFB\u7EDF\u63D0\u793A\u66F4\u65B0\uFF0C\n * \u5B8C\u6574\u7CFB\u7EDF\u63D0\u793A\u6BCF\u8F6E\u90FD\u5728\u5F00\u5934\uFF0C\u5408\u5E76\u540E\u8BED\u4E49\u4E0D\u53D8\uFF09\uFF1Bassistant \u6587\u672C + `function_call` \u9879\uFF1B\n * tool \u7ED3\u679C\u53D8 `function_call_output`\uFF0C\u5176\u4E2D\u7684\u56FE\u7247\u63D0\u5347\u5230\u7D27\u968F\u5176\u540E\u7684 user \u8F93\u5165\u9879\u3002\n */\nexport function buildResponsesRequest(ctx: ProtocolContext): WireRequest {\n const { options, model } = ctx;\n const instructions: string[] = [];\n const input: Record<string, unknown>[] = [];\n const lookup: ImageLookup | undefined = ctx.images.size ? ref => ctx.images.get(ref.attachmentId) : undefined;\n let lifted: string[] = [];\n const flushLifted = (): void => {\n if (!lifted.length) return;\n input.push({ role: 'user', content: userContent('(Image content from the preceding tool result.)', lifted) });\n lifted = [];\n };\n\n for (const message of options.messages) {\n if (message.role !== 'tool') flushLifted();\n const projected = projectContent(message.content, message.role === 'user' || message.role === 'tool' ? lookup : undefined);\n switch (message.role) {\n case 'system':\n case 'developer':\n if (projected.text) instructions.push(projected.text);\n break;\n case 'user':\n if (projected.text || projected.images.length) input.push({ role: 'user', content: userContent(projected.text, projected.images) });\n break;\n case 'assistant': {\n if (projected.text) input.push({ role: 'assistant', content: projected.text });\n for (const block of message.content) {\n if (block.type === 'tool-call') input.push({ type: 'function_call', call_id: block.id, name: block.name, arguments: block.arguments });\n }\n break;\n }\n case 'tool': {\n input.push({\n type: 'function_call_output',\n call_id: message.toolCallId,\n output: projected.text || (projected.images.length ? '(Image content follows in the next user message.)' : ''),\n });\n lifted.push(...projected.images);\n break;\n }\n }\n }\n flushLifted();\n if (options.system?.trim()) instructions.unshift(options.system);\n\n const body: Record<string, unknown> = { model: model.id, input, stream: true, store: false };\n if (instructions.length) body.instructions = instructions.join('\\n\\n');\n if (options.tools?.length) body.tools = options.tools.map(tool => ({ type: 'function', name: tool.name, description: tool.description, parameters: tool.parameters }));\n if (options.temperature !== undefined) body.temperature = options.temperature;\n if (ctx.topP !== undefined) body.top_p = ctx.topP;\n if (options.maxTokens !== undefined) {\n if (!Number.isSafeInteger(options.maxTokens) || options.maxTokens <= 0) throw new LlmError('maxTokens \u5FC5\u987B\u662F\u6B63\u6574\u6570', 'INVALID_REQUEST');\n body.max_output_tokens = options.maxTokens;\n }\n if (options.reasoningEffort !== undefined) {\n const effort = String(options.reasoningEffort);\n if (!REASONING_EFFORTS.includes(effort)) throw new LlmError(`Responses \u534F\u8BAE\u4E0D\u63A5\u53D7\u601D\u8003\u6DF1\u5EA6\u300C${effort}\u300D`, 'UNSUPPORTED_OPTION');\n // \u540C\u65F6\u8BF7\u6C42\u6458\u8981\uFF0C\u624D\u80FD\u628A\u63A8\u7406\u6620\u5C04\u6210 reasoning \u5757\uFF1B\u5426\u5219\u63A8\u7406\u4E0D\u53EF\u89C1\u3002\n body.reasoning = { effort, summary: 'auto' };\n }\n if (options.stop?.length) throw new LlmError('Responses \u534F\u8BAE\u4E0D\u652F\u6301 stop \u5E8F\u5217', 'UNSUPPORTED_OPTION');\n return { url: inferenceEndpoint(ctx.baseURL, 'responses'), headers: streamHeaders(ctx.apiKey), body };\n}\n\ninterface TextState { index: number; text: string; started: boolean }\ninterface CallState { index: number; id: string; name: string; args: string; started: boolean }\n\nfunction str(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\nfunction int(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : undefined;\n}\n\n/** \u4ECE\u7EC8\u6001 Response \u5BF9\u8C61\u91CC\u8BFB\u51FA usage\uFF08`input_tokens` \u542B\u7F13\u5B58\uFF0C\u6309 OpenAI \u53E3\u5F84\u6298\u6210\u4E0D\u76F8\u4EA4\u8BA1\u6570\uFF09\u3002 */\nfunction responseUsage(response: Record<string, unknown>): TokenUsage | undefined {\n if (!record(response.usage)) return undefined;\n const usage = response.usage;\n const input = record(usage.input_tokens_details) ? usage.input_tokens_details : {};\n const output = record(usage.output_tokens_details) ? usage.output_tokens_details : {};\n return openAiUsage({\n input: typeof usage.input_tokens === 'number' ? usage.input_tokens : undefined,\n output: typeof usage.output_tokens === 'number' ? usage.output_tokens : undefined,\n cacheRead: typeof input.cached_tokens === 'number' ? input.cached_tokens : undefined,\n cacheWrite: typeof input.cache_write_tokens === 'number' ? input.cache_write_tokens : undefined,\n reasoning: typeof output.reasoning_tokens === 'number' ? output.reasoning_tokens : undefined,\n });\n}\n\n/**\n * \u628A Responses \u7684 SSE \u4E8B\u4EF6\u7FFB\u8BD1\u6210 DSH \u6D41\u5F0F\u5757\u3002\n *\n * \u652F\u6301\u4EA4\u9519\u8F93\u51FA\u9879\uFF08\u6587\u672C / \u5DE5\u5177\u8C03\u7528 / \u63A8\u7406\uFF09\uFF0C\u6309\u9996\u6B21\u51FA\u73B0\u987A\u5E8F\u5206\u914D\u5757\u7D22\u5F15\uFF1B\n * \u53EA\u51FA\u73B0\u5728\u7EC8\u6001 `output` \u91CC\u7684\u9879\u4E5F\u4F1A\u8865\u6210\u5757\uFF0C\u907F\u514D\u201C\u7EC8\u6001\u624D\u7ED9\u5185\u5BB9\u201D\u7684\u7F51\u5173\u88AB\u8BEF\u5224\u4E3A\u7A7A\u54CD\u5E94\u3002\n */\nexport async function* streamResponses(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n idleMs: number,\n): AsyncGenerator<StreamChunk> {\n let nextIndex = 0;\n let count = 0;\n let usage: TokenUsage | undefined;\n let finish: FinishReason | undefined;\n const texts = new Map<string, TextState>();\n const reasonings = new Map<string, TextState>();\n const calls = new Map<string, CallState>();\n const keyByOutput = new Map<number, string>();\n\n function textState(key: string): TextState {\n let state = texts.get(key);\n if (!state) {\n state = { index: nextIndex++, text: '', started: false };\n texts.set(key, state);\n count++;\n }\n return state;\n }\n\n function reasoningState(key: string): TextState {\n let state = reasonings.get(key);\n if (!state) {\n state = { index: nextIndex++, text: '', started: false };\n reasonings.set(key, state);\n count++;\n }\n return state;\n }\n\n function appendText(state: TextState, delta: string, out: StreamChunk[]): void {\n if (!state.started) {\n state.started = true;\n out.push({ type: 'block-start', index: state.index, blockType: 'text' });\n }\n state.text += delta;\n out.push({ type: 'text-delta', index: state.index, text: delta });\n }\n\n function appendReasoning(state: TextState, delta: string, out: StreamChunk[]): void {\n if (!state.started) {\n state.started = true;\n out.push({ type: 'block-start', index: state.index, blockType: 'reasoning' });\n }\n state.text += delta;\n out.push({ type: 'reasoning-delta', index: state.index, text: delta });\n }\n\n function callState(key: string, item?: Record<string, unknown>, out?: StreamChunk[]): CallState {\n let call = calls.get(key);\n if (!call) {\n call = { index: nextIndex++, id: '', name: '', args: '', started: false };\n calls.set(key, call);\n count++;\n out?.push({ type: 'block-start', index: call.index, blockType: 'tool-call' });\n }\n if (item) {\n const id = str(item.call_id) ?? str(item.id);\n if (id && !call.id) call.id = id;\n const name = str(item.name);\n if (name) call.name = name;\n }\n return call;\n }\n\n /** \u53EA\u5728 id \u5DF2\u77E5\u65F6\u6295\u9012\u5DE5\u5177\u8C03\u7528\u589E\u91CF\uFF1Bid \u8FDF\u5230\u65F6\u4E00\u6B21\u6027\u8865\u4E0A\u5DF2\u7D2F\u79EF\u53C2\u6570\u3002 */\n function flushCall(call: CallState, delta: string, out: StreamChunk[]): void {\n if (!call.id) return;\n const name = call.name ? { name: call.name } : {};\n if (!call.started) {\n call.started = true;\n out.push({ type: 'tool-call-delta', index: call.index, id: ToolCallId(call.id), ...name, argumentsDelta: call.args });\n return;\n }\n out.push({ type: 'tool-call-delta', index: call.index, id: ToolCallId(call.id), ...name, argumentsDelta: delta });\n }\n\n /** \u5B8C\u6574\u9879\u662F\u6743\u5A01\u5FEB\u7167\uFF1B\u5DF2\u53D1\u589E\u91CF\u53EA\u80FD\u8FFD\u52A0\uFF0C\u4E0D\u80FD\u56DE\u9000\u6216\u6539\u5199\u3002 */\n function completeCall(call: CallState, item: Record<string, unknown>, out: StreamChunk[]): void {\n const args = item.arguments;\n let delta = '';\n if (args !== undefined) {\n // \u7A7A\u5B57\u7B26\u4E32\u4E5F\u662F\u6743\u5A01\u503C\uFF0C\u4E0D\u80FD\u7528 str() \u5F53\u4F5C\u201C\u5B57\u6BB5\u7F3A\u5931\u201D\u8DF3\u8FC7\u77DB\u76FE\u6821\u9A8C\u3002\n if (typeof args !== 'string' || !args.startsWith(call.args)) {\n throw new LlmError('OpenDesign\uFF1A\u5DE5\u5177\u8C03\u7528\u5B8C\u6574\u53C2\u6570\u4E0E\u6D41\u5F0F\u589E\u91CF\u4E0D\u4E00\u81F4', 'INVALID_RESPONSE');\n }\n delta = args.slice(call.args.length);\n call.args = args;\n }\n flushCall(call, delta, out);\n }\n\n function keyFor(value: Record<string, unknown>, kind: string, outputIndex?: number): string {\n const itemId = str(value.item_id) ?? (outputIndex === undefined ? undefined : keyByOutput.get(outputIndex));\n return `${kind}:${itemId ?? `idx:${outputIndex ?? -1}`}`;\n }\n\n /** \u7EC8\u6001 `output` \u8865\u9F50\u5DF2\u6709\u5DE5\u5177\u8C03\u7528\uFF0C\u4E5F\u628A\u4EC5\u5728\u7EC8\u6001\u51FA\u73B0\u7684\u8F93\u51FA\u9879\u8865\u6210\u5757\u3002 */\n function hydrate(output: unknown, out: StreamChunk[]): void {\n if (!Array.isArray(output)) return;\n for (const item of output) {\n if (!record(item)) continue;\n if (item.type === 'function_call') {\n const itemId = str(item.id) ?? str(item.call_id);\n const callId = str(item.call_id) ?? itemId;\n if (!callId) continue;\n const existing = [...calls].find(([, call]) => call.id === callId);\n const call = callState(existing?.[0] ?? `call:${itemId ?? callId}`, item, out);\n completeCall(call, item, out);\n continue;\n }\n if (item.type === 'message') {\n const key = `text:${str(item.id) ?? 'unknown'}:0`;\n if (texts.has(key)) continue;\n const content = Array.isArray(item.content) ? item.content : [];\n const text = content\n .map(part => record(part) && (part.type === 'output_text' || part.type === 'refusal') ? str(part.text) ?? '' : '')\n .join('');\n if (!text) continue;\n appendText(textState(key), text, out);\n continue;\n }\n if (item.type === 'reasoning') {\n const key = `reasoning:${str(item.id) ?? 'unknown'}:s0`;\n if (reasonings.has(key)) continue;\n const summary = Array.isArray(item.summary) ? item.summary : [];\n const text = summary.map(part => record(part) ? str(part.text) ?? '' : '').join('');\n if (!text) continue;\n appendReasoning(reasoningState(key), text, out);\n }\n }\n }\n\n function close(): StreamChunk[] {\n const out: StreamChunk[] = [];\n for (const state of texts.values()) if (state.started) out.push({ type: 'block-end', index: state.index, block: { type: 'text', text: state.text } });\n for (const state of reasonings.values()) if (state.started) out.push({ type: 'block-end', index: state.index, block: { type: 'reasoning', text: state.text } });\n for (const call of calls.values()) {\n if (!call.id || !call.name) throw new LlmError('OpenDesign\uFF1A\u5DE5\u5177\u8C03\u7528\u7F3A\u5C11\u6807\u8BC6\u6216\u540D\u79F0', 'INVALID_RESPONSE');\n out.push({ type: 'block-end', index: call.index, block: { type: 'tool-call', id: ToolCallId(call.id), name: call.name, arguments: call.args } });\n }\n return out.sort((a, b) => ('index' in a ? a.index : 0) - ('index' in b ? b.index : 0));\n }\n\n function reasonOf(type: string, response: Record<string, unknown>): FinishReason {\n if (type === 'response.incomplete') {\n const details = record(response.incomplete_details) ? response.incomplete_details : {};\n const why = str(details.reason) ?? '';\n if (why === 'max_tokens' || why === 'max_output_tokens') return { kind: 'max-tokens' };\n if (why === 'content_filter') throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u54CD\u5E94\u88AB\u5185\u5BB9\u8FC7\u6EE4', 'INVALID_RESPONSE');\n throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u54CD\u5E94\u672A\u5B8C\u6210\uFF0C\u4E0A\u6E38\u4E2D\u65AD', 'SERVER');\n }\n const output = Array.isArray(response.output) ? response.output : [];\n return output.some(item => record(item) && item.type === 'function_call') || calls.size > 0\n ? { kind: 'tool-calls' }\n : { kind: 'stop' };\n }\n\n for await (const frame of sseFrames(body, signal, idleMs)) {\n if (frame.data.trim() === '[DONE]') break; // Responses \u4E0D\u8981\u6C42\u8BE5\u54E8\u5175\uFF0C\u5BB9\u5FCD\u7F51\u5173\u8865\u9F50\n let value: unknown;\n try {\n value = JSON.parse(frame.data);\n } catch {\n throw new LlmError('OpenDesign\uFF1A\u65E0\u6548\u7684\u6D41\u5F0F JSON', 'INVALID_RESPONSE');\n }\n if (!record(value)) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u4E8B\u4EF6\u4E0D\u662F\u5BF9\u8C61', 'INVALID_RESPONSE');\n const type = str(value.type) ?? frame.event;\n if (!type) throw new LlmError('OpenDesign\uFF1A\u6D41\u5F0F\u4E8B\u4EF6\u7F3A\u5C11\u7C7B\u578B', 'INVALID_RESPONSE');\n const out: StreamChunk[] = [];\n\n switch (type) {\n case 'response.output_item.added': {\n const outputIndex = int(value.output_index);\n const item = record(value.item) ? value.item : undefined;\n if (item && outputIndex !== undefined) {\n // \u4E8B\u4EF6\u91CC\u7684 `item_id` \u662F\u8F93\u51FA\u9879\u81EA\u8EAB id\uFF08fc_/msg_/rs_\uFF09\uFF0C\u6240\u4EE5\u8FD9\u91CC\u4E5F\u6309 item.id \u5EFA\u7D22\u5F15\uFF1B\n // DSH \u7684\u5DE5\u5177\u8C03\u7528 id \u4ECD\u53D6 `call_id`\uFF0C\u4E24\u8005\u4E0D\u6DF7\u7528\u3002\n const itemId = str(item.id) ?? str(item.call_id);\n if (itemId) keyByOutput.set(outputIndex, itemId);\n }\n if (item?.type === 'function_call') callState(keyFor({ item: value.item }, 'call', outputIndex), item, out);\n break;\n }\n case 'response.output_text.delta':\n case 'response.output_text.done': {\n if (type.endsWith('.done')) break; // \u589E\u91CF\u5DF2\u5B8C\u6574\u91CD\u5EFA\uFF0Cdone \u53EA\u7528\u4E8E\u6821\u9A8C\n const delta = str(value.delta);\n if (!delta) break;\n const outputIndex = int(value.output_index);\n const contentIndex = int(value.content_index) ?? 0;\n const itemId = str(value.item_id) ?? (outputIndex === undefined ? undefined : keyByOutput.get(outputIndex));\n appendText(textState(`text:${itemId ?? `idx:${outputIndex ?? -1}`}:${contentIndex}`), delta, out);\n break;\n }\n case 'response.refusal.delta': {\n const delta = str(value.delta);\n if (!delta) break;\n const outputIndex = int(value.output_index);\n const contentIndex = int(value.content_index) ?? 0;\n const itemId = str(value.item_id) ?? (outputIndex === undefined ? undefined : keyByOutput.get(outputIndex));\n appendText(textState(`text:${itemId ?? `idx:${outputIndex ?? -1}`}:${contentIndex}`), delta, out);\n break;\n }\n case 'response.reasoning_summary_text.delta': {\n const delta = str(value.delta);\n if (!delta) break;\n const key = keyFor(value, 'reasoning', int(value.output_index));\n appendReasoning(reasoningState(`${key}:s${int(value.summary_index) ?? 0}`), delta, out);\n break;\n }\n case 'response.reasoning_text.delta': {\n const delta = str(value.delta);\n if (!delta) break;\n const key = keyFor(value, 'reasoning', int(value.output_index));\n appendReasoning(reasoningState(`${key}:t`), delta, out);\n break;\n }\n case 'response.function_call_arguments.delta': {\n const call = callState(keyFor(value, 'call', int(value.output_index)), undefined, out);\n const delta = str(value.delta) ?? '';\n call.args += delta;\n flushCall(call, delta, out);\n break;\n }\n case 'response.output_item.done': {\n const item = record(value.item) ? value.item : undefined;\n if (!item) break;\n const outputIndex = int(value.output_index);\n if (item.type === 'function_call') {\n const call = callState(keyFor(value, 'call', outputIndex), item, out);\n completeCall(call, item, out);\n } else if (item.type === 'message') {\n const key = `text:${str(item.id) ?? `idx:${outputIndex ?? -1}`}:0`;\n if (!texts.has(key)) {\n const content = Array.isArray(item.content) ? item.content : [];\n const text = content.map(part => record(part) && (part.type === 'output_text' || part.type === 'refusal') ? str(part.text) ?? '' : '').join('');\n if (text) appendText(textState(key), text, out);\n }\n } else if (item.type === 'reasoning') {\n const key = `reasoning:${str(item.id) ?? `idx:${outputIndex ?? -1}`}:s0`;\n if (!reasonings.has(key)) {\n const summary = Array.isArray(item.summary) ? item.summary : [];\n const text = summary.map(part => record(part) ? str(part.text) ?? '' : '').join('');\n if (text) appendReasoning(reasoningState(key), text, out);\n }\n }\n break;\n }\n case 'response.completed':\n case 'response.incomplete':\n case 'response.failed': {\n const response = record(value.response) ? value.response : {};\n if (type === 'response.failed') throw inBandError(record(response.error) ? response.error : {}, 'SERVER');\n usage = responseUsage(response) ?? usage;\n hydrate(response.output, out);\n const reason = reasonOf(type, response);\n // finish \u4E4B\u524D\u5B8C\u6210\u5168\u90E8\u6821\u9A8C\uFF1A\u6D88\u8D39\u8005\u6536\u5230 finish \u53EF\u80FD\u7ACB\u5373 return\uFF0C\u4E4B\u540E\u7684\u68C0\u67E5\u4E0D\u4F1A\u6267\u884C\u3002\n if (reason.kind === 'tool-calls' && calls.size === 0) throw new LlmError('OpenDesign\uFF1A\u54CD\u5E94\u58F0\u660E\u5DE5\u5177\u8C03\u7528\uFF0C\u4F46\u672A\u8FD4\u56DE\u4EFB\u4F55\u5DE5\u5177\u5757', 'INVALID_RESPONSE');\n if (!count) throw new LlmError('OpenDesign\uFF1A\u6A21\u578B\u8FD4\u56DE\u7A7A\u54CD\u5E94', 'EMPTY_RESPONSE');\n out.push(...close());\n if (usage) out.push({ type: 'usage', usage });\n finish = reason;\n out.push({ type: 'finish', reason });\n break;\n }\n case 'error':\n throw inBandError(value);\n default:\n // \u5176\u5B83\u4E8B\u4EF6\uFF08created/in_progress/content_part.*/annotation.* \u7B49\uFF09\u4E0D\u5F71\u54CD\u5757\u8BED\u4E49\u3002\n break;\n }\n\n for (const chunk of out) yield chunk;\n if (finish) break;\n }\n\n signal.throwIfAborted();\n if (!finish) throw new LlmError('OpenDesign\uFF1A\u54CD\u5E94\u6D41\u63D0\u524D\u4E2D\u65AD\uFF0C\u672A\u6536\u5230\u7ED3\u675F\u4E8B\u4EF6', 'INVALID_RESPONSE');\n}\n\nexport const responses: Protocol = {\n id: 'responses',\n build: buildResponsesRequest,\n stream: streamResponses,\n};\n", "/**\n * OpenAI \u517C\u5BB9 `GET /models` \u6A21\u578B\u53D1\u73B0\uFF08\u4E0E\u9009\u5B9A\u63A8\u7406\u534F\u8BAE\u65E0\u5173\uFF09\u3002\n *\n * \u5951\u7EA6\uFF1A\n * - \u53EA\u8BF7\u6C42 OpenAI \u517C\u5BB9 API \u7684 `/models`\uFF1B\u88F8\u7F51\u5173 origin \u81EA\u52A8\u8865 `/v1`\uFF0C\u663E\u5F0F\u524D\u7F00\u4FDD\u7559\u3002\u4F7F\u7528 `Bearer` \u9274\u6743 + \u5E94\u7528\u5F52\u56E0\u5934\uFF0C\n * `redirect: 'error'`\uFF0C20 \u79D2\u4E0A\u9650\uFF0C\u54CD\u5E94\u4F53\u4E0A\u9650 2 MiB\u3002\n * - \u4E0E\u63A8\u7406\u534F\u8BAE\u89E3\u8026\uFF1A\u672C\u51FD\u6570\u4E0D\u63A5\u53D7 protocol \u53C2\u6570\uFF0C\u4E5F\u4E0D\u6839\u636E\u534F\u8BAE\u6311\u9009\u8DEF\u5F84\u3002\n * - \u5F52\u4E00\u5316\u53EA\u63A5\u53D7 `data[]` \u4E2D\u53EF\u7528\u4E14\u6709\u754C\u7684 id\uFF1B\u5DF2\u77E5 id \u7EE7\u627F catalog \u7684\u5206\u7EC4\u4E0E\u80FD\u529B\uFF0C\n * \u65B0 id \u4E00\u5F8B\u5F52 `paid` \u4E14**\u4E0D**\u51ED\u540D\u79F0\u63A8\u65AD\u80FD\u529B\uFF08\u672A\u8BC6\u522B\u7684\u4E0A\u6E38\u80FD\u529B\u5B57\u6BB5\u76F4\u63A5\u5FFD\u7565\uFF09\u3002\n * - \u5A92\u4F53\u8F93\u51FA\u6A21\u578B\uFF08\u56FE\u50CF/\u89C6\u9891/\u8BED\u97F3\uFF0C\u8D70 `/api/v1/media/*`\uFF09\u4E0D\u8FDB\u5BF9\u8BDD\u76EE\u5F55\u3002\n * - \u6240\u6709\u5931\u8D25\u6298\u53E0\u4E3A `ModelDiscoveryError` \u7684\u56FA\u5B9A\u5206\u7C7B\u4E0E\u56FA\u5B9A\u6587\u5B57\uFF0C\u4E0D\u56DE\u663E\u51ED\u636E\u3001\n * \u8BF7\u6C42\u5934\u6216\u54CD\u5E94\u4F53\u3002\n */\n\nimport { attributionHeaders } from '@deepseek-ai/dsh-llm';\nimport { findModel, type CatalogModel } from './catalog.js';\nimport { assertBaseURL } from './config.js';\nimport { openAiBaseURL as normalizeOpenAiBase } from './protocol-options.js';\nimport { combinedSignal, record, safeSecret } from './util.js';\n\n/** \u53D1\u73B0\u8BF7\u6C42\u7684\u603B\u65F6\u9650\uFF08\u6BEB\u79D2\uFF09\u3002 */\nexport const DISCOVERY_TIMEOUT_MS = 20_000;\n/** \u54CD\u5E94\u4F53\u4E0A\u9650\uFF08\u5B57\u8282\uFF09\uFF1B\u8D85\u51FA\u5373\u6309\u683C\u5F0F\u9519\u8BEF\u62D2\u7EDD\uFF0C\u4E0D\u89E3\u6790\u90E8\u5206 JSON\u3002 */\nexport const MAX_DISCOVERY_BODY_BYTES = 2 * 1024 * 1024;\n/** \u5355\u6B21\u53D1\u73B0\u7684\u6A21\u578B\u6761\u6570\u4E0A\u9650\u3002 */\nconst MAX_MODELS = 512;\nconst MAX_MODEL_ID_LENGTH = 128;\nconst MAX_MODEL_NAME_LENGTH = 128;\nconst MODEL_ID = /^[A-Za-z0-9._:/-]{1,128}$/u;\n/**\n * \u663E\u5F0F\u5A92\u4F53\u8F93\u51FA\u6A21\u578B\u7684 id \u524D\u7F00\uFF1A\u5B98\u7F51\u8BC1\u636E\u91CC\u8FD9\u4E9B\u6A21\u578B\u8D70 `/api/v1/media/*`\uFF0C\n * \u9009\u4E2D\u540E chat \u8BF7\u6C42\u5FC5\u8D25\u3002\u53EA\u6309 id \u524D\u7F00\u6392\u9664\uFF0C\u4E0D\u4ECE\u540D\u79F0\u6216\u672A\u77E5\u80FD\u529B\u5B57\u6BB5\u63A8\u65AD\u3002\n */\nconst MEDIA_MODEL_ID = /^(?:gpt-image-|nano-banana-|seedream-|imagen-|veo-|doubao-seedance-|sora-)/u;\n\n/** Failure taxonomy; `status` is the HTTP status when one was received. */\nexport type ModelDiscoveryErrorKind = 'url' | 'credential' | 'network' | 'timeout' | 'aborted' | 'auth' | 'permission' | 'rate-limit' | 'server' | 'response';\n\nconst MESSAGES: Record<ModelDiscoveryErrorKind, string> = {\n url: '\u6A21\u578B\u53D1\u73B0\u5730\u5740\u65E0\u6548\uFF1A\u5FC5\u987B\u662F\u7EDD\u5BF9 HTTP(S) \u5730\u5740\uFF0C\u4E14\u4E0D\u542B\u51ED\u636E\u3001\u67E5\u8BE2\u4E32\u6216\u7247\u6BB5',\n credential: '\u6A21\u578B\u53D1\u73B0\u51ED\u636E\u7F3A\u5931\uFF0C\u6216\u542B\u6709\u4E0D\u53EF\u7528\u4E8E HTTP \u8BF7\u6C42\u5934\u7684\u5B57\u7B26',\n network: '\u65E0\u6CD5\u8FDE\u63A5\u6A21\u578B\u53D1\u73B0\u670D\u52A1',\n timeout: '\u6A21\u578B\u53D1\u73B0\u8BF7\u6C42\u8D85\u8FC7 20 \u79D2\u65F6\u9650',\n aborted: '\u6A21\u578B\u53D1\u73B0\u8BF7\u6C42\u5DF2\u53D6\u6D88',\n auth: '\u6A21\u578B\u53D1\u73B0\u8BA4\u8BC1\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u51ED\u636E',\n permission: '\u6A21\u578B\u53D1\u73B0\u51ED\u636E\u65E0\u6743\u8BFB\u53D6\u6A21\u578B\u5217\u8868',\n 'rate-limit': '\u6A21\u578B\u53D1\u73B0\u8BF7\u6C42\u88AB\u9650\u6D41\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5',\n server: '\u6A21\u578B\u53D1\u73B0\u670D\u52A1\u6682\u65F6\u4E0D\u53EF\u7528',\n response: '\u6A21\u578B\u53D1\u73B0\u54CD\u5E94\u4E0D\u7B26\u5408 OpenAI \u6A21\u578B\u5217\u8868\u683C\u5F0F',\n};\n\n/**\n * Fixed-text discovery failure. The message is one of the constants above, so callers may\n * log it verbatim: no credential, header, URL or upstream body is ever interpolated.\n */\nexport class ModelDiscoveryError extends Error {\n constructor(readonly kind: ModelDiscoveryErrorKind, readonly status?: number) {\n super(MESSAGES[kind]);\n this.name = 'ModelDiscoveryError';\n }\n}\n\nfunction statusKind(status: number): ModelDiscoveryErrorKind {\n if (status === 401) return 'auth';\n if (status === 403) return 'permission';\n if (status === 429) return 'rate-limit';\n if (status === 408 || status === 504) return 'timeout';\n if (status >= 500) return 'server';\n return 'response';\n}\n\n/**\n * Read at most `MAX_DISCOVERY_BODY_BYTES` and decode once; partial bodies are refused.\n * A body cut off by the caller's cancellation or the deadline is classified as such instead\n * of being reported as a format problem.\n */\nasync function boundedJson(response: Response, signal: AbortSignal | undefined, deadline: AbortSignal): Promise<unknown> {\n const reader = response.body?.getReader();\n if (!reader) throw new ModelDiscoveryError('response');\n const declared = Number(response.headers.get('content-length'));\n if (Number.isFinite(declared) && declared > MAX_DISCOVERY_BODY_BYTES) {\n await reader.cancel().catch(() => undefined);\n reader.releaseLock();\n throw new ModelDiscoveryError('response');\n }\n let size = 0;\n let raw = '';\n const decoder = new TextDecoder();\n try {\n while (true) {\n const chunk = await reader.read();\n if (chunk.done) break;\n size += chunk.value.byteLength;\n if (size > MAX_DISCOVERY_BODY_BYTES) throw new ModelDiscoveryError('response');\n raw += decoder.decode(chunk.value, { stream: true });\n }\n raw += decoder.decode();\n } catch (error) {\n if (signal?.aborted) throw new ModelDiscoveryError('aborted');\n if (deadline.aborted) throw new ModelDiscoveryError('timeout');\n if (error instanceof ModelDiscoveryError) throw error;\n throw new ModelDiscoveryError('response');\n } finally {\n await reader.cancel().catch(() => undefined);\n reader.releaseLock();\n }\n try { return JSON.parse(raw); } catch { throw new ModelDiscoveryError('response'); }\n}\n\n/**\n * Normalize an OpenAI list body. Rows without a usable id are dropped, duplicates keep\n * their first occurrence, and no capability is invented: a known id is copied from the\n * catalog, an unknown id becomes a `paid` row with only its id and name.\n */\nfunction normalize(body: unknown): readonly CatalogModel[] {\n if (!record(body) || !Array.isArray(body.data)) throw new ModelDiscoveryError('response');\n if (body.data.length > MAX_MODELS) throw new ModelDiscoveryError('response');\n const seen = new Set<string>();\n const rows: CatalogModel[] = [];\n for (const value of body.data) {\n if (!record(value) || typeof value.id !== 'string' || !MODEL_ID.test(value.id) || ['__proto__', 'constructor', 'prototype'].includes(value.id)) continue;\n if (MEDIA_MODEL_ID.test(value.id) || seen.has(value.id)) continue;\n seen.add(value.id);\n const known = findModel(value.id);\n if (known) { rows.push({ ...known }); continue; }\n const offered = typeof value.name === 'string' ? value.name.trim() : '';\n const name = offered !== '' && offered.length <= MAX_MODEL_NAME_LENGTH ? offered : value.id;\n rows.push({ id: value.id, name, group: 'paid' });\n }\n return rows;\n}\n\n/**\n * Discover the chat models an OpenAI-compatible endpoint advertises.\n *\n * @param openAiBaseURL Absolute HTTP(S) base URL without credentials/query/fragment.\n * @param key Bearer credential; trimmed once, never echoed or persisted here.\n * @param signal Caller cancellation, combined with the internal 20 s deadline.\n * @param fetcher Optional `fetch` replacement (tests, hosts with a custom transport).\n * @throws {ModelDiscoveryError} Fixed classification and fixed message for every failure.\n */\nexport async function fetchModelCatalog(openAiBaseURL: string, key: string, signal?: AbortSignal, fetcher?: typeof fetch): Promise<readonly CatalogModel[]> {\n let base: string;\n try { base = normalizeOpenAiBase(assertBaseURL(openAiBaseURL)); } catch { throw new ModelDiscoveryError('url'); }\n let credential: string;\n try { credential = safeSecret(key); } catch { throw new ModelDiscoveryError('credential'); }\n const request = fetcher ?? fetch;\n const deadline = combinedSignal(signal, DISCOVERY_TIMEOUT_MS);\n let response: Response;\n try {\n response = await request(`${base}/models`, {\n method: 'GET',\n headers: { ...attributionHeaders(), authorization: `Bearer ${credential}`, accept: 'application/json' },\n signal: deadline,\n redirect: 'error',\n });\n } catch {\n if (signal?.aborted) throw new ModelDiscoveryError('aborted');\n if (deadline.aborted) throw new ModelDiscoveryError('timeout');\n throw new ModelDiscoveryError('network');\n }\n if (!response.ok) {\n await response.body?.cancel().catch(() => undefined);\n throw new ModelDiscoveryError(statusKind(response.status), response.status);\n }\n return normalize(await boundedJson(response, signal, deadline));\n}\n", "// OpenDesign CoRouter \u2014 desktop login state and session resolution.\n//\n// Contract source: OpenDesign desktop daemon (`resources/app/prebundled/daemon/chunks/*.mjs`,\n// `configDir()` / `amrConfigPath()` / `readRawVelaControlApiContext()` / `readVelaProfileConfigSnapshot()`)\n// and `vela.exe` (profile struct tags). See docs/quota-evidence.md \u00A71.\n//\n// This module never prints, logs or echoes credential material. Every failure path\n// reports a *reason code*, never the offending text, so an unreadable or hostile\n// config can never leak its contents through an error message.\nimport { readFile as fsReadFile } from 'node:fs/promises';\nimport { homedir as osHomedir } from 'node:os';\nimport { join } from 'node:path';\nimport type { Session, SessionSource } from './quota.js';\nimport { record, safeSecret } from './util.js';\n\n/** Control-plane origin the desktop build ships with (open-design-config.json / daemon default). */\nexport const DEFAULT_API_URL = 'https://amr-api.open-design.ai';\n/** The one host this plugin is willing to send an account token to. */\nexport const API_HOST = 'amr-api.open-design.ai';\n\n/** Profiles the official client recognizes; anything else falls back to `prod`. */\nexport const DESKTOP_PROFILES = ['prod', 'test', 'feature-test', 'local'] as const;\nexport type DesktopProfile = (typeof DESKTOP_PROFILES)[number];\nexport const DEFAULT_PROFILE: DesktopProfile = 'prod';\n\n/** Reference names holding a console session cookie, read through the credential seam. */\nexport const COOKIE_ENV_REFS = ['OPEN_DESIGN_COOKIE', 'OPEN_DESIGN_SESSION'] as const;\n\n/**\n * Exactly one accepted origin. `apiUrl` comes from a file this plugin does not own, so an\n * edited or attacker-supplied value must never receive the account token: without this gate,\n * pointing `apiUrl` anywhere would exfiltrate the desktop `controlKey`. A sibling subdomain is\n * not accepted either \u2014 no widening \"just in case\" (`*.open-design.ai` would already be wrong).\n */\nexport function isOfficialApiUrl(raw: string): boolean {\n let url: URL;\n try { url = new URL(raw); } catch { return false; }\n if (url.protocol !== 'https:') return false;\n if (url.username || url.password) return false;\n if (url.search || url.hash) return false;\n if (url.pathname !== '/' && url.pathname !== '') return false;\n return url.hostname.toLowerCase() === API_HOST;\n}\n\n/** Canonical `https://host` form, or `undefined` when the value is not an official origin. */\nexport function normalizeApiUrl(raw: string | undefined): string | undefined {\n const value = typeof raw === 'string' ? raw.trim() : '';\n if (!value) return undefined;\n if (!isOfficialApiUrl(value)) return undefined;\n const url = new URL(value);\n return `https://${url.hostname.toLowerCase()}`;\n}\n\n/** Profile selection matches the client: `OPEN_DESIGN_AMR_PROFILE` wins over `VELA_PROFILE`. */\nexport function resolveProfile(env: NodeJS.ProcessEnv = process.env): DesktopProfile {\n const raw = (env.OPEN_DESIGN_AMR_PROFILE ?? env.VELA_PROFILE ?? '').trim();\n return (DESKTOP_PROFILES as readonly string[]).includes(raw) ? raw as DesktopProfile : DEFAULT_PROFILE;\n}\n\n/** `AMR_HOME` (with `~` / `~/x` expansion), else `<home>/.amr` \u2014 the client's `configDir()`. */\nexport function desktopConfigDir(env: NodeJS.ProcessEnv = process.env, home = osHomedir()): string {\n const raw = (env.AMR_HOME ?? '').trim();\n if (!raw) return join(home, '.amr');\n if (raw === '~') return home;\n if (raw.startsWith('~/') || raw.startsWith('~\\\\')) return join(home, raw.slice(2));\n return raw;\n}\n\n/** Full path of the desktop credential file. */\nexport function desktopConfigPath(env: NodeJS.ProcessEnv = process.env, home = osHomedir()): string {\n return join(desktopConfigDir(env, home), 'config.json');\n}\n\n/** What the desktop file says about one profile. Values are held in memory only. */\nexport interface DesktopCredential {\n profile: DesktopProfile;\n controlKey: string;\n /** Present only when the profile carries an official origin. */\n apiUrl?: string;\n plan?: string;\n /** `runtimeKey` present means the desktop considers itself signed in. */\n signedIn: boolean;\n}\n\nexport type DesktopRead =\n | { state: 'missing' }\n | { state: 'unreadable' }\n | { state: 'invalid' }\n | { state: 'incomplete'; profile: DesktopProfile }\n /** The profile's `apiUrl` is not the one accepted origin: never used, and never retried elsewhere. */\n | { state: 'unsafe-api-url'; profile: DesktopProfile }\n /** A non-`prod` profile: its token belongs to another environment, so it is not sent to prod. */\n | { state: 'unsupported-profile'; profile: DesktopProfile }\n | { state: 'credential'; credential: DesktopCredential };\n\n/**\n * Parse `config.json` text. Never throws and never returns the raw text, so callers can\n * treat a hostile file as \"absent\" without risking a leak. `state: 'invalid'` means the\n * JSON or its shape was not what the client writes.\n */\nexport function parseDesktopConfigText(text: string, profile: DesktopProfile = DEFAULT_PROFILE): DesktopRead {\n let parsed: unknown;\n try { parsed = JSON.parse(text); } catch { return { state: 'invalid' }; }\n if (!record(parsed)) return { state: 'invalid' };\n const profiles = parsed['profiles'];\n if (!record(profiles)) return { state: 'invalid' };\n const entry = profiles[profile];\n // A config for other profiles only is \"no credential here\", not \"invalid\".\n if (entry === undefined) return { state: 'incomplete', profile };\n if (!record(entry)) return { state: 'invalid' };\n const controlKey = typeof entry['controlKey'] === 'string' ? entry['controlKey'].trim() : '';\n const runtimeKey = typeof entry['runtimeKey'] === 'string' ? entry['runtimeKey'].trim() : '';\n const rawApiUrl = typeof entry['apiUrl'] === 'string' ? entry['apiUrl'].trim() : '';\n const user = record(entry['user']) ? entry['user'] : undefined;\n const plan = typeof user?.['plan'] === 'string' ? user['plan'].trim() : '';\n if (!controlKey) return { state: 'incomplete', profile };\n try { safeSecret(controlKey); } catch { return { state: 'invalid' }; }\n const apiUrl = normalizeApiUrl(rawApiUrl);\n // A stored origin that is not the accepted one is reported, not discarded: silently falling\n // back to the default host is exactly how one environment's token would end up at another\n // environment's endpoint.\n if (rawApiUrl && !apiUrl) return { state: 'unsafe-api-url', profile };\n // Only `prod` is supported. Sending another profile's token to the prod endpoint (or the\n // reverse) would mix accounts, so the mismatch stops here.\n if (profile !== DEFAULT_PROFILE) return { state: 'unsupported-profile', profile };\n return {\n state: 'credential',\n credential: {\n profile,\n controlKey,\n ...(apiUrl === undefined ? {} : { apiUrl }),\n ...(plan ? { plan } : {}),\n signedIn: runtimeKey.length > 0,\n },\n };\n}\n\nexport interface DesktopDeps {\n env?: NodeJS.ProcessEnv;\n home?: string;\n profile?: DesktopProfile;\n readFile?: (path: string) => Promise<string>;\n}\n\n/**\n * Read the desktop credential, distinguishing \"no desktop installed or signed out\"\n * (`missing` / `incomplete`) from \"there is a file but it cannot be used\"\n * (`unreadable` / `invalid`). The two must not be conflated: the first is normal for\n * users without the desktop app, the second deserves a different hint.\n */\nexport async function readDesktopCredential(deps: DesktopDeps = {}): Promise<DesktopRead> {\n const env = deps.env ?? process.env;\n const profile = deps.profile ?? resolveProfile(env);\n const path = desktopConfigPath(env, deps.home ?? osHomedir());\n const readFile = deps.readFile ?? ((file: string) => fsReadFile(file, 'utf8'));\n let text: string;\n try { text = await readFile(path); }\n catch (error) {\n const code = record(error) && typeof error['code'] === 'string' ? error['code'] : '';\n return code === 'ENOENT' || code === 'ENOTDIR' ? { state: 'missing' } : { state: 'unreadable' };\n }\n return parseDesktopConfigText(text, profile);\n}\n\n/** Cookie payload persisted through the credential seam as a `grant` record. */\nexport interface LoginGrant {\n cookie: string;\n /** Epoch ms; `0`/absent means the console declared no expiry. */\n expiresAt?: number;\n}\n\nexport type AuthSource = 'desktop' | 'login' | 'environment';\n\nexport interface AuthSession extends Session {\n source: SessionSource;\n via: AuthSource;\n apiUrl: string;\n /** Desktop profile name, when the session came from the desktop file. */\n profile?: string;\n plan?: string;\n}\n\nexport type AuthReason =\n | 'no-credential'\n | 'desktop-incomplete'\n | 'desktop-unreadable'\n | 'unsafe-api-url'\n | 'unsupported-profile';\n\nexport type AuthOutcome =\n | { state: 'ready'; session: AuthSession; warnings: AuthReason[] }\n | { state: 'need-login'; reason: AuthReason; warnings: AuthReason[] };\n\nexport interface AuthDeps extends DesktopDeps {\n /** Allow reading the desktop login state; `false` for users who only use this plugin's login. */\n useDesktop?: boolean;\n /** Read the persisted login grant (Host-owned credential store). */\n readGrant?: () => Promise<LoginGrant | undefined>;\n /** Resolve an environment-variable reference (Host-owned credential seam). */\n resolveRef?: (ref: string) => Promise<string | undefined>;\n now?: () => number;\n}\n\nfunction cookieHeader(raw: string): string | undefined {\n const value = raw.trim();\n if (!value || !value.includes('=')) return undefined;\n try { return safeSecret(value); } catch { return undefined; }\n}\n\n/** Desktop `controlKey` as a Bearer header (daemon evidence: `/api/v1/wallet/balance`). */\nexport function desktopSession(credential: DesktopCredential, apiUrl = credential.apiUrl ?? DEFAULT_API_URL): AuthSession {\n const base = normalizeApiUrl(apiUrl) ?? DEFAULT_API_URL;\n return {\n headers: { authorization: `Bearer ${safeSecret(credential.controlKey)}` },\n source: 'desktop',\n via: 'desktop',\n apiUrl: base,\n profile: credential.profile,\n ...(credential.plan ? { plan: credential.plan } : {}),\n };\n}\n\n/** A persisted or environment-supplied console cookie as a `cookie` header. */\nexport function cookieSession(cookie: string, source: SessionSource, apiUrl = DEFAULT_API_URL): AuthSession | undefined {\n const header = cookieHeader(cookie);\n if (!header) return undefined;\n return {\n headers: { cookie: header },\n source,\n via: source === 'environment' ? 'environment' : 'login',\n apiUrl: normalizeApiUrl(apiUrl) ?? DEFAULT_API_URL,\n };\n}\n\n/**\n * Resolve the session in the order the user asked for: **desktop first**, then the\n * cookie saved by this plugin's own login, then environment references.\n *\n * A desktop config whose `apiUrl` is not an official origin is *skipped*, not used: the\n * token must not travel to a host the plugin cannot vouch for. The skip is reported as a\n * warning so a UI can explain why the desktop session was ignored.\n */\nexport async function resolveSession(deps: AuthDeps = {}): Promise<AuthOutcome> {\n const env = deps.env ?? process.env;\n const warnings: AuthReason[] = [];\n const now = deps.now ?? Date.now;\n\n if (deps.useDesktop !== false) {\n const desktop = await readDesktopCredential(deps);\n if (desktop.state === 'credential') {\n const envApiUrl = (env.VELA_API_URL ?? '').trim();\n // An environment-supplied origin passes through the same single-host gate. A rejected\n // value means \"desktop off\", not \"use the token on the default host\": that substitution\n // is precisely the cross-environment leak this check exists to prevent.\n if (envApiUrl && !normalizeApiUrl(envApiUrl)) {\n warnings.push('unsafe-api-url');\n } else {\n return { state: 'ready', session: desktopSession(desktop.credential, envApiUrl || DEFAULT_API_URL), warnings };\n }\n } else if (desktop.state === 'unsafe-api-url') {\n warnings.push('unsafe-api-url');\n } else if (desktop.state === 'unsupported-profile') {\n warnings.push('unsupported-profile');\n } else if (desktop.state === 'incomplete') {\n warnings.push('desktop-incomplete');\n } else if (desktop.state === 'unreadable' || desktop.state === 'invalid') {\n warnings.push('desktop-unreadable');\n }\n }\n\n if (deps.readGrant) {\n let grant: LoginGrant | undefined;\n try { grant = await deps.readGrant(); } catch { grant = undefined; }\n const expiry = typeof grant?.expiresAt === 'number' && Number.isFinite(grant.expiresAt) ? grant.expiresAt : 0;\n if (grant && (expiry === 0 || expiry > now())) {\n const session = cookieSession(grant.cookie, 'login');\n if (session) return { state: 'ready', session, warnings };\n }\n }\n\n if (deps.resolveRef) {\n for (const ref of COOKIE_ENV_REFS) {\n let value: string | undefined;\n try { value = await deps.resolveRef(ref); } catch { value = undefined; }\n if (!value) continue;\n const session = cookieSession(value, 'environment');\n if (session) return { state: 'ready', session, warnings };\n }\n }\n\n return { state: 'need-login', reason: warnings[0] ?? 'no-credential', warnings };\n}\n\n/** Endpoint builders for a resolved origin, mirroring `quota.ts` for non-default hosts. */\nexport function endpoints(apiUrl: string) {\n const base = `${apiUrl}/api/v1`;\n return {\n base,\n current: `${base}/workspaces/current`,\n summary: `${base}/billing/summary`,\n usage: (workspaceId: string) => `${base}/workspaces/${encodeURIComponent(workspaceId)}/billing/coding-plan-usage`,\n };\n}\n", "// OpenDesign CoRouter \u2014 independent console login.\n//\n// Browser-lifecycle skeleton adapted from `dsh-subusage` 0.16.2 `lib/cookie-login.js` (MIT,\n// Copyright (c) 2026 KouzakiUmi). Flow and state machine are the same as that module: the\n// button that starts the login says \"\u767B\u5F55\u5E76\u4FDD\u5B58\u4F1A\u8BDD\", so a successful verification commits\n// without a second confirmation step.\n//\n// Guarantees this module owns:\n// - no credential ever appears in `status()` output;\n// - nothing is written while the attempt is in `launching`/`waiting`;\n// - `commit` is called at most once per attempt, and never after a terminal state;\n// - `commit` **success is the linearization point**: once the Host's atomic store has\n// accepted the write, a cancel that arrived earlier cannot retract it, and the attempt\n// reports `success`. A cancel that arrives before the store accepts the write aborts the\n// signal the store re-checks, and the attempt reports `cancelled`;\n// - the browser is closed on every terminal path.\nimport { randomUUID } from 'node:crypto';\nimport { sleep } from './util.js';\n\n/** Console origin and dashboard entry the official desktop uses. */\nexport const CONSOLE_ORIGIN = 'https://open-design.ai';\nexport const CONSOLE_DASHBOARD_URL = `${CONSOLE_ORIGIN}/cloud/dashboard`;\n/** The API host whose cookies matter; `context.cookies()` uses it to pick the right ones. */\nexport const API_COOKIE_URL = 'https://amr-api.open-design.ai/api/v1/workspaces/current';\n\nexport interface RawCookie { name?: string; value?: string; expires?: number }\n\n/** One usable console session: the exact `Cookie` header a browser would send. */\nexport interface ExtractedCookie { cookie: string; expiresAt: number }\n\n/**\n * Pick the session cookies by **URL scope**, never by name. The real cookie is\n * better-auth's `__Secure-better-auth.session_token` today, but it can be renamed at any\n * time and no third party can enumerate the alternatives; joining every unexpired cookie\n * that applies to the API URL reproduces exactly what the browser itself sends. Before\n * login completes this may also collect non-auth cookies (`od_attr`, `__cf_bm`), which is\n * harmless: such a bundle fails `verify` and is therefore never saved.\n */\nexport function extractConsoleSession(cookies: readonly RawCookie[], now = Date.now()): ExtractedCookie | null {\n const usable = cookies.filter(c =>\n typeof c.name === 'string' && c.name.length > 0 &&\n typeof c.value === 'string' && c.value.length > 0 &&\n (c.expires === undefined || c.expires === -1 || c.expires * 1000 > now));\n if (!usable.length) return null;\n const declared = usable\n .map(c => c.expires)\n .filter((expires): expires is number => typeof expires === 'number' && Number.isFinite(expires) && expires > 0);\n return {\n cookie: usable.map(c => `${c.name}=${c.value}`).join('; '),\n expiresAt: declared.length ? Math.min(...declared) * 1000 : 0,\n };\n}\n\nexport interface LoginSite {\n origin: string;\n loginUrl: string;\n cookieUrls: readonly string[];\n extract(cookies: readonly RawCookie[], now: number): ExtractedCookie | null;\n}\n\n/** Site parameters, overridable so a rebrand (for example a new console origin) needs no code fork. */\nexport function consoleSite(overrides: { origin?: string; loginUrl?: string; cookieUrls?: readonly string[] } = {}): LoginSite {\n const origin = overrides.origin ?? CONSOLE_ORIGIN;\n return {\n origin,\n loginUrl: overrides.loginUrl ?? (origin === CONSOLE_ORIGIN ? CONSOLE_DASHBOARD_URL : `${origin}/cloud/dashboard`),\n cookieUrls: overrides.cookieUrls ?? [API_COOKIE_URL],\n extract: extractConsoleSession,\n };\n}\n\nexport interface VerifyResult {\n /** Whether the account was read at all; a read-but-quota-unknown result still verifies. */\n balanceOk: boolean;\n /** Set when the quota endpoint failed; the cookie itself is still valid, so the host may still save it. */\n usageError?: { code: string } | undefined;\n /**\n * Caller-supplied context, echoed nowhere and used only for the success message. The Host\n * re-reads the real quota after commit, so these are never trusted as state.\n */\n coverage?: string | undefined;\n windows?: readonly unknown[] | undefined;\n}\n\n/** Host-supplied operations. No Host type is imported: the caller wires these. */\nexport interface LoginCallbacks {\n /** Snapshot the state a commit must not overwrite, keyed by the revision the caller saw. */\n capture(expectedRevision: string): unknown | Promise<unknown>;\n /** Prove the cookie works. Any throw means \"not usable yet\"; abort is a cancel. */\n verify(cookie: string, signal: AbortSignal): Promise<VerifyResult>;\n /**\n * Persist the verified cookie. The Host's store must run its write inside a mutex and call\n * `signal.throwIfAborted()` there, so a cancel that landed before the mutex was acquired\n * wins, and one that lands afterwards does not.\n *\n * `expiresAt` is the cookie bundle's earliest declared expiry in epoch ms, or `0` when the\n * console declared none (a session cookie). It is passed through so the Host can store it and\n * let `resolveSession` expire a stale grant proactively instead of waiting for a 401.\n */\n commit(cookie: string, captured: unknown, signal: AbortSignal, expiresAt: number): Promise<unknown>;\n}\n\n/**\n * Attempt phases, matching the shared wire contract (`LoginPhase` in `remote.ts`) exactly;\n * `success`/`cancelled`/`error` are terminal. The Host maps `status()` onto the wire type.\n */\nexport type LoginPhase = 'idle' | 'launching' | 'waiting' | 'verifying' | 'success' | 'cancelled' | 'error';\n\nexport interface LoginStatus {\n jobId: string | null;\n state: LoginPhase;\n startedAt?: string;\n finishedAt?: string;\n message?: string;\n errorCode?: string;\n /** The page could not be opened; the UI may offer the URL instead. */\n browserOpenFailed?: boolean;\n}\n\nexport interface LoginStartRequest { expectedRevision: string }\nexport interface LoginJobRequest { jobId: string }\n\n/** Minimal structural browser surface, so tests need no Playwright and Host wiring stays loose. */\nexport interface BrowserLike {\n on?(event: 'disconnected', listener: () => void): void;\n newContext(): Promise<ContextLike>;\n close(): Promise<void>;\n}\nexport interface ContextLike {\n newPage(): Promise<PageLike>;\n cookies(urls: readonly string[]): Promise<readonly RawCookie[]>;\n}\nexport interface PageLike {\n on?(event: 'close', listener: () => void): void;\n goto(url: string, options?: { waitUntil?: string; timeout?: number }): Promise<unknown>;\n}\n\nexport type Launcher = (signal: AbortSignal) => Promise<BrowserLike | null>;\n\nexport interface LoginOptions {\n site?: LoginSite;\n /** Total life of one login attempt. Default five minutes. */\n timeoutMs?: number;\n pollMs?: number;\n now?: () => number;\n /** Injected browser launcher; the default uses `playwright-core` and a real Chrome window. */\n launch?: Launcher;\n /** Injected sleep, for tests. */\n delay?: (ms: number, signal: AbortSignal) => Promise<void>;\n}\n\nexport class LoginError extends Error {\n constructor(readonly code: 'opendesign/login-state' | 'opendesign/login-disposed' | 'opendesign/login-capture') {\n super(code === 'opendesign/login-state' ? '\u767B\u5F55\u4EFB\u52A1\u4E0D\u5B58\u5728\u6216\u72B6\u6001\u5DF2\u6539\u53D8' : code === 'opendesign/login-disposed' ? '\u767B\u5F55\u670D\u52A1\u5DF2\u5378\u8F7D' : '\u65E0\u6CD5\u6355\u83B7\u5F53\u524D\u8BBE\u7F6E\u72B6\u6001\uFF0C\u767B\u5F55\u5DF2\u53D6\u6D88');\n }\n}\n\nconst ACTIVE = new Set<LoginPhase>(['launching', 'waiting', 'verifying']);\nconst DEFAULT_TIMEOUT_MS = 300_000;\nconst DEFAULT_POLL_MS = 1_000;\n/** Codes that mean \"the environment changed under us\": retrying would only repeat the failure. */\nconst FATAL_COMMIT_CODES = new Set(['opendesign/revision-conflict', 'opendesign/invalid-request', 'opendesign/config', 'opendesign/login-disposed']);\n\n/**\n * Chrome flags that let a *human* pass the console's bot check. The console looks at\n * `navigator.webdriver` when its Cloudflare challenge is submitted; `headless: false` alone\n * leaves it `true`, and this blink switch is what the official Playwright browser tool\n * appends for chromium. This is not a challenge bypass \u2014 the user still solves it \u2014 it only\n * avoids announcing automation before they can act. `ignoreDefaultArgs` is a no-op on\n * 1.63.0 and stays for forward compatibility.\n */\nexport const CHROME_LAUNCH_OPTIONS = {\n channel: 'chrome',\n headless: false,\n ignoreDefaultArgs: ['--enable-automation'],\n args: ['--disable-blink-features=AutomationControlled'],\n} as const;\n\ninterface Job {\n readonly id: string;\n readonly startedAt: string;\n readonly controller: AbortController;\n readonly expectedRevision: string;\n readonly status: LoginStatus;\n timer?: NodeJS.Timeout | undefined;\n browser?: BrowserLike | undefined;\n /** In memory only; never copied into `status`. */\n secret?: ExtractedCookie | undefined;\n captured: unknown;\n capturedAt?: Promise<unknown> | undefined;\n verifying: boolean;\n committing: boolean;\n /** A cancel arrived while `commit` was in flight: only the store's own abort check decides. */\n cancelRequested: boolean;\n cancellationMessage?: string;\n}\n\nexport class ConsoleLogin {\n private job: Job | null = null;\n private disposed = false;\n private readonly callbacks: LoginCallbacks;\n private readonly options: LoginOptions;\n private readonly now: () => number;\n private readonly delay: (ms: number, signal: AbortSignal) => Promise<void>;\n\n constructor(callbacks: LoginCallbacks, options: LoginOptions = {}) {\n this.callbacks = callbacks;\n this.options = options;\n this.now = options.now ?? Date.now;\n this.delay = options.delay ?? sleep;\n }\n\n /** Idempotent, credential-free view of the current attempt. */\n status(): LoginStatus {\n if (!this.job) return { jobId: null, state: 'idle' };\n // Explicit allowlist: an added field cannot start leaking a secret by accident.\n const s = this.job.status;\n return {\n jobId: s.jobId,\n state: s.state,\n ...(s.startedAt ? { startedAt: s.startedAt } : {}),\n ...(s.finishedAt ? { finishedAt: s.finishedAt } : {}),\n ...(s.message ? { message: s.message } : {}),\n ...(s.errorCode ? { errorCode: s.errorCode } : {}),\n ...(s.browserOpenFailed ? { browserOpenFailed: true } : {}),\n };\n }\n\n /**\n * Queue one attempt and return immediately: the RPC that starts a login must not wait on a\n * browser window or on a human. Re-entrant calls while an attempt is live return that\n * attempt's status instead of opening a second browser.\n */\n start(request: LoginStartRequest): LoginStatus {\n if (this.disposed) throw new LoginError('opendesign/login-disposed');\n if (this.job && ACTIVE.has(this.job.status.state)) return this.status();\n const job: Job = {\n id: randomUUID(),\n startedAt: new Date(this.now()).toISOString(),\n controller: new AbortController(),\n expectedRevision: request.expectedRevision,\n status: { jobId: '', state: 'launching', message: '\u6B63\u5728\u6253\u5F00\u4E34\u65F6 Chrome \u767B\u5F55\u7A97\u53E3' },\n captured: undefined,\n capturedAt: undefined,\n verifying: false,\n committing: false,\n cancelRequested: false,\n };\n job.status.jobId = job.id;\n job.status.startedAt = job.startedAt;\n this.job = job;\n job.timer = setTimeout(() => this.requestCancellation(job, '\u767B\u5F55\u5DF2\u8D85\u8FC7\u4E94\u5206\u949F\uFF0C\u8BF7\u91CD\u65B0\u5F00\u59CB'), this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n job.timer.unref?.();\n // The capture runs before the browser opens, so a revision conflict is discovered while\n // nothing is on screen yet.\n job.capturedAt = Promise.resolve()\n .then(() => this.callbacks.capture(job.expectedRevision))\n .then(captured => { job.captured = captured; return captured; });\n void job.capturedAt\n .then(() => this.run(job))\n .catch(error => { if (this.alive(job)) this.finish(job, 'error', '\u767B\u5F55\u65E0\u6CD5\u5F00\u59CB\uFF0C\u8BF7\u91CD\u8BD5', errorCode(error) ?? 'opendesign/login-capture'); });\n return this.status();\n }\n\n /**\n * Abandon the attempt. While `commit` is in flight this only aborts the signal and records\n * the request: the Host's atomic store decides, because the commit is the linearization\n * point. A cancel that wins that race reports `cancelled`; one that loses reports `success`\n * and the cookie really is stored.\n */\n cancel(request: LoginJobRequest): LoginStatus {\n const job = this.job;\n if (!job || job.status.jobId !== request.jobId) return this.status();\n this.requestCancellation(job, '\u767B\u5F55\u5DF2\u53D6\u6D88\uFF0C\u672A\u4FDD\u5B58 Cookie');\n return this.status();\n }\n\n /** Plugin teardown: abort the attempt and close the browser. */\n dispose(): void {\n const job = this.job;\n if (job) this.requestCancellation(job, '\u670D\u52A1\u5DF2\u5378\u8F7D\uFF0C\u767B\u5F55\u5DF2\u53D6\u6D88');\n this.disposed = true;\n }\n\n /** Every cancellation source must let an in-flight atomic store decide the final outcome. */\n private requestCancellation(job: Job, message: string): void {\n if (this.job !== job || !ACTIVE.has(job.status.state)) return;\n if (!job.committing) {\n this.finish(job, 'cancelled', message);\n return;\n }\n if (!job.cancelRequested) {\n job.cancellationMessage = message;\n job.status.message = '\u6B63\u5728\u786E\u8BA4\u4F1A\u8BDD\u4FDD\u5B58\u7ED3\u679C';\n }\n job.cancelRequested = true;\n this.stopTimer(job);\n job.controller.abort();\n void this.close(job);\n }\n\n private alive(job: Job): boolean {\n if (this.disposed || this.job !== job) return false;\n if (job.controller.signal.aborted && !job.committing) return false;\n return job.status.state !== 'success' && job.status.state !== 'cancelled' && job.status.state !== 'error';\n }\n\n private stopTimer(job: Job): void {\n if (job.timer) { clearTimeout(job.timer); job.timer = undefined; }\n }\n\n private async close(job: Job): Promise<void> {\n const browser = job.browser;\n job.browser = undefined;\n try { await browser?.close(); } catch { /* closing a dead browser is not an error worth surfacing */ }\n }\n\n private finish(job: Job, state: 'success' | 'cancelled' | 'error', message: string, errorCode?: string): void {\n if (this.job !== job) return;\n if (job.status.state === 'success' || job.status.state === 'cancelled' || job.status.state === 'error') return;\n job.status.state = state;\n job.status.finishedAt = new Date(this.now()).toISOString();\n job.status.message = message;\n if (errorCode) job.status.errorCode = errorCode;\n job.secret = undefined;\n this.stopTimer(job);\n job.controller.abort();\n void this.close(job);\n }\n\n private async resolveBrowser(job: Job): Promise<BrowserLike | null> {\n if (!this.alive(job)) return null;\n const launch = this.options.launch ?? defaultLaunch;\n const browser = await launch(job.controller.signal);\n if (!browser) return null;\n job.browser = browser;\n browser.on?.('disconnected', () => this.requestCancellation(job, '\u767B\u5F55\u7A97\u53E3\u5DF2\u5173\u95ED\uFF0C\u672A\u4FDD\u5B58 Cookie'));\n return browser;\n }\n\n private async run(job: Job): Promise<void> {\n const site = this.options.site ?? consoleSite();\n const browser = await this.resolveBrowser(job);\n if (!browser) return;\n if (!this.alive(job)) { await this.close(job); return; }\n const context = await browser.newContext();\n if (!this.alive(job)) { await this.close(job); return; }\n const page = await context.newPage();\n page.on?.('close', () => this.requestCancellation(job, '\u767B\u5F55\u7A97\u53E3\u5DF2\u5173\u95ED\uFF0C\u672A\u4FDD\u5B58 Cookie'));\n if (!this.alive(job)) { await this.close(job); return; }\n // Navigate to the page that actually triggers sign-in; the site home is only a fallback\n // for the times the dashboard is down, so the user can still navigate somewhere useful.\n try { await page.goto(site.loginUrl, { waitUntil: 'domcontentloaded', timeout: 30_000 }); }\n catch {\n if (!this.alive(job)) return;\n try { await page.goto(site.origin, { waitUntil: 'domcontentloaded', timeout: 30_000 }); }\n catch { job.status.browserOpenFailed = true; }\n }\n if (!this.alive(job)) return;\n job.status.state = 'waiting';\n job.status.message = '\u8BF7\u5728\u5B98\u65B9\u7A97\u53E3\u81EA\u884C\u5B8C\u6210\u767B\u5F55\uFF1B\u8D26\u6237\u9A8C\u8BC1\u901A\u8FC7\u540E\u4FDD\u5B58\uFF0C\u989D\u5EA6\u72B6\u6001\u53E6\u884C\u663E\u793A';\n let nextAttempt = 0;\n let failures = 0;\n const pollMs = this.options.pollMs ?? DEFAULT_POLL_MS;\n while (this.alive(job)) {\n if (!job.verifying) {\n const session = site.extract(await context.cookies(site.cookieUrls), this.now());\n if (!this.alive(job)) return;\n if (session && this.now() >= nextAttempt) {\n job.verifying = true;\n job.status.state = 'verifying';\n job.status.message = '\u6B63\u5728\u9A8C\u8BC1\u767B\u5F55\u548C\u8BA2\u9605\u989D\u5EA6\uFF08\u5C1A\u672A\u4FDD\u5B58\uFF09';\n try {\n const verified = await this.callbacks.verify(session.cookie, job.controller.signal);\n if (!this.alive(job)) return;\n if (verified.usageError || !verified.balanceOk) {\n // \"Logged in but the quota is not fully readable\" is not a failed login: the\n // cookie is real. Keep waiting and re-check, but do not save yet.\n job.status.state = 'waiting';\n job.status.message = '\u5DF2\u8BFB\u53D6\u8D26\u6237\uFF0C\u4F46\u8BA2\u9605\u989D\u5EA6\u5C1A\u672A\u5B8C\u6574\u9A8C\u8BC1\uFF1B\u5C1A\u672A\u4FDD\u5B58\uFF0C\u8BF7\u786E\u8BA4\u5957\u9910\u6216\u7EE7\u7EED\u767B\u5F55';\n nextAttempt = this.now() + 15_000;\n } else {\n const outcome = await this.commit(job, session);\n if (outcome !== 'retry') return;\n // The store rejected the write transiently: back off and verify again rather than\n // reporting success that did not happen.\n failures += 1;\n nextAttempt = this.now() + Math.max(5_000, Math.min(60_000, 2_000 * 2 ** Math.min(failures, 5)));\n }\n } catch (error) {\n if (!this.alive(job)) return;\n failures += 1;\n nextAttempt = this.now() + Math.max(5_000, Math.min(60_000, 2_000 * 2 ** Math.min(failures, 5)), retryAfterMs(error));\n job.status.state = 'waiting';\n job.status.message = errorCode(error) === 'opendesign/auth'\n ? '\u767B\u5F55\u5C1A\u672A\u751F\u6548\uFF0C\u8BF7\u7EE7\u7EED\u5728\u5B98\u65B9\u7A97\u53E3\u5B8C\u6210\u767B\u5F55\uFF1B\u672A\u4FDD\u5B58'\n : '\u989D\u5EA6\u9A8C\u8BC1\u6682\u672A\u6210\u529F\uFF0C\u5C06\u9650\u9891\u91CD\u8BD5\uFF1B\u672A\u4FDD\u5B58';\n } finally {\n job.verifying = false;\n }\n }\n }\n await this.delay(pollMs, job.controller.signal);\n }\n }\n\n /**\n * Persist the verified session; `commit` resolving is the linearization point. Returns\n * `retry` when the store rejected the write transiently, so the caller decides when to try\n * again instead of claiming a success that did not happen.\n */\n private async commit(job: Job, session: ExtractedCookie): Promise<'success' | 'cancelled' | 'error' | 'retry'> {\n if (job.committing || !this.alive(job)) return 'cancelled';\n job.committing = true;\n job.status.state = 'verifying';\n job.status.message = '\u767B\u5F55\u5DF2\u9A8C\u8BC1\uFF0C\u6B63\u5728\u4FDD\u5B58\u4F1A\u8BDD';\n try {\n await this.callbacks.commit(session.cookie, job.captured, job.controller.signal, session.expiresAt);\n job.committing = false;\n // The store accepted the write. A cancel that arrived earlier cannot retract it, so the\n // honest report is success \u2014 this is the linearization boundary.\n this.finish(job, 'success', '\u767B\u5F55\u53CA\u8BA2\u9605\u989D\u5EA6\u5DF2\u9A8C\u8BC1\uFF0CCookie \u5DF2\u4FDD\u5B58');\n return 'success';\n } catch (error) {\n job.committing = false;\n if (job.cancelRequested || job.controller.signal.aborted) {\n this.finish(job, 'cancelled', job.cancellationMessage ?? '\u767B\u5F55\u5DF2\u53D6\u6D88\uFF0C\u672A\u4FDD\u5B58 Cookie');\n return 'cancelled';\n }\n if (FATAL_COMMIT_CODES.has(errorCode(error) ?? '')) {\n this.finish(job, 'error', '\u8BBE\u7F6E\u5DF2\u6539\u53D8\u6216\u65E0\u6CD5\u4FDD\u5B58\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\u540E\u91CD\u8BD5', errorCode(error));\n return 'error';\n }\n job.status.state = 'waiting';\n job.status.message = '\u767B\u5F55\u5DF2\u9A8C\u8BC1\uFF0C\u4F46\u4FDD\u5B58\u6682\u672A\u6210\u529F\uFF0C\u5C06\u9650\u9891\u91CD\u8BD5\uFF1B\u5C1A\u672A\u4FDD\u5B58';\n return 'retry';\n }\n }\n}\n\nfunction errorCode(error: unknown): string | undefined {\n if (error && typeof error === 'object' && 'code' in error && typeof (error as { code?: unknown }).code === 'string') return (error as { code: string }).code;\n return undefined;\n}\n\nfunction retryAfterMs(error: unknown): number {\n if (!error || typeof error !== 'object') return 0;\n const details = (error as { details?: unknown }).details;\n if (!details || typeof details !== 'object') return 0;\n const value = (details as { retryAfterMs?: unknown }).retryAfterMs;\n return typeof value === 'number' && Number.isFinite(value) && value > 0 ? Math.min(300_000, value) : 0;\n}\n\n/** Default launcher: a real, visible Chrome via `playwright-core` (a declared dependency). */\nasync function defaultLaunch(signal: AbortSignal): Promise<BrowserLike | null> {\n if (signal.aborted) return null;\n const { chromium } = await import('playwright-core');\n if (signal.aborted) return null;\n return await chromium.launch({\n channel: CHROME_LAUNCH_OPTIONS.channel,\n headless: CHROME_LAUNCH_OPTIONS.headless,\n // Copied so Playwright, which wants mutable arrays, cannot freeze on the readonly literals.\n ignoreDefaultArgs: [...CHROME_LAUNCH_OPTIONS.ignoreDefaultArgs],\n args: [...CHROME_LAUNCH_OPTIONS.args],\n }) as unknown as BrowserLike;\n}\n", "// OpenDesign normalization and independent-pool degradation adapted from dsh-subusage 0.16.2 (MIT).\nimport { attributionHeaders } from '@deepseek-ai/dsh-llm';\nimport { record, combinedSignal } from './util.js';\n\nexport const API_BASE = 'https://amr-api.open-design.ai/api/v1';\nexport const CURRENT_URL = `${API_BASE}/workspaces/current`;\nexport const SUMMARY_URL = `${API_BASE}/billing/summary`;\nexport const usageUrl = (workspace: string) => `${API_BASE}/workspaces/${encodeURIComponent(workspace)}/billing/coding-plan-usage`;\nexport type SessionSource = 'desktop' | 'login' | 'environment';\nexport interface Session { headers: Record<string, string>; source: SessionSource }\nexport interface QuotaWindow {\n durationSeconds: number; used: number; limit: number; remaining?: number; percent: number; resetsAt?: string;\n /** Window start as reported by coding-plan-usage (ISO-8601); never derived from the reset time. */\n windowStart?: string;\n /** Service-side window policy (`activity_triggered`, `anchored_recurring`, ...), when reported. */\n resetMode?: string;\n}\nexport interface QuotaSnapshot {\n state: 'ok' | 'partial' | 'need-login' | 'error';\n source?: SessionSource;\n updatedAt: string;\n tier?: string;\n eligible?: boolean;\n windows: QuotaWindow[];\n balances: { subscriptionUsd?: number; rechargeUsd?: number; totalUsd?: number };\n /**\n * Billing-period boundaries of the subscription pool (ISO-8601), from\n * `billing/summary`'s `subscriptionCurrentPeriodStart/End`. `End` is when the\n * plan model credits refresh \u2014 distinct from a rolling window's `resetsAt`.\n */\n subscriptionPeriodStart?: string;\n subscriptionPeriodEnd?: string;\n /** Next client-side read, owned by the host cache policy; this module never invents it. */\n nextRefreshAt?: string;\n /** A failed non-auth refresh retained the previous successful readings. */\n stale?: boolean;\n /** Consecutive failed automatic reads; manual refresh starts a new bounded sequence. */\n refreshFailures?: number;\n autoRefreshPaused?: boolean;\n note?: string;\n}\nexport class ConsoleError extends Error {\n constructor(readonly kind: 'auth' | 'permission' | 'network' | 'response' | 'rate-limit', readonly status?: number) {\n super(kind === 'auth' ? 'OpenDesign \u767B\u5F55\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55' : kind === 'permission' ? 'OpenDesign \u5F53\u524D\u767B\u5F55\u6001\u65E0\u6743\u8BFB\u53D6\u8BE5\u989D\u5EA6\u5C42' : kind === 'rate-limit' ? 'OpenDesign \u989D\u5EA6\u63A5\u53E3\u9650\u6D41\uFF0C\u8BF7\u7A0D\u540E\u5237\u65B0' : kind === 'response' ? 'OpenDesign \u989D\u5EA6\u63A5\u53E3\u8FD4\u56DE\u683C\u5F0F\u53D1\u751F\u53D8\u5316' : 'OpenDesign \u989D\u5EA6\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6');\n }\n}\nexport async function consoleJson(url: string, session: Session, signal?: AbortSignal, fetcher = fetch): Promise<unknown> {\n let response: Response;\n try {\n response = await fetcher(url, { headers: { ...attributionHeaders(), accept: 'application/json', ...session.headers }, signal: combinedSignal(signal, 20000), redirect: 'error' });\n } catch { throw new ConsoleError('network'); }\n if (response.status === 401 || response.status === 403) { await response.body?.cancel(); throw new ConsoleError(response.status === 401 ? 'auth' : 'permission', response.status); }\n if (!response.ok) { await response.body?.cancel(); throw new ConsoleError(response.status === 429 ? 'rate-limit' : 'network', response.status); }\n // Console responses are small; reject unexpected HTML/downloads without echoing it.\n const reader = response.body?.getReader();\n if (!reader) throw new ConsoleError('response');\n let size = 0, raw = '';\n const decoder = new TextDecoder();\n try {\n while (true) {\n const chunk = await reader.read();\n if (chunk.done) break;\n size += chunk.value.byteLength;\n if (size > 2 * 1024 * 1024) throw new ConsoleError('response');\n raw += decoder.decode(chunk.value, { stream: true });\n }\n raw += decoder.decode();\n } finally { await reader.cancel().catch(() => undefined); reader.releaseLock(); }\n let body: unknown;\n try { body = JSON.parse(raw); } catch { throw new ConsoleError('response'); }\n if (record(body) && (body.code === 401 || body.code === '401')) throw new ConsoleError('auth', 401);\n if (record(body) && (body.code === 403 || body.code === '403')) throw new ConsoleError('permission', 403);\n return body;\n}\nfunction number(value: unknown, negative = false): number | undefined {\n const n = typeof value === 'number' ? value : typeof value === 'string' && /^-?\\d+(\\.\\d+)?$/u.test(value.trim()) ? Number(value) : NaN;\n return Number.isFinite(n) && (negative || n >= 0) ? n : undefined;\n}\n/** Normalize a reported timestamp to ISO-8601; anything unparsable stays unknown. */\nfunction iso(value: unknown): string | undefined {\n return typeof value === 'string' && Number.isFinite(Date.parse(value)) ? new Date(value).toISOString() : undefined;\n}\nexport function normalizeQuota(body: unknown, summary?: unknown): Pick<QuotaSnapshot, 'windows' | 'balances' | 'tier' | 'eligible' | 'subscriptionPeriodStart' | 'subscriptionPeriodEnd'> {\n if (!record(body) || !(typeof body.eligible === 'boolean' || typeof body.tier === 'string' || body.tier === null || Array.isArray(body.windows))) throw new ConsoleError('response');\n const windows: QuotaWindow[] = [];\n for (const row of Array.isArray(body.windows) ? body.windows : []) {\n if (!record(row)) continue;\n const seconds = number(row.durationSeconds), used = number(row.usedCredits), limit = number(row.limitCredits), remaining = number(row.remainingCredits);\n if (seconds === undefined || seconds <= 0 || used === undefined || limit === undefined || limit <= 0) continue;\n const resetsAt = iso(row.resetsAt), windowStart = iso(row.windowStart);\n const resetMode = typeof row.resetMode === 'string' && row.resetMode.trim() ? row.resetMode.trim() : undefined;\n windows.push({ durationSeconds: seconds, used, limit, percent: Math.min(100, used / limit * 100), ...(remaining === undefined ? {} : { remaining }), ...(resetsAt === undefined ? {} : { resetsAt }), ...(windowStart === undefined ? {} : { windowStart }), ...(resetMode === undefined ? {} : { resetMode }) });\n }\n const membershipTier = record(summary) && typeof summary.membershipTier === 'string' ? summary.membershipTier.trim() : '';\n const tier = typeof body.tier === 'string' ? body.tier.trim() : body.tier === undefined && body.eligible !== false ? membershipTier : '';\n const eligible = typeof body.eligible === 'boolean' ? body.eligible : body.tier === null ? false : undefined;\n return { windows, balances: normalizeBalances(summary), ...normalizeSubscription(summary), ...(tier ? { tier } : {}), ...(eligible === undefined ? {} : { eligible }) };\n}\n/** Billing period of the subscription pool; absent fields stay unknown, never derived. */\nexport function normalizeSubscription(summary: unknown): Pick<QuotaSnapshot, 'subscriptionPeriodStart' | 'subscriptionPeriodEnd'> {\n if (!record(summary)) return {};\n const start = iso(summary.subscriptionCurrentPeriodStart), end = iso(summary.subscriptionCurrentPeriodEnd);\n return { ...(start === undefined ? {} : { subscriptionPeriodStart: start }), ...(end === undefined ? {} : { subscriptionPeriodEnd: end }) };\n}\nexport function normalizeBalances(summary: unknown): QuotaSnapshot['balances'] {\n if (!record(summary)) return {};\n const perUsd = number(summary.creditsPerUsd), balances = record(summary.balances) ? summary.balances : {};\n const subscription = number(balances.subscriptionCredits), recharge = number(balances.rechargeCredits), total = number(balances.totalAvailableCredits, true);\n const divisor = perUsd !== undefined && perUsd > 0 ? perUsd : undefined;\n const totalUsd = number(summary.balanceUsd, true) ?? number(summary.totalAvailableCreditsUsd, true) ?? (divisor !== undefined && total !== undefined ? total / divisor : undefined);\n return { ...(divisor !== undefined && subscription !== undefined ? { subscriptionUsd: subscription / divisor } : {}), ...(divisor !== undefined && recharge !== undefined ? { rechargeUsd: recharge / divisor } : {}), ...(totalUsd !== undefined ? { totalUsd } : {}) };\n}\nexport async function readQuota(session: Session, signal?: AbortSignal, fetcher = fetch): Promise<QuotaSnapshot> {\n const current = await consoleJson(CURRENT_URL, session, signal, fetcher);\n if (!record(current) || typeof current.workspaceId !== 'string' || !/^[A-Za-z0-9_-]{1,64}$/u.test(current.workspaceId)) throw new ConsoleError('response');\n const personal = current.workspaceType === 'personal';\n const [usage, billing] = await Promise.allSettled([\n consoleJson(usageUrl(current.workspaceId), session, signal, fetcher),\n personal ? consoleJson(SUMMARY_URL, session, signal, fetcher) : Promise.resolve(undefined),\n ]);\n // Never hide an authentication failure behind success from the other pool.\n for (const item of [usage, billing]) if (item.status === 'rejected' && item.reason instanceof ConsoleError && item.reason.kind === 'auth') throw item.reason;\n const summary = billing.status === 'fulfilled' ? billing.value : undefined;\n const common = { source: session.source, updatedAt: new Date().toISOString() };\n let normalized: ReturnType<typeof normalizeQuota>;\n try {\n if (usage.status === 'rejected') throw usage.reason;\n normalized = normalizeQuota(usage.value, summary);\n } catch (error) {\n const balances = normalizeBalances(summary);\n if (!Object.keys(balances).length) throw error;\n return { ...common, state: 'partial', windows: [], balances, ...normalizeSubscription(summary), note: '\u94B1\u5305\u5DF2\u8BFB\u53D6\uFF1B\u5957\u9910\u8D60\u9001\u989D\u5EA6\u6682\u4E0D\u53EF\u786E\u8BA4' };\n }\n const missingWindows = normalized.eligible !== false && !normalized.windows.length;\n const noSubscription = normalized.eligible === false && !normalized.windows.length;\n const missingBalances = personal && Object.keys(normalized.balances).length < 3;\n const partial = missingWindows || missingBalances || !personal;\n const note = !personal ? '\u56E2\u961F\u6216\u672A\u77E5\u5DE5\u4F5C\u533A\uFF1A\u8D26\u53F7\u94B1\u5305\u53E3\u5F84\u672A\u6838\u5B9E\uFF0C\u6682\u4E0D\u663E\u793A'\n : missingWindows ? '\u5957\u9910\u989D\u5EA6\u7A97\u53E3\u6682\u4E0D\u53EF\u786E\u8BA4'\n : noSubscription ? '\u8BE5\u8D26\u53F7\u6CA1\u6709 Design Plan \u8BA2\u9605\uFF1B\u94B1\u5305\u4F59\u989D\u7167\u5E38\u663E\u793A'\n : missingBalances ? '\u90E8\u5206\u94B1\u5305\u4F59\u989D\u6682\u4E0D\u53EF\u786E\u8BA4' : undefined;\n return { ...common, ...normalized, state: partial ? 'partial' : 'ok', ...(note === undefined ? {} : { note }) };\n}\n", "import { execFile } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { isAbsolute, join } from 'node:path';\nimport type { AuthSession } from './auth.js';\nimport { normalizeQuota, normalizeBalances, consoleJson, ConsoleError, type QuotaSnapshot } from './quota.js';\nimport { record, combinedSignal } from './util.js';\n\nexport type VelaRunner = (args: readonly string[], signal: AbortSignal, profile?: string) => Promise<unknown>;\nexport function locateVela(env: NodeJS.ProcessEnv = process.env, platform = process.platform): string | undefined {\n const explicit = env.OPENDESIGN_VELA_PATH?.trim();\n if (explicit && isAbsolute(explicit) && existsSync(explicit)) return explicit;\n if (platform !== 'win32' || !env.LOCALAPPDATA) return;\n const path = join(env.LOCALAPPDATA, 'Programs', 'Open Design', 'resources', 'open-design', 'bin', 'vela.exe');\n return existsSync(path) ? path : undefined;\n}\n/** Read-only official CLI, fixed argv and bounded output; stderr is never projected. */\nexport const runVela: VelaRunner = (args, signal, profile) => new Promise((resolve, reject) => {\n const binary = locateVela();\n if (!binary) return reject(new ConsoleError('network'));\n execFile(binary, [...args], { timeout: 8000, maxBuffer: 2 * 1024 * 1024, windowsHide: true, signal, encoding: 'utf8', env: { ...process.env, ...(profile ? { VELA_PROFILE: profile, OPEN_DESIGN_AMR_PROFILE: profile } : {}) } }, (error, stdout) => {\n if (error) return reject(new ConsoleError('network'));\n try { resolve(JSON.parse(stdout)); } catch { reject(new ConsoleError('response')); }\n });\n});\n/** Desktop tokens can have narrower scopes than console cookies; never invent an HTTP funding-check. */\nexport async function readDesktopQuota(session: AuthSession, signal?: AbortSignal, runner: VelaRunner = runVela, fetcher = fetch): Promise<QuotaSnapshot> {\n const deadline = combinedSignal(signal, 18000);\n const cli = (async () => {\n const workspace = await runner(['team-projects', 'list'], deadline, session.profile);\n if (!record(workspace) || typeof workspace.workspaceId !== 'string' || !/^[A-Za-z0-9_-]{1,64}$/u.test(workspace.workspaceId)) throw new ConsoleError('response');\n const funding = await runner(['billing', 'funding-check', '--workspace-id', workspace.workspaceId, '--format', 'json'], deadline, session.profile);\n if (!record(funding) || !record(funding.codingPlan)) throw new ConsoleError('response');\n // `generatedAt` is the server-side reading time; only an ISO value is kept.\n const generatedAt = typeof funding.generatedAt === 'string' && Number.isFinite(Date.parse(funding.generatedAt)) ? new Date(funding.generatedAt).toISOString() : undefined;\n return { ...normalizeQuota(funding.codingPlan), ...(typeof funding.balanceUsd === 'string' ? { balance: funding.balanceUsd } : {}), ...(generatedAt === undefined ? {} : { generatedAt }) };\n })();\n const [wallet, funding] = await Promise.allSettled([\n consoleJson(`${session.apiUrl}/api/v1/wallet/balance`, session, deadline, fetcher),\n cli,\n ]);\n // An expired wallet credential is not a scope limitation, even if the CLI still has data.\n if (wallet.status === 'rejected' && wallet.reason instanceof ConsoleError && wallet.reason.kind === 'auth') throw wallet.reason;\n const walletBalances = wallet.status === 'fulfilled' ? normalizeBalances(wallet.value) : {};\n const cliBalances = funding.status === 'fulfilled' && 'balance' in funding.value ? normalizeBalances({ balanceUsd: funding.value.balance }) : {};\n const windows = funding.status === 'fulfilled' ? funding.value.windows : [];\n const balances = { ...cliBalances, ...walletBalances };\n const eligible = funding.status === 'fulfilled' ? funding.value.eligible : undefined;\n // A recognised `eligible: false` with no windows is a definite answer (\"no Design Plan\"), not a\n // failed read: it must not be thrown away, nor turned into a fabricated 0% window.\n const noSubscription = funding.status === 'fulfilled' && eligible === false && windows.length === 0;\n if (!windows.length && !Object.keys(balances).length && !noSubscription) {\n if (wallet.status === 'rejected' && wallet.reason instanceof ConsoleError && (wallet.reason.kind === 'auth' || wallet.reason.kind === 'permission')) throw wallet.reason;\n throw new ConsoleError('network');\n }\n const tier = (funding.status === 'fulfilled' ? funding.value.tier : undefined) ?? session.plan;\n const updatedAt = (funding.status === 'fulfilled' && funding.value.generatedAt) || new Date().toISOString();\n // The subscription pool and its billing period are only evidenced on the console-cookie channel\n // (`billing/summary`); `vela` has no command that reports them. Leave both unknown instead of\n // inferring them, and say which half is missing so the host can fall back deliberately.\n const note = noSubscription\n ? '\u684C\u9762\u767B\u5F55\u6001\u663E\u793A\u8BE5\u8D26\u53F7\u6CA1\u6709 Design Plan \u8BA2\u9605\uFF1B\u672A\u8BFB\u5230\u7684\u5206\u6C60\u4FDD\u6301\u672A\u77E5\u3002\u53EF\u5728\u8FDE\u63A5\u9875\u5B8C\u6210\u72EC\u7ACB\u767B\u5F55\uFF0C\u63D2\u4EF6\u4F1A\u4F18\u5148\u91C7\u7528\u53EF\u8BFB\u53D6\u7684\u5B8C\u6574\u989D\u5EA6\u3002'\n : !windows.length\n ? '\u684C\u9762\u767B\u5F55\u6001\u672A\u8FD4\u56DE\u5957\u9910\u7A97\u53E3\uFF1B\u5DF2\u8BFB\u5230\u7684\u94B1\u5305\u4F59\u989D\u7167\u5E38\u663E\u793A\uFF0C\u672A\u8BFB\u5230\u7684\u5206\u6C60\u4FDD\u6301\u672A\u77E5\u3002\u53EF\u5728\u8FDE\u63A5\u9875\u5B8C\u6210\u72EC\u7ACB\u767B\u5F55\uFF0C\u63D2\u4EF6\u4F1A\u4F18\u5148\u91C7\u7528\u53EF\u8BFB\u53D6\u7684\u5B8C\u6574\u989D\u5EA6\u3002'\n : '\u684C\u9762\u767B\u5F55\u6001\u90E8\u5206\u63A5\u53E3\u6743\u9650\u53D7\u9650\uFF1B\u672A\u8BFB\u5230\u7684\u5206\u6C60\u663E\u793A\u672A\u77E5\u3002\u53EF\u5728\u8FDE\u63A5\u9875\u5B8C\u6210\u72EC\u7ACB\u767B\u5F55\uFF0C\u63D2\u4EF6\u4F1A\u4F18\u5148\u91C7\u7528\u53EF\u8BFB\u53D6\u7684\u5B8C\u6574\u989D\u5EA6\u3002';\n return { state: 'partial', source: 'desktop', updatedAt, windows, balances,\n ...(tier ? { tier } : {}), ...(eligible === undefined ? {} : { eligible }),\n note,\n };\n}\n", "/** Shared JSON value types and allowlist parsers; no credential or opaque Host state is returned. */\n\nimport type { QuotaSnapshot, QuotaWindow, SessionSource } from './quota.js';\nimport { record } from './util.js';\nimport { API_PROTOCOL_IDS, type ApiProtocol } from './protocol-options.js';\nimport { parseModelSettingsMap, type ModelSettingsMap } from './model-settings.js';\n\n// Type-only: browser imports must not pull in quota.ts runtime dependencies.\nexport type { QuotaSnapshot, QuotaWindow, SessionSource } from './quota.js';\n\n/** npm package that owns the Remote methods; must satisfy typert's segment rules. */\nexport const REMOTE_PACKAGE = 'dsh-opendesign-corouter';\n/** Cordis service key and wire namespace. The Client resolves `remote.<this>`. */\nexport const REMOTE_SERVICE = 'openDesignCoRouter';\n\n/** Upper bounds on every accepted string, so an oversized Host value fails here. */\nconst MAX_REVISION = 256;\nconst MAX_JOB_ID = 128;\nconst MAX_BASE_URL = 2048;\nconst MAX_ENV_REF = 128;\nconst MAX_TEXT = 4096;\nconst MAX_MESSAGE = 1024;\nconst MAX_TIER = 256;\nconst MAX_MODELS = 512;\nconst MAX_WINDOWS = 64;\n/** Printable ASCII only: what an HTTP header field can carry verbatim. */\nconst MAX_API_KEY = 16_384;\nconst HTTP_ASCII = /^[\\x21-\\x7e]+$/u;\nconst ENV_REF = /^[A-Za-z_][A-Za-z0-9_]*$/u;\nconst MODEL_ID = /^[A-Za-z0-9._:/-]{1,128}$/u;\n\n/** Live switches of this plugin, mirrored for a settings page that only has this RPC. */\nexport interface StatusConfig {\n emptyTurnGuard: boolean;\n useDesktopCredential: boolean;\n baseURL: string;\n /** Credential reference name (an env var or a DSH credential ref), never the value. */\n apiKeyEnv: string;\n apiProtocol?: ApiProtocol;\n modelSettings?: ModelSettingsMap;\n requestTimeoutMs?: number;\n streamIdleTimeoutMs?: number;\n quotaRefreshSeconds?: number;\n}\n\n/** One selectable model; `group` selects which of the two Providers owns it. */\nexport interface StatusModel {\n id: string;\n name: string;\n group: 'plan' | 'paid';\n enabled?: boolean;\n contextWindow?: number;\n maxOutputTokens?: number;\n reasoningEfforts?: readonly string[];\n}\n\n/** Terminal-or-in-flight phases a login job may report. */\nexport type LoginPhase = 'idle' | 'launching' | 'waiting' | 'verifying' | 'success' | 'cancelled' | 'error';\n\n/** Credential-free view of the independent console login. */\nexport interface LoginState {\n jobId: string | null;\n state: LoginPhase;\n message?: string;\n startedAt?: string;\n finishedAt?: string;\n}\n\n/** Everything the settings/usage surface may read; no field is derived from a secret. */\nexport interface Status {\n /** Opaque Host revision of the credential record; passed back on every write. */\n revision: string;\n apiKeyConfigured: boolean;\n sessionSource?: SessionSource;\n quota: QuotaSnapshot;\n login: LoginState;\n config: StatusConfig;\n /** Turns the empty-turn guard actually intercepted since process start. */\n guardedTurns: number;\n models: readonly StatusModel[];\n modelsSource?: 'builtin' | 'openai';\n modelsUpdatedAt?: string;\n modelsError?: string;\n}\n\nexport interface StartLoginRequest {\n expectedRevision: string;\n}\n\nexport interface CancelLoginRequest {\n jobId: string;\n}\n\nexport interface SaveApiKeyRequest {\n value: string;\n expectedRevision: string;\n}\n\nconst LOGIN_PHASES: readonly LoginPhase[] = ['idle', 'launching', 'waiting', 'verifying', 'success', 'cancelled', 'error'];\nconst QUOTA_STATES: readonly QuotaSnapshot['state'][] = ['ok', 'partial', 'need-login', 'error'];\nconst SESSION_SOURCES: readonly SessionSource[] = ['desktop', 'login', 'environment'];\nconst MODEL_GROUPS: readonly StatusModel['group'][] = ['plan', 'paid'];\n\nfunction text(value: unknown, label: string, max: number): string {\n if (typeof value !== 'string' || value.length === 0 || value.length > max) throw new Error(`${label} \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32\uFF08\u6700\u591A ${max} \u5B57\u7B26\uFF09`);\n return value;\n}\n\nfunction isoTime(value: unknown, label: string): string {\n const time = text(value, label, 64);\n if (!Number.isFinite(Date.parse(time))) throw new Error(`${label} \u5FC5\u987B\u662F ISO \u65F6\u95F4\u5B57\u7B26\u4E32`);\n return time;\n}\n\nfunction flag(value: unknown, label: string): boolean {\n if (typeof value !== 'boolean') throw new Error(`${label} \u5FC5\u987B\u662F\u5E03\u5C14\u503C`);\n return value;\n}\n\nfunction count(value: unknown, label: string): number {\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) throw new Error(`${label} \u5FC5\u987B\u662F\u975E\u8D1F\u6574\u6570`);\n return value;\n}\n\n/** A finite number, optionally non-negative. */\nfunction amount(value: unknown, label: string, negative = false): number {\n if (typeof value !== 'number' || !Number.isFinite(value) || (!negative && value < 0)) throw new Error(`${label} \u5FC5\u987B\u662F${negative ? '' : '\u975E\u8D1F'}\u6709\u9650\u6570\u5B57`);\n return value;\n}\n\nfunction positiveInteger(value: unknown, label: string, max: number): number {\n const result = count(value, label);\n if (result === 0 || result > max) throw new Error(`${label} \u8D85\u51FA\u8303\u56F4`);\n return result;\n}\nfunction parseEfforts(value: unknown): string[] {\n if (!Array.isArray(value) || value.length > 16) throw new Error('\u6A21\u578B\u601D\u8003\u6863\u4F4D\u683C\u5F0F\u65E0\u6548');\n return value.map(item => text(item, '\u601D\u8003\u6863\u4F4D', 32));\n}\nfunction member<T extends string>(value: unknown, allowed: readonly T[], label: string): T {\n const hit = allowed.find(candidate => candidate === value);\n if (hit === undefined) throw new Error(`${label} \u4E0D\u5728\u5141\u8BB8\u7684\u53D6\u503C\u5185`);\n return hit;\n}\n\nfunction parseQuotaWindow(value: unknown): QuotaWindow {\n if (!record(value)) throw new Error('\u989D\u5EA6\u7A97\u53E3\u5FC5\u987B\u662F\u5BF9\u8C61');\n const durationSeconds = amount(value.durationSeconds, '\u989D\u5EA6\u7A97\u53E3\u65F6\u957F');\n if (durationSeconds <= 0) throw new Error('\u989D\u5EA6\u7A97\u53E3\u65F6\u957F\u5FC5\u987B\u5927\u4E8E 0');\n const limit = amount(value.limit, '\u989D\u5EA6\u4E0A\u9650');\n if (limit <= 0) throw new Error('\u989D\u5EA6\u4E0A\u9650\u5FC5\u987B\u5927\u4E8E 0');\n return {\n durationSeconds,\n used: amount(value.used, '\u5DF2\u7528\u989D\u5EA6'),\n limit,\n ...(value.remaining === undefined ? {} : { remaining: amount(value.remaining, '\u5269\u4F59\u989D\u5EA6') }),\n percent: Math.min(100, Math.max(0, amount(value.percent, '\u5DF2\u7528\u767E\u5206\u6BD4'))),\n ...(value.resetsAt === undefined ? {} : { resetsAt: isoTime(value.resetsAt, '\u989D\u5EA6\u91CD\u7F6E\u65F6\u95F4') }),\n ...(value.windowStart === undefined ? {} : { windowStart: isoTime(value.windowStart, '\u989D\u5EA6\u7A97\u53E3\u5F00\u59CB\u65F6\u95F4') }),\n ...(value.resetMode === undefined ? {} : { resetMode: text(value.resetMode, '\u989D\u5EA6\u5237\u65B0\u65B9\u5F0F', 128) }),\n };\n}\n\n/** Rebuild a `QuotaSnapshot` from an allowlist; unknown keys are dropped. */\nexport function parseQuotaSnapshot(value: unknown): QuotaSnapshot {\n if (!record(value)) throw new Error('\u989D\u5EA6\u5FEB\u7167\u5FC5\u987B\u662F\u5BF9\u8C61');\n const windows = value.windows;\n if (!Array.isArray(windows) || windows.length > MAX_WINDOWS) throw new Error(`\u989D\u5EA6\u7A97\u53E3\u5FC5\u987B\u662F\u6570\u7EC4\uFF08\u6700\u591A ${MAX_WINDOWS} \u9879\uFF09`);\n const balances = value.balances === undefined ? {} : value.balances;\n if (!record(balances)) throw new Error('\u989D\u5EA6\u4F59\u989D\u5FC5\u987B\u662F\u5BF9\u8C61');\n return {\n state: member(value.state, QUOTA_STATES, '\u989D\u5EA6\u72B6\u6001'),\n ...(value.source === undefined ? {} : { source: member(value.source, SESSION_SOURCES, '\u989D\u5EA6\u6765\u6E90') }),\n updatedAt: isoTime(value.updatedAt, '\u989D\u5EA6\u66F4\u65B0\u65F6\u95F4'),\n ...(value.subscriptionPeriodStart === undefined ? {} : { subscriptionPeriodStart: isoTime(value.subscriptionPeriodStart, '\u8BA2\u9605\u5468\u671F\u5F00\u59CB\u65F6\u95F4') }),\n ...(value.subscriptionPeriodEnd === undefined ? {} : { subscriptionPeriodEnd: isoTime(value.subscriptionPeriodEnd, '\u8BA2\u9605\u5468\u671F\u7ED3\u675F\u65F6\u95F4') }),\n ...(value.nextRefreshAt === undefined ? {} : { nextRefreshAt: isoTime(value.nextRefreshAt, '\u4E0B\u6B21\u81EA\u52A8\u5237\u65B0\u65F6\u95F4') }),\n ...(value.stale === undefined ? {} : { stale: flag(value.stale, '\u5386\u53F2\u989D\u5EA6\u8BFB\u6570') }),\n ...(value.refreshFailures === undefined ? {} : { refreshFailures: count(value.refreshFailures, '\u8FDE\u7EED\u5237\u65B0\u5931\u8D25\u6B21\u6570') }),\n ...(value.autoRefreshPaused === undefined ? {} : { autoRefreshPaused: flag(value.autoRefreshPaused, '\u81EA\u52A8\u5237\u65B0\u6682\u505C\u72B6\u6001') }),\n ...(value.tier === undefined ? {} : { tier: text(value.tier, '\u5957\u9910\u540D', MAX_TIER) }),\n ...(value.eligible === undefined ? {} : { eligible: flag(value.eligible, '\u5957\u9910\u8D44\u683C') }),\n windows: windows.map(parseQuotaWindow),\n balances: {\n ...(balances.subscriptionUsd === undefined ? {} : { subscriptionUsd: amount(balances.subscriptionUsd, '\u8BA2\u9605\u4F59\u989D') }),\n ...(balances.rechargeUsd === undefined ? {} : { rechargeUsd: amount(balances.rechargeUsd, '\u5145\u503C\u4F59\u989D') }),\n ...(balances.totalUsd === undefined ? {} : { totalUsd: amount(balances.totalUsd, '\u53EF\u7528\u4F59\u989D', true) }),\n },\n ...(value.note === undefined ? {} : { note: text(value.note, '\u989D\u5EA6\u8BF4\u660E', MAX_TEXT) }),\n };\n}\n\n/** Rebuild a `LoginState` from an allowlist; the job's secret material never had a field here. */\nexport function parseLoginState(value: unknown): LoginState {\n if (!record(value)) throw new Error('\u767B\u5F55\u72B6\u6001\u5FC5\u987B\u662F\u5BF9\u8C61');\n const jobId = value.jobId;\n if (jobId !== null && jobId !== undefined && typeof jobId !== 'string') throw new Error('\u767B\u5F55\u4EFB\u52A1 id \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6216 null');\n return {\n jobId: typeof jobId === 'string' && jobId.length > 0 ? text(jobId, '\u767B\u5F55\u4EFB\u52A1 id', MAX_JOB_ID) : null,\n state: member(value.state, LOGIN_PHASES, '\u767B\u5F55\u9636\u6BB5'),\n ...(value.message === undefined ? {} : { message: text(value.message, '\u767B\u5F55\u8BF4\u660E', MAX_MESSAGE) }),\n ...(value.startedAt === undefined ? {} : { startedAt: isoTime(value.startedAt, '\u767B\u5F55\u5F00\u59CB\u65F6\u95F4') }),\n ...(value.finishedAt === undefined ? {} : { finishedAt: isoTime(value.finishedAt, '\u767B\u5F55\u7ED3\u675F\u65F6\u95F4') }),\n };\n}\n\nfunction parseStatusModel(value: unknown): StatusModel {\n if (!record(value)) throw new Error('\u6A21\u578B\u6761\u76EE\u5FC5\u987B\u662F\u5BF9\u8C61');\n const id = text(value.id, '\u6A21\u578B id', 128);\n if (!MODEL_ID.test(id)) throw new Error('\u6A21\u578B id \u542B\u4E0D\u5141\u8BB8\u7684\u5B57\u7B26');\n return {\n id,\n name: text(value.name, '\u6A21\u578B\u540D', 128),\n group: member(value.group, MODEL_GROUPS, '\u6A21\u578B\u5206\u7EC4'),\n ...(value.enabled === undefined ? {} : { enabled: flag(value.enabled, '\u6A21\u578B\u542F\u7528\u72B6\u6001') }),\n ...(value.contextWindow === undefined ? {} : { contextWindow: positiveInteger(value.contextWindow, '\u4E0A\u4E0B\u6587\u9884\u7B97', 100_000_000) }),\n ...(value.maxOutputTokens === undefined ? {} : { maxOutputTokens: positiveInteger(value.maxOutputTokens, '\u6700\u5927\u8F93\u51FA', 10_000_000) }),\n ...(value.reasoningEfforts === undefined ? {} : { reasoningEfforts: parseEfforts(value.reasoningEfforts) }),\n };\n}\n\nfunction parseStatusConfig(value: unknown): StatusConfig {\n if (!record(value)) throw new Error('\u914D\u7F6E\u89C6\u56FE\u5FC5\u987B\u662F\u5BF9\u8C61');\n const apiKeyEnv = text(value.apiKeyEnv, '\u51ED\u636E\u5F15\u7528\u540D', MAX_ENV_REF);\n if (!ENV_REF.test(apiKeyEnv)) throw new Error('\u51ED\u636E\u5F15\u7528\u540D\u5FC5\u987B\u662F\u5408\u6CD5\u6807\u8BC6\u7B26');\n return {\n emptyTurnGuard: flag(value.emptyTurnGuard, '\u7A7A\u8F6E\u4FDD\u62A4\u5F00\u5173'),\n useDesktopCredential: flag(value.useDesktopCredential, '\u684C\u9762\u767B\u5F55\u6001\u5F00\u5173'),\n baseURL: text(value.baseURL, '\u63A8\u7406\u5730\u5740', MAX_BASE_URL),\n apiKeyEnv,\n ...(value.apiProtocol === undefined ? {} : { apiProtocol: member(value.apiProtocol, API_PROTOCOL_IDS, '\u63A8\u7406\u534F\u8BAE') }),\n ...(value.modelSettings === undefined ? {} : { modelSettings: parseModelSettingsMap(value.modelSettings) }),\n ...(value.requestTimeoutMs === undefined ? {} : { requestTimeoutMs: positiveInteger(value.requestTimeoutMs, '\u8BF7\u6C42\u8D85\u65F6', 3_600_000) }),\n ...(value.streamIdleTimeoutMs === undefined ? {} : { streamIdleTimeoutMs: positiveInteger(value.streamIdleTimeoutMs, '\u6D41\u7A7A\u95F2\u8D85\u65F6', 1_800_000) }),\n ...(value.quotaRefreshSeconds === undefined ? {} : { quotaRefreshSeconds: positiveInteger(value.quotaRefreshSeconds, '\u81EA\u52A8\u5237\u65B0\u95F4\u9694', 3600) }),\n };\n}\n\n/** Rebuild a `Status` from an allowlist; the credential itself has no field here. */\nexport function parseStatus(value: unknown): Status {\n if (!record(value)) throw new Error('\u72B6\u6001\u5FC5\u987B\u662F\u5BF9\u8C61');\n const models = value.models;\n if (!Array.isArray(models) || models.length > MAX_MODELS) throw new Error(`\u6A21\u578B\u5217\u8868\u5FC5\u987B\u662F\u6570\u7EC4\uFF08\u6700\u591A ${MAX_MODELS} \u9879\uFF09`);\n const ids = new Set<string>();\n const parsed = models.map(parseStatusModel);\n for (const model of parsed) {\n if (ids.has(model.id)) throw new Error(`\u6A21\u578B\u5217\u8868\u91CD\u590D\u4E86 id \"${model.id}\"`);\n ids.add(model.id);\n }\n return {\n revision: text(value.revision, '\u914D\u7F6E\u7248\u672C', MAX_REVISION),\n apiKeyConfigured: flag(value.apiKeyConfigured, '\u51ED\u636E\u662F\u5426\u5C31\u7EEA'),\n ...(value.sessionSource === undefined ? {} : { sessionSource: member(value.sessionSource, SESSION_SOURCES, '\u767B\u5F55\u6001\u6765\u6E90') }),\n quota: parseQuotaSnapshot(value.quota),\n login: parseLoginState(value.login),\n config: parseStatusConfig(value.config),\n guardedTurns: count(value.guardedTurns, '\u5DF2\u62E6\u622A\u7A7A\u8F6E\u6570'),\n models: parsed,\n ...(value.modelsSource === undefined ? {} : { modelsSource: member(value.modelsSource, ['builtin', 'openai'] as const, '\u6A21\u578B\u76EE\u5F55\u6765\u6E90') }),\n ...(value.modelsUpdatedAt === undefined ? {} : { modelsUpdatedAt: isoTime(value.modelsUpdatedAt, '\u6A21\u578B\u66F4\u65B0\u65F6\u95F4') }),\n ...(value.modelsError === undefined ? {} : { modelsError: text(value.modelsError, '\u6A21\u578B\u66F4\u65B0\u63D0\u793A', MAX_MESSAGE) }),\n };\n}\n\n/** `{ expectedRevision }`: the revision the UI saw before the user started a login. */\nexport function parseStartLoginRequest(value: unknown): StartLoginRequest {\n if (!record(value)) throw new Error('\u767B\u5F55\u8BF7\u6C42\u5FC5\u987B\u662F\u5BF9\u8C61');\n return { expectedRevision: text(value.expectedRevision, '\u914D\u7F6E\u7248\u672C', MAX_REVISION) };\n}\n\n/** `{ jobId }`: the attempt to cancel; a stale id is the Host's call to refuse. */\nexport function parseCancelLoginRequest(value: unknown): CancelLoginRequest {\n if (!record(value)) throw new Error('\u53D6\u6D88\u8BF7\u6C42\u5FC5\u987B\u662F\u5BF9\u8C61');\n return { jobId: text(value.jobId, '\u767B\u5F55\u4EFB\u52A1 id', MAX_JOB_ID) };\n}\n\n/**\n * `{ value, expectedRevision }`: the raw key plus the revision it replaces.\n *\n * The key is trimmed exactly once, here, because every real source (settings field,\n * `.env` line, shell export) carries surrounding whitespace. Anything outside\n * printable ASCII is refused rather than handed to `fetch`, whose ByteString error\n * names a UTF-16 code point instead of the setting to fix.\n */\nexport function parseSaveApiKeyRequest(value: unknown): SaveApiKeyRequest {\n if (!record(value)) throw new Error('\u4FDD\u5B58\u8BF7\u6C42\u5FC5\u987B\u662F\u5BF9\u8C61');\n if (typeof value.value !== 'string') throw new Error('API Key \u5FC5\u987B\u662F\u5B57\u7B26\u4E32');\n const key = value.value.trim();\n if (!HTTP_ASCII.test(key)) throw new Error('API Key \u4E3A\u7A7A\u6216\u542B\u6709\u4E0D\u53EF\u7528\u4E8E HTTP \u8BF7\u6C42\u5934\u7684\u5B57\u7B26');\n if (key.length > MAX_API_KEY) throw new Error(`API Key \u4E0D\u80FD\u8D85\u8FC7 ${MAX_API_KEY} \u5B57\u7B26`);\n return { value: key, expectedRevision: text(value.expectedRevision, '\u914D\u7F6E\u7248\u672C', MAX_REVISION) };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["randomUUID", "LlmError", "LlmError", "text", "LlmError", "LlmError", "LlmError", "LlmError", "name", "count", "text", "LlmError", "text", "LlmError", "LlmError", "messages", "LlmError", "LlmError", "ToolCallId", "LlmError", "textOnlyImageText", "text", "LlmError", "messages", "content", "count", "ToolCallId", "text", "LlmError", "ToolCallId", "text", "LlmError", "count", "name", "ToolCallId", "call", "content", "LlmError", "LlmError", "messages", "raw", "attributionHeaders", "MESSAGES", "name", "openAiBaseURL", "attributionHeaders", "text", "errorCode", "attributionHeaders", "attributionHeaders", "join", "join", "funding", "MAX_MODELS", "MODEL_ID", "randomUUID", "name", "group", "count", "LlmError", "config"]
7
7
  }