@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 +43 -12
- package/dist/compaction/budget.d.mts +2 -1
- package/dist/compaction/budget.d.mts.map +1 -1
- package/dist/compaction/budget.mjs +3 -1
- package/dist/compaction/budget.mjs.map +1 -1
- package/dist/providers/openai/codex-provider.d.mts +7 -3
- package/dist/providers/openai/codex-provider.d.mts.map +1 -1
- package/dist/providers/openai/codex-provider.mjs +1 -1
- package/dist/providers/openai/codex-provider.mjs.map +1 -1
- package/dist/providers/provider-error.d.mts.map +1 -1
- package/dist/providers/provider-error.mjs +1 -1
- package/dist/providers/provider-error.mjs.map +1 -1
- package/dist/skillset/merge.d.mts +1 -1
- package/dist/skillset/name.d.mts +2 -2
- package/dist/skillset/name.d.mts.map +1 -1
- package/dist/tools/index.d.mts +2 -2
- package/dist/tools/index.mjs +2 -2
- package/dist/tools/subagent.d.mts +24 -2
- package/dist/tools/subagent.d.mts.map +1 -1
- package/dist/tools/subagent.mjs +126 -20
- package/dist/tools/subagent.mjs.map +1 -1
- package/package.json +1 -1
- package/src/compaction/budget.ts +11 -1
- package/src/providers/openai/codex-provider.ts +8 -3
- package/src/providers/provider-error.ts +3 -0
- package/src/tools/index.ts +5 -0
- package/src/tools/subagent.ts +172 -10
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
|
|
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 |
|
|
116
|
-
| ---------------------------------- |
|
|
117
|
-
| `makeOpenAiProviderLayer` | `maxCompletionTokens`
|
|
118
|
-
| `makeOpenAiCodexProviderLayer` |
|
|
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
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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,
|
|
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,
|
|
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":"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"}
|
|
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: {
|
package/dist/skillset/name.d.mts
CHANGED
|
@@ -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<
|
|
7
|
-
declare const validateDirectoryName: (expected: string, actual: string) => Effect.Effect<
|
|
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,
|
|
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"}
|
package/dist/tools/index.d.mts
CHANGED
|
@@ -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 };
|
package/dist/tools/index.mjs
CHANGED
|
@@ -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":";;;;;;
|
|
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"}
|
package/dist/tools/subagent.mjs
CHANGED
|
@@ -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
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
...
|
|
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.
|
|
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",
|
package/src/compaction/budget.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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') ||
|
package/src/tools/index.ts
CHANGED
|
@@ -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
|
package/src/tools/subagent.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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
|
-
|
|
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
|
|
324
|
-
|
|
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:
|
|
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
|
|
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
|
+
}
|