eve 0.30.0 → 0.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/src/channel/routes.d.ts +11 -4
- package/dist/src/channel/send.js +1 -1
- package/dist/src/channel/types.d.ts +6 -3
- package/dist/src/compiler/extension-compatibility.d.ts +10 -10
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/execution/agent-handle-dispatch.d.ts +32 -0
- package/dist/src/execution/agent-handle-dispatch.js +1 -0
- package/dist/src/execution/cancel-descendant-turns-step.d.ts +1 -1
- package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
- package/dist/src/execution/delegated-parent-notification.d.ts +2 -2
- package/dist/src/execution/delegated-parent-result.d.ts +4 -4
- package/dist/src/execution/delegated-parent-result.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.d.ts +8 -6
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/dispatch-workflow-runtime-actions-step.d.ts +2 -2
- package/dist/src/execution/dispatch-workflow-runtime-actions-step.js +1 -1
- package/dist/src/execution/durable-session-migrations/turn-workflow.d.ts +10 -2
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/remote-agent-dispatch.d.ts +7 -2
- package/dist/src/execution/remote-agent-dispatch.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/session-callback-step.js +1 -1
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/turn-execution-cursor.d.ts +3 -3
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/agent-handle-errors.d.ts +25 -0
- package/dist/src/harness/agent-handle-errors.js +1 -0
- package/dist/src/harness/handles/operation-id.d.ts +15 -0
- package/dist/src/harness/handles/operation-id.js +1 -0
- package/dist/src/harness/handles/prompt.d.ts +21 -0
- package/dist/src/harness/handles/prompt.js +2 -0
- package/dist/src/harness/handles/query.d.ts +41 -0
- package/dist/src/harness/handles/query.js +1 -0
- package/dist/src/harness/handles/state-key.d.ts +8 -0
- package/dist/src/harness/handles/state-key.js +1 -0
- package/dist/src/harness/handles/store.d.ts +132 -0
- package/dist/src/harness/handles/store.js +1 -0
- package/dist/src/harness/handles/transitions.d.ts +107 -0
- package/dist/src/harness/handles/transitions.js +1 -0
- package/dist/src/harness/input-requests.js +1 -1
- package/dist/src/harness/runtime-actions.d.ts +4 -25
- package/dist/src/harness/runtime-actions.js +1 -1
- package/dist/src/harness/tool-loop.d.ts +22 -0
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/harness/types.d.ts +6 -0
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/protocol/agent-handle-error.d.ts +13 -0
- package/dist/src/protocol/agent-handle-error.js +1 -0
- package/dist/src/public/channels/eve.js +1 -1
- package/dist/src/runtime/actions/results.d.ts +6 -0
- package/dist/src/runtime/actions/results.js +1 -0
- package/dist/src/runtime/actions/types.d.ts +40 -7
- package/dist/src/runtime/actions/types.js +1 -1
- package/dist/src/runtime/session-callback-route.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/package.json +1 -1
- package/dist/src/harness/agent-handles.d.ts +0 -238
- package/dist/src/harness/agent-handles.js +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{dispatchRuntimeActionsStep}from"#execution/dispatch-runtime-actions-step.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{turnStep}from"#execution/workflow-steps.js";import{createHook,getWorkflowMetadata,sleep}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook,isHookConflictError}from"#execution/hook-ownership.js";import{activeTurnId}from"#harness/active-turn-id.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{sendTurnControlStep}from"#execution/turn-control-protocol.js";import{isInboxSubagentResultFromRunningHandle}from"#harness/handles/query.js";import{cancelDescendantTurnsStep}from"#execution/cancel-descendant-turns-step.js";import{dispatchWorkflowRuntimeActionsStep}from"#execution/dispatch-workflow-runtime-actions-step.js";import{migrateTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{runProxySubagentEventStep}from"#execution/subagent-event-proxy-step.js";import{createTurnCancellationControl}from"#execution/turn-cancellation-control.js";import{TurnExecutionCursor}from"#execution/turn-execution-cursor.js";import{resolveRuntimeActionResultsForKeys}from"#runtime/actions/results.js";const TASK_MODE_WAIT_ERROR_MESSAGE="Task mode cannot wait for follow-up input (`next: null`).";function canSettleCancelledTurnAsPark(e){return e.mode===`conversation`||e.stepInput.sessionState.continuationToken!==``}async function turnWorkflow(e){"use workflow";let t=migrateTurnWorkflowInput(e);return t.driverCapabilities?.turnInbox===!0?runTurnOwnedWorkflow(t):runLegacyTurnWorkflow(t)}async function runTurnOwnedWorkflow(a){let s=createHook({token:`${a.completionToken}:inbox`}),c=s[Symbol.asyncIterator](),l=new TurnExecutionCursor({controlToken:a.completionToken,parentWritable:a.stepInput.parentWritable,serializedContext:a.stepInput.serializedContext,sessionState:a.stepInput.sessionState}),u=0,nextDeliveryRequestId=()=>`${s.token}:delivery:${String(u++)}`,d=[],f=a.stepInput.input,p=!1,m;try{try{await claimHookOwnership(s),p=!0}catch(e){if(isHookConflictError(e))return;throw e}for(a.driverCapabilities?.cancelledTurnSettle===!0&&canSettleCancelledTurnAsPark(a)&&(m=await createTurnCancellationControl({expectedTurnId:activeTurnId(a.stepInput.sessionState.emissionState),sessionId:a.stepInput.sessionState.sessionId}));;){let r=await turnStep(l.createStepInput(f,m?.signal)),o=r.action===`dispatch-workflow-runtime-actions`||r.action===`park`?r.pendingRuntimeActionKeys:void 0;if(r.action===`cancelled`||m?.signal.aborted===!0&&o===void 0){await finishCancelledTurn({bufferedDeliveries:d,cancellation:m,cursor:l});return}if(r.sleepDurationMs!==void 0&&await waitForTurnSleep(r.sleepDurationMs,m)===`cancel`){await finishCancelledTurn({bufferedDeliveries:d,cancellation:m,cursor:l});return}if(r.action===`done`){await m?.dispose(),await l.finish(r,{kind:`done`,output:r.output??``,isError:r.isError,usage:r.usage},d);return}if(o!==void 0){await l.adopt(r);let n=await(r.action===`dispatch-workflow-runtime-actions`?dispatchWorkflowRuntimeActionsStep:dispatchRuntimeActionsStep)({callbackBaseUrl:resolveWorkflowCallbackBaseUrl(getWorkflowMetadata().url),parentContinuationToken:s.token,parentWritable:l.parentWritable,serializedContext:l.serializedContext,sessionState:l.sessionState});await l.adopt(n);let a=await waitForRuntimeActionResults({bufferedDeliveries:d,cancellation:m,cursor:l,inboxToken:s.token,initialResults:n.results,iterator:c,nextDeliveryRequestId,pendingActionKeys:o});if(a===`cancelled`){f=void 0;continue}if(a===`cancel-turn`){await finishCancelledTurn({bufferedDeliveries:d,cancellation:m,cursor:l});return}f={kind:`runtime-action-result`,results:a};continue}if(r.action===`park`){if(!(r.hasPendingAuthorization||r.hasPendingInputBatch&&a.capabilities?.requestInput===!0||a.mode===`conversation`))throw Error(TASK_MODE_WAIT_ERROR_MESSAGE);await m?.dispose(),await l.finish(r,{authorizationNames:r.authorizationNames,kind:`park`},d);return}await l.adopt(r),f=void 0}}catch(e){throw await l.send({error:normalizeSerializableError(e),kind:`turn-error`}),e}finally{m!==void 0&&await m.dispose(),p&&await disposeHook(s)}}async function finishCancelledTurn(e){await cancelDescendantTurnsStep({serializedContext:e.cursor.serializedContext,sessionState:e.cursor.sessionState}),await e.cancellation?.dispose(),await e.cursor.finish({sessionState:e.cursor.sessionState},{cancelled:!0,kind:`park`},e.bufferedDeliveries)}async function waitForTurnSleep(e,t){if(t?.signal.aborted===!0)return`cancel`;let n=sleep(e).then(()=>`slept`);return t===void 0?n:Promise.race([n,t.requested])}async function waitForRuntimeActionResults(e){let t,n=[...e.initialResults];for(;;){let r=resolveRuntimeActionResultsForKeys({pendingKeys:e.pendingActionKeys,results:n});if(r!==void 0)return t!==void 0&&await e.cursor.send({kind:`turn-delivery-cancelled`,requestId:t}),r;e.cursor.sessionState.hasProxyInputRequests&&t===void 0&&(t=e.nextDeliveryRequestId(),await e.cursor.send({continuationToken:e.cursor.sessionState.continuationToken,inboxToken:e.inboxToken,kind:`turn-delivery-request`,requestId:t}));let i=e.iterator.next();i.catch(()=>{});let a=await(e.cancellation===void 0?i:Promise.race([i,e.cancellation.requested]));if(a===`cancel`)return t!==void 0&&await e.cursor.send({kind:`turn-delivery-cancelled`,requestId:t}),`cancelled`;if(a.done)throw Error(`Turn inbox closed before runtime actions completed.`);let o=a.value;if(o.kind===`runtime-action-result`){let t=e.cursor.sessionState.snapshot?.session.state;n.push(...o.results.filter(e=>isInboxSubagentResultFromRunningHandle(t,e)));continue}if(o.kind===`subagent-input-request`||o.kind===`subagent-authorization-event`){let t=await runProxySubagentEventStep({hookPayload:o,parentWritable:e.cursor.parentWritable,serializedContext:e.cursor.serializedContext,sessionState:e.cursor.sessionState});await e.cursor.adopt(t);continue}if(o.kind===`driver-delivery`&&o.requestId===t){await e.cursor.send({kind:`turn-delivery-accepted`,requestId:o.requestId}),t=void 0;let n=await routeDeliverToChildren({auth:o.delivery.auth,parentWritable:e.cursor.parentWritable,payloads:o.delivery.payloads,sessionState:e.cursor.sessionState});if(n.kind===`cancel-turn`)return n.kind;n.remainder!==void 0&&e.bufferedDeliveries.push({...o.delivery,payloads:[n.remainder]})}}}async function runLegacyTurnWorkflow(e){let t=e.stepInput;try{for(;;){let r=await turnStep(t);if(r.action!==`cancelled`&&r.sleepDurationMs!==void 0&&await sleep(r.sleepDurationMs),r.action===`done`){await sendTurnControlStep({controlToken:e.completionToken,payload:{action:{kind:`done`,output:r.output??``,isError:r.isError,serializedContext:r.serializedContext,sessionState:r.sessionState,usage:r.usage},kind:`turn-result`}});return}if(r.action===`dispatch-workflow-runtime-actions`){await sendTurnControlStep({controlToken:e.completionToken,payload:{action:{kind:`dispatch-workflow-runtime-actions`,pendingActionKeys:r.pendingRuntimeActionKeys,serializedContext:r.serializedContext,sessionState:r.sessionState},kind:`turn-result`}});return}if(r.action===`park`){let t=r.pendingRuntimeActionKeys;if(!(t!==void 0||r.hasPendingAuthorization||r.hasPendingInputBatch&&e.capabilities?.requestInput===!0||e.mode===`conversation`))throw Error(TASK_MODE_WAIT_ERROR_MESSAGE);let n=t===void 0?{kind:`park`,serializedContext:r.serializedContext,sessionState:r.sessionState,authorizationNames:r.authorizationNames}:{kind:`dispatch-runtime-actions`,pendingActionKeys:t,serializedContext:r.serializedContext,sessionState:r.sessionState};await sendTurnControlStep({controlToken:e.completionToken,payload:{action:n,kind:`turn-result`}});return}t={input:void 0,parentWritable:t.parentWritable,serializedContext:r.serializedContext,sessionState:r.sessionState}}}catch(t){throw await sendTurnControlStep({controlToken:e.completionToken,payload:{error:normalizeSerializableError(t),kind:`turn-error`}}),t}}export{turnWorkflow};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{callAdapterEventHandler,defaultDeliverResult}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ModeKey,SessionDynamicSubagentRuntimeRevisionKey,SessionDynamicToolRuntimeRevisionKey}from"#context/keys.js";import{createAuthorizationCompletedEvent,createSessionStartedEvent,encodeMessageStreamEvent,stampMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{getHarnessEmissionState}from"#harness/emission.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{createWorkflowRuntime,startWorkflowPreferLatest,turnWorkflowReference}from"#execution/workflow-runtime.js";import{getPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{dispatchDynamicSubagentEvent,refreshDynamicSessionSubagentsForRuntimeRevision}from"#context/dynamic-subagent-lifecycle.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{resumeHook}from"#internal/workflow/runtime.js";import{coalesceTurnInputs}from"#harness/messages.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{preserveSerializedAgentTraceState}from"#tracing/agent-trace-context-store.js";import{getPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{getRuntimeActionKeysFromWorkflowInterrupt,isWorkflowRuntimeActionInterrupt}from"#harness/workflow-runtime-action-state.js";import{dispatchDynamicModelEvent}from"#context/dynamic-model-lifecycle.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{setChannelContext}from"#execution/channel-context.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{runStep}from"#context/run-step.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{hasPendingInputBatch}from"#harness/input-requests.js";import{routeDeliverPayload}from"#execution/subagent-hitl-proxy.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey,clearPendingAuthorization,getPendingAuthorization}from"#harness/authorization.js";import{isTurnCancellation,throwIfTurnAborted}from"#harness/turn-cancellation.js";import{createTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{buildTurnAttributes,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{dispatchDynamicInstructionEvent}from"#context/dynamic-instruction-lifecycle.js";import{dispatchDynamicSkillEvent}from"#context/dynamic-skill-lifecycle.js";import{dispatchDynamicToolEvent,refreshDynamicSessionToolsForRuntimeRevision}from"#context/dynamic-tool-lifecycle.js";import{readTurnSleepDurationMs}from"#harness/turn-sleep.js";import{getTurnUsageState,toUsage}from"#harness/turn-tag-state.js";import{getRuntimeActionRequestKey}from"#runtime/actions/keys.js";import{buildRuntimeIdentity,createExecutionNodeStep}from"#execution/node-step.js";import{recordSubagentUsageSpans}from"#execution/subagent-usage-span.js";import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";async function turnStep(a){"use step";let o=a,s=await readDurableSession(o.sessionState),c=await deserializeContext(o.serializedContext),l=c.require(ChannelKey),u=c.require(BundleKey),d=resolveEffectiveAgentRuntime(u,c);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&c.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(t.url))}catch{}let f=getPendingAuthorization(s.state),p;if(f&&o.input?.kind===`deliver`){let e=[],t=[],n=[];for(let r of o.input.payloads){let i=r.authorizationCallback;if(i){let n=f.challenges.find(e=>e.name===i.connectionName);n&&(e.push({name:n.name,resume:n.resume,callback:i.callback,hookUrl:n.hookUrl}),t.push({name:n.name,authorization:n.challenge}))}else n.push(r)}e.length>0&&(c.set(PendingAuthorizationResultKey,e),s={...s,state:clearPendingAuthorization(s.state,e.map(e=>e.name))},p=t,o=n.length>0?{...o,input:{...o.input,payloads:n}}:{...o,input:void 0})}o.input?.kind===`deliver`&&o.input.auth!==void 0&&c.set(AuthKey,o.input.auth??null);let m=hydrateDurableSession({compactionOverrides:{thresholdPercent:d.thresholdPercent},durable:s,turnAgent:d.turnAgent}),h=buildAdapterContext(l,c),g;if(o.input?.kind===`deliver`){let e=[];for(let n of o.input.payloads){let r=l.deliver?await l.deliver(n,h):defaultDeliverResult(n);r!=null&&e.push(r)}g=e.length===0?void 0:e.reduce(coalesceTurnInputs)}else o.input?.kind===`runtime-action-result`&&(recordSubagentUsageSpans(o.input.results),g={runtimeActionResults:o.input.results});if(o.input?.kind===`deliver`&&setChannelContext(c,{...l,state:{...h.state}}),o.input?.kind===`deliver`&&g===void 0){let e=reconcileSessionContinuationToken(c,m),t=serializeContext(c),n=e===m?o.sessionState:createDurableSessionState({session:e});return{action:`park`,...derivePendingState(e),serializedContext:t,sessionState:n}}let _=u.hookRegistry,v=u.resolvedAgent.dynamicInstructionsResolvers??[],y=u.resolvedAgent.dynamicSkillResolvers??[],b=u.subagentRegistry.dynamicResolvers??[],x=u.resolvedAgent.dynamicToolResolvers??[],S={...u.graph.root,turnAgent:d.turnAgent},C=buildRuntimeIdentity(S),w=process.env.VERCEL_DEPLOYMENT_ID?.trim(),T=w?`deployment:${w}`:await resolveRuntimeCompiledArtifactsVersionedCacheKey(u.compiledArtifactsSource);if(!getHarnessEmissionState(m.state).sessionStarted)c.set(SessionDynamicSubagentRuntimeRevisionKey,T),c.set(SessionDynamicToolRuntimeRevisionKey,T);else{let e=createSessionStartedEvent({runtime:C});await Promise.all([refreshDynamicSessionSubagentsForRuntimeRevision({ctx:c,resolvers:b,event:e,messages:m.history,runtimeRevision:T}),refreshDynamicSessionToolsForRuntimeRevision({ctx:c,resolvers:x,event:e,messages:m.history,runtimeRevision:T})])}let E=o.parentWritable.getWriter(),emit=async t=>{let n=await callAdapterEventHandler(l,t,h);setChannelContext(c,{...l,state:{...h.state}});let r=stampMessageStreamEvent(n);return await E.write(encodeMessageStreamEvent(r)),r},handleEvent=async(e,t)=>{let n=await emit(e);await dispatchStreamEventHooks({ctx:c,registry:_,event:n}),n.type!==`step.started`&&await dispatchDynamicModelEvent({ctx:c,dynamicModel:d.turnAgent.dynamicModel,event:n,fallback:d.turnAgent.model,messages:t??[],scope:{moduleMap:u.moduleMap,nodeId:u.nodeId}}),await dispatchDynamicSubagentEvent({ctx:c,resolvers:b,event:n,messages:t??[]}),await dispatchDynamicToolEvent({ctx:c,resolvers:x,event:n,messages:t??[]}),await dispatchDynamicSkillEvent({ctx:c,resolvers:y,event:n,messages:t??[]}),await dispatchDynamicInstructionEvent({ctx:c,resolvers:v,event:n,messages:t??[]})},D=c.require(ModeKey),O;try{throwIfTurnAborted(o.abortSignal),O=await runStep(c,m,async e=>{let t=resolveEffectiveOutputSchema({agentOutputSchema:d.turnAgent.outputSchema,input:g,mode:D,session:e});if(p){let e=getHarnessEmissionState(t.state);for(let{name:t,authorization:n}of p)await handleEvent(createAuthorizationCompletedEvent({authorization:n,name:t,outcome:`authorized`,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId}))}let n=c.get(CapabilitiesKey);return(async(e,t)=>{let r=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:d.thresholdPercent},session:e,turnAgent:d.turnAgent});return createExecutionNodeStep({abortSignal:o.abortSignal,capabilities:n,clearOnly:o.input?.kind===`clear`,compactOnly:o.input?.kind===`compact`,createRuntime:createWorkflowRuntime,handleEvent,mode:D,modelResolutionScope:{moduleMap:u.moduleMap,nodeId:u.nodeId},node:S,workflowMaxSubagents:r.workflowMaxSubagents})(r,t)})(t,g)})}catch(e){if(!isTurnCancellation(e))throw e;return E.releaseLock(),{action:`cancelled`,serializedContext:preserveSerializedAgentTraceState(o.serializedContext,serializeContext(c)),sessionState:o.sessionState}}let k=reconcileSessionContinuationToken(c,O.session),A=serializeContext(c);O={...O,session:k};let j=createDurableSessionState({session:O.session}),M=readTurnSleepDurationMs(c),N=M===void 0?{}:{sleepDurationMs:M};if(O.next!==null&&typeof O.next==`object`&&`done`in O.next){await E.close();let e=getTurnUsageState(O.session.state)?.session;return{action:`done`,output:O.next.output,isError:O.next.isError,...N,serializedContext:A,sessionState:j,usage:e===void 0?void 0:toUsage(e)}}if(O.next===null){E.releaseLock();let e=getPendingWorkflowInterrupt(O.session.state);return e!==void 0&&isWorkflowRuntimeActionInterrupt(e.interrupt)?{action:`dispatch-workflow-runtime-actions`,pendingRuntimeActionKeys:getRuntimeActionKeysFromWorkflowInterrupt(e.interrupt),...N,serializedContext:A,sessionState:j}:{action:`park`,...derivePendingState(O.session),...N,serializedContext:A,sessionState:j}}return E.releaseLock(),{action:`continue`,...N,serializedContext:A,sessionState:j}}function derivePendingState(e){let t=getPendingRuntimeActionBatch(e.state),n=getPendingAuthorization(e.state),r={authorizationNames:n?.challenges.map(e=>e.name),hasPendingAuthorization:n!==void 0,hasPendingInputBatch:hasPendingInputBatch(e.state)};return t===void 0?r:{...r,pendingRuntimeActionKeys:t.actions.map(e=>getRuntimeActionRequestKey(e))}}function resolveEffectiveOutputSchema(e){let{agentOutputSchema:t,input:n,mode:r,session:i}=e;return n?.outputSchema===void 0?r===`task`&&i.outputSchema===void 0&&t!==void 0?{...i,outputSchema:t}:i:{...i,outputSchema:n.outputSchema}}async function routeProxiedDeliverStep(e){"use step";let t=await readDurableSession(e.sessionState),n=routeDeliverPayload({payload:e.payload,state:t.state});for(let t of n.forChildren)await resumeHook(t.childContinuationToken,{auth:e.auth,kind:`deliver`,payloads:[t.payload]});return n.parentAction??{kind:`continue`,remainder:n.forSelf}}async function dispatchTurnStep(e){"use step";return{runId:(await startWorkflowPreferLatest(turnWorkflowReference,[createTurnWorkflowInput(e)],{allowReservedAttributes:!0,attributes:normalizeEveAttributes(buildTurnAttributes({parentSessionId:e.sessionState.sessionId,requestId:e.delivery.kind===`deliver`?e.delivery.requestId:void 0,rootSessionId:readRootSessionId(e.serializedContext)??e.sessionState.sessionId}))})).runId}}export{dispatchTurnStep,resolveEffectiveOutputSchema,routeProxiedDeliverStep,turnStep};
|
|
1
|
+
import{callAdapterEventHandler,defaultDeliverResult}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ModeKey,SessionDynamicSubagentRuntimeRevisionKey,SessionDynamicToolRuntimeRevisionKey}from"#context/keys.js";import{createAuthorizationCompletedEvent,createSessionStartedEvent,encodeMessageStreamEvent,stampMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{getHarnessEmissionState}from"#harness/emission.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{createWorkflowRuntime,startWorkflowPreferLatest,turnWorkflowReference}from"#execution/workflow-runtime.js";import{dispatchDynamicSubagentEvent,refreshDynamicSessionSubagentsForRuntimeRevision}from"#context/dynamic-subagent-lifecycle.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{resumeHook}from"#internal/workflow/runtime.js";import{coalesceTurnInputs}from"#harness/messages.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{getPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{preserveSerializedAgentTraceState}from"#tracing/agent-trace-context-store.js";import{getPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{getRuntimeActionKeysFromWorkflowInterrupt,isWorkflowRuntimeActionInterrupt}from"#harness/workflow-runtime-action-state.js";import{dispatchDynamicModelEvent}from"#context/dynamic-model-lifecycle.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{setChannelContext}from"#execution/channel-context.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{runStep}from"#context/run-step.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{hasPendingInputBatch}from"#harness/input-requests.js";import{routeDeliverPayload}from"#execution/subagent-hitl-proxy.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey,clearPendingAuthorization,getPendingAuthorization}from"#harness/authorization.js";import{isTurnCancellation,throwIfTurnAborted}from"#harness/turn-cancellation.js";import{createTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{buildTurnAttributes,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{dispatchDynamicInstructionEvent}from"#context/dynamic-instruction-lifecycle.js";import{dispatchDynamicSkillEvent}from"#context/dynamic-skill-lifecycle.js";import{dispatchDynamicToolEvent,refreshDynamicSessionToolsForRuntimeRevision}from"#context/dynamic-tool-lifecycle.js";import{readTurnSleepDurationMs}from"#harness/turn-sleep.js";import{getTurnUsageState,toUsage}from"#harness/turn-tag-state.js";import{getRuntimeActionRequestKey}from"#runtime/actions/keys.js";import{buildRuntimeIdentity,createExecutionNodeStep}from"#execution/node-step.js";import{recordSubagentUsageSpans}from"#execution/subagent-usage-span.js";import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";async function turnStep(a){"use step";let o=a,s=await readDurableSession(o.sessionState),c=await deserializeContext(o.serializedContext),l=c.require(ChannelKey),u=c.require(BundleKey),d=resolveEffectiveAgentRuntime(u,c);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&c.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(t.url))}catch{}let f=getPendingAuthorization(s.state),p;if(f&&o.input?.kind===`deliver`){let e=[],t=[],n=[];for(let r of o.input.payloads){let i=r.authorizationCallback;if(i){let n=f.challenges.find(e=>e.name===i.connectionName);n&&(e.push({name:n.name,resume:n.resume,callback:i.callback,hookUrl:n.hookUrl}),t.push({name:n.name,authorization:n.challenge}))}else n.push(r)}e.length>0&&(c.set(PendingAuthorizationResultKey,e),s={...s,state:clearPendingAuthorization(s.state,e.map(e=>e.name))},p=t,o=n.length>0?{...o,input:{...o.input,payloads:n}}:{...o,input:void 0})}o.input?.kind===`deliver`&&o.input.auth!==void 0&&c.set(AuthKey,o.input.auth??null);let m=hydrateDurableSession({compactionOverrides:{thresholdPercent:d.thresholdPercent},durable:s,turnAgent:d.turnAgent}),h=buildAdapterContext(l,c),g;if(o.input?.kind===`deliver`){let e=[];for(let n of o.input.payloads){let r=l.deliver?await l.deliver(n,h):defaultDeliverResult(n);r!=null&&e.push(r)}g=e.length===0?void 0:e.reduce(coalesceTurnInputs)}else o.input?.kind===`runtime-action-result`&&(recordSubagentUsageSpans(o.input.results),g={runtimeActionResults:o.input.results});if(o.input?.kind===`deliver`&&setChannelContext(c,{...l,state:{...h.state}}),o.input?.kind===`deliver`&&g===void 0){let e=reconcileSessionContinuationToken(c,m),t=serializeContext(c),n=e===m?o.sessionState:createDurableSessionState({session:e});return{action:`park`,...derivePendingState(e),serializedContext:t,sessionState:n}}let _=u.hookRegistry,v=u.resolvedAgent.dynamicInstructionsResolvers??[],y=u.resolvedAgent.dynamicSkillResolvers??[],b=u.subagentRegistry.dynamicResolvers??[],x=u.resolvedAgent.dynamicToolResolvers??[],S={...u.graph.root,turnAgent:d.turnAgent},C=buildRuntimeIdentity(S),w=process.env.VERCEL_DEPLOYMENT_ID?.trim(),T=w?`deployment:${w}`:await resolveRuntimeCompiledArtifactsVersionedCacheKey(u.compiledArtifactsSource);if(!getHarnessEmissionState(m.state).sessionStarted)c.set(SessionDynamicSubagentRuntimeRevisionKey,T),c.set(SessionDynamicToolRuntimeRevisionKey,T);else{let e=createSessionStartedEvent({runtime:C});await Promise.all([refreshDynamicSessionSubagentsForRuntimeRevision({ctx:c,resolvers:b,event:e,messages:m.history,runtimeRevision:T}),refreshDynamicSessionToolsForRuntimeRevision({ctx:c,resolvers:x,event:e,messages:m.history,runtimeRevision:T})])}let E=o.parentWritable.getWriter(),emit=async t=>{let n=await callAdapterEventHandler(l,t,h);setChannelContext(c,{...l,state:{...h.state}});let r=stampMessageStreamEvent(n);return await E.write(encodeMessageStreamEvent(r)),r},handleEvent=async(e,t)=>{let n=await emit(e);await dispatchStreamEventHooks({ctx:c,registry:_,event:n}),n.type!==`step.started`&&await dispatchDynamicModelEvent({ctx:c,dynamicModel:d.turnAgent.dynamicModel,event:n,fallback:d.turnAgent.model,messages:t??[],scope:{moduleMap:u.moduleMap,nodeId:u.nodeId}}),await dispatchDynamicSubagentEvent({ctx:c,resolvers:b,event:n,messages:t??[]}),await dispatchDynamicToolEvent({ctx:c,resolvers:x,event:n,messages:t??[]}),await dispatchDynamicSkillEvent({ctx:c,resolvers:y,event:n,messages:t??[]}),await dispatchDynamicInstructionEvent({ctx:c,resolvers:v,event:n,messages:t??[]})},D=c.require(ModeKey),O;try{throwIfTurnAborted(o.abortSignal),O=await runStep(c,m,async e=>{let t=resolveEffectiveOutputSchema({agentOutputSchema:d.turnAgent.outputSchema,input:g,mode:D,session:e});if(p){let e=getHarnessEmissionState(t.state);for(let{name:t,authorization:n}of p)await handleEvent(createAuthorizationCompletedEvent({authorization:n,name:t,outcome:`authorized`,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId}))}let n=c.get(CapabilitiesKey);return(async(e,t)=>{let r=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:d.thresholdPercent},session:e,turnAgent:d.turnAgent});return createExecutionNodeStep({abortSignal:o.abortSignal,capabilities:n,clearOnly:o.input?.kind===`clear`,compactOnly:o.input?.kind===`compact`,createRuntime:createWorkflowRuntime,handleEvent,mode:D,modelResolutionScope:{moduleMap:u.moduleMap,nodeId:u.nodeId},node:S,workflowMaxSubagents:r.workflowMaxSubagents})(r,t)})(t,g)})}catch(e){if(!isTurnCancellation(e))throw e;return E.releaseLock(),{action:`cancelled`,serializedContext:preserveSerializedAgentTraceState(o.serializedContext,serializeContext(c)),sessionState:o.sessionState}}let k=reconcileSessionContinuationToken(c,O.session),A=serializeContext(c);O={...O,session:k};let j=createDurableSessionState({session:O.session}),M=readTurnSleepDurationMs(c),N=M===void 0?{}:{sleepDurationMs:M};if(O.next!==null&&typeof O.next==`object`&&`done`in O.next){await E.close();let e=getTurnUsageState(O.session.state)?.session;return{action:`done`,output:O.next.output,isError:O.next.isError,...N,serializedContext:A,sessionState:j,usage:e===void 0?void 0:toUsage(e)}}if(O.next===null){E.releaseLock();let e=getPendingWorkflowInterrupt(O.session.state);return e!==void 0&&isWorkflowRuntimeActionInterrupt(e.interrupt)?{action:`dispatch-workflow-runtime-actions`,pendingRuntimeActionKeys:getRuntimeActionKeysFromWorkflowInterrupt(e.interrupt),...N,serializedContext:A,sessionState:j}:{action:`park`,...derivePendingState(O.session),...N,serializedContext:A,sessionState:j}}return E.releaseLock(),{action:`continue`,...N,serializedContext:A,sessionState:j}}function derivePendingState(e){let t=getPendingRuntimeActionBatch(e.state),n=getPendingAuthorization(e.state),r={authorizationNames:n?.challenges.map(e=>e.name),hasPendingAuthorization:n!==void 0,hasPendingInputBatch:hasPendingInputBatch(e.state)};return t===void 0?r:{...r,pendingRuntimeActionKeys:t.actions.map(e=>getRuntimeActionRequestKey(e))}}function resolveEffectiveOutputSchema(e){let{agentOutputSchema:t,input:n,mode:r,session:i}=e;return n?.outputSchema===void 0?r===`task`&&i.outputSchema===void 0&&t!==void 0?{...i,outputSchema:t}:i:{...i,outputSchema:n.outputSchema}}async function routeProxiedDeliverStep(e){"use step";let t=await readDurableSession(e.sessionState),n=routeDeliverPayload({payload:e.payload,state:t.state});for(let t of n.forChildren)await resumeHook(t.childContinuationToken,{auth:e.auth,kind:`deliver`,payloads:[t.payload]});return n.parentAction??{kind:`continue`,remainder:n.forSelf}}async function dispatchTurnStep(e){"use step";return{runId:(await startWorkflowPreferLatest(turnWorkflowReference,[createTurnWorkflowInput(e)],{allowReservedAttributes:!0,attributes:normalizeEveAttributes(buildTurnAttributes({parentSessionId:e.sessionState.sessionId,requestId:e.delivery.kind===`deliver`?e.delivery.requestId:void 0,rootSessionId:readRootSessionId(e.serializedContext)??e.sessionState.sessionId}))})).runId}}export{dispatchTurnStep,resolveEffectiveOutputSchema,routeProxiedDeliverStep,turnStep};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error codes carried by delegated agent (`subagent-result`) failures.
|
|
3
|
+
*
|
|
4
|
+
* Every producer that mints a code imports from this module, so the set
|
|
5
|
+
* stays closed. Codes are diagnostic only: child lifecycle is owned by the
|
|
6
|
+
* agent handle store and is never inferred from an error code.
|
|
7
|
+
*/
|
|
8
|
+
/** Error code for a requested agent id that is not registered. */
|
|
9
|
+
export declare const AGENT_UNKNOWN = "AGENT_UNKNOWN";
|
|
10
|
+
/** Error code for an agent id invoked through the wrong subagent tool. */
|
|
11
|
+
export declare const AGENT_MISMATCH = "AGENT_MISMATCH";
|
|
12
|
+
/** Error code for a registered agent that cannot be reached. */
|
|
13
|
+
export declare const AGENT_UNREACHABLE = "AGENT_UNREACHABLE";
|
|
14
|
+
/** Error code for an agent that is starting or already running a turn. */
|
|
15
|
+
export declare const AGENT_BUSY = "AGENT_BUSY";
|
|
16
|
+
/** Error code for a local subagent that failed to start. */
|
|
17
|
+
export declare const SUBAGENT_START_FAILED = "SUBAGENT_START_FAILED";
|
|
18
|
+
/** Error code for a delegated subagent whose execution threw. */
|
|
19
|
+
export declare const SUBAGENT_EXECUTION_FAILED = "SUBAGENT_EXECUTION_FAILED";
|
|
20
|
+
/** Error code for a remote agent session that failed to start. */
|
|
21
|
+
export declare const REMOTE_AGENT_START_FAILED = "REMOTE_AGENT_START_FAILED";
|
|
22
|
+
/** Fallback error code for a remote `session.failed` callback without error detail. */
|
|
23
|
+
export declare const REMOTE_AGENT_FAILED = "REMOTE_AGENT_FAILED";
|
|
24
|
+
/** Error code a child session reports back when the whole session failed. */
|
|
25
|
+
export declare const SESSION_FAILED = "SESSION_FAILED";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const AGENT_UNKNOWN=`AGENT_UNKNOWN`,AGENT_MISMATCH=`AGENT_MISMATCH`,AGENT_UNREACHABLE=`AGENT_UNREACHABLE`,AGENT_BUSY=`AGENT_BUSY`,SUBAGENT_START_FAILED=`SUBAGENT_START_FAILED`,SUBAGENT_EXECUTION_FAILED=`SUBAGENT_EXECUTION_FAILED`,REMOTE_AGENT_START_FAILED=`REMOTE_AGENT_START_FAILED`,REMOTE_AGENT_FAILED=`REMOTE_AGENT_FAILED`,SESSION_FAILED=`SESSION_FAILED`;export{AGENT_BUSY,AGENT_MISMATCH,AGENT_UNKNOWN,AGENT_UNREACHABLE,REMOTE_AGENT_FAILED,REMOTE_AGENT_START_FAILED,SESSION_FAILED,SUBAGENT_EXECUTION_FAILED,SUBAGENT_START_FAILED};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derives the stable operation id for one dispatch. All three inputs are
|
|
3
|
+
* parent-controlled, so the id exists before any child does and replaying
|
|
4
|
+
* the same call produces the same operation.
|
|
5
|
+
*
|
|
6
|
+
* Lives apart from the handle store because it needs `node:crypto`: the
|
|
7
|
+
* store module is bundled into the workflow driver body (which rejects
|
|
8
|
+
* Node.js builtins), while operation ids are only ever minted inside
|
|
9
|
+
* dispatch steps.
|
|
10
|
+
*/
|
|
11
|
+
export declare function deriveAgentOperationId(input: {
|
|
12
|
+
readonly callId: string;
|
|
13
|
+
readonly parentSessionId: string;
|
|
14
|
+
readonly parentTurnId: string;
|
|
15
|
+
}): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash}from"node:crypto";function deriveAgentOperationId(e){return createHash(`sha256`).update(`${e.parentSessionId}\0${e.parentTurnId}\0${e.callId}`).digest(`hex`)}export{deriveAgentOperationId};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ModelMessage } from "ai";
|
|
2
|
+
import type { AgentHandle, AgentHandleStore } from "#harness/handles/store.js";
|
|
3
|
+
/** Returns the resumable handles: the only phase the model may continue. */
|
|
4
|
+
export declare function projectParkedAgentHandles(store: AgentHandleStore): readonly Extract<AgentHandle, {
|
|
5
|
+
phase: "parked";
|
|
6
|
+
}>[];
|
|
7
|
+
/**
|
|
8
|
+
* Renders the model-visible agent listing. Only parked handles appear:
|
|
9
|
+
* starting and running children cannot accept a continuation, and private
|
|
10
|
+
* delivery coordinates never render.
|
|
11
|
+
*/
|
|
12
|
+
export declare function renderAgentsSnippet(store: AgentHandleStore): string;
|
|
13
|
+
/**
|
|
14
|
+
* Returns an append-only model announcement when the visible handle listing
|
|
15
|
+
* changed. Keeping volatile handles in conversation history preserves the
|
|
16
|
+
* stable system prompt cache prefix.
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveAgentsAnnouncement(input: {
|
|
19
|
+
readonly messages: readonly ModelMessage[];
|
|
20
|
+
readonly store: AgentHandleStore | undefined;
|
|
21
|
+
}): string | undefined;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const AGENTS_SNIPPET_LABEL=`[Agents]`;function projectParkedAgentHandles(e){return e.handles.filter(e=>e.phase===`parked`)}function renderAgentsSnippet(t){let n=projectParkedAgentHandles(t).map(e=>`<agent id="${escapeXml(e.identity.id)}" name="${escapeXml(e.identity.name)}">${escapeXml(e.lastStatus===``?`(no status)`:e.lastStatus)}</agent>`);return[AGENTS_SNIPPET_LABEL,`<agents>`,...n,`</agents>`].join(`
|
|
2
|
+
`)}function resolveAgentsAnnouncement(t){let n=t.messages.findLast(t=>t.role===`assistant`&&typeof t.content==`string`&&t.content.startsWith(AGENTS_SNIPPET_LABEL)),r=t.store??{handles:[]};if(n===void 0&&projectParkedAgentHandles(r).length===0)return;let i=renderAgentsSnippet(r);return n?.content===i?void 0:i}function escapeXml(e){return e.replaceAll(`&`,`&`).replaceAll(`"`,`"`).replaceAll(`<`,`<`).replaceAll(`>`,`>`)}export{projectParkedAgentHandles,renderAgentsSnippet,resolveAgentsAnnouncement};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { RuntimeActionResult, RuntimeSubagentChildResult } from "#runtime/actions/types.js";
|
|
2
|
+
import type { AgentHandle } from "#harness/handles/store.js";
|
|
3
|
+
import type { SessionStateMap } from "#harness/types.js";
|
|
4
|
+
/** A handle with one outstanding operation and a confirmed child address. */
|
|
5
|
+
export type RunningAgentHandle = Extract<AgentHandle, {
|
|
6
|
+
phase: "running";
|
|
7
|
+
}>;
|
|
8
|
+
/**
|
|
9
|
+
* Finds the running agent handle a child-produced result must settle: the
|
|
10
|
+
* handle whose recorded operation carries the result's callId.
|
|
11
|
+
*
|
|
12
|
+
* Binding is by callId alone. Possession of the parent's callback token is
|
|
13
|
+
* the authorization to settle; the handle's recorded address is used for
|
|
14
|
+
* outbound delivery (continuation, cancellation), never as an inbound
|
|
15
|
+
* identity check. Under the accepted at-least-once dispatch window a
|
|
16
|
+
* replay-orphaned duplicate child holds the same token and callId and may
|
|
17
|
+
* settle the call in place of the owned child — an accepted trade-off,
|
|
18
|
+
* since both children computed the same input.
|
|
19
|
+
*/
|
|
20
|
+
export declare function findRunningAgentHandle(state: SessionStateMap | undefined, input: {
|
|
21
|
+
readonly callId: string;
|
|
22
|
+
}): RunningAgentHandle | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* A subagent result may settle a call only when a running handle records
|
|
25
|
+
* its callId: a late or duplicate result for an already-settled call finds
|
|
26
|
+
* no running handle and is dropped.
|
|
27
|
+
*
|
|
28
|
+
* `dispatch`-origin failures pass unconditionally: the parent synthesizes
|
|
29
|
+
* them for calls whose child never started, and they reach the harness only
|
|
30
|
+
* through the trusted step-result path. Untrusted channels must use
|
|
31
|
+
* {@link isInboxSubagentResultFromRunningHandle} instead.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isResultBoundToRunningHandle(state: SessionStateMap | undefined, result: RuntimeActionResult): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Strict variant of {@link isResultBoundToRunningHandle} for results arriving
|
|
36
|
+
* over the shared turn inbox (child notifications and remote callbacks).
|
|
37
|
+
* An inbox result must bind to a running handle by callId; one with no
|
|
38
|
+
* matching running handle — including one for a callId whose dispatch
|
|
39
|
+
* already failed — must not overwrite the dispatch-produced error result.
|
|
40
|
+
*/
|
|
41
|
+
export declare function isInboxSubagentResultFromRunningHandle(state: SessionStateMap | undefined, result: RuntimeSubagentChildResult): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AGENT_HANDLES_STATE_KEY}from"#harness/handles/state-key.js";function readAgentHandles(t){let n=t?.[AGENT_HANDLES_STATE_KEY];if(n===void 0)return[];let r=n.handles;return Array.isArray(r)?r:[]}function findRunningAgentHandle(e,t){return readAgentHandles(e).find(e=>e.phase===`running`&&e.operation.callId===t.callId)}function isResultBoundToRunningHandle(e,t){return t.kind!==`subagent-result`||t.origin===`dispatch`||findRunningAgentHandle(e,{callId:t.callId})!==void 0}function isInboxSubagentResultFromRunningHandle(e,t){return findRunningAgentHandle(e,{callId:t.callId})!==void 0}export{findRunningAgentHandle,isInboxSubagentResultFromRunningHandle,isResultBoundToRunningHandle};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-state key for delegated agent handles.
|
|
3
|
+
*
|
|
4
|
+
* Lives apart from the store so schema-free readers (the workflow driver's
|
|
5
|
+
* handle query) can import the key without pulling the zod-backed store
|
|
6
|
+
* module into their bundle.
|
|
7
|
+
*/
|
|
8
|
+
export declare const AGENT_HANDLES_STATE_KEY = "eve.agent.handles";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const AGENT_HANDLES_STATE_KEY=`eve.agent.handles`;export{AGENT_HANDLES_STATE_KEY};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { SessionStateMap } from "#harness/types.js";
|
|
2
|
+
import { AGENT_HANDLES_STATE_KEY } from "./state-key.js";
|
|
3
|
+
export { AGENT_HANDLES_STATE_KEY };
|
|
4
|
+
/**
|
|
5
|
+
* Stable identity of one delegated child, minted before its start side
|
|
6
|
+
* effect runs. The model-visible `id` derives from the first start
|
|
7
|
+
* operation, never from the child session id, so it exists before the
|
|
8
|
+
* child does and cannot collide on externally supplied session suffixes.
|
|
9
|
+
*/
|
|
10
|
+
export interface AgentIdentity {
|
|
11
|
+
/** Model-visible identifier: `ag_<name>:<operation-hash>`. */
|
|
12
|
+
readonly id: string;
|
|
13
|
+
/** Subagent tool name. */
|
|
14
|
+
readonly name: string;
|
|
15
|
+
/** Agent-graph node used to re-resolve delivery configuration. */
|
|
16
|
+
readonly nodeId: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* One dispatch the parent intends to perform or has performed. Repeating
|
|
20
|
+
* the same operation is a replay; a different operation against a
|
|
21
|
+
* starting/running handle is a busy conflict.
|
|
22
|
+
*/
|
|
23
|
+
export interface StartOperation {
|
|
24
|
+
readonly kind: "start";
|
|
25
|
+
/** Derived via {@link deriveAgentOperationId}; stable across replays. */
|
|
26
|
+
readonly id: string;
|
|
27
|
+
readonly callId: string;
|
|
28
|
+
readonly parentTurnId: string;
|
|
29
|
+
}
|
|
30
|
+
/** A continuation delivery against a parked handle. */
|
|
31
|
+
export interface ContinueOperation {
|
|
32
|
+
readonly kind: "continue";
|
|
33
|
+
/** Derived via {@link deriveAgentOperationId}; stable across replays. */
|
|
34
|
+
readonly id: string;
|
|
35
|
+
readonly callId: string;
|
|
36
|
+
readonly parentTurnId: string;
|
|
37
|
+
/**
|
|
38
|
+
* Status the handle showed before this delivery, restored when the
|
|
39
|
+
* delivery is rejected as retryable so the handle returns to `parked`
|
|
40
|
+
* without optional state.
|
|
41
|
+
*/
|
|
42
|
+
readonly previousStatus: string;
|
|
43
|
+
}
|
|
44
|
+
/** Where a fresh child will be started. No session exists yet. */
|
|
45
|
+
export type AgentStartTarget = {
|
|
46
|
+
readonly kind: "agent/local";
|
|
47
|
+
/** Deterministic child continuation token chosen at dispatch. */
|
|
48
|
+
readonly continuationToken: string;
|
|
49
|
+
} | {
|
|
50
|
+
readonly kind: "agent/self";
|
|
51
|
+
readonly continuationToken: string;
|
|
52
|
+
} | {
|
|
53
|
+
readonly kind: "agent/remote";
|
|
54
|
+
/** Deliver target base URL; never model-visible. */
|
|
55
|
+
readonly url: string;
|
|
56
|
+
/** Callback base URL stub captured at dispatch; never model-visible. */
|
|
57
|
+
readonly callbackBaseUrl: string;
|
|
58
|
+
};
|
|
59
|
+
/** Confirmed delivery coordinates of a started child. */
|
|
60
|
+
export type AgentAddress = {
|
|
61
|
+
readonly kind: "agent/local";
|
|
62
|
+
readonly sessionId: string;
|
|
63
|
+
readonly continuationToken: string;
|
|
64
|
+
} | {
|
|
65
|
+
readonly kind: "agent/self";
|
|
66
|
+
readonly sessionId: string;
|
|
67
|
+
readonly continuationToken: string;
|
|
68
|
+
} | {
|
|
69
|
+
readonly kind: "agent/remote";
|
|
70
|
+
readonly sessionId: string;
|
|
71
|
+
/**
|
|
72
|
+
* Absent when the remote deployment predates continuation tokens; the
|
|
73
|
+
* child completes as a task-mode one-shot and can never be continued.
|
|
74
|
+
*/
|
|
75
|
+
readonly continuationToken?: string;
|
|
76
|
+
readonly url: string;
|
|
77
|
+
readonly callbackBaseUrl: string;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Durable ownership record for one delegated child.
|
|
81
|
+
*
|
|
82
|
+
* The store owns the full nonterminal lifecycle:
|
|
83
|
+
*
|
|
84
|
+
* - `starting` — the parent committed intent to start; the child may or
|
|
85
|
+
* may not exist yet.
|
|
86
|
+
* - `running` — one identified child turn is outstanding.
|
|
87
|
+
* - `parked` — the child is idle and resumable; only this phase is
|
|
88
|
+
* model-visible.
|
|
89
|
+
*
|
|
90
|
+
* A terminal child has no handle: settlement deletes it.
|
|
91
|
+
*/
|
|
92
|
+
export type AgentHandle = {
|
|
93
|
+
readonly phase: "starting";
|
|
94
|
+
readonly identity: AgentIdentity;
|
|
95
|
+
readonly operation: StartOperation;
|
|
96
|
+
readonly target: AgentStartTarget;
|
|
97
|
+
} | {
|
|
98
|
+
readonly phase: "running";
|
|
99
|
+
readonly identity: AgentIdentity;
|
|
100
|
+
readonly operation: StartOperation | ContinueOperation;
|
|
101
|
+
readonly address: AgentAddress;
|
|
102
|
+
} | {
|
|
103
|
+
readonly phase: "parked";
|
|
104
|
+
readonly identity: AgentIdentity;
|
|
105
|
+
readonly address: AgentAddress;
|
|
106
|
+
readonly lastStatus: string;
|
|
107
|
+
};
|
|
108
|
+
/** Lifecycle phase of a delegated agent handle. */
|
|
109
|
+
export type AgentHandlePhase = AgentHandle["phase"];
|
|
110
|
+
/** Session-state collection of delegated agent handles. */
|
|
111
|
+
export interface AgentHandleStore {
|
|
112
|
+
readonly handles: readonly AgentHandle[];
|
|
113
|
+
}
|
|
114
|
+
/** Derives the model-visible agent id from the first start operation. */
|
|
115
|
+
export declare function deriveAgentId(name: string, startOperationId: string): string;
|
|
116
|
+
/** Collapses whitespace and truncates output into a handle status line. */
|
|
117
|
+
export declare function formatAgentStatus(output: unknown): string;
|
|
118
|
+
/**
|
|
119
|
+
* Validates one agent handle store about to be persisted, returning the
|
|
120
|
+
* parsed value. Throws instead of writing an invalid store: transitions run
|
|
121
|
+
* this on every write, which is the invariant that lets the schema-free
|
|
122
|
+
* driver-side reader (`query.ts`) trust stored values without revalidating.
|
|
123
|
+
*/
|
|
124
|
+
export declare function assertPersistableAgentHandleStore(store: AgentHandleStore): AgentHandleStore;
|
|
125
|
+
/**
|
|
126
|
+
* Reads and validates the agent handle store from session state.
|
|
127
|
+
*
|
|
128
|
+
* Returns `undefined` only when no store has been written. A present but
|
|
129
|
+
* invalid store throws: treating corruption as absence would let the next
|
|
130
|
+
* transition silently replace every delegated child's delivery coordinates.
|
|
131
|
+
*/
|
|
132
|
+
export declare function getAgentHandleStore(state: SessionStateMap | undefined): AgentHandleStore | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AGENT_HANDLES_STATE_KEY}from"./state-key.js";import{z}from"#compiled/zod/index.js";const nonEmptyString=z.string().min(1),identitySchema=z.strictObject({id:nonEmptyString,name:nonEmptyString,nodeId:nonEmptyString}),startOperationSchema=z.strictObject({callId:nonEmptyString,id:nonEmptyString,kind:z.literal(`start`),parentTurnId:nonEmptyString}),continueOperationSchema=z.strictObject({callId:nonEmptyString,id:nonEmptyString,kind:z.literal(`continue`),parentTurnId:nonEmptyString,previousStatus:z.string().max(120)}),startTargetSchema=z.discriminatedUnion(`kind`,[z.strictObject({continuationToken:nonEmptyString,kind:z.literal(`agent/local`)}),z.strictObject({continuationToken:nonEmptyString,kind:z.literal(`agent/self`)}),z.strictObject({callbackBaseUrl:z.url(),kind:z.literal(`agent/remote`),url:z.url()})]),addressSchema=z.discriminatedUnion(`kind`,[z.strictObject({continuationToken:nonEmptyString,kind:z.literal(`agent/local`),sessionId:nonEmptyString}),z.strictObject({continuationToken:nonEmptyString,kind:z.literal(`agent/self`),sessionId:nonEmptyString}),z.strictObject({callbackBaseUrl:z.url(),continuationToken:nonEmptyString.optional(),kind:z.literal(`agent/remote`),sessionId:nonEmptyString,url:z.url()})]),agentHandleSchema=z.discriminatedUnion(`phase`,[z.strictObject({identity:identitySchema,operation:startOperationSchema,phase:z.literal(`starting`),target:startTargetSchema}),z.strictObject({address:addressSchema,identity:identitySchema,operation:z.discriminatedUnion(`kind`,[startOperationSchema,continueOperationSchema]),phase:z.literal(`running`)}),z.strictObject({address:addressSchema,identity:identitySchema,lastStatus:z.string().max(120),phase:z.literal(`parked`)})]),agentHandleStoreSchema=z.strictObject({handles:z.array(agentHandleSchema)}).refine(e=>new Set(e.handles.map(e=>e.identity.id)).size===e.handles.length,{message:`Agent handle ids must be unique.`});function deriveAgentId(e,t){return`ag_${e}:${t.slice(0,12)}`}function formatAgentStatus(e){return(typeof e==`string`?e:JSON.stringify(e)??``).replaceAll(/\s+/g,` `).trim().slice(0,120)}function assertPersistableAgentHandleStore(e){let t=agentHandleStoreSchema.safeParse(e);if(!t.success)throw Error(`Refusing to persist a corrupt agent handle store: ${t.error.message}`);return t.data}function getAgentHandleStore(t){let n=t?.[AGENT_HANDLES_STATE_KEY];if(n===void 0)return;let r=agentHandleStoreSchema.safeParse(n);if(!r.success)throw Error(`Corrupt agent handle store under session state key "${AGENT_HANDLES_STATE_KEY}": ${r.error.message}`);return r.data}export{AGENT_HANDLES_STATE_KEY,assertPersistableAgentHandleStore,deriveAgentId,formatAgentStatus,getAgentHandleStore};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { type AgentAddress, type AgentHandle, type AgentIdentity, type ContinueOperation, type StartOperation } from "#harness/handles/store.js";
|
|
2
|
+
import type { HarnessSession } from "#harness/types.js";
|
|
3
|
+
import type { AgentTurnOutcome } from "#shared/agent-turn-outcome.js";
|
|
4
|
+
/**
|
|
5
|
+
* Records intent to start a fresh child. Must be applied to the step's
|
|
6
|
+
* working snapshot before the start side effect runs, so the returned state
|
|
7
|
+
* owns any child the step may have created.
|
|
8
|
+
*
|
|
9
|
+
* The guarantee is intra-step, not exactly-once: the prepared handle
|
|
10
|
+
* durably commits only when the enclosing dispatch step's result commits.
|
|
11
|
+
* A crash between an accepted start and that commit replays the step from
|
|
12
|
+
* the pre-step snapshot and re-runs the side effect.
|
|
13
|
+
*
|
|
14
|
+
* Throws when the identity or operation already exists: fresh starts mint
|
|
15
|
+
* a new identity, so a collision means corrupted derivation, not a replay.
|
|
16
|
+
*/
|
|
17
|
+
export declare function prepareAgentStart(session: HarnessSession, input: {
|
|
18
|
+
readonly identity: AgentIdentity;
|
|
19
|
+
readonly operation: StartOperation;
|
|
20
|
+
readonly target: AgentStartTargetInput;
|
|
21
|
+
}): HarnessSession;
|
|
22
|
+
type AgentStartTargetInput = Extract<AgentHandle, {
|
|
23
|
+
phase: "starting";
|
|
24
|
+
}>["target"];
|
|
25
|
+
/** Result of preparing a continuation against an existing handle. */
|
|
26
|
+
export type PrepareAgentContinuationResult = {
|
|
27
|
+
readonly kind: "ready";
|
|
28
|
+
readonly session: HarnessSession;
|
|
29
|
+
readonly handle: Extract<AgentHandle, {
|
|
30
|
+
phase: "running";
|
|
31
|
+
}>;
|
|
32
|
+
} | {
|
|
33
|
+
readonly kind: "unknown";
|
|
34
|
+
} | {
|
|
35
|
+
readonly kind: "mismatch";
|
|
36
|
+
} | {
|
|
37
|
+
readonly kind: "busy";
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Records intent to deliver a follow-up turn to a parked child. Must be
|
|
41
|
+
* applied to the step's working snapshot before the delivery side effect
|
|
42
|
+
* runs.
|
|
43
|
+
*
|
|
44
|
+
* Delivery is at-least-once, not exactly-once: the `running` handle durably
|
|
45
|
+
* commits only when the enclosing dispatch step's result commits. If the
|
|
46
|
+
* step dies after a successful delivery, replay starts from `parked` and
|
|
47
|
+
* delivers the same operation again — which is why replaying the operation
|
|
48
|
+
* already recorded on a running handle returns `ready` with the unchanged
|
|
49
|
+
* session instead of a busy conflict.
|
|
50
|
+
*
|
|
51
|
+
* `unknown`, `mismatch`, and `busy` do not change the session; the caller
|
|
52
|
+
* maps them onto `AGENT_UNKNOWN`, `AGENT_MISMATCH`, and `AGENT_BUSY`
|
|
53
|
+
* results.
|
|
54
|
+
*/
|
|
55
|
+
export declare function prepareAgentContinuation(session: HarnessSession, input: {
|
|
56
|
+
readonly agentId: string;
|
|
57
|
+
readonly invokedName: string;
|
|
58
|
+
readonly operation: ContinueOperation;
|
|
59
|
+
}): PrepareAgentContinuationResult;
|
|
60
|
+
/**
|
|
61
|
+
* Confirms a started child: `starting` becomes `running` with the child's
|
|
62
|
+
* confirmed address. Throws when no starting handle carries the operation,
|
|
63
|
+
* because confirming an unprepared start means ownership was never
|
|
64
|
+
* committed. Re-confirming an already-running handle with the same
|
|
65
|
+
* operation and address is a replay no-op.
|
|
66
|
+
*/
|
|
67
|
+
export declare function confirmAgentStarted(session: HarnessSession, input: {
|
|
68
|
+
readonly operationId: string;
|
|
69
|
+
readonly address: AgentAddress;
|
|
70
|
+
}): HarnessSession;
|
|
71
|
+
/**
|
|
72
|
+
* Resolves a dispatch that definitively failed.
|
|
73
|
+
*
|
|
74
|
+
* - A dead start or dead continuation deletes the handle: there is no
|
|
75
|
+
* child left to own.
|
|
76
|
+
* - A retryable continuation failure restores `parked` with the status the
|
|
77
|
+
* handle showed before the delivery, so the model may retry the same
|
|
78
|
+
* `agentId` later.
|
|
79
|
+
*
|
|
80
|
+
* Unknown operations are a no-op: the failure raced a settlement that
|
|
81
|
+
* already resolved the handle.
|
|
82
|
+
*/
|
|
83
|
+
export declare function rejectAgentEffect(session: HarnessSession, input: {
|
|
84
|
+
readonly operationId: string;
|
|
85
|
+
readonly disposition: "dead" | "retryable";
|
|
86
|
+
}): HarnessSession;
|
|
87
|
+
/** Result of applying a settled child turn to the store. */
|
|
88
|
+
export type SettleAgentTurnResult = {
|
|
89
|
+
readonly kind: "settled";
|
|
90
|
+
readonly session: HarnessSession;
|
|
91
|
+
} | {
|
|
92
|
+
readonly kind: "ignored";
|
|
93
|
+
readonly reason: "unknown-operation";
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Applies one settled child turn: `running` becomes `parked` for a parked
|
|
97
|
+
* outcome or is deleted for a terminal outcome.
|
|
98
|
+
*
|
|
99
|
+
* The settlement must carry the operation currently recorded on the
|
|
100
|
+
* running handle; anything else is ignored so a stale delivery can never
|
|
101
|
+
* move a newer turn.
|
|
102
|
+
*/
|
|
103
|
+
export declare function settleAgentTurn(session: HarnessSession, input: {
|
|
104
|
+
readonly operationId: string;
|
|
105
|
+
readonly outcome: AgentTurnOutcome;
|
|
106
|
+
}): SettleAgentTurnResult;
|
|
107
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AGENT_HANDLES_STATE_KEY,assertPersistableAgentHandleStore,formatAgentStatus,getAgentHandleStore}from"#harness/handles/store.js";function prepareAgentStart(e,t){let n=getAgentHandleStore(e.state)?.handles??[];if(n.some(e=>e.identity.id===t.identity.id))throw Error(`Agent handle "${t.identity.id}" already exists.`);return writeHandles(e,[...n,{identity:t.identity,operation:t.operation,phase:`starting`,target:t.target}])}function prepareAgentContinuation(e,t){let n=getAgentHandleStore(e.state)?.handles??[],i=n.find(e=>e.identity.id===t.agentId);if(i===void 0)return{kind:`unknown`};if(i.identity.name!==t.invokedName)return{kind:`mismatch`};if(i.phase===`running`&&i.operation.id===t.operation.id)return{handle:i,kind:`ready`,session:e};if(i.phase!==`parked`)return{kind:`busy`};let a={address:i.address,identity:i.identity,operation:{...t.operation,previousStatus:i.lastStatus},phase:`running`};return{handle:a,kind:`ready`,session:writeHandles(e,n.map(e=>e.identity.id===t.agentId?a:e))}}function findActiveHandle(e,t){return e.find(e=>e.phase!==`parked`&&e.operation.id===t)}function confirmAgentStarted(e,t){let n=getAgentHandleStore(e.state)?.handles??[],i=findActiveHandle(n,t.operationId);if(i===void 0)throw Error(`No prepared agent handle for operation "${t.operationId}".`);return i.phase===`running`?e:writeHandles(e,n.map(e=>e===i?{address:t.address,identity:i.identity,operation:i.operation,phase:`running`}:e))}function rejectAgentEffect(e,t){let n=getAgentHandleStore(e.state)?.handles??[],i=findActiveHandle(n,t.operationId);if(i===void 0)return e;if(t.disposition===`retryable`&&i.phase===`running`){let{operation:t}=i;if(t.kind===`continue`)return writeHandles(e,n.map(e=>e===i?{address:i.address,identity:i.identity,lastStatus:t.previousStatus,phase:`parked`}:e))}return writeHandles(e,n.filter(e=>e!==i))}function settleAgentTurn(e,t){let i=getAgentHandleStore(e.state)?.handles??[],a=i.find(e=>e.phase===`running`&&e.operation.id===t.operationId);if(a===void 0||a.phase!==`running`)return{kind:`ignored`,reason:`unknown-operation`};if(t.outcome.kind===`terminal`)return{kind:`settled`,session:writeHandles(e,i.filter(e=>e!==a))};let{result:o}=t.outcome,s=o.kind===`succeeded`?formatAgentStatus(o.output):o.kind===`failed`?formatAgentStatus(o.error):`(cancelled)`;return{kind:`settled`,session:writeHandles(e,i.map(e=>e===a?{address:a.address,identity:a.identity,lastStatus:s,phase:`parked`}:e))}}function writeHandles(n,r){return{...n,state:{...n.state,[AGENT_HANDLES_STATE_KEY]:assertPersistableAgentHandleStore({handles:r})}}}export{confirmAgentStarted,prepareAgentContinuation,prepareAgentStart,rejectAgentEffect,settleAgentTurn};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveTextToResponses}from"#channel/resolve-text.js";import{
|
|
1
|
+
import{resolveTextToResponses}from"#channel/resolve-text.js";import{coalesceTurnInputs}from"#harness/messages.js";import{resolveToolCallInputObject}from"#harness/runtime-actions.js";import{isSessionLimitContinuationRequest,resolveSessionLimitContinuation}from"#harness/session-limit-continuation.js";import{classifyInputRequest,isApprovalRequest}from"#harness/input-request-class.js";const PENDING_INPUT_BATCH_KEY=`eve.runtime.pendingInputBatch`,APPROVED_TOOLS_KEY=`eve.runtime.hitl.approvedTools`,DEFERRED_STEP_INPUT_KEY=`eve.runtime.deferredStepInput`,TOOL_EXECUTION_DENIED_MESSAGE=`Tool execution was denied.`;function hasStepInput(e){return e===void 0?!1:e.message!==void 0||(e.inputResponses?.length??0)>0}function consumeDeferredStepInput(e){let n=getDeferredStepInput(e.session);if(n===void 0)return e;let r=clearDeferredStepInput(e.session);return e.input===void 0?{input:n,session:r}:{input:coalesceTurnInputs(n,e.input),session:r}}function hasDeferredStepInput(e){return getDeferredStepInput(e)!==void 0}function resolvePendingInput(e){let{stepInput:t}=e,n=e.session,r=[...e.history??n.history],a=getPendingInputBatch(n.state);if(a===void 0)return{outcome:`continue`,messages:r,session:n};let o=resolveTextMessageInput(a,t),s=o?.inputResponses??[],c=a.requests.some(e=>isApprovalRequest(e));if(s.length===0&&o?.message===void 0)return{outcome:`unresolved`,messages:r,session:n};if(hasUnansweredRequiredRequest({pendingBatch:a,responses:s}))return n=queueDeferredStepInput(n,compactStepInput(o)),{deferredMessage:!0,outcome:`unresolved`,messages:r,session:n};if(s.length===0&&o?.message!==void 0){let e=buildToolResponseParts(a,[]),t=[...r,...a.responseMessages];e.length>0&&t.push({content:e,role:`tool`});let i=buildRejectedActionBatch(a,[]);return n=clearPendingInputBatch(n),{consumedMessage:o?.messageConsumed,outcome:`resolved`,messages:t,rejectedActions:i,session:n}}let l=resolveSessionLimitContinuation({requests:a.requests,responses:s});n=recordApprovedTools({pendingBatch:a,resolveApprovalKey:e.resolveApprovalKey,responses:s,session:n});let u=buildToolResponseParts(a,s),d=[...r,...a.responseMessages];u.length>0&&d.push({content:u,role:`tool`});let f=buildRejectedActionBatch(a,s);if(n=clearPendingInputBatch(n),c){let e={};if((o?.context?.length??0)>0&&(e.context=o?.context),o?.message!==void 0&&(e.message=o.message),e.context!==void 0||e.message!==void 0)return n=queueDeferredStepInput(n,e),{consumedMessage:o?.messageConsumed,deferredContext:e.context!==void 0||void 0,deferredMessage:e.message!==void 0||void 0,limitContinuation:l,outcome:`resolved`,messages:d,rejectedActions:f,session:n}}return{consumedMessage:o?.messageConsumed,limitContinuation:l,outcome:`resolved`,messages:d,rejectedActions:f,session:n}}function resolveTextMessageInput(t,n){if(typeof n?.message!=`string`||(n.inputResponses?.length??0)>0)return n;let r=resolveTextToResponses(n.message,t.requests);return r.length===0?n:compactStepInput({...n,inputResponses:r,messageConsumed:!0,message:void 0})}function compactStepInput(e){if(e===void 0)return{};let t={};return(e.context?.length??0)>0&&(t.context=e.context),(e.inputResponses?.length??0)>0&&(t.inputResponses=e.inputResponses),e.message!==void 0&&(t.message=e.message),e.messageConsumed===!0&&(t.messageConsumed=!0),e.outputSchema!==void 0&&(t.outputSchema=e.outputSchema),t}function clearPendingSessionLimitPrompt(e){let t=getPendingInputBatch(e.state);return t===void 0||t.requests.length===0||!t.requests.every(e=>isSessionLimitContinuationRequest(e))?e:clearPendingInputBatch(e)}function hasUnansweredRequiredRequest(e){let t=new Set(e.responses.map(e=>e.requestId));return e.pendingBatch.requests.some(e=>classifyInputRequest(e)===`required`&&!t.has(e.requestId))}function hasPendingInputBatch(e){return getPendingInputBatch(e)!==void 0}function getPendingInputRequestIds(e){return new Set(getPendingInputBatch(e)?.requests.map(e=>e.requestId))}function getPendingInputBatch(e){let t=e?.[PENDING_INPUT_BATCH_KEY];if(typeof t!=`object`||!t)return;let n=t;if(!(!Array.isArray(n.requests)||!Array.isArray(n.responseMessages)))return n}function setPendingInputBatch(e){let t={...e.session.state};return t[PENDING_INPUT_BATCH_KEY]={event:e.event,requests:[...e.requests],responseMessages:[...e.responseMessages]},{...e.session,state:t}}function clearPendingInputBatch(e){if(e.state?.[PENDING_INPUT_BATCH_KEY]===void 0)return e;let t={...e.state};return delete t[PENDING_INPUT_BATCH_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function getDeferredStepInput(e){return e.state?.[DEFERRED_STEP_INPUT_KEY]}function queueDeferredStepInput(e,n){let r=getDeferredStepInput(e),i=r===void 0?n:coalesceTurnInputs(r,n),a={...e.state};return a[DEFERRED_STEP_INPUT_KEY]=i,{...e,state:a}}function clearDeferredStepInput(e){if(e.state?.[DEFERRED_STEP_INPUT_KEY]===void 0)return e;let t={...e.state};return delete t[DEFERRED_STEP_INPUT_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function getApprovedTools(e){let t=e.state?.[APPROVED_TOOLS_KEY];return Array.isArray(t)?new Set(t):new Set}function recordApprovedTools(e){let t=new Set(e.responses.filter(e=>e.optionId===`approve`).map(e=>e.requestId)),n=e.pendingBatch.requests.filter(e=>t.has(e.requestId)).map(t=>e.resolveApprovalKey?.(t)??t.action.toolName);if(n.length===0)return e.session;let r=getApprovedTools(e.session),i=[...new Set([...r,...n])],a={...e.session.state};return a[APPROVED_TOOLS_KEY]=i,{...e.session,state:a}}function resolveApprovalOutcome(e){return e===void 0?{approved:!1,reason:`Ignored because the user continued without responding.`,status:`ignored`}:e.optionId===`approve`?{approved:!0,reason:void 0,status:`approved`}:e.optionId===`deny`?{approved:!1,reason:TOOL_EXECUTION_DENIED_MESSAGE,status:`denied`}:{approved:!1,reason:`Invalid approval response.`,status:`invalid`}}function buildRejectedActionBatch(e,t){if(e.event===void 0)return;let n=new Map(t.map(e=>[e.requestId,e])),r=[];for(let t of e.requests){if(!isApprovalRequest(t))continue;let{approved:e,reason:i,status:a}=resolveApprovalOutcome(n.get(t.requestId));e||r.push({callId:t.action.callId,isError:!0,kind:`tool-result`,output:{approval:{requestId:t.requestId,status:a},code:`TOOL_EXECUTION_DENIED`,message:i??TOOL_EXECUTION_DENIED_MESSAGE,tool:{result:`not_run`}},toolName:t.action.toolName})}return r.length>0?{event:e.event,results:r}:void 0}function buildToolResponseParts(e,t){let n=new Map(t.map(e=>[e.requestId,e])),r=[];for(let t of e.requests)r.push(...buildToolResponsePartsForRequest(t,n.get(t.requestId)));return r}function buildToolResponsePartsForRequest(e,t){if(isSessionLimitContinuationRequest(e))return[];if(isApprovalRequest(e)){let{approved:n,reason:r}=resolveApprovalOutcome(t),i=[{approvalId:e.requestId,approved:n,reason:r,type:`tool-approval-response`}];return n||i.push({output:{type:`execution-denied`,reason:r},toolCallId:e.action.callId,toolName:e.action.toolName,type:`tool-result`}),i}return[{output:{type:`json`,value:t===void 0?{status:`ignored`}:{optionId:t.optionId,text:t.text,status:`answered`}},toolCallId:e.action.callId,toolName:e.action.toolName,type:`tool-result`}]}function createRuntimeToolCallActionFromToolCall(e){return{callId:e.toolCall.toolCallId,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`tool-call`,toolName:e.toolCall.toolName}}export{clearPendingSessionLimitPrompt,consumeDeferredStepInput,createRuntimeToolCallActionFromToolCall,getApprovedTools,getPendingInputRequestIds,hasDeferredStepInput,hasPendingInputBatch,hasStepInput,resolvePendingInput,setPendingInputBatch};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ModelMessage, ToolSet, TypedToolCall } from "ai";
|
|
2
|
-
import type { RuntimeActionRequest
|
|
2
|
+
import type { RuntimeActionRequest } from "#runtime/actions/types.js";
|
|
3
3
|
import { type JsonObject } from "#shared/json.js";
|
|
4
4
|
import type { HarnessEmitFn, HarnessSession, HarnessToolMap, SessionStateMap, StepInput } from "#harness/types.js";
|
|
5
5
|
/**
|
|
@@ -16,14 +16,12 @@ interface PendingRuntimeActionEventMetadata {
|
|
|
16
16
|
/**
|
|
17
17
|
* Serializable pending runtime-action batch stored on `session.state`.
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* Child ownership does not live here: the agent handle store records every
|
|
20
|
+
* dispatched child (from before its start side effect) and is the sole
|
|
21
|
+
* authority for continuing, settling, and cancelling children.
|
|
22
22
|
*/
|
|
23
23
|
export interface PendingRuntimeActionBatch {
|
|
24
24
|
readonly actions: readonly RuntimeActionRequest[];
|
|
25
|
-
readonly childContinuationTokens?: Readonly<Record<string, string>>;
|
|
26
|
-
readonly childSessionIds?: Readonly<Record<string, string>>;
|
|
27
25
|
readonly event: PendingRuntimeActionEventMetadata;
|
|
28
26
|
readonly responseMessages: readonly ModelMessage[];
|
|
29
27
|
}
|
|
@@ -51,25 +49,6 @@ export declare function setPendingRuntimeActionBatch(input: {
|
|
|
51
49
|
readonly responseMessages: readonly ModelMessage[];
|
|
52
50
|
readonly session: HarnessSession;
|
|
53
51
|
}): HarnessSession;
|
|
54
|
-
type PendingSubagentChildIdentity = {
|
|
55
|
-
readonly continuationToken: string;
|
|
56
|
-
readonly kind: "local";
|
|
57
|
-
readonly sessionId: string;
|
|
58
|
-
} | {
|
|
59
|
-
readonly kind: "remote";
|
|
60
|
-
readonly sessionId: string;
|
|
61
|
-
};
|
|
62
|
-
/** Records one successfully dispatched child's durable identities. */
|
|
63
|
-
export declare function recordPendingSubagentChild(input: {
|
|
64
|
-
readonly callId: string;
|
|
65
|
-
readonly child: PendingSubagentChildIdentity;
|
|
66
|
-
readonly session: HarnessSession;
|
|
67
|
-
}): HarnessSession;
|
|
68
|
-
/** Returns results in pending-key order once every requested action has completed. */
|
|
69
|
-
export declare function resolveRuntimeActionResultsForKeys(input: {
|
|
70
|
-
readonly pendingKeys: readonly string[];
|
|
71
|
-
readonly results: readonly RuntimeActionResult[];
|
|
72
|
-
}): RuntimeActionResult[] | undefined;
|
|
73
52
|
/**
|
|
74
53
|
* Resolves one pending runtime-action batch back into model history.
|
|
75
54
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createActionResultEvent}from"#protocol/message.js";import{parseJsonObject}from"#shared/json.js";import{clearProxyInputRequestsForChild}from"#harness/proxy-input-requests.js";import{accumulateSessionUsage,getTurnUsageState,setTurnUsageState}from"#harness/turn-tag-state.js";import{getRuntimeActionRequestKey
|
|
1
|
+
import{createActionResultEvent}from"#protocol/message.js";import{parseJsonObject}from"#shared/json.js";import{settleAgentTurn}from"#harness/handles/transitions.js";import{clearProxyInputRequestsForChild}from"#harness/proxy-input-requests.js";import{findRunningAgentHandle,isResultBoundToRunningHandle}from"#harness/handles/query.js";import{resolveRuntimeActionResultsForKeys}from"#runtime/actions/results.js";import{accumulateSessionUsage,getTurnUsageState,setTurnUsageState}from"#harness/turn-tag-state.js";import{getRuntimeActionRequestKey}from"#runtime/actions/keys.js";const PENDING_RUNTIME_ACTION_BATCH_KEY=`eve.runtime.pendingActionBatch`,ZERO_TOKEN_USAGE={cacheReadTokens:0,cacheWriteTokens:0,inputTokens:0,outputTokens:0};function readSubagentResultUsage(e){return e.origin===`child`?e.usage:void 0}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 resolveReadyRuntimeActionResults(e){let t=getPendingRuntimeActionBatch(e.session.state);if(t!==void 0)return resolveRuntimeActionResultsForBatch({batch:t,results:e.results,state:e.session.state})}function resolveRuntimeActionResultsForBatch(e){return resolveRuntimeActionResultsForKeys({pendingKeys:e.batch.actions.map(e=>getRuntimeActionRequestKey(e)),results:e.results.filter(t=>isResultBoundToRunningHandle(e.state,t))})}async function resolvePendingRuntimeActions(t){let i=getPendingRuntimeActionBatch(t.session.state);if(i===void 0)return{messages:[...t.session.history],outcome:`continue`,session:t.session};let a=resolveReadyRuntimeActionResults({results:t.stepInput?.runtimeActionResults??[],session:t.session});if(a===void 0)return{messages:[...t.session.history],outcome:`unresolved`,session:t.session};if(t.emit!==void 0)for(let n of a)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:i.event.sequence,stepIndex:i.event.stepIndex,turnId:i.event.turnId}));let o=t.session;for(let e of a){if(e.kind!==`subagent-result`||e.origin!==`child`)continue;let t=findRunningAgentHandle(o.state,{callId:e.callId});if(t===void 0)continue;t.address.continuationToken!==void 0&&(o=clearProxyInputRequestsForChild(o,t.address.continuationToken));let i=settleAgentTurn(o,{operationId:t.operation.id,outcome:{kind:`terminal`,result:e.isError===!0?{error:e.output,kind:`failed`}:{kind:`succeeded`,output:e.output},usageDelta:e.usage??ZERO_TOKEN_USAGE}});i.kind===`settled`&&(o=i.session)}let s={...o.state};delete s[PENDING_RUNTIME_ACTION_BATCH_KEY],o={...o,state:Object.keys(s).length>0?s:void 0};for(let e of a){if(e.kind!==`subagent-result`)continue;let t=readSubagentResultUsage(e);t!==void 0&&(o=setTurnUsageState(o,accumulateSessionUsage({previous:getTurnUsageState(o.state),usage:t})))}let c=a.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,...i.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||typeof e==`string`&&e.trim()===``)return{};try{return parseJsonObject(typeof e==`string`?parseJsonStringInput(e):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 parseJsonStringInput(e){return JSON.parse(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,resolvePendingRuntimeActions,resolveToolCallInputObject,setPendingRuntimeActionBatch};
|