eve 0.30.0 → 0.30.2

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.
Files changed (86) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/src/channel/routes.d.ts +11 -4
  3. package/dist/src/channel/send.js +1 -1
  4. package/dist/src/channel/types.d.ts +6 -3
  5. package/dist/src/compiler/extension-compatibility.d.ts +10 -10
  6. package/dist/src/compiler/extension-compatibility.js +1 -1
  7. package/dist/src/compiler/manifest.d.ts +13 -2
  8. package/dist/src/compiler/manifest.js +1 -1
  9. package/dist/src/compiler/normalize-extension.js +1 -1
  10. package/dist/src/compiler/normalize-manifest.js +2 -2
  11. package/dist/src/compiler/normalize-tool.d.ts +3 -0
  12. package/dist/src/compiler/normalize-tool.js +1 -1
  13. package/dist/src/execution/agent-handle-dispatch.d.ts +32 -0
  14. package/dist/src/execution/agent-handle-dispatch.js +1 -0
  15. package/dist/src/execution/cancel-descendant-turns-step.d.ts +1 -1
  16. package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
  17. package/dist/src/execution/delegated-parent-notification.d.ts +2 -2
  18. package/dist/src/execution/delegated-parent-result.d.ts +4 -4
  19. package/dist/src/execution/delegated-parent-result.js +1 -1
  20. package/dist/src/execution/dispatch-runtime-actions-step.d.ts +8 -6
  21. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  22. package/dist/src/execution/dispatch-workflow-runtime-actions-step.d.ts +2 -2
  23. package/dist/src/execution/dispatch-workflow-runtime-actions-step.js +1 -1
  24. package/dist/src/execution/durable-session-migrations/turn-workflow.d.ts +10 -2
  25. package/dist/src/execution/node-step.js +1 -1
  26. package/dist/src/execution/remote-agent-dispatch.d.ts +7 -2
  27. package/dist/src/execution/remote-agent-dispatch.js +1 -1
  28. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  29. package/dist/src/execution/session-callback-step.js +1 -1
  30. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  31. package/dist/src/execution/turn-execution-cursor.d.ts +3 -3
  32. package/dist/src/execution/turn-workflow.js +1 -1
  33. package/dist/src/execution/workflow-steps.js +1 -1
  34. package/dist/src/harness/agent-handle-errors.d.ts +25 -0
  35. package/dist/src/harness/agent-handle-errors.js +1 -0
  36. package/dist/src/harness/handles/operation-id.d.ts +15 -0
  37. package/dist/src/harness/handles/operation-id.js +1 -0
  38. package/dist/src/harness/handles/prompt.d.ts +21 -0
  39. package/dist/src/harness/handles/prompt.js +2 -0
  40. package/dist/src/harness/handles/query.d.ts +41 -0
  41. package/dist/src/harness/handles/query.js +1 -0
  42. package/dist/src/harness/handles/state-key.d.ts +8 -0
  43. package/dist/src/harness/handles/state-key.js +1 -0
  44. package/dist/src/harness/handles/store.d.ts +132 -0
  45. package/dist/src/harness/handles/store.js +1 -0
  46. package/dist/src/harness/handles/transitions.d.ts +107 -0
  47. package/dist/src/harness/handles/transitions.js +1 -0
  48. package/dist/src/harness/input-requests.js +1 -1
  49. package/dist/src/harness/provider-tools.d.ts +4 -3
  50. package/dist/src/harness/provider-tools.js +1 -1
  51. package/dist/src/harness/runtime-actions.d.ts +4 -25
  52. package/dist/src/harness/runtime-actions.js +1 -1
  53. package/dist/src/harness/tool-loop.d.ts +22 -0
  54. package/dist/src/harness/tool-loop.js +2 -2
  55. package/dist/src/harness/tools.d.ts +2 -0
  56. package/dist/src/harness/tools.js +1 -1
  57. package/dist/src/harness/types.d.ts +9 -0
  58. package/dist/src/internal/application/package.js +1 -1
  59. package/dist/src/internal/authored-definition/schema-backed.d.ts +3 -0
  60. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  61. package/dist/src/protocol/agent-handle-error.d.ts +13 -0
  62. package/dist/src/protocol/agent-handle-error.js +1 -0
  63. package/dist/src/public/channels/eve.js +1 -1
  64. package/dist/src/public/tools/defaults.d.ts +0 -12
  65. package/dist/src/public/tools/defaults.js +1 -1
  66. package/dist/src/public/tools/index.d.ts +1 -0
  67. package/dist/src/public/tools/index.js +1 -1
  68. package/dist/src/public/tools/web-search.d.ts +36 -0
  69. package/dist/src/public/tools/web-search.js +1 -0
  70. package/dist/src/runtime/actions/results.d.ts +6 -0
  71. package/dist/src/runtime/actions/results.js +1 -0
  72. package/dist/src/runtime/actions/types.d.ts +40 -7
  73. package/dist/src/runtime/actions/types.js +1 -1
  74. package/dist/src/runtime/framework-tools/web-search.d.ts +4 -0
  75. package/dist/src/runtime/framework-tools/web-search.js +1 -1
  76. package/dist/src/runtime/resolve-agent.js +1 -1
  77. package/dist/src/runtime/session-callback-route.js +1 -1
  78. package/dist/src/runtime/types.d.ts +3 -0
  79. package/dist/src/setup/scaffold/create/project.js +1 -1
  80. package/dist/src/shared/web-search.d.ts +2 -0
  81. package/dist/src/shared/web-search.js +1 -0
  82. package/docs/concepts/default-harness.md +12 -2
  83. package/docs/reference/typescript-api.md +1 -1
  84. package/package.json +1 -1
  85. package/dist/src/harness/agent-handles.d.ts +0 -238
  86. package/dist/src/harness/agent-handles.js +0 -2
