feat(llm): route adapters by provider

This commit is contained in:
Yichen Jiang
2026-07-14 21:57:52 +08:00
parent a0359bc4a9
commit e547980d77
218 files changed
+2605 -1844

No files matched your search

@@ -388,7 +388,14 @@ export class WorkerRun implements WorkflowRun {
parent: this.parent,
signal: this.controller.signal,
...request.schema !== undefined ? { outputSchema: request.schema } : {},
...request.model !== undefined ? { agentOptions: { model: request.model } } : {},
...request.provider !== undefined || request.model !== undefined
? {
agentOptions: {
...request.provider !== undefined ? { provider: request.provider } : {},
...request.model !== undefined ? { model: request.model } : {},
},
}
: {},
})
} catch (error: unknown) {
const failure = this.childAdmissionFailure()
@@ -40,15 +40,17 @@ function validateMetaShape(meta: unknown): { meta?: WorkflowMeta; violations: st
}
const entry = phase as Record<string, unknown>
for (const key of Object.keys(entry)) {
if (!['title', 'detail', 'model'].includes(key)) violations.push(`meta.phases[${index}].${key} is not a recognized field`)
if (!['title', 'detail', 'provider', 'model'].includes(key)) violations.push(`meta.phases[${index}].${key} is not a recognized field`)
}
if (typeof entry.title !== 'string' || entry.title.length === 0) violations.push(`meta.phases[${index}].title must be a non-empty string`)
if (entry.detail !== undefined && typeof entry.detail !== 'string') violations.push(`meta.phases[${index}].detail must be a string`)
if (entry.provider !== undefined && typeof entry.provider !== 'string') violations.push(`meta.phases[${index}].provider must be a string`)
if (entry.model !== undefined && typeof entry.model !== 'string') violations.push(`meta.phases[${index}].model must be a string`)
if (violations.length === 0) {
phases.push({
title: entry.title as string,
...entry.detail !== undefined ? { detail: entry.detail as string } : {},
...entry.provider !== undefined ? { provider: entry.provider as string } : {},
...entry.model !== undefined ? { model: entry.model as string } : {},
})
}
@@ -61,7 +61,7 @@ export interface ExecutionObserver {
}
/** The `agent()` options the script may pass; everything else rejects loud. */
const SUPPORTED_AGENT_OPTIONS = new Set(['label', 'phase', 'schema', 'model'])
const SUPPORTED_AGENT_OPTIONS = new Set(['label', 'phase', 'schema', 'provider', 'model'])
/** Deferred Claude Code options we name explicitly in the rejection message. */
const DEFERRED_AGENT_OPTIONS = new Set(['effort', 'isolation', 'agentType'])
@@ -302,6 +302,7 @@ export class WorkflowExecution {
run = await this.children.startAgent({
prompt: rawPrompt,
...opts.schema !== undefined ? { schema: opts.schema } : {},
...opts.provider !== undefined ? { provider: opts.provider } : {},
...opts.model !== undefined ? { model: opts.model } : {},
})
} catch (error: unknown) {
@@ -369,7 +370,13 @@ export class WorkflowExecution {
}
/** Materialize + validate the `agent()` options bag from the realm. */
private readAgentOptions(rawOpts: unknown): { label?: string; phase?: string; model?: string; schema?: StructuredOutputSchema } {
private readAgentOptions(rawOpts: unknown): {
label?: string
phase?: string
provider?: string
model?: string
schema?: StructuredOutputSchema
} {
if (rawOpts === undefined) return {}
let opts: unknown
try {
@@ -388,9 +395,9 @@ export class WorkflowExecution {
if (DEFERRED_AGENT_OPTIONS.has(key)) {
throw new WorkflowError(`agent() option "${key}" is deferred and not supported by this engine (supported: label, phase, schema, model)`, 'UNSUPPORTED_OPTION')
}
throw new WorkflowError(`agent() option "${key}" is not recognized (supported: label, phase, schema, model)`, 'UNSUPPORTED_OPTION')
throw new WorkflowError(`agent() option "${key}" is not recognized (supported: label, phase, schema, provider, model)`, 'UNSUPPORTED_OPTION')
}
for (const key of ['label', 'phase', 'model'] as const) {
for (const key of ['label', 'phase', 'provider', 'model'] as const) {
if (record[key] !== undefined && typeof record[key] !== 'string') {
throw new WorkflowError(`agent() option "${key}" must be a string`, 'INVALID_ARGUMENT')
}
@@ -409,6 +416,7 @@ export class WorkflowExecution {
return {
...record.label !== undefined ? { label: record.label as string } : {},
...record.phase !== undefined ? { phase: record.phase as string } : {},
...record.provider !== undefined ? { provider: record.provider as string } : {},
...record.model !== undefined ? { model: record.model as string } : {},
...schema !== undefined ? { schema } : {},
}
@@ -46,6 +46,8 @@ export interface ChildStartRequest {
prompt: string
/** The structured-output schema, if the call passed one (already subset-checked). */
schema?: StructuredOutputSchema
/** The per-child provider override, if the call passed one. */
provider?: string
/** The per-child model override, if the call passed one. */
model?: string
}