eve 0.15.1 → 0.15.3

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 (50) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/src/execution/deliver-payloads.d.ts +3 -0
  3. package/dist/src/execution/deliver-payloads.js +1 -0
  4. package/dist/src/execution/dispatch-runtime-actions-step.d.ts +2 -0
  5. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  6. package/dist/src/execution/dispatch-workflow-runtime-actions-step.d.ts +1 -0
  7. package/dist/src/execution/dispatch-workflow-runtime-actions-step.js +1 -1
  8. package/dist/src/execution/durable-session-migrations/turn-workflow.d.ts +7 -0
  9. package/dist/src/execution/durable-session-migrations/turn-workflow.js +1 -1
  10. package/dist/src/execution/forward-turn-delivery-step.d.ts +6 -0
  11. package/dist/src/execution/forward-turn-delivery-step.js +1 -0
  12. package/dist/src/execution/hook-ownership.d.ts +6 -0
  13. package/dist/src/execution/hook-ownership.js +1 -1
  14. package/dist/src/execution/remote-agent-dispatch.d.ts +1 -0
  15. package/dist/src/execution/remote-agent-dispatch.js +1 -1
  16. package/dist/src/execution/route-child-delivery.d.ts +18 -0
  17. package/dist/src/execution/route-child-delivery.js +1 -0
  18. package/dist/src/execution/session-delivery-hook.d.ts +20 -0
  19. package/dist/src/execution/session-delivery-hook.js +1 -0
  20. package/dist/src/execution/subagent-tool.d.ts +2 -0
  21. package/dist/src/execution/subagent-tool.js +1 -1
  22. package/dist/src/execution/turn-control-protocol.d.ts +36 -0
  23. package/dist/src/execution/turn-control-protocol.js +1 -0
  24. package/dist/src/execution/turn-control-receiver.d.ts +35 -0
  25. package/dist/src/execution/turn-control-receiver.js +1 -0
  26. package/dist/src/execution/turn-dispatch.d.ts +17 -0
  27. package/dist/src/execution/turn-dispatch.js +1 -0
  28. package/dist/src/execution/turn-execution-cursor.d.ts +48 -0
  29. package/dist/src/execution/turn-execution-cursor.js +1 -0
  30. package/dist/src/execution/turn-workflow.d.ts +1 -27
  31. package/dist/src/execution/turn-workflow.js +1 -1
  32. package/dist/src/execution/workflow-entry.d.ts +6 -4
  33. package/dist/src/execution/workflow-entry.js +1 -1
  34. package/dist/src/execution/workflow-steps.js +1 -1
  35. package/dist/src/harness/provider-tool-history.d.ts +18 -0
  36. package/dist/src/harness/provider-tool-history.js +1 -0
  37. package/dist/src/harness/runtime-actions.d.ts +4 -22
  38. package/dist/src/harness/runtime-actions.js +1 -1
  39. package/dist/src/harness/tool-loop.js +1 -1
  40. package/dist/src/internal/application/package.js +1 -1
  41. package/dist/src/internal/workflow-bundle/workflow-builders.js +1 -1
  42. package/dist/src/setup/scaffold/create/project.js +1 -1
  43. package/docs/connections/overview.mdx +11 -11
  44. package/docs/meta.json +1 -0
  45. package/docs/patterns/dynamic-scheduling.md +257 -0
  46. package/docs/patterns/meta.json +9 -0
  47. package/docs/patterns/multi-tenant-approvals.md +191 -0
  48. package/docs/patterns/multi-tenant-auth.md +177 -0
  49. package/docs/patterns/multi-tenant-memory.md +188 -0
  50. package/package.json +1 -1
@@ -61,29 +61,11 @@ export declare function recordPendingSubagentChildToken(input: {
61
61
  readonly childContinuationToken: string;
62
62
  readonly session: HarnessSession;
63
63
  }): HarnessSession;