@@ -0,0 +1,13 @@
1
+ /** JSON error returned when an agent-handle operation cannot be completed. */
2
+ export interface AgentHandleErrorJson<TCode extends string = string> {
3
+ readonly code: TCode;
4
+ readonly error: string;
5
+ readonly ok: false;
6
+ }
7
+ /** Stable agent-handle errors shared by HTTP producers and consumers. */
8
+ export declare const AgentHandleError: {
9
+ readonly SessionNotResumable: {
10
+ readonly code: "SESSION_NOT_RESUMABLE";
11
+ readonly toJson: () => AgentHandleErrorJson<"SESSION_NOT_RESUMABLE">;
12
+ };
13
+ };
@@ -0,0 +1 @@
1
+ function defineAgentHandleError(e,t){return{code:e,toJson:()=>({code:e,error:t,ok:!1})}}const AgentHandleError={SessionNotResumable:defineAgentHandleError(`SESSION_NOT_RESUMABLE`,`Session is not active and cannot be resumed.`)};export{AgentHandleError};
@@ -1,3 +1,3 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{hasInternalRefScheme}from"#internal/attachments/url-refs.js";import{EVE_CANCEL_TURN_ROUTE_PATTERN,EVE_CLEAR_SESSION_ROUTE_PATH,EVE_COMPACT_SESSION_ROUTE_PATH,EVE_INFO_ROUTE_PATH,EVE_RESET_SESSION_ROUTE_PATH}from"#protocol/routes.js";import{EVE_MESSAGE_STREAM_CONTENT_TYPE,EVE_MESSAGE_STREAM_FORMAT,EVE_MESSAGE_STREAM_VERSION,EVE_SESSION_ID_HEADER,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_TAIL_INDEX_HEADER,EVE_STREAM_VERSION_HEADER}from"#protocol/message.js";import{isInputResponse}from"#runtime/input/types.js";import{parseJsonObject}from"#shared/json.js";import{GET,POST,defineChannel}from"#public/definitions/channel.js";import"ai";import{parseSessionCallback}from"#channel/session-callback.js";import{readAgentInfoRouteResponse,readRouteAgent}from"#internal/nitro/routes/channel-route-context.js";import{resolveForwardedPrincipal}from"#channel/forwarded-principal.js";import{routeAuth}from"#public/channels/auth.js";import{collectUploadPolicyViolations,formatUploadPolicyViolation,mergeUploadPolicy}from"#public/channels/upload-policy.js";const log=createLogger(`eve.channel`);function defaultEveAuth(e){return e.eve.caller}function eveChannel(e){let n=mergeUploadPolicy(e.uploadPolicy);return defineChannel({cors:normalizeEveCors(e.cors),routes:[GET(EVE_INFO_ROUTE_PATH,async(t,n)=>{let r=await routeAuth(t,e.auth);if(r instanceof Response)return r;let i=readAgentInfoRouteResponse(n);return i===void 0?Response.json({error:`Agent info route requires internal channel dispatch context.`,ok:!1},{status:500}):await i()}),POST(`/eve/v1/session`,async(t,{send:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=i,o;try{o=await t.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof o!=`object`||!o)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let s=await resolveForwardedPrincipal({trustedForwarders:e.trustedForwarders,forwarder:a,payload:o});if(s instanceof Response)return s;let c=parseCreateBody(o);if(c instanceof Response)return c;let l=checkUploadPolicy(c,n);if(l!==null)return l;let u=await resolveOnMessage({auth:s.auth,config:e,message:c.message,request:t});if(u instanceof Response)return u;if(!u.dispatch)return droppedMessageResponse();let d=`eve:${crypto.randomUUID()}`,f=mergeContext(c.context,u.context),p={auth:u.auth,callback:c.callback,continuationToken:d,mode:c.mode};s.accepted&&(p.initiatorAuth=s.initiatorAuth);let m=await r(createSendPayload(c,f),p);return Response.json({continuationToken:m.continuationToken,ok:!0,sessionId:m.id},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:m.id},status:202})}),POST(EVE_RESET_SESSION_ROUTE_PATH,async(n,{reset:r})=>{let i=await routeAuth(n,e.auth);if(i instanceof Response)return i;let a=await parseContinuationTokenBody(n);if(a instanceof Response)return a;let o;try{o=await r({continuationToken:a.continuationToken,reason:`Client requested session reset`})}catch(e){let n=logError(log,`session-reset request failed`,e);return Response.json({error:`Failed to reset the session.`,errorId:n,ok:!1},{status:500})}let s=o.status===`reset`?{ok:!0,previousSessionId:o.previousSessionId,status:`reset`}:{ok:!0,status:`no_active_session`};return Response.json(s,{headers:{"cache-control":`no-store`}})}),POST(EVE_CLEAR_SESSION_ROUTE_PATH,async(n,{clear:r})=>{let i=await routeAuth(n,e.auth);if(i instanceof Response)return i;let a=await parseContinuationTokenBody(n);if(a instanceof Response)return a;let o;try{o=await r({continuationToken:a.continuationToken})}catch(e){let n=logError(log,`session-clear request failed`,e);return Response.json({error:`Failed to clear the session context.`,errorId:n,ok:!1},{status:500})}let s=o.status===`accepted`?{ok:!0,sessionId:o.sessionId,status:`accepted`}:{ok:!0,status:`no_active_session`};return Response.json(s,{headers:{"cache-control":`no-store`},status:o.status===`accepted`?202:200})}),POST(EVE_COMPACT_SESSION_ROUTE_PATH,async(n,{compact:r})=>{let i=await routeAuth(n,e.auth);if(i instanceof Response)return i;let a=await parseContinuationTokenBody(n);if(a instanceof Response)return a;let o;try{o=await r({continuationToken:a.continuationToken})}catch(e){let n=logError(log,`session-compaction request failed`,e);return Response.json({error:`Failed to compact the session.`,errorId:n,ok:!1},{status:500})}let s=o.status===`accepted`?{ok:!0,sessionId:o.sessionId,status:`accepted`}:{ok:!0,status:`no_active_session`};return Response.json(s,{headers:{"cache-control":`no-store`},status:o.status===`accepted`?202:200})}),POST(`/eve/v1/session/:sessionId`,async(t,{send:r,getSession:i,params:a})=>{let o=await routeAuth(t,e.auth);if(o instanceof Response)return o;let s=o,c=a.sessionId;if(!c)return Response.json({error:`Missing session id.`,ok:!1},{status:400});try{i(c)}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}let l;try{l=await t.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof l!=`object`||!l)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let u=parseContinueBody(l);if(u instanceof Response)return u;let d=checkUploadPolicy(u,n);if(d!==null)return d;let f=u.context,p=s;if(u.message!==void 0){let n=await resolveOnMessage({auth:s,config:e,message:u.message,request:t,sessionId:c});if(n instanceof Response)return n;if(!n.dispatch)return droppedMessageResponse();f=mergeContext(u.context,n.context),p=n.auth}let m=await r({inputResponses:u.inputResponses,message:u.message,context:f,outputSchema:u.outputSchema},{auth:p,continuationToken:u.continuationToken});return Response.json({ok:!0,sessionId:m.id},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:m.id},status:200})}),POST(EVE_CANCEL_TURN_ROUTE_PATTERN,async(n,r)=>{let i=await routeAuth(n,e.auth);if(i instanceof Response)return i;let a=r.params.sessionId;if(!a)return Response.json({error:`Missing session id.`,ok:!1},{status:400});let o=await parseCancelTurnBody(n);if(o instanceof Response)return o;let s;try{let e=readRouteAgent(r);if(e===void 0)throw Error(`Missing route agent.`);s=await e.cancelTurn({sessionId:a,turnId:o.turnId})}catch(e){let n=logError(log,`cancel-turn request failed`,e,{sessionId:a});return Response.json({error:`Failed to cancel the turn.`,errorId:n,ok:!1},{status:500})}return Response.json({ok:!0,sessionId:a,status:s.status},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:a},status:202})}),GET(`/eve/v1/session/:sessionId/stream`,async(t,{getSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=r.sessionId;if(!a)return Response.json({error:`Missing session id.`,ok:!1},{status:400});let o=parseStartIndex(t);if(o instanceof Response)return o;let s=parseIncludeTailIndex(t);try{let e=n(a),t=s?await e.getStreamTailIndex():void 0,r=serializeAsNdjson(await e.getEventStream({startIndex:o}));return new Response(r,{headers:{"cache-control":`no-store, no-transform`,"content-type":EVE_MESSAGE_STREAM_CONTENT_TYPE,"x-accel-buffering":`no`,[EVE_SESSION_ID_HEADER]:a,[EVE_STREAM_FORMAT_HEADER]:EVE_MESSAGE_STREAM_FORMAT,...t===void 0?{}:{[EVE_STREAM_TAIL_INDEX_HEADER]:String(t)},[EVE_STREAM_VERSION_HEADER]:EVE_MESSAGE_STREAM_VERSION}})}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}})],events:e.events})}function normalizeEveCors(e){if(e===void 0||e===!1)return!1;if(e===!0)return!0;let t={};return e.origin!==void 0&&(t.origin=normalizeEveCorsOrigin(e.origin)),e.methods!==void 0&&(t.methods=e.methods),e.allowedHeaders!==void 0&&(t.allowHeaders=e.allowedHeaders),e.exposedHeaders!==void 0&&(t.exposeHeaders=e.exposedHeaders),e.credentials!==void 0&&(t.credentials=e.credentials),e.maxAge!==void 0&&(t.maxAge=e.maxAge),e.preflightStatus!==void 0&&(t.preflight={statusCode:e.preflightStatus}),t}function normalizeEveCorsOrigin(e){return e===`*`||e===`null`?e:typeof e==`string`?[e]:e}async function resolveOnMessage(e){let n=e.config.onMessage??defaultOnMessage,r;try{r=await n({eve:e.sessionId===void 0?{caller:e.auth,request:e.request}:{caller:e.auth,request:e.request,sessionId:e.sessionId}},e.message)}catch(n){let r=logError(log,`onMessage handler failed`,n,{sessionId:e.sessionId});return Response.json({error:`onMessage handler failed.`,errorId:r,ok:!1},{status:500})}return r==null?{dispatch:!1}:r.context===void 0?{auth:r.auth,dispatch:!0}:{auth:r.auth,context:r.context,dispatch:!0}}function defaultOnMessage(e){return{auth:defaultEveAuth(e)}}function droppedMessageResponse(){return new Response(null,{headers:{"cache-control":`no-store`},status:204})}function parseCreateBody(e){let t=parseMessageField(e.message);if(t instanceof Response)return t;let n=parseClientContextField(e.clientContext);if(n instanceof Response)return n;let r=parseCallbackField(e.callback);if(r instanceof Response)return r;let i=parseModeField(e.mode);if(i instanceof Response)return i;let a=parseOutputSchemaField(e.outputSchema);return a instanceof Response?a:t===void 0?Response.json({error:`Missing or empty 'message' field.`,ok:!1},{status:400}):{callback:r,message:t,mode:i,context:n,outputSchema:a}}function parseContinueBody(e){if(e.forwardedPrincipal!==void 0)return Response.json({error:`A forwarded principal is only accepted on session creation.`,ok:!1},{status:400});let t=typeof e.continuationToken==`string`&&e.continuationToken.length>0?e.continuationToken:void 0;if(t===void 0)return Response.json({error:`Missing or empty 'continuationToken' field.`,ok:!1},{status:400});let n=parseMessageField(e.message);if(n instanceof Response)return n;let r=parseInputResponses(e.inputResponses);if(r instanceof Response)return r;let i=parseClientContextField(e.clientContext);if(i instanceof Response)return i;let a=parseOutputSchemaField(e.outputSchema);return a instanceof Response?a:n===void 0&&r===void 0?Response.json({error:`Expected a non-empty 'message', a non-empty 'inputResponses' array, or both.`,ok:!1},{status:400}):{message:n,continuationToken:t,inputResponses:r,context:i,outputSchema:a}}async function parseContinuationTokenBody(e){let t;try{t=await e.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof t!=`object`||!t||Array.isArray(t))return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let n=t.continuationToken;return typeof n!=`string`||n.length===0?Response.json({error:`Expected 'continuationToken' to be a non-empty string.`,ok:!1},{status:400}):{continuationToken:n}}async function parseCancelTurnBody(e){let t;try{t=await e.text()}catch{return Response.json({error:`Unreadable request body.`,ok:!1},{status:400})}if(t.trim().length===0)return{};let n;try{n=JSON.parse(t)}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof n!=`object`||!n||Array.isArray(n))return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let r=n.turnId;return r===void 0?{}:typeof r!=`string`||r.length===0?Response.json({error:`Expected 'turnId' to be a non-empty string.`,ok:!1},{status:400}):{turnId:r}}function createSendPayload(e,t=e.context){if(t===void 0&&e.outputSchema===void 0)return e.message;let n={message:e.message};return t!==void 0&&(n.context=t),e.outputSchema!==void 0&&(n.outputSchema=e.outputSchema),n}function parseOutputSchemaField(e){if(e!==void 0)try{return parseJsonObject(e)}catch{return Response.json({error:`Expected 'outputSchema' to be a JSON-serializable object.`,ok:!1},{status:400})}}function parseCallbackField(e){if(e===void 0)return;let t=parseSessionCallback(e);return t.ok?t.callback:Response.json({error:t.message,ok:!1},{status:400})}function parseModeField(e){if(e!==void 0)return e===`conversation`||e===`task`?e:Response.json({error:`Expected 'mode' to be either 'conversation' or 'task'.`,ok:!1},{status:400})}function parseMessageField(e){if(e===void 0)return;if(typeof e==`string`)return e.length>0?e:void 0;if(!Array.isArray(e))return Response.json({error:`Expected 'message' to be a string or an array of text/file parts.`,ok:!1},{status:400});if(e.length===0)return;let t=[];for(let n of e){let e=parseMessagePart(n);if(e instanceof Response)return e;t.push(e)}return t}function parseMessagePart(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected each message part to be an object.`,ok:!1},{status:400});let t=e;if(t.type===`text`)return typeof t.text!=`string`||t.text.length===0?Response.json({error:`Text parts require a non-empty 'text' string.`,ok:!1},{status:400}):{type:`text`,text:t.text};if(t.type===`file`){if(typeof t.mediaType!=`string`||t.mediaType.length===0)return Response.json({error:`File parts require a non-empty 'mediaType' string.`,ok:!1},{status:400});if(typeof t.data!=`string`)return Response.json({error:`File parts require a 'data' string (base64, data URL, or URL).`,ok:!1},{status:400});if(hasInternalRefScheme(t.data))return Response.json({error:`File part 'data' must not use a framework-internal ref scheme.`,ok:!1},{status:400});let e={type:`file`,mediaType:t.mediaType,data:t.data};return typeof t.filename==`string`&&t.filename.length>0&&(e.filename=t.filename),e}return Response.json({error:`Unsupported message part type "${String(t.type)}". Use 'text' or 'file'.`,ok:!1},{status:400})}function checkUploadPolicy(e,t){if(!e.message)return null;let n=collectUploadPolicyViolations(e.message,t);if(n.length===0)return null;let[r]=n;if(!r)return null;let i=r.kind===`too-large`?413:415;return Response.json({error:formatUploadPolicyViolation(r),ok:!1,violations:n.map(e=>e.kind===`too-large`?{byteLength:e.byteLength,filename:e.filename,kind:e.kind,limit:e.limit,mediaType:e.mediaType}:{allowedMediaTypes:e.allowedMediaTypes,filename:e.filename,kind:e.kind,mediaType:e.mediaType})},{status:i})}function parseInputResponses(e){if(e===void 0)return;if(!Array.isArray(e)||e.length===0)return Response.json({error:`Expected 'inputResponses' to be a non-empty array.`,ok:!1},{status:400});let t=e.filter(isInputResponse);return t.length===e.length?t:Response.json({error:`Expected every 'inputResponses' entry to match the HITL response schema.`,ok:!1},{status:400})}function mergeContext(e,t){return e===void 0?t:t===void 0?e:[...e,...t]}function parseClientContextField(e){if(e!==void 0){if(typeof e==`string`)return e.length>0?[toClientContextMessage(e)]:void 0;if(Array.isArray(e))return e.length===0?void 0:e.every(e=>typeof e==`string`&&e.length>0)?e.map(e=>toClientContextMessage(e)):Response.json({error:`Expected 'clientContext' array entries to be non-empty strings.`,ok:!1},{status:400});if(typeof e!=`object`||!e)return Response.json({error:`Expected 'clientContext' to be a string, string array, or JSON object.`,ok:!1},{status:400});try{let t=parseJsonObject(e);return[toClientContextMessage(JSON.stringify(t))]}catch{return Response.json({error:`Expected 'clientContext' to be a JSON-serializable object.`,ok:!1},{status:400})}}}function toClientContextMessage(e){return`Client context:
1
+ import{createLogger,logError}from"#internal/logging.js";import{isRuntimeNoActiveSessionError}from"#execution/runtime-errors.js";import{hasInternalRefScheme}from"#internal/attachments/url-refs.js";import{EVE_CANCEL_TURN_ROUTE_PATTERN,EVE_CLEAR_SESSION_ROUTE_PATH,EVE_COMPACT_SESSION_ROUTE_PATH,EVE_INFO_ROUTE_PATH,EVE_RESET_SESSION_ROUTE_PATH}from"#protocol/routes.js";import{EVE_MESSAGE_STREAM_CONTENT_TYPE,EVE_MESSAGE_STREAM_FORMAT,EVE_MESSAGE_STREAM_VERSION,EVE_SESSION_ID_HEADER,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_TAIL_INDEX_HEADER,EVE_STREAM_VERSION_HEADER}from"#protocol/message.js";import{isInputResponse}from"#runtime/input/types.js";import{parseJsonObject}from"#shared/json.js";import{GET,POST,defineChannel}from"#public/definitions/channel.js";import"ai";import{parseSessionCallback}from"#channel/session-callback.js";import{readAgentInfoRouteResponse,readRouteAgent}from"#internal/nitro/routes/channel-route-context.js";import{resolveForwardedPrincipal}from"#channel/forwarded-principal.js";import{AgentHandleError}from"#protocol/agent-handle-error.js";import{routeAuth}from"#public/channels/auth.js";import{collectUploadPolicyViolations,formatUploadPolicyViolation,mergeUploadPolicy}from"#public/channels/upload-policy.js";const log=createLogger(`eve.channel`);function defaultEveAuth(e){return e.eve.caller}function eveChannel(e){let r=mergeUploadPolicy(e.uploadPolicy);return defineChannel({cors:normalizeEveCors(e.cors),routes:[GET(EVE_INFO_ROUTE_PATH,async(t,n)=>{let r=await routeAuth(t,e.auth);if(r instanceof Response)return r;let i=readAgentInfoRouteResponse(n);return i===void 0?Response.json({error:`Agent info route requires internal channel dispatch context.`,ok:!1},{status:500}):await i()}),POST(`/eve/v1/session`,async(t,{send:n})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=i,o;try{o=await t.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof o!=`object`||!o)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let s=await resolveForwardedPrincipal({trustedForwarders:e.trustedForwarders,forwarder:a,payload:o});if(s instanceof Response)return s;let c=parseCreateBody(o);if(c instanceof Response)return c;let l=checkUploadPolicy(c,r);if(l!==null)return l;let u=await resolveOnMessage({auth:s.auth,config:e,message:c.message,request:t});if(u instanceof Response)return u;if(!u.dispatch)return droppedMessageResponse();let d=`eve:${crypto.randomUUID()}`,f=mergeContext(c.context,u.context),p={auth:u.auth,callback:c.callback,capabilities:c.capabilities,continuationToken:d,mode:c.mode};s.accepted&&(p.initiatorAuth=s.initiatorAuth);let m=await n(createSendPayload(c,f),p);return Response.json({continuationToken:m.continuationToken,ok:!0,sessionId:m.id},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:m.id},status:202})}),POST(EVE_RESET_SESSION_ROUTE_PATH,async(n,{reset:r})=>{let i=await routeAuth(n,e.auth);if(i instanceof Response)return i;let a=await parseContinuationTokenBody(n);if(a instanceof Response)return a;let o;try{o=await r({continuationToken:a.continuationToken,reason:`Client requested session reset`})}catch(e){let n=logError(log,`session-reset request failed`,e);return Response.json({error:`Failed to reset the session.`,errorId:n,ok:!1},{status:500})}let s=o.status===`reset`?{ok:!0,previousSessionId:o.previousSessionId,status:`reset`}:{ok:!0,status:`no_active_session`};return Response.json(s,{headers:{"cache-control":`no-store`}})}),POST(EVE_CLEAR_SESSION_ROUTE_PATH,async(n,{clear:r})=>{let i=await routeAuth(n,e.auth);if(i instanceof Response)return i;let a=await parseContinuationTokenBody(n);if(a instanceof Response)return a;let o;try{o=await r({continuationToken:a.continuationToken})}catch(e){let n=logError(log,`session-clear request failed`,e);return Response.json({error:`Failed to clear the session context.`,errorId:n,ok:!1},{status:500})}let s=o.status===`accepted`?{ok:!0,sessionId:o.sessionId,status:`accepted`}:{ok:!0,status:`no_active_session`};return Response.json(s,{headers:{"cache-control":`no-store`},status:o.status===`accepted`?202:200})}),POST(EVE_COMPACT_SESSION_ROUTE_PATH,async(n,{compact:r})=>{let i=await routeAuth(n,e.auth);if(i instanceof Response)return i;let a=await parseContinuationTokenBody(n);if(a instanceof Response)return a;let o;try{o=await r({continuationToken:a.continuationToken})}catch(e){let n=logError(log,`session-compaction request failed`,e);return Response.json({error:`Failed to compact the session.`,errorId:n,ok:!1},{status:500})}let s=o.status===`accepted`?{ok:!0,sessionId:o.sessionId,status:`accepted`}:{ok:!0,status:`no_active_session`};return Response.json(s,{headers:{"cache-control":`no-store`},status:o.status===`accepted`?202:200})}),POST(`/eve/v1/session/:sessionId`,async(t,{send:i,getSession:a,params:o})=>{let s=await routeAuth(t,e.auth);if(s instanceof Response)return s;let c=s,l=o.sessionId;if(!l)return Response.json({error:`Missing session id.`,ok:!1},{status:400});try{a(l)}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}let u;try{u=await t.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof u!=`object`||!u)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let d=parseContinueBody(u);if(d instanceof Response)return d;let f=checkUploadPolicy(d,r);if(f!==null)return f;let p=d.context,m=c;if(d.message!==void 0){let n=await resolveOnMessage({auth:c,config:e,message:d.message,request:t,sessionId:l});if(n instanceof Response)return n;if(!n.dispatch)return droppedMessageResponse();p=mergeContext(d.context,n.context),m=n.auth}let h={auth:m,continuationToken:d.continuationToken,intent:`resume`};d.callback!==void 0&&(h.caller={callId:d.callback.callId,replyTo:{kind:`callback`,url:d.callback.url},subagentName:d.callback.subagentName});let g;try{g=await i({inputResponses:d.inputResponses,message:d.message,context:p,outputSchema:d.outputSchema},h)}catch(e){if(!isRuntimeNoActiveSessionError(e))throw e;return Response.json(AgentHandleError.SessionNotResumable.toJson(),{status:404})}return Response.json({ok:!0,sessionId:g.id},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:g.id},status:200})}),POST(EVE_CANCEL_TURN_ROUTE_PATTERN,async(n,r)=>{let i=await routeAuth(n,e.auth);if(i instanceof Response)return i;let a=r.params.sessionId;if(!a)return Response.json({error:`Missing session id.`,ok:!1},{status:400});let o=await parseCancelTurnBody(n);if(o instanceof Response)return o;let s;try{let e=readRouteAgent(r);if(e===void 0)throw Error(`Missing route agent.`);s=await e.cancelTurn({sessionId:a,turnId:o.turnId})}catch(e){let n=logError(log,`cancel-turn request failed`,e,{sessionId:a});return Response.json({error:`Failed to cancel the turn.`,errorId:n,ok:!1},{status:500})}return Response.json({ok:!0,sessionId:a,status:s.status},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:a},status:202})}),GET(`/eve/v1/session/:sessionId/stream`,async(t,{getSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=r.sessionId;if(!a)return Response.json({error:`Missing session id.`,ok:!1},{status:400});let o=parseStartIndex(t);if(o instanceof Response)return o;let s=parseIncludeTailIndex(t);try{let e=n(a),t=s?await e.getStreamTailIndex():void 0,r=serializeAsNdjson(await e.getEventStream({startIndex:o}));return new Response(r,{headers:{"cache-control":`no-store, no-transform`,"content-type":EVE_MESSAGE_STREAM_CONTENT_TYPE,"x-accel-buffering":`no`,[EVE_SESSION_ID_HEADER]:a,[EVE_STREAM_FORMAT_HEADER]:EVE_MESSAGE_STREAM_FORMAT,...t===void 0?{}:{[EVE_STREAM_TAIL_INDEX_HEADER]:String(t)},[EVE_STREAM_VERSION_HEADER]:EVE_MESSAGE_STREAM_VERSION}})}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}})],events:e.events})}function normalizeEveCors(e){if(e===void 0||e===!1)return!1;if(e===!0)return!0;let t={};return e.origin!==void 0&&(t.origin=normalizeEveCorsOrigin(e.origin)),e.methods!==void 0&&(t.methods=e.methods),e.allowedHeaders!==void 0&&(t.allowHeaders=e.allowedHeaders),e.exposedHeaders!==void 0&&(t.exposeHeaders=e.exposedHeaders),e.credentials!==void 0&&(t.credentials=e.credentials),e.maxAge!==void 0&&(t.maxAge=e.maxAge),e.preflightStatus!==void 0&&(t.preflight={statusCode:e.preflightStatus}),t}function normalizeEveCorsOrigin(e){return e===`*`||e===`null`?e:typeof e==`string`?[e]:e}async function resolveOnMessage(e){let n=e.config.onMessage??defaultOnMessage,r;try{r=await n({eve:e.sessionId===void 0?{caller:e.auth,request:e.request}:{caller:e.auth,request:e.request,sessionId:e.sessionId}},e.message)}catch(n){let r=logError(log,`onMessage handler failed`,n,{sessionId:e.sessionId});return Response.json({error:`onMessage handler failed.`,errorId:r,ok:!1},{status:500})}return r==null?{dispatch:!1}:r.context===void 0?{auth:r.auth,dispatch:!0}:{auth:r.auth,context:r.context,dispatch:!0}}function defaultOnMessage(e){return{auth:defaultEveAuth(e)}}function droppedMessageResponse(){return new Response(null,{headers:{"cache-control":`no-store`},status:204})}function parseCreateBody(e){let t=parseMessageField(e.message);if(t instanceof Response)return t;let n=parseClientContextField(e.clientContext);if(n instanceof Response)return n;let r=parseCallbackField(e.callback);if(r instanceof Response)return r;let i=parseCapabilitiesField(e.capabilities);if(i instanceof Response)return i;let a=parseModeField(e.mode);if(a instanceof Response)return a;let o=parseOutputSchemaField(e.outputSchema);return o instanceof Response?o:t===void 0?Response.json({error:`Missing or empty 'message' field.`,ok:!1},{status:400}):{callback:r,capabilities:i,message:t,mode:a,context:n,outputSchema:o}}function parseContinueBody(e){if(e.forwardedPrincipal!==void 0)return Response.json({error:`A forwarded principal is only accepted on session creation.`,ok:!1},{status:400});let t=typeof e.continuationToken==`string`&&e.continuationToken.length>0?e.continuationToken:void 0;if(t===void 0)return Response.json({error:`Missing or empty 'continuationToken' field.`,ok:!1},{status:400});let n=parseMessageField(e.message);if(n instanceof Response)return n;let r=parseCallbackField(e.callback);if(r instanceof Response)return r;let i=parseInputResponses(e.inputResponses);if(i instanceof Response)return i;let a=parseClientContextField(e.clientContext);if(a instanceof Response)return a;let o=parseOutputSchemaField(e.outputSchema);return o instanceof Response?o:n===void 0&&i===void 0?Response.json({error:`Expected a non-empty 'message', a non-empty 'inputResponses' array, or both.`,ok:!1},{status:400}):{callback:r,message:n,continuationToken:t,inputResponses:i,context:a,outputSchema:o}}async function parseContinuationTokenBody(e){let t;try{t=await e.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof t!=`object`||!t||Array.isArray(t))return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let n=t.continuationToken;return typeof n!=`string`||n.length===0?Response.json({error:`Expected 'continuationToken' to be a non-empty string.`,ok:!1},{status:400}):{continuationToken:n}}async function parseCancelTurnBody(e){let t;try{t=await e.text()}catch{return Response.json({error:`Unreadable request body.`,ok:!1},{status:400})}if(t.trim().length===0)return{};let n;try{n=JSON.parse(t)}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof n!=`object`||!n||Array.isArray(n))return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let r=n.turnId;return r===void 0?{}:typeof r!=`string`||r.length===0?Response.json({error:`Expected 'turnId' to be a non-empty string.`,ok:!1},{status:400}):{turnId:r}}function createSendPayload(e,t=e.context){if(t===void 0&&e.outputSchema===void 0)return e.message;let n={message:e.message};return t!==void 0&&(n.context=t),e.outputSchema!==void 0&&(n.outputSchema=e.outputSchema),n}function parseOutputSchemaField(e){if(e!==void 0)try{return parseJsonObject(e)}catch{return Response.json({error:`Expected 'outputSchema' to be a JSON-serializable object.`,ok:!1},{status:400})}}function parseCallbackField(e){if(e===void 0)return;let t=parseSessionCallback(e);return t.ok?t.callback:Response.json({error:t.message,ok:!1},{status:400})}function parseCapabilitiesField(e){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return Response.json({error:`Expected 'capabilities' to be an object.`,ok:!1},{status:400});let t=Object.keys(e),n=Reflect.get(e,`requestInput`);return t.some(e=>e!==`requestInput`)||n!==void 0&&typeof n!=`boolean`?Response.json({error:`Expected 'capabilities.requestInput' to be a boolean when provided.`,ok:!1},{status:400}):n===void 0?{}:{requestInput:n}}function parseModeField(e){if(e!==void 0)return e===`conversation`||e===`task`?e:Response.json({error:`Expected 'mode' to be either 'conversation' or 'task'.`,ok:!1},{status:400})}function parseMessageField(e){if(e===void 0)return;if(typeof e==`string`)return e.length>0?e:void 0;if(!Array.isArray(e))return Response.json({error:`Expected 'message' to be a string or an array of text/file parts.`,ok:!1},{status:400});if(e.length===0)return;let t=[];for(let n of e){let e=parseMessagePart(n);if(e instanceof Response)return e;t.push(e)}return t}function parseMessagePart(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected each message part to be an object.`,ok:!1},{status:400});let t=e;if(t.type===`text`)return typeof t.text!=`string`||t.text.length===0?Response.json({error:`Text parts require a non-empty 'text' string.`,ok:!1},{status:400}):{type:`text`,text:t.text};if(t.type===`file`){if(typeof t.mediaType!=`string`||t.mediaType.length===0)return Response.json({error:`File parts require a non-empty 'mediaType' string.`,ok:!1},{status:400});if(typeof t.data!=`string`)return Response.json({error:`File parts require a 'data' string (base64, data URL, or URL).`,ok:!1},{status:400});if(hasInternalRefScheme(t.data))return Response.json({error:`File part 'data' must not use a framework-internal ref scheme.`,ok:!1},{status:400});let e={type:`file`,mediaType:t.mediaType,data:t.data};return typeof t.filename==`string`&&t.filename.length>0&&(e.filename=t.filename),e}return Response.json({error:`Unsupported message part type "${String(t.type)}". Use 'text' or 'file'.`,ok:!1},{status:400})}function checkUploadPolicy(e,t){if(!e.message)return null;let n=collectUploadPolicyViolations(e.message,t);if(n.length===0)return null;let[r]=n;if(!r)return null;let i=r.kind===`too-large`?413:415;return Response.json({error:formatUploadPolicyViolation(r),ok:!1,violations:n.map(e=>e.kind===`too-large`?{byteLength:e.byteLength,filename:e.filename,kind:e.kind,limit:e.limit,mediaType:e.mediaType}:{allowedMediaTypes:e.allowedMediaTypes,filename:e.filename,kind:e.kind,mediaType:e.mediaType})},{status:i})}function parseInputResponses(e){if(e===void 0)return;if(!Array.isArray(e)||e.length===0)return Response.json({error:`Expected 'inputResponses' to be a non-empty array.`,ok:!1},{status:400});let t=e.filter(isInputResponse);return t.length===e.length?t:Response.json({error:`Expected every 'inputResponses' entry to match the HITL response schema.`,ok:!1},{status:400})}function mergeContext(e,t){return e===void 0?t:t===void 0?e:[...e,...t]}function parseClientContextField(e){if(e!==void 0){if(typeof e==`string`)return e.length>0?[toClientContextMessage(e)]:void 0;if(Array.isArray(e))return e.length===0?void 0:e.every(e=>typeof e==`string`&&e.length>0)?e.map(e=>toClientContextMessage(e)):Response.json({error:`Expected 'clientContext' array entries to be non-empty strings.`,ok:!1},{status:400});if(typeof e!=`object`||!e)return Response.json({error:`Expected 'clientContext' to be a string, string array, or JSON object.`,ok:!1},{status:400});try{let t=parseJsonObject(e);return[toClientContextMessage(JSON.stringify(t))]}catch{return Response.json({error:`Expected 'clientContext' to be a JSON-serializable object.`,ok:!1},{status:400})}}}function toClientContextMessage(e){return`Client context:
2
2
  ${e}`}function parseIncludeTailIndex(e){let t=new URL(e.url).searchParams.get(`includeTailIndex`);return t===`1`||t===`true`}function parseStartIndex(e){let t=new URL(e.url).searchParams.get(`startIndex`);if(t===null)return;let n=Number(t);return!/^-?\d+$/.test(t)||!Number.isSafeInteger(n)?Response.json({error:`Expected startIndex to be an integer.`,ok:!1},{status:400}):n}function serializeAsNdjson(e){let t=new TextEncoder;return e.pipeThrough(new TransformStream({start(e){e.enqueue(t.encode(`
3
3
  `))},transform(e,n){n.enqueue(t.encode(`${JSON.stringify(e)}\n`))}}))}export{defaultEveAuth,eveChannel};
@@ -44,15 +44,3 @@ export declare const todo: ToolDefinition;
44
44
  * nothing to load.
45
45
  */
46
46
  export declare const loadSkill: ToolDefinition;
47
- /**
48
- * Framework-provided web search tool. The provider manages the real
49
- * implementation; the harness injects it at step time based on the model
50
- * provider. The local `execute` here is a throwing stub: calling it directly
51
- * fails. To run your own search instead, replace this with `defineTool()` in
52
- * `agent/tools/web_search.ts`.
53
- *
54
- * This default has no input schema (`inputSchema` is empty): the
55
- * provider-managed implementation defines its own contract at step time, so it
56
- * is shaped differently from the others, which preserve their real schemas.
57
- */
58
- export declare const webSearch: ToolDefinition;
@@ -1 +1 @@
1
- import{TODO_TOOL_DEFINITION}from"#runtime/framework-tools/todo.js";import{WEB_SEARCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-search.js";import{BASH_TOOL_DEFINITION}from"#runtime/framework-tools/bash.js";import{GLOB_TOOL_DEFINITION}from"#runtime/framework-tools/glob.js";import{GREP_TOOL_DEFINITION}from"#runtime/framework-tools/grep.js";import{READ_FILE_TOOL_DEFINITION}from"#runtime/framework-tools/read-file.js";import{SKILL_TOOL_DEFINITION}from"#runtime/framework-tools/skill.js";import{WEB_FETCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-fetch.js";import{WRITE_FILE_TOOL_DEFINITION}from"#runtime/framework-tools/write-file.js";import{toPublicToolDefinition}from"#public/tools/internal.js";const bash=toPublicToolDefinition(BASH_TOOL_DEFINITION),glob=toPublicToolDefinition(GLOB_TOOL_DEFINITION),grep=toPublicToolDefinition(GREP_TOOL_DEFINITION),readFile=toPublicToolDefinition(READ_FILE_TOOL_DEFINITION),writeFile=toPublicToolDefinition(WRITE_FILE_TOOL_DEFINITION),webFetch=toPublicToolDefinition(WEB_FETCH_TOOL_DEFINITION),todo=toPublicToolDefinition(TODO_TOOL_DEFINITION),loadSkill=toPublicToolDefinition(SKILL_TOOL_DEFINITION),webSearch={description:WEB_SEARCH_TOOL_DEFINITION.description,inputSchema:{},execute(e){throw Error(`web_search is provider-managed and has no local execute. Override with defineTool() to provide a custom implementation.`)}};export{bash,glob,grep,loadSkill,readFile,todo,webFetch,webSearch,writeFile};
1
+ import{TODO_TOOL_DEFINITION}from"#runtime/framework-tools/todo.js";import{BASH_TOOL_DEFINITION}from"#runtime/framework-tools/bash.js";import{GLOB_TOOL_DEFINITION}from"#runtime/framework-tools/glob.js";import{GREP_TOOL_DEFINITION}from"#runtime/framework-tools/grep.js";import{READ_FILE_TOOL_DEFINITION}from"#runtime/framework-tools/read-file.js";import{SKILL_TOOL_DEFINITION}from"#runtime/framework-tools/skill.js";import{WEB_FETCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-fetch.js";import{WRITE_FILE_TOOL_DEFINITION}from"#runtime/framework-tools/write-file.js";import{toPublicToolDefinition}from"#public/tools/internal.js";const bash=toPublicToolDefinition(BASH_TOOL_DEFINITION),glob=toPublicToolDefinition(GLOB_TOOL_DEFINITION),grep=toPublicToolDefinition(GREP_TOOL_DEFINITION),readFile=toPublicToolDefinition(READ_FILE_TOOL_DEFINITION),writeFile=toPublicToolDefinition(WRITE_FILE_TOOL_DEFINITION),webFetch=toPublicToolDefinition(WEB_FETCH_TOOL_DEFINITION),todo=toPublicToolDefinition(TODO_TOOL_DEFINITION),loadSkill=toPublicToolDefinition(SKILL_TOOL_DEFINITION);export{bash,glob,grep,loadSkill,readFile,todo,webFetch,writeFile};
@@ -12,3 +12,4 @@ export { type DefineGlobToolInput, defineGlobTool } from "#public/tools/define-g
12
12
  export { type DefineGrepToolInput, defineGrepTool } from "#public/tools/define-grep-tool.js";
13
13
  export { type DefineReadFileToolInput, defineReadFileTool, } from "#public/tools/define-read-file-tool.js";
14
14
  export { type DefineWriteFileToolInput, defineWriteFileTool, } from "#public/tools/define-write-file-tool.js";
15
+ export { type WebSearchProvider, type WebSearchToolDefinition, type WebSearchToolInput, webSearch, } from "#public/tools/web-search.js";
@@ -1 +1 @@
1
- import{defineDynamic,defineTool,disableTool,experimental_workflow,isDisabledToolSentinel,isExperimentalWorkflowToolDefinition}from"#public/definitions/tool.js";import{toolResultFrom}from"#public/tool-result-narrowing.js";import{toolOutput,toolOutputPart}from"#public/tools/output-builders.js";import{defineBashTool}from"#public/tools/define-bash-tool.js";import{defineGlobTool}from"#public/tools/define-glob-tool.js";import{defineGrepTool}from"#public/tools/define-grep-tool.js";import{defineReadFileTool}from"#public/tools/define-read-file-tool.js";import{defineWriteFileTool}from"#public/tools/define-write-file-tool.js";export{defineBashTool,defineDynamic,defineGlobTool,defineGrepTool,defineReadFileTool,defineTool,defineWriteFileTool,disableTool,experimental_workflow,isDisabledToolSentinel,isExperimentalWorkflowToolDefinition,toolOutput,toolOutputPart,toolResultFrom};
1
+ import{defineDynamic,defineTool,disableTool,experimental_workflow,isDisabledToolSentinel,isExperimentalWorkflowToolDefinition}from"#public/definitions/tool.js";import{webSearch}from"#public/tools/web-search.js";import{toolResultFrom}from"#public/tool-result-narrowing.js";import{toolOutput,toolOutputPart}from"#public/tools/output-builders.js";import{defineBashTool}from"#public/tools/define-bash-tool.js";import{defineGlobTool}from"#public/tools/define-glob-tool.js";import{defineGrepTool}from"#public/tools/define-grep-tool.js";import{defineReadFileTool}from"#public/tools/define-read-file-tool.js";import{defineWriteFileTool}from"#public/tools/define-write-file-tool.js";export{defineBashTool,defineDynamic,defineGlobTool,defineGrepTool,defineReadFileTool,defineTool,defineWriteFileTool,disableTool,experimental_workflow,isDisabledToolSentinel,isExperimentalWorkflowToolDefinition,toolOutput,toolOutputPart,toolResultFrom,webSearch};
@@ -0,0 +1,36 @@
1
+ import type { WebSearchProvider } from "#shared/web-search.js";
2
+ export type { WebSearchProvider };
3
+ declare const WEB_SEARCH_TOOL_KIND = "eve:web-search-tool";
4
+ /** Configuration accepted by {@link webSearch}. */
5
+ export interface WebSearchToolInput {
6
+ /** Provider to use when the agent model is routed through AI Gateway. */
7
+ readonly provider: WebSearchProvider;
8
+ }
9
+ /**
10
+ * Provider-managed web search configuration.
11
+ *
12
+ * Export this from `agent/tools/web_search.ts` to select the AI Gateway
13
+ * search provider for that agent. Direct provider models continue to use
14
+ * their native web search implementation.
15
+ */
16
+ export interface WebSearchToolDefinition {
17
+ readonly kind: typeof WEB_SEARCH_TOOL_KIND;
18
+ readonly provider: WebSearchProvider;
19
+ }
20
+ /**
21
+ * Configures the framework-provided `web_search` tool.
22
+ *
23
+ * When no configuration file is present, eve uses Parallel for AI Gateway
24
+ * models.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * // agent/tools/web_search.ts
29
+ * import { webSearch } from "eve/tools";
30
+ *
31
+ * export default webSearch({ provider: "exa" });
32
+ * ```
33
+ */
34
+ export declare function webSearch(input: WebSearchToolInput): WebSearchToolDefinition;
35
+ /** Returns whether a value is a provider-managed web search definition. */
36
+ export declare function isWebSearchToolDefinition(value: unknown): value is WebSearchToolDefinition;
@@ -0,0 +1 @@
1
+ const WEB_SEARCH_TOOL_KIND=`eve:web-search-tool`;function webSearch(e){return{kind:WEB_SEARCH_TOOL_KIND,provider:e.provider}}function isWebSearchToolDefinition(e){return typeof e==`object`&&!!e&&e.kind===WEB_SEARCH_TOOL_KIND}export{isWebSearchToolDefinition,webSearch};
@@ -0,0 +1,6 @@
1
+ import type { RuntimeActionResult } from "#runtime/actions/types.js";
2
+ /** Returns results in pending-key order once every requested action has completed. */
3
+ export declare function resolveRuntimeActionResultsForKeys(input: {
4
+ readonly pendingKeys: readonly string[];
5
+ readonly results: readonly RuntimeActionResult[];
6
+ }): RuntimeActionResult[] | undefined;
@@ -0,0 +1 @@
1
+ import{getRuntimeActionResultKey}from"#runtime/actions/keys.js";function resolveRuntimeActionResultsForKeys(t){let n=new Set(t.pendingKeys),r=new Map;for(let i of t.results){let t=getRuntimeActionResultKey(i);n.has(t)&&r.set(t,i)}let i=[];for(let e of t.pendingKeys){let t=r.get(e);if(t===void 0)return;i.push(t)}return i}export{resolveRuntimeActionResultsForKeys};
@@ -112,19 +112,27 @@ declare const runtimeToolResultActionResultSchema: z.ZodObject<{
112
112
  toolName: z.ZodString;
113
113
  }, z.core.$strict>;
114
114
  /**
115
- * Runtime-owned subagent result projected back into a harness resume call.
115
+ * Subagent result produced by a dispatched child session and delivered back
116
+ * through the parent's resume hook.
116
117
  *
117
- * `usage` carries the completed child session's token totals so the
118
- * caller can attribute the subagent's spend.
118
+ * Results bind to the pending call by callId alone: possession of the
119
+ * parent's callback token is the authorization to settle, so no further
120
+ * identity verification happens here. Under the accepted at-least-once
121
+ * dispatch window a replay-orphaned duplicate child holds the same token
122
+ * and callId and may settle the call in place of the owned child — its
123
+ * output is computed from the same input, and this is an accepted
124
+ * trade-off, not an oversight. `usage` carries the completed child
125
+ * session's token totals so the caller can attribute the subagent's spend.
119
126
  */
120
- export type RuntimeSubagentResultActionResult = z.infer<typeof runtimeSubagentResultActionResultSchema>;
127
+ export type RuntimeSubagentChildResult = z.infer<typeof runtimeSubagentChildResultSchema>;
121
128
  /**
122
- * Zod schema for one runtime-owned subagent result action result.
129
+ * Zod schema for one child-produced subagent result.
123
130
  */
124
- declare const runtimeSubagentResultActionResultSchema: z.ZodObject<{
131
+ declare const runtimeSubagentChildResultSchema: z.ZodObject<{
125
132
  callId: z.ZodString;
126
133
  isError: z.ZodOptional<z.ZodBoolean>;
127
134
  kind: z.ZodLiteral<"subagent-result">;
135
+ origin: z.ZodLiteral<"child">;
128
136
  output: z.ZodType<import("../../shared/json.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("../../shared/json.ts").JsonValue, unknown>>;
129
137
  subagentName: z.ZodString;
130
138
  usage: z.ZodOptional<z.ZodObject<{
@@ -134,6 +142,31 @@ declare const runtimeSubagentResultActionResultSchema: z.ZodObject<{
134
142
  outputTokens: z.ZodNumber;
135
143
  }, z.core.$strip>>;
136
144
  }, z.core.$strict>;
145
+ /**
146
+ * Subagent failure synthesized on the parent side when no child produced a
147
+ * result: dispatch rejections, start failures, and agentId-continuation
148
+ * delivery errors. Always an error. Enters the harness only through the
149
+ * trusted step-result path, never through the shared callback inbox.
150
+ */
151
+ export type RuntimeSubagentDispatchFailure = z.infer<typeof runtimeSubagentDispatchFailureSchema>;
152
+ /**
153
+ * Zod schema for one parent-synthesized subagent dispatch failure.
154
+ */
155
+ declare const runtimeSubagentDispatchFailureSchema: z.ZodObject<{
156
+ callId: z.ZodString;
157
+ isError: z.ZodLiteral<true>;
158
+ kind: z.ZodLiteral<"subagent-result">;
159
+ origin: z.ZodLiteral<"dispatch">;
160
+ output: z.ZodType<import("../../shared/json.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("../../shared/json.ts").JsonValue, unknown>>;
161
+ subagentName: z.ZodString;
162
+ }, z.core.$strict>;
163
+ /**
164
+ * Runtime-owned subagent result projected back into a harness resume call,
165
+ * discriminated on `origin`: `child` results come from a dispatched child
166
+ * session and must bind to a running agent handle; `dispatch` failures are
167
+ * parent-synthesized and trusted by construction.
168
+ */
169
+ export type RuntimeSubagentResult = RuntimeSubagentChildResult | RuntimeSubagentDispatchFailure;
137
170
  /**
138
171
  * Runtime-owned action result produced by framework-owned loading code.
139
172
  */
@@ -154,5 +187,5 @@ declare const runtimeLoadSkillActionResultSchema: z.ZodObject<{
154
187
  /**
155
188
  * Runtime-owned action result produced by framework-owned runtime code.
156
189
  */
157
- export type RuntimeActionResult = RuntimeLoadSkillActionResult | RuntimeSubagentResultActionResult | RuntimeToolResultActionResult;
190
+ export type RuntimeActionResult = RuntimeLoadSkillActionResult | RuntimeSubagentResult | RuntimeToolResultActionResult;
158
191
  export {};
@@ -1 +1 @@
1
- import{z}from"#compiled/zod/index.js";import{jsonObjectSchema,jsonValueSchema}from"#shared/json-schemas.js";import{tokenUsageSchema}from"#shared/token-usage.js";const runtimeToolCallActionRequestSchema=z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`tool-call`),toolName:z.string()}).strict(),runtimeSubagentCallActionRequestSchema=z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`subagent-call`),name:z.string(),nodeId:z.string(),subagentName:z.string()}).strict(),runtimeRemoteAgentCallActionRequestSchema=z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`remote-agent-call`),name:z.string(),nodeId:z.string(),remoteAgentName:z.string()}).strict(),runtimeLoadSkillActionRequestSchema=z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`load-skill`)}).strict(),runtimeActionRequestSchema=z.discriminatedUnion(`kind`,[runtimeLoadSkillActionRequestSchema,runtimeRemoteAgentCallActionRequestSchema,runtimeSubagentCallActionRequestSchema,runtimeToolCallActionRequestSchema]);z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`tool-result`),output:jsonValueSchema,toolName:z.string()}).strict(),z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`subagent-result`),output:jsonValueSchema,subagentName:z.string(),usage:tokenUsageSchema.optional()}).strict(),z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`load-skill-result`),output:jsonValueSchema,name:z.string().optional()}).strict();export{runtimeActionRequestSchema,runtimeRemoteAgentCallActionRequestSchema,runtimeToolCallActionRequestSchema};
1
+ import{z}from"#compiled/zod/index.js";import{jsonObjectSchema,jsonValueSchema}from"#shared/json-schemas.js";import{tokenUsageSchema}from"#shared/token-usage.js";const runtimeToolCallActionRequestSchema=z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`tool-call`),toolName:z.string()}).strict(),runtimeSubagentCallActionRequestSchema=z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`subagent-call`),name:z.string(),nodeId:z.string(),subagentName:z.string()}).strict(),runtimeRemoteAgentCallActionRequestSchema=z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`remote-agent-call`),name:z.string(),nodeId:z.string(),remoteAgentName:z.string()}).strict(),runtimeLoadSkillActionRequestSchema=z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`load-skill`)}).strict(),runtimeActionRequestSchema=z.discriminatedUnion(`kind`,[runtimeLoadSkillActionRequestSchema,runtimeRemoteAgentCallActionRequestSchema,runtimeSubagentCallActionRequestSchema,runtimeToolCallActionRequestSchema]);z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`tool-result`),output:jsonValueSchema,toolName:z.string()}).strict(),z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`subagent-result`),origin:z.literal(`child`),output:jsonValueSchema,subagentName:z.string(),usage:tokenUsageSchema.optional()}).strict(),z.object({callId:z.string(),isError:z.literal(!0),kind:z.literal(`subagent-result`),origin:z.literal(`dispatch`),output:jsonValueSchema,subagentName:z.string()}).strict(),z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`load-skill-result`),output:jsonValueSchema,name:z.string().optional()}).strict();export{runtimeActionRequestSchema,runtimeRemoteAgentCallActionRequestSchema,runtimeToolCallActionRequestSchema};
@@ -12,6 +12,10 @@ export declare const WEB_SEARCH_ANTHROPIC_OUTPUT_SCHEMA: JsonObject;
12
12
  * Output schema for Google's provider-managed `googleSearch` grounding tool.
