eve 0.25.3 → 0.26.0
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/CHANGELOG.md +23 -0
- package/dist/src/chunks/{use-eve-agent-Cy73lgA6.js → use-eve-agent-BkztZA0v.js} +76 -55
- package/dist/src/chunks/{use-eve-agent-CQIeqmKc.js → use-eve-agent-CruinZmd.js} +76 -55
- package/dist/src/cli/commands/logs-events.d.ts +36 -0
- package/dist/src/cli/commands/logs-events.js +2 -0
- package/dist/src/cli/commands/logs.d.ts +64 -0
- package/dist/src/cli/commands/logs.js +4 -0
- package/dist/src/cli/dev/diagnostic-dump.d.ts +60 -0
- package/dist/src/cli/dev/diagnostic-dump.js +1 -0
- package/dist/src/cli/dev/diagnostic-sink.d.ts +37 -0
- package/dist/src/cli/dev/diagnostic-sink.js +1 -0
- package/dist/src/cli/dev/diagnostics.d.ts +42 -0
- package/dist/src/cli/dev/diagnostics.js +1 -0
- package/dist/src/cli/dev/tui/blocks.d.ts +4 -0
- package/dist/src/cli/dev/tui/blocks.js +7 -7
- package/dist/src/cli/dev/tui/command-typeahead.js +1 -1
- package/dist/src/cli/dev/tui/diagnostic-presentation.d.ts +14 -0
- package/dist/src/cli/dev/tui/diagnostic-presentation.js +2 -0
- package/dist/src/cli/dev/tui/errors.d.ts +21 -16
- package/dist/src/cli/dev/tui/errors.js +1 -1
- package/dist/src/cli/dev/tui/line-editor.js +1 -1
- package/dist/src/cli/dev/tui/markdown.js +1 -1
- package/dist/src/cli/dev/tui/model-editor.d.ts +103 -0
- package/dist/src/cli/dev/tui/model-editor.js +1 -0
- package/dist/src/cli/dev/tui/prompt-command-handler.d.ts +1 -1
- package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
- package/dist/src/cli/dev/tui/remote-auth-command.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +5 -0
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.d.ts +1 -1
- package/dist/src/cli/dev/tui/setup-commands.js +2 -2
- package/dist/src/cli/dev/tui/setup-flow.d.ts +3 -0
- package/dist/src/cli/dev/tui/setup-panel.d.ts +33 -0
- package/dist/src/cli/dev/tui/setup-panel.js +4 -4
- package/dist/src/cli/dev/tui/status-line.d.ts +8 -6
- package/dist/src/cli/dev/tui/status-line.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.d.ts +3 -0
- package/dist/src/cli/dev/tui/terminal-renderer.js +11 -10
- package/dist/src/cli/dev/tui/test/fake-setup-flow-renderer.js +1 -1
- package/dist/src/cli/dev/tui/theme.d.ts +14 -0
- package/dist/src/cli/dev/tui/theme.js +1 -1
- package/dist/src/cli/dev/tui/tool-format.js +1 -1
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/run.js +2 -2
- package/dist/src/cli/ui/live-row.js +1 -1
- package/dist/src/client/agent-info-schema.d.ts +9 -0
- package/dist/src/client/agent-info-schema.js +1 -1
- package/dist/src/client/client.js +1 -1
- package/dist/src/client/eve-agent-store.d.ts +1 -2
- package/dist/src/client/eve-agent-store.js +1 -1
- package/dist/src/client/open-stream.d.ts +14 -10
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session-utils.d.ts +2 -1
- package/dist/src/client/session-utils.js +1 -1
- package/dist/src/client/session.d.ts +3 -5
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/types.d.ts +0 -6
- package/dist/src/compiler/extension-compatibility.d.ts +2 -2
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/context/build-dynamic-tools.js +1 -1
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker-cli.d.ts +4 -0
- package/dist/src/execution/sandbox/bindings/docker-cli.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-create.js +1 -1
- package/dist/src/execution/terminal-session-failure-step.js +1 -1
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/model-call-error.d.ts +11 -30
- package/dist/src/harness/model-call-error.js +1 -1
- package/dist/src/harness/semantic-errors/index.d.ts +9 -0
- package/dist/src/harness/semantic-errors/index.js +1 -0
- package/dist/src/harness/semantic-errors/rule.d.ts +76 -0
- package/dist/src/harness/semantic-errors/rule.js +1 -0
- package/dist/src/harness/semantic-errors/rules/gateway.d.ts +11 -0
- package/dist/src/harness/semantic-errors/rules/gateway.js +1 -0
- package/dist/src/harness/semantic-errors/rules/model-provider.d.ts +11 -0
- package/dist/src/harness/semantic-errors/rules/model-provider.js +1 -0
- package/dist/src/harness/semantic-errors/rules/sandbox.d.ts +16 -0
- package/dist/src/harness/semantic-errors/rules/sandbox.js +1 -0
- package/dist/src/harness/semantic-errors/rules/system.d.ts +2 -0
- package/dist/src/harness/semantic-errors/rules/system.js +1 -0
- package/dist/src/harness/semantic-errors/rules/workflow.d.ts +9 -0
- package/dist/src/harness/semantic-errors/rules/workflow.js +1 -0
- package/dist/src/harness/semantic-errors/signals.d.ts +28 -0
- package/dist/src/harness/semantic-errors/signals.js +1 -0
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/harness/workflow-sandbox.d.ts +6 -0
- package/dist/src/harness/workflow-sandbox.js +2 -2
- package/dist/src/internal/application/output-publication-lock.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/logging.d.ts +33 -1
- package/dist/src/internal/logging.js +1 -1
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.d.ts +3 -1
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
- package/dist/src/internal/workflow/development-world-client.js +1 -1
- package/dist/src/internal/workflow/development-world-server.js +1 -1
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/public/models/openai/chatgpt/model.js +3 -1
- package/dist/src/react/use-eve-agent.d.ts +0 -1
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/setup/boxes/add-channels.js +1 -1
- package/dist/src/setup/boxes/deploy-project.js +1 -1
- package/dist/src/setup/boxes/model-capabilities.d.ts +24 -0
- package/dist/src/setup/boxes/model-capabilities.js +1 -0
- package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
- package/dist/src/setup/boxes/select-model.d.ts +30 -8
- package/dist/src/setup/boxes/select-model.js +1 -1
- package/dist/src/setup/cli/option-row.js +1 -1
- package/dist/src/setup/cli/prompt-ui.d.ts +2 -0
- package/dist/src/setup/cli/prompt-ui.js +2 -2
- package/dist/src/setup/cli/rail-log.d.ts +4 -6
- package/dist/src/setup/cli/rail-log.js +3 -2
- package/dist/src/setup/connection-connector.js +2 -2
- package/dist/src/setup/flows/login.js +1 -1
- package/dist/src/setup/flows/model-source-change.d.ts +38 -0
- package/dist/src/setup/flows/model-source-change.js +1 -0
- package/dist/src/setup/flows/model.d.ts +65 -62
- package/dist/src/setup/flows/model.js +1 -1
- package/dist/src/setup/flows/provider.d.ts +20 -0
- package/dist/src/setup/flows/provider.js +3 -3
- package/dist/src/setup/prompter.d.ts +2 -0
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/slack-connect-lifecycle.js +1 -1
- package/dist/src/setup/slackbot.js +1 -1
- package/dist/src/setup/vercel-project.d.ts +6 -0
- package/dist/src/setup/vercel-project.js +0 -0
- package/dist/src/shared/dynamic-tool-definition.d.ts +1 -8
- package/dist/src/shared/errors.d.ts +5 -0
- package/dist/src/shared/errors.js +1 -1
- package/dist/src/shared/gateway-service-tier.d.ts +19 -0
- package/dist/src/shared/gateway-service-tier.js +1 -0
- package/dist/src/shared/model-summary.d.ts +12 -0
- package/dist/src/shared/model-summary.js +1 -0
- package/dist/src/shared/workflow-sandbox.d.ts +2 -0
- package/dist/src/shared/workflow-sandbox.js +1 -1
- package/dist/src/source-change/agent-config-ast.d.ts +54 -0
- package/dist/src/source-change/agent-config-ast.js +2 -0
- package/dist/src/source-change/agent-config-string-path.d.ts +18 -0
- package/dist/src/source-change/agent-config-string-path.js +2 -0
- package/dist/src/source-change/apply-agent-model-settings.d.ts +26 -0
- package/dist/src/source-change/apply-agent-model-settings.js +1 -0
- package/dist/src/source-change/apply-model-name.js +1 -2
- package/dist/src/source-change/static-source-change.d.ts +14 -0
- package/dist/src/source-change/static-source-change.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +0 -6
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.d.ts +0 -2
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/concepts/execution-model-and-durability.md +1 -1
- package/docs/concepts/sessions-runs-and-streaming.md +1 -1
- package/docs/getting-started.mdx +1 -1
- package/docs/guides/auth-and-route-protection.md +1 -1
- package/docs/guides/client/overview.mdx +1 -1
- package/docs/guides/client/streaming.mdx +1 -10
- package/docs/guides/deployment/meta.json +4 -0
- package/docs/guides/deployment/overview.md +61 -0
- package/docs/guides/deployment/self-hosting.md +88 -0
- package/docs/guides/deployment/vercel.mdx +90 -0
- package/docs/guides/dev-tui.md +8 -4
- package/docs/guides/dynamic-capabilities.md +2 -0
- package/docs/guides/frontend/nextjs.mdx +1 -1
- package/docs/guides/frontend/nuxt.mdx +1 -1
- package/docs/guides/frontend/overview.mdx +2 -5
- package/docs/guides/frontend/sveltekit.mdx +1 -1
- package/docs/guides/frontend/use-eve-agent-svelte.mdx +1 -4
- package/docs/guides/frontend/use-eve-agent-vue.mdx +1 -4
- package/docs/guides/instrumentation.md +1 -1
- package/docs/reference/cli.md +24 -2
- package/docs/tutorial/ship-it.mdx +1 -1
- package/package.json +1 -1
- package/docs/guides/deployment.md +0 -210
- /package/dist/src/cli/{dev/tui → ui}/live-region.d.ts +0 -0
- /package/dist/src/cli/{dev/tui → ui}/live-region.js +0 -0
- /package/dist/src/cli/{dev/tui → ui}/terminal-text.d.ts +0 -0
- /package/dist/src/cli/{dev/tui → ui}/terminal-text.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EVE_CREATE_SESSION_ROUTE_PATH,createEveCancelTurnRoutePath,createEveContinueSessionRoutePath}from"#protocol/routes.js";import{ClientError}from"#client/client-error.js";import{advanceSession}from"#client/session-utils.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{EVE_SESSION_ID_HEADER,isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{
|
|
1
|
+
import{EVE_CREATE_SESSION_ROUTE_PATH,createEveCancelTurnRoutePath,createEveContinueSessionRoutePath}from"#protocol/routes.js";import{ClientError}from"#client/client-error.js";import{advanceSession}from"#client/session-utils.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{EVE_SESSION_ID_HEADER,isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{CancelTurnResponseSchema}from"#protocol/cancel-turn.js";import{followStreamIterable}from"#client/open-stream.js";import{serializeOutputSchema}from"#shared/tool-schema.js";var ClientSession=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}get state(){return this.#t}async send(e){let t=normalizeSendTurnInput(e),n=this.#t,{continuationToken:r,sessionId:i}=await this.#n(t,n);return this.#t===n&&(this.#t={...n,sessionId:i}),new MessageResponse({continuationToken:r,createStream:()=>this.#r(i,r,n,t),sessionId:i})}async cancel(e){let n=this.#t.sessionId;if(!n)throw Error(`Session has no session ID. Send a message first.`);let i=createClientUrl(this.#e.host,createEveCancelTurnRoutePath(n)),o=await this.#e.resolveHeaders();o.set(`content-type`,`application/json`);let s=await fetch(i,withRedirectPolicy({headers:o,method:`POST`,body:e?JSON.stringify(e):void 0},this.#e.redirect)),c=await s.text();if(!s.ok)throw new ClientError(s.status,c,s.headers);let u;try{u=JSON.parse(c)}catch{throw Error(`Cancel route returned invalid JSON (${s.status}).`)}let d=CancelTurnResponseSchema.safeParse(u);if(!d.success||d.data.sessionId!==n)throw Error(`Cancel route returned an invalid response (${s.status}).`);return{sessionId:d.data.sessionId,status:d.data.status}}stream(e){let t=this.#t.sessionId;if(!t)throw Error(`Session has no session ID. Send a message first.`);return this.#i(t,e)}async#n(t,r){let i=r.sessionId?createEveContinueSessionRoutePath(r.sessionId):EVE_CREATE_SESSION_ROUTE_PATH,o=createClientUrl(this.#e.host,i),c=await this.#e.resolveHeaders(t.headers);c.set(`content-type`,`application/json`);let l=createHandleMessageBody({input:t,outputSchema:serializeOutputSchema(t.outputSchema),session:r});if(l===null)throw Error(`Session.send requires a non-empty message, inputResponses, or both.`);let u=await postTurnWithRetry({body:JSON.stringify(l),headers:c,mustDeliver:(t.inputResponses?.length??0)>0,redirect:this.#e.redirect,signal:t.signal,url:o}),f=await u.json(),p=(typeof f.sessionId==`string`?f.sessionId:void 0)??u.headers.get(EVE_SESSION_ID_HEADER)?.trim()??r.sessionId;if(!p)throw Error(`Message route did not return a session id.`);return{continuationToken:typeof f.continuationToken==`string`?f.continuationToken:void 0,sessionId:p}}async*#r(e,t,n,r){let a=[];try{for await(let t of followStreamIterable({host:this.#e.host,resolveHeaders:()=>this.#e.resolveHeaders(r.headers),redirect:this.#e.redirect,sessionId:e,signal:r.signal,startIndex:n.sessionId===e?n.streamIndex:0}))if(a.push(t),yield t,isCurrentTurnBoundaryEvent(t))break}finally{this.#t=advanceSession({continuationToken:t,events:a,preserveCompletedSessions:this.#e.preserveCompletedSessions,sessionId:e,session:n})}}async*#i(e,t){let n=this.#t,r=t?.startIndex??n.streamIndex,a=[];try{for await(let n of followStreamIterable({host:this.#e.host,resolveHeaders:()=>this.#e.resolveHeaders(),redirect:this.#e.redirect,sessionId:e,signal:t?.signal,startIndex:r}))a.push(n),yield n}finally{r>=0&&(this.#t=advanceSession({continuationToken:n.continuationToken,events:a,preserveCompletedSessions:this.#e.preserveCompletedSessions,session:{...n,sessionId:e,streamIndex:r},sessionId:e}))}}};async function postTurnWithRetry(e){let t=e.mustDeliver?10:1,n,i,a;for(let o=0;o<t;o+=1){let s=await fetch(e.url,{body:e.body,headers:e.headers,method:`POST`,redirect:e.redirect,signal:e.signal??null});if(s.ok)return s;if(n=s.status,i=await s.text(),a=s.headers,!isRetryableDeliveryFailure(s.status,i))throw new ClientError(s.status,i,s.headers);o<t-1&&await sleep(200)}throw new ClientError(n??0,i??`Failed to deliver session turn.`,a)}function isRetryableDeliveryFailure(e,t){return e===500&&/target session was not found/i.test(t)}async function sleep(e){await new Promise(t=>setTimeout(t,e))}function normalizeSendTurnInput(e){return typeof e==`string`?{message:e}:e}function createHandleMessageBody(e){let t={};return e.input.message!==void 0&&(t.message=e.input.message),e.input.inputResponses!==void 0&&e.input.inputResponses.length>0&&(t.inputResponses=e.input.inputResponses),e.input.clientContext!==void 0&&(t.clientContext=e.input.clientContext),e.outputSchema!==void 0&&(t.outputSchema=e.outputSchema),e.session.continuationToken!==void 0&&(t.continuationToken=e.session.continuationToken),Object.keys(t).length===0||e.session.continuationToken===void 0&&t.message===void 0||e.session.continuationToken!==void 0&&t.message===void 0&&t.inputResponses===void 0?null:t}function withRedirectPolicy(e,t){return t===void 0?e:{...e,redirect:t}}export{ClientSession};
|
|
@@ -67,12 +67,6 @@ export interface ClientOptions {
|
|
|
67
67
|
* redirect.
|
|
68
68
|
*/
|
|
69
69
|
readonly redirect?: ClientRedirectPolicy;
|
|
70
|
-
/**
|
|
71
|
-
* Maximum number of stream reconnection attempts per message turn.
|
|
72
|
-
*
|
|
73
|
-
* @default 3
|
|
74
|
-
*/
|
|
75
|
-
readonly maxReconnectAttempts?: number;
|
|
76
70
|
/**
|
|
77
71
|
* Keep a session's continuation token after a normal `session.completed`
|
|
78
72
|
* boundary.
|
|
@@ -16,8 +16,8 @@ declare const EXTENSION_CAPABILITY_CONTRACTS: {
|
|
|
16
16
|
readonly dropped: {};
|
|
17
17
|
};
|
|
18
18
|
readonly dynamicTool: {
|
|
19
|
-
readonly current:
|
|
20
|
-
readonly supported: readonly [1];
|
|
19
|
+
readonly current: 2;
|
|
20
|
+
readonly supported: readonly [1, 2];
|
|
21
21
|
readonly dropped: {};
|
|
22
22
|
};
|
|
23
23
|
readonly connection: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z}from"#compiled/zod/index.js";import{join}from"node:path";import{readFile,writeFile}from"node:fs/promises";import{formatValidationError}from"#runtime/validation.js";const EXTENSION_COMPATIBILITY_MANIFEST_KIND=`eve-extension`,EXTENSION_COMPATIBILITY_MANIFEST_FORMAT_VERSION=1,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME=`_manifest.json`,EXTENSION_CAPABILITY_CONTRACTS={extension:{current:1,supported:[1],dropped:{}},tool:{current:1,supported:[1],dropped:{}},dynamicTool:{current:
|
|
1
|
+
import{z}from"#compiled/zod/index.js";import{join}from"node:path";import{readFile,writeFile}from"node:fs/promises";import{formatValidationError}from"#runtime/validation.js";const EXTENSION_COMPATIBILITY_MANIFEST_KIND=`eve-extension`,EXTENSION_COMPATIBILITY_MANIFEST_FORMAT_VERSION=1,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME=`_manifest.json`,EXTENSION_CAPABILITY_CONTRACTS={extension:{current:1,supported:[1],dropped:{}},tool:{current:1,supported:[1],dropped:{}},dynamicTool:{current:2,supported:[1,2],dropped:{}},connection:{current:1,supported:[1],dropped:{}},hook:{current:1,supported:[1],dropped:{}},skill:{current:1,supported:[1],dropped:{}},dynamicSkill:{current:1,supported:[1],dropped:{}},instructions:{current:1,supported:[1],dropped:{}},dynamicInstructions:{current:1,supported:[1],dropped:{}},config:{current:1,supported:[1],dropped:{}},state:{current:1,supported:[1],dropped:{}}},EXTENSION_CAPABILITY_VERSIONS=Object.fromEntries(Object.entries(EXTENSION_CAPABILITY_CONTRACTS).map(([e,t])=>[e,t.current])),EXTENSION_CAPABILITY_SUPPORT=Object.keys(EXTENSION_CAPABILITY_CONTRACTS).reduce((e,t)=>(e[t]=EXTENSION_CAPABILITY_CONTRACTS[t].supported,e),{}),extensionCompatibilityManifestSchema=z.object({kind:z.literal(EXTENSION_COMPATIBILITY_MANIFEST_KIND),formatVersion:z.literal(1),builtWithEve:z.string().min(1),requires:z.record(z.string(),z.number().int().positive())}).strict();function serializeExtensionCompatibilityManifest(e){return`${JSON.stringify(e,null,2)}\n`}function parseExtensionCompatibilityManifest(e,t){let n;try{n=JSON.parse(e)}catch(e){throw Error(`Extension compatibility manifest "${t}" is not valid JSON: ${e instanceof Error?e.message:String(e)}`)}let r=extensionCompatibilityManifestSchema.safeParse(n);if(!r.success)throw Error(`Extension compatibility manifest "${t}" is invalid. ${formatValidationError(r.error)}`);return r.data}async function readExtensionCompatibilityManifest(e){return parseExtensionCompatibilityManifest(await readFile(e,`utf8`),e)}async function writeExtensionCompatibilityManifest(e,n){await writeFile(join(e,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME),serializeExtensionCompatibilityManifest(n),`utf8`)}function findUnsupportedExtensionCapabilities(e,t=EXTENSION_CAPABILITY_SUPPORT){return Object.entries(e.requires).flatMap(([e,n])=>{let r=Object.hasOwn(t,e)?t[e]??[]:[];return r.includes(n)?[]:[{capability:e,requiredVersion:n,supportedVersions:r}]}).sort((e,t)=>e.capability.localeCompare(t.capability))}export{EXTENSION_CAPABILITY_SUPPORT,EXTENSION_CAPABILITY_VERSIONS,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME,EXTENSION_COMPATIBILITY_MANIFEST_FORMAT_VERSION,EXTENSION_COMPATIBILITY_MANIFEST_KIND,findUnsupportedExtensionCapabilities,parseExtensionCompatibilityManifest,readExtensionCompatibilityManifest,serializeExtensionCompatibilityManifest,writeExtensionCompatibilityManifest};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{LiveStepToolsKey,SessionDynamicToolMetadataKey,TurnDynamicToolMetadataKey}from"#context/keys.js";import{toInputSchema,toOutputSchema}from"#shared/tool-schema.js";import{
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{LiveStepToolsKey,SessionDynamicToolMetadataKey,TurnDynamicToolMetadataKey}from"#context/keys.js";import{toInputSchema,toOutputSchema}from"#shared/tool-schema.js";import{createToolExecuteWithAuth}from"#execution/tool-auth.js";const log=createLogger(`dynamic-tools`);function lookupStepFunction(e){try{let t=globalThis[Symbol.for(`@workflow/core//registeredSteps`)];return t===void 0?null:t.get(e)||null}catch{return null}}function replayTools(e){let t=[];for(let n of e){if(!n.executeStepFnName||!n.closureVars){log.warn(`Dynamic tool "${n.name}" has no registered step function — skipping on this step. The bundler transform may not have processed this tool file.`);continue}let e=lookupStepFunction(n.executeStepFnName);if(!e){log.warn(`Dynamic tool "${n.name}" references step function "${n.executeStepFnName}" which is not registered — skipping on this step.`);continue}t.push({description:n.description,execute:createToolExecuteWithAuth({scope:n.name,execute:(t,r)=>e(n.closureVars,t,r)}),inputSchema:toInputSchema(n.inputSchema),name:n.name,approval:buildReplayedApproval(n),outputSchema:toOutputSchema(n.outputSchema)})}return t}function buildReplayedApproval(e){if(e.approvalStepFnName===void 0)return;let t=lookupStepFunction(e.approvalStepFnName);return t===null?(log.warn(`Dynamic tool "${e.name}" references approval function "${e.approvalStepFnName}" which is not registered — requiring approval by default.`),()=>`user-approval`):async n=>await t(e.closureVars??{},n)}function buildDynamicTools(e){let i=e.get(LiveStepToolsKey)??[],a=replayTools(e.get(TurnDynamicToolMetadataKey)??[]),o=replayTools(e.get(SessionDynamicToolMetadataKey)??[]);return[...i,...a,...o]}export{buildDynamicTools};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{LiveStepToolsKey,SessionDynamicToolMetadataKey,TurnDynamicToolMetadataKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{serializeInputSchema,serializeOutputSchema,toInputSchema,toOutputSchema}from"#shared/tool-schema.js";import{ALLOWED_DYNAMIC_TOOL_EVENTS,isBrandedToolEntry}from"#shared/dynamic-tool-definition.js";import{
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{LiveStepToolsKey,SessionDynamicToolMetadataKey,TurnDynamicToolMetadataKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{serializeInputSchema,serializeOutputSchema,toInputSchema,toOutputSchema}from"#shared/tool-schema.js";import{ALLOWED_DYNAMIC_TOOL_EVENTS,isBrandedToolEntry}from"#shared/dynamic-tool-definition.js";import{createToolExecuteWithAuth}from"#execution/tool-auth.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";const log=createLogger(`dynamic-tools`);function toHarnessToolDefinition(e,t){return{description:t.description,execute:createToolExecuteWithAuth({scope:e,execute:(e,n)=>t.execute(e,n)}),inputSchema:toInputSchema(t.inputSchema),name:e,approval:t.approval,outputSchema:toOutputSchema(t.outputSchema),...t.toModelOutput===void 0?{}:{toModelOutput:t.toModelOutput}}}function qualifyDynamicToolNames(e,t,n){let r=Object.keys(n),i=[];if(r.length===0)return i;if(t)return i.push({name:e.slug,entryKey:r[0],entry:n[r[0]]}),i;let a=e.extensionNamespace===void 0?``:`${e.extensionNamespace}__`;for(let e of r)i.push({name:`${a}${e}`,entryKey:e,entry:n[e]});return i}function replayDynamicSessionTools(e,t){let n=[];for(let t of e){if(!t.executeStepFnName||!t.closureVars){log.warn(`Dynamic tool "${t.name}" has no registered step function — skipping on this step. The bundler transform may not have processed this tool file.`);continue}let e=lookupStepFunction(t.executeStepFnName);if(!e){log.warn(`Dynamic tool "${t.name}" references step function "${t.executeStepFnName}" which is not registered — skipping on this step.`);continue}n.push({description:t.description,execute:createToolExecuteWithAuth({scope:t.name,execute:(n,r)=>e(t.closureVars,n,r)}),inputSchema:toInputSchema(t.inputSchema),name:t.name,outputSchema:toOutputSchema(t.outputSchema)})}return n}function getStepRegistry(){let e=Symbol.for(`@workflow/core//registeredSteps`),t=globalThis,n=t[e];return n===void 0&&(n=new Map,t[e]=n),n}function lookupStepFunction(e){try{return getStepRegistry().get(e)||null}catch{return null}}function registerStepFunction(e,t){getStepRegistry().set(e,t)}function safeSerialize(e){try{return JSON.parse(JSON.stringify(e))}catch{return{}}}function durableKeyForEvent(e){switch(e){case`session.started`:return SessionDynamicToolMetadataKey;case`turn.started`:return TurnDynamicToolMetadataKey;default:return}}async function resolveToolsFromEvent(e,t,n,r){let s=await Promise.allSettled(t.map(async t=>{let i=t.events[n.type];if(i===void 0)return null;let a=await i(n,buildResolveContext(e,r));if(a==null)return null;let o,s;return isBrandedToolEntry(a)?(o={_single:a},s=!0):(o=a,s=!1),{resolver:t,entries:o,isSingle:s}})),c=[],l=[],d=new Map;for(let e of s){if(e.status===`rejected`){log.error(`Dynamic tool resolver (${n.type}) threw — skipping.`,{error:toErrorMessage(e.reason)});continue}if(e.value===null)continue;let{resolver:t,entries:r,isSingle:s}=e.value,u=qualifyDynamicToolNames(t,s,r);for(let{name:e,entryKey:r,entry:i}of u){let s=d.get(e);if(s!==void 0&&s!==t.slug)throw Error(`Dynamic tool "${e}" from resolver "${t.slug}" collides with dynamic resolver "${s}". Namespace the map key manually, e.g. "${t.slug}__${e}".`);if(d.set(e,t.slug),l.push(toHarnessToolDefinition(e,i)),n.type===`step.started`)continue;let u=`__executeStepFn`in i?i.__executeStepFn:void 0,f=`__closureVars`in i?i.__closureVars:void 0,p=u?.stepId,m=f===void 0?void 0:safeSerialize(f);if(p===void 0){let e=`eve:framework-dynamic:${t.slug}:${r}`,n=i.execute.bind(i);registerStepFunction(e,(e,t,r)=>n(t,r)),p=e,m={}}let h;if(i.approval!==void 0){h=`eve:dynamic-tool-approval:${t.slug}:${r}`;let e=i.approval.bind(i);registerStepFunction(h,(t,n)=>e(n))}c.push({name:e,description:i.description,inputSchema:serializeInputSchema(i.inputSchema),outputSchema:serializeOutputSchema(i.outputSchema),resolverSlug:t.slug,entryKey:r,executeStepFnName:p,approvalStepFnName:h,closureVars:m})}}return{metadata:c,liveTools:l}}async function dispatchDynamicToolEvent(e){let{ctx:n,resolvers:r,event:i,messages:a}=e;if(!ALLOWED_DYNAMIC_TOOL_EVENTS.has(i.type))return;let o=r.filter(e=>e.eventNames.includes(i.type));if(o.length===0)return;let{metadata:s,liveTools:c}=await resolveToolsFromEvent(n,o,i,a);if(i.type===`step.started`){n.setVirtualContext(LiveStepToolsKey,c);return}let u=durableKeyForEvent(i.type);if(u===void 0)return;let d=new Set(o.map(e=>e.slug)),f=(n.get(u)??[]).filter(e=>!d.has(e.resolverSlug));n.set(u,[...f,...s])}export{dispatchDynamicToolEvent,replayDynamicSessionTools};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{UNSPECIFIED_INPUT_SCHEMA,toInputSchema,toOutputSchema}from"#shared/tool-schema.js";import{resolveRuntimeModelReference}from"#runtime/agent/resolve-model.js";import{dispatchDynamicModelEvent}from"#context/dynamic-model-lifecycle.js";import{createToolLoopHarness}from"#harness/tool-loop.js";import{AGENT_TOOL_DESCRIPTION,AGENT_TOOL_NAME}from"#runtime/framework-tools/agent.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{SUBAGENT_TOOL_INPUT_SCHEMA}from"#runtime/subagents/registry.js";import{findRegisteredRuntimeTool}from"#runtime/tools/registry.js";import{preserveFrameworkStateOnCompaction}from"#execution/compaction.js";
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{UNSPECIFIED_INPUT_SCHEMA,toInputSchema,toOutputSchema}from"#shared/tool-schema.js";import{createToolExecuteWithAuth}from"#execution/tool-auth.js";import{resolveRuntimeModelReference}from"#runtime/agent/resolve-model.js";import{dispatchDynamicModelEvent}from"#context/dynamic-model-lifecycle.js";import{createToolLoopHarness}from"#harness/tool-loop.js";import{AGENT_TOOL_DESCRIPTION,AGENT_TOOL_NAME}from"#runtime/framework-tools/agent.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{SUBAGENT_TOOL_INPUT_SCHEMA}from"#runtime/subagents/registry.js";import{findRegisteredRuntimeTool}from"#runtime/tools/registry.js";import{preserveFrameworkStateOnCompaction}from"#execution/compaction.js";const log=createLogger(`execution.node-step`);function createExecutionNodeStep(e){let t=createRuntimeModelResolver(e.modelResolutionScope),n=e.node.turnAgent.dynamicModel===void 0?void 0:createRuntimeDynamicModelEventDispatcher(e.modelResolutionScope,e.node.turnAgent.dynamicModel),r=createNodeHarnessTools({node:e.node});return createToolLoopHarness({abortSignal:e.abortSignal,capabilities:e.capabilities,workflow:e.node.agent.workflowTool!==void 0,workflowMaxSubagents:e.workflowMaxSubagents,handleEvent:e.handleEvent,mode:e.mode,onCompaction:preserveFrameworkStateOnCompaction,dispatchDynamicModelEvent:n,resolveModel:t,runtimeIdentity:buildRuntimeIdentity(e.node),tools:r})}function buildRuntimeIdentity(e){let n=resolveInstalledPackageInfo(),r={agentId:e.turnAgent.id,agentName:e.agent.config?.name,eveVersion:n.version,modelId:e.turnAgent.dynamicModel===void 0?e.turnAgent.model.id:`dynamic:${e.turnAgent.model.id}`},i=process.env.VERCEL_GIT_COMMIT_SHA?.trim(),a=process.env.VERCEL_GIT_COMMIT_REF?.trim(),o=process.env.VERCEL_DEPLOYMENT_CREATED_AT?.trim();return i||a||o?{...r,build:{deployedAt:o||void 0,gitBranch:a||void 0,gitSha:i||void 0}}:r}function createRuntimeModelResolver(e){return t=>resolveRuntimeModelReference(t,e)}function createRuntimeDynamicModelEventDispatcher(e,t){return n=>dispatchDynamicModelEvent({ctx:n.ctx,dynamicModel:t,event:n.event,fallback:n.fallback,messages:n.messages,scope:e})}function createNodeHarnessTools(e){let t=new Map;for(let n of e.node.turnAgent.tools){let r=resolveHarnessToolDefinition({node:e.node,tool:n});r!==null&&t.set(n.name,r)}return e.node.nodeId===ROOT_RUNTIME_AGENT_NODE_ID&&!e.node.agent.disabledFrameworkTools.includes(AGENT_TOOL_NAME)&&!t.has(AGENT_TOOL_NAME)&&t.set(AGENT_TOOL_NAME,{description:AGENT_TOOL_DESCRIPTION,inputSchema:SUBAGENT_TOOL_INPUT_SCHEMA,name:AGENT_TOOL_NAME,runtimeAction:{kind:`subagent-call`,nodeId:e.node.nodeId,subagentName:AGENT_TOOL_NAME}}),t}function resolveHarnessToolDefinition(e){if(e.tool.kind===`subagent`||e.tool.kind===`remote`){let t=e.tool.kind===`remote`?{kind:`remote-agent-call`,nodeId:e.tool.nodeId,remoteAgentName:e.tool.name,subagentName:e.tool.name}:{kind:`subagent-call`,nodeId:e.tool.nodeId,subagentName:e.tool.name};return{description:e.tool.description??``,inputSchema:toInputSchema(e.tool.inputSchema)??UNSPECIFIED_INPUT_SCHEMA,name:e.tool.name,outputSchema:toOutputSchema(e.tool.outputSchema),runtimeAction:t}}let t=findRegisteredRuntimeTool(e.node.toolRegistry,e.tool.name);if(t===null)return log.warn(`declared tool is not registered — omitting from toolset`,{toolName:e.tool.name,nodeId:e.node.nodeId}),null;let a=t.definition,o=a.sourceId.startsWith(`eve:`),s=a.execute;return{approvalKey:a.approvalKey,description:a.description,execute:resolveAuthoredExecute({isFrameworkTool:o,rawExecute:s,scope:a.name}),inputSchema:a.inputSchema??UNSPECIFIED_INPUT_SCHEMA,name:a.name,approval:a.approval,outputSchema:a.outputSchema,toModelOutput:a.toModelOutput}}function resolveAuthoredExecute(e){let{isFrameworkTool:t,rawExecute:n,scope:r}=e;return n===void 0?void 0:t?n:createToolExecuteWithAuth({execute:n,scope:r})}export{createExecutionNodeStep,createNodeHarnessTools};
|
|
@@ -49,12 +49,16 @@ export interface DockerCli {
|
|
|
49
49
|
* installed or not on `PATH`).
|
|
50
50
|
*/
|
|
51
51
|
export declare class DockerUnavailableError extends Error {
|
|
52
|
+
/** Structured remediation, surfaced by the semantic-error catalog. */
|
|
53
|
+
readonly hint: string;
|
|
52
54
|
constructor(cause?: unknown);
|
|
53
55
|
}
|
|
54
56
|
/**
|
|
55
57
|
* Raised when the `docker` CLI exists but the daemon is not reachable.
|
|
56
58
|
*/
|
|
57
59
|
export declare class DockerDaemonUnavailableError extends Error {
|
|
60
|
+
/** Structured remediation, surfaced by the semantic-error catalog. */
|
|
61
|
+
readonly hint: string;
|
|
58
62
|
constructor(detail: string);
|
|
59
63
|
}
|
|
60
64
|
/**
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{spawn,spawnSync}from"node:child_process";import{Readable}from"node:stream";var DockerUnavailableError=class extends Error{
|
|
1
|
+
import{spawn,spawnSync}from"node:child_process";import{Readable}from"node:stream";var DockerUnavailableError=class extends Error{hint="Install and start Docker Desktop, OrbStack, Colima, or another runtime exposing a Docker-compatible `docker` CLI (or point EVE_DOCKER_PATH at one, e.g. Podman). Alternatively use microsandbox(), the dependency-free justbash(), vercel(), or defaultSandbox() to pick by availability.";constructor(e){super("The Docker sandbox backend requires Docker, but the `docker` CLI was not found.",{cause:e}),this.name=`DockerUnavailableError`}},DockerDaemonUnavailableError=class extends Error{hint="Start Docker Desktop (or your Docker-compatible runtime) and retry. Alternatively use microsandbox(), the dependency-free justbash() (installed automatically by `eve dev`, or `pnpm add -D just-bash`), vercel(), or defaultSandbox() to pick by availability.";constructor(e){super(`The Docker sandbox backend requires a running Docker daemon, but it is not reachable. Docker reported: ${e}`),this.name=`DockerDaemonUnavailableError`}};async function assertDockerDaemonAvailable(e){let t=await e.run([`version`,`--format`,`{{.Server.Version}}`]);if(t.exitCode!==0)throw new DockerDaemonUnavailableError(firstLine(t.stderr)||`exit ${t.exitCode}`)}function resolveDockerExecutable(){let e=process.env.EVE_DOCKER_PATH?.trim();return e!==void 0&&e.length>0?e:`docker`}let cachedDockerAvailability;function isDockerDaemonAvailableSync(){return cachedDockerAvailability??=probeDockerDaemonSync(),cachedDockerAvailability}function probeDockerDaemonSync(){try{return spawnSync(resolveDockerExecutable(),[`version`,`--format`,`{{.Server.Version}}`],{stdio:`ignore`,timeout:5e3}).status===0}catch{return!1}}function createDockerCli(){return{async run(t,n={}){throwIfAborted(n.signal);let r=spawn(resolveDockerExecutable(),t,{signal:n.signal,stdio:[n.stdin===void 0?`ignore`:`pipe`,`pipe`,`pipe`]}),i=[],a=[];r.stdout?.on(`data`,e=>i.push(e)),r.stderr?.on(`data`,e=>a.push(e)),n.stdin!==void 0&&r.stdin?.end(n.stdin);let o=await new Promise((e,t)=>{r.on(`error`,e=>t(adaptSpawnError(e))),r.on(`close`,t=>e(t??1))}),s=Buffer.concat(i);return{exitCode:o,stderr:Buffer.concat(a).toString(`utf8`),stdout:s.toString(`utf8`),stdoutBytes:s}},stream(t,r={}){throwIfAborted(r.signal);let i=spawn(resolveDockerExecutable(),t,{signal:r.signal,stdio:[`ignore`,`pipe`,`pipe`]}),a=new Promise((e,t)=>{i.on(`error`,e=>t(adaptSpawnError(e))),i.on(`close`,t=>e(t??1))});return a.catch(()=>{}),{stdout:Readable.toWeb(i.stdout),stderr:Readable.toWeb(i.stderr),async wait(){return{exitCode:await a}},async kill(){i.kill(`SIGKILL`),await a.catch(()=>{})}}}}}function adaptSpawnError(e){return e.code===`ENOENT`?new DockerUnavailableError(e):e.code===`ABORT_ERR`?new DOMException(`The operation was aborted.`,`AbortError`):e}function throwIfAborted(e){if(e?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`)}function firstLine(e){return e.split(`
|
|
2
2
|
`,1)[0]?.trim()??``}export{DockerDaemonUnavailableError,DockerUnavailableError,assertDockerDaemonAvailable,createDockerCli,isDockerDaemonAvailableSync};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{toErrorMessage}from"#shared/errors.js";async function createMicrosandboxWithProgress(e){let t={phase:`resolving the image`};try{let n=await e.builder.createWithPullProgress(),r=reportMicrosandboxCreateProgress(n,t,e.log);try{return await withHeartbeat(t,e.log,async()=>await n.awaitSandbox())}finally{await r.catch(()=>{})}}catch(n){throw enrichMicrosandboxError({context:`Failed to create microsandbox VM from ${e.source} while ${t.phase}`,error:n,errorType:e.errorType})}}function enrichMicrosandboxError(t){if(t.error instanceof MicrosandboxDiagnosticError)return t.error;let n=readMicrosandboxErrorCode(t.error,t.errorType),r=n===void 0?``:` [${n}]`,i=toErrorMessage(t.error),a=/[.!?]$/u.test(i)?i:`${i}
|
|
1
|
+
import{toErrorMessage}from"#shared/errors.js";async function createMicrosandboxWithProgress(e){let t={phase:`resolving the image`};try{let n=await e.builder.createWithPullProgress(),r=reportMicrosandboxCreateProgress(n,t,e.log);try{return await withHeartbeat(t,e.log,async()=>await n.awaitSandbox())}finally{await r.catch(()=>{})}}catch(n){throw enrichMicrosandboxError({context:`Failed to create microsandbox VM from ${e.source} while ${t.phase}`,error:n,errorType:e.errorType})}}function enrichMicrosandboxError(t){if(t.error instanceof MicrosandboxDiagnosticError)return t.error;let n=readMicrosandboxErrorCode(t.error,t.errorType),r=n===void 0?``:` [${n}]`,i=toErrorMessage(t.error),a=/[.!?]$/u.test(i)?i:`${i}.`;return new MicrosandboxDiagnosticError(`${t.context}${r}: ${a}`,{cause:t.error,hint:microsandboxErrorHint(n)})}var MicrosandboxDiagnosticError=class extends Error{hint;constructor(e,t){super(e,t),this.name=`MicrosandboxDiagnosticError`,t?.hint!==void 0&&(this.hint=t.hint)}};async function reportMicrosandboxCreateProgress(e,t,n){for await(let r of e){let e=microsandboxCreatePhase(r,t.phase);e!==t.phase&&(t.phase=e,n?.(e))}}function microsandboxCreatePhase(e,t){switch(e.kind){case`resolving`:case`resolved`:return`resolving the image`;case`layerDownloadProgress`:case`layerDownloadComplete`:case`layerDownloadVerifying`:case`layerMaterializeStarted`:case`layerMaterializeProgress`:case`layerMaterializeWriting`:case`layerMaterializeComplete`:return`downloading and materializing image layers`;case`stitchMergingTrees`:case`stitchWritingFsmeta`:case`stitchWritingVmdk`:case`stitchComplete`:return`assembling the image filesystem`;case`complete`:return`image ready; booting microsandbox VM`;default:return t}}async function withHeartbeat(e,t,n){if(t?.(e.phase),t===void 0)return await n();let r=Date.now(),i=setInterval(()=>{let n=Math.round((Date.now()-r)/1e3);t(`${e.phase} (${n}s elapsed)`)},1e4);i.unref?.();try{return await n()}finally{clearInterval(i)}}const MICROSANDBOX_ERROR_HINTS={database:`Check that the microsandbox npm package and installed VM runtime use the same version. If versions changed, use a clean MSB_HOME or migrate the existing database.`,imageNotFound:`Check that the image exists and that the registry credentials can pull it.`,libkrunfwNotFound:"Run `npx microsandbox install` and verify that MSB_PATH points to the installed runtime."};function readMicrosandboxErrorCode(e,n){if(n!==void 0&&e instanceof n||e instanceof Error&&`code`in e&&typeof e.code==`string`&&Object.hasOwn(MICROSANDBOX_ERROR_HINTS,e.code))return e.code}function microsandboxErrorHint(e){return e===void 0?void 0:MICROSANDBOX_ERROR_HINTS[e]}export{createMicrosandboxWithProgress,enrichMicrosandboxError};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,formatError}from"#internal/logging.js";import{callAdapterEventHandler}from"#channel/adapter.js";import{createSessionFailedEvent,encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{deserializeContext}from"#context/serialize.js";import{buildAdapterContext}from"#channel/adapter-context.js";const log=createLogger(`execution.workflow-entry`);async function emitTerminalSessionFailureStep(e){"use step";let r=formatError(e.error),i=
|
|
1
|
+
import{createLogger,formatError}from"#internal/logging.js";import{callAdapterEventHandler}from"#channel/adapter.js";import{summarizeKnownError}from"#harness/semantic-errors/index.js";import{createSessionFailedEvent,encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{deserializeContext}from"#context/serialize.js";import{buildAdapterContext}from"#channel/adapter-context.js";const log=createLogger(`execution.workflow-entry`);async function emitTerminalSessionFailureStep(e){"use step";let r=formatError(e.error),i=summarizeKnownError(e.error),a=r;if(i!==null){let e={...r,message:i.message,name:i.name,semanticErrorId:i.id};a=i.hint===void 0?e:{...e,hint:i.hint}}let o=typeof a.name==`string`?a.name:`WORKFLOW_EXECUTION_FAILED`,s=typeof a.message==`string`?a.message:String(e.error),c=e.serializedContext[`eve.sessionId`]??``;log.error(`workflow loop threw — emitting terminal session.failed`,{sessionId:c,errorId:typeof a.errorId==`string`?a.errorId:void 0,code:o,message:s,hint:i?.hint,detail:typeof a.detail==`string`?a.detail:void 0});let l=createSessionFailedEvent({code:o,details:a,message:s,sessionId:c});try{let t=await deserializeContext(e.serializedContext),n=t.get(ChannelKey);n!==void 0&&await callAdapterEventHandler(n,l,buildAdapterContext(n,t))}catch(e){log.error(`adapter failed to handle terminal session.failed event`,{errorId:typeof a.errorId==`string`?a.errorId:void 0,sessionId:c,error:e})}try{let t=e.parentWritable.getWriter();try{await t.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(l)))}finally{t.releaseLock()}}catch(e){log.error(`failed to write terminal session.failed event to durable stream`,{errorId:typeof a.errorId==`string`?a.errorId:void 0,sessionId:c,error:e})}}export{emitTerminalSessionFailureStep};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{createActionResultEvent,createActionsRequestedEvent,createMessageAppendedEvent,createMessageCompletedEvent,createMessageReceivedEvent,createReasoningAppendedEvent,createReasoningCompletedEvent,createSessionCompletedEvent,createSessionFailedEvent,createSessionStartedEvent,createSessionWaitingEvent,createStepFailedEvent,createStepStartedEvent,createTurnCompletedEvent,createTurnFailedEvent,createTurnStartedEvent}from"#protocol/message.js";import{createRuntimeActionRequestFromToolCall,resolveToolCallInputObject}from"#harness/runtime-actions.js";import{hasEmptyDeliverySentinel}from"#shared/empty-delivery.js";import{createRuntimeToolResultFromStepResult,createRuntimeToolResultFromToolError,createToolResultMessagePartFromToolError}from"#harness/action-result-helpers.js";import{createInvalidToolCallInputError,isInvalidToolCall}from"#harness/tool-call-input-errors.js";import{createProviderStreamActionBatch}from"#harness/stream-actions.js";import{normalizeModelStreamError}from"#harness/model-call-error.js";import{createOrderedStreamEmitter}from"#harness/ordered-stream-emitter.js";import{interruptStreamOnFailure}from"#harness/interruptible-stream.js";import{isInlineAuthorizationToolResult}from"#harness/inline-tool-authorization.js";const HARNESS_EMISSION_STATE_KEY=`eve.harness.emission`,DEFAULT_EMISSION_STATE={sessionStarted:!1,sequence:0,stepIndex:0,turnId:``};function getHarnessEmissionState(e){return e?.[HARNESS_EMISSION_STATE_KEY]??DEFAULT_EMISSION_STATE}function isHarnessBetweenTurns(e){return getHarnessEmissionState(e.state).turnId===``}function setHarnessEmissionState(e,t){return{...e,state:{...e.state,[HARNESS_EMISSION_STATE_KEY]:t}}}async function emitTurnPreamble(e,t,n,r){let a=`turn_${n.sequence}`;return n.sessionStarted||await e(createSessionStartedEvent({runtime:r})),await e(createTurnStartedEvent({sequence:n.sequence,turnId:a})),t.message!==void 0&&await e(createMessageReceivedEvent({message:t.message,sequence:n.sequence,turnId:a})),{sessionStarted:!0,sequence:n.sequence,stepIndex:0,turnId:a}}async function emitStepStarted(e,t,n){await e(createStepStartedEvent({sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId}),n)}async function emitStepAndTurnFailed(e,t,n){await e(createStepFailedEvent({...n,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),await e(createTurnFailedEvent({...n,sequence:t.sequence,turnId:t.turnId}))}async function emitFailedStep(e,t,n){await emitStepAndTurnFailed(e,t,n),await e(createSessionFailedEvent(n))}async function emitRecoverableFailedTurn(e,t,n){return await emitStepAndTurnFailed(e,t,n),await e(createSessionWaitingEvent(n.continuationToken)),{sessionStarted:t.sessionStarted,sequence:t.sequence+1,stepIndex:0,turnId:``}}function advanceStep(e){return{...e,stepIndex:e.stepIndex+1}}async function emitTurnEpilogue(e,t,n,r){return await e(createTurnCompletedEvent({sequence:t.sequence,turnId:t.turnId})),n===`conversation`?await e(createSessionWaitingEvent(r)):await e(createSessionCompletedEvent()),{sessionStarted:t.sessionStarted,sequence:t.sequence+1,stepIndex:0,turnId:``}}function normalizeAssistantStepFinishReason(e){switch(e){case`content-filter`:case`error`:case`length`:case`stop`:case`tool-calls`:return e;default:return`other`}}async function emitStreamContent(e,t,n,r){let i=createOrderedStreamEmitter(e),a=createProviderStreamActionBatch({emitFn:i.emit,state:t});try{return await consumeStreamContent(i.emit,t,interruptStreamOnFailure(n,i.failureSignal),a,r)}finally{try{await a.cancel()}finally{await i.closeAndDrain()}}}async function consumeStreamContent(i,o,s,c,l){let u=``,d=``,f=`stop`,p,m=new Set,h=new Set,g=new Set,_=new Set,v=new Set,y=new Set,b=[],x=[],flushCurrentMessage=async()=>{d.length!==0&&(await i(createMessageCompletedEvent({finishReason:`tool-calls`,message:d,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),d=``)},emitActionRequest=async e=>{h.has(e.callId)||(d.trim().length>0&&await flushCurrentMessage(),h.add(e.callId),await i(createActionsRequestedEvent({actions:[e],sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})))},collectProviderToolCall=async e=>{_.has(e.toolCallId)||(_.add(e.toolCallId),!h.has(e.toolCallId)&&(h.add(e.toolCallId),d.trim().length>0&&await flushCurrentMessage(),c.observe({callId:e.toolCallId,input:resolveToolCallInputObject(e.input,{callId:e.toolCallId,toolName:e.toolName}),kind:`tool-call`,toolName:e.toolName})))},emitActionResult=async t=>{g.has(t.callId)||(g.add(t.callId),await i(createActionResultEvent({result:t,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})))},emitToolCall=async e=>{if(isInvalidToolCall(e)){y.add(e.toolCallId);return}if(!(l===void 0||l.excludedActionToolNames.has(e.toolName)))try{await emitActionRequest(createRuntimeActionRequestFromToolCall({toolCall:e,tools:l.tools}))}catch(t){if(t instanceof TypeError){let n=createInvalidToolCallInputError({error:t,toolCall:e});y.add(e.toolCallId),d.trim().length>0&&await flushCurrentMessage(),await emitActionResult(createRuntimeToolResultFromToolError(n)),v.add(e.toolCallId),x.push(createToolResultMessagePartFromToolError(n));return}throw t}};for await(let e of s)if(p===void 0)switch(e.type){case`reasoning-delta`:await c.flush(),u+=e.text,await i(createReasoningAppendedEvent({reasoningDelta:e.text,reasoningSoFar:u,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId}));break;case`text-delta`:await c.flush(),u.trim().length>0&&(await i(createReasoningCompletedEvent({reasoning:u,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),u=``),d+=e.text,await i(createMessageAppendedEvent({messageDelta:e.text,messageSoFar:d,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId}));break;case`tool-call`:{let t=e;m.add(t.toolCallId),t.providerExecuted===!0?await collectProviderToolCall(t):(await c.flush(),await emitToolCall(t));break}case`tool-result`:{let t=e;if(t.preliminary===!0)break;if(t.providerExecuted===!0){await collectProviderToolCall({input:`input`in t?t.input:void 0,toolCallId:t.toolCallId,toolName:t.toolName}),await c.flush(),await emitActionResult(createRuntimeToolResultFromStepResult(t));break}if(m.has(e.toolCallId)){if(isInlineAuthorizationToolResult(t))break;h.has(e.toolCallId)&&(await emitActionResult(createRuntimeToolResultFromStepResult(t)),v.add(e.toolCallId));break}if(await c.flush(),await flushCurrentMessage(),isInlineAuthorizationToolResult(t)){v.add(e.toolCallId),b.push(t);break}await emitActionResult(createRuntimeToolResultFromStepResult(t)),v.add(e.toolCallId);break}case`tool-error`:{let t=e;t.providerExecuted===!0?(await collectProviderToolCall(t),await c.flush(),await emitActionResult(createRuntimeToolResultFromToolError(t))):h.has(t.toolCallId)&&(await emitActionResult(createRuntimeToolResultFromToolError(t)),v.add(t.toolCallId),x.push(createToolResultMessagePartFromToolError(t)));break}case`finish-step`:f=normalizeAssistantStepFinishReason(e.finishReason),await c.flush();break;case`error`:p=normalizeModelStreamError(e.error);break;case`abort`:throw new DOMException(e.reason??`The model stream was aborted.`,`AbortError`);default:break}if(await c.flush(),p!==void 0)throw p;return u.trim().length>0&&await i(createReasoningCompletedEvent({reasoning:u,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),f!==`tool-calls`&&hasEmptyDeliverySentinel(d)?await i(createMessageCompletedEvent({finishReason:f,message:null,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})):d.trim().length>0&&await i(createMessageCompletedEvent({finishReason:f,message:d,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),{emittedActionCallIds:h,handledInlineToolResultCallIds:v,invalidInputToolCallIds:y,inlineAuthorizationResults:b,trailingInlineToolResultParts:x}}export{advanceStep,emitFailedStep,emitRecoverableFailedTurn,emitStepStarted,emitStreamContent,emitTurnEpilogue,emitTurnPreamble,getHarnessEmissionState,isHarnessBetweenTurns,normalizeAssistantStepFinishReason,setHarnessEmissionState};
|
|
@@ -1,41 +1,22 @@
|
|
|
1
1
|
import type { JsonObject } from "#shared/json.js";
|
|
2
2
|
/**
|
|
3
|
-
* The
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* The most informative human-readable rejection a model-call error
|
|
4
|
+
* carries, extracted from the upstream response. Not a semantic-error
|
|
5
|
+
* classification: the message is arbitrary provider prose, so it carries
|
|
6
|
+
* no catalog id — `semanticErrorId` is reserved for registered rules.
|
|
6
7
|
*/
|
|
7
|
-
export
|
|
8
|
-
/**
|
|
9
|
-
* The summary `name` this module assigns to recognized gateway-auth
|
|
10
|
-
* failures, carried into failure-event details. Exported for the same
|
|
11
|
-
* consumers as {@link GATEWAY_AUTHENTICATION_ERROR_NAME}.
|
|
12
|
-
*/
|
|
13
|
-
export declare const GATEWAY_AUTH_FAILURE_SUMMARY_NAME = "AI Gateway authentication failed";
|
|
14
|
-
/**
|
|
15
|
-
* One human-readable summary of a known model-call configuration failure.
|
|
16
|
-
*
|
|
17
|
-
* Returned by {@link summarizeKnownModelCallConfigError} for terminal
|
|
18
|
-
* failures that point at a fixable setup mistake (missing API key,
|
|
19
|
-
* gateway auth failure). Surfaces actionable text in REPL output and in
|
|
20
|
-
* structured `step.failed` events without dumping the full SDK error
|
|
21
|
-
* inspection into user-facing logs.
|
|
22
|
-
*/
|
|
23
|
-
export interface ModelCallConfigErrorSummary {
|
|
8
|
+
export interface UpstreamRejectionSummary {
|
|
24
9
|
readonly name: string;
|
|
25
10
|
readonly message: string;
|
|
26
11
|
}
|
|
27
12
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Returns a concise summary for known model-call request failures that are not
|
|
35
|
-
* configuration errors. These failures happen before the agent can produce a
|
|
36
|
-
* response, so the user-facing message should avoid implying a bad tool call.
|
|
13
|
+
* Extracts the most informative upstream rejection message from a
|
|
14
|
+
* model-call error that the semantic-error catalog did not recognize.
|
|
15
|
+
* These failures happen before the agent can produce a response, so the
|
|
16
|
+
* user-facing message should avoid implying a bad tool call. Returns
|
|
17
|
+
* `null` when the error carries nothing better than its raw message.
|
|
37
18
|
*/
|
|
38
|
-
export declare function
|
|
19
|
+
export declare function extractUpstreamRejectionMessage(error: unknown): UpstreamRejectionSummary | null;
|
|
39
20
|
/**
|
|
40
21
|
* Returns the distinct upstream tool types referenced by any
|
|
41
22
|
* "tool type 'X' is not supported" rejection in an AI Gateway error's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isObject}from"#shared/guards.js";import{toError}from"#shared/errors.js";import{isTurnCancellation}from"#harness/turn-cancellation.js";const GATEWAY_AUTHENTICATION_ERROR_NAME=`GatewayAuthenticationError`,GATEWAY_AUTH_FAILURE_SUMMARY_NAME=`AI Gateway authentication failed`,UNSUPPORTED_TOOL_TYPE_REGEX=/tool type ['"]([\w.-]+)['"] is not supported/i;function summarizeKnownModelCallConfigError(e){let t=readErrorName(e),n=readErrorMessage(e);return t===`GatewayAuthenticationError`||/AI Gateway authentication/i.test(n)?/Invalid API key/i.test(n)?{name:GATEWAY_AUTH_FAILURE_SUMMARY_NAME,message:"AI Gateway rejected the provided API key. Update or unset `AI_GATEWAY_API_KEY` (check your shell profile if you did not set it for this project) — manage keys at https://vercel.com/dashboard/ai/api-keys. Unsetting it falls back to OIDC via `eve link`."}:/Invalid OIDC token/i.test(n)?{name:GATEWAY_AUTH_FAILURE_SUMMARY_NAME,message:"AI Gateway rejected the OIDC token. Run `eve link` to refresh `VERCEL_OIDC_TOKEN` in `.env.local`, or set `AI_GATEWAY_API_KEY` — create a key at https://vercel.com/dashboard/ai/api-keys."}:{name:GATEWAY_AUTH_FAILURE_SUMMARY_NAME,message:"AI Gateway received no credentials. Run `eve link` to populate `VERCEL_OIDC_TOKEN`, or set `AI_GATEWAY_API_KEY` — create a key at https://vercel.com/dashboard/ai/api-keys."}:t===`LoadAPIKeyError`||/API key is missing/i.test(n)?{name:`Model provider API key missing`,message:"The model provider could not load an API key. Export the provider's API key environment variable (for example `AI_GATEWAY_API_KEY` or `OPENAI_API_KEY`) and try again."}:null}function summarizeKnownModelCallRequestError(e){if(e instanceof EmptyModelResponseError)return{name:`Empty model response`,message:e.message};let t=readModelCallErrorSignals(e);if(isTransientHttpStatus(t.statusCode??t.upstreamStatusCode))return null;let n=t.apiErrorMessage;if(n!==void 0)return{name:isGatewayErrorSignal(t)?`AI Gateway model request rejected`:`Model provider API error`,message:n};if(t.statusCode===400&&isGatewayErrorSignal(t))return{name:`AI Gateway model request rejected`,message:`AI Gateway rejected the model request before the agent produced a response.`};let r=formatApiCallErrorFallback(t);return r===void 0?null:{name:isGatewayErrorSignal(t)?`AI Gateway model request rejected`:`Model provider API error`,message:r}}function isTransientHttpStatus(e){return e===408||e===429||e!==void 0&&e>=500}function extractUnsupportedProviderToolTypes(e){let t=new Set;for(let n of walkCauseChain(e)){collectUnsupportedToolTypesFromValue(readObjectField(n,`data`),t);let e=readStringField(n,`responseBody`);if(e!==void 0)try{collectUnsupportedToolTypesFromValue(JSON.parse(e),t)}catch{let n=UNSUPPORTED_TOOL_TYPE_REGEX.exec(e);n?.[1]!==void 0&&t.add(n[1])}}return[...t]}function collectUnsupportedToolTypesFromValue(t,n){if(t!=null){if(typeof t==`string`){let e=UNSUPPORTED_TOOL_TYPE_REGEX.exec(t);e?.[1]!==void 0&&n.add(e[1]);return}if(Array.isArray(t)){for(let e of t)collectUnsupportedToolTypesFromValue(e,n);return}if(isObject(t))for(let e of Object.values(t))collectUnsupportedToolTypesFromValue(e,n)}}function extractModelCallErrorDetails(e){let t=readModelCallErrorSignals(e),n={};return appendJsonField(n,`apiErrorMessage`,t.apiErrorMessage),appendJsonField(n,`gatewayName`,t.gatewayName),appendJsonField(n,`gatewayType`,t.gatewayType),appendJsonField(n,`statusCode`,t.statusCode),appendJsonField(n,`generationId`,t.generationId),appendJsonField(n,`upstreamStatusCode`,t.upstreamStatusCode),appendJsonField(n,`upstreamType`,t.upstreamType),appendJsonField(n,`upstreamMessage`,t.upstreamMessage),appendJsonField(n,`responseBodySnippet`,t.responseBodySnippet),n}function readErrorName(t){if(t instanceof Error||isObject(t)&&typeof t.name==`string`)return t.name}function readErrorMessage(t){return t instanceof Error||isObject(t)&&typeof t.message==`string`?t.message:``}var EmptyModelResponseError=class extends Error{constructor(e){super(`The model did not return a response. Please try again.`,e),this.name=`EmptyModelResponseError`}};function normalizeModelStreamError(e){let n=toError(e);return n===e||Object.defineProperty(n,"cause",{configurable:!0,value:e}),n}function isNoOutputGeneratedError(e){for(let t of walkCauseChain(e))if(readErrorName(t)===`AI_NoOutputGeneratedError`)return!0;return!1}function classifyModelCallError(e){if(isTurnCancellation(e))return`terminal`;if(e instanceof EmptyModelResponseError)return`recoverable`;if(hasRetryableFlag(e))return`retry`;if(summarizeKnownModelCallConfigError(e)!==null)return`terminal`;let t=readModelCallErrorSignals(e);if(isRetryableGatewayType(t.gatewayType)||isRetryableGatewayType(t.upstreamType))return`retry`;if(isTerminalGatewayType(t.gatewayType)||isTerminalGatewayType(t.upstreamType)||t.gatewayName===`GatewayInvalidRequestError`)return`terminal`;let r=t.statusCode;if(r!==void 0){if(r===408||r===409||r===429||r>=500)return`retry`;if(isAmbiguousGatewayInternalBadRequest(t))return`recoverable`;if(r>=400&&r<500)return`terminal`}return isLikelyNetworkError(e)?`retry`:`recoverable`}function hasRetryableFlag(t){for(let n of walkCauseChain(t))if(isObject(n)&&n.isRetryable===!0)return!0;return!1}function isLikelyNetworkError(e){if(!(e instanceof Error))return!1;let t=e.message.toLowerCase();return t.includes(`econnreset`)||t.includes(`etimedout`)||t.includes(`eai_again`)||t.includes(`socket hang up`)||t.includes(`network`)||t.includes(`fetch failed`)?!0:e.cause!==void 0&&e.cause!==e?isLikelyNetworkError(e.cause):!1}function readModelCallErrorSignals(e){let t=findGatewayError(e),n=findUpstreamApiCallError(e),r=readStringField(n,`responseBody`),i=readGatewayErrorBody(n);return{apiCallError:n!==void 0,apiErrorMessage:i?.apiErrorMessage??firstInformativeApiMessage([readErrorMessage(n)]),gatewayName:readErrorName(t),gatewayType:readStringField(t,`type`),generationId:readStringField(t,`generationId`)??i?.generationId,responseBodySnippet:r===void 0?void 0:truncateSnippet(r,1e3),statusCode:readStatusCode(t)??readStatusCode(n)??findStatusCode(e),upstreamMessage:i?.message,upstreamStatusCode:readStatusCode(n),upstreamType:i?.type}}function findGatewayError(e){for(let t of walkCauseChain(e)){let e=readErrorName(t),n=readStringField(t,`type`);if(e?.startsWith(`Gateway`)||n?.endsWith(`_error`)||n===`rate_limit_exceeded`)return t}}function findUpstreamApiCallError(e){for(let t of walkCauseChain(e))if(readErrorName(t)===`AI_APICallError`||readStringField(t,`responseBody`)!==void 0||readObjectField(t,`data`)!==void 0||readObjectField(t,`requestBodyValues`)!==void 0)return t}function readGatewayErrorBody(e){let t=readGatewayErrorBodyFromValue(readObjectField(e,`data`));if(t!==void 0)return t;let n=readStringField(e,`responseBody`);if(n!==void 0)try{return readGatewayErrorBodyFromValue(JSON.parse(n))}catch{return}}function readGatewayErrorBodyFromValue(t){if(!isObject(t))return;let n=readObjectField(t,`error`),r=readStringField(t,`generationId`),i=readStringField(n,`message`)??readStringField(t,`message`),a=readStringField(n,`type`)??readStringField(t,`type`),o=firstInformativeApiMessage([i,...readNestedApiErrorMessages(n),...readNestedApiErrorMessages(t)]);return i===void 0&&a===void 0&&r===void 0&&o===void 0?void 0:{apiErrorMessage:o,generationId:r,message:i,type:a}}function readStatusCode(t){if(isObject(t))return typeof t.statusCode==`number`?t.statusCode:void 0}function findStatusCode(e){for(let t of walkCauseChain(e)){let e=readStatusCode(t);if(e!==void 0)return e}}function readStringField(t,n){if(!isObject(t))return;let r=t[n];return typeof r==`string`&&r.length>0?r:void 0}function readObjectField(t,n){if(!isObject(t))return;let r=t[n];return isObject(r)?r:void 0}function readNestedApiErrorMessages(t){if(!isObject(t))return[];let n=[];return appendString(n,readStringField(t,`message`)),appendString(n,readStringField(t,`error_description`)),appendNestedApiFieldMessages(n,t.error),appendNestedApiFieldMessages(n,t.code),n}function appendNestedApiFieldMessages(t,n){if(typeof n==`string`){appendString(t,n);return}isObject(n)&&(appendString(t,readStringField(n,`message`)),appendString(t,readStringField(n,`error`)),appendString(t,readStringField(n,`description`)),appendString(t,readStringField(n,`error_description`)),appendNestedApiFieldMessages(t,n.error))}function appendString(e,t){t!==void 0&&e.push(t)}function firstInformativeApiMessage(e){for(let t of e)if(t!==void 0&&isInformativeApiMessage(t))return truncateSnippet(t,800)}function isInformativeApiMessage(e){let t=e.trim();return t.length>0&&t!==`[object Object]`&&t!==`AI_APICallError`&&t!==`Bad Request`&&t!==`Internal Server Error`}function formatApiCallErrorFallback(e){if(!e.apiCallError)return;let t=e.statusCode??e.upstreamStatusCode,n=e.responseBodySnippet,r=e.upstreamType!==void 0&&isInformativeApiMessage(e.upstreamType)?e.upstreamType:void 0;if(t===void 0&&n===void 0&&r===void 0)return;let i=[t===void 0?void 0:`HTTP ${t}`,r].filter(e=>e!==void 0).join(`, `),a=i.length===0?`Model provider API request failed`:`Model provider API request failed (${i})`;return n===void 0?`${a}.`:`${a}: ${n}`}function isRetryableGatewayType(e){return e===`overloaded_error`||e===`rate_limit_exceeded`||e===`timeout_error`}function isTerminalGatewayType(e){return e===`authentication_error`||e===`invalid_request_error`||e===`model_not_found`}function isGatewayErrorSignal(e){return e.gatewayName!==void 0||e.gatewayType!==void 0}function isAmbiguousGatewayInternalBadRequest(e){return e.statusCode===400&&(e.gatewayName===`GatewayInternalServerError`||e.gatewayType===`internal_server_error`)&&(e.upstreamType===void 0||e.upstreamType===`internal_server_error`)}function*walkCauseChain(t){let n=new Set,r=t;for(;isObject(r)&&!n.has(r);)n.add(r),yield r,r=r.cause}function appendJsonField(e,t,n){if(typeof n==`string`&&n.length>0){e[t]=n;return}typeof n==`number`&&Number.isFinite(n)&&(e[t]=n)}function truncateSnippet(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}export{EmptyModelResponseError,GATEWAY_AUTHENTICATION_ERROR_NAME,GATEWAY_AUTH_FAILURE_SUMMARY_NAME,classifyModelCallError,extractModelCallErrorDetails,extractUnsupportedProviderToolTypes,isNoOutputGeneratedError,normalizeModelStreamError,summarizeKnownModelCallConfigError,summarizeKnownModelCallRequestError};
|
|
1
|
+
import{isObject}from"#shared/guards.js";import{toError,walkCauseChain}from"#shared/errors.js";import{summarizeKnownError}from"#harness/semantic-errors/index.js";import{isTurnCancellation}from"#harness/turn-cancellation.js";const UNSUPPORTED_TOOL_TYPE_REGEX=/tool type ['"]([\w.-]+)['"] is not supported/i;function extractUpstreamRejectionMessage(e){let t=readModelCallErrorSignals(e);if(isTransientHttpStatus(t.statusCode??t.upstreamStatusCode))return null;let n=t.apiErrorMessage;if(n!==void 0)return{name:upstreamRejectionName(t),message:n};if(t.statusCode===400&&isGatewayErrorSignal(t))return{name:`AI Gateway model request rejected`,message:`AI Gateway rejected the model request before the agent produced a response.`};let r=formatApiCallErrorFallback(t);return r===void 0?null:{name:upstreamRejectionName(t),message:r}}function upstreamRejectionName(e){return isGatewayErrorSignal(e)?`AI Gateway model request rejected`:`Model provider API error`}function isTransientHttpStatus(e){return e===408||e===429||e!==void 0&&e>=500}function extractUnsupportedProviderToolTypes(e){let t=new Set;for(let r of walkCauseChain(e)){collectUnsupportedToolTypesFromValue(readObjectField(r,`data`),t);let e=readStringField(r,`responseBody`);if(e!==void 0)try{collectUnsupportedToolTypesFromValue(JSON.parse(e),t)}catch{let n=UNSUPPORTED_TOOL_TYPE_REGEX.exec(e);n?.[1]!==void 0&&t.add(n[1])}}return[...t]}function collectUnsupportedToolTypesFromValue(t,n){if(t!=null){if(typeof t==`string`){let e=UNSUPPORTED_TOOL_TYPE_REGEX.exec(t);e?.[1]!==void 0&&n.add(e[1]);return}if(Array.isArray(t)){for(let e of t)collectUnsupportedToolTypesFromValue(e,n);return}if(isObject(t))for(let e of Object.values(t))collectUnsupportedToolTypesFromValue(e,n)}}function extractModelCallErrorDetails(e){let t=readModelCallErrorSignals(e),n={};return appendJsonField(n,`apiErrorMessage`,t.apiErrorMessage),appendJsonField(n,`gatewayName`,t.gatewayName),appendJsonField(n,`gatewayType`,t.gatewayType),appendJsonField(n,`statusCode`,t.statusCode),appendJsonField(n,`generationId`,t.generationId),appendJsonField(n,`upstreamStatusCode`,t.upstreamStatusCode),appendJsonField(n,`upstreamType`,t.upstreamType),appendJsonField(n,`upstreamMessage`,t.upstreamMessage),appendJsonField(n,`responseBodySnippet`,t.responseBodySnippet),n}function readErrorName(t){if(t instanceof Error||isObject(t)&&typeof t.name==`string`)return t.name}function readErrorMessage(t){return t instanceof Error||isObject(t)&&typeof t.message==`string`?t.message:``}var EmptyModelResponseError=class extends Error{constructor(e){super(`The model did not return a response. Please try again.`,e),this.name=`EmptyModelResponseError`}};function normalizeModelStreamError(e){let n=toError(e);return n===e||Object.defineProperty(n,"cause",{configurable:!0,value:e}),n}function isNoOutputGeneratedError(e){for(let t of walkCauseChain(e))if(readErrorName(t)===`AI_NoOutputGeneratedError`)return!0;return!1}function classifyModelCallError(e){if(isTurnCancellation(e))return`terminal`;if(e instanceof EmptyModelResponseError)return`recoverable`;if(hasRetryableFlag(e))return`retry`;let t=summarizeKnownError(e);if(t?.tags.includes(`config`)===!0)return`terminal`;if(t?.tags.includes(`transient`)===!0)return`retry`;let n=readModelCallErrorSignals(e);if(isRetryableGatewayType(n.upstreamType))return`retry`;if(isTerminalGatewayType(n.upstreamType)||n.gatewayType===`invalid_request_error`||n.gatewayName===`GatewayInvalidRequestError`)return`terminal`;let a=n.statusCode;if(a!==void 0){if(a===408||a===409||a===429||a>=500)return`retry`;if(isAmbiguousGatewayInternalBadRequest(n))return`recoverable`;if(a>=400&&a<500)return`terminal`}return`recoverable`}function hasRetryableFlag(t){for(let r of walkCauseChain(t))if(isObject(r)&&r.isRetryable===!0)return!0;return!1}function readModelCallErrorSignals(e){let t=findGatewayError(e),n=findUpstreamApiCallError(e),r=readStringField(n,`responseBody`),i=readGatewayErrorBody(n);return{apiCallError:n!==void 0,apiErrorMessage:i?.apiErrorMessage??firstInformativeApiMessage([readErrorMessage(n)]),gatewayName:readErrorName(t),gatewayType:readStringField(t,`type`),generationId:readStringField(t,`generationId`)??i?.generationId,responseBodySnippet:r===void 0?void 0:truncateSnippet(r,1e3),statusCode:readStatusCode(t)??readStatusCode(n)??findStatusCode(e),upstreamMessage:i?.message,upstreamStatusCode:readStatusCode(n),upstreamType:i?.type}}function findGatewayError(e){for(let t of walkCauseChain(e)){let e=readErrorName(t),n=readStringField(t,`type`);if(e?.startsWith(`Gateway`)||n?.endsWith(`_error`)||n===`rate_limit_exceeded`)return t}}function findUpstreamApiCallError(e){for(let t of walkCauseChain(e))if(readErrorName(t)===`AI_APICallError`||readStringField(t,`responseBody`)!==void 0||readObjectField(t,`data`)!==void 0||readObjectField(t,`requestBodyValues`)!==void 0)return t}function readGatewayErrorBody(e){let t=readGatewayErrorBodyFromValue(readObjectField(e,`data`));if(t!==void 0)return t;let n=readStringField(e,`responseBody`);if(n!==void 0)try{return readGatewayErrorBodyFromValue(JSON.parse(n))}catch{return}}function readGatewayErrorBodyFromValue(t){if(!isObject(t))return;let n=readObjectField(t,`error`),r=readStringField(t,`generationId`),i=readStringField(n,`message`)??readStringField(t,`message`),a=readStringField(n,`type`)??readStringField(t,`type`),o=firstInformativeApiMessage([i,...readNestedApiErrorMessages(n),...readNestedApiErrorMessages(t)]);return i===void 0&&a===void 0&&r===void 0&&o===void 0?void 0:{apiErrorMessage:o,generationId:r,message:i,type:a}}function readStatusCode(t){if(isObject(t))return typeof t.statusCode==`number`?t.statusCode:void 0}function findStatusCode(e){for(let t of walkCauseChain(e)){let e=readStatusCode(t);if(e!==void 0)return e}}function readStringField(t,n){if(!isObject(t))return;let r=t[n];return typeof r==`string`&&r.length>0?r:void 0}function readObjectField(t,n){if(!isObject(t))return;let r=t[n];return isObject(r)?r:void 0}function readNestedApiErrorMessages(t){if(!isObject(t))return[];let n=[];return appendString(n,readStringField(t,`message`)),appendString(n,readStringField(t,`error_description`)),appendNestedApiFieldMessages(n,t.error),appendNestedApiFieldMessages(n,t.code),n}function appendNestedApiFieldMessages(t,n){if(typeof n==`string`){appendString(t,n);return}isObject(n)&&(appendString(t,readStringField(n,`message`)),appendString(t,readStringField(n,`error`)),appendString(t,readStringField(n,`description`)),appendString(t,readStringField(n,`error_description`)),appendNestedApiFieldMessages(t,n.error))}function appendString(e,t){t!==void 0&&e.push(t)}function firstInformativeApiMessage(e){for(let t of e)if(t!==void 0&&isInformativeApiMessage(t))return truncateSnippet(t,800)}function isInformativeApiMessage(e){let t=e.trim();return t.length>0&&t!==`[object Object]`&&t!==`AI_APICallError`&&t!==`Bad Request`&&t!==`Internal Server Error`}function formatApiCallErrorFallback(e){if(!e.apiCallError)return;let t=e.statusCode??e.upstreamStatusCode,n=e.responseBodySnippet,r=e.upstreamType!==void 0&&isInformativeApiMessage(e.upstreamType)?e.upstreamType:void 0;if(t===void 0&&n===void 0&&r===void 0)return;let i=[t===void 0?void 0:`HTTP ${t}`,r].filter(e=>e!==void 0).join(`, `),a=i.length===0?`Model provider API request failed`:`Model provider API request failed (${i})`;return n===void 0?`${a}.`:`${a}: ${n}`}function isRetryableGatewayType(e){return e===`overloaded_error`||e===`rate_limit_exceeded`||e===`timeout_error`}function isTerminalGatewayType(e){return e===`authentication_error`||e===`invalid_request_error`||e===`model_not_found`}function isGatewayErrorSignal(e){return e.gatewayName!==void 0||e.gatewayType!==void 0}function isAmbiguousGatewayInternalBadRequest(e){return e.statusCode===400&&(e.gatewayName===`GatewayInternalServerError`||e.gatewayType===`internal_server_error`)&&(e.upstreamType===void 0||e.upstreamType===`internal_server_error`)}function appendJsonField(e,t,n){if(typeof n==`string`&&n.length>0){e[t]=n;return}typeof n==`number`&&Number.isFinite(n)&&(e[t]=n)}function truncateSnippet(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}export{EmptyModelResponseError,classifyModelCallError,extractModelCallErrorDetails,extractUnsupportedProviderToolTypes,extractUpstreamRejectionMessage,isNoOutputGeneratedError,normalizeModelStreamError};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type SemanticErrorSummary } from "./rule.js";
|
|
2
|
+
export type { ErrorLink, ErrorSignals } from "./signals.js";
|
|
3
|
+
export type { LinkPredicate, SemanticErrorRule, SemanticErrorSummary } from "./rule.js";
|
|
4
|
+
/**
|
|
5
|
+
* Projects any thrown error into its cataloged semantic summary, or
|
|
6
|
+
* `null` when no rule matches — callers then fall back to the raw
|
|
7
|
+
* message plus the full diagnostic dump routed to the log.
|
|
8
|
+
*/
|
|
9
|
+
export declare function summarizeKnownError(error: unknown): SemanticErrorSummary | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{evaluateSemanticErrorRules}from"./rule.js";import{extractErrorSignals}from"./signals.js";import{GATEWAY_RULES}from"./rules/gateway.js";import{MODEL_PROVIDER_RULES}from"./rules/model-provider.js";import{SANDBOX_RULES}from"./rules/sandbox.js";import{SYSTEM_RULES}from"./rules/system.js";import{WORKFLOW_RULES}from"./rules/workflow.js";const CATALOG=[...GATEWAY_RULES,...MODEL_PROVIDER_RULES,...WORKFLOW_RULES,...SANDBOX_RULES,...SYSTEM_RULES];function summarizeKnownError(e){return evaluateSemanticErrorRules(CATALOG,extractErrorSignals(e))}export{summarizeKnownError};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { ErrorLink, ErrorSignals } from "./signals.js";
|
|
2
|
+
/**
|
|
3
|
+
* Classification tags a rule carries in addition to its domain:
|
|
4
|
+
*
|
|
5
|
+
* - `config` — the failure points at a fixable setup mistake (missing or
|
|
6
|
+
* invalid credentials, unknown model id). The model-call classifier
|
|
7
|
+
* treats a matched `config` rule as terminal.
|
|
8
|
+
* - `transient` — the failure is expected to clear on retry.
|
|
9
|
+
*/
|
|
10
|
+
export type SemanticErrorTag = "gateway" | "model-provider" | "workflow" | "sandbox" | "system" | "config" | "transient";
|
|
11
|
+
/** A predicate over one extracted cause-chain link. */
|
|
12
|
+
export type LinkPredicate = (link: ErrorLink) => boolean;
|
|
13
|
+
/**
|
|
14
|
+
* One catalog rule, in the linter shape: a stable id, a headline, a
|
|
15
|
+
* declarative predicate over extracted {@link ErrorLink} facts, and the
|
|
16
|
+
* remediation copy. Rules are pure and independent; the catalog is an
|
|
17
|
+
* ordered list where the first match wins, so put specific rules before
|
|
18
|
+
* general ones.
|
|
19
|
+
*/
|
|
20
|
+
export interface SemanticErrorRule {
|
|
21
|
+
/** Stable kebab-case catalog identifier, greppable across logs and code. */
|
|
22
|
+
readonly id: string;
|
|
23
|
+
/** Short human-readable failure title used as the display headline. */
|
|
24
|
+
readonly name: string;
|
|
25
|
+
readonly tags: readonly SemanticErrorTag[];
|
|
26
|
+
/** Matches when ANY link on the cause chain satisfies the predicate. */
|
|
27
|
+
readonly when: LinkPredicate;
|
|
28
|
+
/**
|
|
29
|
+
* What happened — one factual sentence, or a projection of the matched
|
|
30
|
+
* link (e.g. pass-through for eve-authored error messages).
|
|
31
|
+
*/
|
|
32
|
+
readonly message: string | ((link: ErrorLink) => string);
|
|
33
|
+
/**
|
|
34
|
+
* What to do about it. Structured separately from `message` so render
|
|
35
|
+
* surfaces can style, replace, or suppress the remediation
|
|
36
|
+
* independently of the description (the dev TUI swaps in local
|
|
37
|
+
* `/model` hints; a channel adapter may drop CLI advice entirely).
|
|
38
|
+
*/
|
|
39
|
+
readonly hint?: string | ((link: ErrorLink) => string | undefined);
|
|
40
|
+
}
|
|
41
|
+
/** A matched rule projected into a displayable summary. */
|
|
42
|
+
export interface SemanticErrorSummary {
|
|
43
|
+
readonly id: string;
|
|
44
|
+
readonly name: string;
|
|
45
|
+
/**
|
|
46
|
+
* The matched rule's tags, carried so consumers with a recovery policy
|
|
47
|
+
* (the model-call classifier) can read the catalog's judgment —
|
|
48
|
+
* `config` is terminal, `transient` retries — without a second registry
|
|
49
|
+
* of the same knowledge.
|
|
50
|
+
*/
|
|
51
|
+
readonly tags: readonly SemanticErrorTag[];
|
|
52
|
+
/** What happened. */
|
|
53
|
+
readonly message: string;
|
|
54
|
+
/** What to do about it, when the rule carries remediation. */
|
|
55
|
+
readonly hint?: string;
|
|
56
|
+
}
|
|
57
|
+
/** Evaluates an ordered rule list against extracted signals; first match wins. */
|
|
58
|
+
export declare function evaluateSemanticErrorRules(rules: readonly SemanticErrorRule[], signals: ErrorSignals): SemanticErrorSummary | null;
|
|
59
|
+
/** Matches when the link's `name` equals any of the given class names. */
|
|
60
|
+
export declare function nameIs(...names: readonly string[]): LinkPredicate;
|
|
61
|
+
/** Matches when the link's `code` equals any of the given codes. */
|
|
62
|
+
export declare function codeIs(...codes: readonly string[]): LinkPredicate;
|
|
63
|
+
/** Matches when the link's gateway body `type` equals any of the given types. */
|
|
64
|
+
export declare function typeIs(...types: readonly string[]): LinkPredicate;
|
|
65
|
+
/**
|
|
66
|
+
* Matches when the link's message equals one of the given strings exactly
|
|
67
|
+
* (after trimming). Exact equality, not containment: a user error that
|
|
68
|
+
* merely *mentions* a known failure string must not be reclassified.
|
|
69
|
+
*/
|
|
70
|
+
export declare function messageIs(...messages: readonly string[]): LinkPredicate;
|
|
71
|
+
/** Matches when the link's message matches the pattern. */
|
|
72
|
+
export declare function messageMatches(pattern: RegExp): LinkPredicate;
|
|
73
|
+
/** Matches when every given predicate matches the same link. */
|
|
74
|
+
export declare function allOf(...predicates: readonly LinkPredicate[]): LinkPredicate;
|
|
75
|
+
/** Matches when any given predicate matches the link. */
|
|
76
|
+
export declare function anyOf(...predicates: readonly LinkPredicate[]): LinkPredicate;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function evaluateSemanticErrorRules(e,t){for(let n of e){let e=t.chain.find(e=>n.when(e));if(e===void 0)continue;let r={id:n.id,name:n.name,tags:n.tags,message:typeof n.message==`string`?n.message:n.message(e)},i=typeof n.hint==`function`?n.hint(e):n.hint;return i!==void 0&&i.length>0&&(r.hint=i),r}return null}function nameIs(...e){return t=>t.name!==void 0&&e.includes(t.name)}function codeIs(...e){return t=>t.code!==void 0&&e.includes(t.code)}function typeIs(...e){return t=>t.type!==void 0&&e.includes(t.type)}function messageIs(...e){return t=>e.includes(t.message.trim())}function messageMatches(e){return t=>e.test(t.message)}function allOf(...e){return t=>e.every(e=>e(t))}function anyOf(...e){return t=>e.some(e=>e(t))}export{allOf,anyOf,codeIs,evaluateSemanticErrorRules,messageIs,messageMatches,nameIs,typeIs};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type SemanticErrorRule } from "../rule.js";
|
|
2
|
+
/**
|
|
3
|
+
* Error class names and body `type` discriminators are verified against
|
|
4
|
+
* the vendored `@ai-sdk/gateway` source: the `Gateway*Error` classes and
|
|
5
|
+
* the body types `authentication_error`, `invalid_request_error`,
|
|
6
|
+
* `model_not_found`, `rate_limit_exceeded`, `timeout_error`,
|
|
7
|
+
* `internal_server_error` all appear there verbatim. `overloaded_error`
|
|
8
|
+
* is not gateway vocabulary — it is the Anthropic upstream error type the
|
|
9
|
+
* gateway relays on provider overload.
|
|
10
|
+
*/
|
|
11
|
+
export declare const GATEWAY_RULES: readonly SemanticErrorRule[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{allOf,anyOf,messageMatches,nameIs,typeIs}from"../rule.js";const GATEWAY_AUTH_FAILURE_SUMMARY_NAME=`AI Gateway authentication failed`,gatewayAuthenticationFailure=anyOf(nameIs(`GatewayAuthenticationError`),typeIs(`authentication_error`),messageMatches(/AI Gateway authentication/i)),GATEWAY_RULES=[{id:`gateway-auth-invalid-api-key`,name:GATEWAY_AUTH_FAILURE_SUMMARY_NAME,tags:[`gateway`,`config`],when:allOf(gatewayAuthenticationFailure,messageMatches(/Invalid API key/i)),message:`AI Gateway rejected the provided API key.`,hint:"Update or unset `AI_GATEWAY_API_KEY` (check your shell profile if you did not set it for this project) — manage keys at https://vercel.com/dashboard/ai/api-keys. Unsetting it falls back to OIDC via `eve link`."},{id:`gateway-auth-invalid-oidc-token`,name:GATEWAY_AUTH_FAILURE_SUMMARY_NAME,tags:[`gateway`,`config`],when:allOf(gatewayAuthenticationFailure,messageMatches(/Invalid OIDC token/i)),message:`AI Gateway rejected the OIDC token.`,hint:"Run `eve link` to refresh `VERCEL_OIDC_TOKEN` in `.env.local`, or set `AI_GATEWAY_API_KEY` — create a key at https://vercel.com/dashboard/ai/api-keys."},{id:`gateway-auth-missing-credentials`,name:GATEWAY_AUTH_FAILURE_SUMMARY_NAME,tags:[`gateway`,`config`],when:gatewayAuthenticationFailure,message:`AI Gateway received no credentials.`,hint:"Run `eve link` to populate `VERCEL_OIDC_TOKEN`, or set `AI_GATEWAY_API_KEY` — create a key at https://vercel.com/dashboard/ai/api-keys."},{id:`model-not-found`,name:`Model not found`,tags:[`gateway`,`config`],when:anyOf(nameIs(`GatewayModelNotFoundError`,`AI_NoSuchModelError`),typeIs(`model_not_found`)),message:`The requested model is not available.`,hint:"Check the model id in `agent.ts` (`model:`) or switch models with `/model` in `eve dev` — browse available models at https://vercel.com/ai-gateway/models."},{id:`gateway-rate-limited`,name:`AI Gateway rate limit exceeded`,tags:[`gateway`,`transient`],when:anyOf(nameIs(`GatewayRateLimitError`),typeIs(`rate_limit_exceeded`)),message:`AI Gateway rate-limited the request.`,hint:`Retries are automatic; if it persists, reduce request volume or review your plan limits at https://vercel.com/ai-gateway.`},{id:`gateway-upstream-unavailable`,name:`Model provider unavailable`,tags:[`gateway`,`transient`],when:anyOf(nameIs(`GatewayTimeoutError`),typeIs(`timeout_error`,`overloaded_error`)),message:`The model provider is overloaded or timing out upstream of AI Gateway.`,hint:"This is transient — retry shortly, or switch models with `/model` in `eve dev`."}];export{GATEWAY_RULES};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type SemanticErrorRule } from "../rule.js";
|
|
2
|
+
/**
|
|
3
|
+
* Discriminators verified against the vendored `@ai-sdk/provider` /
|
|
4
|
+
* `@ai-sdk/provider-utils` source: the error classes set
|
|
5
|
+
* `name = "AI_LoadAPIKeyError"` / `"AI_UnsupportedFunctionalityError"`,
|
|
6
|
+
* and `loadApiKey` builds its message as
|
|
7
|
+
* `"<provider> API key is missing. Pass it using the …"`. The bare
|
|
8
|
+
* `LoadAPIKeyError` spelling is defensive, for provider adapters that
|
|
9
|
+
* rethrow under the unprefixed class name.
|
|
10
|
+
*/
|
|
11
|
+
export declare const MODEL_PROVIDER_RULES: readonly SemanticErrorRule[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{anyOf,messageMatches,nameIs}from"../rule.js";const MODEL_PROVIDER_RULES=[{id:`model-provider-api-key-missing`,name:`Model provider API key missing`,tags:[`model-provider`,`config`],when:anyOf(nameIs(`LoadAPIKeyError`,`AI_LoadAPIKeyError`),messageMatches(/API key is missing/i)),message:`The model provider could not load an API key.`,hint:"Export the provider's API key environment variable (for example `AI_GATEWAY_API_KEY` or `OPENAI_API_KEY`) and try again."},{id:`empty-model-response`,name:`Empty model response`,tags:[`model-provider`,`transient`],when:nameIs(`EmptyModelResponseError`),message:e=>e.message},{id:`model-capability-unsupported`,name:`Model capability not supported`,tags:[`model-provider`],when:nameIs(`AI_UnsupportedFunctionalityError`),message:`The selected model does not support a capability this agent uses (a tool type, modality, or feature).`,hint:`Remove the unsupported tool or switch to a model that supports it.`}];export{MODEL_PROVIDER_RULES};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type SemanticErrorRule } from "../rule.js";
|
|
2
|
+
/**
|
|
3
|
+
* Error class names come from eve's own sandbox backends —
|
|
4
|
+
* `DockerUnavailableError` / `DockerDaemonUnavailableError` in
|
|
5
|
+
* `execution/sandbox/bindings/docker-cli.ts` and
|
|
6
|
+
* `MicrosandboxDiagnosticError` in
|
|
7
|
+
* `execution/sandbox/bindings/microsandbox-create.ts` — each of which
|
|
8
|
+
* assigns `this.name` explicitly. Those classes already author actionable
|
|
9
|
+
* remediation messages at the failure site — where the missing binary or
|
|
10
|
+
* unreachable daemon is actually known — so these rules contribute the
|
|
11
|
+
* stable catalog identity and pass the message through. Matching is by
|
|
12
|
+
* name string rather than `instanceof` because the harness must not
|
|
13
|
+
* import from `execution/` and the classes survive structured clone as
|
|
14
|
+
* plain shapes.
|
|
15
|
+
*/
|
|
16
|
+
export declare const SANDBOX_RULES: readonly SemanticErrorRule[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{nameIs}from"../rule.js";const passThroughMessage=e=>e.message,passThroughHint=e=>e.hint,SANDBOX_RULES=[{id:`sandbox-docker-cli-missing`,name:`Docker CLI not found`,tags:[`sandbox`,`config`],when:nameIs(`DockerUnavailableError`),message:passThroughMessage,hint:passThroughHint},{id:`sandbox-docker-daemon-unreachable`,name:`Docker daemon unreachable`,tags:[`sandbox`,`config`],when:nameIs(`DockerDaemonUnavailableError`),message:passThroughMessage,hint:passThroughHint},{id:`sandbox-provisioning-failed`,name:`Sandbox provisioning failed`,tags:[`sandbox`],when:nameIs(`MicrosandboxDiagnosticError`),message:passThroughMessage,hint:passThroughHint}];export{SANDBOX_RULES};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{codeIs,messageIs}from"../rule.js";const NETWORK_ERROR_CODES=[`ECONNREFUSED`,`ECONNRESET`,`EAI_AGAIN`,`ENOTFOUND`,`EPIPE`,`ETIMEDOUT`,`UND_ERR_CONNECT_TIMEOUT`,`UND_ERR_SOCKET`],NETWORK_FAILURE_HINT=`Check your internet connection and that the target service is reachable, then try again.`,SYSTEM_RULES=[{id:`port-already-in-use`,name:`Port already in use`,tags:[`system`,`config`],when:codeIs(`EADDRINUSE`),message:"The port is already in use — another process (perhaps another `eve dev`) is listening on it.",hint:"Stop that process or pass a different `--port`."},{id:`disk-full`,name:`Disk full`,tags:[`system`],when:codeIs(`ENOSPC`),message:`The disk is full, so writes are failing.`,hint:`Free up space and retry.`},{id:`network-request-failed`,name:`Network request failed`,tags:[`system`,`transient`],when:codeIs(...NETWORK_ERROR_CODES),message:e=>networkFailureMessage(e.code??`network error`),hint:NETWORK_FAILURE_HINT},{id:`network-request-failed`,name:`Network request failed`,tags:[`system`,`transient`],when:messageIs(`fetch failed`,`socket hang up`),message:e=>networkFailureMessage(e.message.trim()),hint:NETWORK_FAILURE_HINT}];function networkFailureMessage(e){return`A network request failed before completing (${e}).`}export{SYSTEM_RULES};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type SemanticErrorRule } from "../rule.js";
|
|
2
|
+
/**
|
|
3
|
+
* Error class names verified against the vendored `@workflow/errors` and
|
|
4
|
+
* `@workflow/world-local` source: every class assigns `this.name`
|
|
5
|
+
* explicitly in its constructor (`this.name = 'ReplayDivergenceError'`,
|
|
6
|
+
* `'DataDirVersionError'`, …), so the discriminator is stable and
|
|
7
|
+
* survives structured clone across workflow step boundaries.
|
|
8
|
+
*/
|
|
9
|
+
export declare const WORKFLOW_RULES: readonly SemanticErrorRule[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{nameIs}from"../rule.js";const WORKFLOW_RULES=[{id:`workflow-store-version-mismatch`,name:`Local session store incompatible`,tags:[`workflow`],when:nameIs(`DataDirVersionError`),message:"The local workflow store (`.eve/.workflow-data`) was created by an incompatible version.",hint:`Remove that directory to reset local sessions, then retry.`},{id:`workflow-store-inaccessible`,name:`Local session store inaccessible`,tags:[`workflow`],when:nameIs(`DataDirAccessError`),message:"The local workflow store (`.eve/.workflow-data`) could not be created or accessed.",hint:`Check filesystem permissions and free disk space, then retry.`},{id:`workflow-replay-divergence`,name:`Durable replay diverged`,tags:[`workflow`],when:nameIs(`ReplayDivergenceError`),message:`The durable workflow replay diverged from the recorded run — usually caused by code changing mid-session in a way the runtime cannot reconcile.`,hint:"Start a fresh session (`/new` in `eve dev`)."},{id:`workflow-event-log-corrupted`,name:`Durable event log corrupted`,tags:[`workflow`],when:nameIs(`CorruptedEventLogError`),message:`The durable event log for this run is corrupted.`,hint:"Remove `.eve/.workflow-data` to reset local sessions, then retry."},{id:`workflow-run-not-found`,name:`Session run not found`,tags:[`workflow`],when:nameIs(`WorkflowRunNotFoundError`),message:`This session's durable run no longer exists (the local store was reset or pruned).`,hint:`Start a new session.`}];export{WORKFLOW_RULES};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The structural facts extracted from one throwable on a cause chain.
|
|
3
|
+
* Rules match on these fields only — never on live objects — so the
|
|
4
|
+
* same rule works for real Errors and for plain-object shapes that
|
|
5
|
+
* crossed a workflow step boundary (structured clone strips prototypes
|
|
6
|
+
* but keeps own fields).
|
|
7
|
+
*/
|
|
8
|
+
export interface ErrorLink {
|
|
9
|
+
readonly name?: string;
|
|
10
|
+
readonly message: string;
|
|
11
|
+
/** Node/undici style error code (`ECONNREFUSED`, `EADDRINUSE`, …). */
|
|
12
|
+
readonly code?: string;
|
|
13
|
+
readonly statusCode?: number;
|
|
14
|
+
/** Gateway error body discriminator (`rate_limit_exceeded`, …). */
|
|
15
|
+
readonly type?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Structured remediation authored at the throw site (eve's own error
|
|
18
|
+
* classes carry it as an own property, so it survives structured
|
|
19
|
+
* clone). Pass-through rules surface it as the summary hint.
|
|
20
|
+
*/
|
|
21
|
+
readonly hint?: string;
|
|
22
|
+
}
|
|
23
|
+
/** The full cause chain of a throwable, outermost first. */
|
|
24
|
+
export interface ErrorSignals {
|
|
25
|
+
readonly chain: readonly ErrorLink[];
|
|
26
|
+
}
|
|
27
|
+
/** Projects a throwable into the flat signals the rule engine matches on. */
|
|
28
|
+
export declare function extractErrorSignals(error: unknown): ErrorSignals;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isObject}from"#shared/guards.js";import{walkCauseChain}from"#shared/errors.js";function extractErrorSignals(t){let n=[];for(let r of walkCauseChain(t)){if(!isObject(r))continue;let e={message:typeof r.message==`string`?r.message:``};typeof r.name==`string`&&r.name.length>0&&(e.name=r.name),typeof r.code==`string`&&r.code.length>0&&(e.code=r.code),typeof r.statusCode==`number`&&(e.statusCode=r.statusCode),typeof r.type==`string`&&r.type.length>0&&(e.type=r.type),typeof r.hint==`string`&&r.hint.length>0&&(e.hint=r.hint),n.push(e)}return{chain:n}}export{extractErrorSignals};
|