64
- /**
65
- * Discriminated item consumed by {@link accumulateRuntimeActionResults}
66
- * so the loop can process interleaved deliveries and results without
67
- * coupling to a concrete `HookPayload` shape.
68
- */
69
- type RuntimeActionAccumulatorItem<TDeliver> = {
70
- readonly kind: "deliver";
71
- readonly value: TDeliver;
72
- } | {
73
- readonly kind: "runtime-action-result";
64
+ /** Returns results in pending-key order once every requested action has completed. */
65
+ export declare function resolveRuntimeActionResultsForKeys(input: {
66
+ readonly pendingKeys: readonly string[];
74
67
  readonly results: readonly RuntimeActionResult[];
75
- };
76
- /**
77
- * Accumulates runtime-action results until every pending key has a
78
- * matching result. The caller passes the ordered key list so the
79
- * workflow runtime can drive the loop without hydrating a session.
80
- */
81
- export declare function accumulateRuntimeActionResults<TDeliver>(input: {
82
- readonly bufferedDeliveries: TDeliver[];
83
- readonly getNext: () => Promise<RuntimeActionAccumulatorItem<TDeliver> | null>;
84
- readonly initialResults?: readonly RuntimeActionResult[];
85
- readonly pendingActionKeys: readonly string[] | undefined;
86
- }): Promise<RuntimeActionResult[] | null>;
68
+ }): RuntimeActionResult[] | undefined;
87
69
  /**
88
70
  * Resolves one pending runtime-action batch back into model history.
89
71
  *
@@ -1 +1 @@
1
- import{createActionResultEvent}from"#protocol/message.js";import{parseJsonObject}from"#shared/json.js";import{clearProxyInputRequestsForChild}from"#harness/proxy-input-requests.js";import{getRuntimeActionRequestKey,getRuntimeActionResultKey}from"#runtime/actions/keys.js";const PENDING_RUNTIME_ACTION_BATCH_KEY=`eve.runtime.pendingActionBatch`;function getPendingRuntimeActionBatch(e){let t=e?.[PENDING_RUNTIME_ACTION_BATCH_KEY];if(typeof t!=`object`||!t)return;let n=t;if(!(!Array.isArray(n.actions)||!Array.isArray(n.responseMessages)||typeof n.event!=`object`||n.event===null))return n}function hasPendingRuntimeActionBatch(e){return getPendingRuntimeActionBatch(e)!==void 0}function clearPendingRuntimeActionBatch(e){if(e.state?.[PENDING_RUNTIME_ACTION_BATCH_KEY]===void 0)return e;let t={...e.state};return delete t[PENDING_RUNTIME_ACTION_BATCH_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function setPendingRuntimeActionBatch(e){let t={...e.session.state};return t[PENDING_RUNTIME_ACTION_BATCH_KEY]={actions:[...e.actions],event:e.event,responseMessages:[...e.responseMessages]},{...e.session,state:t}}function recordPendingSubagentChildToken(e){let t=getPendingRuntimeActionBatch(e.session.state);if(t===void 0)return e.session;let n={...e.session.state};return n[PENDING_RUNTIME_ACTION_BATCH_KEY]={...t,childContinuationTokens:{...t.childContinuationTokens,[e.callId]:e.childContinuationToken}},{...e.session,state:n}}async function accumulateRuntimeActionResults(e){let t=e.pendingActionKeys,n=[...e.initialResults??[]];if(t!==void 0&&n.length>0){let e=resolveRuntimeActionResultsForKeys({pendingKeys:t,results:n});if(e!==void 0)return e}for(;;){let r=await e.getNext();if(r===null)return null;if(r.kind===`deliver`){e.bufferedDeliveries.push(r.value);continue}if(n.push(...r.results),t===void 0)continue;let i=resolveRuntimeActionResultsForKeys({pendingKeys:t,results:n});if(i!==void 0)return i}}function resolveReadyRuntimeActionResults(e){let t=getPendingRuntimeActionBatch(e.session.state);if(t!==void 0)return resolveRuntimeActionResultsForBatch({batch:t,results:e.results})}function resolveRuntimeActionResultsForBatch(e){return resolveRuntimeActionResultsForKeys({pendingKeys:e.batch.actions.map(e=>getRuntimeActionRequestKey(e)),results:e.results})}function resolveRuntimeActionResultsForKeys(e){let t=new Set(e.pendingKeys),n=new Map;for(let r of e.results){let e=getRuntimeActionResultKey(r);t.has(e)&&n.set(e,r)}let r=[];for(let t of e.pendingKeys){let e=n.get(t);if(e===void 0)return;r.push(e)}return r}async function resolvePendingRuntimeActions(t){let r=getPendingRuntimeActionBatch(t.session.state);if(r===void 0)return{messages:[...t.session.history],outcome:`continue`,session:t.session};let i=resolveReadyRuntimeActionResults({results:t.stepInput?.runtimeActionResults??[],session:t.session});if(i===void 0)return{messages:[...t.session.history],outcome:`unresolved`,session:t.session};if(t.emit!==void 0)for(let n of i)n.kind===`subagent-result`&&n.isError!==!0&&await t.emit({data:{callId:n.callId,output:typeof n.output==`string`?n.output:JSON.stringify(n.output),subagentName:n.subagentName},type:`subagent.completed`}),await t.emit(createActionResultEvent({result:n,sequence:r.event.sequence,stepIndex:r.event.stepIndex,turnId:r.event.turnId}));let a={...t.session.state};delete a[PENDING_RUNTIME_ACTION_BATCH_KEY];let o={...t.session,state:Object.keys(a).length>0?a:void 0},s=r.childContinuationTokens;if(s!==void 0)for(let e of i){if(e.kind!==`subagent-result`)continue;let t=s[e.callId];t!==void 0&&(o=clearProxyInputRequestsForChild(o,t))}let c=i.map(e=>{switch(e.kind){case`load-skill-result`:return{output:toToolResultOutput(e),toolCallId:e.callId,toolName:`load_skill`,type:`tool-result`};case`subagent-result`:return{output:toToolResultOutput(e),toolCallId:e.callId,toolName:e.subagentName,type:`tool-result`};case`tool-result`:return{output:toToolResultOutput(e),toolCallId:e.callId,toolName:e.toolName,type:`tool-result`}}throw Error(`Unsupported runtime action result kind "${String(e)}".`)}),l=[...o.history,...r.responseMessages];return c.length>0&&l.push({content:c,role:`tool`}),{messages:l,outcome:`resolved`,session:o}}function createRuntimeActionRequestFromToolCall(e){let t=e.tools.get(e.toolCall.toolName);return t?.runtimeAction?.kind===`subagent-call`?{callId:e.toolCall.toolCallId,description:t.description,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`subagent-call`,name:t.name,nodeId:t.runtimeAction.nodeId,subagentName:t.runtimeAction.subagentName}:t?.runtimeAction?.kind===`remote-agent-call`?{callId:e.toolCall.toolCallId,description:t.description,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`remote-agent-call`,name:t.name,nodeId:t.runtimeAction.nodeId,remoteAgentName:t.runtimeAction.remoteAgentName??t.name}:{callId:e.toolCall.toolCallId,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`tool-call`,toolName:e.toolCall.toolName}}function resolveToolCallInputObject(e,n){if(e==null)return{};try{return parseJsonObject(e)}catch(e){let t=e instanceof Error?e.message:String(e);throw TypeError(`Failed to parse tool-call arguments for "${n.toolName}" (${n.callId}): ${t}`,{cause:e})}}function toToolResultOutput(e){return typeof e.output==`string`?e.isError===!0?{type:`error-text`,value:e.output}:{type:`text`,value:e.output}:e.isError===!0?{type:`error-json`,value:toMutableJsonValue(e.output)}:{type:`json`,value:toMutableJsonValue(e.output)}}function toMutableJsonValue(e){if(e===null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`)return e;if(Array.isArray(e))return e.map(e=>toMutableJsonValue(e));let t={};for(let[n,r]of Object.entries(e))t[n]=toMutableJsonValue(r);return t}export{accumulateRuntimeActionResults,clearPendingRuntimeActionBatch,createRuntimeActionRequestFromToolCall,getPendingRuntimeActionBatch,hasPendingRuntimeActionBatch,recordPendingSubagentChildToken,resolvePendingRuntimeActions,resolveToolCallInputObject,setPendingRuntimeActionBatch};
1
+ import{createActionResultEvent}from"#protocol/message.js";import{parseJsonObject}from"#shared/json.js";import{clearProxyInputRequestsForChild}from"#harness/proxy-input-requests.js";import{getRuntimeActionRequestKey,getRuntimeActionResultKey}from"#runtime/actions/keys.js";const PENDING_RUNTIME_ACTION_BATCH_KEY=`eve.runtime.pendingActionBatch`;function getPendingRuntimeActionBatch(e){let t=e?.[PENDING_RUNTIME_ACTION_BATCH_KEY];if(typeof t!=`object`||!t)return;let n=t;if(!(!Array.isArray(n.actions)||!Array.isArray(n.responseMessages)||typeof n.event!=`object`||n.event===null))return n}function hasPendingRuntimeActionBatch(e){return getPendingRuntimeActionBatch(e)!==void 0}function clearPendingRuntimeActionBatch(e){if(e.state?.[PENDING_RUNTIME_ACTION_BATCH_KEY]===void 0)return e;let t={...e.state};return delete t[PENDING_RUNTIME_ACTION_BATCH_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function setPendingRuntimeActionBatch(e){let t={...e.session.state};return t[PENDING_RUNTIME_ACTION_BATCH_KEY]={actions:[...e.actions],event:e.event,responseMessages:[...e.responseMessages]},{...e.session,state:t}}function recordPendingSubagentChildToken(e){let t=getPendingRuntimeActionBatch(e.session.state);if(t===void 0)return e.session;let n={...e.session.state};return n[PENDING_RUNTIME_ACTION_BATCH_KEY]={...t,childContinuationTokens:{...t.childContinuationTokens,[e.callId]:e.childContinuationToken}},{...e.session,state:n}}function resolveReadyRuntimeActionResults(e){let t=getPendingRuntimeActionBatch(e.session.state);if(t!==void 0)return resolveRuntimeActionResultsForBatch({batch:t,results:e.results})}function resolveRuntimeActionResultsForBatch(e){return resolveRuntimeActionResultsForKeys({pendingKeys:e.batch.actions.map(e=>getRuntimeActionRequestKey(e)),results:e.results})}function resolveRuntimeActionResultsForKeys(e){let t=new Set(e.pendingKeys),n=new Map;for(let r of e.results){let e=getRuntimeActionResultKey(r);t.has(e)&&n.set(e,r)}let r=[];for(let t of e.pendingKeys){let e=n.get(t);if(e===void 0)return;r.push(e)}return r}async function resolvePendingRuntimeActions(t){let r=getPendingRuntimeActionBatch(t.session.state);if(r===void 0)return{messages:[...t.session.history],outcome:`continue`,session:t.session};let i=resolveReadyRuntimeActionResults({results:t.stepInput?.runtimeActionResults??[],session:t.session});if(i===void 0)return{messages:[...t.session.history],outcome:`unresolved`,session:t.session};if(t.emit!==void 0)for(let n of i)n.kind===`subagent-result`&&n.isError!==!0&&await t.emit({data:{callId:n.callId,output:typeof n.output==`string`?n.output:JSON.stringify(n.output),subagentName:n.subagentName},type:`subagent.completed`}),await t.emit(createActionResultEvent({result:n,sequence:r.event.sequence,stepIndex:r.event.stepIndex,turnId:r.event.turnId}));let a={...t.session.state};delete a[PENDING_RUNTIME_ACTION_BATCH_KEY];let o={...t.session,state:Object.keys(a).length>0?a:void 0},s=r.childContinuationTokens;if(s!==void 0)for(let e of i){if(e.kind!==`subagent-result`)continue;let t=s[e.callId];t!==void 0&&(o=clearProxyInputRequestsForChild(o,t))}let c=i.map(e=>{switch(e.kind){case`load-skill-result`:return{output:toToolResultOutput(e),toolCallId:e.callId,toolName:`load_skill`,type:`tool-result`};case`subagent-result`:return{output:toToolResultOutput(e),toolCallId:e.callId,toolName:e.subagentName,type:`tool-result`};case`tool-result`:return{output:toToolResultOutput(e),toolCallId:e.callId,toolName:e.toolName,type:`tool-result`}}throw Error(`Unsupported runtime action result kind "${String(e)}".`)}),l=[...o.history,...r.responseMessages];return c.length>0&&l.push({content:c,role:`tool`}),{messages:l,outcome:`resolved`,session:o}}function createRuntimeActionRequestFromToolCall(e){let t=e.tools.get(e.toolCall.toolName);return t?.runtimeAction?.kind===`subagent-call`?{callId:e.toolCall.toolCallId,description:t.description,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`subagent-call`,name:t.name,nodeId:t.runtimeAction.nodeId,subagentName:t.runtimeAction.subagentName}:t?.runtimeAction?.kind===`remote-agent-call`?{callId:e.toolCall.toolCallId,description:t.description,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`remote-agent-call`,name:t.name,nodeId:t.runtimeAction.nodeId,remoteAgentName:t.runtimeAction.remoteAgentName??t.name}:{callId:e.toolCall.toolCallId,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`tool-call`,toolName:e.toolCall.toolName}}function resolveToolCallInputObject(e,n){if(e==null)return{};try{return parseJsonObject(e)}catch(e){let t=e instanceof Error?e.message:String(e);throw TypeError(`Failed to parse tool-call arguments for "${n.toolName}" (${n.callId}): ${t}`,{cause:e})}}function toToolResultOutput(e){return typeof e.output==`string`?e.isError===!0?{type:`error-text`,value:e.output}:{type:`text`,value:e.output}:e.isError===!0?{type:`error-json`,value:toMutableJsonValue(e.output)}:{type:`json`,value:toMutableJsonValue(e.output)}}function toMutableJsonValue(e){if(e===null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`)return e;if(Array.isArray(e))return e.map(e=>toMutableJsonValue(e));let t={};for(let[n,r]of Object.entries(e))t[n]=toMutableJsonValue(r);return t}export{clearPendingRuntimeActionBatch,createRuntimeActionRequestFromToolCall,getPendingRuntimeActionBatch,hasPendingRuntimeActionBatch,recordPendingSubagentChildToken,resolvePendingRuntimeActions,resolveRuntimeActionResultsForKeys,resolveToolCallInputObject,setPendingRuntimeActionBatch};
@@ -1 +1 @@
1
- import{createErrorId,createLogger,formatError,logError,recordErrorOnSpan}from"#internal/logging.js";import{isScheduleAppAuth}from"#channel/schedule-auth.js";import{AuthKey,ParentSessionKey}from"#context/keys.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{EmptyModelResponseError,classifyModelCallError,extractModelCallErrorDetails,extractUnsupportedProviderToolTypes,isNoOutputGeneratedError,summarizeKnownModelCallConfigError,summarizeKnownModelCallRequestError}from"#harness/model-call-error.js";import{toErrorMessage}from"#shared/errors.js";import{createActionResultEvent,createAuthorizationRequiredEvent,createCompactionCompletedEvent,createCompactionRequestedEvent,createInputRequestedEvent,createResultCompletedEvent}from"#protocol/message.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{contextStorage}from"#context/container.js";import{ToolLoopAgent,isStepCount}from"ai";import{advanceStep,emitFailedStep,emitRecoverableFailedTurn,emitStepStarted,emitStreamContent,emitTurnEpilogue,emitTurnPreamble,getHarnessEmissionState,setHarnessEmissionState}from"#harness/emission.js";import{createRuntimeActionRequestFromToolCall,resolvePendingRuntimeActions,setPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{clearPendingWorkflowInterrupt,getPendingWorkflowInterrupt,setPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{getWorkflowRuntimeActionInterrupts,isWorkflowRuntimeActionInterrupt}from"#harness/workflow-runtime-action-state.js";import{isAuthorizationSignal,setPendingAuthorization}from"#harness/authorization.js";import{resolveAssistantStepText}from"#harness/messages.js";import{buildDynamicInstructionMessages}from"#context/dynamic-instruction-lifecycle.js";import{PendingSkillAnnouncementKey}from"#context/dynamic-skill-lifecycle.js";import{consumeDeferredStepInput,getApprovedTools,hasDeferredStepInput,hasStepInput,resolvePendingInput,setPendingInputBatch}from"#harness/input-requests.js";import{CONDITIONAL_DELIVERY_INSTRUCTION,EMPTY_DELIVERY_SENTINEL,hasEmptyDeliverySentinel}from"#shared/empty-delivery.js";import{readToolInterrupt}from"#harness/tool-interrupts.js";import{ASK_QUESTION_TOOL_NAME}from"#runtime/framework-tools/ask-question.js";import{extractQuestionInputRequests,extractToolApprovalInputRequests}from"#harness/input-extraction.js";import{applyLastToolCacheBreakpoint,applySystemCacheBreakpoint,detectPromptCachePath,getAnthropicCacheMarker}from"#harness/prompt-cache.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{buildDynamicTools}from"#context/build-dynamic-tools.js";import{hydrateSandboxAttachments,stageAttachmentsToSandbox}from"#harness/attachment-staging.js";import{applyWorkflowTool,buildWorkflowHostTools}from"#harness/workflow-sandbox.js";import{ensureWorkflowContinuationSecurity,getWorkflowContinuationSecurity}from"#harness/workflow-continuation-security.js";import{createWorkflowLifecycle}from"#harness/workflow-lifecycle.js";import{compactMessages,getInputTokenCount,resolveCompactionModel,shouldCompact}from"#harness/compaction.js";import{accumulateTurnUsage,getTurnUsageState,setTurnUsageState}from"#harness/turn-tag-state.js";import{setEveAttributes}from"#runtime/attributes/emit.js";import{buildTelemetryRuntimeContext}from"#harness/instrumentation-runtime-context.js";import{getInstrumentationConfig}from"#harness/instrumentation-config.js";import{extractWorkflowStreamWriteErrorDetails}from"#harness/workflow-stream-error.js";import{ensureOtelIntegration}from"#harness/otel-integration.js";import{resolveFrameworkToolFromUpstreamType}from"#harness/provider-tools.js";import{buildStepHooks,emitStepActions,isInvalidToolCall}from"#harness/step-hooks.js";import{buildToolApproval,buildToolSetFromDefinitions,buildToolSetWithProviderTools}from"#harness/tools.js";import{continueWorkflowSandboxInterrupt,getWorkflowSandboxInterrupt,unwrapWorkflowSandboxResult}from"#shared/workflow-sandbox.js";import{FINAL_OUTPUT_TOOL_NAME,buildFinalOutputTool}from"#runtime/framework-tools/final-output.js";const environment=process.env.NODE_ENV??`unknown`,eveVersion=resolveInstalledPackageInfo().version,log=createLogger(`harness.tool-loop`);function logToolExecutionError(e){e.toolOutput.type===`tool-error`&&logError(log,`tool execution failed`,e.toolOutput.error,{toolName:e.toolCall.toolName,toolCallId:e.toolCall.toolCallId})}function enrichTelemetry(e,t,n){if(e===void 0)return;let r={};for(let e of Object.keys(n??{}))r[e]=!0;return{functionId:e.functionId??t,includeRuntimeContext:r,isEnabled:!0,recordInputs:e.recordInputs??!0,recordOutputs:e.recordOutputs??!0}}function buildGatewayAttributionHeaders(e,t){if(typeof e!=`string`)return;let n=t?.agentName??t?.agentId,r=process.env.VERCEL_PROJECT_PRODUCTION_URL||process.env.VERCEL_URL,i=r?`https://${r}`:void 0;if(!n&&!i)return;let a={};return n&&(a[`x-title`]=n),i&&(a[`http-referer`]=i),a}const TURN_TRACE_STATE_KEY=`eve.harness.turnTrace`;function getTurnTraceState(e){return e.state?.[TURN_TRACE_STATE_KEY]}function setTurnTraceState(e,t){let n={traceId:t.traceId,spanId:t.spanId,traceFlags:t.traceFlags};return{...e,state:{...e.state,[TURN_TRACE_STATE_KEY]:n}}}function resolveStepOtelContext(e,t,n){if(t)return trace.setSpan(context.active(),t);if(e){let e=getTurnTraceState(n);if(e){let t=trace.wrapSpanContext({traceId:e.traceId,spanId:e.spanId,traceFlags:e.traceFlags});return trace.setSpan(context.active(),t)}}}function createToolLoopHarness(t){let n=t.handleEvent,c=getInstrumentationConfig();c!==void 0&&ensureOtelIntegration();let f=c===void 0?void 0:trace.getTracer(`eve`),p=t.runtimeIdentity?.agentName;async function runStep(e,t){let n;if(f&&hasStepInput(t)){let t=c?.functionId??p,r={"eve.version":eveVersion,"eve.environment":environment,"eve.session.id":e.sessionId};t&&(r[`ai.telemetry.functionId`]=t),n=f.startSpan(`ai.eve.turn`,{attributes:r})}let r=resolveStepOtelContext(f,n,e),executeStep=()=>executeStepBody(e,t,n);try{return r?await context.with(r,executeStep):await executeStep()}finally{n?.end()}}async function executeStepBody(f,v,y){let b=f;y&&(b=setTurnTraceState(b,y.spanContext()));let x=getHarnessEmissionState(b.state),S=consumeDeferredStepInput({input:v,session:b});b=S.session;let E=await resolvePendingRuntimeActions({emit:n,session:b,stepInput:S.input});if(E.outcome===`unresolved`)return{next:null,session:E.session};b=E.session;let D=resolvePendingInput({history:E.messages,resolveApprovalKey:resolveApprovalKeyFromTools(t.tools),session:b,stepInput:S.input});if(D.outcome===`unresolved`)return{next:null,session:D.session};if(n&&D.rejectedActions)for(let e of D.rejectedActions.results)await n(createActionResultEvent({rejected:!0,result:e,sequence:D.rejectedActions.event.sequence,stepIndex:D.rejectedActions.event.stepIndex,turnId:D.rejectedActions.event.turnId}));n&&hasStepInput(v)&&(x=await emitTurnPreamble(n,v??{},x,t.runtimeIdentity),b=setHarnessEmissionState(b,x),y&&y.setAttribute(`eve.turn.id`,x.turnId)),b=D.session,t.workflow===!0&&(b=ensureWorkflowContinuationSecurity(b));let O=D.messages;if(S.input?.context!==void 0)for(let e of S.input.context)O.push({content:e,role:`user`});if(S.input?.message!==void 0&&!D.deferredMessage){let e=await stageAttachmentsToSandbox(S.input.message);O.push({content:e,role:`user`})}let k=await t.resolveModel(b.agent.modelReference),A=detectPromptCachePath(k),j=A.kind===`anthropic-direct`?getAnthropicCacheMarker():void 0,M=buildGatewayAttributionHeaders(k,t.runtimeIdentity);({messages:O,session:b}=await maybeCompact({emit:n,emissionState:x,headers:M,messages:O,model:k,onCompaction:t.onCompaction,resolveModel:t.resolveModel,session:b,telemetry:enrichTelemetry(c,p)??void 0}));let N=getApprovedTools(b),P=contextStorage.getStore(),F=b.outputSchema===void 0&&P!==void 0&&isScheduleAppAuth(P.get(AuthKey))&&P.get(ParentSessionKey)===void 0,I=await hydrateSandboxAttachments(O),L=[],R=[];for(let e of I)e.role===`system`?L.push(e):R.push(e);if(P!==void 0){L.push(...buildDynamicInstructionMessages(P));let e=P.get(PendingSkillAnnouncementKey);e!==void 0&&e.length>0&&L.push({role:`system`,content:e})}F&&L.push({role:`system`,content:CONDITIONAL_DELIVERY_INSTRUCTION});let z=R,prepareModelCallInput=e=>{let t=e?[{role:`system`,content:e}]:[],n=b.agent.system?[{role:`system`,content:b.agent.system}]:[],r=L.length>0||t.length>0?[...t,...n,...L]:void 0,i=r!==void 0&&j?applySystemCacheBreakpoint(r,j):r??b.agent.system??void 0;return{instructions:i,telemetryRuntimeContext:buildTelemetryRuntimeContext({eveVersion,authored:c,emissionState:x,environment,modelInput:{instructions:i,messages:z},session:b})}},runOneModelCall=async e=>{let{instructions:i,telemetryRuntimeContext:a={}}=e.preparedInput??prepareModelCallInput(e.extraSystemNote);e.retryReason&&(a[`eve.retry.reason`]=e.retryReason);let o=e.trailingUserNote?[...z,{role:`user`,content:e.trailingUserNote}]:z,s=await buildToolSetWithProviderTools({approvedTools:N,capabilities:t.capabilities,disabledProviderTools:e.disabledProviderTools,modelReference:b.agent.modelReference,tools:t.tools});if(P!==void 0){let n=buildDynamicTools(P),r=buildToolSetFromDefinitions({approvedTools:N,capabilities:t.capabilities,disabledProviderTools:e.disabledProviderTools,tools:n});for(let[e,t]of Object.entries(r))s[e]=t}b.outputSchema!==void 0&&(s[FINAL_OUTPUT_TOOL_NAME]=buildFinalOutputTool(b.outputSchema));let u=t.workflow===!0?(await applyWorkflowTool({continuationSecurity:getWorkflowContinuationSecurity(b),harnessTools:t.tools,lifecycle:n===void 0?void 0:createWorkflowLifecycle({emit:n,emissionState:x,tools:t.tools}),tools:s})).modelTools:s,d=j?applyLastToolCacheBreakpoint(u,j):u,f=buildStepHooks({cachePath:A,emit:n,emissionState:x,emitStepStarted:e.suppressStepStartedEmission!==!0,marker:j,session:b}),h=new ToolLoopAgent({headers:M,instructions:i,model:k,onToolExecutionEnd:logToolExecutionError,onError(e){summarizeKnownModelCallConfigError(e.error)===null&&logError(log,`tool-loop stream error`,e.error)},onStepFinish:f.onStepFinish,prepareStep:f.prepareStep,reasoning:b.agent.reasoning,runtimeContext:a,stopWhen:isStepCount(1),telemetry:enrichTelemetry(c,p,a),toolApproval:buildToolApproval(u),tools:d}),executeModelCall=async()=>{if(n){let e=new Set([ASK_QUESTION_TOOL_NAME,FINAL_OUTPUT_TOOL_NAME]),r=await h.stream({messages:o}),{emittedActionCallIds:i,handledInlineToolResultCallIds:a,inlineAuthorizationResults:s,inlineToolResultParts:c}=await emitStreamContent(n,x,r.fullStream,{excludedActionToolNames:e,tools:t.tools}),u=await f.stepResult;if(isEmptyModelResponse(u)&&c.length===0&&s.length===0)throw new EmptyModelResponseError;if(await emitStepActions(n,x,u,{emittedActionCallIds:i,excludedActionToolNames:e,handledInlineToolResultCallIds:a,tools:t.tools}),c.length>0||s.length>0){let e=u.toolResults,t=new Map(e.map(e=>[e.toolCallId,e]));for(let e of s)t.set(e.toolCallId,e);return{content:u.content,finishReason:u.finishReason,response:{...u.response,...c.length>0?{messages:[{role:`tool`,content:[...c]},...u.response.messages]}:{}},text:u.text,toolCalls:u.toolCalls,toolResults:[...t.values()],usage:u.usage}}return u}await h.generate({messages:o});let e=await f.stepResult;if(isEmptyModelResponse(e))throw new EmptyModelResponseError;return e};return runModelCallWithRetries(()=>executeModelCall().catch(rethrowNoOutputAsEmptyResponse),{sessionId:b.sessionId,turnId:x.turnId})},B=prepareModelCallInput();n&&await emitStepStarted(n,x,O);let V=await continuePendingWorkflowInterrupt({childResults:S.input?.runtimeActionResults,config:t,emit:n,emissionState:x,runStep,session:b});if(V!==null)return V;let H;try{H=await runOneModelCall({preparedInput:B,suppressStepStartedEmission:!0})}catch(r){let a=await runModelCallRecoveryPipeline({error:r,stages:[e=>attemptUnsupportedProviderToolRecovery({error:e.error,runOneModelCall,sessionId:b.sessionId,turnId:x.turnId}),e=>attemptEmptyResponseRecovery({emptyDeliveryEnabled:F,error:e.error,retryCallOptions:e.retryCallOptions,runOneModelCall,sessionId:b.sessionId,turnId:x.turnId})]});if(a.outcome===`recovered`)H=a.result;else{let r=a.error;if(y&&recordErrorOnSpan(y,r),!n)throw r;let o=extractWorkflowStreamWriteErrorDetails(r);if(o!==null){let t=createErrorId();return log.error(`workflow stream write failed — parking session for retry by the user`,{...o,errorId:t,error:r,sessionId:b.sessionId,turnId:x.turnId}),x=await emitRecoverableFailedTurn(n,x,{code:`WORKFLOW_STREAM_WRITE_FAILED`,details:{...o,errorId:t},message:toErrorMessage(r)}),{next:null,session:setHarnessEmissionState(b,x)}}let s=classifyModelCallError(r),c=createErrorId(),l=s===`terminal`?summarizeKnownModelCallConfigError(r):null,f=l===null?summarizeKnownModelCallRequestError(r):null,p=l?.message??f?.message??toErrorMessage(r),_=extractModelCallErrorDetails(r),v=buildModelCallFailureDetails({configSummary:l,error:r,errorId:c,modelCallDetails:_,requestSummary:f}),S=buildModelCallFailureLogFields({error:r,errorId:c,modelCallDetails:_,requestSummary:f,sessionId:b.sessionId,turnId:x.turnId});return s===`terminal`?(l===null?log.error(f?.message??`model call failed terminally`,S):log.error(`${l.name}: ${l.message}`,{errorId:c,sessionId:b.sessionId,turnId:x.turnId}),await emitFailedStep(n,x,{code:`MODEL_CALL_FAILED`,details:v,message:p,sessionId:b.sessionId}),{next:{done:!0,output:``},session:b}):t.mode===`task`?(log.error(f?.message??`model call failed; failing the task run`,S),await emitFailedStep(n,x,{code:`MODEL_CALL_FAILED`,details:v,message:p,sessionId:b.sessionId}),{next:{done:!0,isError:!0,output:p},session:b}):(log.error(f?.message??`model call failed — parking session for retry by the user`,S),x=await emitRecoverableFailedTurn(n,x,{code:`MODEL_CALL_FAILED`,details:v,message:p}),{next:null,session:setHarnessEmissionState(b,x)})}}let U=accumulateTurnUsage({previous:getTurnUsageState(b.state),turnId:x.turnId,usage:H.usage??{}});b=setTurnUsageState(b,U);let W;try{W=formatLanguageModelGatewayId(k)}catch{W=void 0}return await setEveAttributes({"$eve.model":W,"$eve.input_tokens":U.inputTokens,"$eve.output_tokens":U.outputTokens,"$eve.cache_read_tokens":U.cacheReadTokens,"$eve.cache_write_tokens":U.cacheWriteTokens,"$eve.tool_count":t.tools.size}),handleStepResult({config:t,emit:n,emissionState:x,promptMessages:O,result:H,runStep,session:b})}return runStep}function buildModelCallFailureDetails(e){let{configSummary:t,error:r,errorId:i,modelCallDetails:a,requestSummary:o}=e;return t===null?o===null?{...formatError(r,i),...a}:{errorId:i,message:toErrorMessage(r),name:o.name,...a}:{errorId:i,message:t.message,name:t.name,...a}}function buildModelCallFailureLogFields(e){let t={errorId:e.errorId,sessionId:e.sessionId,turnId:e.turnId};return e.requestSummary===null?{...t,error:e.error}:{...t,details:e.modelCallDetails}}async function runModelCallRecoveryPipeline(e){let t=e.error,n;for(let r of e.stages){let e=await r({error:t,retryCallOptions:n});if(e.outcome===`recovered`)return e;e.outcome===`failed`&&(t=e.error,n=e.retryCallOptions)}return{outcome:`failed`,error:t}}async function attemptUnsupportedProviderToolRecovery(e){let t=extractUnsupportedProviderToolTypes(e.error);if(t.length===0)return{outcome:`skipped`};let n=[];for(let e of t){let t=resolveFrameworkToolFromUpstreamType(e);t!==null&&!n.includes(t)&&n.push(t)}if(n.length===0)return{outcome:`skipped`};log.warn(`disabling unsupported provider tool(s); retrying step once`,{disabled:n,sessionId:e.sessionId,turnId:e.turnId,upstreamTypes:t});let r={disabledProviderTools:new Set(n),extraSystemNote:buildDisabledToolNote(n)};try{return{outcome:`recovered`,result:await e.runOneModelCall({...r,suppressStepStartedEmission:!0})}}catch(e){return{outcome:`failed`,error:e,retryCallOptions:r}}}function buildDisabledToolNote(e){let t=e.join(`, `);return`The following ${e.length===1?`tool is`:`tools are`} not available with the current model and has been removed: ${t}. Proceed using the remaining tools or your training knowledge.`}function isEmptyModelResponse(e){return e.toolCalls.length===0&&e.toolResults.length===0&&resolveAssistantStepText(e.response.messages,e.text)===null}function rethrowNoOutputAsEmptyResponse(e){throw isNoOutputGeneratedError(e)?new EmptyModelResponseError({cause:e}):e}const EMPTY_RESPONSE_NUDGE=`Your previous reply was empty and was not delivered. Answer now from the tool results above; do not re-run tools or mention this notice.`;function buildEmptyResponseNudge(e){return e?`${EMPTY_RESPONSE_NUDGE} If the current task explicitly requires conditional delivery and there is nothing to report, reply with exactly ${EMPTY_DELIVERY_SENTINEL}.`:EMPTY_RESPONSE_NUDGE}async function attemptEmptyResponseRecovery(e){if(!(e.error instanceof EmptyModelResponseError))return{outcome:`skipped`};log.warn(`empty model response; reissuing the model call once`,{sessionId:e.sessionId,turnId:e.turnId});try{return{outcome:`recovered`,result:await e.runOneModelCall({...e.retryCallOptions,retryReason:`empty-response`,suppressStepStartedEmission:!0,trailingUserNote:buildEmptyResponseNudge(e.emptyDeliveryEnabled)})}}catch(t){return{outcome:`failed`,error:t,retryCallOptions:e.retryCallOptions}}}async function handleStepResult(e){let{config:t,emit:n,promptMessages:r,result:i,runStep:a}=e,{emissionState:o,session:s}=e,c=resolveAssistantStepText(i.response.messages,i.text),l=i.finishReason!==`tool-calls`&&i.toolCalls.length===0&&hasEmptyDeliverySentinel(c),u=l?[]:i.response.messages,d=l?null:c,f={...s,compaction:createNextCompactionConfig(s.compaction,r,i)};if(t.workflow===!0){let e=await getWorkflowSandboxInterrupt(i,getWorkflowContinuationSecurity(f));if(e!==void 0){if(!isWorkflowRuntimeActionInterrupt(e))throw Error(`Unsupported Workflow interrupt kind "${e.payload.kind}".`);return parkOnWorkflowInterrupt({baseSession:f,emissionState:o,interrupt:e,promptMessages:r,responseMessages:u})}}let p=extractToolApprovalInputRequests({content:i.content??[]}),m=new Set(p.map(e=>e.action.callId)),h=extractQuestionInputRequests({toolCalls:i.toolCalls,excludedCallIds:m}),g=[...p,...h],_=(i.toolCalls??[]).filter(e=>!isInvalidToolCall(e)).filter(e=>t.tools.get(e.toolName)?.runtimeAction!==void 0).map(e=>createRuntimeActionRequestFromToolCall({toolCall:e,tools:t.tools}));if(_.length>0)return{next:null,session:setHarnessEmissionState(setPendingRuntimeActionBatch({actions:_,event:{sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId},responseMessages:u,session:{...f,history:[...r]}}),o)};if(g.length>0){let e=setPendingInputBatch({event:{sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId},requests:g,responseMessages:u,session:{...f,history:[...r]}});return n&&(await n(createInputRequestedEvent({requests:g,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),t.mode===`conversation`&&(o=await emitTurnEpilogue(n,o,t.mode),e=setHarnessEmissionState(e,o))),{next:null,session:e}}let y=findAuthorizationSignalFromToolResults(i.toolResults);if(y){let{challenges:e}=y;if(n)for(let t of e)await n(createAuthorizationRequiredEvent({authorization:t.challenge,name:t.name,description:t.challenge.instructions??`Authorization required for ${t.name}`,webhookUrl:t.hookUrl,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId}));return{next:null,session:setHarnessEmissionState({...f,history:[...r],state:setPendingAuthorization(f.state,{challenges:e})},o)}}let b=new Set((d===null?i.toolResults??[]:[]).filter(e=>e.providerExecuted===!0).map(e=>e.toolCallId)),S=[],C=u.map(e=>e.role===`assistant`&&Array.isArray(e.content)?{...e,content:e.content.flatMap(e=>e.type===`tool-result`&&b.has(e.toolCallId)?(S.push(e),[]):[e.type===`tool-call`&&b.has(e.toolCallId)?{...e,providerExecuted:!1}:e])}:e);S.length>0&&C.push({role:`tool`,content:S});let w=[...r,...C],T={...f,history:w};return!(T.outputSchema!==void 0&&extractFinalOutput(i)!==void 0)&&(C.at(-1)?.role===`tool`||hasDeferredStepInput(T))?(n&&(o=advanceStep(o),T=setHarnessEmissionState(T,o)),{next:a,session:T}):t.mode===`task`?finishTaskTurn({emissionState:o,emit:n,history:r,result:i,schema:T.outputSchema,session:T,stepOutput:d}):finishConversationTurn({emissionState:o,emit:n,history:r,result:i,schema:T.outputSchema,session:T})}const OUTPUT_SCHEMA_NOT_FULFILLED={code:`OUTPUT_SCHEMA_NOT_FULFILLED`,message:`The agent could not produce a result matching the requested schema.`};function extractFinalOutput(e){return(e.toolCalls??[]).find(e=>e.toolName===FINAL_OUTPUT_TOOL_NAME)?.input}function persistStructuredAssistantTurn(e,t,n){return{...e,history:[...t,{content:JSON.stringify(n),role:`assistant`}],outputSchema:void 0}}async function emitStructuredResult(e,t,n,r){return await e(createResultCompletedEvent({result:n,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),emitTurnEpilogue(e,t,r)}async function finishTaskTurn(e){let{emit:t,history:n,result:r,schema:i,stepOutput:a}=e,{emissionState:o,session:s}=e;if(i===void 0)return t&&(o=await emitTurnEpilogue(t,o,`task`),s=setHarnessEmissionState(s,o)),{next:{done:!0,output:a??``},session:s};let c=extractFinalOutput(r);return c===void 0?(t&&await emitFailedStep(t,o,{...OUTPUT_SCHEMA_NOT_FULFILLED,sessionId:s.sessionId}),{next:{done:!0,isError:!0,output:OUTPUT_SCHEMA_NOT_FULFILLED.message},session:s}):(s=persistStructuredAssistantTurn(s,n,c),t&&(o=await emitStructuredResult(t,o,c,`task`),s=setHarnessEmissionState(s,o)),{next:{done:!0,output:c},session:s})}async function finishConversationTurn(e){let{emit:t,history:n,result:r,schema:i}=e,{emissionState:a,session:o}=e;if(i===void 0)return t&&(a=await emitTurnEpilogue(t,a,`conversation`),o=setHarnessEmissionState(o,a)),{next:null,session:o};let s=extractFinalOutput(r);return s===void 0?(t&&(a=await emitRecoverableFailedTurn(t,a,OUTPUT_SCHEMA_NOT_FULFILLED),o=setHarnessEmissionState(o,a)),{next:null,session:o}):(o=persistStructuredAssistantTurn(o,n,s),t&&(a=await emitStructuredResult(t,a,s,`conversation`),o=setHarnessEmissionState(o,a)),{next:null,session:o})}async function continuePendingWorkflowInterrupt(e){let t=getPendingWorkflowInterrupt(e.session.state);if(t===void 0)return null;let n=t.interrupt;if(!isWorkflowRuntimeActionInterrupt(n))throw Error(`Unsupported Workflow interrupt kind "${n.payload.kind}".`);let i=e.emit===void 0?void 0:createWorkflowLifecycle({emit:e.emit,emissionState:e.emissionState,skipReplayed:!0,tools:e.config.tools}),a=getWorkflowContinuationSecurity(e.session),o;try{let t=buildWorkflowHostTools({tools:e.config.tools}),r=e.childResults??[],s=n,c=0;for(;;){o=await continueWorkflowSandboxInterrupt({continuationSecurity:a,interrupt:s,lifecycle:i,resolution:r[c]?.output,tools:t});let e=await unwrapWorkflowSandboxResult(o,a);if(e.status!==`interrupted`||!isWorkflowRuntimeActionInterrupt(e.interrupt)||c+1>=r.length)break;let n=getWorkflowRuntimeActionInterrupts(e.interrupt)[0];if(n===void 0)throw Error(`Workflow continuation contains no pending runtime-action interrupt.`);c++,s=n}}catch(e){logError(log,`Workflow interrupt continuation failed`,e),o={error:`workflow_continuation_failed`,message:toErrorMessage(e),retryable:!1}}let s=await unwrapWorkflowSandboxResult(o,a),c=s.status===`interrupted`?s.interrupt:s.output,l=replaceWorkflowToolResult([...e.session.history,...t.responseMessages],n.outerToolCallId,c),u=clearPendingWorkflowInterrupt({...e.session,history:l});if(s.status===`interrupted`){if(!isWorkflowRuntimeActionInterrupt(s.interrupt))throw Error(`Unsupported Workflow interrupt kind "${s.interrupt.payload.kind}".`);let t=e.session.history.length,n=l.slice(0,t),r=l.slice(t);return u={...u,history:n},parkOnWorkflowInterrupt({baseSession:u,emissionState:e.emissionState,interrupt:s.interrupt,promptMessages:n,responseMessages:r})}return{next:e.runStep,session:u}}function replaceWorkflowToolResult(e,t,n){if(t===void 0)return[...e];let r=typeof n==`string`?{type:`text`,value:n}:{type:`json`,value:n};return e.map(e=>{if(e.role!==`tool`)return e;let n=e.content.map(e=>e.type!==`tool-result`||e.toolCallId!==t?e:{...e,output:r});return{...e,content:n}})}function parkOnWorkflowInterrupt(e){let t=getWorkflowRuntimeActionInterrupts(e.interrupt)[0];if(t===void 0)throw Error(`Workflow continuation contains no pending runtime-action interrupt.`);let n={...e.baseSession,history:[...e.promptMessages]};return{next:null,session:setHarnessEmissionState(setPendingWorkflowInterrupt({interrupt:t,responseMessages:e.responseMessages,session:n}),e.emissionState)}}function createNextCompactionConfig(e,t,n){let r={recentWindowSize:e.recentWindowSize,threshold:e.threshold};return n.usage?.inputTokens!==void 0&&(r.lastKnownInputTokens=n.usage.inputTokens,r.lastKnownPromptMessageCount=t.length),r}async function maybeCompact(e){let{emit:t,emissionState:n}=e,r=e.messages,i=e.session;if(!shouldCompact(r,i.compaction))return{messages:r,session:i};let a=await resolveCompactionModel({compactionModelReference:i.agent.compactionModelReference,model:e.model,modelReference:i.agent.modelReference,resolveModel:e.resolveModel});if(t&&await t(createCompactionRequestedEvent({modelId:formatLanguageModelGatewayId(a.model),sequence:n.sequence,sessionId:i.sessionId,turnId:n.turnId,usageInputTokens:getInputTokenCount(r,i.compaction)})),r=await compactMessages(r,a.model,i.compaction,a.providerOptions,e.telemetry,e.headers),e.onCompaction)for(let t of e.onCompaction())r.push(t);return t&&await t(createCompactionCompletedEvent({modelId:formatLanguageModelGatewayId(a.model),sequence:n.sequence,sessionId:i.sessionId,turnId:n.turnId})),{messages:r,session:i}}function resolveApprovalKeyFromTools(e){return t=>{let n=e.get(t.action.toolName);if(n?.approvalKey!==void 0)return n.approvalKey(t.action.input)}}async function runModelCallWithRetries(e,t){for(let n=1;;n++)try{return await e()}catch(e){if(n===3||classifyModelCallError(e)!==`retry`)throw e;let r=500*2**(n-1)+Math.floor(Math.random()*250);log.warn(`model call failed transiently — retrying`,{attempt:n,delayMs:r,sessionId:t.sessionId,turnId:t.turnId,error:e}),await new Promise(e=>setTimeout(e,r))}}function findAuthorizationSignalFromToolResults(e){let t=contextStorage.getStore();if(t!==void 0)for(let n of e??[]){let e=readToolInterrupt(t,n.toolCallId);if(e!==void 0&&isAuthorizationSignal(e))return e}for(let t of e??[])if(isAuthorizationSignal(t.output))return t.output}export{createToolLoopHarness};
1
+ import{createErrorId,createLogger,formatError,logError,recordErrorOnSpan}from"#internal/logging.js";import{isScheduleAppAuth}from"#channel/schedule-auth.js";import{AuthKey,ParentSessionKey}from"#context/keys.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{EmptyModelResponseError,classifyModelCallError,extractModelCallErrorDetails,extractUnsupportedProviderToolTypes,isNoOutputGeneratedError,summarizeKnownModelCallConfigError,summarizeKnownModelCallRequestError}from"#harness/model-call-error.js";import{toErrorMessage}from"#shared/errors.js";import{createActionResultEvent,createAuthorizationRequiredEvent,createCompactionCompletedEvent,createCompactionRequestedEvent,createInputRequestedEvent,createResultCompletedEvent}from"#protocol/message.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{contextStorage}from"#context/container.js";import{ToolLoopAgent,isStepCount}from"ai";import{advanceStep,emitFailedStep,emitRecoverableFailedTurn,emitStepStarted,emitStreamContent,emitTurnEpilogue,emitTurnPreamble,getHarnessEmissionState,setHarnessEmissionState}from"#harness/emission.js";import{createRuntimeActionRequestFromToolCall,resolvePendingRuntimeActions,setPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{clearPendingWorkflowInterrupt,getPendingWorkflowInterrupt,setPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{getWorkflowRuntimeActionInterrupts,isWorkflowRuntimeActionInterrupt}from"#harness/workflow-runtime-action-state.js";import{isAuthorizationSignal,setPendingAuthorization}from"#harness/authorization.js";import{resolveAssistantStepText}from"#harness/messages.js";import{buildDynamicInstructionMessages}from"#context/dynamic-instruction-lifecycle.js";import{PendingSkillAnnouncementKey}from"#context/dynamic-skill-lifecycle.js";import{consumeDeferredStepInput,getApprovedTools,hasDeferredStepInput,hasStepInput,resolvePendingInput,setPendingInputBatch}from"#harness/input-requests.js";import{CONDITIONAL_DELIVERY_INSTRUCTION,EMPTY_DELIVERY_SENTINEL,hasEmptyDeliverySentinel}from"#shared/empty-delivery.js";import{readToolInterrupt}from"#harness/tool-interrupts.js";import{ASK_QUESTION_TOOL_NAME}from"#runtime/framework-tools/ask-question.js";import{extractQuestionInputRequests,extractToolApprovalInputRequests}from"#harness/input-extraction.js";import{applyLastToolCacheBreakpoint,applySystemCacheBreakpoint,detectPromptCachePath,getAnthropicCacheMarker}from"#harness/prompt-cache.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{buildDynamicTools}from"#context/build-dynamic-tools.js";import{hydrateSandboxAttachments,stageAttachmentsToSandbox}from"#harness/attachment-staging.js";import{applyWorkflowTool,buildWorkflowHostTools}from"#harness/workflow-sandbox.js";import{ensureWorkflowContinuationSecurity,getWorkflowContinuationSecurity}from"#harness/workflow-continuation-security.js";import{createWorkflowLifecycle}from"#harness/workflow-lifecycle.js";import{compactMessages,getInputTokenCount,resolveCompactionModel,shouldCompact}from"#harness/compaction.js";import{accumulateTurnUsage,getTurnUsageState,setTurnUsageState}from"#harness/turn-tag-state.js";import{setEveAttributes}from"#runtime/attributes/emit.js";import{buildTelemetryRuntimeContext}from"#harness/instrumentation-runtime-context.js";import{getInstrumentationConfig}from"#harness/instrumentation-config.js";import{normalizeProviderToolHistory}from"#harness/provider-tool-history.js";import{extractWorkflowStreamWriteErrorDetails}from"#harness/workflow-stream-error.js";import{ensureOtelIntegration}from"#harness/otel-integration.js";import{resolveFrameworkToolFromUpstreamType}from"#harness/provider-tools.js";import{buildStepHooks,emitStepActions,isInvalidToolCall}from"#harness/step-hooks.js";import{buildToolApproval,buildToolSetFromDefinitions,buildToolSetWithProviderTools}from"#harness/tools.js";import{continueWorkflowSandboxInterrupt,getWorkflowSandboxInterrupt,unwrapWorkflowSandboxResult}from"#shared/workflow-sandbox.js";import{FINAL_OUTPUT_TOOL_NAME,buildFinalOutputTool}from"#runtime/framework-tools/final-output.js";const environment=process.env.NODE_ENV??`unknown`,eveVersion=resolveInstalledPackageInfo().version,log=createLogger(`harness.tool-loop`);function logToolExecutionError(e){e.toolOutput.type===`tool-error`&&logError(log,`tool execution failed`,e.toolOutput.error,{toolName:e.toolCall.toolName,toolCallId:e.toolCall.toolCallId})}function enrichTelemetry(e,t,n){if(e===void 0)return;let r={};for(let e of Object.keys(n??{}))r[e]=!0;return{functionId:e.functionId??t,includeRuntimeContext:r,isEnabled:!0,recordInputs:e.recordInputs??!0,recordOutputs:e.recordOutputs??!0}}function buildGatewayAttributionHeaders(e,t){if(typeof e!=`string`)return;let n=t?.agentName??t?.agentId,r=process.env.VERCEL_PROJECT_PRODUCTION_URL||process.env.VERCEL_URL,i=r?`https://${r}`:void 0;if(!n&&!i)return;let a={};return n&&(a[`x-title`]=n),i&&(a[`http-referer`]=i),a}const TURN_TRACE_STATE_KEY=`eve.harness.turnTrace`;function getTurnTraceState(e){return e.state?.[TURN_TRACE_STATE_KEY]}function setTurnTraceState(e,t){let n={traceId:t.traceId,spanId:t.spanId,traceFlags:t.traceFlags};return{...e,state:{...e.state,[TURN_TRACE_STATE_KEY]:n}}}function resolveStepOtelContext(e,t,n){if(t)return trace.setSpan(context.active(),t);if(e){let e=getTurnTraceState(n);if(e){let t=trace.wrapSpanContext({traceId:e.traceId,spanId:e.spanId,traceFlags:e.traceFlags});return trace.setSpan(context.active(),t)}}}function createToolLoopHarness(t){let n=t.handleEvent,c=getInstrumentationConfig();c!==void 0&&ensureOtelIntegration();let f=c===void 0?void 0:trace.getTracer(`eve`),p=t.runtimeIdentity?.agentName;async function runStep(e,t){let n;if(f&&hasStepInput(t)){let t=c?.functionId??p,r={"eve.version":eveVersion,"eve.environment":environment,"eve.session.id":e.sessionId};t&&(r[`ai.telemetry.functionId`]=t),n=f.startSpan(`ai.eve.turn`,{attributes:r})}let r=resolveStepOtelContext(f,n,e),executeStep=()=>executeStepBody(e,t,n);try{return r?await context.with(r,executeStep):await executeStep()}finally{n?.end()}}async function executeStepBody(f,v,y){let b=f;y&&(b=setTurnTraceState(b,y.spanContext()));let x=getHarnessEmissionState(b.state),S=consumeDeferredStepInput({input:v,session:b});b=S.session;let D=await resolvePendingRuntimeActions({emit:n,session:b,stepInput:S.input});if(D.outcome===`unresolved`)return{next:null,session:D.session};b=D.session;let O=resolvePendingInput({history:D.messages,resolveApprovalKey:resolveApprovalKeyFromTools(t.tools),session:b,stepInput:S.input});if(O.outcome===`unresolved`)return{next:null,session:O.session};if(n&&O.rejectedActions)for(let e of O.rejectedActions.results)await n(createActionResultEvent({rejected:!0,result:e,sequence:O.rejectedActions.event.sequence,stepIndex:O.rejectedActions.event.stepIndex,turnId:O.rejectedActions.event.turnId}));n&&hasStepInput(v)&&(x=await emitTurnPreamble(n,v??{},x,t.runtimeIdentity),b=setHarnessEmissionState(b,x),y&&y.setAttribute(`eve.turn.id`,x.turnId)),b=O.session,t.workflow===!0&&(b=ensureWorkflowContinuationSecurity(b));let k=O.messages;if(S.input?.context!==void 0)for(let e of S.input.context)k.push({content:e,role:`user`});if(S.input?.message!==void 0&&!O.deferredMessage){let e=await stageAttachmentsToSandbox(S.input.message);k.push({content:e,role:`user`})}let A=await t.resolveModel(b.agent.modelReference),j=detectPromptCachePath(A),M=j.kind===`anthropic-direct`?getAnthropicCacheMarker():void 0,N=buildGatewayAttributionHeaders(A,t.runtimeIdentity);({messages:k,session:b}=await maybeCompact({emit:n,emissionState:x,headers:N,messages:k,model:A,onCompaction:t.onCompaction,resolveModel:t.resolveModel,session:b,telemetry:enrichTelemetry(c,p)??void 0}));let P=getApprovedTools(b),F=contextStorage.getStore(),I=b.outputSchema===void 0&&F!==void 0&&isScheduleAppAuth(F.get(AuthKey))&&F.get(ParentSessionKey)===void 0,L=await hydrateSandboxAttachments(k),R=[],z=[];for(let e of L)e.role===`system`?R.push(e):z.push(e);if(F!==void 0){R.push(...buildDynamicInstructionMessages(F));let e=F.get(PendingSkillAnnouncementKey);e!==void 0&&e.length>0&&R.push({role:`system`,content:e})}I&&R.push({role:`system`,content:CONDITIONAL_DELIVERY_INSTRUCTION});let B=z,prepareModelCallInput=e=>{let t=e?[{role:`system`,content:e}]:[],n=b.agent.system?[{role:`system`,content:b.agent.system}]:[],r=R.length>0||t.length>0?[...t,...n,...R]:void 0,i=r!==void 0&&M?applySystemCacheBreakpoint(r,M):r??b.agent.system??void 0;return{instructions:i,telemetryRuntimeContext:buildTelemetryRuntimeContext({eveVersion,authored:c,emissionState:x,environment,modelInput:{instructions:i,messages:B},session:b})}},runOneModelCall=async e=>{let{instructions:i,telemetryRuntimeContext:a={}}=e.preparedInput??prepareModelCallInput(e.extraSystemNote);e.retryReason&&(a[`eve.retry.reason`]=e.retryReason);let o=e.trailingUserNote?[...B,{role:`user`,content:e.trailingUserNote}]:B,s=await buildToolSetWithProviderTools({approvedTools:P,capabilities:t.capabilities,disabledProviderTools:e.disabledProviderTools,modelReference:b.agent.modelReference,tools:t.tools});if(F!==void 0){let n=buildDynamicTools(F),r=buildToolSetFromDefinitions({approvedTools:P,capabilities:t.capabilities,disabledProviderTools:e.disabledProviderTools,tools:n});for(let[e,t]of Object.entries(r))s[e]=t}b.outputSchema!==void 0&&(s[FINAL_OUTPUT_TOOL_NAME]=buildFinalOutputTool(b.outputSchema));let u=t.workflow===!0?(await applyWorkflowTool({continuationSecurity:getWorkflowContinuationSecurity(b),harnessTools:t.tools,lifecycle:n===void 0?void 0:createWorkflowLifecycle({emit:n,emissionState:x,tools:t.tools}),tools:s})).modelTools:s,d=M?applyLastToolCacheBreakpoint(u,M):u,f=buildStepHooks({cachePath:j,emit:n,emissionState:x,emitStepStarted:e.suppressStepStartedEmission!==!0,marker:M,session:b}),h=new ToolLoopAgent({headers:N,instructions:i,model:A,onToolExecutionEnd:logToolExecutionError,onError(e){summarizeKnownModelCallConfigError(e.error)===null&&logError(log,`tool-loop stream error`,e.error)},onStepFinish:f.onStepFinish,prepareStep:f.prepareStep,reasoning:b.agent.reasoning,runtimeContext:a,stopWhen:isStepCount(1),telemetry:enrichTelemetry(c,p,a),toolApproval:buildToolApproval(u),tools:d}),executeModelCall=async()=>{if(n){let e=new Set([ASK_QUESTION_TOOL_NAME,FINAL_OUTPUT_TOOL_NAME]),r=await h.stream({messages:o}),{emittedActionCallIds:i,handledInlineToolResultCallIds:a,inlineAuthorizationResults:s,inlineToolResultParts:c}=await emitStreamContent(n,x,r.fullStream,{excludedActionToolNames:e,tools:t.tools}),u=await f.stepResult;if(isEmptyModelResponse(u)&&c.length===0&&s.length===0)throw new EmptyModelResponseError;if(await emitStepActions(n,x,u,{emittedActionCallIds:i,excludedActionToolNames:e,handledInlineToolResultCallIds:a,tools:t.tools}),c.length>0||s.length>0){let e=u.toolResults,t=new Map(e.map(e=>[e.toolCallId,e]));for(let e of s)t.set(e.toolCallId,e);return{content:u.content,finishReason:u.finishReason,response:{...u.response,...c.length>0?{messages:[{role:`tool`,content:[...c]},...u.response.messages]}:{}},text:u.text,toolCalls:u.toolCalls,toolResults:[...t.values()],usage:u.usage}}return u}await h.generate({messages:o});let e=await f.stepResult;if(isEmptyModelResponse(e))throw new EmptyModelResponseError;return e};return runModelCallWithRetries(()=>executeModelCall().catch(rethrowNoOutputAsEmptyResponse),{sessionId:b.sessionId,turnId:x.turnId})},V=prepareModelCallInput();n&&await emitStepStarted(n,x,k);let H=await continuePendingWorkflowInterrupt({childResults:S.input?.runtimeActionResults,config:t,emit:n,emissionState:x,runStep,session:b});if(H!==null)return H;let U;try{U=await runOneModelCall({preparedInput:V,suppressStepStartedEmission:!0})}catch(r){let a=await runModelCallRecoveryPipeline({error:r,stages:[e=>attemptUnsupportedProviderToolRecovery({error:e.error,runOneModelCall,sessionId:b.sessionId,turnId:x.turnId}),e=>attemptEmptyResponseRecovery({emptyDeliveryEnabled:I,error:e.error,retryCallOptions:e.retryCallOptions,runOneModelCall,sessionId:b.sessionId,turnId:x.turnId})]});if(a.outcome===`recovered`)U=a.result;else{let r=a.error;if(y&&recordErrorOnSpan(y,r),!n)throw r;let o=extractWorkflowStreamWriteErrorDetails(r);if(o!==null){let t=createErrorId();return log.error(`workflow stream write failed — parking session for retry by the user`,{...o,errorId:t,error:r,sessionId:b.sessionId,turnId:x.turnId}),x=await emitRecoverableFailedTurn(n,x,{code:`WORKFLOW_STREAM_WRITE_FAILED`,details:{...o,errorId:t},message:toErrorMessage(r)}),{next:null,session:setHarnessEmissionState(b,x)}}let s=classifyModelCallError(r),c=createErrorId(),l=s===`terminal`?summarizeKnownModelCallConfigError(r):null,f=l===null?summarizeKnownModelCallRequestError(r):null,p=l?.message??f?.message??toErrorMessage(r),_=extractModelCallErrorDetails(r),v=buildModelCallFailureDetails({configSummary:l,error:r,errorId:c,modelCallDetails:_,requestSummary:f}),S=buildModelCallFailureLogFields({error:r,errorId:c,modelCallDetails:_,requestSummary:f,sessionId:b.sessionId,turnId:x.turnId});return s===`terminal`?(l===null?log.error(f?.message??`model call failed terminally`,S):log.error(`${l.name}: ${l.message}`,{errorId:c,sessionId:b.sessionId,turnId:x.turnId}),await emitFailedStep(n,x,{code:`MODEL_CALL_FAILED`,details:v,message:p,sessionId:b.sessionId}),{next:{done:!0,output:``},session:b}):t.mode===`task`?(log.error(f?.message??`model call failed; failing the task run`,S),await emitFailedStep(n,x,{code:`MODEL_CALL_FAILED`,details:v,message:p,sessionId:b.sessionId}),{next:{done:!0,isError:!0,output:p},session:b}):(log.error(f?.message??`model call failed — parking session for retry by the user`,S),x=await emitRecoverableFailedTurn(n,x,{code:`MODEL_CALL_FAILED`,details:v,message:p}),{next:null,session:setHarnessEmissionState(b,x)})}}let W=accumulateTurnUsage({previous:getTurnUsageState(b.state),turnId:x.turnId,usage:U.usage??{}});b=setTurnUsageState(b,W);let G;try{G=formatLanguageModelGatewayId(A)}catch{G=void 0}return await setEveAttributes({"$eve.model":G,"$eve.input_tokens":W.inputTokens,"$eve.output_tokens":W.outputTokens,"$eve.cache_read_tokens":W.cacheReadTokens,"$eve.cache_write_tokens":W.cacheWriteTokens,"$eve.tool_count":t.tools.size}),handleStepResult({config:t,emit:n,emissionState:x,promptMessages:k,result:U,runStep,session:b})}return runStep}function buildModelCallFailureDetails(e){let{configSummary:t,error:r,errorId:i,modelCallDetails:a,requestSummary:o}=e;return t===null?o===null?{...formatError(r,i),...a}:{errorId:i,message:toErrorMessage(r),name:o.name,...a}:{errorId:i,message:t.message,name:t.name,...a}}function buildModelCallFailureLogFields(e){let t={errorId:e.errorId,sessionId:e.sessionId,turnId:e.turnId};return e.requestSummary===null?{...t,error:e.error}:{...t,details:e.modelCallDetails}}async function runModelCallRecoveryPipeline(e){let t=e.error,n;for(let r of e.stages){let e=await r({error:t,retryCallOptions:n});if(e.outcome===`recovered`)return e;e.outcome===`failed`&&(t=e.error,n=e.retryCallOptions)}return{outcome:`failed`,error:t}}async function attemptUnsupportedProviderToolRecovery(e){let t=extractUnsupportedProviderToolTypes(e.error);if(t.length===0)return{outcome:`skipped`};let n=[];for(let e of t){let t=resolveFrameworkToolFromUpstreamType(e);t!==null&&!n.includes(t)&&n.push(t)}if(n.length===0)return{outcome:`skipped`};log.warn(`disabling unsupported provider tool(s); retrying step once`,{disabled:n,sessionId:e.sessionId,turnId:e.turnId,upstreamTypes:t});let r={disabledProviderTools:new Set(n),extraSystemNote:buildDisabledToolNote(n)};try{return{outcome:`recovered`,result:await e.runOneModelCall({...r,suppressStepStartedEmission:!0})}}catch(e){return{outcome:`failed`,error:e,retryCallOptions:r}}}function buildDisabledToolNote(e){let t=e.join(`, `);return`The following ${e.length===1?`tool is`:`tools are`} not available with the current model and has been removed: ${t}. Proceed using the remaining tools or your training knowledge.`}function isEmptyModelResponse(e){return e.toolCalls.length===0&&e.toolResults.length===0&&resolveAssistantStepText(e.response.messages,e.text)===null}function rethrowNoOutputAsEmptyResponse(e){throw isNoOutputGeneratedError(e)?new EmptyModelResponseError({cause:e}):e}const EMPTY_RESPONSE_NUDGE=`Your previous reply was empty and was not delivered. Answer now from the tool results above; do not re-run tools or mention this notice.`;function buildEmptyResponseNudge(e){return e?`${EMPTY_RESPONSE_NUDGE} If the current task explicitly requires conditional delivery and there is nothing to report, reply with exactly ${EMPTY_DELIVERY_SENTINEL}.`:EMPTY_RESPONSE_NUDGE}async function attemptEmptyResponseRecovery(e){if(!(e.error instanceof EmptyModelResponseError))return{outcome:`skipped`};log.warn(`empty model response; reissuing the model call once`,{sessionId:e.sessionId,turnId:e.turnId});try{return{outcome:`recovered`,result:await e.runOneModelCall({...e.retryCallOptions,retryReason:`empty-response`,suppressStepStartedEmission:!0,trailingUserNote:buildEmptyResponseNudge(e.emptyDeliveryEnabled)})}}catch(t){return{outcome:`failed`,error:t,retryCallOptions:e.retryCallOptions}}}async function handleStepResult(e){let{config:t,emit:n,promptMessages:r,result:i,runStep:a}=e,{emissionState:o,session:s}=e,c=resolveAssistantStepText(i.response.messages,i.text),l=i.finishReason!==`tool-calls`&&i.toolCalls.length===0&&hasEmptyDeliverySentinel(c),u=l?[]:i.response.messages,d=l?null:c,f=new Set;for(let e of[...i.content??[],...i.toolResults??[]])(e.type===`tool-result`||e.type===`tool-error`)&&e.providerExecuted===!0&&f.add(e.toolCallId);let p=normalizeProviderToolHistory({messages:u,providerExecutedOutcomeIds:f}),m=p.messages,h={...s,compaction:createNextCompactionConfig(s.compaction,r,i)};if(t.workflow===!0){let e=await getWorkflowSandboxInterrupt(i,getWorkflowContinuationSecurity(h));if(e!==void 0){if(!isWorkflowRuntimeActionInterrupt(e))throw Error(`Unsupported Workflow interrupt kind "${e.payload.kind}".`);return parkOnWorkflowInterrupt({baseSession:h,emissionState:o,interrupt:e,promptMessages:r,responseMessages:m})}}let g=extractToolApprovalInputRequests({content:i.content??[]}),_=new Set(g.map(e=>e.action.callId)),y=extractQuestionInputRequests({toolCalls:i.toolCalls,excludedCallIds:_}),b=[...g,...y],S=(i.toolCalls??[]).filter(e=>!isInvalidToolCall(e)).filter(e=>t.tools.get(e.toolName)?.runtimeAction!==void 0).map(e=>createRuntimeActionRequestFromToolCall({toolCall:e,tools:t.tools}));if(S.length>0)return{next:null,session:setHarnessEmissionState(setPendingRuntimeActionBatch({actions:S,event:{sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId},responseMessages:m,session:{...h,history:[...r]}}),o)};if(b.length>0){let e=setPendingInputBatch({event:{sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId},requests:b,responseMessages:m,session:{...h,history:[...r]}});return n&&(await n(createInputRequestedEvent({requests:b,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),t.mode===`conversation`&&(o=await emitTurnEpilogue(n,o,t.mode),e=setHarnessEmissionState(e,o))),{next:null,session:e}}let C=findAuthorizationSignalFromToolResults(i.toolResults);if(C){let{challenges:e}=C;if(n)for(let t of e)await n(createAuthorizationRequiredEvent({authorization:t.challenge,name:t.name,description:t.challenge.instructions??`Authorization required for ${t.name}`,webhookUrl:t.hookUrl,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId}));return{next:null,session:setHarnessEmissionState({...h,history:[...r],state:setPendingAuthorization(h.state,{challenges:e})},o)}}let w=m,T=[...r,...w],E={...h,history:T};return!(E.outputSchema!==void 0&&extractFinalOutput(i)!==void 0)&&(w.at(-1)?.role===`tool`||p.outcomeEndsResponse||hasDeferredStepInput(E))?(n&&(o=advanceStep(o),E=setHarnessEmissionState(E,o)),{next:a,session:E}):t.mode===`task`?finishTaskTurn({emissionState:o,emit:n,history:r,result:i,schema:E.outputSchema,session:E,stepOutput:d}):finishConversationTurn({emissionState:o,emit:n,history:r,result:i,schema:E.outputSchema,session:E})}const OUTPUT_SCHEMA_NOT_FULFILLED={code:`OUTPUT_SCHEMA_NOT_FULFILLED`,message:`The agent could not produce a result matching the requested schema.`};function extractFinalOutput(e){return(e.toolCalls??[]).find(e=>e.toolName===FINAL_OUTPUT_TOOL_NAME)?.input}function persistStructuredAssistantTurn(e,t,n){return{...e,history:[...t,{content:JSON.stringify(n),role:`assistant`}],outputSchema:void 0}}async function emitStructuredResult(e,t,n,r){return await e(createResultCompletedEvent({result:n,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),emitTurnEpilogue(e,t,r)}async function finishTaskTurn(e){let{emit:t,history:n,result:r,schema:i,stepOutput:a}=e,{emissionState:o,session:s}=e;if(i===void 0)return t&&(o=await emitTurnEpilogue(t,o,`task`),s=setHarnessEmissionState(s,o)),{next:{done:!0,output:a??``},session:s};let c=extractFinalOutput(r);return c===void 0?(t&&await emitFailedStep(t,o,{...OUTPUT_SCHEMA_NOT_FULFILLED,sessionId:s.sessionId}),{next:{done:!0,isError:!0,output:OUTPUT_SCHEMA_NOT_FULFILLED.message},session:s}):(s=persistStructuredAssistantTurn(s,n,c),t&&(o=await emitStructuredResult(t,o,c,`task`),s=setHarnessEmissionState(s,o)),{next:{done:!0,output:c},session:s})}async function finishConversationTurn(e){let{emit:t,history:n,result:r,schema:i}=e,{emissionState:a,session:o}=e;if(i===void 0)return t&&(a=await emitTurnEpilogue(t,a,`conversation`),o=setHarnessEmissionState(o,a)),{next:null,session:o};let s=extractFinalOutput(r);return s===void 0?(t&&(a=await emitRecoverableFailedTurn(t,a,OUTPUT_SCHEMA_NOT_FULFILLED),o=setHarnessEmissionState(o,a)),{next:null,session:o}):(o=persistStructuredAssistantTurn(o,n,s),t&&(a=await emitStructuredResult(t,a,s,`conversation`),o=setHarnessEmissionState(o,a)),{next:null,session:o})}async function continuePendingWorkflowInterrupt(e){let t=getPendingWorkflowInterrupt(e.session.state);if(t===void 0)return null;let n=t.interrupt;if(!isWorkflowRuntimeActionInterrupt(n))throw Error(`Unsupported Workflow interrupt kind "${n.payload.kind}".`);let i=e.emit===void 0?void 0:createWorkflowLifecycle({emit:e.emit,emissionState:e.emissionState,skipReplayed:!0,tools:e.config.tools}),a=getWorkflowContinuationSecurity(e.session),o;try{let t=buildWorkflowHostTools({tools:e.config.tools}),r=e.childResults??[],s=n,c=0;for(;;){o=await continueWorkflowSandboxInterrupt({continuationSecurity:a,interrupt:s,lifecycle:i,resolution:r[c]?.output,tools:t});let e=await unwrapWorkflowSandboxResult(o,a);if(e.status!==`interrupted`||!isWorkflowRuntimeActionInterrupt(e.interrupt)||c+1>=r.length)break;let n=getWorkflowRuntimeActionInterrupts(e.interrupt)[0];if(n===void 0)throw Error(`Workflow continuation contains no pending runtime-action interrupt.`);c++,s=n}}catch(e){logError(log,`Workflow interrupt continuation failed`,e),o={error:`workflow_continuation_failed`,message:toErrorMessage(e),retryable:!1}}let s=await unwrapWorkflowSandboxResult(o,a),c=s.status===`interrupted`?s.interrupt:s.output,l=replaceWorkflowToolResult([...e.session.history,...t.responseMessages],n.outerToolCallId,c),u=clearPendingWorkflowInterrupt({...e.session,history:l});if(s.status===`interrupted`){if(!isWorkflowRuntimeActionInterrupt(s.interrupt))throw Error(`Unsupported Workflow interrupt kind "${s.interrupt.payload.kind}".`);let t=e.session.history.length,n=l.slice(0,t),r=l.slice(t);return u={...u,history:n},parkOnWorkflowInterrupt({baseSession:u,emissionState:e.emissionState,interrupt:s.interrupt,promptMessages:n,responseMessages:r})}return{next:e.runStep,session:u}}function replaceWorkflowToolResult(e,t,n){if(t===void 0)return[...e];let r=typeof n==`string`?{type:`text`,value:n}:{type:`json`,value:n};return e.map(e=>{if(e.role!==`tool`)return e;let n=e.content.map(e=>e.type!==`tool-result`||e.toolCallId!==t?e:{...e,output:r});return{...e,content:n}})}function parkOnWorkflowInterrupt(e){let t=getWorkflowRuntimeActionInterrupts(e.interrupt)[0];if(t===void 0)throw Error(`Workflow continuation contains no pending runtime-action interrupt.`);let n={...e.baseSession,history:[...e.promptMessages]};return{next:null,session:setHarnessEmissionState(setPendingWorkflowInterrupt({interrupt:t,responseMessages:e.responseMessages,session:n}),e.emissionState)}}function createNextCompactionConfig(e,t,n){let r={recentWindowSize:e.recentWindowSize,threshold:e.threshold};return n.usage?.inputTokens!==void 0&&(r.lastKnownInputTokens=n.usage.inputTokens,r.lastKnownPromptMessageCount=t.length),r}async function maybeCompact(e){let{emit:t,emissionState:n}=e,r=e.messages,i=e.session;if(!shouldCompact(r,i.compaction))return{messages:r,session:i};let a=await resolveCompactionModel({compactionModelReference:i.agent.compactionModelReference,model:e.model,modelReference:i.agent.modelReference,resolveModel:e.resolveModel});if(t&&await t(createCompactionRequestedEvent({modelId:formatLanguageModelGatewayId(a.model),sequence:n.sequence,sessionId:i.sessionId,turnId:n.turnId,usageInputTokens:getInputTokenCount(r,i.compaction)})),r=await compactMessages(r,a.model,i.compaction,a.providerOptions,e.telemetry,e.headers),e.onCompaction)for(let t of e.onCompaction())r.push(t);return t&&await t(createCompactionCompletedEvent({modelId:formatLanguageModelGatewayId(a.model),sequence:n.sequence,sessionId:i.sessionId,turnId:n.turnId})),{messages:r,session:i}}function resolveApprovalKeyFromTools(e){return t=>{let n=e.get(t.action.toolName);if(n?.approvalKey!==void 0)return n.approvalKey(t.action.input)}}async function runModelCallWithRetries(e,t){for(let n=1;;n++)try{return await e()}catch(e){if(n===3||classifyModelCallError(e)!==`retry`)throw e;let r=500*2**(n-1)+Math.floor(Math.random()*250);log.warn(`model call failed transiently — retrying`,{attempt:n,delayMs:r,sessionId:t.sessionId,turnId:t.turnId,error:e}),await new Promise(e=>setTimeout(e,r))}}function findAuthorizationSignalFromToolResults(e){let t=contextStorage.getStore();if(t!==void 0)for(let n of e??[]){let e=readToolInterrupt(t,n.toolCallId);if(e!==void 0&&isAuthorizationSignal(e))return e}for(let t of e??[])if(isAuthorizationSignal(t.output))return t.output}export{createToolLoopHarness};
@@ -1 +1 @@
1
- import{createRequire}from"node:module";import{existsSync,readFileSync,realpathSync}from"node:fs";import{basename,dirname,join}from"node:path";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";import{fileURLToPath}from"node:url";let cachedPackageInfo;const BUNDLED_FALLBACK_PACKAGE_VERSION=`0.15.1`,WORKFLOW_MODULE_ALIASES={"workflow/errors":`src/compiled/@workflow/errors/index.js`,"workflow/internal/private":`src/compiled/@workflow/core/private.js`};function resolveFallbackPackageVersion(){return BUNDLED_FALLBACK_PACKAGE_VERSION.startsWith(`__`)?`0.0.0`:BUNDLED_FALLBACK_PACKAGE_VERSION}const FALLBACK_PACKAGE_INFO={name:EVE_PACKAGE_NAME,version:resolveFallbackPackageVersion()};function resolveCurrentModulePath(){return typeof __filename==`string`?__filename:resolveCurrentModulePathFromStack()}function resolveCurrentModulePathFromStack(){let e=Error.prepareStackTrace;try{Error.prepareStackTrace=(e,t)=>t;let e=Error().stack?.[0]?.getFileName();if(typeof e!=`string`||e.length===0)throw Error(`Failed to resolve the current module path from the stack trace.`);return e.startsWith(`file:`)?fileURLToPath(e):e}finally{Error.prepareStackTrace=e}}const require=createRequire(resolveCurrentModulePath());function isBuildOutputPackageRoot(e){return basename(e)===`dist`&&existsSync(join(dirname(e),`package.json`))}function resolvePackageBuildRoot(){let e=dirname(realpathSync(resolveCurrentModulePath()));for(;;){if(isBuildOutputPackageRoot(e))return e;let t=dirname(e);if(t===e)return null;e=t}}function findNearestPackageRoot(e){let n=e;for(;;){if(existsSync(join(n,`package.json`))&&!isBuildOutputPackageRoot(n))return n;let r=dirname(n);if(r===n)throw Error(`Failed to resolve package root from "${e}".`);n=r}}function resolvePackageRoot(){return findNearestPackageRoot(dirname(realpathSync(resolveCurrentModulePath())))}function tryResolvePackageRoot(){try{return resolvePackageRoot()}catch{return}}function rewriteSourceFilePathForBuild(e){return e.replace(/\.[cm]?tsx?$/,`.js`)}function resolvePackageSourceFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),e):join(t,rewriteSourceFilePathForBuild(e))}function resolvePackageSourceDirectoryPath(e){let t=resolvePackageBuildRoot();return join(t===null?resolvePackageRoot():t,e)}function resolvePackageDependencyPath(e){return require.resolve(e)}function resolvePackageCompiledFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),`.generated`,`compiled`,e.replace(/^src\/compiled\//,``)):join(t,e)}function normalizeInstalledPackageInfo(e){let t=e;if(!(typeof t.name!=`string`||typeof t.version!=`string`))return{name:t.name,version:t.version}}function tryReadInstalledPackageInfo(e,t){let r=normalizeInstalledPackageInfo(JSON.parse(readFileSync(e,`utf8`)));if(r?.name===t)return r}function resolveInstalledPackageInfo(){if(cachedPackageInfo)return cachedPackageInfo;let e=tryResolvePackageRoot(),t=e===void 0?void 0:tryReadInstalledPackageInfo(join(e,`package.json`),EVE_PACKAGE_NAME);if(t)return cachedPackageInfo=t,cachedPackageInfo;try{let e=tryReadInstalledPackageInfo(require.resolve(`${EVE_PACKAGE_NAME}/package.json`),EVE_PACKAGE_NAME);if(e)return cachedPackageInfo=e,cachedPackageInfo}catch{}return cachedPackageInfo={...FALLBACK_PACKAGE_INFO},cachedPackageInfo}function readWorkflowVersionFromManifest(e){let t=e;for(let e of[t.devDependencies,t.dependencies,t.peerDependencies]){let t=e?.[`@workflow/core`];if(typeof t==`string`&&t.trim().length>0)return t}}function resolveExpectedWorkflowVersion(){let e=tryResolvePackageRoot();if(e!==void 0)try{return readWorkflowVersionFromManifest(JSON.parse(readFileSync(join(e,`package.json`),`utf8`)))}catch{}try{return readWorkflowVersionFromManifest(JSON.parse(readFileSync(require.resolve(`${EVE_PACKAGE_NAME}/package.json`),`utf8`)))}catch{return}}function resolveWorkflowModulePath(e){if(e===`workflow`)return resolvePackageSourceFilePath(`src/internal/workflow/index.ts`);if(e===`workflow/api`||e===`workflow/runtime`)return resolvePackageSourceFilePath(`src/internal/workflow/runtime.ts`);if(e===`workflow/internal/builtins`)return resolvePackageSourceFilePath(`src/internal/workflow/builtins.ts`);let t=WORKFLOW_MODULE_ALIASES[e];return t===void 0?require.resolve(e):resolvePackageCompiledFilePath(t)}export{resolveExpectedWorkflowVersion,resolveInstalledPackageInfo,resolvePackageDependencyPath,resolvePackageRoot,resolvePackageSourceDirectoryPath,resolvePackageSourceFilePath,resolveWorkflowModulePath};
1
+ import{createRequire}from"node:module";import{existsSync,readFileSync,realpathSync}from"node:fs";import{basename,dirname,join}from"node:path";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";import{fileURLToPath}from"node:url";let cachedPackageInfo;const BUNDLED_FALLBACK_PACKAGE_VERSION=`0.15.3`,WORKFLOW_MODULE_ALIASES={"workflow/errors":`src/compiled/@workflow/errors/index.js`,"workflow/internal/private":`src/compiled/@workflow/core/private.js`};function resolveFallbackPackageVersion(){return BUNDLED_FALLBACK_PACKAGE_VERSION.startsWith(`__`)?`0.0.0`:BUNDLED_FALLBACK_PACKAGE_VERSION}const FALLBACK_PACKAGE_INFO={name:EVE_PACKAGE_NAME,version:resolveFallbackPackageVersion()};function resolveCurrentModulePath(){return typeof __filename==`string`?__filename:resolveCurrentModulePathFromStack()}function resolveCurrentModulePathFromStack(){let e=Error.prepareStackTrace;try{Error.prepareStackTrace=(e,t)=>t;let e=Error().stack?.[0]?.getFileName();if(typeof e!=`string`||e.length===0)throw Error(`Failed to resolve the current module path from the stack trace.`);return e.startsWith(`file:`)?fileURLToPath(e):e}finally{Error.prepareStackTrace=e}}const require=createRequire(resolveCurrentModulePath());function isBuildOutputPackageRoot(e){return basename(e)===`dist`&&existsSync(join(dirname(e),`package.json`))}function resolvePackageBuildRoot(){let e=dirname(realpathSync(resolveCurrentModulePath()));for(;;){if(isBuildOutputPackageRoot(e))return e;let t=dirname(e);if(t===e)return null;e=t}}function findNearestPackageRoot(e){let n=e;for(;;){if(existsSync(join(n,`package.json`))&&!isBuildOutputPackageRoot(n))return n;let r=dirname(n);if(r===n)throw Error(`Failed to resolve package root from "${e}".`);n=r}}function resolvePackageRoot(){return findNearestPackageRoot(dirname(realpathSync(resolveCurrentModulePath())))}function tryResolvePackageRoot(){try{return resolvePackageRoot()}catch{return}}function rewriteSourceFilePathForBuild(e){return e.replace(/\.[cm]?tsx?$/,`.js`)}function resolvePackageSourceFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),e):join(t,rewriteSourceFilePathForBuild(e))}function resolvePackageSourceDirectoryPath(e){let t=resolvePackageBuildRoot();return join(t===null?resolvePackageRoot():t,e)}function resolvePackageDependencyPath(e){return require.resolve(e)}function resolvePackageCompiledFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),`.generated`,`compiled`,e.replace(/^src\/compiled\//,``)):join(t,e)}function normalizeInstalledPackageInfo(e){let t=e;if(!(typeof t.name!=`string`||typeof t.version!=`string`))return{name:t.name,version:t.version}}function tryReadInstalledPackageInfo(e,t){let r=normalizeInstalledPackageInfo(JSON.parse(readFileSync(e,`utf8`)));if(r?.name===t)return r}function resolveInstalledPackageInfo(){if(cachedPackageInfo)return cachedPackageInfo;let e=tryResolvePackageRoot(),t=e===void 0?void 0:tryReadInstalledPackageInfo(join(e,`package.json`),EVE_PACKAGE_NAME);if(t)return cachedPackageInfo=t,cachedPackageInfo;try{let e=tryReadInstalledPackageInfo(require.resolve(`${EVE_PACKAGE_NAME}/package.json`),EVE_PACKAGE_NAME);if(e)return cachedPackageInfo=e,cachedPackageInfo}catch{}return cachedPackageInfo={...FALLBACK_PACKAGE_INFO},cachedPackageInfo}function readWorkflowVersionFromManifest(e){let t=e;for(let e of[t.devDependencies,t.dependencies,t.peerDependencies]){let t=e?.[`@workflow/core`];if(typeof t==`string`&&t.trim().length>0)return t}}function resolveExpectedWorkflowVersion(){let e=tryResolvePackageRoot();if(e!==void 0)try{return readWorkflowVersionFromManifest(JSON.parse(readFileSync(join(e,`package.json`),`utf8`)))}catch{}try{return readWorkflowVersionFromManifest(JSON.parse(readFileSync(require.resolve(`${EVE_PACKAGE_NAME}/package.json`),`utf8`)))}catch{return}}function resolveWorkflowModulePath(e){if(e===`workflow`)return resolvePackageSourceFilePath(`src/internal/workflow/index.ts`);if(e===`workflow/api`||e===`workflow/runtime`)return resolvePackageSourceFilePath(`src/internal/workflow/runtime.ts`);if(e===`workflow/internal/builtins`)return resolvePackageSourceFilePath(`src/internal/workflow/builtins.ts`);let t=WORKFLOW_MODULE_ALIASES[e];return t===void 0?require.resolve(e):resolvePackageCompiledFilePath(t)}export{resolveExpectedWorkflowVersion,resolveInstalledPackageInfo,resolvePackageDependencyPath,resolvePackageRoot,resolvePackageSourceDirectoryPath,resolvePackageSourceFilePath,resolveWorkflowModulePath};
@@ -1 +1 @@
1
- import{transformWorkflowDirectives}from"./workflow-transformer.js";import{existsSync,readFileSync}from"node:fs";import{dirname,isAbsolute,join,relative,resolve,sep}from"node:path";import{readFile}from"node:fs/promises";import{STABLE_WORKFLOW_NAMES}from"#execution/workflow-runtime.js";import{EVE_WORKFLOW_QUEUE_TOPIC}from"#internal/workflow/queue-namespace.js";const WORKFLOW_QUEUE_TRIGGER={type:`queue/v2beta`,topic:EVE_WORKFLOW_QUEUE_TOPIC,consumer:`default`,retryAfterSeconds:5,initialDelaySeconds:0},packageJsonCache=new Map,projectDepsCache=new Map;async function applyWorkflowTransform(t,n,r,o,s,c=STABLE_WORKFLOW_NAMES){let l=s??process.cwd(),{moduleSpecifier:u,stableModuleSpecifier:d}=resolveModuleSpecifier(o===void 0?isAbsolute(t)?t:join(l,t):o,l);return transformWorkflowDirectives({filename:t,mode:r,moduleSpecifier:u,source:n,stableModuleSpecifier:d,stableWorkflowNames:c})}function detectWorkflowPatterns(e){return{hasSerde:e.includes(`workflow.serde`)||e.includes(`@serde`)||e.includes(`workflowSerde`)||e.includes(`__workflow_serde`),hasUseStep:/["']use step["']/.test(e),hasUseWorkflow:/["']use workflow["']/.test(e)}}function getImportPath(e,t){let n=isInNodeModules(e),r=!n&&isWorkspacePackage(e,t);if(n||r){let n=findPackageJson(e);if(n!==null){let i=getProjectDependencies(t).has(n.name);if(!(r||i))return{importPath:toRelativeImportPath(e,t),isPackage:!1};let a=resolveExportSubpath(e,n);return a?{importPath:`${n.name}${a}`,isPackage:!0}:isRootEntrypointFile(e,n)?{importPath:n.name,isPackage:!0}:{importPath:toRelativeImportPath(e,t),isPackage:!1}}}return{importPath:toRelativeImportPath(e,t),isPackage:!1}}function resolveModuleSpecifier(e,t){let n=isInNodeModules(e),r=!n&&isWorkspacePackage(e,t);if(!n&&!r)return{moduleSpecifier:void 0,stableModuleSpecifier:void 0};let i=findPackageJson(e);if(i===null)return{moduleSpecifier:void 0,stableModuleSpecifier:void 0};let a=resolveExportSubpath(e,i),o=a?`${i.name}${a}`:i.name;return{moduleSpecifier:`${o}@${i.version}`,stableModuleSpecifier:o}}function findPackageJson(e){let i=dirname(e),o=[];for(;i!==dirname(i);){let e=packageJsonCache.get(i);if(e!==void 0){for(let t of o)packageJsonCache.set(t,e);return e}o.push(i);let s=join(i,`package.json`);if(existsSync(s))try{let e=JSON.parse(readFileSync(s,`utf8`));if(typeof e.name==`string`&&typeof e.version==`string`){let t={dir:i,exports:e.exports,main:e.main,module:e.module,name:e.name,version:e.version};packageJsonCache.set(i,t);for(let e of o)packageJsonCache.set(e,t);return t}}catch{}i=dirname(i)}for(let e of o)packageJsonCache.set(e,null);return null}function resolveExportSubpath(e,t){if(t.exports===null||typeof t.exports!=`object`||Array.isArray(t.exports))return``;let n=e.replace(/\\/g,`/`),r=t.dir.replace(/\\/g,`/`),i=n.startsWith(`${r}/`)?`./${n.substring(r.length+1)}`:null;if(i===null)return``;for(let[e,n]of Object.entries(t.exports)){let t=resolveExportTarget(n);if(t!==null&&normalizeExportPath(t)===i)return e===`.`?``:e.substring(1)}return``}function resolveExportTarget(e){if(typeof e==`string`)return e;if(Array.isArray(e)){for(let t of e){let e=resolveExportTarget(t);if(e!==null)return e}return null}if(typeof e==`object`&&e)for(let t of[`workflow`,`default`,`require`,`import`,`node`]){let n=e[t],r=resolveExportTarget(n);if(r!==null)return r}return null}function normalizeExportPath(e){return e.startsWith(`./`)?e:`./${e}`}function isInNodeModules(e){return e.split(sep).join(`/`).includes(`/node_modules/`)}function getProjectDependencies(e){let r=projectDepsCache.get(e);if(r!==void 0)return r;let i=new Set,o=join(e,`package.json`);if(existsSync(o))try{let e=JSON.parse(readFileSync(o,`utf8`));for(let t of[`dependencies`,`devDependencies`,`peerDependencies`,`optionalDependencies`]){let n=e[t];if(typeof n==`object`&&n&&!Array.isArray(n))for(let e of Object.keys(n))i.add(e)}}catch{}return projectDepsCache.set(e,i),i}function isWorkspacePackage(e,t){if(isInNodeModules(e))return!1;let n=findPackageJson(e);return n===null||resolve(n.dir)===resolve(t)?!1:getProjectDependencies(t).has(n.name)}function toRelativeImportPath(e,t){let n=t.replace(/\\/g,`/`),r=e.replace(/\\/g,`/`),i=r.startsWith(`${n}/`)?r.substring(n.length+1):relative(t,e).replace(/\\/g,`/`);return i.startsWith(`.`)||(i=`./${i}`),i}function hasRootExport(e){if(typeof e==`string`||Array.isArray(e))return!0;if(typeof e!=`object`||!e)return!1;let t=Object.keys(e);return t.length>0&&t.every(e=>!e.startsWith(`.`))?!0:`.`in e}function normalizePackageTargetPath(e){let t=e.replace(/\\/g,`/`);return t.startsWith(`./`)?t.substring(2):t.startsWith(`/`)?t.substring(1):t}function isRootEntrypointFile(e,t){let n=e.replace(/\\/g,`/`),r=t.dir.replace(/\\/g,`/`);if(!n.startsWith(`${r}/`))return!1;let i=n.substring(r.length+1);if(t.exports!==void 0){let e;if(t.exports!==null&&typeof t.exports==`object`&&`.`in t.exports)e=t.exports[`.`];else if(hasRootExport(t.exports))e=t.exports;else return!1;let n=resolveExportTarget(e);return n!==null&&normalizePackageTargetPath(n)===i}return[t.module,t.main,`index.js`,`index.mjs`,`index.cjs`,`index.ts`,`index.mts`,`index.cts`].flatMap(e=>typeof e==`string`?[normalizePackageTargetPath(e)]:[]).includes(i)}async function readSourceFile(e){return await readFile(e,`utf8`)}export{WORKFLOW_QUEUE_TRIGGER,applyWorkflowTransform,detectWorkflowPatterns,getImportPath,readSourceFile};
1
+ import{transformWorkflowDirectives}from"./workflow-transformer.js";import{existsSync,readFileSync}from"node:fs";import{dirname,isAbsolute,join,relative,resolve,sep}from"node:path";import{readFile}from"node:fs/promises";import{STABLE_WORKFLOW_NAMES}from"#execution/workflow-runtime.js";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";import{EVE_WORKFLOW_QUEUE_TOPIC}from"#internal/workflow/queue-namespace.js";const WORKFLOW_QUEUE_TRIGGER={type:`queue/v2beta`,topic:EVE_WORKFLOW_QUEUE_TOPIC,consumer:`default`,retryAfterSeconds:5,initialDelaySeconds:0},packageJsonCache=new Map,projectDepsCache=new Map;async function applyWorkflowTransform(t,n,r,o,s,c=STABLE_WORKFLOW_NAMES){let l=s??process.cwd(),{moduleSpecifier:u,stableModuleSpecifier:d}=resolveModuleSpecifier(o===void 0?isAbsolute(t)?t:join(l,t):o,l);return transformWorkflowDirectives({filename:t,mode:r,moduleSpecifier:u,source:n,stableModuleSpecifier:d,stableWorkflowNames:c})}function detectWorkflowPatterns(e){return{hasSerde:e.includes(`workflow.serde`)||e.includes(`@serde`)||e.includes(`workflowSerde`)||e.includes(`__workflow_serde`),hasUseStep:/["']use step["']/.test(e),hasUseWorkflow:/["']use workflow["']/.test(e)}}function getImportPath(e,t){let n=isInNodeModules(e),r=!n&&isWorkspacePackage(e,t);if(n||r){let n=findPackageJson(e);if(n!==null){let i=getProjectDependencies(t).has(n.name);if(!(r||i))return{importPath:toRelativeImportPath(e,t),isPackage:!1};let a=resolveExportSubpath(e,n);return a?{importPath:`${n.name}${a}`,isPackage:!0}:isRootEntrypointFile(e,n)?{importPath:n.name,isPackage:!0}:{importPath:toRelativeImportPath(e,t),isPackage:!1}}}return{importPath:toRelativeImportPath(e,t),isPackage:!1}}function resolveModuleSpecifier(e,t){let n=isInNodeModules(e),r=!n&&isWorkspacePackage(e,t),i=findPackageJson(e);if(!n&&!r)return{moduleSpecifier:void 0,stableModuleSpecifier:i?.name===EVE_PACKAGE_NAME?EVE_PACKAGE_NAME:void 0};if(i===null)return{moduleSpecifier:void 0,stableModuleSpecifier:void 0};let a=resolveExportSubpath(e,i),o=a?`${i.name}${a}`:i.name;return{moduleSpecifier:`${o}@${i.version}`,stableModuleSpecifier:o}}function findPackageJson(e){let i=dirname(e),o=[];for(;i!==dirname(i);){let e=packageJsonCache.get(i);if(e!==void 0){for(let t of o)packageJsonCache.set(t,e);return e}o.push(i);let s=join(i,`package.json`);if(existsSync(s))try{let e=JSON.parse(readFileSync(s,`utf8`));if(typeof e.name==`string`&&typeof e.version==`string`){let t={dir:i,exports:e.exports,main:e.main,module:e.module,name:e.name,version:e.version};packageJsonCache.set(i,t);for(let e of o)packageJsonCache.set(e,t);return t}}catch{}i=dirname(i)}for(let e of o)packageJsonCache.set(e,null);return null}function resolveExportSubpath(e,t){if(t.exports===null||typeof t.exports!=`object`||Array.isArray(t.exports))return``;let n=e.replace(/\\/g,`/`),r=t.dir.replace(/\\/g,`/`),i=n.startsWith(`${r}/`)?`./${n.substring(r.length+1)}`:null;if(i===null)return``;for(let[e,n]of Object.entries(t.exports)){let t=resolveExportTarget(n);if(t!==null&&normalizeExportPath(t)===i)return e===`.`?``:e.substring(1)}return``}function resolveExportTarget(e){if(typeof e==`string`)return e;if(Array.isArray(e)){for(let t of e){let e=resolveExportTarget(t);if(e!==null)return e}return null}if(typeof e==`object`&&e)for(let t of[`workflow`,`default`,`require`,`import`,`node`]){let n=e[t],r=resolveExportTarget(n);if(r!==null)return r}return null}function normalizeExportPath(e){return e.startsWith(`./`)?e:`./${e}`}function isInNodeModules(e){return e.split(sep).join(`/`).includes(`/node_modules/`)}function getProjectDependencies(e){let r=projectDepsCache.get(e);if(r!==void 0)return r;let i=new Set,o=join(e,`package.json`);if(existsSync(o))try{let e=JSON.parse(readFileSync(o,`utf8`));for(let t of[`dependencies`,`devDependencies`,`peerDependencies`,`optionalDependencies`]){let n=e[t];if(typeof n==`object`&&n&&!Array.isArray(n))for(let e of Object.keys(n))i.add(e)}}catch{}return projectDepsCache.set(e,i),i}function isWorkspacePackage(e,t){if(isInNodeModules(e))return!1;let n=findPackageJson(e);return n===null||resolve(n.dir)===resolve(t)?!1:getProjectDependencies(t).has(n.name)}function toRelativeImportPath(e,t){let n=t.replace(/\\/g,`/`),r=e.replace(/\\/g,`/`),i=r.startsWith(`${n}/`)?r.substring(n.length+1):relative(t,e).replace(/\\/g,`/`);return i.startsWith(`.`)||(i=`./${i}`),i}function hasRootExport(e){if(typeof e==`string`||Array.isArray(e))return!0;if(typeof e!=`object`||!e)return!1;let t=Object.keys(e);return t.length>0&&t.every(e=>!e.startsWith(`.`))?!0:`.`in e}function normalizePackageTargetPath(e){let t=e.replace(/\\/g,`/`);return t.startsWith(`./`)?t.substring(2):t.startsWith(`/`)?t.substring(1):t}function isRootEntrypointFile(e,t){let n=e.replace(/\\/g,`/`),r=t.dir.replace(/\\/g,`/`);if(!n.startsWith(`${r}/`))return!1;let i=n.substring(r.length+1);if(t.exports!==void 0){let e;if(t.exports!==null&&typeof t.exports==`object`&&`.`in t.exports)e=t.exports[`.`];else if(hasRootExport(t.exports))e=t.exports;else return!1;let n=resolveExportTarget(e);return n!==null&&normalizePackageTargetPath(n)===i}return[t.module,t.main,`index.js`,`index.mjs`,`index.cjs`,`index.ts`,`index.mts`,`index.cts`].flatMap(e=>typeof e==`string`?[normalizePackageTargetPath(e)]:[]).includes(i)}async function readSourceFile(e){return await readFile(e,`utf8`)}export{WORKFLOW_QUEUE_TRIGGER,applyWorkflowTransform,detectWorkflowPatterns,getImportPath,readSourceFile};
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_AI_PACKAGE_VERSION=`^7.0.0`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.15.1`,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{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_AI_PACKAGE_VERSION=`^7.0.0`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.15.3`,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__",
@@ -32,11 +32,11 @@ eve resolves and caches connection tokens per step; they never land in conversat
32
32
 
33
33
  A connection credential can belong to the agent or to the person using it. This choice is separate from route auth, but user-scoped connection auth depends on route auth: eve can only resolve a user token when the active session has `ctx.session.auth.current?.principalType === "user"`.
34
34
 
35
- | Credential owner | Use when | Auth shape |
36
- | ---------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
37
- | App | The agent should use one shared service, bot, installation, or app credential. | `auth: { getToken }` defaults to `principalType: "app"`, or use `connect({ connector: "linear/myagent", principalType: "app" })` with Vercel Connect. |
38
- | User | Each end-user should authorize and use their own third-party account. | `connect("linear/myagent")`, `connect({ connector: "linear/myagent", principalType: "user" })`, or `auth: { principalType: "user", getToken }`. |
39
- | User from a job | Background work should use the same user's OAuth grant that started the work. | Start or resume the session through a channel whose route auth resolved that user, or pass an explicit user auth context when dispatching through a channel. |
35
+ | Credential owner | Use when | Auth shape |
36
+ | ---------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
37
+ | App | The agent should use one shared service, bot, installation, or app credential. | `auth: { getToken }` defaults to `principalType: "app"`, or use `connect({ connector: "linear/myagent", principalType: "app" })` with Vercel Connect. |
38
+ | User | Each end-user should authorize and use their own third-party account. | `connect("linear/myagent")`, `connect({ connector: "linear/myagent", principalType: "user" })`, or `auth: { principalType: "user", getToken }`. |
39
+ | User from a job | Background work should use the same user's OAuth grant that started the work. | Start or resume the session through a channel whose route auth resolved that user, or pass an explicit user auth context when dispatching through a channel. |
40
40
 
41
41
  `principalType: "user"` does not mean "ask any human later." It means "key this credential to the authenticated user already attached to the eve session." If the run was started by a schedule, a same-project runtime token, `localDev()`, or another internal runtime path without an end-user principal, a user-scoped connection fails with `reason: "principal_required"` instead of starting OAuth. In that case, either authenticate the inbound channel as a user or configure the connection as app-scoped.
42
42
 
@@ -157,12 +157,12 @@ App-scoped Connect auth is non-interactive. eve asks Vercel Connect for an app t
157
157
 
158
158
  ### Troubleshooting Vercel Connect auth
159
159
 
160
- | Symptom | What it means | Fix |
161
- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
162
- | `reason: "principal_required"` | A user-scoped connection ran without an authenticated user on the active session. | Return `principalType: "user"` from the channel's route auth, or change the connection to `principalType: "app"` if it should be shared. |
163
- | `authorization.required` appears but no UI | eve parked the turn for OAuth, but the channel or frontend is not rendering the challenge. | Render the challenge from the stream event and continue the same session after the callback. |
164
- | OAuth works locally but fails after deploy | The project may not be linked to the Connect client, or the deployed runtime may not have the expected Vercel OIDC/project scope. | Run Connect setup from the consuming project directory, link the project, deploy again, and verify the connector UID in `connect("...")`. |
165
- | A scheduled or internal run needs user OAuth | Schedules and runtime callers do not automatically carry an end-user principal. | Dispatch through a user-authenticated channel when work is user-owned, or use app-scoped auth for agent-owned background work. |
160
+ | Symptom | What it means | Fix |
161
+ | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
162
+ | `reason: "principal_required"` | A user-scoped connection ran without an authenticated user on the active session. | Return `principalType: "user"` from the channel's route auth, or change the connection to `principalType: "app"` if it should be shared. |
163
+ | `authorization.required` appears but no UI | eve parked the turn for OAuth, but the channel or frontend is not rendering the challenge. | Render the challenge from the stream event and continue the same session after the callback. |
164
+ | OAuth works locally but fails after deploy | The project may not be linked to the Connect client, or the deployed runtime may not have the expected Vercel OIDC/project scope. | Run Connect setup from the consuming project directory, link the project, deploy again, and verify the connector UID in `connect("...")`. |
165
+ | A scheduled or internal run needs user OAuth | Schedules and runtime callers do not automatically carry an end-user principal. | Dispatch through a user-authenticated channel when work is user-owned, or use app-scoped auth for agent-owned background work. |
166
166
 
167
167
  ## Self-hosted interactive OAuth
168
168
 
package/docs/meta.json CHANGED
@@ -16,6 +16,7 @@
16
16
  "---",
17
17
  "guides",
18
18
  "concepts",
19
+ "patterns",
19
20
  "---",
20
21
  "reference",
21
22
  "tutorial"
@@ -0,0 +1,257 @@
1
+ ---
2
+ title: "Dynamic scheduling"
3
+ description: "Compose one minute-level eve schedule, proactive channel handoff, and CRUD tools into application-managed schedules."
4
+ ---
5
+
6
+ Authored eve schedules are static files discovered at build time. You can build dynamic scheduling today by putting schedule rows in your application store and using one authored schedule as a dispatcher:
7
+
8
+ 1. CRUD tools let the agent create and manage rows for the current tenant;
9
+ 2. `defineSchedule({ cron: "* * * * *" })` wakes once a minute;
10
+ 3. the handler atomically claims due rows;
11
+ 4. `receive(...)` starts a normal durable agent session for each row.
12
+
13
+ PostgreSQL or a durable KV store can back the adapter. The important storage capability is an atomic lease, not a particular schema.
14
+
15
+ ```text
16
+ agent/
17
+ channels/slack.ts
18
+ lib/schedule-store.ts # your storage adapter
19
+ lib/tenant.ts
20
+ schedules/dynamic.ts
21
+ tools/create_schedule.ts
22
+ tools/delete_schedule.ts
23
+ tools/list_schedules.ts
24
+ tools/update_schedule.ts
25
+ ```
26
+
27
+ ## Dispatch due schedules every minute
28
+
29
+ This is the only authored schedule. It looks up due application-managed rows and hands each one to Slack as a proactive session:
30
+
31
+ ```ts title="agent/schedules/dynamic.ts"
32
+ import { defineSchedule } from "eve/schedules";
33
+ import slack from "../channels/slack.js";
34
+ import { scheduleStore } from "../lib/schedule-store.js";
35
+
36
+ export default defineSchedule({
37
+ cron: "* * * * *",
38
+ run({ receive, waitUntil }) {
39
+ waitUntil(
40
+ (async () => {
41
+ const jobs = await scheduleStore.claimDue({
42
+ now: new Date(),
43
+ limit: 25,
44
+ leaseForMs: 5 * 60_000,
45
+ });
46
+
47
+ await Promise.all(
48
+ jobs.map(async (job) => {
49
+ try {
50
+ await receive(slack, {
51
+ message: [
52
+ `Run dynamic schedule ${job.id}.`,
53
+ "Complete this tenant-owned task:",
54
+ job.prompt,
55
+ ].join("\n\n"),
56
+ target: { channelId: job.channelId },
57
+ auth: {
58
+ attributes: {
59
+ tenantId: job.tenantId,
60
+ role: job.ownerRole,
61
+ scheduleId: job.id,
62
+ },
63
+ authenticator: job.authenticator,
64
+ ...(job.issuer ? { issuer: job.issuer } : {}),
65
+ principalId: job.ownerId,
66
+ principalType: "user",
67
+ },
68
+ });
69
+ await scheduleStore.complete(job);
70
+ } catch (error) {
71
+ await scheduleStore.release(job, { error, retryAt: new Date(Date.now() + 300_000) });
72
+ }
73
+ }),
74
+ );
75
+ })(),
76
+ );
77
+ },
78
+ });
79
+ ```
80
+
81
+ `waitUntil` keeps the cron invocation alive until claiming and handoff settle. `receive` starts the same durable runtime used by inbound channel messages.
82
+
83
+ This example uses Slack because it has a proactive target of `{ channelId }`. Any channel that implements `receive` can replace it.
84
+
85
+ Configure Slack normally:
86
+
87
+ ```ts title="agent/channels/slack.ts"
88
+ import { connectSlackCredentials } from "@vercel/connect/eve";
89
+ import { slackChannel } from "eve/channels/slack";
90
+
91
+ export default slackChannel({
92
+ credentials: connectSlackCredentials("slack/my-agent"),
93
+ });
94
+ ```
95
+
96
+ ## Give the agent CRUD tools
97
+
98
+ Tenant and owner identity come from `ctx.session`, never the model:
99
+
100
+ ```ts title="agent/lib/tenant.ts"
101
+ import type { SessionAuthContext, SessionContext } from "eve/context";
102
+
103
+ export function requireScheduleOwner(ctx: SessionContext): {
104
+ tenantId: string;
105
+ userId: string;
106
+ auth: SessionAuthContext;
107
+ } {
108
+ const auth = ctx.session.auth.current;
109
+ const tenantId = auth?.attributes.tenantId;
110
+ if (auth?.principalType !== "user" || typeof tenantId !== "string") {
111
+ throw new Error("An authenticated tenant user is required.");
112
+ }
113
+ return { tenantId, userId: auth.principalId, auth };
114
+ }
115
+ ```
116
+
117
+ Create a one-time schedule with `everyMinutes: null`, or a recurring one with an interval:
118
+
119
+ ```ts title="agent/tools/create_schedule.ts"
120
+ import { defineTool } from "eve/tools";
121
+ import { z } from "zod";
122
+ import { scheduleStore } from "../lib/schedule-store.js";
123
+ import { requireScheduleOwner } from "../lib/tenant.js";
124
+
125
+ export default defineTool({
126
+ description: "Create a one-time or repeating scheduled agent run for this tenant.",
127
+ inputSchema: z.object({
128
+ prompt: z.string().min(1).max(8000),
129
+ channelId: z.string().min(1),
130
+ firstRunAt: z.string().datetime({ offset: true }),
131
+ everyMinutes: z.number().int().min(1).max(525600).nullable().default(null),
132
+ }),
133
+ async execute(input, ctx) {
134
+ return await scheduleStore.create(requireScheduleOwner(ctx), {
135
+ ...input,
136
+ firstRunAt: new Date(input.firstRunAt),
137
+ });
138
+ },
139
+ });
140
+ ```
141
+
142
+ ```ts title="agent/tools/list_schedules.ts"
143
+ import { defineTool } from "eve/tools";
144
+ import { z } from "zod";
145
+ import { scheduleStore } from "../lib/schedule-store.js";
146
+ import { requireScheduleOwner } from "../lib/tenant.js";
147
+
148
+ export default defineTool({
149
+ description: "List this tenant's dynamic schedules and their latest status.",
150
+ inputSchema: z.object({}),
151
+ async execute(_input, ctx) {
152
+ return await scheduleStore.list(requireScheduleOwner(ctx));
153
+ },
154
+ });
155
+ ```
156
+
157
+ ```ts title="agent/tools/update_schedule.ts"
158
+ import { defineTool } from "eve/tools";
159
+ import { z } from "zod";
160
+ import { scheduleStore } from "../lib/schedule-store.js";
161
+ import { requireScheduleOwner } from "../lib/tenant.js";
162
+
163
+ export default defineTool({
164
+ description: "Change, pause, or resume one of this tenant's schedules.",
165
+ inputSchema: z.object({
166
+ id: z.string().uuid(),
167
+ prompt: z.string().min(1).max(8000).optional(),
168
+ channelId: z.string().min(1).optional(),
169
+ nextRunAt: z.string().datetime({ offset: true }).optional(),
170
+ everyMinutes: z.number().int().min(1).max(525600).nullable().optional(),
171
+ enabled: z.boolean().optional(),
172
+ }),
173
+ async execute({ id, nextRunAt, ...patch }, ctx) {
174
+ return await scheduleStore.update(requireScheduleOwner(ctx), id, {
175
+ ...patch,
176
+ ...(nextRunAt ? { nextRunAt: new Date(nextRunAt) } : {}),
177
+ });
178
+ },
179
+ });
180
+ ```
181
+
182
+ ```ts title="agent/tools/delete_schedule.ts"
183
+ import { defineTool } from "eve/tools";
184
+ import { always } from "eve/tools/approval";
185
+ import { z } from "zod";
186
+ import { scheduleStore } from "../lib/schedule-store.js";
187
+ import { requireScheduleOwner } from "../lib/tenant.js";
188
+
189
+ export default defineTool({
190
+ description: "Permanently delete one of this tenant's schedules.",
191
+ inputSchema: z.object({ id: z.string().uuid() }),
192
+ approval: always(),
193
+ async execute({ id }, ctx) {
194
+ return { deleted: await scheduleStore.delete(requireScheduleOwner(ctx), id) };
195
+ },
196
+ });
197
+ ```
198
+
199
+ ## Supply the schedule adapter
200
+
201
+ The eve-facing implementation depends on this shape, not a database schema:
202
+
203
+ ```ts title="agent/lib/schedule-store.ts"
204
+ import type { SessionAuthContext } from "eve/context";
205
+
206
+ export interface ScheduleOwner {
207
+ tenantId: string;
208
+ userId: string;
209
+ auth: SessionAuthContext;
210
+ }
211
+
212
+ export interface ClaimedSchedule {
213
+ id: string;
214
+ leaseToken: string;
215
+ tenantId: string;
216
+ ownerId: string;
217
+ ownerRole: string;
218
+ authenticator: string;
219
+ issuer?: string;
220
+ prompt: string;
221
+ channelId: string;
222
+ everyMinutes: number | null;
223
+ }
224
+
225
+ export interface ScheduleStore {
226
+ create(owner: ScheduleOwner, input: unknown): Promise<unknown>;
227
+ list(owner: ScheduleOwner): Promise<unknown[]>;
228
+ update(owner: ScheduleOwner, id: string, patch: unknown): Promise<unknown>;
229
+ delete(owner: ScheduleOwner, id: string): Promise<boolean>;
230
+ claimDue(options: { now: Date; limit: number; leaseForMs: number }): Promise<ClaimedSchedule[]>;
231
+ complete(job: ClaimedSchedule): Promise<void>;
232
+ release(job: ClaimedSchedule, failure: { error: unknown; retryAt: Date }): Promise<void>;
233
+ }
234
+
235
+ export { scheduleStore } from "../../lib/schedule-store.js";
236
+ ```
237
+
238
+ Implement that adapter with whichever durable store already belongs to your application. It must preserve a few semantics:
239
+
240
+ - user-facing CRUD is always tenant-scoped;
241
+ - `claimDue` atomically leases rows so overlapping minute ticks do not claim the same work;
242
+ - dispatch revalidates the owner and destination before returning a job;
243
+ - `complete` disables one-time rows or computes the next recurring run;
244
+ - expired leases are recoverable.
245
+
246
+ Delivery is at least once. A crash after `receive` succeeds but before `complete` can dispatch again, so side-effecting tasks need application-level idempotency.
247
+
248
+ ## Scheduling instructions
249
+
250
+ ```md title="agent/instructions.md"
251
+ Before creating a schedule, confirm the user's time zone and destination.
252
+ Convert the first run to ISO 8601 with an explicit offset. Use everyMinutes only
253
+ for repeating work and null for a one-time run. List schedules before changing
254
+ an ambiguous one.
255
+ ```
256
+
257
+ The eve-specific core is small: four tools, one one-minute `defineSchedule`, and proactive `receive`. Storage and recurrence policy stay behind the application's adapter.
@@ -0,0 +1,9 @@
1
+ {
2
+ "title": "Patterns",
3
+ "pages": [
4
+ "multi-tenant-memory",
5
+ "dynamic-scheduling",
6
+ "multi-tenant-auth",
7
+ "multi-tenant-approvals"
8
+ ]
9
+ }