13
13
  */
14
14
  export declare const WEB_SEARCH_GOOGLE_OUTPUT_SCHEMA: JsonObject;
15
+ /**
16
+ * Output schema for AI Gateway's provider-managed `exaSearch` tool.
17
+ */
18
+ export declare const WEB_SEARCH_EXA_OUTPUT_SCHEMA: JsonObject;
15
19
  /**
16
20
  * Output schema for AI Gateway's provider-managed `parallelSearch` tool.
17
21
  */
@@ -1 +1 @@
1
- const WEB_SEARCH_OPENAI_OUTPUT_SCHEMA={$schema:`http://json-schema.org/draft-07/schema#`,additionalProperties:!1,properties:{action:{oneOf:[{additionalProperties:!1,properties:{queries:{items:{type:`string`},type:`array`},query:{type:`string`},type:{const:`search`,type:`string`}},required:[`type`],type:`object`},{additionalProperties:!1,properties:{type:{const:`openPage`,type:`string`},url:{anyOf:[{type:`string`},{type:`null`}]}},required:[`type`],type:`object`},{additionalProperties:!1,properties:{pattern:{anyOf:[{type:`string`},{type:`null`}]},type:{const:`findInPage`,type:`string`},url:{anyOf:[{type:`string`},{type:`null`}]}},required:[`type`],type:`object`}]},sources:{items:{oneOf:[{additionalProperties:!1,properties:{type:{const:`url`,type:`string`},url:{type:`string`}},required:[`type`,`url`],type:`object`},{additionalProperties:!1,properties:{name:{type:`string`},type:{const:`api`,type:`string`}},required:[`type`,`name`],type:`object`}]},type:`array`}},type:`object`},WEB_SEARCH_ANTHROPIC_OUTPUT_SCHEMA={$schema:`http://json-schema.org/draft-07/schema#`,items:{additionalProperties:!1,properties:{encryptedContent:{type:`string`},pageAge:{anyOf:[{type:`string`},{type:`null`}]},title:{anyOf:[{type:`string`},{type:`null`}]},type:{const:`web_search_result`,type:`string`},url:{type:`string`}},required:[`url`,`title`,`pageAge`,`encryptedContent`,`type`],type:`object`},type:`array`},WEB_SEARCH_GOOGLE_OUTPUT_SCHEMA={$schema:`http://json-schema.org/draft-07/schema#`,additionalProperties:!1,properties:{},type:`object`},WEB_SEARCH_PARALLEL_OUTPUT_SCHEMA={$schema:`http://json-schema.org/draft-07/schema#`,anyOf:[{additionalProperties:!1,properties:{results:{items:{additionalProperties:!1,properties:{excerpt:{type:`string`},publishDate:{anyOf:[{type:`string`},{type:`null`}]},relevanceScore:{type:`number`},title:{type:`string`},url:{type:`string`}},required:[`url`,`title`,`excerpt`],type:`object`},type:`array`},searchId:{type:`string`}},required:[`searchId`,`results`],type:`object`},{additionalProperties:!1,properties:{error:{enum:[`api_error`,`rate_limit`,`timeout`,`invalid_input`,`configuration_error`,`unknown`],type:`string`},message:{type:`string`},statusCode:{type:`number`}},required:[`error`,`message`],type:`object`}]},WEB_SEARCH_TOOL_DEFINITION={description:`Search the web for real-time information. Use this to find up-to-date information about current events, recent developments, or topics that may have changed since the knowledge cutoff.`,inputSchema:null,logicalPath:`eve:framework/web-search`,name:`web_search`,sourceId:`eve:web-search-tool`,sourceKind:`module`};export{WEB_SEARCH_ANTHROPIC_OUTPUT_SCHEMA,WEB_SEARCH_GOOGLE_OUTPUT_SCHEMA,WEB_SEARCH_OPENAI_OUTPUT_SCHEMA,WEB_SEARCH_PARALLEL_OUTPUT_SCHEMA,WEB_SEARCH_TOOL_DEFINITION};
1
+ const WEB_SEARCH_OPENAI_OUTPUT_SCHEMA={$schema:`http://json-schema.org/draft-07/schema#`,additionalProperties:!1,properties:{action:{oneOf:[{additionalProperties:!1,properties:{queries:{items:{type:`string`},type:`array`},query:{type:`string`},type:{const:`search`,type:`string`}},required:[`type`],type:`object`},{additionalProperties:!1,properties:{type:{const:`openPage`,type:`string`},url:{anyOf:[{type:`string`},{type:`null`}]}},required:[`type`],type:`object`},{additionalProperties:!1,properties:{pattern:{anyOf:[{type:`string`},{type:`null`}]},type:{const:`findInPage`,type:`string`},url:{anyOf:[{type:`string`},{type:`null`}]}},required:[`type`],type:`object`}]},sources:{items:{oneOf:[{additionalProperties:!1,properties:{type:{const:`url`,type:`string`},url:{type:`string`}},required:[`type`,`url`],type:`object`},{additionalProperties:!1,properties:{name:{type:`string`},type:{const:`api`,type:`string`}},required:[`type`,`name`],type:`object`}]},type:`array`}},type:`object`},WEB_SEARCH_ANTHROPIC_OUTPUT_SCHEMA={$schema:`http://json-schema.org/draft-07/schema#`,items:{additionalProperties:!1,properties:{encryptedContent:{type:`string`},pageAge:{anyOf:[{type:`string`},{type:`null`}]},title:{anyOf:[{type:`string`},{type:`null`}]},type:{const:`web_search_result`,type:`string`},url:{type:`string`}},required:[`url`,`title`,`pageAge`,`encryptedContent`,`type`],type:`object`},type:`array`},WEB_SEARCH_GOOGLE_OUTPUT_SCHEMA={$schema:`http://json-schema.org/draft-07/schema#`,additionalProperties:!1,properties:{},type:`object`},WEB_SEARCH_EXA_OUTPUT_SCHEMA={$schema:`http://json-schema.org/draft-07/schema#`,anyOf:[{properties:{costDollars:{additionalProperties:!1,properties:{search:{additionalProperties:{type:`number`},type:`object`},total:{type:`number`}},type:`object`},requestId:{type:`string`},resolvedSearchType:{type:`string`},results:{items:{properties:{author:{anyOf:[{type:`string`},{type:`null`}]},entities:{items:{properties:{id:{type:`string`},properties:{type:`object`},type:{type:`string`},version:{type:`number`}},required:[`id`,`type`,`version`,`properties`],type:`object`},type:`array`},extras:{additionalProperties:!1,properties:{imageLinks:{items:{type:`string`},type:`array`},links:{items:{type:`string`},type:`array`}},type:`object`},favicon:{anyOf:[{type:`string`},{type:`null`}]},highlightScores:{items:{type:`number`},type:`array`},highlights:{items:{type:`string`},type:`array`},id:{type:`string`},image:{anyOf:[{type:`string`},{type:`null`}]},publishedDate:{anyOf:[{type:`string`},{type:`null`}]},score:{anyOf:[{type:`number`},{type:`null`}]},subpages:{items:{},type:`array`},summary:{type:`string`},text:{type:`string`},title:{anyOf:[{type:`string`},{type:`null`}]},url:{type:`string`}},required:[`url`,`id`],type:`object`},type:`array`},searchTime:{type:`number`},searchType:{type:`string`}},required:[`requestId`,`results`],type:`object`},{additionalProperties:!1,properties:{error:{enum:[`api_error`,`rate_limit`,`timeout`,`invalid_input`,`configuration_error`,`execution_error`,`unknown`],type:`string`},message:{type:`string`},statusCode:{type:`number`}},required:[`error`,`message`],type:`object`}]},WEB_SEARCH_PARALLEL_OUTPUT_SCHEMA={$schema:`http://json-schema.org/draft-07/schema#`,anyOf:[{additionalProperties:!1,properties:{results:{items:{additionalProperties:!1,properties:{excerpt:{type:`string`},publishDate:{anyOf:[{type:`string`},{type:`null`}]},relevanceScore:{type:`number`},title:{type:`string`},url:{type:`string`}},required:[`url`,`title`,`excerpt`],type:`object`},type:`array`},searchId:{type:`string`}},required:[`searchId`,`results`],type:`object`},{additionalProperties:!1,properties:{error:{enum:[`api_error`,`rate_limit`,`timeout`,`invalid_input`,`configuration_error`,`unknown`],type:`string`},message:{type:`string`},statusCode:{type:`number`}},required:[`error`,`message`],type:`object`}]},WEB_SEARCH_TOOL_DEFINITION={description:`Search the web for real-time information. Use this to find up-to-date information about current events, recent developments, or topics that may have changed since the knowledge cutoff.`,inputSchema:null,logicalPath:`eve:framework/web-search`,name:`web_search`,sourceId:`eve:web-search-tool`,sourceKind:`module`};export{WEB_SEARCH_ANTHROPIC_OUTPUT_SCHEMA,WEB_SEARCH_EXA_OUTPUT_SCHEMA,WEB_SEARCH_GOOGLE_OUTPUT_SCHEMA,WEB_SEARCH_OPENAI_OUTPUT_SCHEMA,WEB_SEARCH_PARALLEL_OUTPUT_SCHEMA,WEB_SEARCH_TOOL_DEFINITION};
@@ -1 +1 @@
1
- import{ResolveAgentError,createResolvedModuleSourceRef}from"#runtime/resolve-helpers.js";import{resolveDynamicToolDefinition}from"#runtime/resolve-dynamic-tool.js";import{resolveChannelDefinition}from"#runtime/resolve-channel.js";import{resolveConnectionDefinition}from"#runtime/resolve-connection.js";import{resolveHookDefinition}from"#runtime/resolve-hook.js";import{resolveSandboxDefinition}from"#runtime/resolve-sandbox.js";import{resolveDynamicInstructionsDefinition}from"#runtime/resolve-dynamic-instructions.js";import{resolveDynamicSkillDefinition}from"#runtime/resolve-dynamic-skill.js";import{resolveToolDefinition}from"#runtime/resolve-tool.js";async function resolveAgent(e){let t=e.manifest.skills.map(e=>({...e,metadata:e.metadata===void 0?void 0:{...e.metadata}})),r=[],i=[];for(let t of e.manifest.channels){if(t.kind===`disabled`){i.push(t.name);continue}r.push(await resolveChannelDefinition(t,e.moduleMap,e.nodeId))}let a=await Promise.all(e.manifest.tools.map(t=>resolveToolDefinition(t,e.moduleMap,e.nodeId))),o=await Promise.all((e.manifest.dynamicInstructions??[]).map(t=>resolveDynamicInstructionsDefinition(t,e.moduleMap,e.nodeId))),s=await Promise.all((e.manifest.dynamicSkills??[]).map(t=>resolveDynamicSkillDefinition(t,e.moduleMap,e.nodeId))),c=await Promise.all(e.manifest.dynamicTools.map(t=>resolveDynamicToolDefinition(t,e.moduleMap,e.nodeId))),l=await Promise.all(e.manifest.hooks.map(t=>resolveHookDefinition(t,e.moduleMap,e.nodeId))),u=await Promise.all(e.manifest.connections.map(t=>resolveConnectionDefinition(t,e.moduleMap,e.nodeId))),d=e.manifest.sandbox===null?null:await resolveSandboxDefinition(e.manifest.sandbox,e.moduleMap,e.nodeId),f=createResolvedInstructionsDefinition(e.manifest.instructions),p=e.manifest.workspaceResourceRoot,m={channels:r,config:createResolvedAgentConfig(e.manifest),connections:u,disabledFrameworkChannels:i,disabledFrameworkTools:[...e.manifest.disabledFrameworkTools],workflowTool:e.manifest.workflowTool===void 0?void 0:{maxSubagents:e.manifest.workflowTool.maxSubagents},dynamicInstructionsResolvers:o,dynamicSkillResolvers:s,dynamicToolResolvers:c,hooks:l,metadata:{agentRoot:e.manifest.agentRoot,appRoot:e.manifest.appRoot,diagnosticsSummary:e.manifest.diagnosticsSummary},sandbox:d,workspaceResourceRoot:p,skills:t,tools:a,workspaceSpec:{rootEntries:[...p.rootEntries]}};return f===void 0?m:{...m,instructions:f}}function createResolvedInstructionsDefinition(e){if(e!==void 0)return{name:e.name,logicalPath:e.logicalPath,markdown:e.markdown,sourceId:e.sourceId,sourceKind:e.sourceKind}}function createResolvedAgentConfig(e){let n={model:e.config.model.source===void 0?{id:e.config.model.id,contextWindowTokens:e.config.model.contextWindowTokens,providerOptions:e.config.model.providerOptions}:{contextWindowTokens:e.config.model.contextWindowTokens,id:e.config.model.id,providerOptions:e.config.model.providerOptions,source:{exportName:e.config.model.source.exportName,sourceKind:`module`,logicalPath:e.config.model.source.logicalPath,sourceId:e.config.model.source.sourceId}},name:e.config.name};if(e.config.compaction!==void 0){let t={};e.config.compaction.model!==void 0&&(t.model=e.config.compaction.model.source===void 0?{contextWindowTokens:e.config.compaction.model.contextWindowTokens,id:e.config.compaction.model.id,providerOptions:e.config.compaction.model.providerOptions}:{contextWindowTokens:e.config.compaction.model.contextWindowTokens,id:e.config.compaction.model.id,providerOptions:e.config.compaction.model.providerOptions,source:{exportName:e.config.compaction.model.source.exportName,sourceKind:`module`,logicalPath:e.config.compaction.model.source.logicalPath,sourceId:e.config.compaction.model.source.sourceId}}),e.config.compaction.thresholdPercent!==void 0&&(t.thresholdPercent=e.config.compaction.thresholdPercent),n.compaction=t}return e.config.dynamicModel!==void 0&&(n.dynamicModel={...createResolvedModuleSourceRef(e.config.dynamicModel),eventNames:[...e.config.dynamicModel.eventNames]}),e.config.experimental!==void 0&&(n.experimental={subagentPersistentSessions:e.config.experimental.subagentPersistentSessions,workflow:e.config.experimental.workflow===void 0?void 0:{world:e.config.experimental.workflow.world}}),e.config.outputSchema!==void 0&&(n.outputSchema=e.config.outputSchema),e.config.reasoning!==void 0&&(n.reasoning=e.config.reasoning),e.config.source!==void 0&&(n.source=createResolvedModuleSourceRef(e.config.source)),e.config.limits!==void 0&&(n.limits={maxInputTokensPerSession:e.config.limits.maxInputTokensPerSession,maxOutputTokensPerSession:e.config.limits.maxOutputTokensPerSession,sessionTimeoutMs:e.config.limits.sessionTimeoutMs}),n}export{ResolveAgentError,resolveAgent};
1
+ import{ResolveAgentError,createResolvedModuleSourceRef}from"#runtime/resolve-helpers.js";import{resolveDynamicToolDefinition}from"#runtime/resolve-dynamic-tool.js";import{resolveChannelDefinition}from"#runtime/resolve-channel.js";import{resolveConnectionDefinition}from"#runtime/resolve-connection.js";import{resolveHookDefinition}from"#runtime/resolve-hook.js";import{resolveSandboxDefinition}from"#runtime/resolve-sandbox.js";import{resolveDynamicInstructionsDefinition}from"#runtime/resolve-dynamic-instructions.js";import{resolveDynamicSkillDefinition}from"#runtime/resolve-dynamic-skill.js";import{resolveToolDefinition}from"#runtime/resolve-tool.js";async function resolveAgent(e){let t=e.manifest.skills.map(e=>({...e,metadata:e.metadata===void 0?void 0:{...e.metadata}})),r=[],i=[];for(let t of e.manifest.channels){if(t.kind===`disabled`){i.push(t.name);continue}r.push(await resolveChannelDefinition(t,e.moduleMap,e.nodeId))}let a=await Promise.all(e.manifest.tools.map(t=>resolveToolDefinition(t,e.moduleMap,e.nodeId))),o=await Promise.all((e.manifest.dynamicInstructions??[]).map(t=>resolveDynamicInstructionsDefinition(t,e.moduleMap,e.nodeId))),s=await Promise.all((e.manifest.dynamicSkills??[]).map(t=>resolveDynamicSkillDefinition(t,e.moduleMap,e.nodeId))),c=await Promise.all(e.manifest.dynamicTools.map(t=>resolveDynamicToolDefinition(t,e.moduleMap,e.nodeId))),l=await Promise.all(e.manifest.hooks.map(t=>resolveHookDefinition(t,e.moduleMap,e.nodeId))),u=await Promise.all(e.manifest.connections.map(t=>resolveConnectionDefinition(t,e.moduleMap,e.nodeId))),d=e.manifest.sandbox===null?null:await resolveSandboxDefinition(e.manifest.sandbox,e.moduleMap,e.nodeId),f=createResolvedInstructionsDefinition(e.manifest.instructions),p=e.manifest.workspaceResourceRoot,m={channels:r,config:createResolvedAgentConfig(e.manifest),connections:u,disabledFrameworkChannels:i,disabledFrameworkTools:[...e.manifest.disabledFrameworkTools],workflowTool:e.manifest.workflowTool===void 0?void 0:{maxSubagents:e.manifest.workflowTool.maxSubagents},webSearchProvider:e.manifest.webSearchProvider,dynamicInstructionsResolvers:o,dynamicSkillResolvers:s,dynamicToolResolvers:c,hooks:l,metadata:{agentRoot:e.manifest.agentRoot,appRoot:e.manifest.appRoot,diagnosticsSummary:e.manifest.diagnosticsSummary},sandbox:d,workspaceResourceRoot:p,skills:t,tools:a,workspaceSpec:{rootEntries:[...p.rootEntries]}};return f===void 0?m:{...m,instructions:f}}function createResolvedInstructionsDefinition(e){if(e!==void 0)return{name:e.name,logicalPath:e.logicalPath,markdown:e.markdown,sourceId:e.sourceId,sourceKind:e.sourceKind}}function createResolvedAgentConfig(e){let n={model:e.config.model.source===void 0?{id:e.config.model.id,contextWindowTokens:e.config.model.contextWindowTokens,providerOptions:e.config.model.providerOptions}:{contextWindowTokens:e.config.model.contextWindowTokens,id:e.config.model.id,providerOptions:e.config.model.providerOptions,source:{exportName:e.config.model.source.exportName,sourceKind:`module`,logicalPath:e.config.model.source.logicalPath,sourceId:e.config.model.source.sourceId}},name:e.config.name};if(e.config.compaction!==void 0){let t={};e.config.compaction.model!==void 0&&(t.model=e.config.compaction.model.source===void 0?{contextWindowTokens:e.config.compaction.model.contextWindowTokens,id:e.config.compaction.model.id,providerOptions:e.config.compaction.model.providerOptions}:{contextWindowTokens:e.config.compaction.model.contextWindowTokens,id:e.config.compaction.model.id,providerOptions:e.config.compaction.model.providerOptions,source:{exportName:e.config.compaction.model.source.exportName,sourceKind:`module`,logicalPath:e.config.compaction.model.source.logicalPath,sourceId:e.config.compaction.model.source.sourceId}}),e.config.compaction.thresholdPercent!==void 0&&(t.thresholdPercent=e.config.compaction.thresholdPercent),n.compaction=t}return e.config.dynamicModel!==void 0&&(n.dynamicModel={...createResolvedModuleSourceRef(e.config.dynamicModel),eventNames:[...e.config.dynamicModel.eventNames]}),e.config.experimental!==void 0&&(n.experimental={subagentPersistentSessions:e.config.experimental.subagentPersistentSessions,workflow:e.config.experimental.workflow===void 0?void 0:{world:e.config.experimental.workflow.world}}),e.config.outputSchema!==void 0&&(n.outputSchema=e.config.outputSchema),e.config.reasoning!==void 0&&(n.reasoning=e.config.reasoning),e.config.source!==void 0&&(n.source=createResolvedModuleSourceRef(e.config.source)),e.config.limits!==void 0&&(n.limits={maxInputTokensPerSession:e.config.limits.maxInputTokensPerSession,maxOutputTokensPerSession:e.config.limits.maxOutputTokensPerSession,sessionTimeoutMs:e.config.limits.sessionTimeoutMs}),n}export{ResolveAgentError,resolveAgent};
@@ -1 +1 @@
1
- import{EVE_CALLBACK_ROUTE_PATTERN}from"#protocol/routes.js";import{resumeHook}from"#internal/workflow/runtime.js";import{tokenUsageSchema}from"#shared/token-usage.js";const HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX=`eve/v1/callback`,HANDLED_METHODS=[`POST`];function getSessionCallbackChannelDefinitions(){return HANDLED_METHODS.map(e=>buildCallbackChannelDefinition(e))}function getSessionCallbackChannelNames(){return new Set(HANDLED_METHODS.map(channelNameForMethod))}function buildCallbackChannelDefinition(t){let n=channelNameForMethod(t);return{name:n,method:t,urlPath:EVE_CALLBACK_ROUTE_PATTERN,fetch:handleSessionCallbackRequest,logicalPath:`framework://channels/${n}`,sourceId:`eve:framework:session-callback-${t.toLowerCase()}`,sourceKind:`module`}}function channelNameForMethod(e){return`${HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX}/${e.toLowerCase()}`}async function handleSessionCallbackRequest(e,n){let r=n.params.token;if(typeof r!=`string`||r.length===0)return Response.json({error:`Missing callback token.`,ok:!1},{status:400});let i;try{i=await e.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}let a=projectSessionCallbackResult(i);if(a instanceof Response)return a;try{await resumeHook(r,{kind:`runtime-action-result`,results:[a]})}catch{return Response.json({error:`Session callback not pending.`,ok:!1},{status:404})}return Response.json({ok:!0},{status:202})}function projectSessionCallbackResult(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let t=e;if(typeof t.callId!=`string`||t.callId.length===0)return Response.json({error:`Missing callback callId.`,ok:!1},{status:400});if(typeof t.subagentName!=`string`||t.subagentName.length===0)return Response.json({error:`Missing callback subagentName.`,ok:!1},{status:400});if(t.kind===`session.completed`){let e={callId:t.callId,kind:`subagent-result`,output:t.output??``,subagentName:t.subagentName},n=parseCallbackUsage(t.usage);return n===void 0?e:{...e,usage:n}}return t.kind===`session.failed`?{callId:t.callId,isError:!0,kind:`subagent-result`,output:t.error===void 0?{code:`REMOTE_AGENT_FAILED`,message:`Remote agent failed.`}:t.error,subagentName:t.subagentName}:Response.json({error:`Unsupported callback kind.`,ok:!1},{status:400})}function parseCallbackUsage(e){if(e===void 0)return;let t=tokenUsageSchema.safeParse(e);return t.success?t.data:void 0}export{HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX,getSessionCallbackChannelDefinitions,getSessionCallbackChannelNames,handleSessionCallbackRequest};
1
+ import{EVE_CALLBACK_ROUTE_PATTERN}from"#protocol/routes.js";import{resumeHook}from"#internal/workflow/runtime.js";import{REMOTE_AGENT_FAILED}from"#harness/agent-handle-errors.js";import{tokenUsageSchema}from"#shared/token-usage.js";const HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX=`eve/v1/callback`,HANDLED_METHODS=[`POST`];function getSessionCallbackChannelDefinitions(){return HANDLED_METHODS.map(e=>buildCallbackChannelDefinition(e))}function getSessionCallbackChannelNames(){return new Set(HANDLED_METHODS.map(channelNameForMethod))}function buildCallbackChannelDefinition(t){let n=channelNameForMethod(t);return{name:n,method:t,urlPath:EVE_CALLBACK_ROUTE_PATTERN,fetch:handleSessionCallbackRequest,logicalPath:`framework://channels/${n}`,sourceId:`eve:framework:session-callback-${t.toLowerCase()}`,sourceKind:`module`}}function channelNameForMethod(e){return`${HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX}/${e.toLowerCase()}`}async function handleSessionCallbackRequest(e,n){let r=n.params.token;if(typeof r!=`string`||r.length===0)return Response.json({error:`Missing callback token.`,ok:!1},{status:400});let i;try{i=await e.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}let a=projectSessionCallbackResult(i);if(a instanceof Response)return a;try{await resumeHook(r,{kind:`runtime-action-result`,results:[a]})}catch{return Response.json({error:`Session callback not pending.`,ok:!1},{status:404})}return Response.json({ok:!0},{status:202})}function projectSessionCallbackResult(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let t=e;if(typeof t.callId!=`string`||t.callId.length===0)return Response.json({error:`Missing callback callId.`,ok:!1},{status:400});if(typeof t.subagentName!=`string`||t.subagentName.length===0)return Response.json({error:`Missing callback subagentName.`,ok:!1},{status:400});if(t.kind===`session.completed`||t.kind===`turn.completed`){let e={callId:t.callId,kind:`subagent-result`,origin:`child`,output:t.output??``,subagentName:t.subagentName},n=parseCallbackUsage(t.usage);return n===void 0?e:{...e,usage:n}}return t.kind===`session.failed`?{callId:t.callId,isError:!0,kind:`subagent-result`,origin:`child`,output:t.error===void 0?{code:REMOTE_AGENT_FAILED,message:`Remote agent failed.`}:t.error,subagentName:t.subagentName}:t.kind===`turn.failed`?t.error===void 0?Response.json({error:`Missing callback error.`,ok:!1},{status:400}):{callId:t.callId,isError:!0,kind:`subagent-result`,origin:`child`,output:t.error,subagentName:t.subagentName}:Response.json({error:`Unsupported callback kind.`,ok:!1},{status:400})}function parseCallbackUsage(e){if(e===void 0)return;let t=tokenUsageSchema.safeParse(e);return t.success?t.data:void 0}export{HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX,getSessionCallbackChannelDefinitions,getSessionCallbackChannelNames,handleSessionCallbackRequest};
@@ -22,6 +22,7 @@ import type { NamedSkillDefinition } from "#shared/skill-definition.js";
22
22
  import type { InternalAgentDefinition } from "#shared/agent-definition.js";
