@yolk-sdk/agent 0.1.0-canary.56 → 0.1.0-canary.57

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/README.md CHANGED
@@ -13,6 +13,7 @@ pnpm add @yolk-sdk/agent@canary effect
13
13
  Add `react` if you use `@yolk-sdk/agent/react`.
14
14
 
15
15
  Canary APIs are unstable. Keep all `@yolk-sdk/*` packages on the same version.
16
+ Published package metadata requires Node.js 22+.
16
17
 
17
18
  ## Subpaths
18
19
 
@@ -107,21 +108,40 @@ const program = run({
107
108
  // Provide LLM provider, loop config, context transformer, and tool executor layers in the host app.
108
109
  ```
109
110
 
111
+ ## OAuth credentials
112
+
113
+ `@yolk-sdk/agent/oauth` defines provider-neutral access-token, broker, freshness, and credential-source
114
+ contracts. Provider subpaths add vendor request/response conversion without owning persistence.
115
+
116
+ ```ts
117
+ import { credentialSourceFromBroker, type TokenBrokerClient } from '@yolk-sdk/agent/oauth'
118
+
119
+ const makeTokenProgram = (hostBroker: TokenBrokerClient) =>
120
+ credentialSourceFromBroker(hostBroker, {
121
+ provider: 'openai-codex',
122
+ subjectId: 'host-user-id'
123
+ }).getAccessToken({ minTtlSeconds: 300 })
124
+ ```
125
+
126
+ `hostBroker` is a host implementation of `TokenBrokerClient`. The host stores, refreshes, revokes,
127
+ and authorizes credentials; the package receives short-lived access tokens and never persists
128
+ secrets.
129
+
110
130
  ## Provider configuration
111
131
 
112
- Provider output limits are required and host-owned. Yolk does not infer model limits or apply hidden
113
- fallbacks.
132
+ Provider output limits are host-owned when the endpoint supports them. Yolk does not infer model
133
+ limits or apply hidden fallbacks.
114
134
 
115
- | Provider factory | Required output-limit field |
116
- | ---------------------------------- | --------------------------- |
117
- | `makeOpenAiProviderLayer` | `maxCompletionTokens` |
118
- | `makeOpenAiCodexProviderLayer` | `maxOutputTokens` |
119
- | `makeAnthropicClaudeProviderLayer` | `maxTokens` |
135
+ | Provider factory | Output-limit field |
136
+ | ---------------------------------- | --------------------- |
137
+ | `makeOpenAiProviderLayer` | `maxCompletionTokens` |
138
+ | `makeOpenAiCodexProviderLayer` | none |
139
+ | `makeAnthropicClaudeProviderLayer` | `maxTokens` |
120
140
 
121
- The public `toOpenAiRequestBody`, `toOpenAiCodexRequestBody`, and
122
- `toAnthropicClaudeRequestBody` helpers require the same limit configuration. ChatGPT subscription
123
- Codex rejects vendor `max_output_tokens`, so the Codex adapter retains the required host config but
124
- omits that field from requests. `OpenAiProviderLayer` reads both `OPENAI_API_KEY` and integer
141
+ The public `toOpenAiRequestBody` and `toAnthropicClaudeRequestBody` helpers require the matching
142
+ limit configuration. ChatGPT subscription Codex rejects vendor `max_output_tokens`, so
143
+ `makeOpenAiCodexProviderLayer` and `toOpenAiCodexRequestBody` ignore the optional deprecated
144
+ `maxOutputTokens` compatibility field. `OpenAiProviderLayer` reads both `OPENAI_API_KEY` and integer
125
145
  `OPENAI_MAX_COMPLETION_TOKENS` through Effect Config.
126
146
 
127
147
  Set optional `reasoningEffort` on `run` or `runRuntime`; provider adapters lower it to vendor
@@ -203,6 +223,14 @@ transformers. Exact provider-request accounting must also include system prompts
203
223
  vendor framing, and a safety margin. Reuse one estimator for warnings, planning, and before/after
204
224
  checks; tokenizer dependencies remain host-owned.
205
225
 
226
+ ## Skillsets
227
+
228
+ `@yolk-sdk/agent/skillset` parses skill Markdown and slash-command Markdown into portable
229
+ `SkillInfo`, `CommandInfo`, and `SkillsetManifest` data. Use `parseSkillMarkdown` /
230
+ `parseCommandMarkdown` at file or database boundaries, `renderCommand` for command invocation, and
231
+ `mergeSkillsets` to combine host sources. Earlier sources win name conflicts; duplicate names
232
+ inside one source fail validation. Hosts own file discovery, storage, enablement, and source order.
233
+
206
234
  ## Protocol content
207
235
 
208
236
  `Content` is either plain text or ordered parts:
@@ -412,7 +440,8 @@ Recommended setup:
412
440
  - use `makeSubagentRunId(call.id)` for protocol-aligned run ids
413
441
  - optionally configure model and reasoning-effort choices so the parent can select child runtime settings
414
442
  - treat omitted `model` and `reasoning_effort` parameters as inheritance of host runtime settings
415
- - return `makeSubagentToolResult(...)` so UI can show subagent id, type, status, model, reasoning effort, and timing
443
+ - return `makeSubagentToolResult(...)` so UI can show subagent id, type, status, model, reasoning effort, timing, optional usage/turns, and typed failure metadata
444
+ - use `subagentUsageFromToolResult(...)` when a host must add child usage to cumulative workflow usage
416
445
 
417
446
  Keep host-owned subagent execution wiring outside this package; pass only the package subagent contract across the boundary.
418
447
 
@@ -431,7 +460,9 @@ aborts, and implementation bugs outside typed tool execution.
431
460
  ## Host responsibilities
432
461
 
433
462
  - Choose models/providers and provide an LLM provider layer, using SDK provider subpaths or host adapters.
463
+ - Store, refresh, revoke, and authorize OAuth credentials; expose only runtime access tokens.
434
464
  - Configure model-specific provider output-token limits.
465
+ - Build UI components and styling, own auth, and wire headless React hooks to host transports.
435
466
  - Persist sessions, transcripts, and append logs.
436
467
  - Persist/return one `ToolResultMessage` for every host tool call, including `isError` failures.
437
468
  - Persist terminal provider failures and clear active run ids where applicable.
@@ -8,7 +8,8 @@ type ContextBudget = {
8
8
  };
9
9
  type ContextBudgetInput = {
10
10
  readonly contextWindowTokens: number;
11
- readonly reservedOutputTokens: number;
11
+ readonly reservedOutputTokens: number; /** Optional provider- or endpoint-specific ceiling below the model's total context window. */
12
+ readonly maxInputTokens?: number;
12
13
  readonly warningRatio: number;
13
14
  readonly compactionRatio: number;
14
15
  };
@@ -1 +1 @@
1
- {"version":3,"file":"budget.d.mts","names":[],"sources":["../../src/compaction/budget.ts"],"mappings":";KAAY,aAAA;EAAA,SACD,mBAAA;EAAA,SACA,oBAAA;EAAA,SACA,iBAAA;EAAA,SACA,kBAAA;EAAA,SACA,qBAAA;AAAA;AAAA,KAGC,kBAAA;EAAA,SACD,mBAAA;EAAA,SACA,oBAAA;EAAA,SACA,YAAA;EAAA,SACA,eAAA;AAAA;AAAA,cAGE,iBAAA,GAAqB,KAAA,EAAO,kBAAA,KAAqB,aAU7D;AAAA,cAEY,uBAAA,GAA2B,MAAA,UAAgB,MAAA,EAAQ,aAAa;AAAA,KAGjE,mBAAA;AAAA,cAEC,mBAAA,GAAuB,MAAA,UAAgB,MAAA,EAAQ,aAAA,KAAgB,mBAU3E"}
1
+ {"version":3,"file":"budget.d.mts","names":[],"sources":["../../src/compaction/budget.ts"],"mappings":";KAAY,aAAA;EAAA,SACD,mBAAA;EAAA,SACA,oBAAA;EAAA,SACA,iBAAA;EAAA,SACA,kBAAA;EAAA,SACA,qBAAA;AAAA;AAAA,KAGC,kBAAA;EAAA,SACD,mBAAA;EAAA,SACA,oBAAA,UALqB;EAAA,SAOrB,cAAA;EAAA,SACA,YAAA;EAAA,SACA,eAAA;AAAA;AAAA,cAGE,iBAAA,GAAqB,KAAA,EAAO,kBAAA,KAAqB,aAkB7D;AAAA,cAEY,uBAAA,GAA2B,MAAA,UAAgB,MAAA,EAAQ,aAAa;AAAA,KAGjE,mBAAA;AAAA,cAEC,mBAAA,GAAuB,MAAA,UAAgB,MAAA,EAAQ,aAAA,KAAgB,mBAU3E"}
@@ -1,6 +1,8 @@
1
1
  //#region src/compaction/budget.ts
2
2
  const makeContextBudget = (input) => {
3
- const usableInputTokens = Math.max(0, input.contextWindowTokens - input.reservedOutputTokens);
3
+ const contextUsableInputTokens = Math.max(0, input.contextWindowTokens - input.reservedOutputTokens);
4
+ const maxInputTokens = input.maxInputTokens === void 0 || !Number.isFinite(input.maxInputTokens) ? contextUsableInputTokens : Math.max(0, input.maxInputTokens);
5
+ const usableInputTokens = Math.min(contextUsableInputTokens, maxInputTokens);
4
6
  return {
5
7
  contextWindowTokens: input.contextWindowTokens,
6
8
  reservedOutputTokens: input.reservedOutputTokens,
@@ -1 +1 @@
1
- {"version":3,"file":"budget.mjs","names":[],"sources":["../../src/compaction/budget.ts"],"sourcesContent":["export type ContextBudget = {\n readonly contextWindowTokens: number\n readonly reservedOutputTokens: number\n readonly usableInputTokens: number\n readonly warningInputTokens: number\n readonly compactionInputTokens: number\n}\n\nexport type ContextBudgetInput = {\n readonly contextWindowTokens: number\n readonly reservedOutputTokens: number\n readonly warningRatio: number\n readonly compactionRatio: number\n}\n\nexport const makeContextBudget = (input: ContextBudgetInput): ContextBudget => {\n const usableInputTokens = Math.max(0, input.contextWindowTokens - input.reservedOutputTokens)\n\n return {\n contextWindowTokens: input.contextWindowTokens,\n reservedOutputTokens: input.reservedOutputTokens,\n usableInputTokens,\n warningInputTokens: Math.floor(usableInputTokens * input.warningRatio),\n compactionInputTokens: Math.floor(usableInputTokens * input.compactionRatio)\n }\n}\n\nexport const contextBudgetUsageRatio = (tokens: number, budget: ContextBudget) =>\n budget.usableInputTokens === 0 ? 0 : tokens / budget.usableInputTokens\n\nexport type ContextBudgetStatus = 'idle' | 'normal' | 'warning' | 'compact'\n\nexport const contextBudgetStatus = (tokens: number, budget: ContextBudget): ContextBudgetStatus => {\n if (tokens <= 0) {\n return 'idle'\n }\n\n if (tokens >= budget.compactionInputTokens) {\n return 'compact'\n }\n\n return tokens >= budget.warningInputTokens ? 'warning' : 'normal'\n}\n"],"mappings":";AAeA,MAAa,qBAAqB,UAA6C;CAC7E,MAAM,oBAAoB,KAAK,IAAI,GAAG,MAAM,sBAAsB,MAAM,oBAAoB;CAE5F,OAAO;EACL,qBAAqB,MAAM;EAC3B,sBAAsB,MAAM;EAC5B;EACA,oBAAoB,KAAK,MAAM,oBAAoB,MAAM,YAAY;EACrE,uBAAuB,KAAK,MAAM,oBAAoB,MAAM,eAAe;CAC7E;AACF;AAEA,MAAa,2BAA2B,QAAgB,WACtD,OAAO,sBAAsB,IAAI,IAAI,SAAS,OAAO;AAIvD,MAAa,uBAAuB,QAAgB,WAA+C;CACjG,IAAI,UAAU,GACZ,OAAO;CAGT,IAAI,UAAU,OAAO,uBACnB,OAAO;CAGT,OAAO,UAAU,OAAO,qBAAqB,YAAY;AAC3D"}
1
+ {"version":3,"file":"budget.mjs","names":[],"sources":["../../src/compaction/budget.ts"],"sourcesContent":["export type ContextBudget = {\n readonly contextWindowTokens: number\n readonly reservedOutputTokens: number\n readonly usableInputTokens: number\n readonly warningInputTokens: number\n readonly compactionInputTokens: number\n}\n\nexport type ContextBudgetInput = {\n readonly contextWindowTokens: number\n readonly reservedOutputTokens: number\n /** Optional provider- or endpoint-specific ceiling below the model's total context window. */\n readonly maxInputTokens?: number\n readonly warningRatio: number\n readonly compactionRatio: number\n}\n\nexport const makeContextBudget = (input: ContextBudgetInput): ContextBudget => {\n const contextUsableInputTokens = Math.max(\n 0,\n input.contextWindowTokens - input.reservedOutputTokens\n )\n const maxInputTokens =\n input.maxInputTokens === undefined || !Number.isFinite(input.maxInputTokens)\n ? contextUsableInputTokens\n : Math.max(0, input.maxInputTokens)\n const usableInputTokens = Math.min(contextUsableInputTokens, maxInputTokens)\n\n return {\n contextWindowTokens: input.contextWindowTokens,\n reservedOutputTokens: input.reservedOutputTokens,\n usableInputTokens,\n warningInputTokens: Math.floor(usableInputTokens * input.warningRatio),\n compactionInputTokens: Math.floor(usableInputTokens * input.compactionRatio)\n }\n}\n\nexport const contextBudgetUsageRatio = (tokens: number, budget: ContextBudget) =>\n budget.usableInputTokens === 0 ? 0 : tokens / budget.usableInputTokens\n\nexport type ContextBudgetStatus = 'idle' | 'normal' | 'warning' | 'compact'\n\nexport const contextBudgetStatus = (tokens: number, budget: ContextBudget): ContextBudgetStatus => {\n if (tokens <= 0) {\n return 'idle'\n }\n\n if (tokens >= budget.compactionInputTokens) {\n return 'compact'\n }\n\n return tokens >= budget.warningInputTokens ? 'warning' : 'normal'\n}\n"],"mappings":";AAiBA,MAAa,qBAAqB,UAA6C;CAC7E,MAAM,2BAA2B,KAAK,IACpC,GACA,MAAM,sBAAsB,MAAM,oBACpC;CACA,MAAM,iBACJ,MAAM,mBAAmB,KAAA,KAAa,CAAC,OAAO,SAAS,MAAM,cAAc,IACvE,2BACA,KAAK,IAAI,GAAG,MAAM,cAAc;CACtC,MAAM,oBAAoB,KAAK,IAAI,0BAA0B,cAAc;CAE3E,OAAO;EACL,qBAAqB,MAAM;EAC3B,sBAAsB,MAAM;EAC5B;EACA,oBAAoB,KAAK,MAAM,oBAAoB,MAAM,YAAY;EACrE,uBAAuB,KAAK,MAAM,oBAAoB,MAAM,eAAe;CAC7E;AACF;AAEA,MAAa,2BAA2B,QAAgB,WACtD,OAAO,sBAAsB,IAAI,IAAI,SAAS,OAAO;AAIvD,MAAa,uBAAuB,QAAgB,WAA+C;CACjG,IAAI,UAAU,GACZ,OAAO;CAGT,IAAI,UAAU,OAAO,uBACnB,OAAO;CAGT,OAAO,UAAU,OAAO,qBAAqB,YAAY;AAC3D"}
@@ -8,7 +8,11 @@ import { OAuthAccessToken } from "@yolk-sdk/agent/oauth";
8
8
  type OpenAiCodexReasoningSummary = 'auto' | 'concise' | 'detailed';
9
9
  type OpenAiCodexProviderConfig = {
10
10
  readonly token: OAuthAccessToken;
11
- readonly maxOutputTokens: number;
11
+ /**
12
+ * @deprecated The ChatGPT Codex endpoint does not accept `max_output_tokens`; this value is
13
+ * retained as an ignored compatibility field for existing hosts.
14
+ */
15
+ readonly maxOutputTokens?: number;
12
16
  readonly responsesUrl?: string;
13
17
  readonly extraHeaders?: Readonly<Record<string, string>>;
14
18
  readonly defaultReasoningEffort?: AgentReasoningEffort;
@@ -67,8 +71,8 @@ type OpenAiCodexRequestBody = {
67
71
  readonly tools?: ReadonlyArray<OpenAiCodexTool>;
68
72
  readonly parallel_tool_calls?: true;
69
73
  };
70
- declare const toOpenAiCodexRequestBody: (request: LLMRequest, config: {
71
- readonly maxOutputTokens: number;
74
+ declare const toOpenAiCodexRequestBody: (request: LLMRequest, config?: {
75
+ /** @deprecated Ignored by the ChatGPT Codex endpoint. */readonly maxOutputTokens?: number;
72
76
  readonly defaultReasoningEffort?: AgentReasoningEffort;
73
77
  readonly reasoningSummary?: OpenAiCodexReasoningSummary;
74
78
  }) => Effect.Effect<OpenAiCodexRequestBody, LLMError>;
@@ -1 +1 @@
1
- {"version":3,"file":"codex-provider.d.mts","names":[],"sources":["../../../src/providers/openai/codex-provider.ts"],"mappings":";;;;;;;KAiDY,2BAAA;AAAA,KAEA,yBAAA;EAAA,SACD,KAAA,EAAO,gBAAA;EAAA,SACP,eAAA;EAAA,SACA,YAAA;EAAA,SACA,YAAA,GAAe,QAAA,CAAS,MAAA;EAAA,SACxB,sBAAA,GAAyB,oBAAA;EAAA,SACzB,gBAAA,GAAmB,2BAAA;AAAA;AAAA,KAGzB,uBAAA;EAAA,SACM,IAAA;EAAA,SACA,OAAA,WAAkB,aAAa,CAAC,2BAAA;AAAA;AAAA,KAGtC,wBAAA;EAAA,SACM,IAAA;EAAA,SACA,IAAI;AAAA;AAAA,KAGV,yBAAA;EAAA,SACM,IAAA;EAAA,SACA,SAAS;AAAA;AAAA,KAGf,wBAAA;EAAA,SAEU,IAAA;EAAA,SACA,QAAA;EAAA,SACA,SAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,QAAA;AAAA;AAAA,KAGV,2BAAA,GACD,wBAAA,GACA,yBAAA,GACA,wBAAA;AAAA,KAEC,yBAAA,YAAqC,aAAa,CAAC,2BAAA;AAAA,KAEnD,4BAAA;EAAA,SACM,IAAA;EAAA,SACA,OAAA;EAAA,SACA,IAAA;EAAA,SACA,SAAA;AAAA;AAAA,KAGN,8BAAA;EAAA,SACM,IAAA;EAAA,SACA,OAAA;EAAA,SACA,MAAA,EAAQ,yBAAyB;AAAA;AAAA,KAGvC,oBAAA,GACD,uBAAA,GACA,4BAAA,GACA,8BAAA;AAAA,KAEC,eAAA;EAAA,SACM,IAAA;EAAA,SACA,IAAA;EAAA,SACA,WAAA;EAAA,SACA,UAAA;AAAA;AAAA,KAGN,sBAAA;EAAA,SACM,KAAA;EAAA,SACA,YAAA;EAAA,SACA,KAAA,EAAO,aAAA,CAAc,oBAAA;EAAA,SACrB,KAAA;EAAA,SACA,MAAA;EAAA,SACA,SAAA;IAAA,SACE,MAAA,EAAQ,oBAAA;IAAA,SACR,OAAA,EAAS,2BAAA;EAAA;EAAA,SAEX,KAAA,GAAQ,aAAA,CAAc,eAAA;EAAA,SACtB,mBAAA;AAAA;AAAA,cA2RE,wBAAA,GACX,OAAA,EAAS,UAAA,EACT,MAAA;EAAA,SACW,eAAA;EAAA,SACA,sBAAA,GAAyB,oBAAA;EAAA,SACzB,gBAAA,GAAmB,2BAAA;AAAA,MAE7B,MAAA,CAAO,MAAA,CAAO,sBAAA,EAAwB,QAAA;AAAA,cA2lB5B,yBAAA,GACX,QAAA,EAAU,kBAAA,CAAmB,kBAAA,KAC5B,MAAA,CAAO,MAAA,CAAO,QAAA,EAAU,QAAA;AAAA,cA0Fd,4BAAA,GAAgC,MAAA,EAAQ,yBAAA,KAAyB,KAAA,CAAA,KAAA,CAAA,WAAA,SAAA,UAAA,CAAA,UAAA"}
1
+ {"version":3,"file":"codex-provider.d.mts","names":[],"sources":["../../../src/providers/openai/codex-provider.ts"],"mappings":";;;;;;;KAiDY,2BAAA;AAAA,KAEA,yBAAA;EAAA,SACD,KAAA,EAAO,gBAAA;EAHqB;;;AAAA;EAAA,SAQ5B,eAAA;EAAA,SACA,YAAA;EAAA,SACA,YAAA,GAAe,QAAA,CAAS,MAAA;EAAA,SACxB,sBAAA,GAAyB,oBAAA;EAAA,SACzB,gBAAA,GAAmB,2BAAA;AAAA;AAAA,KAGzB,uBAAA;EAAA,SACM,IAAA;EAAA,SACA,OAAA,WAAkB,aAAa,CAAC,2BAAA;AAAA;AAAA,KAGtC,wBAAA;EAAA,SACM,IAAA;EAAA,SACA,IAAI;AAAA;AAAA,KAGV,yBAAA;EAAA,SACM,IAAA;EAAA,SACA,SAAS;AAAA;AAAA,KAGf,wBAAA;EAAA,SAEU,IAAA;EAAA,SACA,QAAA;EAAA,SACA,SAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,QAAA;AAAA;AAAA,KAGV,2BAAA,GACD,wBAAA,GACA,yBAAA,GACA,wBAAA;AAAA,KAEC,yBAAA,YAAqC,aAAa,CAAC,2BAAA;AAAA,KAEnD,4BAAA;EAAA,SACM,IAAA;EAAA,SACA,OAAA;EAAA,SACA,IAAA;EAAA,SACA,SAAA;AAAA;AAAA,KAGN,8BAAA;EAAA,SACM,IAAA;EAAA,SACA,OAAA;EAAA,SACA,MAAA,EAAQ,yBAAyB;AAAA;AAAA,KAGvC,oBAAA,GACD,uBAAA,GACA,4BAAA,GACA,8BAAA;AAAA,KAEC,eAAA;EAAA,SACM,IAAA;EAAA,SACA,IAAA;EAAA,SACA,WAAA;EAAA,SACA,UAAA;AAAA;AAAA,KAGN,sBAAA;EAAA,SACM,KAAA;EAAA,SACA,YAAA;EAAA,SACA,KAAA,EAAO,aAAA,CAAc,oBAAA;EAAA,SACrB,KAAA;EAAA,SACA,MAAA;EAAA,SACA,SAAA;IAAA,SACE,MAAA,EAAQ,oBAAA;IAAA,SACR,OAAA,EAAS,2BAAA;EAAA;EAAA,SAEX,KAAA,GAAQ,aAAA,CAAc,eAAA;EAAA,SACtB,mBAAA;AAAA;AAAA,cA2RE,wBAAA,GACX,OAAA,EAAS,UAAA,EACT,MAAA;EArU0B,kEAuUf,eAAA;EAAA,SACA,sBAAA,GAAyB,oBAAA;EAAA,SACzB,gBAAA,GAAmB,2BAAA;AAAA,MAE7B,MAAA,CAAO,MAAA,CAAO,sBAAA,EAAwB,QAAA;AAAA,cA2lB5B,yBAAA,GACX,QAAA,EAAU,kBAAA,CAAmB,kBAAA,KAC5B,MAAA,CAAO,MAAA,CAAO,QAAA,EAAU,QAAA;AAAA,cA0Fd,4BAAA,GAAgC,MAAA,EAAQ,yBAAA,KAAyB,KAAA,CAAA,KAAA,CAAA,WAAA,SAAA,UAAA,CAAA,UAAA"}
@@ -161,7 +161,7 @@ const toOpenAiCodexTool = (tool) => ({
161
161
  description: tool.description,
162
162
  parameters: tool.parameters
163
163
  });
164
- const toOpenAiCodexRequestBody = (request, config) => Effect.gen(function* () {
164
+ const toOpenAiCodexRequestBody = (request, config = {}) => Effect.gen(function* () {
165
165
  yield* validateProviderTranscript(request.messages);
166
166
  const input = Array.flatten(yield* Effect.forEach(request.messages, messageToCodexInput));
167
167
  const body = {
@@ -1 +1 @@
1
- {"version":3,"file":"codex-provider.mjs","names":["Arr","LLMReasoningDelta","LLMTextDelta"],"sources":["../../../src/providers/openai/codex-provider.ts"],"sourcesContent":["import { Array as Arr, Effect, Layer, Option, Ref, Stream } from 'effect'\nimport {\n HttpClient,\n HttpClientRequest,\n type HttpClientError,\n type HttpClientResponse\n} from 'effect/unstable/http'\nimport * as Schema from 'effect/Schema'\nimport {\n AgentInputUsage,\n AgentOutputUsage,\n AgentUsage,\n ToolCall,\n attachmentSourceDataUrl,\n attachmentSourceUrl,\n assistantContent,\n assistantHostToolCalls,\n contentParts,\n messageContextText,\n replaceLoneSurrogatesDeep,\n prependMessageContextToContent,\n type AgentMessage,\n type AgentReasoningEffort,\n type Content,\n type ContentPart,\n type ProviderFailureKind,\n type ToolDef\n} from '@yolk-sdk/agent/protocol'\nimport {\n LLMError,\n LLMDone,\n LLMProvider,\n LLMReasoningDelta,\n LLMTextDelta,\n LLMToolCall,\n LLMUsage,\n type LLMEvent,\n type LLMRequest\n} from '@yolk-sdk/agent/loop'\nimport { openAiCodexAuthorizationHeaders, openAiCodexResponsesUrl } from './codex.ts'\nimport type { OAuthAccessToken } from '@yolk-sdk/agent/oauth'\nimport {\n classifyProviderFailure,\n providerErrorInfo,\n providerFailureCause,\n providerFailureRetryable\n} from '../provider-error.ts'\nimport { validateProviderTranscript } from '../transcript.ts'\n\nexport type OpenAiCodexReasoningSummary = 'auto' | 'concise' | 'detailed'\n\nexport type OpenAiCodexProviderConfig = {\n readonly token: OAuthAccessToken\n readonly maxOutputTokens: number\n readonly responsesUrl?: string\n readonly extraHeaders?: Readonly<Record<string, string>>\n readonly defaultReasoningEffort?: AgentReasoningEffort\n readonly reasoningSummary?: OpenAiCodexReasoningSummary\n}\n\ntype OpenAiCodexMessageInput = {\n readonly role: 'user' | 'assistant'\n readonly content: string | ReadonlyArray<OpenAiCodexInputContentPart>\n}\n\ntype OpenAiCodexInputTextPart = {\n readonly type: 'input_text'\n readonly text: string\n}\n\ntype OpenAiCodexInputImagePart = {\n readonly type: 'input_image'\n readonly image_url: string\n}\n\ntype OpenAiCodexInputFilePart =\n | {\n readonly type: 'input_file'\n readonly filename: string\n readonly file_data: string\n }\n | {\n readonly type: 'input_file'\n readonly file_url: string\n }\n\ntype OpenAiCodexInputContentPart =\n | OpenAiCodexInputTextPart\n | OpenAiCodexInputImagePart\n | OpenAiCodexInputFilePart\n\ntype OpenAiCodexFunctionOutput = string | ReadonlyArray<OpenAiCodexInputContentPart>\n\ntype OpenAiCodexFunctionCallInput = {\n readonly type: 'function_call'\n readonly call_id: string\n readonly name: string\n readonly arguments: string\n}\n\ntype OpenAiCodexFunctionOutputInput = {\n readonly type: 'function_call_output'\n readonly call_id: string\n readonly output: OpenAiCodexFunctionOutput\n}\n\ntype OpenAiCodexInputItem =\n | OpenAiCodexMessageInput\n | OpenAiCodexFunctionCallInput\n | OpenAiCodexFunctionOutputInput\n\ntype OpenAiCodexTool = {\n readonly type: 'function'\n readonly name: string\n readonly description: string\n readonly parameters: unknown\n}\n\ntype OpenAiCodexRequestBody = {\n readonly model: string\n readonly instructions: string\n readonly input: ReadonlyArray<OpenAiCodexInputItem>\n readonly store: false\n readonly stream: true\n readonly reasoning: {\n readonly effort: AgentReasoningEffort\n readonly summary: OpenAiCodexReasoningSummary\n }\n readonly tools?: ReadonlyArray<OpenAiCodexTool>\n readonly parallel_tool_calls?: true\n}\n\nclass OpenAiCodexReasoningSummaryText extends Schema.Class<OpenAiCodexReasoningSummaryText>(\n 'OpenAiCodexReasoningSummaryText'\n)({\n type: Schema.Literals(['summary_text']),\n text: Schema.String\n}) {}\n\nclass OpenAiCodexReasoningText extends Schema.Class<OpenAiCodexReasoningText>(\n 'OpenAiCodexReasoningText'\n)({\n type: Schema.Literals(['reasoning_text']),\n text: Schema.String\n}) {}\n\nclass OpenAiCodexOutputText extends Schema.Class<OpenAiCodexOutputText>('OpenAiCodexOutputText')({\n type: Schema.Literals(['output_text']),\n text: Schema.String\n}) {}\n\nclass OpenAiCodexMessageOutput extends Schema.Class<OpenAiCodexMessageOutput>(\n 'OpenAiCodexMessageOutput'\n)({\n type: Schema.Literals(['message']),\n content: Schema.Array(OpenAiCodexOutputText)\n}) {}\n\nclass OpenAiCodexFunctionCallOutput extends Schema.Class<OpenAiCodexFunctionCallOutput>(\n 'OpenAiCodexFunctionCallOutput'\n)({\n type: Schema.Literals(['function_call']),\n call_id: Schema.String,\n name: Schema.String,\n arguments: Schema.String\n}) {}\n\nclass OpenAiCodexReasoningOutput extends Schema.Class<OpenAiCodexReasoningOutput>(\n 'OpenAiCodexReasoningOutput'\n)({\n type: Schema.Literals(['reasoning']),\n summary: Schema.optional(Schema.Array(OpenAiCodexReasoningSummaryText)),\n content: Schema.optional(Schema.Array(OpenAiCodexReasoningText))\n}) {}\n\nclass OpenAiCodexInputTokensDetails extends Schema.Class<OpenAiCodexInputTokensDetails>(\n 'OpenAiCodexInputTokensDetails'\n)({\n cached_tokens: Schema.optional(Schema.Number)\n}) {}\n\nclass OpenAiCodexOutputTokensDetails extends Schema.Class<OpenAiCodexOutputTokensDetails>(\n 'OpenAiCodexOutputTokensDetails'\n)({\n reasoning_tokens: Schema.optional(Schema.Number)\n}) {}\n\nclass OpenAiCodexUsageResponse extends Schema.Class<OpenAiCodexUsageResponse>(\n 'OpenAiCodexUsageResponse'\n)({\n input_tokens: Schema.Number,\n output_tokens: Schema.Number,\n input_tokens_details: Schema.optional(OpenAiCodexInputTokensDetails),\n output_tokens_details: Schema.optional(OpenAiCodexOutputTokensDetails)\n}) {}\n\nconst OpenAiCodexOutputItem = Schema.Union([\n OpenAiCodexMessageOutput,\n OpenAiCodexFunctionCallOutput,\n OpenAiCodexReasoningOutput\n])\ntype OpenAiCodexOutputItem = typeof OpenAiCodexOutputItem.Type\n\nclass OpenAiCodexResponse extends Schema.Class<OpenAiCodexResponse>('OpenAiCodexResponse')({\n output_text: Schema.optional(Schema.String),\n output: Schema.Array(OpenAiCodexOutputItem),\n usage: Schema.optional(OpenAiCodexUsageResponse)\n}) {}\n\nconst unknownToMessage = (error: unknown) =>\n error instanceof Error ? error.message : String(error)\n\nconst encodeJsonString = (value: unknown, message: string) =>\n Schema.encodeUnknownEffect(Schema.UnknownFromJsonString)(value).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'provider_error',\n message: `${message}: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst decodeJsonString = (raw: string, message: string) =>\n Schema.decodeUnknownEffect(Schema.UnknownFromJsonString)(raw).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `${message}: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst unsupportedContentError = (contentType: string) =>\n new LLMError({\n cause: 'provider_error',\n message: `${contentType} content is not supported by the OpenAI Codex OAuth provider yet`,\n retryable: false\n })\n\nconst contentPartToText = (part: ContentPart, owner: string): Effect.Effect<string, LLMError> => {\n switch (part._tag) {\n case 'Text':\n return Effect.succeed(part.text)\n case 'Image':\n return Effect.fail(unsupportedContentError(`${owner} image`))\n case 'Document':\n return Effect.fail(unsupportedContentError(`${owner} document`))\n case 'Audio':\n return Effect.fail(unsupportedContentError(`${owner} audio`))\n }\n}\n\nconst contentToText = (content: Content, owner: string): Effect.Effect<string, LLMError> =>\n typeof content === 'string'\n ? Effect.succeed(content)\n : Effect.forEach(content, part => contentPartToText(part, owner)).pipe(\n Effect.map(textParts => textParts.join('\\n'))\n )\n\nconst contentPartToCodexInputPart = (\n part: ContentPart\n): Effect.Effect<\n OpenAiCodexInputTextPart | OpenAiCodexInputImagePart | OpenAiCodexInputFilePart,\n LLMError\n> => {\n switch (part._tag) {\n case 'Text':\n return Effect.succeed({ type: 'input_text', text: part.text })\n case 'Image':\n return Option.match(attachmentSourceUrl(part.source, part.mimeType), {\n onNone: () => Effect.fail(unsupportedContentError('Unresolved image source')),\n onSome: url =>\n Effect.succeed({\n type: 'input_image',\n image_url: url\n })\n })\n case 'Document':\n switch (part.source._tag) {\n case 'InlineBase64':\n return Option.match(attachmentSourceDataUrl(part.source, part.mimeType), {\n onNone: () => Effect.fail(unsupportedContentError('Invalid document source')),\n onSome: url =>\n Effect.succeed({\n type: 'input_file',\n filename: part.filename,\n file_data: url\n })\n })\n case 'Url':\n return Effect.succeed({ type: 'input_file', file_url: part.source.url })\n case 'Ref':\n return Effect.fail(unsupportedContentError('Unresolved document source'))\n }\n case 'Audio':\n return Effect.fail(unsupportedContentError('Audio'))\n }\n}\n\nconst contentToUserInput = (\n content: Content\n): Effect.Effect<OpenAiCodexMessageInput['content'], LLMError> => {\n if (typeof content === 'string') {\n return Effect.succeed(content)\n }\n\n const parts = contentParts(content)\n const onlyPart = parts[0]\n\n if (onlyPart !== undefined && parts.length === 1 && onlyPart._tag === 'Text') {\n return Effect.succeed(onlyPart.text)\n }\n\n return Effect.forEach(parts, contentPartToCodexInputPart)\n}\n\nconst contentToCodexFunctionOutput = (\n content: Content\n): Effect.Effect<OpenAiCodexFunctionOutput, LLMError> =>\n typeof content === 'string'\n ? Effect.succeed(content)\n : Effect.forEach(content, contentPartToCodexInputPart)\n\nconst codexToolResultOutput = (\n content: Content,\n isError: boolean | undefined\n): Effect.Effect<OpenAiCodexFunctionOutput, LLMError> =>\n contentToCodexFunctionOutput(content).pipe(\n Effect.map(output => {\n if (isError !== true) return output\n\n const errorPart: OpenAiCodexInputTextPart = {\n type: 'input_text',\n text: 'Tool execution failed.'\n }\n\n return typeof output === 'string' ? `${errorPart.text}\\n\\n${output}` : [errorPart, ...output]\n })\n )\n\nconst serializeToolArguments = (params: unknown) =>\n encodeJsonString(params, 'Could not serialize OpenAI Codex tool arguments')\n\nconst toolCallToCodexInput = (\n call: ToolCall\n): Effect.Effect<OpenAiCodexFunctionCallInput, LLMError> =>\n Effect.gen(function* () {\n return {\n type: 'function_call',\n call_id: call.id,\n name: call.name,\n arguments: yield* serializeToolArguments(call.params)\n }\n })\n\nconst messageToCodexInput = (\n message: AgentMessage\n): Effect.Effect<ReadonlyArray<OpenAiCodexInputItem>, LLMError> =>\n Effect.gen(function* () {\n switch (message._tag) {\n case 'User':\n return [\n {\n role: 'user',\n content: yield* contentToUserInput(\n prependMessageContextToContent(message.content, messageContextText(message))\n )\n }\n ]\n case 'Assistant': {\n const content = yield* contentToText(\n prependMessageContextToContent(assistantContent(message), messageContextText(message)),\n 'Assistant'\n )\n const toolCallInputs = yield* Effect.forEach(\n assistantHostToolCalls(message),\n toolCallToCodexInput\n )\n\n if (content.length > 0) {\n const assistantMessage: OpenAiCodexInputItem = { role: 'assistant', content }\n\n return [assistantMessage, ...toolCallInputs]\n }\n\n return toolCallInputs\n }\n case 'ToolResult':\n return [\n {\n type: 'function_call_output',\n call_id: message.toolCallId,\n output: yield* codexToolResultOutput(\n prependMessageContextToContent(message.content, messageContextText(message)),\n message.isError\n )\n }\n ]\n }\n })\n\nconst toOpenAiCodexTool = (tool: ToolDef): OpenAiCodexTool => ({\n type: 'function',\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters\n})\n\nexport const toOpenAiCodexRequestBody = (\n request: LLMRequest,\n config: {\n readonly maxOutputTokens: number\n readonly defaultReasoningEffort?: AgentReasoningEffort\n readonly reasoningSummary?: OpenAiCodexReasoningSummary\n }\n): Effect.Effect<OpenAiCodexRequestBody, LLMError> =>\n Effect.gen(function* () {\n yield* validateProviderTranscript(request.messages)\n const input = Arr.flatten(yield* Effect.forEach(request.messages, messageToCodexInput))\n\n const body: Omit<OpenAiCodexRequestBody, 'tools'> = {\n model: request.model,\n instructions: request.systemPrompt,\n input,\n store: false,\n stream: true,\n reasoning: {\n effort: request.reasoningEffort ?? config.defaultReasoningEffort ?? 'low',\n summary: config.reasoningSummary ?? 'auto'\n }\n }\n\n if (request.tools.length === 0) {\n return body\n }\n\n return {\n ...body,\n tools: request.tools.map(toOpenAiCodexTool),\n parallel_tool_calls: true\n }\n })\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null\n\nconst stringField = (value: unknown, key: string) => {\n if (!isRecord(value)) {\n return undefined\n }\n\n const field = Object.getOwnPropertyDescriptor(value, key)?.value\n\n return typeof field === 'string' ? field : undefined\n}\n\nconst recordField = (value: unknown, key: string) => {\n if (!isRecord(value)) {\n return undefined\n }\n\n const field = Object.getOwnPropertyDescriptor(value, key)?.value\n\n return isRecord(field) ? field : undefined\n}\n\nconst openAiCodexProvider = 'openai_codex'\n\nconst providerSignalError = (input: {\n readonly message: string\n readonly providerCode?: string\n readonly fallbackKind?: ProviderFailureKind\n}) => {\n const provider = classifyProviderFailure({\n provider: openAiCodexProvider,\n message: input.message,\n ...(input.providerCode === undefined ? {} : { providerCode: input.providerCode }),\n ...(input.fallbackKind === undefined ? {} : { fallbackKind: input.fallbackKind })\n })\n\n return new LLMError({\n cause: providerFailureCause(provider.kind),\n message: `OpenAI Codex stream error: ${input.message}`,\n retryable: providerFailureRetryable(provider.kind),\n provider\n })\n}\n\nconst parseToolArguments = (raw: string) =>\n decodeJsonString(raw, 'Invalid OpenAI Codex tool arguments JSON')\n\nconst textFromOutputItem = (item: OpenAiCodexOutputItem) => {\n switch (item.type) {\n case 'message':\n return Arr.map(item.content, content => content.text)\n case 'function_call':\n case 'reasoning':\n return []\n }\n}\n\nconst textFromOutputItems = (items: ReadonlyArray<OpenAiCodexOutputItem>) => {\n const textParts = Arr.flatten(Arr.map(items, textFromOutputItem))\n\n return textParts.join('')\n}\n\nconst reasoningFromOutputItem = (item: OpenAiCodexOutputItem) => {\n switch (item.type) {\n case 'reasoning':\n return [\n ...(item.summary ?? []).map(summary => summary.text),\n ...(item.content ?? []).map(content => content.text)\n ]\n case 'message':\n case 'function_call':\n return []\n }\n}\n\nconst reasoningFromOutputItems = (items: ReadonlyArray<OpenAiCodexOutputItem>) => {\n const reasoningParts = Arr.flatten(Arr.map(items, reasoningFromOutputItem))\n\n return reasoningParts.join('')\n}\n\nconst toAgentUsage = (usage: OpenAiCodexUsageResponse) =>\n AgentUsage.make({\n input: AgentInputUsage.make({\n total: usage.input_tokens,\n uncached: usage.input_tokens - (usage.input_tokens_details?.cached_tokens ?? 0),\n cacheRead: usage.input_tokens_details?.cached_tokens\n }),\n output: AgentOutputUsage.make({\n total: usage.output_tokens,\n reasoning: usage.output_tokens_details?.reasoning_tokens,\n text: usage.output_tokens - (usage.output_tokens_details?.reasoning_tokens ?? 0)\n })\n })\n\ntype ToLlmEventsOptions = {\n readonly allowEmptyStop: boolean\n}\n\nconst toLlmEvents = (\n response: OpenAiCodexResponse,\n options: ToLlmEventsOptions\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const text = response.output_text ?? textFromOutputItems(response.output)\n const reasoning = reasoningFromOutputItems(response.output)\n const reasoningEvents =\n reasoning.length > 0 ? [LLMReasoningDelta.make({ text: reasoning })] : []\n const textEvents = text.length > 0 ? [LLMTextDelta.make({ text })] : []\n const toolCallEvents = Arr.getSomes(\n yield* Effect.forEach(response.output, item => {\n switch (item.type) {\n case 'message':\n case 'reasoning':\n return Effect.succeed(Option.none())\n case 'function_call':\n return parseToolArguments(item.arguments).pipe(\n Effect.map(params =>\n Option.some(\n LLMToolCall.make({\n call: ToolCall.make({\n id: item.call_id,\n name: item.name,\n params\n })\n })\n )\n )\n )\n }\n })\n )\n\n if (textEvents.length === 0 && toolCallEvents.length === 0 && !options.allowEmptyStop) {\n return yield* Effect.fail(\n new LLMError({\n cause: 'invalid_response',\n message: 'OpenAI Codex response did not include text or tool calls',\n retryable: false\n })\n )\n }\n\n const events: Array<LLMEvent> = [\n ...reasoningEvents,\n ...textEvents,\n ...toolCallEvents,\n LLMDone.make({ stopReason: toolCallEvents.length > 0 ? 'tool_use' : 'stop' })\n ]\n\n if (response.usage !== undefined) {\n events.push(LLMUsage.make({ usage: toAgentUsage(response.usage) }))\n }\n\n return events\n })\n\nconst decodeOpenAiCodexResponse = (json: unknown) =>\n Schema.decodeUnknownEffect(OpenAiCodexResponse)(json).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `Invalid OpenAI Codex response: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst parseOpenAiCodexJsonResponse = (\n raw: string\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const json = yield* decodeJsonString(raw, 'Could not parse OpenAI Codex response JSON')\n const parsed = yield* decodeOpenAiCodexResponse(json)\n\n return yield* toLlmEvents(parsed, { allowEmptyStop: false })\n })\n\ntype OpenAiCodexBodyFormat = 'undecided' | 'sse' | 'json'\n\ntype OpenAiCodexSseState = {\n readonly hasTextDelta: boolean\n readonly hasReasoningDelta: boolean\n readonly toolCallIds: ReadonlySet<string>\n readonly hasDone: boolean\n}\n\ntype OpenAiCodexSseStep = {\n readonly state: OpenAiCodexSseState\n readonly events: ReadonlyArray<LLMEvent>\n}\n\ntype OpenAiCodexBodyState = {\n readonly format: OpenAiCodexBodyFormat\n readonly buffer: string\n readonly sse: OpenAiCodexSseState\n}\n\nconst initialSseState: OpenAiCodexSseState = {\n hasTextDelta: false,\n hasReasoningDelta: false,\n toolCallIds: new Set(),\n hasDone: false\n}\n\nconst initialBodyState: OpenAiCodexBodyState = {\n format: 'undecided',\n buffer: '',\n sse: initialSseState\n}\n\nconst shouldEmitSseEvent = (state: OpenAiCodexSseState, event: LLMEvent) => {\n if (state.hasTextDelta && event._tag === 'TextDelta') return false\n if (state.hasReasoningDelta && event._tag === 'ReasoningDelta') return false\n if (event._tag === 'ToolCall' && state.toolCallIds.has(event.call.id)) return false\n\n return true\n}\n\nconst dedupeSseEvents = (\n state: OpenAiCodexSseState,\n events: ReadonlyArray<LLMEvent>\n): ReadonlyArray<LLMEvent> => events.filter(event => shouldEmitSseEvent(state, event))\n\nconst toolCallIdsFromEvents = (events: ReadonlyArray<LLMEvent>) =>\n events.flatMap(event => (event._tag === 'ToolCall' ? [event.call.id] : []))\n\nconst normalizeNewlines = (text: string) => text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n')\n\nconst classifyCodexBody = (buffer: string): OpenAiCodexBodyFormat => {\n const trimmed = buffer.trimStart()\n\n if (trimmed.length === 0) {\n return 'undecided'\n }\n\n if (trimmed.startsWith('event:') || trimmed.startsWith('data:')) {\n return 'sse'\n }\n\n if ('event:'.startsWith(trimmed) || 'data:'.startsWith(trimmed)) {\n return 'undecided'\n }\n\n return 'json'\n}\n\nconst splitCompleteSseBlocks = (buffer: string) => {\n const blocks = buffer.split('\\n\\n')\n const tail = blocks.at(-1) ?? ''\n\n return { completeBlocks: blocks.slice(0, -1), tail }\n}\n\nconst dataFromSseBlock = (block: string) => {\n const lines = Arr.map(\n Arr.filter(block.split('\\n'), line => line.startsWith('data:')),\n line => line.slice(5).trimStart()\n )\n\n const data = lines.join('\\n').trim()\n\n if (data.length === 0 || data === '[DONE]') {\n return undefined\n }\n\n return data\n}\n\nconst parseOpenAiCodexSseJson = (data: string) =>\n decodeJsonString(data, 'Could not parse OpenAI Codex stream event JSON')\n\nconst decodeOpenAiCodexOutputItem = (value: unknown) =>\n Schema.decodeUnknownEffect(OpenAiCodexOutputItem)(value).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `Invalid OpenAI Codex output item: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst invalidFunctionCallSseItemError = () =>\n new LLMError({\n cause: 'invalid_response',\n message: 'Invalid OpenAI Codex function call stream item',\n retryable: false\n })\n\nconst eventsFromOutputItem = (\n item: OpenAiCodexOutputItem\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> => {\n switch (item.type) {\n case 'message': {\n const text = textFromOutputItems([item])\n\n return Effect.succeed(text.length > 0 ? [LLMTextDelta.make({ text })] : [])\n }\n case 'reasoning': {\n const reasoning = reasoningFromOutputItems([item])\n\n return Effect.succeed(\n reasoning.length > 0 ? [LLMReasoningDelta.make({ text: reasoning })] : []\n )\n }\n case 'function_call':\n return parseToolArguments(item.arguments).pipe(\n Effect.map(params => [\n LLMToolCall.make({\n call: ToolCall.make({\n id: item.call_id,\n name: item.name,\n params\n })\n })\n ])\n )\n }\n}\n\nconst eventsFromOutputItemDone = (\n event: Record<string, unknown>\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n if (event.type !== 'response.output_item.done') {\n return []\n }\n\n const item = event.item\n\n if (item === undefined) {\n return yield* Effect.fail(invalidFunctionCallSseItemError())\n }\n\n return yield* decodeOpenAiCodexOutputItem(item).pipe(Effect.flatMap(eventsFromOutputItem))\n })\n\nconst responseWithoutReplayedToolCalls = (\n response: OpenAiCodexResponse,\n emittedCallIds: ReadonlySet<string>\n): OpenAiCodexResponse => ({\n ...response,\n output: response.output.filter(\n item => item.type !== 'function_call' || !emittedCallIds.has(item.call_id)\n )\n})\n\nconst finalResponseToEvents = (\n response: unknown,\n state: OpenAiCodexSseState\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const hasToolCalls = state.toolCallIds.size > 0\n const parsedFinal = yield* decodeOpenAiCodexResponse(response)\n const finalEvents = yield* toLlmEvents(\n responseWithoutReplayedToolCalls(parsedFinal, state.toolCallIds),\n { allowEmptyStop: state.hasTextDelta || hasToolCalls }\n )\n\n const shouldDedupe = state.hasTextDelta || state.hasReasoningDelta || hasToolCalls\n const dedupedEvents = shouldDedupe ? dedupeSseEvents(state, finalEvents) : finalEvents\n\n if (!hasToolCalls) {\n return dedupedEvents\n }\n\n return dedupedEvents.map(event =>\n event._tag === 'Done' ? LLMDone.make({ stopReason: 'tool_use' }) : event\n )\n })\n\nconst processSseData = (\n state: OpenAiCodexSseState,\n data: string\n): Effect.Effect<OpenAiCodexSseStep, LLMError> =>\n Effect.gen(function* () {\n const parsed = yield* parseOpenAiCodexSseJson(data)\n\n if (!isRecord(parsed)) {\n return { state, events: [] }\n }\n\n if (\n (parsed.type === 'response.output_text.delta' ||\n parsed.type === 'response.content_part.delta') &&\n typeof parsed.delta === 'string'\n ) {\n return {\n state: { ...state, hasTextDelta: true },\n events: [LLMTextDelta.make({ text: parsed.delta })]\n }\n }\n\n if (\n (parsed.type === 'response.reasoning_summary_text.delta' ||\n parsed.type === 'response.reasoning_text.delta') &&\n typeof parsed.delta === 'string'\n ) {\n return {\n state: { ...state, hasReasoningDelta: true },\n events: [LLMReasoningDelta.make({ text: parsed.delta })]\n }\n }\n\n const outputItemDoneEvents = yield* eventsFromOutputItemDone(parsed)\n if (outputItemDoneEvents.length > 0) {\n const events = dedupeSseEvents(state, outputItemDoneEvents)\n const emittedToolCallIds = toolCallIdsFromEvents(events)\n\n return {\n state: {\n hasTextDelta: state.hasTextDelta || events.some(event => event._tag === 'TextDelta'),\n hasReasoningDelta:\n state.hasReasoningDelta || events.some(event => event._tag === 'ReasoningDelta'),\n toolCallIds: new Set([...state.toolCallIds, ...emittedToolCallIds]),\n hasDone: state.hasDone\n },\n events\n }\n }\n\n if (parsed.type === 'response.completed') {\n const events = yield* finalResponseToEvents(parsed.response, state)\n const emittedText = events.some(event => event._tag === 'TextDelta')\n const emittedReasoning = events.some(event => event._tag === 'ReasoningDelta')\n const emittedToolCallIds = toolCallIdsFromEvents(events)\n\n return {\n state: {\n hasTextDelta: state.hasTextDelta || emittedText,\n hasReasoningDelta: state.hasReasoningDelta || emittedReasoning,\n toolCallIds: new Set([...state.toolCallIds, ...emittedToolCallIds]),\n hasDone: true\n },\n events\n }\n }\n\n if (parsed.type === 'response.failed') {\n const error = recordField(recordField(parsed, 'response'), 'error')\n const message = stringField(error, 'message') ?? 'OpenAI Codex response failed'\n const providerCode = stringField(error, 'code') ?? stringField(error, 'type')\n\n return yield* Effect.fail(\n providerSignalError({\n message,\n ...(providerCode === undefined ? {} : { providerCode })\n })\n )\n }\n\n if (parsed.type === 'error' && typeof parsed.message === 'string') {\n const providerCode = stringField(parsed, 'code') ?? stringField(parsed, 'type')\n\n return yield* Effect.fail(\n providerSignalError({\n message: parsed.message,\n ...(providerCode === undefined ? {} : { providerCode })\n })\n )\n }\n\n return { state, events: [] }\n })\n\nconst processSseBlock = (\n state: OpenAiCodexSseState,\n block: string\n): Effect.Effect<OpenAiCodexSseStep, LLMError> => {\n const data = dataFromSseBlock(block)\n\n if (data === undefined) {\n return Effect.succeed({ state, events: [] })\n }\n\n return processSseData(state, data)\n}\n\nconst processSseBlocks = (\n state: OpenAiCodexSseState,\n blocks: ReadonlyArray<string>\n): Effect.Effect<OpenAiCodexSseStep, LLMError> =>\n Effect.gen(function* () {\n const events: Array<LLMEvent> = []\n let currentState = state\n\n for (const block of blocks) {\n const step = yield* processSseBlock(currentState, block)\n currentState = step.state\n events.push(...step.events)\n }\n\n return { state: currentState, events }\n })\n\nconst processBodyChunk = (\n state: OpenAiCodexBodyState,\n chunk: string\n): Effect.Effect<OpenAiCodexSseStep & { readonly bodyState: OpenAiCodexBodyState }, LLMError> =>\n Effect.gen(function* () {\n const buffer = normalizeNewlines(`${state.buffer}${chunk}`)\n const format = state.format === 'undecided' ? classifyCodexBody(buffer) : state.format\n\n if (format !== 'sse') {\n return {\n state: state.sse,\n bodyState: { ...state, format, buffer },\n events: []\n }\n }\n\n const split = splitCompleteSseBlocks(buffer)\n const step = yield* processSseBlocks(state.sse, split.completeBlocks)\n\n return {\n state: step.state,\n bodyState: { format, buffer: split.tail, sse: step.state },\n events: step.events\n }\n })\n\nconst finalizeBodyState = (\n state: OpenAiCodexBodyState\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const buffer = normalizeNewlines(state.buffer)\n const format = state.format === 'undecided' ? classifyCodexBody(buffer) : state.format\n\n if (format === 'json') {\n return yield* parseOpenAiCodexJsonResponse(buffer)\n }\n\n const events: Array<LLMEvent> = []\n let sseState = state.sse\n\n if (format === 'sse') {\n const split = splitCompleteSseBlocks(buffer)\n const step = yield* processSseBlocks(sseState, split.completeBlocks)\n sseState = step.state\n events.push(...step.events)\n\n if (split.tail.trim().length > 0) {\n const tailStep = yield* processSseBlock(sseState, split.tail)\n sseState = tailStep.state\n events.push(...tailStep.events)\n }\n }\n\n if (!sseState.hasDone) {\n events.push(\n LLMDone.make({ stopReason: sseState.toolCallIds.size > 0 ? 'tool_use' : 'stop' })\n )\n }\n\n return events\n })\n\nconst toHttpClientLlmError =\n (message: string, retryable: boolean, kind: ProviderFailureKind = 'network') =>\n (error: HttpClientError.HttpClientError) =>\n new LLMError({\n cause: 'provider_error',\n message: `${message}: ${error.message}`,\n retryable,\n provider: providerErrorInfo({\n provider: openAiCodexProvider,\n kind: retryable ? kind : 'unknown'\n })\n })\n\nexport const streamOpenAiCodexResponse = (\n response: HttpClientResponse.HttpClientResponse\n): Stream.Stream<LLMEvent, LLMError> =>\n Stream.unwrap(\n Ref.make(initialBodyState).pipe(\n Effect.map(bodyStateRef => {\n const chunks = response.stream.pipe(\n Stream.mapError(\n toHttpClientLlmError('Could not read OpenAI Codex stream', true, 'stream')\n ),\n Stream.decodeText,\n Stream.mapEffect(chunk =>\n Effect.gen(function* () {\n const state = yield* Ref.get(bodyStateRef)\n const step = yield* processBodyChunk(state, chunk)\n yield* Ref.set(bodyStateRef, step.bodyState)\n return step.events\n })\n ),\n Stream.flatMap(events => Stream.fromIterable(events))\n )\n\n const finalEvents = Stream.fromEffect(\n Ref.get(bodyStateRef).pipe(Effect.flatMap(finalizeBodyState))\n ).pipe(Stream.flatMap(events => Stream.fromIterable(events)))\n\n return chunks.pipe(Stream.concat(finalEvents))\n })\n )\n )\n\nconst sendOpenAiCodexRequest = (\n config: OpenAiCodexProviderConfig,\n request: LLMRequest,\n client: HttpClient.HttpClient\n): Effect.Effect<HttpClientResponse.HttpClientResponse, LLMError> =>\n Effect.gen(function* () {\n const body = yield* toOpenAiCodexRequestBody(request, config)\n // Replayed transcripts can carry lone surrogates; harden the lowered\n // body so one bad historical string cannot poison every model call.\n const serializedBody = yield* encodeJsonString(\n replaceLoneSurrogatesDeep(body),\n 'Could not serialize OpenAI Codex request'\n )\n\n const headers: Record<string, string> = {\n accept: 'application/json',\n ...openAiCodexAuthorizationHeaders(config.token),\n 'content-type': 'application/json',\n ...config.extraHeaders\n }\n\n const httpRequest = HttpClientRequest.post(config.responsesUrl ?? openAiCodexResponsesUrl).pipe(\n HttpClientRequest.setHeaders(headers),\n HttpClientRequest.bodyText(serializedBody, 'application/json')\n )\n const response = yield* client\n .execute(httpRequest)\n .pipe(Effect.mapError(toHttpClientLlmError('OpenAI Codex request failed', true)))\n\n if (response.status < 200 || response.status >= 300) {\n const errorText = yield* response.text.pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'provider_error',\n message: `Could not read OpenAI Codex error body: ${error.message}`,\n retryable: false\n })\n )\n )\n\n const provider = classifyProviderFailure({\n provider: openAiCodexProvider,\n status: response.status,\n headers: response.headers,\n body: errorText\n })\n\n return yield* Effect.fail(\n new LLMError({\n cause: providerFailureCause(provider.kind),\n message: `OpenAI Codex returned ${response.status}`,\n retryable: providerFailureRetryable(provider.kind),\n provider\n })\n )\n }\n\n return response\n }).pipe(Effect.withSpan('OpenAiCodexProvider.stream'))\n\nexport const makeOpenAiCodexProviderLayer = (config: OpenAiCodexProviderConfig) =>\n Layer.effect(LLMProvider)(\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n\n return LLMProvider.of({\n stream: request =>\n Stream.fromEffect(sendOpenAiCodexRequest(config, request, client)).pipe(\n Stream.flatMap(streamOpenAiCodexResponse)\n )\n })\n })\n )\n"],"mappings":"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"}
1
+ {"version":3,"file":"codex-provider.mjs","names":["Arr","LLMReasoningDelta","LLMTextDelta"],"sources":["../../../src/providers/openai/codex-provider.ts"],"sourcesContent":["import { Array as Arr, Effect, Layer, Option, Ref, Stream } from 'effect'\nimport {\n HttpClient,\n HttpClientRequest,\n type HttpClientError,\n type HttpClientResponse\n} from 'effect/unstable/http'\nimport * as Schema from 'effect/Schema'\nimport {\n AgentInputUsage,\n AgentOutputUsage,\n AgentUsage,\n ToolCall,\n attachmentSourceDataUrl,\n attachmentSourceUrl,\n assistantContent,\n assistantHostToolCalls,\n contentParts,\n messageContextText,\n replaceLoneSurrogatesDeep,\n prependMessageContextToContent,\n type AgentMessage,\n type AgentReasoningEffort,\n type Content,\n type ContentPart,\n type ProviderFailureKind,\n type ToolDef\n} from '@yolk-sdk/agent/protocol'\nimport {\n LLMError,\n LLMDone,\n LLMProvider,\n LLMReasoningDelta,\n LLMTextDelta,\n LLMToolCall,\n LLMUsage,\n type LLMEvent,\n type LLMRequest\n} from '@yolk-sdk/agent/loop'\nimport { openAiCodexAuthorizationHeaders, openAiCodexResponsesUrl } from './codex.ts'\nimport type { OAuthAccessToken } from '@yolk-sdk/agent/oauth'\nimport {\n classifyProviderFailure,\n providerErrorInfo,\n providerFailureCause,\n providerFailureRetryable\n} from '../provider-error.ts'\nimport { validateProviderTranscript } from '../transcript.ts'\n\nexport type OpenAiCodexReasoningSummary = 'auto' | 'concise' | 'detailed'\n\nexport type OpenAiCodexProviderConfig = {\n readonly token: OAuthAccessToken\n /**\n * @deprecated The ChatGPT Codex endpoint does not accept `max_output_tokens`; this value is\n * retained as an ignored compatibility field for existing hosts.\n */\n readonly maxOutputTokens?: number\n readonly responsesUrl?: string\n readonly extraHeaders?: Readonly<Record<string, string>>\n readonly defaultReasoningEffort?: AgentReasoningEffort\n readonly reasoningSummary?: OpenAiCodexReasoningSummary\n}\n\ntype OpenAiCodexMessageInput = {\n readonly role: 'user' | 'assistant'\n readonly content: string | ReadonlyArray<OpenAiCodexInputContentPart>\n}\n\ntype OpenAiCodexInputTextPart = {\n readonly type: 'input_text'\n readonly text: string\n}\n\ntype OpenAiCodexInputImagePart = {\n readonly type: 'input_image'\n readonly image_url: string\n}\n\ntype OpenAiCodexInputFilePart =\n | {\n readonly type: 'input_file'\n readonly filename: string\n readonly file_data: string\n }\n | {\n readonly type: 'input_file'\n readonly file_url: string\n }\n\ntype OpenAiCodexInputContentPart =\n | OpenAiCodexInputTextPart\n | OpenAiCodexInputImagePart\n | OpenAiCodexInputFilePart\n\ntype OpenAiCodexFunctionOutput = string | ReadonlyArray<OpenAiCodexInputContentPart>\n\ntype OpenAiCodexFunctionCallInput = {\n readonly type: 'function_call'\n readonly call_id: string\n readonly name: string\n readonly arguments: string\n}\n\ntype OpenAiCodexFunctionOutputInput = {\n readonly type: 'function_call_output'\n readonly call_id: string\n readonly output: OpenAiCodexFunctionOutput\n}\n\ntype OpenAiCodexInputItem =\n | OpenAiCodexMessageInput\n | OpenAiCodexFunctionCallInput\n | OpenAiCodexFunctionOutputInput\n\ntype OpenAiCodexTool = {\n readonly type: 'function'\n readonly name: string\n readonly description: string\n readonly parameters: unknown\n}\n\ntype OpenAiCodexRequestBody = {\n readonly model: string\n readonly instructions: string\n readonly input: ReadonlyArray<OpenAiCodexInputItem>\n readonly store: false\n readonly stream: true\n readonly reasoning: {\n readonly effort: AgentReasoningEffort\n readonly summary: OpenAiCodexReasoningSummary\n }\n readonly tools?: ReadonlyArray<OpenAiCodexTool>\n readonly parallel_tool_calls?: true\n}\n\nclass OpenAiCodexReasoningSummaryText extends Schema.Class<OpenAiCodexReasoningSummaryText>(\n 'OpenAiCodexReasoningSummaryText'\n)({\n type: Schema.Literals(['summary_text']),\n text: Schema.String\n}) {}\n\nclass OpenAiCodexReasoningText extends Schema.Class<OpenAiCodexReasoningText>(\n 'OpenAiCodexReasoningText'\n)({\n type: Schema.Literals(['reasoning_text']),\n text: Schema.String\n}) {}\n\nclass OpenAiCodexOutputText extends Schema.Class<OpenAiCodexOutputText>('OpenAiCodexOutputText')({\n type: Schema.Literals(['output_text']),\n text: Schema.String\n}) {}\n\nclass OpenAiCodexMessageOutput extends Schema.Class<OpenAiCodexMessageOutput>(\n 'OpenAiCodexMessageOutput'\n)({\n type: Schema.Literals(['message']),\n content: Schema.Array(OpenAiCodexOutputText)\n}) {}\n\nclass OpenAiCodexFunctionCallOutput extends Schema.Class<OpenAiCodexFunctionCallOutput>(\n 'OpenAiCodexFunctionCallOutput'\n)({\n type: Schema.Literals(['function_call']),\n call_id: Schema.String,\n name: Schema.String,\n arguments: Schema.String\n}) {}\n\nclass OpenAiCodexReasoningOutput extends Schema.Class<OpenAiCodexReasoningOutput>(\n 'OpenAiCodexReasoningOutput'\n)({\n type: Schema.Literals(['reasoning']),\n summary: Schema.optional(Schema.Array(OpenAiCodexReasoningSummaryText)),\n content: Schema.optional(Schema.Array(OpenAiCodexReasoningText))\n}) {}\n\nclass OpenAiCodexInputTokensDetails extends Schema.Class<OpenAiCodexInputTokensDetails>(\n 'OpenAiCodexInputTokensDetails'\n)({\n cached_tokens: Schema.optional(Schema.Number)\n}) {}\n\nclass OpenAiCodexOutputTokensDetails extends Schema.Class<OpenAiCodexOutputTokensDetails>(\n 'OpenAiCodexOutputTokensDetails'\n)({\n reasoning_tokens: Schema.optional(Schema.Number)\n}) {}\n\nclass OpenAiCodexUsageResponse extends Schema.Class<OpenAiCodexUsageResponse>(\n 'OpenAiCodexUsageResponse'\n)({\n input_tokens: Schema.Number,\n output_tokens: Schema.Number,\n input_tokens_details: Schema.optional(OpenAiCodexInputTokensDetails),\n output_tokens_details: Schema.optional(OpenAiCodexOutputTokensDetails)\n}) {}\n\nconst OpenAiCodexOutputItem = Schema.Union([\n OpenAiCodexMessageOutput,\n OpenAiCodexFunctionCallOutput,\n OpenAiCodexReasoningOutput\n])\ntype OpenAiCodexOutputItem = typeof OpenAiCodexOutputItem.Type\n\nclass OpenAiCodexResponse extends Schema.Class<OpenAiCodexResponse>('OpenAiCodexResponse')({\n output_text: Schema.optional(Schema.String),\n output: Schema.Array(OpenAiCodexOutputItem),\n usage: Schema.optional(OpenAiCodexUsageResponse)\n}) {}\n\nconst unknownToMessage = (error: unknown) =>\n error instanceof Error ? error.message : String(error)\n\nconst encodeJsonString = (value: unknown, message: string) =>\n Schema.encodeUnknownEffect(Schema.UnknownFromJsonString)(value).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'provider_error',\n message: `${message}: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst decodeJsonString = (raw: string, message: string) =>\n Schema.decodeUnknownEffect(Schema.UnknownFromJsonString)(raw).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `${message}: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst unsupportedContentError = (contentType: string) =>\n new LLMError({\n cause: 'provider_error',\n message: `${contentType} content is not supported by the OpenAI Codex OAuth provider yet`,\n retryable: false\n })\n\nconst contentPartToText = (part: ContentPart, owner: string): Effect.Effect<string, LLMError> => {\n switch (part._tag) {\n case 'Text':\n return Effect.succeed(part.text)\n case 'Image':\n return Effect.fail(unsupportedContentError(`${owner} image`))\n case 'Document':\n return Effect.fail(unsupportedContentError(`${owner} document`))\n case 'Audio':\n return Effect.fail(unsupportedContentError(`${owner} audio`))\n }\n}\n\nconst contentToText = (content: Content, owner: string): Effect.Effect<string, LLMError> =>\n typeof content === 'string'\n ? Effect.succeed(content)\n : Effect.forEach(content, part => contentPartToText(part, owner)).pipe(\n Effect.map(textParts => textParts.join('\\n'))\n )\n\nconst contentPartToCodexInputPart = (\n part: ContentPart\n): Effect.Effect<\n OpenAiCodexInputTextPart | OpenAiCodexInputImagePart | OpenAiCodexInputFilePart,\n LLMError\n> => {\n switch (part._tag) {\n case 'Text':\n return Effect.succeed({ type: 'input_text', text: part.text })\n case 'Image':\n return Option.match(attachmentSourceUrl(part.source, part.mimeType), {\n onNone: () => Effect.fail(unsupportedContentError('Unresolved image source')),\n onSome: url =>\n Effect.succeed({\n type: 'input_image',\n image_url: url\n })\n })\n case 'Document':\n switch (part.source._tag) {\n case 'InlineBase64':\n return Option.match(attachmentSourceDataUrl(part.source, part.mimeType), {\n onNone: () => Effect.fail(unsupportedContentError('Invalid document source')),\n onSome: url =>\n Effect.succeed({\n type: 'input_file',\n filename: part.filename,\n file_data: url\n })\n })\n case 'Url':\n return Effect.succeed({ type: 'input_file', file_url: part.source.url })\n case 'Ref':\n return Effect.fail(unsupportedContentError('Unresolved document source'))\n }\n case 'Audio':\n return Effect.fail(unsupportedContentError('Audio'))\n }\n}\n\nconst contentToUserInput = (\n content: Content\n): Effect.Effect<OpenAiCodexMessageInput['content'], LLMError> => {\n if (typeof content === 'string') {\n return Effect.succeed(content)\n }\n\n const parts = contentParts(content)\n const onlyPart = parts[0]\n\n if (onlyPart !== undefined && parts.length === 1 && onlyPart._tag === 'Text') {\n return Effect.succeed(onlyPart.text)\n }\n\n return Effect.forEach(parts, contentPartToCodexInputPart)\n}\n\nconst contentToCodexFunctionOutput = (\n content: Content\n): Effect.Effect<OpenAiCodexFunctionOutput, LLMError> =>\n typeof content === 'string'\n ? Effect.succeed(content)\n : Effect.forEach(content, contentPartToCodexInputPart)\n\nconst codexToolResultOutput = (\n content: Content,\n isError: boolean | undefined\n): Effect.Effect<OpenAiCodexFunctionOutput, LLMError> =>\n contentToCodexFunctionOutput(content).pipe(\n Effect.map(output => {\n if (isError !== true) return output\n\n const errorPart: OpenAiCodexInputTextPart = {\n type: 'input_text',\n text: 'Tool execution failed.'\n }\n\n return typeof output === 'string' ? `${errorPart.text}\\n\\n${output}` : [errorPart, ...output]\n })\n )\n\nconst serializeToolArguments = (params: unknown) =>\n encodeJsonString(params, 'Could not serialize OpenAI Codex tool arguments')\n\nconst toolCallToCodexInput = (\n call: ToolCall\n): Effect.Effect<OpenAiCodexFunctionCallInput, LLMError> =>\n Effect.gen(function* () {\n return {\n type: 'function_call',\n call_id: call.id,\n name: call.name,\n arguments: yield* serializeToolArguments(call.params)\n }\n })\n\nconst messageToCodexInput = (\n message: AgentMessage\n): Effect.Effect<ReadonlyArray<OpenAiCodexInputItem>, LLMError> =>\n Effect.gen(function* () {\n switch (message._tag) {\n case 'User':\n return [\n {\n role: 'user',\n content: yield* contentToUserInput(\n prependMessageContextToContent(message.content, messageContextText(message))\n )\n }\n ]\n case 'Assistant': {\n const content = yield* contentToText(\n prependMessageContextToContent(assistantContent(message), messageContextText(message)),\n 'Assistant'\n )\n const toolCallInputs = yield* Effect.forEach(\n assistantHostToolCalls(message),\n toolCallToCodexInput\n )\n\n if (content.length > 0) {\n const assistantMessage: OpenAiCodexInputItem = { role: 'assistant', content }\n\n return [assistantMessage, ...toolCallInputs]\n }\n\n return toolCallInputs\n }\n case 'ToolResult':\n return [\n {\n type: 'function_call_output',\n call_id: message.toolCallId,\n output: yield* codexToolResultOutput(\n prependMessageContextToContent(message.content, messageContextText(message)),\n message.isError\n )\n }\n ]\n }\n })\n\nconst toOpenAiCodexTool = (tool: ToolDef): OpenAiCodexTool => ({\n type: 'function',\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters\n})\n\nexport const toOpenAiCodexRequestBody = (\n request: LLMRequest,\n config: {\n /** @deprecated Ignored by the ChatGPT Codex endpoint. */\n readonly maxOutputTokens?: number\n readonly defaultReasoningEffort?: AgentReasoningEffort\n readonly reasoningSummary?: OpenAiCodexReasoningSummary\n } = {}\n): Effect.Effect<OpenAiCodexRequestBody, LLMError> =>\n Effect.gen(function* () {\n yield* validateProviderTranscript(request.messages)\n const input = Arr.flatten(yield* Effect.forEach(request.messages, messageToCodexInput))\n\n const body: Omit<OpenAiCodexRequestBody, 'tools'> = {\n model: request.model,\n instructions: request.systemPrompt,\n input,\n store: false,\n stream: true,\n reasoning: {\n effort: request.reasoningEffort ?? config.defaultReasoningEffort ?? 'low',\n summary: config.reasoningSummary ?? 'auto'\n }\n }\n\n if (request.tools.length === 0) {\n return body\n }\n\n return {\n ...body,\n tools: request.tools.map(toOpenAiCodexTool),\n parallel_tool_calls: true\n }\n })\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null\n\nconst stringField = (value: unknown, key: string) => {\n if (!isRecord(value)) {\n return undefined\n }\n\n const field = Object.getOwnPropertyDescriptor(value, key)?.value\n\n return typeof field === 'string' ? field : undefined\n}\n\nconst recordField = (value: unknown, key: string) => {\n if (!isRecord(value)) {\n return undefined\n }\n\n const field = Object.getOwnPropertyDescriptor(value, key)?.value\n\n return isRecord(field) ? field : undefined\n}\n\nconst openAiCodexProvider = 'openai_codex'\n\nconst providerSignalError = (input: {\n readonly message: string\n readonly providerCode?: string\n readonly fallbackKind?: ProviderFailureKind\n}) => {\n const provider = classifyProviderFailure({\n provider: openAiCodexProvider,\n message: input.message,\n ...(input.providerCode === undefined ? {} : { providerCode: input.providerCode }),\n ...(input.fallbackKind === undefined ? {} : { fallbackKind: input.fallbackKind })\n })\n\n return new LLMError({\n cause: providerFailureCause(provider.kind),\n message: `OpenAI Codex stream error: ${input.message}`,\n retryable: providerFailureRetryable(provider.kind),\n provider\n })\n}\n\nconst parseToolArguments = (raw: string) =>\n decodeJsonString(raw, 'Invalid OpenAI Codex tool arguments JSON')\n\nconst textFromOutputItem = (item: OpenAiCodexOutputItem) => {\n switch (item.type) {\n case 'message':\n return Arr.map(item.content, content => content.text)\n case 'function_call':\n case 'reasoning':\n return []\n }\n}\n\nconst textFromOutputItems = (items: ReadonlyArray<OpenAiCodexOutputItem>) => {\n const textParts = Arr.flatten(Arr.map(items, textFromOutputItem))\n\n return textParts.join('')\n}\n\nconst reasoningFromOutputItem = (item: OpenAiCodexOutputItem) => {\n switch (item.type) {\n case 'reasoning':\n return [\n ...(item.summary ?? []).map(summary => summary.text),\n ...(item.content ?? []).map(content => content.text)\n ]\n case 'message':\n case 'function_call':\n return []\n }\n}\n\nconst reasoningFromOutputItems = (items: ReadonlyArray<OpenAiCodexOutputItem>) => {\n const reasoningParts = Arr.flatten(Arr.map(items, reasoningFromOutputItem))\n\n return reasoningParts.join('')\n}\n\nconst toAgentUsage = (usage: OpenAiCodexUsageResponse) =>\n AgentUsage.make({\n input: AgentInputUsage.make({\n total: usage.input_tokens,\n uncached: usage.input_tokens - (usage.input_tokens_details?.cached_tokens ?? 0),\n cacheRead: usage.input_tokens_details?.cached_tokens\n }),\n output: AgentOutputUsage.make({\n total: usage.output_tokens,\n reasoning: usage.output_tokens_details?.reasoning_tokens,\n text: usage.output_tokens - (usage.output_tokens_details?.reasoning_tokens ?? 0)\n })\n })\n\ntype ToLlmEventsOptions = {\n readonly allowEmptyStop: boolean\n}\n\nconst toLlmEvents = (\n response: OpenAiCodexResponse,\n options: ToLlmEventsOptions\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const text = response.output_text ?? textFromOutputItems(response.output)\n const reasoning = reasoningFromOutputItems(response.output)\n const reasoningEvents =\n reasoning.length > 0 ? [LLMReasoningDelta.make({ text: reasoning })] : []\n const textEvents = text.length > 0 ? [LLMTextDelta.make({ text })] : []\n const toolCallEvents = Arr.getSomes(\n yield* Effect.forEach(response.output, item => {\n switch (item.type) {\n case 'message':\n case 'reasoning':\n return Effect.succeed(Option.none())\n case 'function_call':\n return parseToolArguments(item.arguments).pipe(\n Effect.map(params =>\n Option.some(\n LLMToolCall.make({\n call: ToolCall.make({\n id: item.call_id,\n name: item.name,\n params\n })\n })\n )\n )\n )\n }\n })\n )\n\n if (textEvents.length === 0 && toolCallEvents.length === 0 && !options.allowEmptyStop) {\n return yield* Effect.fail(\n new LLMError({\n cause: 'invalid_response',\n message: 'OpenAI Codex response did not include text or tool calls',\n retryable: false\n })\n )\n }\n\n const events: Array<LLMEvent> = [\n ...reasoningEvents,\n ...textEvents,\n ...toolCallEvents,\n LLMDone.make({ stopReason: toolCallEvents.length > 0 ? 'tool_use' : 'stop' })\n ]\n\n if (response.usage !== undefined) {\n events.push(LLMUsage.make({ usage: toAgentUsage(response.usage) }))\n }\n\n return events\n })\n\nconst decodeOpenAiCodexResponse = (json: unknown) =>\n Schema.decodeUnknownEffect(OpenAiCodexResponse)(json).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `Invalid OpenAI Codex response: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst parseOpenAiCodexJsonResponse = (\n raw: string\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const json = yield* decodeJsonString(raw, 'Could not parse OpenAI Codex response JSON')\n const parsed = yield* decodeOpenAiCodexResponse(json)\n\n return yield* toLlmEvents(parsed, { allowEmptyStop: false })\n })\n\ntype OpenAiCodexBodyFormat = 'undecided' | 'sse' | 'json'\n\ntype OpenAiCodexSseState = {\n readonly hasTextDelta: boolean\n readonly hasReasoningDelta: boolean\n readonly toolCallIds: ReadonlySet<string>\n readonly hasDone: boolean\n}\n\ntype OpenAiCodexSseStep = {\n readonly state: OpenAiCodexSseState\n readonly events: ReadonlyArray<LLMEvent>\n}\n\ntype OpenAiCodexBodyState = {\n readonly format: OpenAiCodexBodyFormat\n readonly buffer: string\n readonly sse: OpenAiCodexSseState\n}\n\nconst initialSseState: OpenAiCodexSseState = {\n hasTextDelta: false,\n hasReasoningDelta: false,\n toolCallIds: new Set(),\n hasDone: false\n}\n\nconst initialBodyState: OpenAiCodexBodyState = {\n format: 'undecided',\n buffer: '',\n sse: initialSseState\n}\n\nconst shouldEmitSseEvent = (state: OpenAiCodexSseState, event: LLMEvent) => {\n if (state.hasTextDelta && event._tag === 'TextDelta') return false\n if (state.hasReasoningDelta && event._tag === 'ReasoningDelta') return false\n if (event._tag === 'ToolCall' && state.toolCallIds.has(event.call.id)) return false\n\n return true\n}\n\nconst dedupeSseEvents = (\n state: OpenAiCodexSseState,\n events: ReadonlyArray<LLMEvent>\n): ReadonlyArray<LLMEvent> => events.filter(event => shouldEmitSseEvent(state, event))\n\nconst toolCallIdsFromEvents = (events: ReadonlyArray<LLMEvent>) =>\n events.flatMap(event => (event._tag === 'ToolCall' ? [event.call.id] : []))\n\nconst normalizeNewlines = (text: string) => text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n')\n\nconst classifyCodexBody = (buffer: string): OpenAiCodexBodyFormat => {\n const trimmed = buffer.trimStart()\n\n if (trimmed.length === 0) {\n return 'undecided'\n }\n\n if (trimmed.startsWith('event:') || trimmed.startsWith('data:')) {\n return 'sse'\n }\n\n if ('event:'.startsWith(trimmed) || 'data:'.startsWith(trimmed)) {\n return 'undecided'\n }\n\n return 'json'\n}\n\nconst splitCompleteSseBlocks = (buffer: string) => {\n const blocks = buffer.split('\\n\\n')\n const tail = blocks.at(-1) ?? ''\n\n return { completeBlocks: blocks.slice(0, -1), tail }\n}\n\nconst dataFromSseBlock = (block: string) => {\n const lines = Arr.map(\n Arr.filter(block.split('\\n'), line => line.startsWith('data:')),\n line => line.slice(5).trimStart()\n )\n\n const data = lines.join('\\n').trim()\n\n if (data.length === 0 || data === '[DONE]') {\n return undefined\n }\n\n return data\n}\n\nconst parseOpenAiCodexSseJson = (data: string) =>\n decodeJsonString(data, 'Could not parse OpenAI Codex stream event JSON')\n\nconst decodeOpenAiCodexOutputItem = (value: unknown) =>\n Schema.decodeUnknownEffect(OpenAiCodexOutputItem)(value).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `Invalid OpenAI Codex output item: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst invalidFunctionCallSseItemError = () =>\n new LLMError({\n cause: 'invalid_response',\n message: 'Invalid OpenAI Codex function call stream item',\n retryable: false\n })\n\nconst eventsFromOutputItem = (\n item: OpenAiCodexOutputItem\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> => {\n switch (item.type) {\n case 'message': {\n const text = textFromOutputItems([item])\n\n return Effect.succeed(text.length > 0 ? [LLMTextDelta.make({ text })] : [])\n }\n case 'reasoning': {\n const reasoning = reasoningFromOutputItems([item])\n\n return Effect.succeed(\n reasoning.length > 0 ? [LLMReasoningDelta.make({ text: reasoning })] : []\n )\n }\n case 'function_call':\n return parseToolArguments(item.arguments).pipe(\n Effect.map(params => [\n LLMToolCall.make({\n call: ToolCall.make({\n id: item.call_id,\n name: item.name,\n params\n })\n })\n ])\n )\n }\n}\n\nconst eventsFromOutputItemDone = (\n event: Record<string, unknown>\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n if (event.type !== 'response.output_item.done') {\n return []\n }\n\n const item = event.item\n\n if (item === undefined) {\n return yield* Effect.fail(invalidFunctionCallSseItemError())\n }\n\n return yield* decodeOpenAiCodexOutputItem(item).pipe(Effect.flatMap(eventsFromOutputItem))\n })\n\nconst responseWithoutReplayedToolCalls = (\n response: OpenAiCodexResponse,\n emittedCallIds: ReadonlySet<string>\n): OpenAiCodexResponse => ({\n ...response,\n output: response.output.filter(\n item => item.type !== 'function_call' || !emittedCallIds.has(item.call_id)\n )\n})\n\nconst finalResponseToEvents = (\n response: unknown,\n state: OpenAiCodexSseState\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const hasToolCalls = state.toolCallIds.size > 0\n const parsedFinal = yield* decodeOpenAiCodexResponse(response)\n const finalEvents = yield* toLlmEvents(\n responseWithoutReplayedToolCalls(parsedFinal, state.toolCallIds),\n { allowEmptyStop: state.hasTextDelta || hasToolCalls }\n )\n\n const shouldDedupe = state.hasTextDelta || state.hasReasoningDelta || hasToolCalls\n const dedupedEvents = shouldDedupe ? dedupeSseEvents(state, finalEvents) : finalEvents\n\n if (!hasToolCalls) {\n return dedupedEvents\n }\n\n return dedupedEvents.map(event =>\n event._tag === 'Done' ? LLMDone.make({ stopReason: 'tool_use' }) : event\n )\n })\n\nconst processSseData = (\n state: OpenAiCodexSseState,\n data: string\n): Effect.Effect<OpenAiCodexSseStep, LLMError> =>\n Effect.gen(function* () {\n const parsed = yield* parseOpenAiCodexSseJson(data)\n\n if (!isRecord(parsed)) {\n return { state, events: [] }\n }\n\n if (\n (parsed.type === 'response.output_text.delta' ||\n parsed.type === 'response.content_part.delta') &&\n typeof parsed.delta === 'string'\n ) {\n return {\n state: { ...state, hasTextDelta: true },\n events: [LLMTextDelta.make({ text: parsed.delta })]\n }\n }\n\n if (\n (parsed.type === 'response.reasoning_summary_text.delta' ||\n parsed.type === 'response.reasoning_text.delta') &&\n typeof parsed.delta === 'string'\n ) {\n return {\n state: { ...state, hasReasoningDelta: true },\n events: [LLMReasoningDelta.make({ text: parsed.delta })]\n }\n }\n\n const outputItemDoneEvents = yield* eventsFromOutputItemDone(parsed)\n if (outputItemDoneEvents.length > 0) {\n const events = dedupeSseEvents(state, outputItemDoneEvents)\n const emittedToolCallIds = toolCallIdsFromEvents(events)\n\n return {\n state: {\n hasTextDelta: state.hasTextDelta || events.some(event => event._tag === 'TextDelta'),\n hasReasoningDelta:\n state.hasReasoningDelta || events.some(event => event._tag === 'ReasoningDelta'),\n toolCallIds: new Set([...state.toolCallIds, ...emittedToolCallIds]),\n hasDone: state.hasDone\n },\n events\n }\n }\n\n if (parsed.type === 'response.completed') {\n const events = yield* finalResponseToEvents(parsed.response, state)\n const emittedText = events.some(event => event._tag === 'TextDelta')\n const emittedReasoning = events.some(event => event._tag === 'ReasoningDelta')\n const emittedToolCallIds = toolCallIdsFromEvents(events)\n\n return {\n state: {\n hasTextDelta: state.hasTextDelta || emittedText,\n hasReasoningDelta: state.hasReasoningDelta || emittedReasoning,\n toolCallIds: new Set([...state.toolCallIds, ...emittedToolCallIds]),\n hasDone: true\n },\n events\n }\n }\n\n if (parsed.type === 'response.failed') {\n const error = recordField(recordField(parsed, 'response'), 'error')\n const message = stringField(error, 'message') ?? 'OpenAI Codex response failed'\n const providerCode = stringField(error, 'code') ?? stringField(error, 'type')\n\n return yield* Effect.fail(\n providerSignalError({\n message,\n ...(providerCode === undefined ? {} : { providerCode })\n })\n )\n }\n\n if (parsed.type === 'error' && typeof parsed.message === 'string') {\n const providerCode = stringField(parsed, 'code') ?? stringField(parsed, 'type')\n\n return yield* Effect.fail(\n providerSignalError({\n message: parsed.message,\n ...(providerCode === undefined ? {} : { providerCode })\n })\n )\n }\n\n return { state, events: [] }\n })\n\nconst processSseBlock = (\n state: OpenAiCodexSseState,\n block: string\n): Effect.Effect<OpenAiCodexSseStep, LLMError> => {\n const data = dataFromSseBlock(block)\n\n if (data === undefined) {\n return Effect.succeed({ state, events: [] })\n }\n\n return processSseData(state, data)\n}\n\nconst processSseBlocks = (\n state: OpenAiCodexSseState,\n blocks: ReadonlyArray<string>\n): Effect.Effect<OpenAiCodexSseStep, LLMError> =>\n Effect.gen(function* () {\n const events: Array<LLMEvent> = []\n let currentState = state\n\n for (const block of blocks) {\n const step = yield* processSseBlock(currentState, block)\n currentState = step.state\n events.push(...step.events)\n }\n\n return { state: currentState, events }\n })\n\nconst processBodyChunk = (\n state: OpenAiCodexBodyState,\n chunk: string\n): Effect.Effect<OpenAiCodexSseStep & { readonly bodyState: OpenAiCodexBodyState }, LLMError> =>\n Effect.gen(function* () {\n const buffer = normalizeNewlines(`${state.buffer}${chunk}`)\n const format = state.format === 'undecided' ? classifyCodexBody(buffer) : state.format\n\n if (format !== 'sse') {\n return {\n state: state.sse,\n bodyState: { ...state, format, buffer },\n events: []\n }\n }\n\n const split = splitCompleteSseBlocks(buffer)\n const step = yield* processSseBlocks(state.sse, split.completeBlocks)\n\n return {\n state: step.state,\n bodyState: { format, buffer: split.tail, sse: step.state },\n events: step.events\n }\n })\n\nconst finalizeBodyState = (\n state: OpenAiCodexBodyState\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const buffer = normalizeNewlines(state.buffer)\n const format = state.format === 'undecided' ? classifyCodexBody(buffer) : state.format\n\n if (format === 'json') {\n return yield* parseOpenAiCodexJsonResponse(buffer)\n }\n\n const events: Array<LLMEvent> = []\n let sseState = state.sse\n\n if (format === 'sse') {\n const split = splitCompleteSseBlocks(buffer)\n const step = yield* processSseBlocks(sseState, split.completeBlocks)\n sseState = step.state\n events.push(...step.events)\n\n if (split.tail.trim().length > 0) {\n const tailStep = yield* processSseBlock(sseState, split.tail)\n sseState = tailStep.state\n events.push(...tailStep.events)\n }\n }\n\n if (!sseState.hasDone) {\n events.push(\n LLMDone.make({ stopReason: sseState.toolCallIds.size > 0 ? 'tool_use' : 'stop' })\n )\n }\n\n return events\n })\n\nconst toHttpClientLlmError =\n (message: string, retryable: boolean, kind: ProviderFailureKind = 'network') =>\n (error: HttpClientError.HttpClientError) =>\n new LLMError({\n cause: 'provider_error',\n message: `${message}: ${error.message}`,\n retryable,\n provider: providerErrorInfo({\n provider: openAiCodexProvider,\n kind: retryable ? kind : 'unknown'\n })\n })\n\nexport const streamOpenAiCodexResponse = (\n response: HttpClientResponse.HttpClientResponse\n): Stream.Stream<LLMEvent, LLMError> =>\n Stream.unwrap(\n Ref.make(initialBodyState).pipe(\n Effect.map(bodyStateRef => {\n const chunks = response.stream.pipe(\n Stream.mapError(\n toHttpClientLlmError('Could not read OpenAI Codex stream', true, 'stream')\n ),\n Stream.decodeText,\n Stream.mapEffect(chunk =>\n Effect.gen(function* () {\n const state = yield* Ref.get(bodyStateRef)\n const step = yield* processBodyChunk(state, chunk)\n yield* Ref.set(bodyStateRef, step.bodyState)\n return step.events\n })\n ),\n Stream.flatMap(events => Stream.fromIterable(events))\n )\n\n const finalEvents = Stream.fromEffect(\n Ref.get(bodyStateRef).pipe(Effect.flatMap(finalizeBodyState))\n ).pipe(Stream.flatMap(events => Stream.fromIterable(events)))\n\n return chunks.pipe(Stream.concat(finalEvents))\n })\n )\n )\n\nconst sendOpenAiCodexRequest = (\n config: OpenAiCodexProviderConfig,\n request: LLMRequest,\n client: HttpClient.HttpClient\n): Effect.Effect<HttpClientResponse.HttpClientResponse, LLMError> =>\n Effect.gen(function* () {\n const body = yield* toOpenAiCodexRequestBody(request, config)\n // Replayed transcripts can carry lone surrogates; harden the lowered\n // body so one bad historical string cannot poison every model call.\n const serializedBody = yield* encodeJsonString(\n replaceLoneSurrogatesDeep(body),\n 'Could not serialize OpenAI Codex request'\n )\n\n const headers: Record<string, string> = {\n accept: 'application/json',\n ...openAiCodexAuthorizationHeaders(config.token),\n 'content-type': 'application/json',\n ...config.extraHeaders\n }\n\n const httpRequest = HttpClientRequest.post(config.responsesUrl ?? openAiCodexResponsesUrl).pipe(\n HttpClientRequest.setHeaders(headers),\n HttpClientRequest.bodyText(serializedBody, 'application/json')\n )\n const response = yield* client\n .execute(httpRequest)\n .pipe(Effect.mapError(toHttpClientLlmError('OpenAI Codex request failed', true)))\n\n if (response.status < 200 || response.status >= 300) {\n const errorText = yield* response.text.pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'provider_error',\n message: `Could not read OpenAI Codex error body: ${error.message}`,\n retryable: false\n })\n )\n )\n\n const provider = classifyProviderFailure({\n provider: openAiCodexProvider,\n status: response.status,\n headers: response.headers,\n body: errorText\n })\n\n return yield* Effect.fail(\n new LLMError({\n cause: providerFailureCause(provider.kind),\n message: `OpenAI Codex returned ${response.status}`,\n retryable: providerFailureRetryable(provider.kind),\n provider\n })\n )\n }\n\n return response\n }).pipe(Effect.withSpan('OpenAiCodexProvider.stream'))\n\nexport const makeOpenAiCodexProviderLayer = (config: OpenAiCodexProviderConfig) =>\n Layer.effect(LLMProvider)(\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n\n return LLMProvider.of({\n stream: request =>\n Stream.fromEffect(sendOpenAiCodexRequest(config, request, client)).pipe(\n Stream.flatMap(streamOpenAiCodexResponse)\n )\n })\n })\n )\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"provider-error.d.mts","names":[],"sources":["../../src/providers/provider-error.ts"],"mappings":";;;KAMK,SAAA,GAAY,QAAQ,CAAC,MAAA;AAAA,KAErB,oBAAA;EAAA,SACM,QAAA;EAAA,SACA,MAAA;EAAA,SACA,OAAA,GAAU,SAAA;EAAA,SACV,IAAA;EAAA,SACA,OAAA;EAAA,SACA,YAAA;EAAA,SACA,YAAA,GAAe,mBAAmB;AAAA;AAAA,KAGxC,sBAAA;EAAA,SACM,QAAA;EAAA,SACA,IAAA,EAAM,mBAAmB;EAAA,SACzB,MAAA;EAAA,SACA,YAAA;EAAA,SACA,YAAA;AAAA;AAAA,KAGC,qBAAA,GAAwB,OAAO,CACzC,cAAA;AAAA,cAmBW,iBAAA,GAAqB,KAAyB;AAAA,cAQ9C,eAAA,GAAmB,KAAyB;AAAA,cAsB5C,uBAAA,GAA2B,OAA8B,EAArB,SAAS;AAAA,cAkF7C,mBAAA,GAAuB,KAAA,EAAO,oBAAA,KAAuB,mBACwB;AAAA,cAE7E,wBAAA,GAA4B,IAAyB,EAAnB,mBAAmB;AAAA,cAgBrD,oBAAA,GAAwB,IAAA,EAAM,mBAAA,KAAsB,qBAiBhE;AAAA,cAEY,iBAAA,GAAqB,KAAA,EAAO,sBAAA,KAAsB,iBAO3D;AAAA,cAES,uBAAA,GAA2B,KAAA,EAAO,oBAAA,KAAoB,iBAUlE"}
1
+ {"version":3,"file":"provider-error.d.mts","names":[],"sources":["../../src/providers/provider-error.ts"],"mappings":";;;KAMK,SAAA,GAAY,QAAQ,CAAC,MAAA;AAAA,KAErB,oBAAA;EAAA,SACM,QAAA;EAAA,SACA,MAAA;EAAA,SACA,OAAA,GAAU,SAAA;EAAA,SACV,IAAA;EAAA,SACA,OAAA;EAAA,SACA,YAAA;EAAA,SACA,YAAA,GAAe,mBAAmB;AAAA;AAAA,KAGxC,sBAAA;EAAA,SACM,QAAA;EAAA,SACA,IAAA,EAAM,mBAAmB;EAAA,SACzB,MAAA;EAAA,SACA,YAAA;EAAA,SACA,YAAA;AAAA;AAAA,KAGC,qBAAA,GAAwB,OAAO,CACzC,cAAA;AAAA,cAmBW,iBAAA,GAAqB,KAAyB;AAAA,cAQ9C,eAAA,GAAmB,KAAyB;AAAA,cAsB5C,uBAAA,GAA2B,OAA8B,EAArB,SAAS;AAAA,cAqF7C,mBAAA,GAAuB,KAAA,EAAO,oBAAA,KAAuB,mBACwB;AAAA,cAE7E,wBAAA,GAA4B,IAAyB,EAAnB,mBAAmB;AAAA,cAgBrD,oBAAA,GAAwB,IAAA,EAAM,mBAAA,KAAsB,qBAiBhE;AAAA,cAEY,iBAAA,GAAqB,KAAA,EAAO,sBAAA,KAAsB,iBAO3D;AAAA,cAES,uBAAA,GAA2B,KAAA,EAAO,oBAAA,KAAoB,iBAUlE"}
@@ -39,7 +39,7 @@ const kindFromSignal = (input) => {
39
39
  const signal = normalizedSignal(input);
40
40
  if (signal.includes("rate_limit") || signal.includes("rate limit") || signal.includes("too_many_requests") || signal.includes("too many request")) return "rate_limit";
41
41
  if (signal.includes("overloaded_error") || signal.includes("overloaded") || signal.includes("overload") || signal.includes("service unavailable")) return "overloaded";
42
- if (signal.includes("context_length") || signal.includes("context length") || signal.includes("context_overflow") || signal.includes("context overflow") || signal.includes("prompt is too long") || signal.includes("input is too long") || signal.includes("too many tokens") || signal.includes("input_length_error")) return "context_overflow";
42
+ if (signal.includes("context_length") || signal.includes("context length") || signal.includes("context_window_exceeded") || signal.includes("exceeds the context window") || signal.includes("context window exceeded") || signal.includes("context_overflow") || signal.includes("context overflow") || signal.includes("prompt is too long") || signal.includes("input is too long") || signal.includes("too many tokens") || signal.includes("input_length_error")) return "context_overflow";
43
43
  };
44
44
  const providerFailureKind = (input) => kindFromSignal(input) ?? kindFromStatus(input.status) ?? input.fallbackKind ?? "unknown";
45
45
  const providerFailureRetryable = (kind) => {
@@ -1 +1 @@
1
- {"version":3,"file":"provider-error.mjs","names":[],"sources":["../../src/providers/provider-error.ts"],"sourcesContent":["import {\n ProviderErrorInfo,\n type AgentErrorCode,\n type ProviderFailureKind\n} from '@yolk-sdk/agent/protocol'\n\ntype HeaderMap = Readonly<Record<string, string>>\n\ntype ProviderFailureInput = {\n readonly provider: string\n readonly status?: number\n readonly headers?: HeaderMap\n readonly body?: string\n readonly message?: string\n readonly providerCode?: string\n readonly fallbackKind?: ProviderFailureKind\n}\n\ntype ProviderErrorInfoInput = {\n readonly provider: string\n readonly kind: ProviderFailureKind\n readonly status?: number\n readonly providerCode?: string\n readonly retryAfterMs?: number\n}\n\nexport type ProviderLlmErrorCause = Extract<\n AgentErrorCode,\n 'provider_error' | 'rate_limit' | 'overloaded' | 'context_overflow' | 'invalid_response'\n>\n\nconst numericDelayMs = (value: number) =>\n Number.isFinite(value) && value >= 0 ? Math.floor(value) : undefined\n\nconst headerValue = (headers: HeaderMap, name: string) => {\n const lowerName = name.toLowerCase()\n\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === lowerName) {\n return value\n }\n }\n\n return undefined\n}\n\nexport const parseRetryAfterMs = (value: string | undefined) => {\n if (value === undefined) {\n return undefined\n }\n\n return numericDelayMs(Number(value.trim()))\n}\n\nexport const parseRetryAfter = (value: string | undefined) => {\n if (value === undefined) {\n return undefined\n }\n\n const trimmed = value.trim()\n const seconds = Number(trimmed)\n const secondsDelay = numericDelayMs(seconds * 1000)\n\n if (secondsDelay !== undefined) {\n return secondsDelay\n }\n\n const timestamp = Date.parse(trimmed)\n\n if (Number.isNaN(timestamp)) {\n return undefined\n }\n\n return numericDelayMs(timestamp - Date.now())\n}\n\nexport const retryAfterMsFromHeaders = (headers: HeaderMap | undefined) => {\n if (headers === undefined) {\n return undefined\n }\n\n return (\n parseRetryAfterMs(headerValue(headers, 'retry-after-ms')) ??\n parseRetryAfter(headerValue(headers, 'retry-after'))\n )\n}\n\nconst kindFromStatus = (status: number | undefined): ProviderFailureKind | undefined => {\n if (status === undefined) {\n return undefined\n }\n\n if (status === 429) {\n return 'rate_limit'\n }\n\n if (status === 529) {\n return 'overloaded'\n }\n\n if (status === 413) {\n return 'context_overflow'\n }\n\n if (status === 401 || status === 403) {\n return 'auth'\n }\n\n if (status >= 500) {\n return 'server_error'\n }\n\n return undefined\n}\n\nconst normalizedSignal = (input: ProviderFailureInput) =>\n [input.providerCode, input.message, input.body]\n .filter(value => value !== undefined)\n .join(' ')\n .toLowerCase()\n\nconst kindFromSignal = (input: ProviderFailureInput): ProviderFailureKind | undefined => {\n const signal = normalizedSignal(input)\n\n if (\n signal.includes('rate_limit') ||\n signal.includes('rate limit') ||\n signal.includes('too_many_requests') ||\n signal.includes('too many request')\n ) {\n return 'rate_limit'\n }\n\n if (\n signal.includes('overloaded_error') ||\n signal.includes('overloaded') ||\n signal.includes('overload') ||\n signal.includes('service unavailable')\n ) {\n return 'overloaded'\n }\n\n if (\n signal.includes('context_length') ||\n signal.includes('context length') ||\n signal.includes('context_overflow') ||\n signal.includes('context overflow') ||\n signal.includes('prompt is too long') ||\n signal.includes('input is too long') ||\n signal.includes('too many tokens') ||\n signal.includes('input_length_error')\n ) {\n return 'context_overflow'\n }\n\n return undefined\n}\n\nexport const providerFailureKind = (input: ProviderFailureInput): ProviderFailureKind =>\n kindFromSignal(input) ?? kindFromStatus(input.status) ?? input.fallbackKind ?? 'unknown'\n\nexport const providerFailureRetryable = (kind: ProviderFailureKind) => {\n switch (kind) {\n case 'rate_limit':\n case 'overloaded':\n case 'server_error':\n case 'network':\n case 'stream':\n return true\n case 'auth':\n case 'context_overflow':\n case 'invalid_response':\n case 'unknown':\n return false\n }\n}\n\nexport const providerFailureCause = (kind: ProviderFailureKind): ProviderLlmErrorCause => {\n switch (kind) {\n case 'rate_limit':\n return 'rate_limit'\n case 'overloaded':\n return 'overloaded'\n case 'context_overflow':\n return 'context_overflow'\n case 'invalid_response':\n return 'invalid_response'\n case 'auth':\n case 'network':\n case 'server_error':\n case 'stream':\n case 'unknown':\n return 'provider_error'\n }\n}\n\nexport const providerErrorInfo = (input: ProviderErrorInfoInput) =>\n ProviderErrorInfo.make({\n provider: input.provider,\n kind: input.kind,\n ...(input.status === undefined ? {} : { status: input.status }),\n ...(input.providerCode === undefined ? {} : { providerCode: input.providerCode }),\n ...(input.retryAfterMs === undefined ? {} : { retryAfterMs: input.retryAfterMs })\n })\n\nexport const classifyProviderFailure = (input: ProviderFailureInput) => {\n const kind = providerFailureKind(input)\n\n return providerErrorInfo({\n provider: input.provider,\n kind,\n ...(input.status === undefined ? {} : { status: input.status }),\n ...(input.providerCode === undefined ? {} : { providerCode: input.providerCode }),\n ...(input.headers === undefined ? {} : { retryAfterMs: retryAfterMsFromHeaders(input.headers) })\n })\n}\n"],"mappings":";;AA+BA,MAAM,kBAAkB,UACtB,OAAO,SAAS,KAAK,KAAK,SAAS,IAAI,KAAK,MAAM,KAAK,IAAI,KAAA;AAE7D,MAAM,eAAe,SAAoB,SAAiB;CACxD,MAAM,YAAY,KAAK,YAAY;CAEnC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,GAC/C,IAAI,IAAI,YAAY,MAAM,WACxB,OAAO;AAKb;AAEA,MAAa,qBAAqB,UAA8B;CAC9D,IAAI,UAAU,KAAA,GACZ;CAGF,OAAO,eAAe,OAAO,MAAM,KAAK,CAAC,CAAC;AAC5C;AAEA,MAAa,mBAAmB,UAA8B;CAC5D,IAAI,UAAU,KAAA,GACZ;CAGF,MAAM,UAAU,MAAM,KAAK;CAE3B,MAAM,eAAe,eADL,OAAO,OACmB,IAAI,GAAI;CAElD,IAAI,iBAAiB,KAAA,GACnB,OAAO;CAGT,MAAM,YAAY,KAAK,MAAM,OAAO;CAEpC,IAAI,OAAO,MAAM,SAAS,GACxB;CAGF,OAAO,eAAe,YAAY,KAAK,IAAI,CAAC;AAC9C;AAEA,MAAa,2BAA2B,YAAmC;CACzE,IAAI,YAAY,KAAA,GACd;CAGF,OACE,kBAAkB,YAAY,SAAS,gBAAgB,CAAC,KACxD,gBAAgB,YAAY,SAAS,aAAa,CAAC;AAEvD;AAEA,MAAM,kBAAkB,WAAgE;CACtF,IAAI,WAAW,KAAA,GACb;CAGF,IAAI,WAAW,KACb,OAAO;CAGT,IAAI,WAAW,KACb,OAAO;CAGT,IAAI,WAAW,KACb,OAAO;CAGT,IAAI,WAAW,OAAO,WAAW,KAC/B,OAAO;CAGT,IAAI,UAAU,KACZ,OAAO;AAIX;AAEA,MAAM,oBAAoB,UACxB;CAAC,MAAM;CAAc,MAAM;CAAS,MAAM;AAAI,EAC3C,QAAO,UAAS,UAAU,KAAA,CAAS,EACnC,KAAK,GAAG,EACR,YAAY;AAEjB,MAAM,kBAAkB,UAAiE;CACvF,MAAM,SAAS,iBAAiB,KAAK;CAErC,IACE,OAAO,SAAS,YAAY,KAC5B,OAAO,SAAS,YAAY,KAC5B,OAAO,SAAS,mBAAmB,KACnC,OAAO,SAAS,kBAAkB,GAElC,OAAO;CAGT,IACE,OAAO,SAAS,kBAAkB,KAClC,OAAO,SAAS,YAAY,KAC5B,OAAO,SAAS,UAAU,KAC1B,OAAO,SAAS,qBAAqB,GAErC,OAAO;CAGT,IACE,OAAO,SAAS,gBAAgB,KAChC,OAAO,SAAS,gBAAgB,KAChC,OAAO,SAAS,kBAAkB,KAClC,OAAO,SAAS,kBAAkB,KAClC,OAAO,SAAS,oBAAoB,KACpC,OAAO,SAAS,mBAAmB,KACnC,OAAO,SAAS,iBAAiB,KACjC,OAAO,SAAS,oBAAoB,GAEpC,OAAO;AAIX;AAEA,MAAa,uBAAuB,UAClC,eAAe,KAAK,KAAK,eAAe,MAAM,MAAM,KAAK,MAAM,gBAAgB;AAEjF,MAAa,4BAA4B,SAA8B;CACrE,QAAQ,MAAR;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,UACH,OAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,WACH,OAAO;CACX;AACF;AAEA,MAAa,wBAAwB,SAAqD;CACxF,QAAQ,MAAR;EACE,KAAK,cACH,OAAO;EACT,KAAK,cACH,OAAO;EACT,KAAK,oBACH,OAAO;EACT,KAAK,oBACH,OAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,WACH,OAAO;CACX;AACF;AAEA,MAAa,qBAAqB,UAChC,kBAAkB,KAAK;CACrB,UAAU,MAAM;CAChB,MAAM,MAAM;CACZ,GAAI,MAAM,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO;CAC7D,GAAI,MAAM,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc,MAAM,aAAa;CAC/E,GAAI,MAAM,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc,MAAM,aAAa;AACjF,CAAC;AAEH,MAAa,2BAA2B,UAAgC;CACtE,MAAM,OAAO,oBAAoB,KAAK;CAEtC,OAAO,kBAAkB;EACvB,UAAU,MAAM;EAChB;EACA,GAAI,MAAM,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO;EAC7D,GAAI,MAAM,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc,MAAM,aAAa;EAC/E,GAAI,MAAM,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc,wBAAwB,MAAM,OAAO,EAAE;CAChG,CAAC;AACH"}
1
+ {"version":3,"file":"provider-error.mjs","names":[],"sources":["../../src/providers/provider-error.ts"],"sourcesContent":["import {\n ProviderErrorInfo,\n type AgentErrorCode,\n type ProviderFailureKind\n} from '@yolk-sdk/agent/protocol'\n\ntype HeaderMap = Readonly<Record<string, string>>\n\ntype ProviderFailureInput = {\n readonly provider: string\n readonly status?: number\n readonly headers?: HeaderMap\n readonly body?: string\n readonly message?: string\n readonly providerCode?: string\n readonly fallbackKind?: ProviderFailureKind\n}\n\ntype ProviderErrorInfoInput = {\n readonly provider: string\n readonly kind: ProviderFailureKind\n readonly status?: number\n readonly providerCode?: string\n readonly retryAfterMs?: number\n}\n\nexport type ProviderLlmErrorCause = Extract<\n AgentErrorCode,\n 'provider_error' | 'rate_limit' | 'overloaded' | 'context_overflow' | 'invalid_response'\n>\n\nconst numericDelayMs = (value: number) =>\n Number.isFinite(value) && value >= 0 ? Math.floor(value) : undefined\n\nconst headerValue = (headers: HeaderMap, name: string) => {\n const lowerName = name.toLowerCase()\n\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === lowerName) {\n return value\n }\n }\n\n return undefined\n}\n\nexport const parseRetryAfterMs = (value: string | undefined) => {\n if (value === undefined) {\n return undefined\n }\n\n return numericDelayMs(Number(value.trim()))\n}\n\nexport const parseRetryAfter = (value: string | undefined) => {\n if (value === undefined) {\n return undefined\n }\n\n const trimmed = value.trim()\n const seconds = Number(trimmed)\n const secondsDelay = numericDelayMs(seconds * 1000)\n\n if (secondsDelay !== undefined) {\n return secondsDelay\n }\n\n const timestamp = Date.parse(trimmed)\n\n if (Number.isNaN(timestamp)) {\n return undefined\n }\n\n return numericDelayMs(timestamp - Date.now())\n}\n\nexport const retryAfterMsFromHeaders = (headers: HeaderMap | undefined) => {\n if (headers === undefined) {\n return undefined\n }\n\n return (\n parseRetryAfterMs(headerValue(headers, 'retry-after-ms')) ??\n parseRetryAfter(headerValue(headers, 'retry-after'))\n )\n}\n\nconst kindFromStatus = (status: number | undefined): ProviderFailureKind | undefined => {\n if (status === undefined) {\n return undefined\n }\n\n if (status === 429) {\n return 'rate_limit'\n }\n\n if (status === 529) {\n return 'overloaded'\n }\n\n if (status === 413) {\n return 'context_overflow'\n }\n\n if (status === 401 || status === 403) {\n return 'auth'\n }\n\n if (status >= 500) {\n return 'server_error'\n }\n\n return undefined\n}\n\nconst normalizedSignal = (input: ProviderFailureInput) =>\n [input.providerCode, input.message, input.body]\n .filter(value => value !== undefined)\n .join(' ')\n .toLowerCase()\n\nconst kindFromSignal = (input: ProviderFailureInput): ProviderFailureKind | undefined => {\n const signal = normalizedSignal(input)\n\n if (\n signal.includes('rate_limit') ||\n signal.includes('rate limit') ||\n signal.includes('too_many_requests') ||\n signal.includes('too many request')\n ) {\n return 'rate_limit'\n }\n\n if (\n signal.includes('overloaded_error') ||\n signal.includes('overloaded') ||\n signal.includes('overload') ||\n signal.includes('service unavailable')\n ) {\n return 'overloaded'\n }\n\n if (\n signal.includes('context_length') ||\n signal.includes('context length') ||\n signal.includes('context_window_exceeded') ||\n signal.includes('exceeds the context window') ||\n signal.includes('context window exceeded') ||\n signal.includes('context_overflow') ||\n signal.includes('context overflow') ||\n signal.includes('prompt is too long') ||\n signal.includes('input is too long') ||\n signal.includes('too many tokens') ||\n signal.includes('input_length_error')\n ) {\n return 'context_overflow'\n }\n\n return undefined\n}\n\nexport const providerFailureKind = (input: ProviderFailureInput): ProviderFailureKind =>\n kindFromSignal(input) ?? kindFromStatus(input.status) ?? input.fallbackKind ?? 'unknown'\n\nexport const providerFailureRetryable = (kind: ProviderFailureKind) => {\n switch (kind) {\n case 'rate_limit':\n case 'overloaded':\n case 'server_error':\n case 'network':\n case 'stream':\n return true\n case 'auth':\n case 'context_overflow':\n case 'invalid_response':\n case 'unknown':\n return false\n }\n}\n\nexport const providerFailureCause = (kind: ProviderFailureKind): ProviderLlmErrorCause => {\n switch (kind) {\n case 'rate_limit':\n return 'rate_limit'\n case 'overloaded':\n return 'overloaded'\n case 'context_overflow':\n return 'context_overflow'\n case 'invalid_response':\n return 'invalid_response'\n case 'auth':\n case 'network':\n case 'server_error':\n case 'stream':\n case 'unknown':\n return 'provider_error'\n }\n}\n\nexport const providerErrorInfo = (input: ProviderErrorInfoInput) =>\n ProviderErrorInfo.make({\n provider: input.provider,\n kind: input.kind,\n ...(input.status === undefined ? {} : { status: input.status }),\n ...(input.providerCode === undefined ? {} : { providerCode: input.providerCode }),\n ...(input.retryAfterMs === undefined ? {} : { retryAfterMs: input.retryAfterMs })\n })\n\nexport const classifyProviderFailure = (input: ProviderFailureInput) => {\n const kind = providerFailureKind(input)\n\n return providerErrorInfo({\n provider: input.provider,\n kind,\n ...(input.status === undefined ? {} : { status: input.status }),\n ...(input.providerCode === undefined ? {} : { providerCode: input.providerCode }),\n ...(input.headers === undefined ? {} : { retryAfterMs: retryAfterMsFromHeaders(input.headers) })\n })\n}\n"],"mappings":"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"}
@@ -17,8 +17,8 @@ declare const mergeSkillsets: (sources: ReadonlyArray<SkillsetSource>) => Effect
17
17
  skills: {
18
18
  readonly name: string;
19
19
  readonly description: string;
20
- readonly content: string;
21
20
  readonly location: string;
21
+ readonly content: string;
22
22
  readonly source?: string | undefined;
23
23
  }[];
24
24
  commands: {
@@ -3,8 +3,8 @@ import { Effect } from "effect";
3
3
 
4
4
  //#region src/skillset/name.d.ts
5
5
  declare const isValidSkillsetName: (name: string) => boolean;
6
- declare const validateSkillsetName: (name: string) => Effect.Effect<string, never, never> | Effect.Effect<never, SkillsetError, never>;
7
- declare const validateDirectoryName: (expected: string, actual: string) => Effect.Effect<string, never, never> | Effect.Effect<never, SkillsetError, never>;
6
+ declare const validateSkillsetName: (name: string) => Effect.Effect<never, SkillsetError, never> | Effect.Effect<string, never, never>;
7
+ declare const validateDirectoryName: (expected: string, actual: string) => Effect.Effect<never, SkillsetError, never> | Effect.Effect<string, never, never>;
8
8
  //#endregion
9
9
  export { isValidSkillsetName, validateDirectoryName, validateSkillsetName };
10
10
  //# sourceMappingURL=name.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"name.d.mts","names":[],"sources":["../../src/skillset/name.ts"],"mappings":";;;;cAMa,mBAAA,GAAuB,IAAY;AAAA,cAGnC,oBAAA,GAAwB,IAAA,aAAY,MAAA,CAAA,MAAA,yBAAA,MAAA,CAAA,MAAA,QAAA,aAAA;AAAA,cAUpC,qBAAA,GAAyB,QAAA,UAAkB,MAAA,aAAc,MAAA,CAAA,MAAA,yBAAA,MAAA,CAAA,MAAA,QAAA,aAAA"}
1
+ {"version":3,"file":"name.d.mts","names":[],"sources":["../../src/skillset/name.ts"],"mappings":";;;;cAMa,mBAAA,GAAuB,IAAY;AAAA,cAGnC,oBAAA,GAAwB,IAAA,aAAY,MAAA,CAAA,MAAA,QAAA,aAAA,WAAA,MAAA,CAAA,MAAA;AAAA,cAUpC,qBAAA,GAAyB,QAAA,UAAkB,MAAA,aAAc,MAAA,CAAA,MAAA,QAAA,aAAA,WAAA,MAAA,CAAA,MAAA"}
@@ -1,4 +1,4 @@
1
1
  import { EmptyToolParams, ModelVisibleToolError, ModelVisibleToolErrorInput, ModelVisibleToolErrorReason, ModelVisibleToolErrorStructuredContent, ModelVisibleToolErrorStructuredContentSchema, ResolvedToolSet, SchemaToolExecutionInput, ToolAccess, ToolExecutionInput, ToolMetadata, ToolModule, ToolRegistration, ToolRegistryError, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, resolveTools } from "./registry.mjs";
2
2
  import { QuestionExecutionInput, QuestionToolOptions, makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, questionToolName } from "./question.mjs";
3
- import { SubagentContext, SubagentDefinition, SubagentExecutionInput, SubagentModelDefinition, SubagentReasoningEffortDefinition, SubagentRuntimeSelectionOptions, SubagentToolOptions, SubagentToolParams, SubagentToolResultInput, formatSubagentResult, makeNonRecursiveSubagentToolModule, makeSubagentToolDef, makeSubagentToolModule, makeSubagentToolRegistration, makeSubagentToolResult, subagentResultText, subagentToolName, subagentToolRunId } from "./subagent.mjs";
4
- export { EmptyToolParams, ModelVisibleToolError, type ModelVisibleToolErrorInput, ModelVisibleToolErrorReason, type ModelVisibleToolErrorStructuredContent, ModelVisibleToolErrorStructuredContentSchema, type QuestionExecutionInput, type QuestionToolOptions, type ResolvedToolSet, type SchemaToolExecutionInput, type SubagentContext, type SubagentDefinition, type SubagentExecutionInput, type SubagentModelDefinition, type SubagentReasoningEffortDefinition, type SubagentRuntimeSelectionOptions, type SubagentToolOptions, type SubagentToolParams, type SubagentToolResultInput, ToolAccess, type ToolExecutionInput, type ToolMetadata, type ToolModule, type ToolRegistration, ToolRegistryError, formatSubagentResult, makeNonRecursiveSubagentToolModule, makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, makeSubagentToolDef, makeSubagentToolModule, makeSubagentToolRegistration, makeSubagentToolResult, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, questionToolName, resolveTools, subagentResultText, subagentToolName, subagentToolRunId };
3
+ import { SubagentContext, SubagentDefinition, SubagentExecutionInput, SubagentModelDefinition, SubagentReasoningEffortDefinition, SubagentRunError, SubagentRunResult, SubagentRunStatus, SubagentRuntimeSelectionOptions, SubagentToolOptions, SubagentToolParams, SubagentToolResultInput, formatSubagentResult, makeNonRecursiveSubagentToolModule, makeSubagentToolDef, makeSubagentToolModule, makeSubagentToolRegistration, makeSubagentToolResult, subagentResultFromEvents, subagentResultText, subagentToolName, subagentToolRunId, subagentUsageFromToolResult } from "./subagent.mjs";
4
+ export { EmptyToolParams, ModelVisibleToolError, type ModelVisibleToolErrorInput, ModelVisibleToolErrorReason, type ModelVisibleToolErrorStructuredContent, ModelVisibleToolErrorStructuredContentSchema, type QuestionExecutionInput, type QuestionToolOptions, type ResolvedToolSet, type SchemaToolExecutionInput, type SubagentContext, type SubagentDefinition, type SubagentExecutionInput, type SubagentModelDefinition, type SubagentReasoningEffortDefinition, type SubagentRunError, type SubagentRunResult, type SubagentRunStatus, type SubagentRuntimeSelectionOptions, type SubagentToolOptions, type SubagentToolParams, type SubagentToolResultInput, ToolAccess, type ToolExecutionInput, type ToolMetadata, type ToolModule, type ToolRegistration, ToolRegistryError, formatSubagentResult, makeNonRecursiveSubagentToolModule, makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, makeSubagentToolDef, makeSubagentToolModule, makeSubagentToolRegistration, makeSubagentToolResult, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, questionToolName, resolveTools, subagentResultFromEvents, subagentResultText, subagentToolName, subagentToolRunId, subagentUsageFromToolResult };
@@ -1,4 +1,4 @@
1
1
  import { EmptyToolParams, ModelVisibleToolError, ModelVisibleToolErrorReason, ModelVisibleToolErrorStructuredContentSchema, ToolAccess, ToolRegistryError, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, resolveTools } from "./registry.mjs";
2
2
  import { makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, questionToolName } from "./question.mjs";
3
- import { formatSubagentResult, makeNonRecursiveSubagentToolModule, makeSubagentToolDef, makeSubagentToolModule, makeSubagentToolRegistration, makeSubagentToolResult, subagentResultText, subagentToolName, subagentToolRunId } from "./subagent.mjs";
4
- export { EmptyToolParams, ModelVisibleToolError, ModelVisibleToolErrorReason, ModelVisibleToolErrorStructuredContentSchema, ToolAccess, ToolRegistryError, formatSubagentResult, makeNonRecursiveSubagentToolModule, makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, makeSubagentToolDef, makeSubagentToolModule, makeSubagentToolRegistration, makeSubagentToolResult, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, questionToolName, resolveTools, subagentResultText, subagentToolName, subagentToolRunId };
3
+ import { formatSubagentResult, makeNonRecursiveSubagentToolModule, makeSubagentToolDef, makeSubagentToolModule, makeSubagentToolRegistration, makeSubagentToolResult, subagentResultFromEvents, subagentResultText, subagentToolName, subagentToolRunId, subagentUsageFromToolResult } from "./subagent.mjs";
4
+ export { EmptyToolParams, ModelVisibleToolError, ModelVisibleToolErrorReason, ModelVisibleToolErrorStructuredContentSchema, ToolAccess, ToolRegistryError, formatSubagentResult, makeNonRecursiveSubagentToolModule, makeQuestionToolDef, makeQuestionToolModule, makeQuestionToolRegistration, makeSubagentToolDef, makeSubagentToolModule, makeSubagentToolRegistration, makeSubagentToolResult, makeTool, makeToolExecutorLayer, modelVisibleToolError, modelVisibleToolErrorResult, modelVisibleToolErrorStructuredContent, questionToolName, resolveTools, subagentResultFromEvents, subagentResultText, subagentToolName, subagentToolRunId, subagentUsageFromToolResult };
@@ -1,6 +1,6 @@
1
1
  import { ToolModule, ToolRegistration, ToolRegistryError } from "./registry.mjs";
2
2
  import { Effect } from "effect";
3
- import { AgentEvent, AgentReasoningEffort, ToolCall, ToolResult } from "@yolk-sdk/agent/protocol";
3
+ import { AgentErrorCode, AgentEvent, AgentReasoningEffort, AgentUsage, HitlRequest, ProviderErrorInfo, ToolCall, ToolResult } from "@yolk-sdk/agent/protocol";
4
4
  import { ToolError } from "@yolk-sdk/agent/loop";
5
5
 
6
6
  //#region src/tools/subagent.d.ts
@@ -41,6 +41,21 @@ type SubagentToolOptions<Context> = SubagentRuntimeSelectionOptions & {
41
41
  readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>;
42
42
  readonly execute: (input: SubagentExecutionInput<Context>) => Effect.Effect<ToolResult, ToolError>;
43
43
  };
44
+ type SubagentRunError = {
45
+ readonly code: AgentErrorCode;
46
+ readonly message: string;
47
+ readonly retryable: boolean;
48
+ readonly provider?: ProviderErrorInfo;
49
+ };
50
+ type SubagentRunStatus = 'completed' | 'awaiting_input' | 'error';
51
+ type SubagentRunResult = {
52
+ readonly status: SubagentRunStatus;
53
+ readonly text: string;
54
+ readonly usage?: AgentUsage;
55
+ readonly turns?: number;
56
+ readonly requests?: ReadonlyArray<HitlRequest>;
57
+ readonly error?: SubagentRunError;
58
+ };
44
59
  type SubagentToolResultInput = {
45
60
  readonly callId: string;
46
61
  readonly output: string;
@@ -51,6 +66,11 @@ type SubagentToolResultInput = {
51
66
  readonly endedAtMs: number;
52
67
  readonly model: string;
53
68
  readonly reasoningEffort?: AgentReasoningEffort;
69
+ readonly usage?: AgentUsage;
70
+ readonly turns?: number;
71
+ readonly status?: SubagentRunStatus;
72
+ readonly requests?: ReadonlyArray<HitlRequest>;
73
+ readonly error?: SubagentRunError;
54
74
  readonly isError?: boolean;
55
75
  };
56
76
  declare const makeSubagentToolRegistration: <Context>(options: SubagentToolOptions<Context>) => ToolRegistration<Context>;
@@ -59,8 +79,10 @@ declare const makeSubagentToolModule: <Context>(options: SubagentToolOptions<Con
59
79
  declare const makeNonRecursiveSubagentToolModule: <Context extends SubagentContext>(options: SubagentToolOptions<Context>) => ToolModule<Context>;
60
80
  declare const formatSubagentResult: (output: string) => string;
61
81
  declare const subagentToolRunId: (parentToolCallId: string) => string;
82
+ declare const subagentUsageFromToolResult: (result: ToolResult) => AgentUsage | undefined;
83
+ declare const subagentResultFromEvents: (events: ReadonlyArray<AgentEvent>) => SubagentRunResult;
62
84
  declare const subagentResultText: (events: ReadonlyArray<AgentEvent>) => string;
63
85
  declare const makeSubagentToolResult: (input: SubagentToolResultInput) => ToolResult;
64
86
  //#endregion
65
- export { SubagentContext, SubagentDefinition, SubagentExecutionInput, SubagentModelDefinition, SubagentReasoningEffortDefinition, SubagentRuntimeSelectionOptions, SubagentToolOptions, SubagentToolParams, SubagentToolResultInput, formatSubagentResult, makeNonRecursiveSubagentToolModule, makeSubagentToolDef, makeSubagentToolModule, makeSubagentToolRegistration, makeSubagentToolResult, subagentResultText, subagentToolName, subagentToolRunId };
87
+ export { SubagentContext, SubagentDefinition, SubagentExecutionInput, SubagentModelDefinition, SubagentReasoningEffortDefinition, SubagentRunError, SubagentRunResult, SubagentRunStatus, SubagentRuntimeSelectionOptions, SubagentToolOptions, SubagentToolParams, SubagentToolResultInput, formatSubagentResult, makeNonRecursiveSubagentToolModule, makeSubagentToolDef, makeSubagentToolModule, makeSubagentToolRegistration, makeSubagentToolResult, subagentResultFromEvents, subagentResultText, subagentToolName, subagentToolRunId, subagentUsageFromToolResult };
66
88
  //# sourceMappingURL=subagent.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"subagent.d.mts","names":[],"sources":["../../src/tools/subagent.ts"],"mappings":";;;;;;cAsBa,gBAAA;AAAA,KAiBD,kBAAA;EAAA,SACD,WAAA;EAAA,SACA,MAAA;EAAA,SACA,aAAA;EAAA,SACA,KAAA;EAAA,SACA,gBAAA,GAAmB,oBAAoB;AAAA;AAAA,KAGtC,kBAAA;EAAA,SACD,IAAA;EAAA,SACA,WAAW;AAAA;AAAA,KAGV,uBAAA;EAAA,SACD,EAAA;EAAA,SACA,WAAW;AAAA;AAAA,KAGV,iCAAA;EAAA,SACD,KAAA,EAAO,oBAAoB;EAAA,SAC3B,WAAA;AAAA;AAAA,KAGC,+BAAA;EAAA,SACD,MAAA,GAAS,aAAA,CAAc,uBAAA;EAAA,SACvB,gBAAA,GAAmB,aAAA,CAAc,iCAAA;AAAA;AAAA,KAGhC,eAAA;EAAA,SACD,QAAQ;AAAA;AAAA,KAGP,sBAAA;EAAA,SACD,IAAA,EAAM,QAAA;EAAA,SACN,OAAA,EAAS,OAAA;EAAA,SACT,MAAA,EAAQ,kBAAA;AAAA;AAAA,KAGP,mBAAA,YAA+B,+BAAA;EAAA,SAChC,SAAA,EAAW,aAAA,CAAc,kBAAA;EAAA,SACzB,SAAA,IAAa,OAAA,EAAS,OAAA,KAAY,MAAA,CAAO,MAAA,UAAgB,iBAAA;EAAA,SACzD,OAAA,GAAU,KAAA,EAAO,sBAAA,CAAuB,OAAA,MAAa,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,SAAA;AAAA;AAAA,KAG9E,uBAAA;EAAA,SACD,MAAA;EAAA,SACA,MAAA;EAAA,SACA,YAAA;EAAA,SACA,WAAA;EAAA,SACA,aAAA;EAAA,SACA,WAAA;EAAA,SACA,SAAA;EAAA,SACA,KAAA;EAAA,SACA,eAAA,GAAkB,oBAAoB;EAAA,SACtC,OAAA;AAAA;AAAA,cA2JE,4BAAA,YACX,OAAA,EAAS,mBAAA,CAAoB,OAAA,MAC5B,gBAAA,CAAiB,OAAA;AAAA,cAwBP,mBAAA,GACX,SAAA,EAAW,aAAA,CAAc,kBAAA,GACzB,iBAAA,GAAmB,+BAAA,wCAAoC,OAAA;AAAA,cAQ5C,sBAAA,YACX,OAAA,EAAS,mBAAA,CAAoB,OAAA,MAC5B,UAAA,CAAW,OAAA;AAAA,cAKD,kCAAA,mBAAsD,eAAA,EACjE,OAAA,EAAS,mBAAA,CAAoB,OAAA,MAC5B,UAAA,CAAW,OAAA;AAAA,cAWD,oBAAA,GAAwB,MAAc;AAAA,cAGtC,iBAAA,GAAiB,gBAAA;AAAA,cAQjB,kBAAA,GAAsB,MAAA,EAAQ,aAAa,CAAC,UAAA;AAAA,cAO5C,sBAAA,GAA0B,KAAA,EAAO,uBAAA,KAAuB,UAgBjE"}
1
+ {"version":3,"file":"subagent.d.mts","names":[],"sources":["../../src/tools/subagent.ts"],"mappings":";;;;;;cA6Ba,gBAAA;AAAA,KAiBD,kBAAA;EAAA,SACD,WAAA;EAAA,SACA,MAAA;EAAA,SACA,aAAA;EAAA,SACA,KAAA;EAAA,SACA,gBAAA,GAAmB,oBAAoB;AAAA;AAAA,KAGtC,kBAAA;EAAA,SACD,IAAA;EAAA,SACA,WAAW;AAAA;AAAA,KAGV,uBAAA;EAAA,SACD,EAAA;EAAA,SACA,WAAW;AAAA;AAAA,KAGV,iCAAA;EAAA,SACD,KAAA,EAAO,oBAAoB;EAAA,SAC3B,WAAA;AAAA;AAAA,KAGC,+BAAA;EAAA,SACD,MAAA,GAAS,aAAA,CAAc,uBAAA;EAAA,SACvB,gBAAA,GAAmB,aAAA,CAAc,iCAAA;AAAA;AAAA,KAGhC,eAAA;EAAA,SACD,QAAQ;AAAA;AAAA,KAGP,sBAAA;EAAA,SACD,IAAA,EAAM,QAAA;EAAA,SACN,OAAA,EAAS,OAAA;EAAA,SACT,MAAA,EAAQ,kBAAA;AAAA;AAAA,KAGP,mBAAA,YAA+B,+BAAA;EAAA,SAChC,SAAA,EAAW,aAAA,CAAc,kBAAA;EAAA,SACzB,SAAA,IAAa,OAAA,EAAS,OAAA,KAAY,MAAA,CAAO,MAAA,UAAgB,iBAAA;EAAA,SACzD,OAAA,GAAU,KAAA,EAAO,sBAAA,CAAuB,OAAA,MAAa,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,SAAA;AAAA;AAAA,KAG9E,gBAAA;EAAA,SACD,IAAA,EAAM,cAAA;EAAA,SACN,OAAA;EAAA,SACA,SAAA;EAAA,SACA,QAAA,GAAW,iBAAiB;AAAA;AAAA,KAG3B,iBAAA;AAAA,KAEA,iBAAA;EAAA,SACD,MAAA,EAAQ,iBAAA;EAAA,SACR,IAAA;EAAA,SACA,KAAA,GAAQ,UAAA;EAAA,SACR,KAAA;EAAA,SACA,QAAA,GAAW,aAAA,CAAc,WAAA;EAAA,SACzB,KAAA,GAAQ,gBAAA;AAAA;AAAA,KAGP,uBAAA;EAAA,SACD,MAAA;EAAA,SACA,MAAA;EAAA,SACA,YAAA;EAAA,SACA,WAAA;EAAA,SACA,aAAA;EAAA,SACA,WAAA;EAAA,SACA,SAAA;EAAA,SACA,KAAA;EAAA,SACA,eAAA,GAAkB,oBAAA;EAAA,SAClB,KAAA,GAAQ,UAAA;EAAA,SACR,KAAA;EAAA,SACA,MAAA,GAAS,iBAAA;EAAA,SACT,QAAA,GAAW,aAAA,CAAc,WAAA;EAAA,SACzB,KAAA,GAAQ,gBAAA;EAAA,SACR,OAAA;AAAA;AAAA,cA2JE,4BAAA,YACX,OAAA,EAAS,mBAAA,CAAoB,OAAA,MAC5B,gBAAA,CAAiB,OAAA;AAAA,cAwBP,mBAAA,GACX,SAAA,EAAW,aAAA,CAAc,kBAAA,GACzB,iBAAA,GAAmB,+BAAA,wCAAoC,OAAA;AAAA,cAQ5C,sBAAA,YACX,OAAA,EAAS,mBAAA,CAAoB,OAAA,MAC5B,UAAA,CAAW,OAAA;AAAA,cAKD,kCAAA,mBAAsD,eAAA,EACjE,OAAA,EAAS,mBAAA,CAAoB,OAAA,MAC5B,UAAA,CAAW,OAAA;AAAA,cAWD,oBAAA,GAAwB,MAAc;AAAA,cAGtC,iBAAA,GAAiB,gBAAA;AAAA,cAyDjB,2BAAA,GAA+B,MAAA,EAAQ,UAAA,KAAa,UAAU;AAAA,cAyB9D,wBAAA,GAA4B,MAAA,EAAQ,aAAA,CAAc,UAAA,MAAc,iBAAA;AAAA,cAsDhE,kBAAA,GAAsB,MAAA,EAAQ,aAAa,CAAC,UAAA;AAAA,cAG5C,sBAAA,GAA0B,KAAA,EAAO,uBAAA,KAAuB,UAwBpE"}
@@ -1,6 +1,6 @@
1
1
  import { makeTool, modelVisibleToolError } from "./registry.mjs";
2
2
  import { Effect } from "effect";
3
- import { ToolResult, assistantContent, contentText, makeSubagentRunId } from "@yolk-sdk/agent/protocol";
3
+ import { AgentUsage, ToolResult, addAgentUsage, assistantContent, contentText, isTerminalAgentEvent, makeSubagentRunId, zeroAgentUsage } from "@yolk-sdk/agent/protocol";
4
4
  import * as Schema from "effect/Schema";
5
5
  import { ToolError } from "@yolk-sdk/agent/loop";
6
6
  //#region src/tools/subagent.ts
@@ -131,27 +131,133 @@ const latestAssistantText = (messages) => {
131
131
  const assistant = [...messages].reverse().find((message) => message._tag === "Assistant");
132
132
  return assistant === void 0 ? "" : contentText(assistantContent(assistant));
133
133
  };
134
- const subagentResultText = (events) => {
135
- const text = latestAssistantText([...events].reverse().find((event) => event._tag === "AgentEnd")?.messages ?? []).trim();
136
- return text.length === 0 ? "Subagent completed without a final text response." : text;
137
- };
138
- const makeSubagentToolResult = (input) => ToolResult.make({
139
- toolCallId: input.callId,
140
- content: formatSubagentResult(input.output),
141
- isError: input.isError,
142
- structuredContent: {
143
- subagent_run_id: input.subagentRunId,
144
- subagent_type: input.subagentType,
145
- description: input.description,
146
- started_at_ms: input.startedAtMs,
147
- ended_at_ms: input.endedAtMs,
148
- duration_ms: Math.max(0, input.endedAtMs - input.startedAtMs),
149
- status: input.isError === true ? "error" : "completed",
150
- model: input.model,
151
- ...input.reasoningEffort === void 0 ? {} : { reasoning_effort: input.reasoningEffort }
134
+ const subagentProviderMetadata = (provider) => ({
135
+ provider: provider.provider,
136
+ kind: provider.kind,
137
+ ...provider.status === void 0 ? {} : { status: provider.status },
138
+ ...provider.providerCode === void 0 ? {} : { provider_code: provider.providerCode },
139
+ ...provider.retryAfterMs === void 0 ? {} : { retry_after_ms: provider.retryAfterMs }
140
+ });
141
+ const subagentUsageMetadata = (usage) => ({
142
+ input: {
143
+ total: usage.input.total,
144
+ ...usage.input.uncached === void 0 ? {} : { uncached: usage.input.uncached },
145
+ ...usage.input.cacheRead === void 0 ? {} : { cache_read: usage.input.cacheRead },
146
+ ...usage.input.cacheWrite === void 0 ? {} : { cache_write: usage.input.cacheWrite }
147
+ },
148
+ output: {
149
+ total: usage.output.total,
150
+ ...usage.output.text === void 0 ? {} : { text: usage.output.text },
151
+ ...usage.output.reasoning === void 0 ? {} : { reasoning: usage.output.reasoning }
152
152
  }
153
153
  });
154
+ const subagentErrorMetadata = (error) => ({
155
+ code: error.code,
156
+ message: error.message,
157
+ retryable: error.retryable,
158
+ ...error.provider === void 0 ? {} : { provider: subagentProviderMetadata(error.provider) }
159
+ });
160
+ const SubagentUsageMetadata = Schema.Struct({
161
+ input: Schema.Struct({
162
+ total: Schema.Number,
163
+ uncached: Schema.optional(Schema.Number),
164
+ cache_read: Schema.optional(Schema.Number),
165
+ cache_write: Schema.optional(Schema.Number)
166
+ }),
167
+ output: Schema.Struct({
168
+ total: Schema.Number,
169
+ text: Schema.optional(Schema.Number),
170
+ reasoning: Schema.optional(Schema.Number)
171
+ })
172
+ });
173
+ const SubagentStructuredUsage = Schema.Struct({
174
+ subagent_run_id: Schema.String,
175
+ subagent_type: Schema.String,
176
+ usage: SubagentUsageMetadata
177
+ });
178
+ const subagentUsageFromToolResult = (result) => {
179
+ if (!Schema.is(SubagentStructuredUsage)(result.structuredContent) || result.structuredContent.subagent_run_id !== subagentToolRunId(result.toolCallId)) return;
180
+ const usage = result.structuredContent.usage;
181
+ return AgentUsage.make({
182
+ input: {
183
+ total: usage.input.total,
184
+ ...usage.input.uncached === void 0 ? {} : { uncached: usage.input.uncached },
185
+ ...usage.input.cache_read === void 0 ? {} : { cacheRead: usage.input.cache_read },
186
+ ...usage.input.cache_write === void 0 ? {} : { cacheWrite: usage.input.cache_write }
187
+ },
188
+ output: {
189
+ total: usage.output.total,
190
+ ...usage.output.text === void 0 ? {} : { text: usage.output.text },
191
+ ...usage.output.reasoning === void 0 ? {} : { reasoning: usage.output.reasoning }
192
+ }
193
+ });
194
+ };
195
+ const subagentResultFromEvents = (events) => {
196
+ const terminal = [...events].reverse().find(isTerminalAgentEvent);
197
+ const usageUpdates = events.filter((event) => event._tag === "UsageUpdate");
198
+ const usage = usageUpdates.reduce((total, event) => addAgentUsage(total, event.usage), zeroAgentUsage);
199
+ const turns = events.reduce((latest, event) => event._tag === "TurnStart" ? Math.max(latest, event.turn) : latest, 0);
200
+ if (terminal === void 0) {
201
+ const message = "Subagent stream ended without a terminal event.";
202
+ return {
203
+ status: "error",
204
+ text: `Subagent failed: ${message}`,
205
+ ...usageUpdates.length === 0 ? {} : { usage },
206
+ ...turns === 0 ? {} : { turns },
207
+ error: {
208
+ code: "invalid_response",
209
+ message,
210
+ retryable: false
211
+ }
212
+ };
213
+ }
214
+ if (terminal._tag === "AgentError") return {
215
+ status: "error",
216
+ text: `Subagent failed: ${terminal.message}`,
217
+ ...usageUpdates.length === 0 ? {} : { usage },
218
+ ...turns === 0 ? {} : { turns },
219
+ error: {
220
+ code: terminal.code,
221
+ message: terminal.message,
222
+ retryable: terminal.retryable,
223
+ ...terminal.provider === void 0 ? {} : { provider: terminal.provider }
224
+ }
225
+ };
226
+ const text = latestAssistantText(terminal.messages).trim();
227
+ return {
228
+ status: terminal._tag === "AgentAwaitingInput" ? "awaiting_input" : "completed",
229
+ text: text.length === 0 ? "Subagent completed without a final text response." : text,
230
+ usage: terminal.usage,
231
+ turns: terminal.turns,
232
+ ...terminal._tag === "AgentAwaitingInput" ? { requests: terminal.requests } : {}
233
+ };
234
+ };
235
+ const subagentResultText = (events) => subagentResultFromEvents(events).text;
236
+ const makeSubagentToolResult = (input) => {
237
+ const isError = input.isError === true || input.error !== void 0 || input.status === "error";
238
+ const status = isError ? "error" : input.status ?? "completed";
239
+ return ToolResult.make({
240
+ toolCallId: input.callId,
241
+ content: formatSubagentResult(input.output),
242
+ isError: isError ? true : void 0,
243
+ structuredContent: {
244
+ subagent_run_id: input.subagentRunId,
245
+ subagent_type: input.subagentType,
246
+ description: input.description,
247
+ started_at_ms: input.startedAtMs,
248
+ ended_at_ms: input.endedAtMs,
249
+ duration_ms: Math.max(0, input.endedAtMs - input.startedAtMs),
250
+ status,
251
+ model: input.model,
252
+ ...input.reasoningEffort === void 0 ? {} : { reasoning_effort: input.reasoningEffort },
253
+ ...input.usage === void 0 ? {} : { usage: subagentUsageMetadata(input.usage) },
254
+ ...input.turns === void 0 ? {} : { turns: input.turns },
255
+ ...input.requests === void 0 ? {} : { hitl_requests: input.requests },
256
+ ...input.error === void 0 ? {} : { error: subagentErrorMetadata(input.error) }
257
+ }
258
+ });
259
+ };
154
260
  //#endregion
155
- export { formatSubagentResult, makeNonRecursiveSubagentToolModule, makeSubagentToolDef, makeSubagentToolModule, makeSubagentToolRegistration, makeSubagentToolResult, subagentResultText, subagentToolName, subagentToolRunId };
261
+ export { formatSubagentResult, makeNonRecursiveSubagentToolModule, makeSubagentToolDef, makeSubagentToolModule, makeSubagentToolRegistration, makeSubagentToolResult, subagentResultFromEvents, subagentResultText, subagentToolName, subagentToolRunId, subagentUsageFromToolResult };
156
262
 
157
263
  //# sourceMappingURL=subagent.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"subagent.mjs","names":[],"sources":["../../src/tools/subagent.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { ToolError } from '@yolk-sdk/agent/loop'\nimport {\n assistantContent,\n contentText,\n makeSubagentRunId,\n ToolResult,\n type AgentEvent,\n type AgentMessage,\n type AgentReasoningEffort,\n type ToolCall\n} from '@yolk-sdk/agent/protocol'\nimport {\n makeTool,\n modelVisibleToolError,\n type ModelVisibleToolError,\n type ToolModule,\n type ToolRegistration,\n type ToolRegistryError\n} from './registry.ts'\n\nexport const subagentToolName = 'subagent'\n\nconst SubagentToolBaseFields = {\n description: Schema.String.pipe(\n Schema.annotate({ description: 'A short 3-5 word description of the task.' })\n ),\n prompt: Schema.String.pipe(\n Schema.annotate({\n description:\n 'The complete task instructions for the subagent, including all context it needs.'\n })\n ),\n subagent_type: Schema.String.pipe(\n Schema.annotate({ description: 'The specialized subagent type to use for this task.' })\n )\n}\n\nexport type SubagentToolParams = {\n readonly description: string\n readonly prompt: string\n readonly subagent_type: string\n readonly model?: string\n readonly reasoning_effort?: AgentReasoningEffort\n}\n\nexport type SubagentDefinition = {\n readonly name: string\n readonly description: string\n}\n\nexport type SubagentModelDefinition = {\n readonly id: string\n readonly description: string\n}\n\nexport type SubagentReasoningEffortDefinition = {\n readonly value: AgentReasoningEffort\n readonly description: string\n}\n\nexport type SubagentRuntimeSelectionOptions = {\n readonly models?: ReadonlyArray<SubagentModelDefinition>\n readonly reasoningEfforts?: ReadonlyArray<SubagentReasoningEffortDefinition>\n}\n\nexport type SubagentContext = {\n readonly subagent?: boolean\n}\n\nexport type SubagentExecutionInput<Context> = {\n readonly call: ToolCall\n readonly context: Context\n readonly params: SubagentToolParams\n}\n\nexport type SubagentToolOptions<Context> = SubagentRuntimeSelectionOptions & {\n readonly subagents: ReadonlyArray<SubagentDefinition>\n readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>\n readonly execute: (input: SubagentExecutionInput<Context>) => Effect.Effect<ToolResult, ToolError>\n}\n\nexport type SubagentToolResultInput = {\n readonly callId: string\n readonly output: string\n readonly subagentType: string\n readonly description: string\n readonly subagentRunId: string\n readonly startedAtMs: number\n readonly endedAtMs: number\n readonly model: string\n readonly reasoningEffort?: AgentReasoningEffort\n readonly isError?: boolean\n}\n\nconst subagentToolError = (message: string, cause: ToolError['cause']) =>\n new ToolError({\n tool: subagentToolName,\n message,\n cause\n })\n\nconst subagentModelVisibleError = (message: string) =>\n modelVisibleToolError({\n tool: subagentToolName,\n message,\n reason: 'validation'\n })\n\nconst enumRecord = <Value extends string>(\n values: ReadonlyArray<Value>\n): Readonly<Record<string, Value>> => Object.fromEntries(values.map(value => [value, value]))\n\nconst optionalRuntimeSelection = <Value extends string>(input: {\n readonly values: ReadonlyArray<Value>\n readonly description: string\n}) =>\n Schema.optionalKey(\n Schema.Enum(enumRecord(input.values)).pipe(Schema.annotate({ description: input.description }))\n )\n\nconst configuredSubagentToolParams = (options: SubagentRuntimeSelectionOptions) => {\n const model =\n options.models === undefined || options.models.length === 0\n ? undefined\n : optionalRuntimeSelection({\n values: options.models.map(item => item.id),\n description: 'Model for this subagent. Omit to inherit the host runtime model.'\n })\n const reasoningEffort =\n options.reasoningEfforts === undefined || options.reasoningEfforts.length === 0\n ? undefined\n : optionalRuntimeSelection({\n values: options.reasoningEfforts.map(item => item.value),\n description:\n 'Reasoning effort for this subagent. Omit to inherit the host runtime effort.'\n })\n\n if (model !== undefined && reasoningEffort !== undefined) {\n return Schema.Struct({\n ...SubagentToolBaseFields,\n model,\n reasoning_effort: reasoningEffort\n })\n }\n\n if (model !== undefined) {\n return Schema.Struct({ ...SubagentToolBaseFields, model })\n }\n\n if (reasoningEffort !== undefined) {\n return Schema.Struct({ ...SubagentToolBaseFields, reasoning_effort: reasoningEffort })\n }\n\n return Schema.Struct(SubagentToolBaseFields)\n}\n\nconst trimmedSubagentParams = (params: SubagentToolParams): SubagentToolParams => ({\n description: params.description.trim(),\n prompt: params.prompt.trim(),\n subagent_type: params.subagent_type.trim(),\n ...(params.model === undefined ? {} : { model: params.model }),\n ...(params.reasoning_effort === undefined ? {} : { reasoning_effort: params.reasoning_effort })\n})\n\nconst validateSubagentParams = (\n params: SubagentToolParams\n): Effect.Effect<\n {\n readonly description: string\n readonly prompt: string\n readonly subagent_type: string\n },\n ModelVisibleToolError\n> => {\n const trimmed = trimmedSubagentParams(params)\n\n if (trimmed.description.length === 0) {\n return Effect.fail(subagentModelVisibleError('description must not be empty'))\n }\n\n if (trimmed.prompt.length === 0) {\n return Effect.fail(subagentModelVisibleError('prompt must not be empty'))\n }\n\n if (trimmed.subagent_type.length === 0) {\n return Effect.fail(subagentModelVisibleError('subagent_type must not be empty'))\n }\n\n return Effect.succeed(trimmed)\n}\n\nconst findSubagent = (subagents: ReadonlyArray<SubagentDefinition>, name: string) =>\n subagents.find(subagent => subagent.name === name)\n\nconst requireKnownSubagent = (\n subagents: ReadonlyArray<SubagentDefinition>,\n name: string\n): Effect.Effect<SubagentDefinition, ModelVisibleToolError> => {\n const subagent = findSubagent(subagents, name)\n\n return subagent === undefined\n ? Effect.fail(subagentModelVisibleError(`Unknown subagent type: ${name}`))\n : Effect.succeed(subagent)\n}\n\nconst subagentDescription = (subagent: SubagentDefinition) =>\n `- ${subagent.name}: ${subagent.description}`\n\nconst modelDescription = (model: SubagentModelDefinition) => `- ${model.id}: ${model.description}`\n\nconst reasoningEffortDescription = (effort: SubagentReasoningEffortDefinition) =>\n `- ${effort.value}: ${effort.description}`\n\nconst subagentToolDescription = (\n options: SubagentRuntimeSelectionOptions & {\n readonly subagents: ReadonlyArray<SubagentDefinition>\n }\n) =>\n [\n 'Launch a new agent to handle complex, multistep tasks autonomously.',\n 'Use this when delegating focused work to a specialized subagent would save context or allow parallel exploration.',\n 'To run subagents in parallel, call this subagent tool multiple times in the same assistant response.',\n 'Yolk runs same-turn subagent calls concurrently automatically.',\n 'A fresh subagent only sees the prompt you provide, so include all required context.',\n 'Subagents can use their normal tools but cannot launch further subagents in v1.',\n options.subagents.length === 0\n ? 'No subagent types are currently available.'\n : `Available subagent types:\\n${options.subagents.map(subagentDescription).join('\\n')}`,\n options.models === undefined || options.models.length === 0\n ? undefined\n : [\n 'Available subagent models:',\n options.models.map(modelDescription).join('\\n'),\n 'Omit model to inherit the host runtime model.'\n ].join('\\n'),\n options.reasoningEfforts === undefined || options.reasoningEfforts.length === 0\n ? undefined\n : [\n 'Available subagent reasoning efforts:',\n options.reasoningEfforts.map(reasoningEffortDescription).join('\\n'),\n 'Omit reasoning_effort to inherit the host runtime effort.'\n ].join('\\n')\n ]\n .filter(section => section !== undefined)\n .join('\\n\\n')\n\nexport const makeSubagentToolRegistration = <Context>(\n options: SubagentToolOptions<Context>\n): ToolRegistration<Context> =>\n makeTool({\n name: subagentToolName,\n description: subagentToolDescription(options),\n parameters: configuredSubagentToolParams(options),\n access: 'read',\n isEnabled: options.isEnabled,\n invalidParamsMessage: error =>\n `Invalid subagent arguments: ${error instanceof Error ? error.message : String(error)}`,\n execute: ({ call, context, params }) =>\n Effect.gen(function* () {\n if (call.name !== subagentToolName) {\n return yield* Effect.fail(\n subagentToolError(`Tool is not configured: ${call.name}`, 'not_found')\n )\n }\n\n const normalizedParams = yield* validateSubagentParams(params)\n yield* requireKnownSubagent(options.subagents, normalizedParams.subagent_type)\n\n return yield* options.execute({ call, context, params: normalizedParams })\n })\n })\n\nexport const makeSubagentToolDef = (\n subagents: ReadonlyArray<SubagentDefinition>,\n runtimeSelections: SubagentRuntimeSelectionOptions = {}\n) =>\n makeSubagentToolRegistration({\n subagents,\n ...runtimeSelections,\n execute: ({ call }) => Effect.succeed(ToolResult.make({ toolCallId: call.id, content: '' }))\n }).def\n\nexport const makeSubagentToolModule = <Context>(\n options: SubagentToolOptions<Context>\n): ToolModule<Context> => ({\n id: 'subagent',\n tools: [makeSubagentToolRegistration(options)]\n})\n\nexport const makeNonRecursiveSubagentToolModule = <Context extends SubagentContext>(\n options: SubagentToolOptions<Context>\n): ToolModule<Context> =>\n makeSubagentToolModule({\n ...options,\n isEnabled: context =>\n context.subagent === true\n ? Effect.succeed(false)\n : options.isEnabled === undefined\n ? Effect.succeed(true)\n : options.isEnabled(context)\n })\n\nexport const formatSubagentResult = (output: string) =>\n ['<subagent_result>', output, '</subagent_result>'].join('\\n')\n\nexport const subagentToolRunId = makeSubagentRunId\n\nconst latestAssistantText = (messages: ReadonlyArray<AgentMessage>) => {\n const assistant = [...messages].reverse().find(message => message._tag === 'Assistant')\n\n return assistant === undefined ? '' : contentText(assistantContent(assistant))\n}\n\nexport const subagentResultText = (events: ReadonlyArray<AgentEvent>) => {\n const messages = [...events].reverse().find(event => event._tag === 'AgentEnd')?.messages ?? []\n const text = latestAssistantText(messages).trim()\n\n return text.length === 0 ? 'Subagent completed without a final text response.' : text\n}\n\nexport const makeSubagentToolResult = (input: SubagentToolResultInput) =>\n ToolResult.make({\n toolCallId: input.callId,\n content: formatSubagentResult(input.output),\n isError: input.isError,\n structuredContent: {\n subagent_run_id: input.subagentRunId,\n subagent_type: input.subagentType,\n description: input.description,\n started_at_ms: input.startedAtMs,\n ended_at_ms: input.endedAtMs,\n duration_ms: Math.max(0, input.endedAtMs - input.startedAtMs),\n status: input.isError === true ? 'error' : 'completed',\n model: input.model,\n ...(input.reasoningEffort === undefined ? {} : { reasoning_effort: input.reasoningEffort })\n }\n })\n"],"mappings":"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"}
1
+ {"version":3,"file":"subagent.mjs","names":[],"sources":["../../src/tools/subagent.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { ToolError } from '@yolk-sdk/agent/loop'\nimport {\n addAgentUsage,\n assistantContent,\n AgentUsage,\n contentText,\n isTerminalAgentEvent,\n makeSubagentRunId,\n ToolResult,\n type AgentErrorCode,\n type AgentEvent,\n type AgentMessage,\n type AgentReasoningEffort,\n type HitlRequest,\n type ProviderErrorInfo,\n type ToolCall,\n zeroAgentUsage\n} from '@yolk-sdk/agent/protocol'\nimport {\n makeTool,\n modelVisibleToolError,\n type ModelVisibleToolError,\n type ToolModule,\n type ToolRegistration,\n type ToolRegistryError\n} from './registry.ts'\n\nexport const subagentToolName = 'subagent'\n\nconst SubagentToolBaseFields = {\n description: Schema.String.pipe(\n Schema.annotate({ description: 'A short 3-5 word description of the task.' })\n ),\n prompt: Schema.String.pipe(\n Schema.annotate({\n description:\n 'The complete task instructions for the subagent, including all context it needs.'\n })\n ),\n subagent_type: Schema.String.pipe(\n Schema.annotate({ description: 'The specialized subagent type to use for this task.' })\n )\n}\n\nexport type SubagentToolParams = {\n readonly description: string\n readonly prompt: string\n readonly subagent_type: string\n readonly model?: string\n readonly reasoning_effort?: AgentReasoningEffort\n}\n\nexport type SubagentDefinition = {\n readonly name: string\n readonly description: string\n}\n\nexport type SubagentModelDefinition = {\n readonly id: string\n readonly description: string\n}\n\nexport type SubagentReasoningEffortDefinition = {\n readonly value: AgentReasoningEffort\n readonly description: string\n}\n\nexport type SubagentRuntimeSelectionOptions = {\n readonly models?: ReadonlyArray<SubagentModelDefinition>\n readonly reasoningEfforts?: ReadonlyArray<SubagentReasoningEffortDefinition>\n}\n\nexport type SubagentContext = {\n readonly subagent?: boolean\n}\n\nexport type SubagentExecutionInput<Context> = {\n readonly call: ToolCall\n readonly context: Context\n readonly params: SubagentToolParams\n}\n\nexport type SubagentToolOptions<Context> = SubagentRuntimeSelectionOptions & {\n readonly subagents: ReadonlyArray<SubagentDefinition>\n readonly isEnabled?: (context: Context) => Effect.Effect<boolean, ToolRegistryError>\n readonly execute: (input: SubagentExecutionInput<Context>) => Effect.Effect<ToolResult, ToolError>\n}\n\nexport type SubagentRunError = {\n readonly code: AgentErrorCode\n readonly message: string\n readonly retryable: boolean\n readonly provider?: ProviderErrorInfo\n}\n\nexport type SubagentRunStatus = 'completed' | 'awaiting_input' | 'error'\n\nexport type SubagentRunResult = {\n readonly status: SubagentRunStatus\n readonly text: string\n readonly usage?: AgentUsage\n readonly turns?: number\n readonly requests?: ReadonlyArray<HitlRequest>\n readonly error?: SubagentRunError\n}\n\nexport type SubagentToolResultInput = {\n readonly callId: string\n readonly output: string\n readonly subagentType: string\n readonly description: string\n readonly subagentRunId: string\n readonly startedAtMs: number\n readonly endedAtMs: number\n readonly model: string\n readonly reasoningEffort?: AgentReasoningEffort\n readonly usage?: AgentUsage\n readonly turns?: number\n readonly status?: SubagentRunStatus\n readonly requests?: ReadonlyArray<HitlRequest>\n readonly error?: SubagentRunError\n readonly isError?: boolean\n}\n\nconst subagentToolError = (message: string, cause: ToolError['cause']) =>\n new ToolError({\n tool: subagentToolName,\n message,\n cause\n })\n\nconst subagentModelVisibleError = (message: string) =>\n modelVisibleToolError({\n tool: subagentToolName,\n message,\n reason: 'validation'\n })\n\nconst enumRecord = <Value extends string>(\n values: ReadonlyArray<Value>\n): Readonly<Record<string, Value>> => Object.fromEntries(values.map(value => [value, value]))\n\nconst optionalRuntimeSelection = <Value extends string>(input: {\n readonly values: ReadonlyArray<Value>\n readonly description: string\n}) =>\n Schema.optionalKey(\n Schema.Enum(enumRecord(input.values)).pipe(Schema.annotate({ description: input.description }))\n )\n\nconst configuredSubagentToolParams = (options: SubagentRuntimeSelectionOptions) => {\n const model =\n options.models === undefined || options.models.length === 0\n ? undefined\n : optionalRuntimeSelection({\n values: options.models.map(item => item.id),\n description: 'Model for this subagent. Omit to inherit the host runtime model.'\n })\n const reasoningEffort =\n options.reasoningEfforts === undefined || options.reasoningEfforts.length === 0\n ? undefined\n : optionalRuntimeSelection({\n values: options.reasoningEfforts.map(item => item.value),\n description:\n 'Reasoning effort for this subagent. Omit to inherit the host runtime effort.'\n })\n\n if (model !== undefined && reasoningEffort !== undefined) {\n return Schema.Struct({\n ...SubagentToolBaseFields,\n model,\n reasoning_effort: reasoningEffort\n })\n }\n\n if (model !== undefined) {\n return Schema.Struct({ ...SubagentToolBaseFields, model })\n }\n\n if (reasoningEffort !== undefined) {\n return Schema.Struct({ ...SubagentToolBaseFields, reasoning_effort: reasoningEffort })\n }\n\n return Schema.Struct(SubagentToolBaseFields)\n}\n\nconst trimmedSubagentParams = (params: SubagentToolParams): SubagentToolParams => ({\n description: params.description.trim(),\n prompt: params.prompt.trim(),\n subagent_type: params.subagent_type.trim(),\n ...(params.model === undefined ? {} : { model: params.model }),\n ...(params.reasoning_effort === undefined ? {} : { reasoning_effort: params.reasoning_effort })\n})\n\nconst validateSubagentParams = (\n params: SubagentToolParams\n): Effect.Effect<\n {\n readonly description: string\n readonly prompt: string\n readonly subagent_type: string\n },\n ModelVisibleToolError\n> => {\n const trimmed = trimmedSubagentParams(params)\n\n if (trimmed.description.length === 0) {\n return Effect.fail(subagentModelVisibleError('description must not be empty'))\n }\n\n if (trimmed.prompt.length === 0) {\n return Effect.fail(subagentModelVisibleError('prompt must not be empty'))\n }\n\n if (trimmed.subagent_type.length === 0) {\n return Effect.fail(subagentModelVisibleError('subagent_type must not be empty'))\n }\n\n return Effect.succeed(trimmed)\n}\n\nconst findSubagent = (subagents: ReadonlyArray<SubagentDefinition>, name: string) =>\n subagents.find(subagent => subagent.name === name)\n\nconst requireKnownSubagent = (\n subagents: ReadonlyArray<SubagentDefinition>,\n name: string\n): Effect.Effect<SubagentDefinition, ModelVisibleToolError> => {\n const subagent = findSubagent(subagents, name)\n\n return subagent === undefined\n ? Effect.fail(subagentModelVisibleError(`Unknown subagent type: ${name}`))\n : Effect.succeed(subagent)\n}\n\nconst subagentDescription = (subagent: SubagentDefinition) =>\n `- ${subagent.name}: ${subagent.description}`\n\nconst modelDescription = (model: SubagentModelDefinition) => `- ${model.id}: ${model.description}`\n\nconst reasoningEffortDescription = (effort: SubagentReasoningEffortDefinition) =>\n `- ${effort.value}: ${effort.description}`\n\nconst subagentToolDescription = (\n options: SubagentRuntimeSelectionOptions & {\n readonly subagents: ReadonlyArray<SubagentDefinition>\n }\n) =>\n [\n 'Launch a new agent to handle complex, multistep tasks autonomously.',\n 'Use this when delegating focused work to a specialized subagent would save context or allow parallel exploration.',\n 'To run subagents in parallel, call this subagent tool multiple times in the same assistant response.',\n 'Yolk runs same-turn subagent calls concurrently automatically.',\n 'A fresh subagent only sees the prompt you provide, so include all required context.',\n 'Subagents can use their normal tools but cannot launch further subagents in v1.',\n options.subagents.length === 0\n ? 'No subagent types are currently available.'\n : `Available subagent types:\\n${options.subagents.map(subagentDescription).join('\\n')}`,\n options.models === undefined || options.models.length === 0\n ? undefined\n : [\n 'Available subagent models:',\n options.models.map(modelDescription).join('\\n'),\n 'Omit model to inherit the host runtime model.'\n ].join('\\n'),\n options.reasoningEfforts === undefined || options.reasoningEfforts.length === 0\n ? undefined\n : [\n 'Available subagent reasoning efforts:',\n options.reasoningEfforts.map(reasoningEffortDescription).join('\\n'),\n 'Omit reasoning_effort to inherit the host runtime effort.'\n ].join('\\n')\n ]\n .filter(section => section !== undefined)\n .join('\\n\\n')\n\nexport const makeSubagentToolRegistration = <Context>(\n options: SubagentToolOptions<Context>\n): ToolRegistration<Context> =>\n makeTool({\n name: subagentToolName,\n description: subagentToolDescription(options),\n parameters: configuredSubagentToolParams(options),\n access: 'read',\n isEnabled: options.isEnabled,\n invalidParamsMessage: error =>\n `Invalid subagent arguments: ${error instanceof Error ? error.message : String(error)}`,\n execute: ({ call, context, params }) =>\n Effect.gen(function* () {\n if (call.name !== subagentToolName) {\n return yield* Effect.fail(\n subagentToolError(`Tool is not configured: ${call.name}`, 'not_found')\n )\n }\n\n const normalizedParams = yield* validateSubagentParams(params)\n yield* requireKnownSubagent(options.subagents, normalizedParams.subagent_type)\n\n return yield* options.execute({ call, context, params: normalizedParams })\n })\n })\n\nexport const makeSubagentToolDef = (\n subagents: ReadonlyArray<SubagentDefinition>,\n runtimeSelections: SubagentRuntimeSelectionOptions = {}\n) =>\n makeSubagentToolRegistration({\n subagents,\n ...runtimeSelections,\n execute: ({ call }) => Effect.succeed(ToolResult.make({ toolCallId: call.id, content: '' }))\n }).def\n\nexport const makeSubagentToolModule = <Context>(\n options: SubagentToolOptions<Context>\n): ToolModule<Context> => ({\n id: 'subagent',\n tools: [makeSubagentToolRegistration(options)]\n})\n\nexport const makeNonRecursiveSubagentToolModule = <Context extends SubagentContext>(\n options: SubagentToolOptions<Context>\n): ToolModule<Context> =>\n makeSubagentToolModule({\n ...options,\n isEnabled: context =>\n context.subagent === true\n ? Effect.succeed(false)\n : options.isEnabled === undefined\n ? Effect.succeed(true)\n : options.isEnabled(context)\n })\n\nexport const formatSubagentResult = (output: string) =>\n ['<subagent_result>', output, '</subagent_result>'].join('\\n')\n\nexport const subagentToolRunId = makeSubagentRunId\n\nconst latestAssistantText = (messages: ReadonlyArray<AgentMessage>) => {\n const assistant = [...messages].reverse().find(message => message._tag === 'Assistant')\n\n return assistant === undefined ? '' : contentText(assistantContent(assistant))\n}\n\nconst subagentProviderMetadata = (provider: ProviderErrorInfo) => ({\n provider: provider.provider,\n kind: provider.kind,\n ...(provider.status === undefined ? {} : { status: provider.status }),\n ...(provider.providerCode === undefined ? {} : { provider_code: provider.providerCode }),\n ...(provider.retryAfterMs === undefined ? {} : { retry_after_ms: provider.retryAfterMs })\n})\n\nconst subagentUsageMetadata = (usage: AgentUsage) => ({\n input: {\n total: usage.input.total,\n ...(usage.input.uncached === undefined ? {} : { uncached: usage.input.uncached }),\n ...(usage.input.cacheRead === undefined ? {} : { cache_read: usage.input.cacheRead }),\n ...(usage.input.cacheWrite === undefined ? {} : { cache_write: usage.input.cacheWrite })\n },\n output: {\n total: usage.output.total,\n ...(usage.output.text === undefined ? {} : { text: usage.output.text }),\n ...(usage.output.reasoning === undefined ? {} : { reasoning: usage.output.reasoning })\n }\n})\n\nconst subagentErrorMetadata = (error: SubagentRunError) => ({\n code: error.code,\n message: error.message,\n retryable: error.retryable,\n ...(error.provider === undefined ? {} : { provider: subagentProviderMetadata(error.provider) })\n})\n\nconst SubagentUsageMetadata = Schema.Struct({\n input: Schema.Struct({\n total: Schema.Number,\n uncached: Schema.optional(Schema.Number),\n cache_read: Schema.optional(Schema.Number),\n cache_write: Schema.optional(Schema.Number)\n }),\n output: Schema.Struct({\n total: Schema.Number,\n text: Schema.optional(Schema.Number),\n reasoning: Schema.optional(Schema.Number)\n })\n})\n\nconst SubagentStructuredUsage = Schema.Struct({\n subagent_run_id: Schema.String,\n subagent_type: Schema.String,\n usage: SubagentUsageMetadata\n})\n\nexport const subagentUsageFromToolResult = (result: ToolResult): AgentUsage | undefined => {\n if (\n !Schema.is(SubagentStructuredUsage)(result.structuredContent) ||\n result.structuredContent.subagent_run_id !== subagentToolRunId(result.toolCallId)\n ) {\n return undefined\n }\n\n const usage = result.structuredContent.usage\n\n return AgentUsage.make({\n input: {\n total: usage.input.total,\n ...(usage.input.uncached === undefined ? {} : { uncached: usage.input.uncached }),\n ...(usage.input.cache_read === undefined ? {} : { cacheRead: usage.input.cache_read }),\n ...(usage.input.cache_write === undefined ? {} : { cacheWrite: usage.input.cache_write })\n },\n output: {\n total: usage.output.total,\n ...(usage.output.text === undefined ? {} : { text: usage.output.text }),\n ...(usage.output.reasoning === undefined ? {} : { reasoning: usage.output.reasoning })\n }\n })\n}\n\nexport const subagentResultFromEvents = (events: ReadonlyArray<AgentEvent>): SubagentRunResult => {\n const terminal = [...events].reverse().find(isTerminalAgentEvent)\n const usageUpdates = events.filter(event => event._tag === 'UsageUpdate')\n const usage = usageUpdates.reduce(\n (total, event) => addAgentUsage(total, event.usage),\n zeroAgentUsage\n )\n const turns = events.reduce(\n (latest, event) => (event._tag === 'TurnStart' ? Math.max(latest, event.turn) : latest),\n 0\n )\n\n if (terminal === undefined) {\n const message = 'Subagent stream ended without a terminal event.'\n\n return {\n status: 'error',\n text: `Subagent failed: ${message}`,\n ...(usageUpdates.length === 0 ? {} : { usage }),\n ...(turns === 0 ? {} : { turns }),\n error: {\n code: 'invalid_response',\n message,\n retryable: false\n }\n }\n }\n\n if (terminal._tag === 'AgentError') {\n return {\n status: 'error',\n text: `Subagent failed: ${terminal.message}`,\n ...(usageUpdates.length === 0 ? {} : { usage }),\n ...(turns === 0 ? {} : { turns }),\n error: {\n code: terminal.code,\n message: terminal.message,\n retryable: terminal.retryable,\n ...(terminal.provider === undefined ? {} : { provider: terminal.provider })\n }\n }\n }\n\n const text = latestAssistantText(terminal.messages).trim()\n\n return {\n status: terminal._tag === 'AgentAwaitingInput' ? 'awaiting_input' : 'completed',\n text: text.length === 0 ? 'Subagent completed without a final text response.' : text,\n usage: terminal.usage,\n turns: terminal.turns,\n ...(terminal._tag === 'AgentAwaitingInput' ? { requests: terminal.requests } : {})\n }\n}\n\nexport const subagentResultText = (events: ReadonlyArray<AgentEvent>) =>\n subagentResultFromEvents(events).text\n\nexport const makeSubagentToolResult = (input: SubagentToolResultInput) => {\n const isError = input.isError === true || input.error !== undefined || input.status === 'error'\n const status = isError ? 'error' : (input.status ?? 'completed')\n\n return ToolResult.make({\n toolCallId: input.callId,\n content: formatSubagentResult(input.output),\n isError: isError ? true : undefined,\n structuredContent: {\n subagent_run_id: input.subagentRunId,\n subagent_type: input.subagentType,\n description: input.description,\n started_at_ms: input.startedAtMs,\n ended_at_ms: input.endedAtMs,\n duration_ms: Math.max(0, input.endedAtMs - input.startedAtMs),\n status,\n model: input.model,\n ...(input.reasoningEffort === undefined ? {} : { reasoning_effort: input.reasoningEffort }),\n ...(input.usage === undefined ? {} : { usage: subagentUsageMetadata(input.usage) }),\n ...(input.turns === undefined ? {} : { turns: input.turns }),\n ...(input.requests === undefined ? {} : { hitl_requests: input.requests }),\n ...(input.error === undefined ? {} : { error: subagentErrorMetadata(input.error) })\n }\n })\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yolk-sdk/agent",
3
- "version": "0.1.0-canary.56",
3
+ "version": "0.1.0-canary.57",
4
4
  "description": "Protocol, loop, runtime, client, compaction, tools, React, providers, OAuth, skillset, and voice primitives for building Yolk agents.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -9,12 +9,22 @@ export type ContextBudget = {
9
9
  export type ContextBudgetInput = {
10
10
  readonly contextWindowTokens: number
11
11
  readonly reservedOutputTokens: number
12
+ /** Optional provider- or endpoint-specific ceiling below the model's total context window. */
13
+ readonly maxInputTokens?: number
12
14
  readonly warningRatio: number
13
15
  readonly compactionRatio: number
14
16
  }
15
17
 
16
18
  export const makeContextBudget = (input: ContextBudgetInput): ContextBudget => {
17
- const usableInputTokens = Math.max(0, input.contextWindowTokens - input.reservedOutputTokens)
19
+ const contextUsableInputTokens = Math.max(
20
+ 0,
21
+ input.contextWindowTokens - input.reservedOutputTokens
22
+ )
23
+ const maxInputTokens =
24
+ input.maxInputTokens === undefined || !Number.isFinite(input.maxInputTokens)
25
+ ? contextUsableInputTokens
26
+ : Math.max(0, input.maxInputTokens)
27
+ const usableInputTokens = Math.min(contextUsableInputTokens, maxInputTokens)
18
28
 
19
29
  return {
20
30
  contextWindowTokens: input.contextWindowTokens,
@@ -51,7 +51,11 @@ export type OpenAiCodexReasoningSummary = 'auto' | 'concise' | 'detailed'
51
51
 
52
52
  export type OpenAiCodexProviderConfig = {
53
53
  readonly token: OAuthAccessToken
54
- readonly maxOutputTokens: number
54
+ /**
55
+ * @deprecated The ChatGPT Codex endpoint does not accept `max_output_tokens`; this value is
56
+ * retained as an ignored compatibility field for existing hosts.
57
+ */
58
+ readonly maxOutputTokens?: number
55
59
  readonly responsesUrl?: string
56
60
  readonly extraHeaders?: Readonly<Record<string, string>>
57
61
  readonly defaultReasoningEffort?: AgentReasoningEffort
@@ -413,10 +417,11 @@ const toOpenAiCodexTool = (tool: ToolDef): OpenAiCodexTool => ({
413
417
  export const toOpenAiCodexRequestBody = (
414
418
  request: LLMRequest,
415
419
  config: {
416
- readonly maxOutputTokens: number
420
+ /** @deprecated Ignored by the ChatGPT Codex endpoint. */
421
+ readonly maxOutputTokens?: number
417
422
  readonly defaultReasoningEffort?: AgentReasoningEffort
418
423
  readonly reasoningSummary?: OpenAiCodexReasoningSummary
419
- }
424
+ } = {}
420
425
  ): Effect.Effect<OpenAiCodexRequestBody, LLMError> =>
421
426
  Effect.gen(function* () {
422
427
  yield* validateProviderTranscript(request.messages)
@@ -143,6 +143,9 @@ const kindFromSignal = (input: ProviderFailureInput): ProviderFailureKind | unde
143
143
  if (
144
144
  signal.includes('context_length') ||
145
145
  signal.includes('context length') ||
146
+ signal.includes('context_window_exceeded') ||
147
+ signal.includes('exceeds the context window') ||
148
+ signal.includes('context window exceeded') ||
146
149
  signal.includes('context_overflow') ||
147
150
  signal.includes('context overflow') ||
148
151
  signal.includes('prompt is too long') ||
@@ -25,8 +25,10 @@ export {
25
25
  makeSubagentToolDef,
26
26
  makeSubagentToolModule,
27
27
  makeSubagentToolRegistration,
28
+ subagentResultFromEvents,
28
29
  subagentResultText,
29
30
  subagentToolName,
31
+ subagentUsageFromToolResult,
30
32
  subagentToolRunId
31
33
  } from './subagent.ts'
32
34
  export type {
@@ -47,6 +49,9 @@ export type {
47
49
  SubagentRuntimeSelectionOptions,
48
50
  SubagentContext,
49
51
  SubagentDefinition,
52
+ SubagentRunError,
53
+ SubagentRunResult,
54
+ SubagentRunStatus,
50
55
  SubagentToolOptions,
51
56
  SubagentToolParams,
52
57
  SubagentToolResultInput
@@ -2,14 +2,21 @@ import { Effect } from 'effect'
2
2
  import * as Schema from 'effect/Schema'
3
3
  import { ToolError } from '@yolk-sdk/agent/loop'
4
4
  import {
5
+ addAgentUsage,
5
6
  assistantContent,
7
+ AgentUsage,
6
8
  contentText,
9
+ isTerminalAgentEvent,
7
10
  makeSubagentRunId,
8
11
  ToolResult,
12
+ type AgentErrorCode,
9
13
  type AgentEvent,
10
14
  type AgentMessage,
11
15
  type AgentReasoningEffort,
12
- type ToolCall
16
+ type HitlRequest,
17
+ type ProviderErrorInfo,
18
+ type ToolCall,
19
+ zeroAgentUsage
13
20
  } from '@yolk-sdk/agent/protocol'
14
21
  import {
15
22
  makeTool,
@@ -81,6 +88,24 @@ export type SubagentToolOptions<Context> = SubagentRuntimeSelectionOptions & {
81
88
  readonly execute: (input: SubagentExecutionInput<Context>) => Effect.Effect<ToolResult, ToolError>
82
89
  }
83
90
 
91
+ export type SubagentRunError = {
92
+ readonly code: AgentErrorCode
93
+ readonly message: string
94
+ readonly retryable: boolean
95
+ readonly provider?: ProviderErrorInfo
96
+ }
97
+
98
+ export type SubagentRunStatus = 'completed' | 'awaiting_input' | 'error'
99
+
100
+ export type SubagentRunResult = {
101
+ readonly status: SubagentRunStatus
102
+ readonly text: string
103
+ readonly usage?: AgentUsage
104
+ readonly turns?: number
105
+ readonly requests?: ReadonlyArray<HitlRequest>
106
+ readonly error?: SubagentRunError
107
+ }
108
+
84
109
  export type SubagentToolResultInput = {
85
110
  readonly callId: string
86
111
  readonly output: string
@@ -91,6 +116,11 @@ export type SubagentToolResultInput = {
91
116
  readonly endedAtMs: number
92
117
  readonly model: string
93
118
  readonly reasoningEffort?: AgentReasoningEffort
119
+ readonly usage?: AgentUsage
120
+ readonly turns?: number
121
+ readonly status?: SubagentRunStatus
122
+ readonly requests?: ReadonlyArray<HitlRequest>
123
+ readonly error?: SubagentRunError
94
124
  readonly isError?: boolean
95
125
  }
96
126
 
@@ -313,18 +343,145 @@ const latestAssistantText = (messages: ReadonlyArray<AgentMessage>) => {
313
343
  return assistant === undefined ? '' : contentText(assistantContent(assistant))
314
344
  }
315
345
 
316
- export const subagentResultText = (events: ReadonlyArray<AgentEvent>) => {
317
- const messages = [...events].reverse().find(event => event._tag === 'AgentEnd')?.messages ?? []
318
- const text = latestAssistantText(messages).trim()
346
+ const subagentProviderMetadata = (provider: ProviderErrorInfo) => ({
347
+ provider: provider.provider,
348
+ kind: provider.kind,
349
+ ...(provider.status === undefined ? {} : { status: provider.status }),
350
+ ...(provider.providerCode === undefined ? {} : { provider_code: provider.providerCode }),
351
+ ...(provider.retryAfterMs === undefined ? {} : { retry_after_ms: provider.retryAfterMs })
352
+ })
353
+
354
+ const subagentUsageMetadata = (usage: AgentUsage) => ({
355
+ input: {
356
+ total: usage.input.total,
357
+ ...(usage.input.uncached === undefined ? {} : { uncached: usage.input.uncached }),
358
+ ...(usage.input.cacheRead === undefined ? {} : { cache_read: usage.input.cacheRead }),
359
+ ...(usage.input.cacheWrite === undefined ? {} : { cache_write: usage.input.cacheWrite })
360
+ },
361
+ output: {
362
+ total: usage.output.total,
363
+ ...(usage.output.text === undefined ? {} : { text: usage.output.text }),
364
+ ...(usage.output.reasoning === undefined ? {} : { reasoning: usage.output.reasoning })
365
+ }
366
+ })
367
+
368
+ const subagentErrorMetadata = (error: SubagentRunError) => ({
369
+ code: error.code,
370
+ message: error.message,
371
+ retryable: error.retryable,
372
+ ...(error.provider === undefined ? {} : { provider: subagentProviderMetadata(error.provider) })
373
+ })
374
+
375
+ const SubagentUsageMetadata = Schema.Struct({
376
+ input: Schema.Struct({
377
+ total: Schema.Number,
378
+ uncached: Schema.optional(Schema.Number),
379
+ cache_read: Schema.optional(Schema.Number),
380
+ cache_write: Schema.optional(Schema.Number)
381
+ }),
382
+ output: Schema.Struct({
383
+ total: Schema.Number,
384
+ text: Schema.optional(Schema.Number),
385
+ reasoning: Schema.optional(Schema.Number)
386
+ })
387
+ })
388
+
389
+ const SubagentStructuredUsage = Schema.Struct({
390
+ subagent_run_id: Schema.String,
391
+ subagent_type: Schema.String,
392
+ usage: SubagentUsageMetadata
393
+ })
394
+
395
+ export const subagentUsageFromToolResult = (result: ToolResult): AgentUsage | undefined => {
396
+ if (
397
+ !Schema.is(SubagentStructuredUsage)(result.structuredContent) ||
398
+ result.structuredContent.subagent_run_id !== subagentToolRunId(result.toolCallId)
399
+ ) {
400
+ return undefined
401
+ }
319
402
 
320
- return text.length === 0 ? 'Subagent completed without a final text response.' : text
403
+ const usage = result.structuredContent.usage
404
+
405
+ return AgentUsage.make({
406
+ input: {
407
+ total: usage.input.total,
408
+ ...(usage.input.uncached === undefined ? {} : { uncached: usage.input.uncached }),
409
+ ...(usage.input.cache_read === undefined ? {} : { cacheRead: usage.input.cache_read }),
410
+ ...(usage.input.cache_write === undefined ? {} : { cacheWrite: usage.input.cache_write })
411
+ },
412
+ output: {
413
+ total: usage.output.total,
414
+ ...(usage.output.text === undefined ? {} : { text: usage.output.text }),
415
+ ...(usage.output.reasoning === undefined ? {} : { reasoning: usage.output.reasoning })
416
+ }
417
+ })
418
+ }
419
+
420
+ export const subagentResultFromEvents = (events: ReadonlyArray<AgentEvent>): SubagentRunResult => {
421
+ const terminal = [...events].reverse().find(isTerminalAgentEvent)
422
+ const usageUpdates = events.filter(event => event._tag === 'UsageUpdate')
423
+ const usage = usageUpdates.reduce(
424
+ (total, event) => addAgentUsage(total, event.usage),
425
+ zeroAgentUsage
426
+ )
427
+ const turns = events.reduce(
428
+ (latest, event) => (event._tag === 'TurnStart' ? Math.max(latest, event.turn) : latest),
429
+ 0
430
+ )
431
+
432
+ if (terminal === undefined) {
433
+ const message = 'Subagent stream ended without a terminal event.'
434
+
435
+ return {
436
+ status: 'error',
437
+ text: `Subagent failed: ${message}`,
438
+ ...(usageUpdates.length === 0 ? {} : { usage }),
439
+ ...(turns === 0 ? {} : { turns }),
440
+ error: {
441
+ code: 'invalid_response',
442
+ message,
443
+ retryable: false
444
+ }
445
+ }
446
+ }
447
+
448
+ if (terminal._tag === 'AgentError') {
449
+ return {
450
+ status: 'error',
451
+ text: `Subagent failed: ${terminal.message}`,
452
+ ...(usageUpdates.length === 0 ? {} : { usage }),
453
+ ...(turns === 0 ? {} : { turns }),
454
+ error: {
455
+ code: terminal.code,
456
+ message: terminal.message,
457
+ retryable: terminal.retryable,
458
+ ...(terminal.provider === undefined ? {} : { provider: terminal.provider })
459
+ }
460
+ }
461
+ }
462
+
463
+ const text = latestAssistantText(terminal.messages).trim()
464
+
465
+ return {
466
+ status: terminal._tag === 'AgentAwaitingInput' ? 'awaiting_input' : 'completed',
467
+ text: text.length === 0 ? 'Subagent completed without a final text response.' : text,
468
+ usage: terminal.usage,
469
+ turns: terminal.turns,
470
+ ...(terminal._tag === 'AgentAwaitingInput' ? { requests: terminal.requests } : {})
471
+ }
321
472
  }
322
473
 
323
- export const makeSubagentToolResult = (input: SubagentToolResultInput) =>
324
- ToolResult.make({
474
+ export const subagentResultText = (events: ReadonlyArray<AgentEvent>) =>
475
+ subagentResultFromEvents(events).text
476
+
477
+ export const makeSubagentToolResult = (input: SubagentToolResultInput) => {
478
+ const isError = input.isError === true || input.error !== undefined || input.status === 'error'
479
+ const status = isError ? 'error' : (input.status ?? 'completed')
480
+
481
+ return ToolResult.make({
325
482
  toolCallId: input.callId,
326
483
  content: formatSubagentResult(input.output),
327
- isError: input.isError,
484
+ isError: isError ? true : undefined,
328
485
  structuredContent: {
329
486
  subagent_run_id: input.subagentRunId,
330
487
  subagent_type: input.subagentType,
@@ -332,8 +489,13 @@ export const makeSubagentToolResult = (input: SubagentToolResultInput) =>
332
489
  started_at_ms: input.startedAtMs,
333
490
  ended_at_ms: input.endedAtMs,
334
491
  duration_ms: Math.max(0, input.endedAtMs - input.startedAtMs),
335
- status: input.isError === true ? 'error' : 'completed',
492
+ status,
336
493
  model: input.model,
337
- ...(input.reasoningEffort === undefined ? {} : { reasoning_effort: input.reasoningEffort })
494
+ ...(input.reasoningEffort === undefined ? {} : { reasoning_effort: input.reasoningEffort }),
495
+ ...(input.usage === undefined ? {} : { usage: subagentUsageMetadata(input.usage) }),
496
+ ...(input.turns === undefined ? {} : { turns: input.turns }),
497
+ ...(input.requests === undefined ? {} : { hitl_requests: input.requests }),
498
+ ...(input.error === undefined ? {} : { error: subagentErrorMetadata(input.error) })
338
499
  }
339
500
  })
501
+ }