23
23
  import type { RuntimeDynamicModelReference } from "#runtime/agent/bootstrap.js";
24
24
  import type { InternalToolDefinitionWithExecuteFn } from "#shared/tool-definition.js";
25
+ import type { WebSearchProvider } from "#shared/web-search.js";
25
26
  import type { SandboxBackend } from "#shared/sandbox-backend.js";
26
27
  import type { SandboxBootstrapContext, SandboxSessionContext } from "#shared/sandbox-definition.js";
27
28
  import type { ToolSchema } from "#shared/tool-schema.js";
@@ -347,6 +348,8 @@ export interface ResolvedAgent {
347
348
  readonly workflowTool?: {
348
349
  readonly maxSubagents?: number;
349
350
  };
351
+ /** AI Gateway provider selected for the framework `web_search` tool. */
352
+ readonly webSearchProvider?: WebSearchProvider;
350
353
  readonly dynamicInstructionsResolvers: readonly ResolvedDynamicInstructionsResolver[];
351
354
  readonly dynamicSkillResolvers: readonly ResolvedDynamicSkillResolver[];
352
355
  readonly dynamicToolResolvers: readonly ResolvedDynamicToolResolver[];
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.38`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.3`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.30.0`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
1
+ import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.38`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.3`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.30.2`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
2
2
 
3
3
  export default defineAgent({
4
4
  model: "__EVE_INIT_MODEL__",
@@ -0,0 +1,2 @@
1
+ /** Web search providers available through Vercel AI Gateway. */
2
+ export type WebSearchProvider = "exa" | "parallel";
@@ -0,0 +1 @@
1
+ export{};
@@ -52,7 +52,7 @@ Notes:
52
52
  - **`agent`** is available only in the root session. Its child uses the root's instructions, tools, connections, and sandbox, but starts with fresh conversation history and fresh [state](../guides/state). The child receives neither `agent` nor `Workflow`; declared subagents do not receive the built-in `agent` either. See [Subagents](../subagents).
53
53
  - **`load_skill`** only pulls instructions into context. It adds no new execution surface, because behavior still comes from the tools the agent already has.
54
54
  - **`connection_search`** surfaces a connection's tools by their qualified name (e.g. `linear__list_issues`), which the model can then call directly. It's registered only when the agent has connections.
55
- - **`web_search`** has no local executor; the provider runs it. To supply your own implementation, override it with `defineTool()`.
55
+ - **`web_search`** has no local executor; the provider runs it. AI Gateway models use Parallel by default. To use Exa instead, export `webSearch({ provider: "exa" })` from `agent/tools/web_search.ts`. Direct provider models continue to use their native search implementation. To supply your own implementation, override it with `defineTool()`.
56
56
 
57
57
  Review these built-in tools before production use. Disable, wrap, restrict, or require approval for any tool that can access the filesystem, network, shell, or sensitive data.
58
58
 
@@ -73,7 +73,17 @@ export default defineTool({
73
73
  });
74
74
  ```
75
75
 
76
- The framework defaults are importable from `eve/tools/defaults` (`bash`, `readFile`, `writeFile`, `glob`, `grep`, `webFetch`, `webSearch`, `todo`, `loadSkill`), so you can spread, wrap, or patch them. Skip the spread and your replacement owns its own context. A fresh `defineTool` for `todo` won't inherit the framework's durable state key.
76
+ The framework defaults are importable from `eve/tools/defaults` (`bash`, `readFile`, `writeFile`, `glob`, `grep`, `webFetch`, `todo`, `loadSkill`), so you can spread, wrap, or patch them. Skip the spread and your replacement owns its own context. A fresh `defineTool` for `todo` won't inherit the framework's durable state key.
77
+
78
+ Provider-managed web search has a dedicated configuration helper instead of an executable default:
79
+
80
+ ```ts title="agent/tools/web_search.ts"
81
+ import { webSearch } from "eve/tools";
82
+
83
+ export default webSearch({ provider: "exa" });
84
+ ```
85
+
86
+ Set `provider` to `"parallel"` or `"exa"`. Without this file, AI Gateway models use Parallel.
77
87
 
78
88
  ## Disable a default
79
89
 
@@ -52,7 +52,7 @@ export default defineTool({
52
52
  | `mockModel` | `eve/evals` | Deterministic fixture agent models | [Evals](../evals/overview) |
53
53
  | `useEveAgent` | `eve/react`, `eve/vue`, `eve/svelte` | frontend | [Frontend](../guides/frontend/overview) |
54
54
 
55
- A few non-`define*` helpers round out the set: `disableTool` and `experimental_workflow` from `eve/tools` (see [Default harness](../concepts/default-harness)), `sleep` from `eve/tools/sleep`, the route verbs `GET`/`POST`/`PUT`/`PATCH`/`DELETE`/`WS` from `eve/channels`, the approval policies `always`/`once`/`never` from `eve/tools/approval`, and the channel auth helpers `localDev`/`vercelOidc`/`placeholderAuth` from `eve/channels/auth`. To wrap a built-in tool, import its default value from `eve/tools/defaults` (`bash`, `readFile`, `writeFile`, `glob`, `grep`, `webFetch`, `webSearch`, `todo`, `loadSkill`). `AgentReasoningDefinition` is exported from `eve` for the top-level `defineAgent({ reasoning })` setting. `AgentLimitsDefinition` is exported for `defineAgent({ limits })`. `AgentWorkflowDefinition` and `AgentWorkflowWorldDefinition` are exported from `eve` for the `defineAgent({ experimental: { workflow } })` config shape. `ExperimentalWorkflowToolInput` is exported from `eve/tools` for the `experimental_workflow(...)` config shape.
55
+ A few non-`define*` helpers round out the set: `disableTool`, `experimental_workflow`, and `webSearch` from `eve/tools` (see [Default harness](../concepts/default-harness)), `sleep` from `eve/tools/sleep`, the route verbs `GET`/`POST`/`PUT`/`PATCH`/`DELETE`/`WS` from `eve/channels`, the approval policies `always`/`once`/`never` from `eve/tools/approval`, and the channel auth helpers `localDev`/`vercelOidc`/`placeholderAuth` from `eve/channels/auth`. To wrap a built-in tool, import its default value from `eve/tools/defaults` (`bash`, `readFile`, `writeFile`, `glob`, `grep`, `webFetch`, `todo`, `loadSkill`). `AgentReasoningDefinition` is exported from `eve` for the top-level `defineAgent({ reasoning })` setting. `AgentLimitsDefinition` is exported for `defineAgent({ limits })`. `AgentWorkflowDefinition` and `AgentWorkflowWorldDefinition` are exported from `eve` for the `defineAgent({ experimental: { workflow } })` config shape. `ExperimentalWorkflowToolInput`, `WebSearchToolInput`, and `WebSearchProvider` are exported from `eve/tools` for their corresponding tool configuration helpers.
56
56
 
57
57
  ## Runtime context (`ctx`)
58
58
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve",
3
- "version": "0.30.0",
3
+ "version": "0.30.2",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [