eve 0.79.1 → 0.79.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/src/channel/pending-authorization.d.ts +10 -0
- package/dist/src/channel/pending-authorization.js +1 -0
- package/dist/src/compiled/.vendor-stamp.json +2 -2
- package/dist/src/compiled/@eve/tracing/index.js +1 -1
- package/dist/src/compiled/@eve/tracing/otel.js +1 -1
- package/dist/src/compiled/_chunks/workflow/{mcp-C01bDEX-.js → mcp-Bwx_LQ4q.js} +4 -4
- package/dist/src/compiler/extension-compatibility.d.ts +18 -18
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/proxied-deliver-step.js +1 -1
- package/dist/src/execution/publish-session-events.d.ts +13 -3
- package/dist/src/execution/publish-session-events.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
- package/dist/src/execution/session/active-turn.d.ts +2 -1
- package/dist/src/execution/session/active-turn.js +1 -1
- package/dist/src/execution/session/turn-step.js +1 -1
- package/dist/src/execution/session/turn.d.ts +1 -0
- package/dist/src/execution/session/turn.js +1 -1
- package/dist/src/execution/tasks/task-id-input.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/tools/workflow/apply-run-messages-step.d.ts +6 -2
- package/dist/src/execution/tools/workflow/apply-run-messages-step.js +1 -1
- package/dist/src/execution/tools/workflow/body.d.ts +10 -1
- package/dist/src/execution/tools/workflow/body.js +1 -1
- package/dist/src/execution/tools/workflow/owner-inbox.js +1 -1
- package/dist/src/execution/tools/workflow/serve.js +1 -1
- package/dist/src/harness/action-result-helpers.js +1 -1
- package/dist/src/harness/attachment-staging.js +1 -1
- package/dist/src/harness/compaction/engine.js +3 -1
- package/dist/src/harness/compaction/prompt.d.ts +7 -0
- package/dist/src/harness/compaction/prompt.js +1 -1
- package/dist/src/harness/hitl/approvals.js +1 -1
- package/dist/src/harness/hitl/approved-calls.js +1 -1
- package/dist/src/harness/input-request-resolution.d.ts +2 -1
- package/dist/src/harness/input-request-resolution.js +1 -1
- package/dist/src/instrumentation/native-events.js +1 -1
- package/dist/src/internal/application/optional-package-import.d.ts +5 -0
- package/dist/src/internal/application/optional-package-import.js +1 -1
- package/dist/src/internal/application/stamped-package-version.js +1 -1
- package/dist/src/internal/nitro/host/start-production-server.js +2 -2
- package/dist/src/protocol/message.d.ts +2 -0
- package/dist/src/protocol/message.js +1 -1
- package/dist/src/public/channels/teams/authorization.d.ts +53 -0
- package/dist/src/public/channels/teams/authorization.js +1 -0
- package/dist/src/public/channels/teams/defaults.js +2 -2
- package/dist/src/public/channels/teams/hitl.d.ts +2 -1
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/authorization-callback.js +1 -1
- package/dist/src/public/next/index.js +1 -1
- package/dist/src/public/next/server.d.ts +11 -2
- package/dist/src/public/next/server.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/shared/action-types.d.ts +1 -0
- package/dist/src/shared/action-types.js +1 -1
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/dist/src/tools/signature.d.ts +4 -2
- package/dist/src/tools/signature.js +1 -1
- package/docs/channels/teams.mdx +6 -0
- package/docs/concepts/built-in-tools.md +1 -1
- package/docs/guides/hooks.md +4 -0
- package/docs/guides/instrumentation/instrumentation.mdx +2 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import"#protocol/session-projection.js";import{createLogger}from"#internal/logging.js";import{callAdapterEventHandler}from"#channel/adapter.js";import{contextStorage}from"#context/container.js";import{currentProjection,enterSessionProjection,recordPublishedEvent,saveSessionProjection}from"#harness/session-machine/current.js";import{AuthKey,InitiatorAuthKey,ParentSessionKey,SessionKey,TurnDeliveryIdsKey}from"#context/keys.js";import{encodeMessageStreamEvent,stampMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{validateHarnessModelMessages}from"#harness/messages.js";import{activeTurnId,storedProjection,turnPosition}from"#harness/session-machine/view.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{withContextScope}from"#context/run-step.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{hydrateDurableSession}from"#execution/session.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{dropClosedRecords,publishTransition,saveTransition,sessionView}from"#harness/session-machine/commit.js";import{setChannelContext}from"#execution/channel-context.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{forwardSessionInput}from"#execution/forward-session-input.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{bindSessionInstrumentation}from"#instrumentation/runtime.js";const log=createLogger(`execution.publish-session-events`);async function publishSessionEvents(e,t){return
|
|
1
|
+
import"#protocol/session-projection.js";import{createLogger}from"#internal/logging.js";import{callAdapterEventHandler}from"#channel/adapter.js";import{contextStorage}from"#context/container.js";import{currentProjection,enterSessionProjection,recordPublishedEvent,saveSessionProjection}from"#harness/session-machine/current.js";import{AuthKey,InitiatorAuthKey,ParentSessionKey,SessionKey,TurnDeliveryIdsKey}from"#context/keys.js";import{encodeMessageStreamEvent,stampMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{validateHarnessModelMessages}from"#harness/messages.js";import{activeTurnId,storedProjection,turnPosition}from"#harness/session-machine/view.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{withContextScope}from"#context/run-step.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{hydrateDurableSession}from"#execution/session.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{dropClosedRecords,publishTransition,saveTransition,sessionView}from"#harness/session-machine/commit.js";import{setChannelContext}from"#execution/channel-context.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{forwardSessionInput}from"#execution/forward-session-input.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{isHookCancellableEvent}from"#execution/session/turn-event-handler.js";import{TurnCancelledError}from"#harness/turn-cancellation.js";import{bindSessionInstrumentation}from"#instrumentation/runtime.js";const log=createLogger(`execution.publish-session-events`);async function publishSessionEvents(e,t,n){let r=new AbortController;return{...await publishEventsFromStep(e,`own`,t,n?.canCancelTurn?()=>r.abort(new TurnCancelledError):void 0),cancelled:r.signal.aborted}}async function publishEventsFromStep(e,t,n,r){if(n.length===0)return{serializedContext:e.serializedContext,sessionState:e.sessionState};let{published:i}=await publishFromSessionStep(await restoreSessionStep(e),{cancelTurn:r,origin:t,async publish(e){for(let t of n)await e(t)}});return i}async function restoreSessionStep(e){return{ctx:await deserializeContext(e.serializedContext),durableSession:readDurableSession(e.sessionState),sessionWritable:e.sessionWritable}}async function publishFromSessionStep(e,t){let{ctx:n}=e,r=await publishInSessionScope(e,t),i=t.updateSession?.(r.session,r.result)??{session:r.session},a=readSessionProjection(n),o=reconcileSessionContinuationToken(n,saveSessionProjection(dropClosedRecords(i.session,a),n));return{published:{serializedContext:serializeContext(n),sessionState:createDurableSessionState({session:o}),...`history`in o&&{history:o.history}},result:i.result}}async function publishInSessionScope(e,t){let{ctx:n}=e;enterSessionProjection(n,e.durableSession.state);let r=resolveEffectiveAgentRuntime(n.require(BundleKey),n),i=hydrateDurableSession({compactionOverrides:{thresholdPercent:r.thresholdPercent},durable:e.durableSession,turnAgent:r.turnAgent}),a=e.history===void 0?i:{...i,history:validateHarnessModelMessages(e.history)},o=t.origin===`own`?bindSessionInstrumentation({agentName:r.turnAgent.id,ctx:n,rootSessionId:a.rootSessionId??a.sessionId,sessionId:a.sessionId}):void 0,s=openSessionEventPublisher({cancelTurn:t.cancelTurn,ctx:n,inputSource:t.inputSource,origin:t.origin,sessionWritable:e.sessionWritable});try{return await withContextScope(n,a,async e=>{let r=o?.createHandleEvent({handleEvent:s.publish,turnId:activeTurnId(turnPosition(readSessionProjection(n)))})??s.publish;return{result:await t.publish(r,e),session:e}})}finally{await o?.flush(),s.writer.release()}}function openSessionEventPublisher(e){let{ctx:t,origin:n}=e,r=createSessionEventDispatcher(e),i=openSessionEventWriter({deliveryIds:()=>n===`own`?t.get(TurnDeliveryIdsKey):void 0,sessionWritable:e.sessionWritable}),emit=async e=>{let n=await i.write(await r.deliver(e));return recordPublishedEvent(t,n),n};return{dispatcher:r,writer:i,emit,async publish(t){let n=await emit(t);await r.runHooks(n,isHookCancellableEvent(n.type)?e.cancelTurn:void 0)}}}function createSessionEventDispatcher(e){let{ctx:t,inputSource:n}=e,r=t.require(ChannelKey),i=buildAdapterContext(r,t);return{adapterCtx:i,async deliver(e){let a=await forwardSessionInput(t,e,n)?e:await callAdapterEventHandler(r,e,n===void 0?i:{...i,inputSource:n});return setChannelContext(t,{...r,state:{...i.state}}),a},async runHooks(e,n){await dispatchStreamEventHooks({cancelTurn:n,ctx:t,event:e,registry:t.require(BundleKey).hookRegistry})}}}function openSessionEventWriter(e){let t=e.sessionWritable.getWriter(),n=!1,release=()=>{n||(n=!0,t.releaseLock())};return{async write(n){let r=stampMessageStreamEvent(n,e.deliveryIds());return await t.write(encodeMessageStreamEvent(r)),r},close:async()=>{await t.close(),release()},release}}function readSessionProjection(e){return currentProjection(e)}async function publishTerminalSessionEvent(e){let t=e.serializedContext[`eve.sessionId`]??``,n={errorId:e.errorId,sessionId:t},{type:r}=e.event,i,a;try{i=await deserializeContext(e.serializedContext),enterSessionProjection(i,void 0),a=openSessionEventPublisher({ctx:i,origin:`own`,sessionWritable:e.sessionWritable})}catch(t){log.error(`failed to restore context for terminal ${r} event`,{...n,error:t}),await writeUnroutedSessionEvent(e.sessionWritable,e.event).catch(e=>log.error(`failed to write terminal ${r} event`,{...n,error:e}));return}let o=i.get(AuthKey)??null;i.setVirtualContext(SessionKey,{auth:{current:o,initiator:i.get(InitiatorAuthKey)??o},parent:i.get(ParentSessionKey),sessionId:t,turn:e.turn??{id:`turn_0`,sequence:0}});let publish=async e=>{await a.emit(e),await a.writer.close()},s;try{s=bindSessionInstrumentation({agentName:i.require(BundleKey).turnAgent.id,ctx:i,rootSessionId:i.get(ParentSessionKey)?.rootSessionId??t,sessionId:t})}catch(e){log.error(`failed to bind instrumentation for terminal ${r} event`,{...n,error:e})}let c=s?.createHandleEvent({handleEvent:publish,turnId:e.turnId})??publish;try{await contextStorage.run(i,()=>c(e.event))}catch(e){log.error(`failed to publish terminal ${r} event`,{...n,error:e})}finally{a.writer.release();try{await s?.flush()}catch(e){log.error(`failed to flush instrumentation after terminal ${r} event`,{...n,error:e})}}}async function writeUnroutedSessionEvent(e,t){let n=openSessionEventWriter({deliveryIds:()=>void 0,sessionWritable:e});try{await n.write(t),await n.close()}finally{n.release()}}async function commitSessionStep(e,t,n){let{state:r}=`ctx`in e?e.durableSession:readDurableSession(e.sessionState),i=sessionView(storedProjection(r),r),a=t(i);if(a.length>1&&a.some(e=>e.turn!==i.turn)||a.filter(e=>e.signIns!==void 0).length>1)throw Error(`A transition batch must not overlap turn or sign-in snapshots.`);return`ctx`in e?await commit(e,a,n):a.every(e=>changesNothing(i,e))?{serializedContext:e.serializedContext,sessionState:e.sessionState}:await commit(await restoreSessionStep(e),a,n)}async function commit(e,t,n){let{published:r}=await publishFromSessionStep(e,{inputSource:n.inputSource,origin:n.origin,async publish(e){for(let n of t)await publishTransition(n,e)},updateSession:e=>({session:t.reduce((e,t)=>saveTransition(e,t),e)})});return r}function changesNothing(e,t){return t.turn===e.turn&&t.events.length===0&&t.signIns===void 0&&t.relays===void 0&&t.commit===void 0&&t.clearsHistory===void 0}export{commitSessionStep,openSessionEventPublisher,publishFromSessionStep,publishSessionEvents,publishTerminalSessionEvent,readSessionProjection,restoreSessionStep};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash,randomUUID}from"node:crypto";import{access}from"node:fs/promises";import{posix}from"node:path";import{withDevelopmentSandboxTags}from"#execution/sandbox/development-run.js";import{importInstalledEnginePackage,isEveDevEnvironment}from"#internal/application/optional-package-install.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{SANDBOX_AGENT_ENV}from"#execution/sandbox/session.js";import{assertMicrosandboxPlatformCandidate,ensureMicrosandboxBaseRuntime}from"#execution/sandbox/bindings/microsandbox-platform.js";import{MICROSANDBOX_METADATA_VERSION,createMicrosandboxSessionMetadata,writeSessionMetadata}from"#execution/sandbox/bindings/microsandbox-metadata.js";import{MICROSANDBOX_USER}from"#execution/sandbox/bindings/microsandbox-options.js";import{createMicrosandboxWithProgress}from"#execution/sandbox/bindings/microsandbox-create.js";import{applyMicrosandboxNetwork,createMicrosandboxNetworkPlan,createTransformBrokerEnvironment}from"#execution/sandbox/bindings/microsandbox-network.js";import{adaptMicrosandboxExecToSandboxProcess}from"#execution/sandbox/bindings/microsandbox-process.js";import{isMicrosandboxNotFoundError,isMicrosandboxNotFoundError as isMicrosandboxNotFoundError$1,isMicrosandboxSnapshotSourceRunningError,isMicrosandboxStillRunningError,removeSnapshotIfExists,removeSnapshotIfExists as removeSnapshotIfExists$1,sandboxExists,snapshotExists,snapshotExists as snapshotExists$1}from"#execution/sandbox/bindings/microsandbox-provider-state.js";const MICROSANDBOX_PACKAGE_NAME=`microsandbox`,MICROSANDBOX_INSTALL_SPECIFIER=`${MICROSANDBOX_PACKAGE_NAME}@0.5.5`,MICROSANDBOX_STOP_TIMEOUT_MS=1e4,MICROSANDBOX_HOME=`/home/${MICROSANDBOX_USER}`;var MicrosandboxVm=class{#e;#t;#n;#r;#i;#a;#o;constructor(e,t,n,r,i,a,o){this.#e=e,this.#i=t,this.#a=n,this.#n=r,this.#t=i,this.#r=a,this.#o=o}get id(){return this.#e.sessionKey}get name(){return this.#a}async captureState(e){if(this.#r=e,isEveDevEnvironment())return this.#t!==void 0&&await this.writeMetadata(this.#t,e),createMicrosandboxSessionMetadata({networkPolicy:this.#n,optionsHash:e,sandboxName:this.#a,stateSnapshotName:this.#o});let t=this.#o,n=createProviderName(`eve-sbx-state`,`${this.#e.sessionKey}:${randomUUID()}`);return await this.stopAndSnapshot(n),this.#o=n,this.#t!==void 0&&await this.writeMetadata(this.#t,e),t!==void 0&&await removeSnapshotIfExists$1(this.#e.module,t),createMicrosandboxSessionMetadata({networkPolicy:this.#n,optionsHash:e,sandboxName:this.#a,stateSnapshotName:n})}async detach(){await this.#i.detach().catch(()=>{})}async shutdown(){await this.#i.stop().catch(()=>{}),await this.detach()}async stop(){await this.#i.stop(),await this.detach()}async readFileBytes(e){try{let t=this.#i.fs();return await t.exists(e)?Buffer.from(await t.read(e)):null}catch{return null}}async removePath(e){let t=`${e.force===!0?`f`:``}${e.recursive===!0?`r`:``}`,n=`${t.length>0?`rm -${t}`:`rm`} -- ${shellQuote(e.path)}`;await this.runInternalCommand({abortSignal:e.abortSignal,command:n,user:MICROSANDBOX_USER})}async removePersisted(){await removeSandboxIfExists(this.#e.module,this.#a);let e=this.#o;e!==void 0&&(await removeSnapshotIfExists$1(this.#e.module,e),this.#o=void 0)}async setNetworkPolicy(e){let t=this.#o,n=createProviderName(`eve-sbx-state`,`${this.#e.sessionKey}:${randomUUID()}`),r=this.#a;await this.stopAndSnapshot(n),await removeSandboxIfExists(this.#e.module,r);let i=createProviderName(`eve-sbx-ses`,`${this.#e.sessionKey}:${randomUUID()}`);this.#i=await createMicrosandbox({fromSnapshot:n,module:this.#e.module,name:i,networkPolicy:e,options:this.#e.options,tags:this.#e.tags,user:MICROSANDBOX_USER,workdir:WORKSPACE_ROOT}),this.#a=i,this.#n=e,this.#o=void 0,this.#t!==void 0&&this.#r!==void 0&&await this.writeMetadata(this.#t,this.#r),await removeSnapshotIfExists$1(this.#e.module,n),t!==void 0&&await removeSnapshotIfExists$1(this.#e.module,t)}async spawn(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t={...SANDBOX_AGENT_ENV,...this.#e.options.env,HOME:MICROSANDBOX_HOME,...createTransformBrokerEnvironment(createMicrosandboxNetworkPlan(this.#n)),...e.env},n=await this.#i.execStreamWith(`bash`,n=>n.args([`-lc`,e.command]).cwd(e.workingDirectory??WORKSPACE_ROOT).envs(t).user(MICROSANDBOX_USER));return e.abortSignal!==void 0&&e.abortSignal.addEventListener(`abort`,()=>{n.kill().catch(()=>{})},{once:!0}),adaptMicrosandboxExecToSandboxProcess(n)}async stopAndSnapshot(e){await this.#i.stop().catch(()=>{}),await stopAndSnapshotMicrosandboxSandbox(this.#e.module,this.#a,e)}async writeFiles(e){let t=this.#i.fs();for(let n of e){let e=posix.dirname(n.path);await this.runInternalCommand({command:`mkdir -p ${shellQuote(e)}`,user:MICROSANDBOX_USER}),await t.write(n.path,n.content),await this.runInternalCommand({command:`chown ${MICROSANDBOX_USER}:${MICROSANDBOX_USER} ${shellQuote(n.path)}`,user:`root`})}}async writeMetadata(e,t){this.#t=e,this.#r=t,await writeSessionMetadata(e,{image:this.#e.options.image,networkPolicy:this.#n,optionsHash:t,sandboxName:this.#a,stateSnapshotName:this.#o,version:MICROSANDBOX_METADATA_VERSION})}async runInternalCommand(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t=await this.#i.execWith(`bash`,t=>t.args([`-lc`,e.command]).cwd(WORKSPACE_ROOT).user(e.user));if(t.code!==0){let n=e.failureMessage??`Microsandbox command failed.`;throw Error(`${n} ${t.stderr()}`.trim())}}};async function createPreparedMicrosandbox(e){let t=e.setupBaseRuntime?`allow-all`:e.networkPolicy,n=await createMicrosandbox({fromSnapshot:e.fromSnapshot,log:e.log,module:e.module,name:e.name,networkPolicy:t,options:e.options,resourcesPath:e.resourcesPath,tags:e.tags,user:e.setupBaseRuntime?void 0:MICROSANDBOX_USER,workdir:e.setupBaseRuntime?`/`:WORKSPACE_ROOT}),r=new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,e.name,t);return e.setupBaseRuntime&&(await withProgressHeartbeat(`preparing base runtime inside VM`,e.log,async()=>{await ensureMicrosandboxBaseRuntime(n,{log:e.log})}),e.networkPolicy!==void 0&&e.networkPolicy!==`allow-all`&&(e.log?.(`applying network policy`),await r.setNetworkPolicy(e.networkPolicy))),r}async function connectMicrosandbox(e){let t;try{t=await e.module.Sandbox.get(e.metadata.sandboxName)}catch(t){if(!isMicrosandboxNotFoundError$1(t))throw t;return e.metadata.stateSnapshotName===void 0?null:await restoreMicrosandboxSessionSnapshot(e)}if(t.status!==`running`&&t.status!==`draining`&&e.metadata.stateSnapshotName!==void 0)return await restoreMicrosandboxSessionSnapshot(e);let n=t.status===`running`||t.status===`draining`?await t.connectWithTimeout(1e4):await t.startDetached();return new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,e.metadata.sandboxName,e.metadata.networkPolicy,e.metadataPath,e.metadata.optionsHash,e.metadata.stateSnapshotName)}async function restoreMicrosandboxSessionSnapshot(e){if(e.metadata.stateSnapshotName===void 0||!await snapshotExists$1(e.module,e.metadata.stateSnapshotName))return null;let t=createProviderName(`eve-sbx-ses`,`${e.sessionKey}:${randomUUID()}`),n=await createMicrosandbox({fromSnapshot:e.metadata.stateSnapshotName,module:e.module,name:t,networkPolicy:e.metadata.networkPolicy,options:e.options,tags:e.tags,user:MICROSANDBOX_USER,workdir:WORKSPACE_ROOT});await removeSandboxIfExists(e.module,e.metadata.sandboxName);let r=new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,t,e.metadata.networkPolicy,e.metadataPath,e.metadata.optionsHash,e.metadata.stateSnapshotName);return await r.writeMetadata(e.metadataPath,e.metadata.optionsHash),r}const MICROSANDBOX_MISSING_PACKAGE_MESSAGE=`The microsandbox sandbox provider requires the \`microsandbox\` package, which is not bundled with eve. Install it in your application (for example \`pnpm add -D ${MICROSANDBOX_INSTALL_SPECIFIER}\`), or use DockerSandbox or VercelSandbox instead.`;async function loadMicrosandboxModule(e){e.log?.(`checking microsandbox platform support`),await assertMicrosandboxPlatformCandidate();let t=await withProgressHeartbeat(`loading microsandbox npm package`,e.log,()=>e.host.loadOptionalPackage({autoInstall:e.options.setup.autoInstall,importModule:async()=>await import(`microsandbox`),installPackageName:MICROSANDBOX_INSTALL_SPECIFIER,missingMessage:MICROSANDBOX_MISSING_PACKAGE_MESSAGE,packageName:MICROSANDBOX_PACKAGE_NAME}));if(e.log?.(`checking microsandbox VM runtime`),!t.isInstalled()){if(!e.options.setup.autoInstall||!isEveDevEnvironment())throw Error("The microsandbox VM runtime is not installed. Run `npx microsandbox install`, set MSB_PATH for a custom install, or let `eve dev` install it automatically with microsandbox({ setup: { autoInstall: true } }).");await withProgressHeartbeat(`installing microsandbox VM runtime`,e.log,async()=>{await t.setup().skipVerify(e.options.setup.skipVerify).install()})}return e.log?.(`microsandbox runtime ready`),t}async function withProgressHeartbeat(e,t,n){if(t?.(e),t===void 0)return await n();let r=Date.now(),i=setInterval(()=>{t(`${e} (${Math.round((Date.now()-r)/1e3)}s elapsed)`)},1e4);i.unref?.();try{return await n()}finally{clearInterval(i)}}async function loadMicrosandboxWithoutInstall(e){try{let t=await importInstalledEnginePackage({appRoot:e,packageName:MICROSANDBOX_PACKAGE_NAME});return t.isInstalled()?t:null}catch{return null}}async function stopAndSnapshotMicrosandboxSandbox(e,t,n){for(let r=0;r<3;r+=1){let i=await e.Sandbox.get(t);await i.stopWithTimeout(r===0?MICROSANDBOX_STOP_TIMEOUT_MS:0).catch(()=>{});try{await i.snapshot(n);return}catch(e){if(!isMicrosandboxSnapshotSourceRunningError(e)||r===2)throw e;await i.kill().catch(()=>{}),await new Promise(e=>setTimeout(e,250))}}}function createProviderName(e,t,n=``){return`${e}-${createStableHash(`${t}:${n}`).slice(0,32)}`}function createStableHash(e){return createHash(`sha256`).update(e).digest(`hex`)}async function doesPathExist(e){try{return await access(e),!0}catch{return!1}}async function createMicrosandbox(e){let t=e.module.Sandbox.builder(e.name).cpus(e.options.cpus).detached(!0).envs({...e.options.env,HOME:MICROSANDBOX_HOME}).labels(resolveMicrosandboxLabels(e.tags)).memory(e.options.memoryMiB).pullPolicy(e.options.pullPolicy).replace().workdir(e.workdir);t=e.fromSnapshot===void 0?t.image(e.options.image):t.fromSnapshot(e.fromSnapshot),e.options.image.startsWith(`127.0.0.1:`)&&(t=t.registry(e=>e.insecure())),e.resourcesPath!==void 0&&(t=t.volume(`/eve/resources`,t=>t.bind(e.resourcesPath).readonly())),e.user!==void 0&&(t=t.user(e.user));let n=e.fromSnapshot===void 0?`image "${e.options.image}"`:`snapshot "${e.fromSnapshot}"`;return await createMicrosandboxWithProgress({builder:applyMicrosandboxNetwork(t,e.networkPolicy),errorType:e.module.MicrosandboxError,log:e.log,source:n})}async function removeSandboxIfExists(e,t){for(let n=0;n<3;n+=1)try{let r=await e.Sandbox.get(t);await r.stopWithTimeout(n===0?MICROSANDBOX_STOP_TIMEOUT_MS:0).catch(()=>{}),await r.remove();return}catch(r){if(isMicrosandboxNotFoundError$1(r))return;if(isMicrosandboxStillRunningError(r)&&n<2){await(await e.Sandbox.get(t).catch(()=>null))?.kill().catch(()=>{}),await new Promise(e=>setTimeout(e,250));continue}throw r}}function resolveMicrosandboxLabels(e){return{"eve.provider":`microsandbox`,...withDevelopmentSandboxTags(e)}}export{MicrosandboxVm,connectMicrosandbox,createPreparedMicrosandbox,createProviderName,createStableHash,doesPathExist,isMicrosandboxNotFoundError,loadMicrosandboxModule,loadMicrosandboxWithoutInstall,removeSnapshotIfExists,sandboxExists,snapshotExists,stopAndSnapshotMicrosandboxSandbox};
|
|
1
|
+
import{createHash,randomUUID}from"node:crypto";import{access}from"node:fs/promises";import{posix}from"node:path";import{withDevelopmentSandboxTags}from"#execution/sandbox/development-run.js";import{importInstalledEnginePackage,isEveDevEnvironment}from"#internal/application/optional-package-install.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{SANDBOX_AGENT_ENV}from"#execution/sandbox/session.js";import{assertMicrosandboxPlatformCandidate,ensureMicrosandboxBaseRuntime}from"#execution/sandbox/bindings/microsandbox-platform.js";import{MICROSANDBOX_METADATA_VERSION,createMicrosandboxSessionMetadata,writeSessionMetadata}from"#execution/sandbox/bindings/microsandbox-metadata.js";import{MICROSANDBOX_USER}from"#execution/sandbox/bindings/microsandbox-options.js";import{createMicrosandboxWithProgress}from"#execution/sandbox/bindings/microsandbox-create.js";import{applyMicrosandboxNetwork,createMicrosandboxNetworkPlan,createTransformBrokerEnvironment}from"#execution/sandbox/bindings/microsandbox-network.js";import{adaptMicrosandboxExecToSandboxProcess}from"#execution/sandbox/bindings/microsandbox-process.js";import{readInstalledPackageVersion}from"#internal/application/optional-package-import.js";import{isMicrosandboxNotFoundError,isMicrosandboxNotFoundError as isMicrosandboxNotFoundError$1,isMicrosandboxSnapshotSourceRunningError,isMicrosandboxStillRunningError,removeSnapshotIfExists,removeSnapshotIfExists as removeSnapshotIfExists$1,sandboxExists,snapshotExists,snapshotExists as snapshotExists$1}from"#execution/sandbox/bindings/microsandbox-provider-state.js";const MICROSANDBOX_PACKAGE_NAME=`microsandbox`,MICROSANDBOX_INSTALL_SPECIFIER=`${MICROSANDBOX_PACKAGE_NAME}@0.5.5`,MICROSANDBOX_STOP_TIMEOUT_MS=1e4,MICROSANDBOX_HOME=`/home/${MICROSANDBOX_USER}`;var MicrosandboxVm=class{#e;#t;#n;#r;#i;#a;#o;constructor(e,t,n,r,i,a,o){this.#e=e,this.#i=t,this.#a=n,this.#n=r,this.#t=i,this.#r=a,this.#o=o}get id(){return this.#e.sessionKey}get name(){return this.#a}async captureState(e){if(this.#r=e,isEveDevEnvironment())return this.#t!==void 0&&await this.writeMetadata(this.#t,e),createMicrosandboxSessionMetadata({networkPolicy:this.#n,optionsHash:e,sandboxName:this.#a,stateSnapshotName:this.#o});let t=this.#o,n=createProviderName(`eve-sbx-state`,`${this.#e.sessionKey}:${randomUUID()}`);return await this.stopAndSnapshot(n),this.#o=n,this.#t!==void 0&&await this.writeMetadata(this.#t,e),t!==void 0&&await removeSnapshotIfExists$1(this.#e.module,t),createMicrosandboxSessionMetadata({networkPolicy:this.#n,optionsHash:e,sandboxName:this.#a,stateSnapshotName:n})}async detach(){await this.#i.detach().catch(()=>{})}async shutdown(){await this.#i.stop().catch(()=>{}),await this.detach()}async stop(){await this.#i.stop(),await this.detach()}async readFileBytes(e){try{let t=this.#i.fs();return await t.exists(e)?Buffer.from(await t.read(e)):null}catch{return null}}async removePath(e){let t=`${e.force===!0?`f`:``}${e.recursive===!0?`r`:``}`,n=`${t.length>0?`rm -${t}`:`rm`} -- ${shellQuote(e.path)}`;await this.runInternalCommand({abortSignal:e.abortSignal,command:n,user:MICROSANDBOX_USER})}async removePersisted(){await removeSandboxIfExists(this.#e.module,this.#a);let e=this.#o;e!==void 0&&(await removeSnapshotIfExists$1(this.#e.module,e),this.#o=void 0)}async setNetworkPolicy(e){let t=this.#o,n=createProviderName(`eve-sbx-state`,`${this.#e.sessionKey}:${randomUUID()}`),r=this.#a;await this.stopAndSnapshot(n),await removeSandboxIfExists(this.#e.module,r);let i=createProviderName(`eve-sbx-ses`,`${this.#e.sessionKey}:${randomUUID()}`);this.#i=await createMicrosandbox({fromSnapshot:n,module:this.#e.module,name:i,networkPolicy:e,options:this.#e.options,tags:this.#e.tags,user:MICROSANDBOX_USER,workdir:WORKSPACE_ROOT}),this.#a=i,this.#n=e,this.#o=void 0,this.#t!==void 0&&this.#r!==void 0&&await this.writeMetadata(this.#t,this.#r),await removeSnapshotIfExists$1(this.#e.module,n),t!==void 0&&await removeSnapshotIfExists$1(this.#e.module,t)}async spawn(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t={...SANDBOX_AGENT_ENV,...this.#e.options.env,HOME:MICROSANDBOX_HOME,...createTransformBrokerEnvironment(createMicrosandboxNetworkPlan(this.#n)),...e.env},n=await this.#i.execStreamWith(`bash`,n=>n.args([`-lc`,e.command]).cwd(e.workingDirectory??WORKSPACE_ROOT).envs(t).user(MICROSANDBOX_USER));return e.abortSignal!==void 0&&e.abortSignal.addEventListener(`abort`,()=>{n.kill().catch(()=>{})},{once:!0}),adaptMicrosandboxExecToSandboxProcess(n)}async stopAndSnapshot(e){await this.#i.stop().catch(()=>{}),await stopAndSnapshotMicrosandboxSandbox(this.#e.module,this.#a,e)}async writeFiles(e){let t=this.#i.fs();for(let n of e){let e=posix.dirname(n.path);await this.runInternalCommand({command:`mkdir -p ${shellQuote(e)}`,user:MICROSANDBOX_USER}),await t.write(n.path,n.content),await this.runInternalCommand({command:`chown ${MICROSANDBOX_USER}:${MICROSANDBOX_USER} ${shellQuote(n.path)}`,user:`root`})}}async writeMetadata(e,t){this.#t=e,this.#r=t,await writeSessionMetadata(e,{image:this.#e.options.image,networkPolicy:this.#n,optionsHash:t,sandboxName:this.#a,stateSnapshotName:this.#o,version:MICROSANDBOX_METADATA_VERSION})}async runInternalCommand(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t=await this.#i.execWith(`bash`,t=>t.args([`-lc`,e.command]).cwd(WORKSPACE_ROOT).user(e.user));if(t.code!==0){let n=e.failureMessage??`Microsandbox command failed.`;throw Error(`${n} ${t.stderr()}`.trim())}}};async function createPreparedMicrosandbox(e){let t=e.setupBaseRuntime?`allow-all`:e.networkPolicy,n=await createMicrosandbox({fromSnapshot:e.fromSnapshot,log:e.log,module:e.module,name:e.name,networkPolicy:t,options:e.options,resourcesPath:e.resourcesPath,tags:e.tags,user:e.setupBaseRuntime?void 0:MICROSANDBOX_USER,workdir:e.setupBaseRuntime?`/`:WORKSPACE_ROOT}),r=new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,e.name,t);return e.setupBaseRuntime&&(await withProgressHeartbeat(`preparing base runtime inside VM`,e.log,async()=>{await ensureMicrosandboxBaseRuntime(n,{log:e.log})}),e.networkPolicy!==void 0&&e.networkPolicy!==`allow-all`&&(e.log?.(`applying network policy`),await r.setNetworkPolicy(e.networkPolicy))),r}async function connectMicrosandbox(e){let t;try{t=await e.module.Sandbox.get(e.metadata.sandboxName)}catch(t){if(!isMicrosandboxNotFoundError$1(t))throw t;return e.metadata.stateSnapshotName===void 0?null:await restoreMicrosandboxSessionSnapshot(e)}if(t.status!==`running`&&t.status!==`draining`&&e.metadata.stateSnapshotName!==void 0)return await restoreMicrosandboxSessionSnapshot(e);let n=t.status===`running`||t.status===`draining`?await t.connectWithTimeout(1e4):await t.startDetached();return new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,e.metadata.sandboxName,e.metadata.networkPolicy,e.metadataPath,e.metadata.optionsHash,e.metadata.stateSnapshotName)}async function restoreMicrosandboxSessionSnapshot(e){if(e.metadata.stateSnapshotName===void 0||!await snapshotExists$1(e.module,e.metadata.stateSnapshotName))return null;let t=createProviderName(`eve-sbx-ses`,`${e.sessionKey}:${randomUUID()}`),n=await createMicrosandbox({fromSnapshot:e.metadata.stateSnapshotName,module:e.module,name:t,networkPolicy:e.metadata.networkPolicy,options:e.options,tags:e.tags,user:MICROSANDBOX_USER,workdir:WORKSPACE_ROOT});await removeSandboxIfExists(e.module,e.metadata.sandboxName);let r=new MicrosandboxVm({module:e.module,options:e.options,sessionKey:e.sessionKey,tags:e.tags},n,t,e.metadata.networkPolicy,e.metadataPath,e.metadata.optionsHash,e.metadata.stateSnapshotName);return await r.writeMetadata(e.metadataPath,e.metadata.optionsHash),r}const MICROSANDBOX_MISSING_PACKAGE_MESSAGE=`The microsandbox sandbox provider requires the \`microsandbox\` package, which is not bundled with eve. Install it in your application (for example \`pnpm add -D ${MICROSANDBOX_INSTALL_SPECIFIER}\`), or use DockerSandbox or VercelSandbox instead.`;async function loadMicrosandboxModule(e){e.log?.(`checking microsandbox platform support`),await assertMicrosandboxPlatformCandidate();let t=await withProgressHeartbeat(`loading microsandbox npm package`,e.log,()=>e.host.loadOptionalPackage({autoInstall:e.options.setup.autoInstall,importModule:async()=>await import(`microsandbox`),installPackageName:MICROSANDBOX_INSTALL_SPECIFIER,missingMessage:MICROSANDBOX_MISSING_PACKAGE_MESSAGE,packageName:MICROSANDBOX_PACKAGE_NAME}));if(await assertSupportedMicrosandboxApi(t,e.host),e.log?.(`checking microsandbox VM runtime`),!t.isInstalled()){if(!e.options.setup.autoInstall||!isEveDevEnvironment())throw Error("The microsandbox VM runtime is not installed. Run `npx microsandbox install`, set MSB_PATH for a custom install, or let `eve dev` install it automatically with microsandbox({ setup: { autoInstall: true } }).");await withProgressHeartbeat(`installing microsandbox VM runtime`,e.log,async()=>{await t.setup().skipVerify(e.options.setup.skipVerify).install()})}return e.log?.(`microsandbox runtime ready`),t}async function assertSupportedMicrosandboxApi(e,t){let n=e;if(typeof n.isInstalled==`function`&&typeof n.setup==`function`)return;let r=await readInstalledPackageVersion({appRoot:t.resolveProjectPath(`.`),packageName:MICROSANDBOX_PACKAGE_NAME}).catch(()=>void 0),i=r===void 0?"The installed `microsandbox`":`\`microsandbox@${r}\``;throw Error(`${i} is not supported by eve. Install the supported version with \`pnpm add -D ${MICROSANDBOX_INSTALL_SPECIFIER}\`, or use DockerSandbox or VercelSandbox instead.`)}async function withProgressHeartbeat(e,t,n){if(t?.(e),t===void 0)return await n();let r=Date.now(),i=setInterval(()=>{t(`${e} (${Math.round((Date.now()-r)/1e3)}s elapsed)`)},1e4);i.unref?.();try{return await n()}finally{clearInterval(i)}}async function loadMicrosandboxWithoutInstall(e){try{let t=await importInstalledEnginePackage({appRoot:e,packageName:MICROSANDBOX_PACKAGE_NAME});return t.isInstalled()?t:null}catch{return null}}async function stopAndSnapshotMicrosandboxSandbox(e,t,n){for(let r=0;r<3;r+=1){let i=await e.Sandbox.get(t);await i.stopWithTimeout(r===0?MICROSANDBOX_STOP_TIMEOUT_MS:0).catch(()=>{});try{await i.snapshot(n);return}catch(e){if(!isMicrosandboxSnapshotSourceRunningError(e)||r===2)throw e;await i.kill().catch(()=>{}),await new Promise(e=>setTimeout(e,250))}}}function createProviderName(e,t,n=``){return`${e}-${createStableHash(`${t}:${n}`).slice(0,32)}`}function createStableHash(e){return createHash(`sha256`).update(e).digest(`hex`)}async function doesPathExist(e){try{return await access(e),!0}catch{return!1}}async function createMicrosandbox(e){let t=e.module.Sandbox.builder(e.name).cpus(e.options.cpus).detached(!0).envs({...e.options.env,HOME:MICROSANDBOX_HOME}).labels(resolveMicrosandboxLabels(e.tags)).memory(e.options.memoryMiB).pullPolicy(e.options.pullPolicy).replace().workdir(e.workdir);t=e.fromSnapshot===void 0?t.image(e.options.image):t.fromSnapshot(e.fromSnapshot),e.options.image.startsWith(`127.0.0.1:`)&&(t=t.registry(e=>e.insecure())),e.resourcesPath!==void 0&&(t=t.volume(`/eve/resources`,t=>t.bind(e.resourcesPath).readonly())),e.user!==void 0&&(t=t.user(e.user));let n=e.fromSnapshot===void 0?`image "${e.options.image}"`:`snapshot "${e.fromSnapshot}"`;return await createMicrosandboxWithProgress({builder:applyMicrosandboxNetwork(t,e.networkPolicy),errorType:e.module.MicrosandboxError,log:e.log,source:n})}async function removeSandboxIfExists(e,t){for(let n=0;n<3;n+=1)try{let r=await e.Sandbox.get(t);await r.stopWithTimeout(n===0?MICROSANDBOX_STOP_TIMEOUT_MS:0).catch(()=>{}),await r.remove();return}catch(r){if(isMicrosandboxNotFoundError$1(r))return;if(isMicrosandboxStillRunningError(r)&&n<2){await(await e.Sandbox.get(t).catch(()=>null))?.kill().catch(()=>{}),await new Promise(e=>setTimeout(e,250));continue}throw r}}function resolveMicrosandboxLabels(e){return{"eve.provider":`microsandbox`,...withDevelopmentSandboxTags(e)}}export{MicrosandboxVm,connectMicrosandbox,createPreparedMicrosandbox,createProviderName,createStableHash,doesPathExist,isMicrosandboxNotFoundError,loadMicrosandboxModule,loadMicrosandboxWithoutInstall,removeSnapshotIfExists,sandboxExists,snapshotExists,stopAndSnapshotMicrosandboxSandbox};
|
|
@@ -105,5 +105,6 @@ export declare class ActiveTurn {
|
|
|
105
105
|
* answered nothing, so its message is for the model.
|
|
106
106
|
*/
|
|
107
107
|
private routeAdmittedToChildren;
|
|
108
|
-
|
|
108
|
+
/** Stops the turn, as `session.cancel()` does; a hook's `ctx.cancel()` uses it too. */
|
|
109
|
+
abort(): void;
|
|
109
110
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{coalesceDeliveries}from"#harness/messages.js";import{activeTurnId,storedProjection,turnPosition}from"#harness/session-machine/view.js";import{readDurableSession}from"#execution/durable-session-read.js";import{mapHeldInputResponsesStep}from"#execution/proxied-deliver-step.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{admitSessionInboxPayload}from"#execution/session/admission.js";import{isSteeringDelivery,isSteeringMessage}from"#execution/session/input-queue.js";import{routeSelectedDelivery}from"#execution/session/route-selected-delivery.js";import{createTurnControl}from"#execution/session/turn-control.js";import{decodeSessionInboxPayload}from"#execution/session-inbox/protocol.js";import{runMessageBatchBudget}from"#execution/tools/workflow/messages.js";import{isAppliedRunMessage,takeLeadingAppliedRunMessages}from"#execution/session-workflow-tool-run.js";
|
|
1
|
+
import{coalesceDeliveries}from"#harness/messages.js";import{activeTurnId,storedProjection,turnPosition}from"#harness/session-machine/view.js";import{readDurableSession}from"#execution/durable-session-read.js";import{TurnCancelledError}from"#harness/turn-cancellation.js";import{mapHeldInputResponsesStep}from"#execution/proxied-deliver-step.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{admitSessionInboxPayload}from"#execution/session/admission.js";import{isSteeringDelivery,isSteeringMessage}from"#execution/session/input-queue.js";import{routeSelectedDelivery}from"#execution/session/route-selected-delivery.js";import{createTurnControl}from"#execution/session/turn-control.js";import{decodeSessionInboxPayload}from"#execution/session-inbox/protocol.js";import{runMessageBatchBudget}from"#execution/tools/workflow/messages.js";import{isAppliedRunMessage,takeLeadingAppliedRunMessages}from"#execution/session-workflow-tool-run.js";var ActiveTurn=class{admitted=new Set;routedToChildren=new Set;mappedForHeldRequest=new Set;runtimeResults=[];controller;expectedTurnId;input;identity;unsubscribe;unsubscribeDelivery;steeringController;caller;compacted=!1;constructor(e,t,n=createTurnControl()){this.controller=n.cancellation,this.steeringController=n.steering,this.input=e,this.caller=t.caller,this.identity={callerCallId:t.caller?.callId,principal:t.principal},this.expectedTurnId=activeTurnId(turnPosition(storedProjection(readDurableSession(e.cursor.sessionState).state))),this.unsubscribe=e.inbox.onInterrupt(e=>{this.cancelsThisTurn(e)&&this.abort()}),this.unsubscribeDelivery=e.inbox.onDelivery(this.signalSteering)}signalSteering=e=>{let t;try{t=decodeSessionInboxPayload(e)}catch{return}t.kind===`deliver`&&isSteeringMessage(t,this.identity)&&!this.input.cursor.sessionState.hasProxyInputRequests&&this.steeringController.abort()};get signal(){return this.controller.signal}dispose(){this.unsubscribe(),this.unsubscribeDelivery()}get steeringSignal(){return this.steeringController.signal}resetSteering(){this.steeringController.signal.aborted&&(this.unsubscribeDelivery(),this.steeringController=new AbortController,this.unsubscribeDelivery=this.input.inbox.onDelivery(this.signalSteering))}async admitBoundary(){let e=this.input.inbox.drain();for(let t of e)await this.admit(t)}async takeSteering(e){let t=[];for(;;){let n=this.input.queue.takeSteering(this.admitted,this.identity,e);if(n===void 0)break;for(let e of n.sequences)this.admitted.delete(e);let r=await routeSelectedDelivery(n,this.input.cursor);if(r.kind===`cancel-turn`){this.abort();break}r.kind===`turn`&&t.push(r.delivery)}if(this.resetSteering(),t.length===0)return;let n=t.length===1?t[0]:coalesceDeliveries(t);return n.caller!==void 0&&(this.caller=n.caller),n}takeBoundaryMessages(e){let t=[],n=[];for(let r of this.runtimeResults){let i=asBoundaryMessage(r);i===void 0||e!==void 0&&i.kind!==e?n.push(r):t.push(i)}return this.runtimeResults.splice(0,this.runtimeResults.length,...n),t}takeAppliedRunMessages(){let e=runMessageBatchBudget(),t=[];for(let n=this.runtimeResults[0];n!==void 0;n=this.runtimeResults[0]){if(n===`cancelled`||n.kind!==`workflow`||!isAppliedRunMessage(n.message)||!e(n.message))return t;t.push(n.message),this.runtimeResults.shift()}return[...t,...takeLeadingAppliedRunMessages(this.input.inbox,e)]}async nextRuntimeEvent(e){for(;;){let t=await this.routeAdmittedToChildren();if(this.signal.aborted)return`cancelled`;if(t)return{kind:`steering`};let n=this.runtimeResults.shift();if(n!==void 0)return n;let r=await this.waitForInboxOrTimer(e);if(r!==void 0)return{callId:r,kind:`timeout`};let i=await this.input.inbox.next();if(i===void 0)throw Error(`Session inbox closed before runtime actions completed.`);if(await this.admit(i))return{kind:`input`}}}async takeInputResponses(e){for(let t of this.admitted){let n=this.input.queue.delivery(t);if(n===void 0)continue;let r=n.payloads.flatMap(e=>e.inputResponses??[]);if(r.length===0)continue;if(!r.some(t=>e.has(t.requestId))){if(this.mappedForHeldRequest.has(t))continue;this.mappedForHeldRequest.add(t);let r=n,i=await this.input.cursor.advance(t=>mapHeldInputResponsesStep({delivery:r,requestIds:[...e],...t}));if(i.delivery===void 0)continue;n=i.delivery}this.admitted.delete(t);let i=isSteeringDelivery(n,this.identity,{heldOnPerson:!0})?void 0:splitAnswers(n);return this.input.queue.replaceDelivery(t,i?.rest),i?.answers??n}}async waitForInboxOrTimer(e){if(e.length===0||this.input.inbox.hasPending())return;let t=this.input.inbox.whenPending().then(()=>void 0);return await Promise.race([t,...e])}cancelsThisTurn(e){return e.kind===`reset`||e.kind===`session-failure`?!0:e.kind===`cancel`?e.turnId===void 0||e.turnId===this.expectedTurnId:!1}async admit(e){let t=await admitSessionInboxPayload(e,this.input);switch(t.kind){case`delivery`:return this.admitted.add(t.admission.sequence),!0;case`runtime-action-result`:return this.runtimeResults.push({kind:`runtime-action-result`,results:t.payload.results}),!1;case`workflow`:return this.runtimeResults.push({kind:`workflow`,message:t.message}),!1;case`cancel`:return this.cancelsThisTurn(e)&&this.abort(),!1;case`consumed`:return e.kind===`authorization-callback`}}async routeAdmittedToChildren(){let e=!1;for(let t of this.admitted){if(this.routedToChildren.has(t))continue;let n=this.input.queue.delivery(t);if(n===void 0){this.admitted.delete(t);continue}this.routedToChildren.add(t);let r=await this.input.cursor.advance(e=>routeDeliverToChildren({delivery:n,...e}));if(r.kind===`cancel-turn`)return this.input.queue.replaceDelivery(t,void 0),this.admitted.delete(t),this.abort(),!1;if(this.input.queue.replaceDelivery(t,r.remainder),r.remainder===void 0){this.admitted.delete(t);continue}isSteeringMessage(r.remainder,this.identity)&&(e=!0)}return e}abort(){this.controller.signal.aborted||this.controller.abort(new TurnCancelledError)}};function asBoundaryMessage(e){if(e!==`cancelled`&&e.kind===`workflow`&&(e.message.from.taskId!==void 0||e.message.kind===`agent-started`))return e.message}function splitAnswers(e){let t=e.payloads.flatMap(e=>e.inputResponses===void 0?[]:[{inputResponses:e.inputResponses}]),n=e.payloads.flatMap(e=>{let{inputResponses:t,...n}=e;return Object.keys(n).length===0?[]:[n]});return{answers:{...e,payloads:t},rest:n.length===0?void 0:{...e,payloads:n}}}export{ActiveTurn};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";import{defaultDeliverResult}from"#channel/adapter.js";import{contextStorage}from"#context/container.js";import{currentProjection,enterSessionProjection,saveSessionProjection}from"#harness/session-machine/current.js";import{AuthKey,CapabilitiesKey,ChannelDeliveryKey,HandleEventKey,InitiatorAuthKey,OccurrenceIdKey,ParentSessionKey,ScheduleIdKey,ScheduleInstanceKey,SessionDynamicSubagentRuntimeRevisionKey,SessionDynamicToolRuntimeRevisionKey,SessionTitleKey,StaticModelReferenceKey,TurnDeliveryIdsKey}from"#context/keys.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{coalesceTurnInputs,validateHarnessModelMessages}from"#harness/messages.js";import{activeTurnId,isBetweenTurns,storedProjection,turnPosition}from"#harness/session-machine/view.js";import{createWorkflowRuntime}from"#execution/workflow-runtime.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{createDurableSessionValues,readDurableSession}from"#execution/durable-session-store.js";import{runStep}from"#context/run-step.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{readHitlState}from"#harness/hitl/index.js";import*as agentTraceState from"#tracing/eve/agent-trace-context-store.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey}from"#harness/authorization.js";import{refreshDynamicSessionSubagentsForRuntimeRevision}from"#context/dynamic-subagent-lifecycle.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{openSessionEventPublisher}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{dropClosedRecords,saveTransition,sessionView}from"#harness/session-machine/commit.js";import{matchSignIns}from"#harness/session-machine/transitions.js";import{sessionStartedForResolvers,turnStartedForResolvers}from"#harness/session-machine/resolver-events.js";import{derivePendingState}from"#execution/session/pending-turn-state.js";import{rebindMissingCompiledDynamicToolCallbacks,refreshDynamicSessionToolsForRuntimeRevision}from"#context/dynamic-tool-lifecycle.js";import{setChannelContext}from"#execution/channel-context.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{bindSessionInstrumentation}from"#instrumentation/runtime.js";import{deriveSessionTitle}from"#execution/eve-workflow-attributes.js";import{isTurnCancellation,throwIfTurnAborted}from"#harness/turn-cancellation.js";import{bindTurnCallerContext}from"#subagents/parent-notification.js";import{bindDynamicConnections}from"#execution/dynamic-connections.js";import{recoverDynamicConnectionRehydration}from"#execution/dynamic-connection-recovery.js";import{setEveAttributes}from"#runtime/attributes/emit.js";import{RuntimeActionSettlementTimesKey}from"#harness/runtime-action-settlement-state.js";import{matchAuthorizationCallbacks}from"#execution/authorization-callback-match.js";import{attributeAnswers}from"#execution/session/answer-caller.js";import{resolveSessionStepResult}from"#execution/session/turn-step-result.js";import{createTurnEventHandler}from"#execution/session/turn-event-handler.js";import{countRunUsage}from"#execution/agent-sessions/usage.js";import{buildRuntimeIdentity,createExecutionNodeStep}from"#execution/node-step.js";import{createExecutionHistoryView}from"#execution/history-view.js";import{runModelCallBatch}from"#execution/model-call-batching.js";import{createCancelledModelCallBatchResult}from"#execution/cancelled-model-call-batch.js";function channelDeliveryErrorCode(e){if(typeof e==`object`&&e&&`code`in e){let t=e.code;if(typeof t==`string`&&t.length>0)return t}return`CHANNEL_DELIVERY_FAILED`}async function turnStep(e){"use step";return await withSessionStateDelta(e,e=>runSessionStep({...e,serializedContext:bindTurnCallerContext(e.caller,e.serializedContext)}))}async function runSessionStep(e){let t={};try{return await runSessionStepBody(e,t)}finally{await t.title}}async function runSessionStepBody(e,t){let n=e.input?.delivery,r=n,i=e.input?.runtimeResults,a=readDurableSession(e.sessionState);for(let e of i?.delegatedUsage??[])a=countRunUsage(a,e);let o=await deserializeContext(e.serializedContext);enterSessionProjection(o,a.state);let s=o.require(ChannelKey),c=o.require(BundleKey),l=resolveEffectiveAgentRuntime(c,o);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&o.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(t.url))}catch{}let{signIns:u}=readHitlState(a.state),d;if(u.length>0&&r!==void 0){let{matches:e,remainingPayloads:t}=matchAuthorizationCallbacks(u,r.payloads);if(r={...r,payloads:t},e.length>0){let n=e.map(e=>e.result.attemptId),i=e.map(e=>e.result);o.set(PendingAuthorizationResultKey,i);let s=sessionView(storedProjection(a.state),a.state),c=matchSignIns(s,{attemptIds:n});if(c.events.length!==0)throw Error(`matchSignIns must not emit events.`);a=saveTransition(a,c),d=e,t.length===0&&(r=void 0)}}r?.payloads.some(e=>e.message!==void 0)&&(o.delete(ScheduleIdKey),o.delete(ScheduleInstanceKey),o.delete(OccurrenceIdKey),r.schedule!==void 0&&(o.set(ScheduleIdKey,r.schedule.definition),r.schedule.instance!==void 0&&o.set(ScheduleInstanceKey,r.schedule.instance),r.schedule.occurrenceId!==void 0&&o.set(OccurrenceIdKey,r.schedule.occurrenceId)));let f=o.get(AuthKey),p=o.has(InitiatorAuthKey);r?.auth!==void 0&&(o.set(AuthKey,r.auth??null),o.has(InitiatorAuthKey)||o.set(InitiatorAuthKey,r.auth??null));let m=r===void 0?d?.find(({challenge:e})=>e.candidateId===void 0)?.challenge.requester:void 0;m!==void 0&&o.set(AuthKey,m);let h={...hydrateDurableSession({compactionOverrides:{thresholdPercent:l.thresholdPercent},durable:a,turnAgent:l.turnAgent}),history:validateHarnessModelMessages(e.history)},g=createExecutionHistoryView(h),_=bindSessionInstrumentation({agentName:l.turnAgent.id,ctx:o,rootSessionId:h.rootSessionId??h.sessionId,sessionId:h.sessionId}),v=turnPosition(currentProjection(o)),y=isBetweenTurns(currentProjection(o));if(!v.sessionStarted&&!o.has(SessionTitleKey)&&!o.has(ParentSessionKey)){let e=n?.payloads.find(e=>e.message!==void 0)?.message,r=deriveSessionTitle(n?.title??e);r!==void 0&&(o.set(SessionTitleKey,r),t.title=setEveAttributes({"$eve.title":r}))}n!==void 0&&(await contextStorage.run(o,()=>_?.preparePreamble({sequence:v.sequence,sessionStarted:v.sessionStarted})),await contextStorage.run(o,()=>_?.instrumentChannelDelivery({agentName:c.turnAgent.id,ctx:o,delivery:n,rootSessionId:h.rootSessionId??h.sessionId,sequence:v.sequence,sessionId:h.sessionId,turnId:activeTurnId(v)})));let failChannelDeliveries=async e=>{await contextStorage.run(o,()=>_?.instrumentChannelDelivery({ctx:o,error:e,errorCode:channelDeliveryErrorCode(e),includeTurn:!1,outcome:`failed`})),await _?.flush()},b=openSessionEventPublisher({ctx:o,origin:`own`,sessionWritable:e.sessionWritable}),{adapterCtx:x}=b.dispatcher,S=new AbortController,C=e.abortSignal===void 0?S.signal:AbortSignal.any([e.abortSignal,S.signal]);try{let u=bindDynamicConnections(o,c.resolvedAgent),m={...c.graph.root,turnAgent:l.turnAgent},w=!1,T=createTurnEventHandler({abortSignal:C,bundle:c,canCancelTurn:e.input?.control===void 0,hookCancellation:S,ctx:o,dynamicConnections:u,effectiveAgent:l,effectiveNode:m,instrumentation:_,publisher:b}),handleEvent=async(e,t)=>{e.type===`compaction.completed`&&(w=!0),await T(e,t)},E=r!==void 0&&!y?structuredClone(x.state):void 0,D;if(r!==void 0){let e=[];try{for(let t of r.payloads){let n=s.deliver?await s.deliver(t,x):defaultDeliverResult(t);n!=null&&e.push(n)}}catch(e){throw await failChannelDeliveries(e),e}D=e.length===0?void 0:e.reduce(coalesceTurnInputs)}let O=r?.auth===void 0?void 0:attributeAnswers({responder:r.auth,state:a.state,stepInput:D});if(O!==void 0&&(D=O,f===void 0?o.delete(AuthKey):o.set(AuthKey,f),p||o.delete(InitiatorAuthKey)),r!==void 0&&D===void 0&&!y)f===void 0?o.delete(AuthKey):o.set(AuthKey,f),x.state=E;else if(n?.payloads.some(e=>e.message!==void 0)){let e=n.deliveryMetadata?.map(e=>e.deliveryId)??[];o.set(TurnDeliveryIdsKey,v.turnId?[...new Set([...o.get(TurnDeliveryIdsKey)??[],...e])]:e)}else!v.sessionStarted&&o.get(ChannelDeliveryKey)!==void 0&&o.set(TurnDeliveryIdsKey,[o.require(ChannelDeliveryKey).deliveryId]);if(i!==void 0&&(i.acceptedAtMsByCallId!==void 0&&o.set(RuntimeActionSettlementTimesKey,i.acceptedAtMsByCallId),D={...D,runtimeActionResults:i.results}),n!==void 0){let e={...s,state:{...x.state}};setChannelContext(o,e)}if(r!==void 0&&D===void 0&&y){await contextStorage.run(o,()=>_?.instrumentChannelDelivery({ctx:o,includeTurn:!1,outcome:`completed`})),await _?.flush();let t=saveSessionProjection(reconcileSessionContinuationToken(o,h),o),n=serializeContext(o),r=t===h?{history:e.history,sessionState:e.sessionState}:createDurableSessionValues(t);return{action:`park`,...derivePendingState(t,currentProjection(o)),serializedContext:n,...r}}let k=c.subagentRegistry.dynamicResolvers??[],A=c.resolvedAgent.dynamicToolResolvers??[],j=buildRuntimeIdentity(m);try{let e=process.env.VERCEL_DEPLOYMENT_ID?.trim(),t=e?`deployment:${e}`:await resolveRuntimeCompiledArtifactsVersionedCacheKey(c.compiledArtifactsSource),n=v.sessionStarted;if(o.setVirtualContext(StaticModelReferenceKey,l.turnAgent.model??null),!n)o.set(SessionDynamicSubagentRuntimeRevisionKey,t),o.set(SessionDynamicToolRuntimeRevisionKey,t);else{let e=sessionStartedForResolvers(j);await Promise.all([refreshDynamicSessionSubagentsForRuntimeRevision({ctx:o,resolvers:k,event:e,messages:g.initial.messages,runtimeRevision:t}),contextStorage.run(o,async()=>await refreshDynamicSessionToolsForRuntimeRevision({ctx:o,resolvers:A,event:e,messages:g.initial.messages,runtimeRevision:t}))]),y||await rebindMissingCompiledDynamicToolCallbacks({ctx:o,event:turnStartedForResolvers({sequence:v.sequence,turnId:activeTurnId(v)}),messages:g.initial.messages,resolvers:A})}}catch(e){throw await failChannelDeliveries(e),e}let M=c.resolvedAgent.config?.experimental?.workflow?.modelCallsPerStep??1,N=o.get(CapabilitiesKey),runHarnessStep=async(n,r,i)=>{let a=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:l.thresholdPercent},session:n,turnAgent:l.turnAgent});return createExecutionNodeStep({steeringSignal:e.steeringSignal,abortSignal:C,capabilities:N,clearOnly:e.input?.control===`clear`,compactOnly:e.input?.control===`compact`,createRuntime:createWorkflowRuntime,handleEvent,prepareApprovalTurn:e=>u.dispatch(turnStartedForResolvers(e)),signInCompletions:i,historyProjector:g.projector,historyView:g.prepare(a),instrumentation:_,modelResolutionScope:{moduleMap:c.moduleMap,nodeId:c.nodeId},node:m,titleAttributeWrite:t.title})(a,r)},P,F;try{throwIfTurnAborted(C),F=await runModelCallBatch({steeringSignal:e.steeringSignal,initialInput:D,initialSession:h,modelCallsPerStep:M,runStep:async({firstCall:e,session:t,stepInput:n})=>{let r=await runStep(o,t,async t=>{o.setVirtualContext(HandleEventKey,handleEvent),o.setVirtualContext(StaticModelReferenceKey,l.turnAgent.model??null);let r=e&&D?.outputSchema!==void 0?{...t,outputSchema:D.outputSchema}:t,i=turnPosition(currentProjection(o));try{await u.rehydrate(i,j,isBetweenTurns(currentProjection(o))?void 0:{sequence:i.sequence,turnId:activeTurnId(i)})}catch(e){let t=await recoverDynamicConnectionRehydration({emit:handleEvent,error:e,projection:currentProjection(o),session:r});if(t!==void 0)return t;throw e}let a=e&&d!==void 0?d.map(({challenge:e})=>e):void 0;return runHarnessStep(r,n,a)});r.settledTurn===void 0&&throwIfTurnAborted(C);let i={...r,session:saveSessionProjection(r.session,o)};return P={result:i,serializedContext:serializeContext(o)},i}})}catch(t){if(!isTurnCancellation(t)&&!C.aborted)throw await failChannelDeliveries(t),t;return createCancelledModelCallBatchResult({beforeBatchContext:e.serializedContext,checkpoint:P,ctx:o,initialSession:h,stepInput:D})}let I=saveSessionProjection(dropClosedRecords(reconcileSessionContinuationToken(o,F.session),currentProjection(o)),o);agentTraceState.pruneAgentTraceState(o,I.sessionId,I.state);let L=serializeContext(o);F={...F,session:I};let R=resolveSessionStepResult(F,L);return R.action===`done`&&await b.writer.close(),w?{...R,compacted:!0}:R}finally{b.writer.release()}}export{turnStep};
|
|
1
|
+
import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";import{defaultDeliverResult}from"#channel/adapter.js";import{contextStorage}from"#context/container.js";import{currentProjection,enterSessionProjection,saveSessionProjection}from"#harness/session-machine/current.js";import{AuthKey,CapabilitiesKey,ChannelDeliveryKey,HandleEventKey,InitiatorAuthKey,OccurrenceIdKey,ParentSessionKey,ScheduleIdKey,ScheduleInstanceKey,SessionDynamicSubagentRuntimeRevisionKey,SessionDynamicToolRuntimeRevisionKey,SessionTitleKey,StaticModelReferenceKey,TurnDeliveryIdsKey}from"#context/keys.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{coalesceTurnInputs,validateHarnessModelMessages}from"#harness/messages.js";import{activeTurnId,isBetweenTurns,storedProjection,turnPosition}from"#harness/session-machine/view.js";import{createWorkflowRuntime}from"#execution/workflow-runtime.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{createDurableSessionValues,readDurableSession}from"#execution/durable-session-store.js";import{runStep}from"#context/run-step.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{readHitlState}from"#harness/hitl/index.js";import*as agentTraceState from"#tracing/eve/agent-trace-context-store.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey}from"#harness/authorization.js";import{refreshDynamicSessionSubagentsForRuntimeRevision}from"#context/dynamic-subagent-lifecycle.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{openSessionEventPublisher}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{dropClosedRecords,saveTransition,sessionView}from"#harness/session-machine/commit.js";import{matchSignIns}from"#harness/session-machine/transitions.js";import{sessionStartedForResolvers,turnStartedForResolvers}from"#harness/session-machine/resolver-events.js";import{derivePendingState}from"#execution/session/pending-turn-state.js";import{rebindMissingCompiledDynamicToolCallbacks,refreshDynamicSessionToolsForRuntimeRevision}from"#context/dynamic-tool-lifecycle.js";import{setChannelContext}from"#execution/channel-context.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{createTurnEventHandler}from"#execution/session/turn-event-handler.js";import{isTurnCancellation,throwIfTurnAborted}from"#harness/turn-cancellation.js";import{bindSessionInstrumentation}from"#instrumentation/runtime.js";import{deriveSessionTitle}from"#execution/eve-workflow-attributes.js";import{bindTurnCallerContext}from"#subagents/parent-notification.js";import{bindDynamicConnections}from"#execution/dynamic-connections.js";import{recoverDynamicConnectionRehydration}from"#execution/dynamic-connection-recovery.js";import{setEveAttributes}from"#runtime/attributes/emit.js";import{RuntimeActionSettlementTimesKey}from"#harness/runtime-action-settlement-state.js";import{matchAuthorizationCallbacks}from"#execution/authorization-callback-match.js";import{attributeAnswers}from"#execution/session/answer-caller.js";import{resolveSessionStepResult}from"#execution/session/turn-step-result.js";import{countRunUsage}from"#execution/agent-sessions/usage.js";import{buildRuntimeIdentity,createExecutionNodeStep}from"#execution/node-step.js";import{createExecutionHistoryView}from"#execution/history-view.js";import{runModelCallBatch}from"#execution/model-call-batching.js";import{createCancelledModelCallBatchResult}from"#execution/cancelled-model-call-batch.js";function channelDeliveryErrorCode(e){if(typeof e==`object`&&e&&`code`in e){let t=e.code;if(typeof t==`string`&&t.length>0)return t}return`CHANNEL_DELIVERY_FAILED`}async function turnStep(e){"use step";return await withSessionStateDelta(e,e=>runSessionStep({...e,serializedContext:bindTurnCallerContext(e.caller,e.serializedContext)}))}async function runSessionStep(e){let t={};try{return await runSessionStepBody(e,t)}finally{await t.title}}async function runSessionStepBody(e,t){let n=e.input?.delivery,r=n,i=e.input?.runtimeResults,a=readDurableSession(e.sessionState);for(let e of i?.delegatedUsage??[])a=countRunUsage(a,e);let o=await deserializeContext(e.serializedContext);enterSessionProjection(o,a.state);let s=o.require(ChannelKey),c=o.require(BundleKey),l=resolveEffectiveAgentRuntime(c,o);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&o.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(t.url))}catch{}let{signIns:u}=readHitlState(a.state),d;if(u.length>0&&r!==void 0){let{matches:e,remainingPayloads:t}=matchAuthorizationCallbacks(u,r.payloads);if(r={...r,payloads:t},e.length>0){let n=e.map(e=>e.result.attemptId),i=e.map(e=>e.result);o.set(PendingAuthorizationResultKey,i);let s=sessionView(storedProjection(a.state),a.state),c=matchSignIns(s,{attemptIds:n});if(c.events.length!==0)throw Error(`matchSignIns must not emit events.`);a=saveTransition(a,c),d=e,t.length===0&&(r=void 0)}}r?.payloads.some(e=>e.message!==void 0)&&(o.delete(ScheduleIdKey),o.delete(ScheduleInstanceKey),o.delete(OccurrenceIdKey),r.schedule!==void 0&&(o.set(ScheduleIdKey,r.schedule.definition),r.schedule.instance!==void 0&&o.set(ScheduleInstanceKey,r.schedule.instance),r.schedule.occurrenceId!==void 0&&o.set(OccurrenceIdKey,r.schedule.occurrenceId)));let f=o.get(AuthKey),p=o.has(InitiatorAuthKey);r?.auth!==void 0&&(o.set(AuthKey,r.auth??null),o.has(InitiatorAuthKey)||o.set(InitiatorAuthKey,r.auth??null));let m=r===void 0?d?.find(({challenge:e})=>e.candidateId===void 0)?.challenge.requester:void 0;m!==void 0&&o.set(AuthKey,m);let h={...hydrateDurableSession({compactionOverrides:{thresholdPercent:l.thresholdPercent},durable:a,turnAgent:l.turnAgent}),history:validateHarnessModelMessages(e.history)},g=createExecutionHistoryView(h),_=bindSessionInstrumentation({agentName:l.turnAgent.id,ctx:o,rootSessionId:h.rootSessionId??h.sessionId,sessionId:h.sessionId}),v=turnPosition(currentProjection(o)),y=isBetweenTurns(currentProjection(o));if(!v.sessionStarted&&!o.has(SessionTitleKey)&&!o.has(ParentSessionKey)){let e=n?.payloads.find(e=>e.message!==void 0)?.message,r=deriveSessionTitle(n?.title??e);r!==void 0&&(o.set(SessionTitleKey,r),t.title=setEveAttributes({"$eve.title":r}))}n!==void 0&&(await contextStorage.run(o,()=>_?.preparePreamble({sequence:v.sequence,sessionStarted:v.sessionStarted})),await contextStorage.run(o,()=>_?.instrumentChannelDelivery({agentName:c.turnAgent.id,ctx:o,delivery:n,rootSessionId:h.rootSessionId??h.sessionId,sequence:v.sequence,sessionId:h.sessionId,turnId:activeTurnId(v)})));let failChannelDeliveries=async e=>{await contextStorage.run(o,()=>_?.instrumentChannelDelivery({ctx:o,error:e,errorCode:channelDeliveryErrorCode(e),includeTurn:!1,outcome:`failed`})),await _?.flush()},b=openSessionEventPublisher({ctx:o,origin:`own`,sessionWritable:e.sessionWritable}),{adapterCtx:x}=b.dispatcher,S=new AbortController,C=e.abortSignal===void 0?S.signal:AbortSignal.any([e.abortSignal,S.signal]);try{let u=bindDynamicConnections(o,c.resolvedAgent),m={...c.graph.root,turnAgent:l.turnAgent},w=!1,T=createTurnEventHandler({abortSignal:C,bundle:c,canCancelTurn:e.input?.control===void 0,hookCancellation:S,ctx:o,dynamicConnections:u,effectiveAgent:l,effectiveNode:m,instrumentation:_,publisher:b}),handleEvent=async(e,t)=>{e.type===`compaction.completed`&&(w=!0),await T(e,t)},E=r!==void 0&&!y?structuredClone(x.state):void 0,D;if(r!==void 0){let e=[];try{for(let t of r.payloads){let n=s.deliver?await s.deliver(t,x):defaultDeliverResult(t);n!=null&&e.push(n)}}catch(e){throw await failChannelDeliveries(e),e}D=e.length===0?void 0:e.reduce(coalesceTurnInputs)}let O=r?.auth===void 0?void 0:attributeAnswers({responder:r.auth,state:a.state,stepInput:D});if(O!==void 0&&(D=O,f===void 0?o.delete(AuthKey):o.set(AuthKey,f),p||o.delete(InitiatorAuthKey)),r!==void 0&&D===void 0&&!y)f===void 0?o.delete(AuthKey):o.set(AuthKey,f),x.state=E;else if(n?.payloads.some(e=>e.message!==void 0)){let e=n.deliveryMetadata?.map(e=>e.deliveryId)??[];o.set(TurnDeliveryIdsKey,v.turnId?[...new Set([...o.get(TurnDeliveryIdsKey)??[],...e])]:e)}else!v.sessionStarted&&o.get(ChannelDeliveryKey)!==void 0&&o.set(TurnDeliveryIdsKey,[o.require(ChannelDeliveryKey).deliveryId]);if(i!==void 0&&(i.acceptedAtMsByCallId!==void 0&&o.set(RuntimeActionSettlementTimesKey,i.acceptedAtMsByCallId),D={...D,runtimeActionResults:i.results}),n!==void 0){let e={...s,state:{...x.state}};setChannelContext(o,e)}if(r!==void 0&&D===void 0&&y){await contextStorage.run(o,()=>_?.instrumentChannelDelivery({ctx:o,includeTurn:!1,outcome:`completed`})),await _?.flush();let t=saveSessionProjection(reconcileSessionContinuationToken(o,h),o),n=serializeContext(o),r=t===h?{history:e.history,sessionState:e.sessionState}:createDurableSessionValues(t);return{action:`park`,...derivePendingState(t,currentProjection(o)),serializedContext:n,...r}}let k=c.subagentRegistry.dynamicResolvers??[],A=c.resolvedAgent.dynamicToolResolvers??[],j=buildRuntimeIdentity(m);try{let e=process.env.VERCEL_DEPLOYMENT_ID?.trim(),t=e?`deployment:${e}`:await resolveRuntimeCompiledArtifactsVersionedCacheKey(c.compiledArtifactsSource),n=v.sessionStarted;if(o.setVirtualContext(StaticModelReferenceKey,l.turnAgent.model??null),!n)o.set(SessionDynamicSubagentRuntimeRevisionKey,t),o.set(SessionDynamicToolRuntimeRevisionKey,t);else{let e=sessionStartedForResolvers(j);await Promise.all([refreshDynamicSessionSubagentsForRuntimeRevision({ctx:o,resolvers:k,event:e,messages:g.initial.messages,runtimeRevision:t}),contextStorage.run(o,async()=>await refreshDynamicSessionToolsForRuntimeRevision({ctx:o,resolvers:A,event:e,messages:g.initial.messages,runtimeRevision:t}))]),y||await rebindMissingCompiledDynamicToolCallbacks({ctx:o,event:turnStartedForResolvers({sequence:v.sequence,turnId:activeTurnId(v)}),messages:g.initial.messages,resolvers:A})}}catch(e){throw await failChannelDeliveries(e),e}let M=c.resolvedAgent.config?.experimental?.workflow?.modelCallsPerStep??1,N=o.get(CapabilitiesKey),runHarnessStep=async(n,r,i)=>{let a=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:l.thresholdPercent},session:n,turnAgent:l.turnAgent});return createExecutionNodeStep({steeringSignal:e.steeringSignal,abortSignal:C,capabilities:N,clearOnly:e.input?.control===`clear`,compactOnly:e.input?.control===`compact`,createRuntime:createWorkflowRuntime,handleEvent,prepareApprovalTurn:e=>u.dispatch(turnStartedForResolvers(e)),signInCompletions:i,historyProjector:g.projector,historyView:g.prepare(a),instrumentation:_,modelResolutionScope:{moduleMap:c.moduleMap,nodeId:c.nodeId},node:m,titleAttributeWrite:t.title})(a,r)},P,F;try{throwIfTurnAborted(C),F=await runModelCallBatch({steeringSignal:e.steeringSignal,initialInput:D,initialSession:h,modelCallsPerStep:M,runStep:async({firstCall:e,session:t,stepInput:n})=>{let r=await runStep(o,t,async t=>{o.setVirtualContext(HandleEventKey,handleEvent),o.setVirtualContext(StaticModelReferenceKey,l.turnAgent.model??null);let r=e&&D?.outputSchema!==void 0?{...t,outputSchema:D.outputSchema}:t,i=turnPosition(currentProjection(o));try{await u.rehydrate(i,j,isBetweenTurns(currentProjection(o))?void 0:{sequence:i.sequence,turnId:activeTurnId(i)})}catch(e){let t=await recoverDynamicConnectionRehydration({emit:handleEvent,error:e,projection:currentProjection(o),session:r});if(t!==void 0)return t;throw e}let a=e&&d!==void 0?d.map(({challenge:e})=>e):void 0;return runHarnessStep(r,n,a)});r.settledTurn===void 0&&throwIfTurnAborted(C);let i={...r,session:saveSessionProjection(r.session,o)};return P={result:i,serializedContext:serializeContext(o)},i}})}catch(t){if(!isTurnCancellation(t)&&!C.aborted)throw await failChannelDeliveries(t),t;return createCancelledModelCallBatchResult({beforeBatchContext:e.serializedContext,checkpoint:P,ctx:o,initialSession:h,stepInput:D})}let I=saveSessionProjection(dropClosedRecords(reconcileSessionContinuationToken(o,F.session),currentProjection(o)),o);agentTraceState.pruneAgentTraceState(o,I.sessionId,I.state);let L=serializeContext(o);F={...F,session:I};let R=resolveSessionStepResult(F,L);return R.action===`done`&&await b.writer.close(),w?{...R,compacted:!0}:R}finally{b.writer.release()}}export{turnStep};
|
|
@@ -40,6 +40,7 @@ export declare class SessionExecution {
|
|
|
40
40
|
* stream is closed, and finalizing the session terminates the children.
|
|
41
41
|
*/
|
|
42
42
|
private handleBoundaryMessages;
|
|
43
|
+
/** Hooks on the messages' events may cancel `turn`, the turn that is running. */
|
|
43
44
|
private applyRunMessages;
|
|
44
45
|
private runTurnSteps;
|
|
45
46
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{TASK_WAIT_TOOL_NAME}from"#protocol/task-tools.js";import{renderTaskWaitResult}from"#execution/tasks/render.js";import{taskWaitResult}from"#execution/tasks/table.js";import{sleep}from"#compiled/@workflow/core/index.js";import{findBlockingWorkflowToolRun,getBlockingWorkflowToolRuns,isInboxToolResultFromRecordedWorkflowToolRun}from"#harness/workflow-tool-runs.js";import{handleWorkflowToolRunMessage,isAppliedRunMessage,takeLeadingAppliedRunMessages}from"#execution/session-workflow-tool-run.js";import{resolveTurnPrincipal}from"#execution/session/principal.js";import{answerTaskCancel,cancelWorkingTasks,sessionTaskTable}from"#execution/tasks/session.js";import{cancelDescendantTurnsStep}from"#execution/cancel-descendant-turns-step.js";import{dispatchCoordinationStep}from"#execution/coordination-dispatch-step.js";import{taskToolResult}from"#execution/tasks/calls.js";import{publishTurnWaitingStep}from"#execution/session/turn-waiting-step.js";import{applyRunMessagesStep}from"#execution/tools/workflow/apply-run-messages-step.js";import{interruptWorkflowToolRun}from"#execution/tools/workflow/interrupt.js";import{turnStep}from"#execution/session/turn-step.js";import{ActiveTurn}from"#execution/session/active-turn.js";import{resolveRuntimeActionResultsForCallIds}from"#runtime/actions/results.js";import{startTaskToolCallsStep,traceTaskToolCallStep}from"#execution/session/task-tool-tracing-step.js";function hasDelegatedCallerContext(e){if(e[`eve.sessionCallback`]!==void 0)return!0;let t=e[`eve.channel`];return typeof t==`object`&&!!t&&Reflect.get(t,`kind`)===`subagent`}var SessionExecution=class{input;constructor(e){this.input=e}get cursor(){return this.input.cursor}async runTurn(e,t={}){let n;try{n=new ActiveTurn(this.input,{caller:t.caller,principal:resolveTurnPrincipal(e,this.input.cursor.serializedContext)},t.control)}catch(e){throw t.control?.dispose(),e}try{let t=await this.runTurnSteps(n,e);return await this.handleBoundaryMessages(n.takeBoundaryMessages(),t.kind===`done`),t.kind===`park`&&t.settled!==void 0&&await cancelWorkingTasks(this.input.cursor,`turn_ended`),{...t,...n.caller!==void 0&&{caller:n.caller},...n.compacted&&{compacted:!0}}}finally{n.dispose()}}async handleBoundaryMessages(e,t=!1){let
|
|
1
|
+
import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{TASK_WAIT_TOOL_NAME}from"#protocol/task-tools.js";import{renderTaskWaitResult}from"#execution/tasks/render.js";import{taskWaitResult}from"#execution/tasks/table.js";import{sleep}from"#compiled/@workflow/core/index.js";import{findBlockingWorkflowToolRun,getBlockingWorkflowToolRuns,isInboxToolResultFromRecordedWorkflowToolRun}from"#harness/workflow-tool-runs.js";import{handleWorkflowToolRunMessage,isAppliedRunMessage,takeLeadingAppliedRunMessages}from"#execution/session-workflow-tool-run.js";import{resolveTurnPrincipal}from"#execution/session/principal.js";import{answerTaskCancel,cancelWorkingTasks,sessionTaskTable}from"#execution/tasks/session.js";import{cancelDescendantTurnsStep}from"#execution/cancel-descendant-turns-step.js";import{dispatchCoordinationStep}from"#execution/coordination-dispatch-step.js";import{taskToolResult}from"#execution/tasks/calls.js";import{publishTurnWaitingStep}from"#execution/session/turn-waiting-step.js";import{applyRunMessagesStep}from"#execution/tools/workflow/apply-run-messages-step.js";import{interruptWorkflowToolRun}from"#execution/tools/workflow/interrupt.js";import{turnStep}from"#execution/session/turn-step.js";import{ActiveTurn}from"#execution/session/active-turn.js";import{resolveRuntimeActionResultsForCallIds}from"#runtime/actions/results.js";import{startTaskToolCallsStep,traceTaskToolCallStep}from"#execution/session/task-tool-tracing-step.js";function hasDelegatedCallerContext(e){if(e[`eve.sessionCallback`]!==void 0)return!0;let t=e[`eve.channel`];return typeof t==`object`&&!!t&&Reflect.get(t,`kind`)===`subagent`}var SessionExecution=class{input;constructor(e){this.input=e}get cursor(){return this.input.cursor}async runTurn(e,t={}){let n;try{n=new ActiveTurn(this.input,{caller:t.caller,principal:resolveTurnPrincipal(e,this.input.cursor.serializedContext)},t.control)}catch(e){throw t.control?.dispose(),e}try{let t=await this.runTurnSteps(n,e);return await this.handleBoundaryMessages(n.takeBoundaryMessages(),t.kind===`done`),t.kind===`park`&&t.settled!==void 0&&await cancelWorkingTasks(this.input.cursor,`turn_ended`),{...t,...n.caller!==void 0&&{caller:n.caller},...n.compacted&&{compacted:!0}}}finally{n.dispose()}}async handleBoundaryMessages(e,t=!1,n){let r=[];for(let i of e)isAppliedRunMessage(i)?(!t||i.kind!==`agent-started`)&&r.push(i):(await this.applyRunMessages(r,n),r=[],await handleWorkflowToolRunMessage({cursor:this.input.cursor,message:i}));await this.applyRunMessages(r,n)}async applyRunMessages(e,t){if(e.length===0)return;let{cancelled:n}=await this.input.cursor.advance(n=>applyRunMessagesStep({...n,canCancelTurn:t!==void 0,messages:e}));n&&t?.abort()}async runTurnSteps(e,t){let n=t,r=e.caller;for(;;){let{cursor:t}=this.input,i=r;r=void 0;let a=await t.advanceWithHistory(t=>turnStep({...t,abortSignal:e.signal,caller:i,input:n,steeringSignal:e.steeringSignal}));a.compacted===!0&&(e.compacted=!0);let o=a.action===`park`?a.pendingCoordinationCallIds:void 0,s=a.action===`park`&&a.settled!==void 0,c=this.input.queue.nextAdmission;await e.admitBoundary();let l=a.action===`done`;if(await this.handleBoundaryMessages(e.takeBoundaryMessages(),l,l?void 0:e),a.action===`cancelled`||!s&&e.signal.aborted&&o===void 0)return await this.finishCancelledTurn(e);if(a.action===`done`)return{isError:a.isError,kind:`done`,output:a.output??``,usage:a.usage,usageDelta:a.usageDelta};if(a.action===`held`&&a.hold===`request`){if(a.hasPendingInputBatch&&this.input.capabilities?.requestInput!==!0&&!hasDelegatedCallerContext(this.input.cursor.serializedContext))throw Error(`This session cannot request human input, so it cannot wait for a tool approval or question. Configure unattended tools with an approval policy that does not require human input.`);let t=await this.waitForHeldRequest(e,a,c);if(t===`cancelled`)return await this.finishCancelledTurn(e);n={delivery:t};continue}if(a.action===`held`){if(await this.waitForHeldTurn(e)===`cancelled`)return await this.finishCancelledTurn(e);let t=await e.takeSteering();n=t===void 0?void 0:{delivery:t};continue}if(o!==void 0&&a.action===`park`){let t=a.hasRunsToDispatch===!1?[]:await this.dispatchRuns(),r=t.length===0?void 0:Date.now(),i=await this.waitForRuntimeActionResults({initialAcceptedAtMs:r,initialResults:t,taskToolCalls:a.pendingTaskToolCalls??[],pendingCallIds:o,turn:e});if(i===`cancelled`)return await this.finishCancelledTurn(e);n={delivery:await e.takeSteering(),runtimeResults:i};continue}if(a.action===`park`)return{kind:`park`,settled:a.settled};let u=await e.takeSteering();n=u===void 0?void 0:{delivery:u}}}async dispatchRuns(){return(await this.input.cursor.advance(e=>dispatchCoordinationStep({action:`park`,workflowToolRunOwner:{inbox:sessionInboxHookToken(sessionCommandHookToken(this.input.sessionId))},...e}))).results}async handleWorkflowMessage(e,t){if(isAppliedRunMessage(e)){let n=t?.takeAppliedRunMessages()??takeLeadingAppliedRunMessages(this.input.inbox);await this.applyRunMessages([e,...n],t);return}return await handleWorkflowToolRunMessage({cursor:this.input.cursor,message:e})}async cancelTurnWork(){let{cursor:e}=this.input;mayWaitOnWorkflowToolRuns(e.sessionState)&&await cancelDescendantTurnsStep({serializedContext:e.serializedContext,sessionState:e.sessionState}),await cancelWorkingTasks(e,`turn_cancelled`)}async finishCancelledTurn(e){return await this.handleBoundaryMessages(e.takeBoundaryMessages(`agent-started`)),await this.cancelTurnWork(),{cancelled:!0,kind:`park`}}async waitForHeldTurn(e){let t=!1;for(;;){let n={interrupted:t,timedOut:!1};if(taskWaitResult(sessionTaskTable(this.input.cursor),n)!==void 0)return`woke`;let r=await e.nextRuntimeEvent([]);if(r===`cancelled`)return r;switch(r.kind){case`steering`:t=!0;continue;case`workflow`:await this.handleWorkflowMessage(r.message,e);continue;case`input`:case`runtime-action-result`:case`timeout`:continue}}}async waitForHeldRequest(e,t,n){let r=new Set(t.authorizationAttemptIds),i=new Set(t.inputRequestIds);for(;;){let t=this.input.queue.takeAuthorizations(r);if(t!==void 0)return{kind:`deliver`,payloads:t};let a=await e.takeInputResponses(i);if(a!==void 0)return a;let o=await e.takeSteering({heldSince:n});if(o!==void 0)return o;let s=await e.nextRuntimeEvent([]);if(s===`cancelled`)return s;s.kind===`workflow`&&await this.handleWorkflowMessage(s.message,e)}}async waitForRuntimeActionResults(e){let t=[...e.initialResults],n=!1,r=new Map,i=new Map;if(e.initialAcceptedAtMs!==void 0)for(let n of t)r.set(n.callId,e.initialAcceptedAtMs);let accept=e=>{t.push(e),r.set(e.callId,Date.now())},a=await this.answerTaskToolCalls(e.taskToolCalls,accept);try{for(;;){a=await this.resolveTaskWaits(a,n,accept);let o=resolveRuntimeActionResultsForCallIds({pendingCallIds:e.pendingCallIds,results:t});if(o!==void 0){let e=o.flatMap(e=>{let t=i.get(e.callId);return t===void 0?[]:[t]});return{acceptedAtMsByCallId:Object.fromEntries(o.map(e=>[e.callId,r.get(e.callId)])),...e.length>0&&{delegatedUsage:e},results:o}}let s=a.flatMap(e=>e.timer===void 0?[]:[e.timer]),c=await e.turn.nextRuntimeEvent(s);if(c===`cancelled`)return c;if(c.kind===`timeout`){for(let e of a)e.callId===c.callId&&(e.timedOut=!0);continue}if(c.kind===`input`)continue;if(c.kind===`steering`){n||await this.interruptWaitedWorkflowCalls(e.pendingCallIds,t),n=!0;continue}if(c.kind===`runtime-action-result`){let e=this.input.cursor.sessionState.snapshot.session.state,n=c.results.filter(t=>t.kind===`tool-result`&&isInboxToolResultFromRecordedWorkflowToolRun(e,t));if(n.length>0){let e=Date.now();t.push(...n);for(let t of n)r.set(t.callId,e)}continue}let l=await this.handleWorkflowMessage(c.message,e.turn);l!==void 0&&(accept(l),c.message.kind===`outcome`&&c.message.usage!==void 0&&i.set(l.callId,c.message.usage))}}finally{for(let e of a)await this.traceTaskWait(e,void 0,!0)}}async resolveTaskWaits(e,t,n){let r=sessionTaskTable(this.input.cursor),i=[];for(let a of e){let e=taskWaitResult(r,{interrupted:t,timedOut:a.timedOut});if(e===void 0){i.push(a);continue}let o=renderTaskWaitResult(e,Date.now()-a.startedAtMs);await this.traceTaskWait(a,o,t),n(taskToolResult(a.callId,TASK_WAIT_TOOL_NAME,o))}return i}async answerTaskToolCalls(e,t){let n=[],r=e.length===0?0:await startTaskToolCallsStep();for(let i of e)if(i.kind===TASK_WAIT_TOOL_NAME)n.push(startTaskWait(i,r));else{let e;try{e=await answerTaskCancel(this.input.cursor,i)}catch(e){throw await this.input.cursor.advance(e=>traceTaskToolCallStep(e,{callId:i.callId,toolName:i.kind,startedAtMs:r,completedAtMs:Date.now(),input:{taskId:i.taskId},failed:!0})),e}await this.input.cursor.advance(t=>traceTaskToolCallStep(t,{callId:i.callId,toolName:i.kind,startedAtMs:r,completedAtMs:Date.now(),input:{taskId:i.taskId},output:e.output})),t(e)}let i=await this.resolveTaskWaits(n,!1,t);return i.length>0&&await this.input.cursor.advance(publishTurnWaitingStep),i}async traceTaskWait(e,t,n=!1){await this.input.cursor.advance(r=>traceTaskToolCallStep(r,{callId:e.callId,toolName:TASK_WAIT_TOOL_NAME,startedAtMs:e.startedAtMs,completedAtMs:Date.now(),input:e.input,output:t,failed:n}))}async interruptWaitedWorkflowCalls(e,t){let n=this.input.cursor.sessionState.snapshot.session.state,r=new Set(t.map(e=>e.callId)),i=e.filter(e=>!r.has(e)).flatMap(e=>{let t=findBlockingWorkflowToolRun(n,e);return t===void 0?[]:[t.address]});await Promise.all(i.map(e=>interruptWorkflowToolRun(e)))}};function startTaskWait(e,t){let{callId:n,timeoutMs:r}=e,i=r===void 0?void 0:sleep(r).then(()=>n);return{callId:n,startedAtMs:t,input:r===void 0?{}:{timeoutSeconds:r/1e3},timedOut:r===0,timer:i}}function mayWaitOnWorkflowToolRuns(e){try{return getBlockingWorkflowToolRuns(e.snapshot?.session?.state).length>0}catch{return!0}}export{SessionExecution,hasDelegatedCallerContext};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{displayTitle}from"#shared/display-name.js";import{firstSentence}from"#shared/presentation-text.js";import{isToolSchema,withOptionalStringProperty}from"#tools/schema.js";import{AGENT_SERVE_TOOL_DESCRIPTION,SERVE_TOOL_DESCRIPTION,TASK_ID_INPUT_DESCRIPTION}from"#execution/tasks/render.js";import{AGENT_TOOL_NAME}from"#tools/framework/agent-contract.js";import{isAgentTool}from"#execution/tasks/tool-entry-point.js";const TASK_ID_INPUT=`taskId`;function withTaskIdSchema(e){return withOptionalStringProperty(e,{description:TASK_ID_INPUT_DESCRIPTION,name:TASK_ID_INPUT})}function withTaskIdInput(e){let t=e.inputSchema;if(!isToolSchema(t))throw Error(`Tool "${e.name}" has no input schema eve can add taskId to.`);let n=isAgentTool(e),r={...e,description:appendSentence(e.description,n?AGENT_SERVE_TOOL_DESCRIPTION:SERVE_TOOL_DESCRIPTION),inputSchema:withTaskIdSchema(t)};return!n||e.label?.start!==void 0?r:{...r,label:{...e.label,start:t=>agentCallLabel(e.name,t)}}}function agentCallLabel(e,t){let n=typeof t==`object`&&t?t.message:void 0,r=typeof n==`string`?firstSentence(n):void 0;return r===void 0?displayTitle(e):e===AGENT_TOOL_NAME?r:`${displayTitle(e)}: ${r}`}function splitTaskIdInput(e){let{[TASK_ID_INPUT]:t,...n}=e;return typeof t
|
|
1
|
+
import{displayTitle}from"#shared/display-name.js";import{firstSentence}from"#shared/presentation-text.js";import{isToolSchema,withOptionalStringProperty}from"#tools/schema.js";import{AGENT_SERVE_TOOL_DESCRIPTION,SERVE_TOOL_DESCRIPTION,TASK_ID_INPUT_DESCRIPTION}from"#execution/tasks/render.js";import{AGENT_TOOL_NAME}from"#tools/framework/agent-contract.js";import{isAgentTool}from"#execution/tasks/tool-entry-point.js";const TASK_ID_INPUT=`taskId`;function withTaskIdSchema(e){return withOptionalStringProperty(e,{description:TASK_ID_INPUT_DESCRIPTION,name:TASK_ID_INPUT})}function withTaskIdInput(e){let t=e.inputSchema;if(!isToolSchema(t))throw Error(`Tool "${e.name}" has no input schema eve can add taskId to.`);let n=isAgentTool(e),r={...e,description:appendSentence(e.description,n?AGENT_SERVE_TOOL_DESCRIPTION:SERVE_TOOL_DESCRIPTION),inputSchema:withTaskIdSchema(t)};return!n||e.label?.start!==void 0?r:{...r,label:{...e.label,start:t=>agentCallLabel(e.name,t)}}}function agentCallLabel(e,t){let n=typeof t==`object`&&t?t.message:void 0,r=typeof n==`string`?firstSentence(n):void 0;return r===void 0?displayTitle(e):e===AGENT_TOOL_NAME?r:`${displayTitle(e)}: ${r}`}function splitTaskIdInput(e){let{[TASK_ID_INPUT]:t,...n}=e;return typeof t!=`string`||t===``?{input:n}:{input:n,taskId:t}}function appendSentence(e,t){let n=e.trimEnd();return n===``?t:`${n} ${t}`}export{TASK_ID_INPUT,splitTaskIdInput,withTaskIdInput,withTaskIdSchema};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{decide}from"#ai/decide.js";async function runAgentRouterTask(e,t){"use workflow";let n=await chooseTarget(e.message,descriptions(t),t.abortSignal),{message:r,status:i}=await(await t.agent(n).send(e.message,{signal:t.abortSignal})).result();if(i===`failed`)throw Error(`Agent "${n}" failed to handle the task.`);return r??null}async function chooseTarget(e,t,n){"use step";let r=Object.keys(t);if(r.length===0)throw Error(`agentRouter requires at least one available agent with a description.`);return r.length===1?r[0]:(await decide({abortSignal:n,state:{message:e},questions:{route:{type:`choice`,instructions:`Which subagent should handle this task?`,criteria:t}}})).answers.route.choice}function descriptions(e){return Object.fromEntries(Object.entries(e.agents).flatMap(([e,t])=>{let n=t.description.trim();return n.length===0?[]:[[e,n]]}))}runAgentRouterTask.workflowId=`workflow//eve@0.79.
|
|
1
|
+
import{decide}from"#ai/decide.js";async function runAgentRouterTask(e,t){"use workflow";let n=await chooseTarget(e.message,descriptions(t),t.abortSignal),{message:r,status:i}=await(await t.agent(n).send(e.message,{signal:t.abortSignal})).result();if(i===`failed`)throw Error(`Agent "${n}" failed to handle the task.`);return r??null}async function chooseTarget(e,t,n){"use step";let r=Object.keys(t);if(r.length===0)throw Error(`agentRouter requires at least one available agent with a description.`);return r.length===1?r[0]:(await decide({abortSignal:n,state:{message:e},questions:{route:{type:`choice`,instructions:`Which subagent should handle this task?`,criteria:t}}})).answers.route.choice}function descriptions(e){return Object.fromEntries(Object.entries(e.agents).flatMap(([e,t])=>{let n=t.description.trim();return n.length===0?[]:[[e,n]]}))}runAgentRouterTask.workflowId=`workflow//eve@0.79.2//runAgentRouterTask`;export{runAgentRouterTask};
|
|
@@ -13,8 +13,12 @@ export type AppliedRunMessage = Extract<WorkflowToolRunMessage, {
|
|
|
13
13
|
/**
|
|
14
14
|
* Applies run messages in the order they arrived, in one step however many
|
|
15
15
|
* there are: a fan-out's starts, reports, and replies would otherwise cost a
|
|
16
|
-
* step each.
|
|
16
|
+
* step each. Set `canCancelTurn` while a turn runs: a hook's `ctx.cancel()`
|
|
17
|
+
* on a report then returns `cancelled` for the turn to stop.
|
|
17
18
|
*/
|
|
18
19
|
export declare function applyRunMessagesStep(input: SessionStepState & {
|
|
20
|
+
readonly canCancelTurn?: boolean;
|
|
19
21
|
readonly messages: readonly AppliedRunMessage[];
|
|
20
|
-
}): Promise<SessionStateTransition
|
|
22
|
+
}): Promise<SessionStateTransition & {
|
|
23
|
+
readonly cancelled: boolean;
|
|
24
|
+
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createActionPartialEvent,createAgentStartedEvent}from"#protocol/message.js";import{publishSessionEvents}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{applyTaskRunMessage}from"#execution/tasks/steps.js";import{createRuntimeToolResultFromValue}from"#harness/action-result-helpers.js";function workflowToolRunReportEvent(e,t){return createActionPartialEvent({result:createRuntimeToolResultFromValue({callId:e.callId,output:t,toolName:e.toolName}),sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId})}function agentStartedEvent(e,{from:t,session:n}){return createAgentStartedEvent({callId:t.callId,name:n.name,parentSessionId:e,remote:n.kind===`remote`?{url:n.url,...n.resolverId!==void 0&&{resolverId:n.resolverId}}:void 0,sessionId:n.sessionId,...t.taskId!==void 0&&{taskId:t.taskId},turnId:t.turnId})}async function applyRunMessagesStep(e){"use step";return await withSessionStateDelta(e,async({messages:
|
|
1
|
+
import{createActionPartialEvent,createAgentStartedEvent}from"#protocol/message.js";import{publishSessionEvents}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{applyTaskRunMessage}from"#execution/tasks/steps.js";import{createRuntimeToolResultFromValue}from"#harness/action-result-helpers.js";function workflowToolRunReportEvent(e,t){return createActionPartialEvent({result:createRuntimeToolResultFromValue({callId:e.callId,output:t,toolName:e.toolName}),sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId})}function agentStartedEvent(e,{from:t,session:n}){return createAgentStartedEvent({callId:t.callId,name:n.name,parentSessionId:e,remote:n.kind===`remote`?{url:n.url,...n.resolverId!==void 0&&{resolverId:n.resolverId}}:void 0,sessionId:n.sessionId,...t.taskId!==void 0&&{taskId:t.taskId},turnId:t.turnId})}async function applyRunMessagesStep(e){"use step";return await withSessionStateDelta(e,async({canCancelTurn:e,messages:t,...n})=>{let r=n,i=!1,a=[],publish=async()=>{if(a.length===0)return;let t=await publishSessionEvents(r,a,{canCancelTurn:e});r={...r,serializedContext:t.serializedContext,sessionState:t.sessionState},i||=t.cancelled,a=[]};for(let e of t)e.kind===`agent-started`?a.push(agentStartedEvent(r.sessionState.sessionId,e)):e.kind===`report`?a.push(workflowToolRunReportEvent(e.from,e.update)):(await publish(),r={...r,...await applyTaskRunMessage({...r,message:e})});return await publish(),{cancelled:i,serializedContext:r.serializedContext,sessionState:r.sessionState}})}export{applyRunMessagesStep};
|
|
@@ -6,7 +6,7 @@ import { WorkflowToolRunAsks } from "#execution/tools/workflow/ask.js";
|
|
|
6
6
|
import type { WorkflowBodyCommand, WorkflowToolRunOutcome, WorkflowToolRunRef } from "#execution/tools/workflow/messages.js";
|
|
7
7
|
import type { WorkflowToolRunInbox } from "#execution/tools/workflow/owner.js";
|
|
8
8
|
import type { WorkflowToolRunEntry } from "#shared/action-types.js";
|
|
9
|
-
import type
|
|
9
|
+
import { type JsonObject, type JsonValue } from "#shared/json.js";
|
|
10
10
|
import type { ToolContext } from "#tools/definition.js";
|
|
11
11
|
export interface WorkflowBodyDefinition {
|
|
12
12
|
/** Everything the run needs to open `ctx.agent` sessions for its caller, and `ctx.agents`. */
|
|
@@ -52,6 +52,15 @@ export interface StartedWorkflowBody {
|
|
|
52
52
|
}
|
|
53
53
|
/** Starts the body of an `execute` or `task` call, which serves the call the run started with. */
|
|
54
54
|
export declare function startCallBody(input: WorkflowBodyInput): StartedWorkflowBody;
|
|
55
|
+
/**
|
|
56
|
+
* An authored result as the run's JSON outcome, parsed the way a local tool's
|
|
57
|
+
* result is: undefined properties are omitted, a missing result is `null`,
|
|
58
|
+
* and a value JSON can't carry throws, failing the run.
|
|
59
|
+
*/
|
|
60
|
+
export declare function toWorkflowOutput(call: {
|
|
61
|
+
readonly callId: string;
|
|
62
|
+
readonly toolName: string;
|
|
63
|
+
}, output: unknown): JsonValue;
|
|
55
64
|
/** A body's failure, or its cancellation when the run stopped. */
|
|
56
65
|
export declare function toFailedOutcome(error: unknown, runSignal: AbortSignal): WorkflowToolRunOutcome;
|
|
57
66
|
export declare function createWorkflowBodyRef(input: WorkflowBodyDefinition & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{callToolStubStep}from"#execution/tool-stubs/steps.js";import{getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{findStubTarget,stubCallId}from"#tool-stubs/target.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{createRunUsageTally}from"#execution/agent-sessions/usage.js";import{toolStubOutput}from"#tool-stubs/output.js";import{createAgentSessions}from"#execution/agent-sessions/session.js";import{WorkflowToolRunAsks,ask,attachWorkflowToolRunContext}from"#execution/tools/workflow/ask.js";import{readRegisteredWorkflow}from"#execution/workflow-registry.js";const INTERRUPTED_OUTPUT={interrupted:!0};var WorkflowCallSignals=class{body=new AbortController;run=new AbortController;asks;constructor(e){this.asks=e}get abortSignal(){return this.body.signal}get runSignal(){return this.run.signal}get interrupted(){return this.body.signal.aborted&&!this.run.signal.aborted}get unwinding(){return this.run.signal.aborted}apply(e){switch(e.kind){case`cancel`:case`end`:this.asks.cancelAll(),this.run.abort(new WorkflowToolRunCancelledError(e.reason)),this.body.abort(this.run.signal.reason);return;case`interrupt`:this.body.abort(new WorkflowToolRunInterruptedError);return;case`call`:return}}};function startCallBody(e){let t=createWorkflowBodyRef(e),n=new WorkflowToolRunAsks(t.runId),r=new WorkflowCallSignals(n),i={agentContext:e.agentContext,asks:n,auth:e.session.auth,control:e.hookToken,from:t,owner:e.owner},a=createRunUsageTally(),o=createAgentSessions(i,a),s=createCallContext(e,r,o.open);return attachWorkflowToolRunContext(s,i),{asks:n,close:o.close,control:r,outcome:executeCallBody(e,s,r,t),usage:a}}async function executeCallBody(e,t,n,r){try{let n=findStubTarget(e.agentContext.toolStubs,e.toolName);if(n!==void 0){let t=await callToolStubStep(n.scope,{callId:stubCallId(e.session.id,e.session.turn.id,e.callId),tool:n.tool,input:e.input});if(t.kind===`error`)throw Error(t.error);if(t.kind===`stub`)return{output:toolStubOutput(t.outcome),status:`completed`}}let i=resolveWorkflowEntryPoint(e)(e.executeInput??e.input,t),a;if(!isAsyncIterable(i))a=await i;else{let t=i[Symbol.asyncIterator](),n,o=await t.next();for(;o.done!==!0;)n=o.value,await e.owner.send({from:r,kind:`report`,update:o.value}),o=await t.next();a=o.value??n
|
|
1
|
+
import{parseJsonValue}from"#shared/json.js";import{callToolStubStep}from"#execution/tool-stubs/steps.js";import{getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{findStubTarget,stubCallId}from"#tool-stubs/target.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{createRunUsageTally}from"#execution/agent-sessions/usage.js";import{toolStubOutput}from"#tool-stubs/output.js";import{createAgentSessions}from"#execution/agent-sessions/session.js";import{WorkflowToolRunAsks,ask,attachWorkflowToolRunContext}from"#execution/tools/workflow/ask.js";import{readRegisteredWorkflow}from"#execution/workflow-registry.js";import{withToolOutputSerializationError}from"#harness/tool-output-serialization.js";const INTERRUPTED_OUTPUT={interrupted:!0};var WorkflowCallSignals=class{body=new AbortController;run=new AbortController;asks;constructor(e){this.asks=e}get abortSignal(){return this.body.signal}get runSignal(){return this.run.signal}get interrupted(){return this.body.signal.aborted&&!this.run.signal.aborted}get unwinding(){return this.run.signal.aborted}apply(e){switch(e.kind){case`cancel`:case`end`:this.asks.cancelAll(),this.run.abort(new WorkflowToolRunCancelledError(e.reason)),this.body.abort(this.run.signal.reason);return;case`interrupt`:this.body.abort(new WorkflowToolRunInterruptedError);return;case`call`:return}}};function startCallBody(e){let t=createWorkflowBodyRef(e),n=new WorkflowToolRunAsks(t.runId),r=new WorkflowCallSignals(n),i={agentContext:e.agentContext,asks:n,auth:e.session.auth,control:e.hookToken,from:t,owner:e.owner},a=createRunUsageTally(),o=createAgentSessions(i,a),s=createCallContext(e,r,o.open);return attachWorkflowToolRunContext(s,i),{asks:n,close:o.close,control:r,outcome:executeCallBody(e,s,r,t),usage:a}}async function executeCallBody(e,t,n,r){try{let n=findStubTarget(e.agentContext.toolStubs,e.toolName);if(n!==void 0){let t=await callToolStubStep(n.scope,{callId:stubCallId(e.session.id,e.session.turn.id,e.callId),tool:n.tool,input:e.input});if(t.kind===`error`)throw Error(t.error);if(t.kind===`stub`)return{output:toolStubOutput(t.outcome),status:`completed`}}let i=resolveWorkflowEntryPoint(e)(e.executeInput??e.input,t),a;if(!isAsyncIterable(i))a=await i;else{let t=i[Symbol.asyncIterator](),n,o=await t.next();for(;o.done!==!0;)n=o.value,await e.owner.send({from:r,kind:`report`,update:o.value}),o=await t.next();a=o.value??n}return{output:toWorkflowOutput(e,a),status:`completed`}}catch(e){return n.interrupted?{output:INTERRUPTED_OUTPUT,status:`completed`}:toFailedOutcome(e,n.runSignal)}}function toWorkflowOutput(e,t){return withToolOutputSerializationError({boundary:`execute`,toolCallId:e.callId,toolName:e.toolName},()=>parseJsonValue(t??null))}function toFailedOutcome(e,t){if(t.aborted){let{reason:e}=t;return{reason:e instanceof Error?e.message:String(e??``),status:`cancelled`}}return{error:normalizeSerializableError(e),status:`failed`}}function createWorkflowBodyRef(e){let t={callId:e.callId,input:e.input,runId:e.runId??getWorkflowMetadata().workflowRunId,sequence:e.session.turn.sequence,stepIndex:e.stepIndex,toolName:e.toolName,turnId:e.session.turn.id};return e.entry.entryPoint===`execute`?t:{...t,taskId:e.entry.taskId}}function resolveWorkflowEntryPoint(e){let t=readRegisteredWorkflow(e.workflowId);if(typeof t!=`function`)throw Error(`Tool "${e.toolName}" is not registered as a workflow in this deployment (${e.workflowId}). The tool was renamed or removed after this run started.`);return t}function createSharedContext(e,t,n){let unavailable=(t,n)=>{throw Error(`ctx.${t} is not available inside a workflow tool; ${n}. Tool "${e.toolName}" runs as a durable workflow body, which only replays deterministic code.`)};return{agent:t,ask:n,getSandbox:()=>unavailable(`getSandbox()`,`the session sandbox belongs to the turn`),getToken:()=>unavailable(`getToken()`,`pass ctx directly to a "use step" helper to resolve credentials`),requireAuth:()=>unavailable(`requireAuth()`,`pass ctx directly to a "use step" helper to request authorization`),toolName:e.toolName}}function createAgentsView(e){return Object.freeze(Object.fromEntries(Object.entries(e.agents).map(([e,t])=>[e,Object.freeze({...t})])))}function createCallContext(e,t,n){let r={...createSharedContext(e,n,(e,t)=>ask(r,e,t)),abortSignal:t.abortSignal,agents:createAgentsView(e.agentContext),callId:e.callId,session:e.session};return r}function isAsyncIterable(e){return typeof e==`object`&&!!e&&typeof e[Symbol.asyncIterator]==`function`}var WorkflowToolRunCancelledError=class extends Error{constructor(e){super(e),this.name=`WorkflowToolRunCancelledError`}},WorkflowToolRunInterruptedError=class extends Error{constructor(){super(`A new message arrived while the turn waited on this call.`),this.name=`WorkflowToolRunInterruptedError`}};export{WorkflowToolRunCancelledError,WorkflowToolRunInterruptedError,createAgentsView,createSharedContext,createWorkflowBodyRef,resolveWorkflowEntryPoint,startCallBody,toFailedOutcome,toWorkflowOutput};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{parseJsonValue}from"#shared/json.js";function workflowToolRunOutcomeToToolResult(e){let{from:t,result:n}=e;return n.status===`completed`?{callId:t.callId,kind:`tool-result`,output:n.output,toolName:t.toolName}:{callId:t.callId,isError:!0,kind:`tool-result`,output:
|
|
1
|
+
import{parseJsonValue}from"#shared/json.js";import{rebuildSerializableError}from"#execution/workflow-errors.js";function workflowToolRunOutcomeToToolResult(e){let{from:t,result:n}=e;return n.status===`completed`?{callId:t.callId,kind:`tool-result`,output:n.output,toolName:t.toolName}:n.status===`failed`?{callId:t.callId,errorName:rebuildSerializableError(n.error).name,isError:!0,kind:`tool-result`,output:workflowToolRunFailureOutput(e),toolName:t.toolName}:{callId:t.callId,isError:!0,kind:`tool-result`,output:n.reason??`The workflow tool run was cancelled.`,toolName:t.toolName}}function workflowToolRunFailureOutput(e){if(e.result.status!==`failed`)throw TypeError(`Expected a failed workflow outcome.`);let t=parseJsonValueOrUndefined(e.result.error);return t!==void 0&&typeof t==`object`&&t&&!Array.isArray(t)&&typeof Reflect.get(t,`code`)==`string`?t:errorMessage(e.result.error)}function errorMessage(e){if(typeof e==`object`&&e&&`message`in e){let t=e.message;if(typeof t==`string`)return t}return String(e)}function parseJsonValueOrUndefined(e){try{return parseJsonValue(e)}catch{return}}function workflowToolRunRequestToInputRequestPayload(e){let{from:t,replyTo:n,requestCoordinates:r}=e;return{callId:t.callId,childContinuationToken:n,childSessionId:t.runId,childSessionInbox:e.childSessionInbox,remote:e.remote,inputSource:e.inputSource,event:{requests:workflowToolRunInputRequests(e),sequence:r?.sequence??t.sequence,stepIndex:r?.stepIndex??t.stepIndex,taskId:t.taskId,turnId:r?.turnId??t.turnId},kind:`subagent-input-request`,subagentName:t.toolName}}function workflowToolRunInputRequests(e){return e.request.kind===`input-batch`?e.request.requests:[normalizeInputRequest(e.request,e.from,e.replyTo)]}function normalizeInputRequest(e,t,n){switch(e.kind){case`authorization-request`:throw TypeError(`A workflow authorization event cannot be normalized as human input.`);case`ask`:return normalizeAskRequest(e.request,t,n);default:return e}}function normalizeAskRequest(e,t,n){if(typeof e.prompt!=`string`||e.prompt.length===0)throw TypeError("A workflow tool run request needs a non-empty `prompt`.");let r={action:{callId:t.callId,input:t.input,kind:`tool-call`,toolName:t.toolName},kind:`question`,prompt:e.prompt,requestId:n};return e.allowFreeform!==void 0&&(r.allowFreeform=e.allowFreeform),e.display!==void 0&&(r.display=e.display),e.options!==void 0&&(r.options=[...e.options]),r}export{workflowToolRunFailureOutput,workflowToolRunInputRequests,workflowToolRunOutcomeToToolResult,workflowToolRunRequestToInputRequestPayload};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{callToolStubStep}from"#execution/tool-stubs/steps.js";import{findStubTarget,stubCallId}from"#tool-stubs/target.js";import{createRunUsageTally}from"#execution/agent-sessions/usage.js";import{toolStubOutput}from"#tool-stubs/output.js";import{createAgentSessions}from"#execution/agent-sessions/session.js";import{WorkflowToolRunAsks,ask,attachWorkflowToolRunContext}from"#execution/tools/workflow/ask.js";import{WorkflowToolRunCancelledError,createAgentsView,createSharedContext,createWorkflowBodyRef,resolveWorkflowEntryPoint,toFailedOutcome}from"#execution/tools/workflow/body.js";var WorkflowServeCalls=class{asks;run=new AbortController;first;runRef;runSession;owner;usage=createRunUsageTally(()=>this.sendUncarriedUsage());carriedUsage;toolName;seenCallIds;firstReceived=!1;arrived=[];waiting;latest;pendingReceive;stretch;unwindingCancel=!1;endedBy;replies=Promise.resolve();constructor(e){this.runRef=createWorkflowBodyRef(e),this.asks=new WorkflowToolRunAsks(this.runRef.runId),this.runSession=e.session,this.owner=e.owner,this.toolName=e.toolName,this.seenCallIds=new Set([e.callId]),this.first=this.serve({agentContext:e.agentContext,auth:e.session.auth,callId:this.runRef.callId,executeInput:e.executeInput,input:this.runRef.input,sequence:this.runRef.sequence,stepIndex:this.runRef.stepIndex,turnId:this.runRef.turnId}),this.waiting=[this.first],this.latest=this.first}get runSignal(){return this.run.signal}get unwinding(){return this.run.signal.aborted||this.unwindingCancel}get currentSignal(){return this.stretch?.signal??this.run.signal}get current(){return this.latest}apply(e){switch(e.kind){case`call`:this.accept(e.call);return;case`cancel`:this.cancel(new WorkflowToolRunCancelledError(e.reason));return;case`end`:this.end(new WorkflowToolRunCancelledError(e.reason));return;case`interrupt`:return}}receive(){if(!this.firstReceived)return this.firstReceived=!0,Promise.resolve(this.first.call);if(this.unwindingCancel=!1,this.pendingReceive!==void 0)return this.pendingReceive.promise;if(this.endedBy!==void 0)return Promise.reject(this.endedBy);let e=this.arrived.shift();return e===void 0?(this.pendingReceive=createPendingReceive(),this.pendingReceive.promise):(this.take(e),Promise.resolve(e.call))}reply(e){let t=this.waiting;if(t.length===0)return;this.waiting=[],this.arrived.length===0&&(this.stretch=void 0),this.asks.withdrawAll();let n=this.replies;this.replies=n.then(()=>this.deliverReply(t,e))}assertWaiting(){if(!(this.waiting.length>0))throw Error(`ctx.ask() needs a call waiting for a result, but tool "${this.toolName}" already replied to every call it received.`)}async flush(){await this.asks.flush(),await this.replies}sendUncarriedUsage(){if(this.waiting.length>0||this.endedBy!==void 0)return;let{from:e}=this.latest;this.replies=this.replies.then(async()=>{let t=this.usage.total();t===void 0||isSameUsage(t,this.carriedUsage)||(this.carriedUsage=t,await this.owner.send({from:e,kind:`usage`,usage:t}))})}accept(e){if(this.endedBy!==void 0||this.seenCallIds.has(e.callId))return;this.seenCallIds.add(e.callId);let t=this.serve(e),n=this.pendingReceive;if(n===void 0){this.arrived.push(t);return}this.pendingReceive=void 0,this.take(t),n.resolve(t.call)}take(e){this.waiting.push(e),this.latest=e}cancel(e){this.pendingReceive===void 0&&(this.unwindingCancel=!0),this.stretch?.abort(e),this.stretch=void 0,this.waiting=[],this.arrived=[]}end(e){this.asks.cancelAll(),this.endedBy=e,this.run.abort(e),this.stretch?.abort(e);let t=this.pendingReceive;this.pendingReceive=void 0,t?.reject(e)}serve(e){return this.stretch??=new AbortController,{agentContext:e.agentContext,agents:createAgentsView(e.agentContext),call:{abortSignal:this.stretch.signal,callId:e.callId,input:e.executeInput??e.input},from:{...this.runRef,callId:e.callId,input:e.input,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},session:{...this.runSession,auth:e.auth,turn:{id:e.turnId,sequence:e.sequence}}}}async deliverReply(e,t){let n=e.at(-1);if(n===void 0)return;let r=e.map(e=>e.from.callId),i=this.usage.total();this.carriedUsage=i,await this.owner.send({callIds:r,from:n.from,kind:`reply`,output:t,...i!==void 0&&{usage:i}})}};function isSameUsage(e,t){return t!==void 0&&e.inputTokens===t.inputTokens&&e.outputTokens===t.outputTokens&&e.cacheReadTokens===t.cacheReadTokens&&e.cacheWriteTokens===t.cacheWriteTokens&&e.costUsd===t.costUsd}function startServeBody(e){let t=new WorkflowServeCalls(e),n={get agentContext(){return t.current.agentContext},asks:t.asks,get auth(){return t.current.session.auth},control:e.hookToken,get from(){return t.current.from},owner:e.owner},r=createAgentSessions(n,t.usage),i=createServeContext(e,t,r.open);return attachWorkflowToolRunContext(i,n),{asks:t.asks,close:r.close,control:t,outcome:executeServeBody(e,t,i),usage:t.usage}}async function executeServeBody(e,t,n){let r;try{let i=findStubTarget(e.agentContext.toolStubs,e.toolName),receive=()=>t.receive()
|
|
1
|
+
import{callToolStubStep}from"#execution/tool-stubs/steps.js";import{findStubTarget,stubCallId}from"#tool-stubs/target.js";import{createRunUsageTally}from"#execution/agent-sessions/usage.js";import{toolStubOutput}from"#tool-stubs/output.js";import{createAgentSessions}from"#execution/agent-sessions/session.js";import{WorkflowToolRunAsks,ask,attachWorkflowToolRunContext}from"#execution/tools/workflow/ask.js";import{WorkflowToolRunCancelledError,createAgentsView,createSharedContext,createWorkflowBodyRef,resolveWorkflowEntryPoint,toFailedOutcome,toWorkflowOutput}from"#execution/tools/workflow/body.js";var WorkflowServeCalls=class{asks;run=new AbortController;first;runRef;runSession;owner;usage=createRunUsageTally(()=>this.sendUncarriedUsage());carriedUsage;toolName;seenCallIds;firstReceived=!1;arrived=[];waiting;latest;pendingReceive;stretch;unwindingCancel=!1;endedBy;replies=Promise.resolve();constructor(e){this.runRef=createWorkflowBodyRef(e),this.asks=new WorkflowToolRunAsks(this.runRef.runId),this.runSession=e.session,this.owner=e.owner,this.toolName=e.toolName,this.seenCallIds=new Set([e.callId]),this.first=this.serve({agentContext:e.agentContext,auth:e.session.auth,callId:this.runRef.callId,executeInput:e.executeInput,input:this.runRef.input,sequence:this.runRef.sequence,stepIndex:this.runRef.stepIndex,turnId:this.runRef.turnId}),this.waiting=[this.first],this.latest=this.first}get runSignal(){return this.run.signal}get unwinding(){return this.run.signal.aborted||this.unwindingCancel}get currentSignal(){return this.stretch?.signal??this.run.signal}get current(){return this.latest}apply(e){switch(e.kind){case`call`:this.accept(e.call);return;case`cancel`:this.cancel(new WorkflowToolRunCancelledError(e.reason));return;case`end`:this.end(new WorkflowToolRunCancelledError(e.reason));return;case`interrupt`:return}}receive(){if(!this.firstReceived)return this.firstReceived=!0,Promise.resolve(this.first.call);if(this.unwindingCancel=!1,this.pendingReceive!==void 0)return this.pendingReceive.promise;if(this.endedBy!==void 0)return Promise.reject(this.endedBy);let e=this.arrived.shift();return e===void 0?(this.pendingReceive=createPendingReceive(),this.pendingReceive.promise):(this.take(e),Promise.resolve(e.call))}reply(e){let t=this.waiting;if(t.length===0)return;this.waiting=[],this.arrived.length===0&&(this.stretch=void 0),this.asks.withdrawAll();let n=this.replies;this.replies=n.then(()=>this.deliverReply(t,e))}assertWaiting(){if(!(this.waiting.length>0))throw Error(`ctx.ask() needs a call waiting for a result, but tool "${this.toolName}" already replied to every call it received.`)}async flush(){await this.asks.flush(),await this.replies}sendUncarriedUsage(){if(this.waiting.length>0||this.endedBy!==void 0)return;let{from:e}=this.latest;this.replies=this.replies.then(async()=>{let t=this.usage.total();t===void 0||isSameUsage(t,this.carriedUsage)||(this.carriedUsage=t,await this.owner.send({from:e,kind:`usage`,usage:t}))})}accept(e){if(this.endedBy!==void 0||this.seenCallIds.has(e.callId))return;this.seenCallIds.add(e.callId);let t=this.serve(e),n=this.pendingReceive;if(n===void 0){this.arrived.push(t);return}this.pendingReceive=void 0,this.take(t),n.resolve(t.call)}take(e){this.waiting.push(e),this.latest=e}cancel(e){this.pendingReceive===void 0&&(this.unwindingCancel=!0),this.stretch?.abort(e),this.stretch=void 0,this.waiting=[],this.arrived=[]}end(e){this.asks.cancelAll(),this.endedBy=e,this.run.abort(e),this.stretch?.abort(e);let t=this.pendingReceive;this.pendingReceive=void 0,t?.reject(e)}serve(e){return this.stretch??=new AbortController,{agentContext:e.agentContext,agents:createAgentsView(e.agentContext),call:{abortSignal:this.stretch.signal,callId:e.callId,input:e.executeInput??e.input},from:{...this.runRef,callId:e.callId,input:e.input,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},session:{...this.runSession,auth:e.auth,turn:{id:e.turnId,sequence:e.sequence}}}}async deliverReply(e,t){let n=e.at(-1);if(n===void 0)return;let r=e.map(e=>e.from.callId),i=this.usage.total();this.carriedUsage=i,await this.owner.send({callIds:r,from:n.from,kind:`reply`,output:t,...i!==void 0&&{usage:i}})}};function isSameUsage(e,t){return t!==void 0&&e.inputTokens===t.inputTokens&&e.outputTokens===t.outputTokens&&e.cacheReadTokens===t.cacheReadTokens&&e.cacheWriteTokens===t.cacheWriteTokens&&e.costUsd===t.costUsd}function startServeBody(e){let t=new WorkflowServeCalls(e),n={get agentContext(){return t.current.agentContext},asks:t.asks,get auth(){return t.current.session.auth},control:e.hookToken,get from(){return t.current.from},owner:e.owner},r=createAgentSessions(n,t.usage),i=createServeContext(e,t,r.open);return attachWorkflowToolRunContext(i,n),{asks:t.asks,close:r.close,control:t,outcome:executeServeBody(e,t,i),usage:t.usage}}async function executeServeBody(e,t,n){let r;try{let i=findStubTarget(e.agentContext.toolStubs,e.toolName),receive=()=>t.receive(),a=i===void 0?await resolveWorkflowEntryPoint(e)(receive,n):await serveStub(i.scope,i.tool,receive,n);r={output:toWorkflowOutput(e,a),status:`completed`}}catch(e){r=toFailedOutcome(e,t.runSignal)}return await t.flush(),r}function createServeContext(e,t,n){let r={...createSharedContext(e,n,(e,n)=>(t.assertWaiting(),ask(r,e,n))),get abortSignal(){return t.currentSignal},get agents(){return t.current.agents},get callId(){return t.current.from.callId},get session(){return t.current.session},reply:n=>t.reply(toWorkflowOutput({callId:r.callId,toolName:e.toolName},n))};return r}function createPendingReceive(){let e,t;return{promise:new Promise((n,r)=>{e=n,t=r}),reject:t,resolve:e}}async function serveStub(e,t,n,r){for(;;){let i=await n();if(i.abortSignal.aborted)continue;let a=await callToolStubStep(e,{callId:stubCallId(r.session.id,r.session.turn.id,i.callId),input:i.input,tool:t,persistent:!0});if(a.kind!==`stub`)throw Error(a.kind===`error`?a.error:`Persistent stub configuration changed.`);r.reply(toolStubOutput(a.outcome))}}export{startServeBody};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{skillTarget}from"#shared/action-request-name.js";import{toError}from"#shared/errors.js";import{SKILL_ENTRY_NAME}from"#protocol/catalog-tools.js";import{parseJsonValue}from"#shared/json.js";import{authorizationPendingAsJsonObject,isAuthorizationPendingModelOutput,isAuthorizationSignal}from"#harness/authorization.js";import{withToolOutputSerializationError}from"#harness/tool-output-serialization.js";function toJsonValue(e){return isAuthorizationSignal(e)?parseJsonValue(authorizationPendingAsJsonObject({connections:e.challenges.map(e=>e.name)})):isAuthorizationPendingModelOutput(e)?parseJsonValue(authorizationPendingAsJsonObject(e)):parseJsonValue(e===void 0?null:e)}function createRuntimeToolResultFromValue(e){let t={callId:e.callId,kind:`tool-result`,output:toolResultOutputToJsonValue({output:{type:e.isError===!0?`error-json`:`json`,value:
|
|
1
|
+
import{skillTarget}from"#shared/action-request-name.js";import{toError}from"#shared/errors.js";import{SKILL_ENTRY_NAME}from"#protocol/catalog-tools.js";import{parseJsonValue}from"#shared/json.js";import{authorizationPendingAsJsonObject,isAuthorizationPendingModelOutput,isAuthorizationSignal}from"#harness/authorization.js";import{withToolOutputSerializationError}from"#harness/tool-output-serialization.js";function toJsonValue(e){return isAuthorizationSignal(e)?parseJsonValue(authorizationPendingAsJsonObject({connections:e.challenges.map(e=>e.name)})):isAuthorizationPendingModelOutput(e)?parseJsonValue(authorizationPendingAsJsonObject(e)):parseJsonValue(e===void 0?null:e)}function createRuntimeToolResultFromValue(e){let t=e.isError===!0&&e.output instanceof Error?e.output:void 0,n={callId:e.callId,kind:`tool-result`,output:toolResultOutputToJsonValue({output:{type:e.isError===!0?`error-json`:`json`,value:t===void 0?e.output:t.message},toolCallId:e.callId,toolName:e.toolName}),toolName:e.toolName};return e.isError===!0?t===void 0?{...n,isError:!0}:{...n,errorName:t.name,isError:!0}:n}function createRuntimeToolResultFromStepResult(e){return createRuntimeToolResultFromValue({callId:e.toolCallId,output:e.output,toolName:e.toolName})}function createRuntimeToolResultFromToolError(e){return createRuntimeToolResultFromValue({callId:e.toolCallId,isError:!0,output:toError(e.error),toolName:e.toolName})}function toActionResult(e,t){let n=e.toolName===SKILL_ENTRY_NAME?skillTarget(t):void 0;return n===void 0?e:{callId:e.callId,isError:e.isError,kind:`load-skill-result`,name:n,output:e.output}}function createToolResultMessagePartFromToolError(e){return{type:`tool-result`,toolCallId:e.toolCallId,toolName:e.toolName,output:{type:`error-text`,value:toError(e.error).message}}}function createRuntimeToolResultFromMessagePart(e,t){return createRuntimeToolResultFromValue({callId:e.toolCallId,output:toolResultOutputToJsonValue({output:e.output,toolCallId:e.toolCallId,toolName:t}),toolName:t,isError:isToolResultError(e.output)})}function toolResultOutputToJsonValue(e){return withToolOutputSerializationError({boundary:`action.result`,toolCallId:e.toolCallId,toolName:e.toolName},()=>{switch(e.output.type){case`text`:case`error-text`:return e.output.value;case`json`:case`error-json`:return toJsonValue(e.output.value);case`execution-denied`:return{code:`TOOL_EXECUTION_DENIED`,message:e.output.reason??`Tool execution was denied.`};case`content`:return toJsonValue(e.output.value)}})}function isToolResultError(e){return e.type===`error-json`||e.type===`error-text`||e.type===`execution-denied`}export{createRuntimeToolResultFromMessagePart,createRuntimeToolResultFromStepResult,createRuntimeToolResultFromToolError,createRuntimeToolResultFromValue,createToolResultMessagePartFromToolError,isToolResultError,toActionResult};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash}from"node:crypto";import{buildSessionHandle}from"#channel/session.js";import{createLogger}from"#internal/logging.js";import{getAdapterKind}from"#channel/adapter.js";import{contextStorage,loadContext}from"#context/container.js";import{SandboxKey}from"#context/keys.js";import{deserializeUrlFilePart,isSerializedUrlFilePart}from"#internal/attachments/url-refs.js";import{basename,dirname,extname}from"node:path";import{ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{createFrameworkUserMessage}from"#harness/messages.js";import{DEFAULT_UPLOAD_POLICY,isMediaTypeAllowed}from"#public/channels/upload-policy.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{readMediaMetadata,verifyMediaType}from"#internal/attachments/media-metadata.js";import{decodeSandboxRef,encodeSandboxRef,inlinesSandboxRefAsBytes,isSandboxRefUrl}from"#internal/attachments/sandbox-refs.js";import{isUnresolvedFileData,readFileData}from"#internal/attachments/data.js";import{EveAttachmentError}from"#internal/attachments/errors.js";import{maxBytesOf}from"#internal/attachments/limited-read.js";import{createPublicDownloads}from"#internal/attachments/public-link.js";const ATTACHMENTS_ROOT=`/workspace/.eve/attachments`,log=createLogger(`harness.attachment-staging`),UNSAFE_FILENAME_CHARS=/[^\w.-]+/g,MEDIA_TYPE_EXTENSIONS={"application/pdf":`.pdf`,"image/gif":`.gif`,"image/jpeg":`.jpg`,"image/png":`.png`,"image/webp":`.webp`};async function stageAttachmentsForAdapter(e,t,n){if(typeof e==`string`)return e;let r=reconstitueFilePartUrls(e),i=n.ctx.get(ChannelKey)?.uploadPolicy,a=createPublicDownloads(maxBytesOf(i??DEFAULT_UPLOAD_POLICY));return Promise.all(r.map(async e=>e.type===`file`?stageFilePart(e,t,n,a,i):e))}async function stageAttachmentsToSandbox(e){if(typeof e==`string`||!Array.isArray(e)||!hasFileParts(e))return e;let t=loadContext(),n=await t.get(SandboxKey)?.get()??null;if(n===null)return e.map(e=>e.type===`file`&&!isSandboxRefUrl(e.data)&&readFileData(e.data).kind!==`reference`?attachmentNote(e,`could not be stored: no sandbox is available.`):e);let r=t.get(ChannelKey);return stageAttachmentsForAdapter(e,n,r?buildAdapterContext(r,t):{ctx:t,state:{},session:buildSessionHandle(t)})}async function stageToolResultMedia(e){if(!e.some(hasInlineToolResultFile))return[...e];let t=await contextStorage.getStore()?.get(SandboxKey)?.get()??null;return Promise.all(e.map(async e=>{if(e.role!==`tool`||!hasInlineToolResultFile(e))return e;let n=await Promise.all(e.content.map(async e=>e.type===`tool-result`?{...e,output:await stageToolOutputFiles(e.output,t)}:e));return{...e,content:n}}))}async function hydrateSandboxAttachments(e){let t=replaceUnresolvedFileParts(e);if(!messagesContainSandboxRef(t))return t;let n=loadContext().get(SandboxKey);if(n===void 0)throw Error(`Cannot hydrate sandbox-ref FilePart: no SandboxKey is bound on the active eve context. Hydration must run inside a step scope with the framework sandbox provider installed.`);let r=await n.get();if(r===null)throw Error(`Cannot hydrate sandbox-ref FilePart: SandboxKey is bound but no active sandbox session is available.`);return Promise.all(t.map(async e=>{if(!messageContainsSandboxRef(e))return e;let t=await hydrateMessageContent(e.content,r);return{...e,content:t}}))}function replaceUnresolvedFileParts(e){let t=!1,n=e.map(e=>{if(e.role!==`user`||!Array.isArray(e.content)||!e.content.some(isUnresolvedFilePart))return e;t=!0;let n=e.content.map(e=>isUnresolvedFilePart(e)?attachmentNote(e,`could not be retrieved.`):e);return{...e,content:n}});return t?n:e}function isUnresolvedFilePart(e){return e.type===`file`&&!isSandboxRefUrl(e.data)&&isUnresolvedFileData(e.data)}function hasFileParts(e){for(let t of e)if(t.type===`file`)return!0;return!1}function messagesContainSandboxRef(e){for(let t of e)if(messageContainsSandboxRef(t))return!0;return!1}function messageContainsSandboxRef(e){let t=e.content;if(!Array.isArray(t))return!1;for(let e of t)if(isSandboxRefFilePart(e)||e.type===`tool-result`&&contentOutputParts(e.output).some(isToolOutputRefFile))return!0;return!1}function contentOutputParts(e){return e.type===`content`?e.value:[]}function hasInlineToolResultFile(e){return e.role===`tool`&&e.content.some(e=>e.type===`tool-result`&&contentOutputParts(e.output).some(isInlineToolOutputFile))}function isInlineToolOutputFile(e){return e.type===`file`&&e.data.type===`data`}function isToolOutputRefFile(e){return e.type===`file`&&e.data.type===`url`&&isSandboxRefUrl(e.data.url)}async function stageToolOutputFiles(e,t){if(e.type!==`content`||!e.value.some(isInlineToolOutputFile))return e;let n=await Promise.all(e.value.map(async e=>{if(!isInlineToolOutputFile(e)||e.data.type!==`data`)return e;let n=readFileData(e.data.data);if(n.kind===`link`)return e;if(t===null||n.kind!==`bytes`)return{text:`Returned file ${e.filename??`file`} (${e.mediaType}) could not be stored.`,type:`text`};let r=await writeSandboxRef(n.bytes,e.mediaType,e.filename,t);return{...e,data:{type:`url`,url:encodeSandboxRef(r)},mediaType:r.mediaType}}));return{...e,value:n}}function isSandboxRefFilePart(e){return typeof e==`object`&&!!e&&e.type===`file`&&isSandboxRefUrl(e.data)}async function hydrateMessageContent(e,t){return Array.isArray(e)?(await Promise.all(e.map(async e=>{if(isSandboxRefFilePart(e)){let n=decodeSandboxRef(e.data),r=renderSandboxRefAsTextPart(n);if(!inlinesSandboxRefAsBytes(n))return[r];let i=await readSandboxRefBytes(n,t);return i===null?[renderMissingSandboxRef(n)]:[r,{...e,data:i,mediaType:n.mediaType}]}if(e.type===`tool-result`){let n=e;return[{...n,output:await hydrateToolOutput(n.output,t)}]}return[e]}))).flat():e}async function hydrateToolOutput(e,t){if(e.type!==`content`||!e.value.some(isToolOutputRefFile))return e;let n=await Promise.all(e.value.map(async e=>{if(!isToolOutputRefFile(e)||e.data.type!==`url`)return[e];let n=decodeSandboxRef(e.data.url),r=renderSandboxRefAsTextPart(n);if(!inlinesSandboxRefAsBytes(n))return[r];let i=await readSandboxRefBytes(n,t);return i===null?[renderMissingSandboxRef(n)]:[r,{...e,data:{data:Buffer.from(i).toString(`base64`),type:`data`}}]}));return{...e,value:n.flat()}}async function readSandboxRefBytes(e,t){let n=await t.readBinaryFile({path:e.path});return n===null?(log.warn(`sandbox-ref attachment bytes missing on hydration — degrading to text reference`,{mediaType:e.mediaType,path:e.path,size:e.size}),null):n.byteLength!==e.size||sha256Prefix(n)!==basename(dirname(e.path))?(log.warn(`sandbox-ref attachment bytes changed since staging — degrading to text reference`,{mediaType:e.mediaType,path:e.path,size:e.size}),null):n}function renderMissingSandboxRef(e){return{text:`FileNotFound: Current snapshot may be newer and does not contain ${e.path}.`,type:`text`}}function moveToolResultFilesToUserMessages(e){let t=[],n=[];for(let r of e){if(r.role!==`tool`&&n.length>0&&(t.push(createReturnedFilesMessage(n)),n=[]),r.role!==`tool`){t.push(r);continue}let e=r.content.map(e=>{if(e.type!==`tool-result`||e.output.type!==`content`)return e;let t=e.output.value.map(e=>{if(e.type!==`file`)return e;let t={data:e.data,mediaType:e.mediaType,type:`file`};return e.filename!==void 0&&(t.filename=e.filename),n.push(t),{text:`Attached file ${e.filename??`file`} (${e.mediaType}) follows this tool result.`,type:`text`}});return{...e,output:{...e.output,value:t}}});t.push({...r,content:e})}return n.length>0&&t.push(createReturnedFilesMessage(n)),t}function createReturnedFilesMessage(e){return createFrameworkUserMessage(`context.state`,[{text:`Files returned by the preceding tool results:`,type:`text`},...e])}function renderSandboxRefAsTextPart(e){return{text:`Attached file ${e.path} (${e.mediaType})`,type:`text`}}async function stageFilePart(e,t,n,r,i){if(isSandboxRefUrl(e.data))return e;let a=readFileData(e.data);if(a.kind===`bytes`)return stageResolvedBytes(e,{bytes:a.bytes},t,i);if(a.kind===`reference`)return e;if(a.kind===`unreadable`)return log.warn(`attachment data is not bytes, base64, or a URL — degrading to text part`,{filename:e.filename,mediaType:e.mediaType}),attachmentNote(e,`could not be read.`);let o;try{o=await resolveLink(a.url,n,r)}catch(t){if(!(t instanceof EveAttachmentError))throw t;return log.warn(`attachment resolver failed — degrading to text part`,{adapterKind:t.adapterKind,error:t.cause,filename:e.filename,kind:t.kind}),attachmentNote(e,`could not be retrieved: ${t.message}`)}return stageResolvedBytes(e,o,t,i)}function attachmentNote(e,t){return{text:`Attachment ${e.filename?.trim()||`file`} ${t}`,type:`text`}}async function stageResolvedBytes(e,t,n,r){let i=verifyMediaType(t.bytes,t.mediaType??e.mediaType??`application/octet-stream`);if(r!==void 0){let n=maxBytesOf(r);if(t.bytes.byteLength>n)return attachmentNote(e,`was not accepted: it is ${t.bytes.byteLength} bytes, over this channel's ${n}-byte upload limit.`);if(!isMediaTypeAllowed(i,r))return attachmentNote(e,`was not accepted: this channel doesn't accept ${i} files.`)}let a=await writeSandboxRef(t.bytes,i,t.filename??e.filename,n);return{...e,data:encodeSandboxRef(a),filename:a.path,mediaType:a.mediaType}}async function writeSandboxRef(e,t,n,r){let i=verifyMediaType(e,t),a=sha256Prefix(e),o=`${ATTACHMENTS_ROOT}/${a}/${safeFilename(n,a,i)}`;return await r.writeBinaryFile({content:e,path:o}),{...readMediaMetadata(e,i),path:r.resolvePath(o)}}async function resolveLink(e,t,n){let r=t.ctx.get(ChannelKey),i=r===void 0?`none`:getAdapterKind(r);if(r?.fetchFile!==void 0){let n;try{n=await r.fetchFile(e.href,t)}catch(e){throw e instanceof EveAttachmentError?new EveAttachmentError({adapterKind:i,cause:e.cause,kind:e.kind,message:e.message}):new EveAttachmentError({adapterKind:i,cause:e,kind:`resolver-threw`,message:`Attachment retrieval failed in the "${i}" channel.`})}if(n!==null)return Buffer.isBuffer(n)?{bytes:n}:n}return n(e,i)}function reconstitueFilePartUrls(e){let t=!1,n=e.map(e=>e.type===`file`&&isSerializedUrlFilePart(e.data)?(t=!0,{...e,data:deserializeUrlFilePart(e.data)}):e);return t?n:e}function sha256Prefix(e){return createHash(`sha256`).update(e).digest(`hex`).slice(0,16)}function safeFilename(e,t,n){let r=e===void 0?``:basename(e).replace(UNSAFE_FILENAME_CHARS,`_`),i=r.length>0?r:`file-${t}`,a=MEDIA_TYPE_EXTENSIONS[n];return a===void 0||extname(i)!==``?i:`${i}${a}`}export{ATTACHMENTS_ROOT,hydrateSandboxAttachments,moveToolResultFilesToUserMessages,stageAttachmentsForAdapter,stageAttachmentsToSandbox,stageToolResultMedia};
|
|
1
|
+
import{createHash}from"node:crypto";import{buildSessionHandle}from"#channel/session.js";import{createLogger}from"#internal/logging.js";import{getAdapterKind}from"#channel/adapter.js";import{contextStorage,loadContext}from"#context/container.js";import{SandboxKey}from"#context/keys.js";import{deserializeUrlFilePart,isSerializedUrlFilePart}from"#internal/attachments/url-refs.js";import{basename,dirname,extname}from"node:path";import{ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{createFrameworkUserMessage}from"#harness/messages.js";import{DEFAULT_UPLOAD_POLICY,isMediaTypeAllowed}from"#public/channels/upload-policy.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{readMediaMetadata,verifyMediaType}from"#internal/attachments/media-metadata.js";import{decodeSandboxRef,encodeSandboxRef,inlinesSandboxRefAsBytes,isSandboxRefUrl}from"#internal/attachments/sandbox-refs.js";import{isUnresolvedFileData,readFileData}from"#internal/attachments/data.js";import{EveAttachmentError}from"#internal/attachments/errors.js";import{maxBytesOf}from"#internal/attachments/limited-read.js";import{createPublicDownloads}from"#internal/attachments/public-link.js";const ATTACHMENTS_ROOT=`/workspace/.eve/attachments`,log=createLogger(`harness.attachment-staging`),UNSAFE_FILENAME_CHARS=/[^\w.-]+/g,MEDIA_TYPE_EXTENSIONS={"application/pdf":`.pdf`,"image/gif":`.gif`,"image/jpeg":`.jpg`,"image/png":`.png`,"image/webp":`.webp`};async function stageAttachmentsForAdapter(e,t,n){if(typeof e==`string`)return e;let r=reconstitueFilePartUrls(e),i=n.ctx.get(ChannelKey)?.uploadPolicy,a=createPublicDownloads(maxBytesOf(i??DEFAULT_UPLOAD_POLICY));return Promise.all(r.map(async e=>e.type===`file`?stageFilePart(e,t,n,a,i):e))}async function stageAttachmentsToSandbox(e){if(typeof e==`string`||!Array.isArray(e)||!hasFileParts(e))return e;let t=loadContext(),n=await activeSandbox(t.get(SandboxKey));if(n===null)return e.map(e=>e.type===`file`&&!isSandboxRefUrl(e.data)&&readFileData(e.data).kind!==`reference`?attachmentNote(e,`could not be stored: no sandbox is available.`):e);let r=t.get(ChannelKey);return stageAttachmentsForAdapter(e,n,r?buildAdapterContext(r,t):{ctx:t,state:{},session:buildSessionHandle(t)})}async function stageToolResultMedia(e){if(!e.some(hasInlineToolResultFile))return[...e];let t=await activeSandbox(contextStorage.getStore()?.get(SandboxKey));return Promise.all(e.map(async e=>{if(e.role!==`tool`||!hasInlineToolResultFile(e))return e;let n=await Promise.all(e.content.map(async e=>e.type===`tool-result`?{...e,output:await stageToolOutputFiles(e.output,t)}:e));return{...e,content:n}}))}async function hydrateSandboxAttachments(e){let t=replaceUnresolvedFileParts(e);if(!messagesContainSandboxRef(t))return t;let n=loadContext().get(SandboxKey);if(n===void 0)throw Error(`Cannot hydrate sandbox-ref FilePart: no SandboxKey is bound on the active eve context. Hydration must run inside a step scope with the framework sandbox provider installed.`);let r=await activeSandbox(n);return Promise.all(t.map(async e=>{if(!messageContainsSandboxRef(e))return e;let t=await hydrateMessageContent(e.content,r);return{...e,content:t}}))}async function activeSandbox(e){if(e===void 0)return null;try{return await e.get()}catch(e){return log.warn(`session sandbox unavailable, degrading attachments to text`,{error:e}),null}}function replaceUnresolvedFileParts(e){let t=!1,n=e.map(e=>{if(e.role!==`user`||!Array.isArray(e.content)||!e.content.some(isUnresolvedFilePart))return e;t=!0;let n=e.content.map(e=>isUnresolvedFilePart(e)?attachmentNote(e,`could not be retrieved.`):e);return{...e,content:n}});return t?n:e}function isUnresolvedFilePart(e){return e.type===`file`&&!isSandboxRefUrl(e.data)&&isUnresolvedFileData(e.data)}function hasFileParts(e){for(let t of e)if(t.type===`file`)return!0;return!1}function messagesContainSandboxRef(e){for(let t of e)if(messageContainsSandboxRef(t))return!0;return!1}function messageContainsSandboxRef(e){let t=e.content;if(!Array.isArray(t))return!1;for(let e of t)if(isSandboxRefFilePart(e)||e.type===`tool-result`&&contentOutputParts(e.output).some(isToolOutputRefFile))return!0;return!1}function contentOutputParts(e){return e.type===`content`?e.value:[]}function hasInlineToolResultFile(e){return e.role===`tool`&&e.content.some(e=>e.type===`tool-result`&&contentOutputParts(e.output).some(isInlineToolOutputFile))}function isInlineToolOutputFile(e){return e.type===`file`&&e.data.type===`data`}function isToolOutputRefFile(e){return e.type===`file`&&e.data.type===`url`&&isSandboxRefUrl(e.data.url)}async function stageToolOutputFiles(e,t){if(e.type!==`content`||!e.value.some(isInlineToolOutputFile))return e;let n=await Promise.all(e.value.map(async e=>{if(!isInlineToolOutputFile(e)||e.data.type!==`data`)return e;let n=readFileData(e.data.data);if(n.kind===`link`)return e;if(t===null||n.kind!==`bytes`)return{text:`Returned file ${e.filename??`file`} (${e.mediaType}) could not be stored.`,type:`text`};let r=await writeSandboxRef(n.bytes,e.mediaType,e.filename,t);return{...e,data:{type:`url`,url:encodeSandboxRef(r)},mediaType:r.mediaType}}));return{...e,value:n}}function isSandboxRefFilePart(e){return typeof e==`object`&&!!e&&e.type===`file`&&isSandboxRefUrl(e.data)}async function hydrateMessageContent(e,t){return Array.isArray(e)?(await Promise.all(e.map(async e=>{if(isSandboxRefFilePart(e)){let n=decodeSandboxRef(e.data),r=renderSandboxRefAsTextPart(n);if(!inlinesSandboxRefAsBytes(n))return[r];let i=await readSandboxRefBytes(n,t);return i===null?[renderMissingSandboxRef(n)]:[r,{...e,data:i,mediaType:n.mediaType}]}if(e.type===`tool-result`){let n=e;return[{...n,output:await hydrateToolOutput(n.output,t)}]}return[e]}))).flat():e}async function hydrateToolOutput(e,t){if(e.type!==`content`||!e.value.some(isToolOutputRefFile))return e;let n=await Promise.all(e.value.map(async e=>{if(!isToolOutputRefFile(e)||e.data.type!==`url`)return[e];let n=decodeSandboxRef(e.data.url),r=renderSandboxRefAsTextPart(n);if(!inlinesSandboxRefAsBytes(n))return[r];let i=await readSandboxRefBytes(n,t);return i===null?[renderMissingSandboxRef(n)]:[r,{...e,data:{data:Buffer.from(i).toString(`base64`),type:`data`}}]}));return{...e,value:n.flat()}}async function readSandboxRefBytes(e,t){if(t===null)return null;let n=await t.readBinaryFile({path:e.path});return n===null?(log.warn(`sandbox-ref attachment bytes missing on hydration — degrading to text reference`,{mediaType:e.mediaType,path:e.path,size:e.size}),null):n.byteLength!==e.size||sha256Prefix(n)!==basename(dirname(e.path))?(log.warn(`sandbox-ref attachment bytes changed since staging — degrading to text reference`,{mediaType:e.mediaType,path:e.path,size:e.size}),null):n}function renderMissingSandboxRef(e){return{text:`FileNotFound: Current snapshot may be newer and does not contain ${e.path}.`,type:`text`}}function moveToolResultFilesToUserMessages(e){let t=[],n=[];for(let r of e){if(r.role!==`tool`&&n.length>0&&(t.push(createReturnedFilesMessage(n)),n=[]),r.role!==`tool`){t.push(r);continue}let e=r.content.map(e=>{if(e.type!==`tool-result`||e.output.type!==`content`)return e;let t=e.output.value.map(e=>{if(e.type!==`file`)return e;let t={data:e.data,mediaType:e.mediaType,type:`file`};return e.filename!==void 0&&(t.filename=e.filename),n.push(t),{text:`Attached file ${e.filename??`file`} (${e.mediaType}) follows this tool result.`,type:`text`}});return{...e,output:{...e.output,value:t}}});t.push({...r,content:e})}return n.length>0&&t.push(createReturnedFilesMessage(n)),t}function createReturnedFilesMessage(e){return createFrameworkUserMessage(`context.state`,[{text:`Files returned by the preceding tool results:`,type:`text`},...e])}function renderSandboxRefAsTextPart(e){return{text:`Attached file ${e.path} (${e.mediaType})`,type:`text`}}async function stageFilePart(e,t,n,r,i){if(isSandboxRefUrl(e.data))return e;let a=readFileData(e.data);if(a.kind===`bytes`)return stageResolvedBytes(e,{bytes:a.bytes},t,i);if(a.kind===`reference`)return e;if(a.kind===`unreadable`)return log.warn(`attachment data is not bytes, base64, or a URL — degrading to text part`,{filename:e.filename,mediaType:e.mediaType}),attachmentNote(e,`could not be read.`);let o;try{o=await resolveLink(a.url,n,r)}catch(t){if(!(t instanceof EveAttachmentError))throw t;return log.warn(`attachment resolver failed — degrading to text part`,{adapterKind:t.adapterKind,error:t.cause,filename:e.filename,kind:t.kind}),attachmentNote(e,`could not be retrieved: ${t.message}`)}return stageResolvedBytes(e,o,t,i)}function attachmentNote(e,t){return{text:`Attachment ${e.filename?.trim()||`file`} ${t}`,type:`text`}}async function stageResolvedBytes(e,t,n,r){let i=verifyMediaType(t.bytes,t.mediaType??e.mediaType??`application/octet-stream`);if(r!==void 0){let n=maxBytesOf(r);if(t.bytes.byteLength>n)return attachmentNote(e,`was not accepted: it is ${t.bytes.byteLength} bytes, over this channel's ${n}-byte upload limit.`);if(!isMediaTypeAllowed(i,r))return attachmentNote(e,`was not accepted: this channel doesn't accept ${i} files.`)}let a=await writeSandboxRef(t.bytes,i,t.filename??e.filename,n);return{...e,data:encodeSandboxRef(a),filename:a.path,mediaType:a.mediaType}}async function writeSandboxRef(e,t,n,r){let i=verifyMediaType(e,t),a=sha256Prefix(e),o=`${ATTACHMENTS_ROOT}/${a}/${safeFilename(n,a,i)}`;return await r.writeBinaryFile({content:e,path:o}),{...readMediaMetadata(e,i),path:r.resolvePath(o)}}async function resolveLink(e,t,n){let r=t.ctx.get(ChannelKey),i=r===void 0?`none`:getAdapterKind(r);if(r?.fetchFile!==void 0){let n;try{n=await r.fetchFile(e.href,t)}catch(e){throw e instanceof EveAttachmentError?new EveAttachmentError({adapterKind:i,cause:e.cause,kind:e.kind,message:e.message}):new EveAttachmentError({adapterKind:i,cause:e,kind:`resolver-threw`,message:`Attachment retrieval failed in the "${i}" channel.`})}if(n!==null)return Buffer.isBuffer(n)?{bytes:n}:n}return n(e,i)}function reconstitueFilePartUrls(e){let t=!1,n=e.map(e=>e.type===`file`&&isSerializedUrlFilePart(e.data)?(t=!0,{...e,data:deserializeUrlFilePart(e.data)}):e);return t?n:e}function sha256Prefix(e){return createHash(`sha256`).update(e).digest(`hex`).slice(0,16)}function safeFilename(e,t,n){let r=e===void 0?``:basename(e).replace(UNSAFE_FILENAME_CHARS,`_`),i=r.length>0?r:`file-${t}`,a=MEDIA_TYPE_EXTENSIONS[n];return a===void 0||extname(i)!==``?i:`${i}${a}`}export{ATTACHMENTS_ROOT,hydrateSandboxAttachments,moveToolResultFilesToUserMessages,stageAttachmentsForAdapter,stageAttachmentsToSandbox,stageToolResultMedia};
|
|
@@ -1 +1,3 @@
|
|
|
1
|
-
import{createFrameworkUserMessage,isFrameworkUserMessage}from"#harness/messages.js";import{COMPACTION_CHECKPOINT_MARKER,COMPACTION_PROMPT_ENVELOPE,COMPACTION_RESUMPTION_MESSAGE,TRANSCRIPT_PAYLOAD_LIMIT,createCompactionPrompt,sliceUtf16Safe,stubContentOutputFileParts}from"#harness/compaction/prompt.js";import{estimateTokens}from"#harness/token-estimate.js";const COMPACTION_PROMPT_OVERHEAD_TOKENS=estimateTokens([{content:COMPACTION_PROMPT_ENVELOPE.system,role:`system`},createFrameworkUserMessage(`context.compaction`,COMPACTION_PROMPT_ENVELOPE.prompt)]);function getInputTokenCount(e,t,n=0,r=0){let i=t.lastKnownInputTokens,a=t.lastKnownPromptMessageCount;return i===void 0||a===void 0||!Number.isInteger(a)||a<0||a>e.length?estimateTokens(e)+n:i+estimateTokens(e.slice(a))+Math.max(0,n-r)}function shouldCompact(e,t,n=0,r=0){return e.length>0&&getInputTokenCount(e,t,n,r)+COMPACTION_PROMPT_OVERHEAD_TOKENS>t.threshold}const COMPACTION_HEURISTICS=[toolResultCapHeuristic];function toolResultCapHeuristic(e){let t=withResumptionGuard([...e.previousCheckpoint===void 0?[]:[createFrameworkUserMessage(`context.compaction`,COMPACTION_CHECKPOINT_MARKER),{content:e.previousCheckpoint,role:`assistant`}],...capToolResults(e.older),...e.recent],e.conversation,e.config.threshold);return evaluateThreshold(t,e.config,`should-compact`,e.tokenEstimateAdjustment).type===`within-limit`?{messages:t,type:`within-limit`}:{type:`insufficient`}}function evaluateThreshold(e,t,n,r=0){let i=n===`should-compact`?COMPACTION_PROMPT_OVERHEAD_TOKENS:0,a=estimateTokens(e)+i+r;return{estimatedTokens:a,type:a<=t.threshold?`within-limit`:`over-limit`}}async function compactMessages(e,t,n,r=!1,i){let{conversation:a,previousCheckpoint:o}=extractPreviousCheckpoint(e),s=selectRecentWindowSize(a,r?{...t,recentWindowSize:1}:t);if(!r){let{older:n,recent:r}=splitMessagesForCompaction(a,s);if(n.length===0&&o===void 0)return keepNonToolResultMessages(r);let c=Math.max(0,(i??getInputTokenCount(e,t))-estimateTokens(e));for(let e of COMPACTION_HEURISTICS){let i=e({config:t,conversation:a,older:n,previousCheckpoint:o,recent:r,tokenEstimateAdjustment:c});if(i.type===`within-limit`)return i.messages}}for(;;){let{older:e,recent:r}=splitMessagesForCompaction(a,s),i=createCompactionPrompt({messages:e,previousCheckpoint:o,transcriptBudgetTokens:t.threshold}),c=await n({messages:[createFrameworkUserMessage(`context.compaction`,i.prompt)],system:i.system}),l=[createFrameworkUserMessage(`context.compaction`,COMPACTION_CHECKPOINT_MARKER),{content:c,role:`assistant`}],u=withResumptionGuard([...l,...r],a,t.threshold);if(evaluateThreshold(u,t,`estimate`).type===`within-limit`)return u;let d=withResumptionGuard([...l,...keepNonToolResultMessages(r)],a,t.threshold);if(evaluateThreshold(d,t,`estimate`).type===`within-limit`||s===0)return d;--s}}function capToolResults(e){return e.map(e=>{if(e.role!==`tool`||typeof e.content==`string`)return e;let t=!1,n=e.content.map(e=>{if(e.type!==`tool-result`)return e;let n=stubContentOutputFileParts(e.output),r=
|
|
1
|
+
import{createFrameworkUserMessage,isFrameworkUserMessage}from"#harness/messages.js";import{COMPACTION_CHECKPOINT_MARKER,COMPACTION_PROMPT_ENVELOPE,COMPACTION_RESUMPTION_MESSAGE,TRANSCRIPT_PAYLOAD_LIMIT,createCompactionPrompt,serializeToolResultOutput,sliceUtf16Safe,stubContentOutputFileParts}from"#harness/compaction/prompt.js";import{estimateTokens}from"#harness/token-estimate.js";const COMPACTION_PROMPT_OVERHEAD_TOKENS=estimateTokens([{content:COMPACTION_PROMPT_ENVELOPE.system,role:`system`},createFrameworkUserMessage(`context.compaction`,COMPACTION_PROMPT_ENVELOPE.prompt)]);function getInputTokenCount(e,t,n=0,r=0){let i=t.lastKnownInputTokens,a=t.lastKnownPromptMessageCount;return i===void 0||a===void 0||!Number.isInteger(a)||a<0||a>e.length?estimateTokens(e)+n:i+estimateTokens(e.slice(a))+Math.max(0,n-r)}function shouldCompact(e,t,n=0,r=0){return e.length>0&&getInputTokenCount(e,t,n,r)+COMPACTION_PROMPT_OVERHEAD_TOKENS>t.threshold}const COMPACTION_HEURISTICS=[toolResultCapHeuristic];function toolResultCapHeuristic(e){let t=withResumptionGuard([...e.previousCheckpoint===void 0?[]:[createFrameworkUserMessage(`context.compaction`,COMPACTION_CHECKPOINT_MARKER),{content:e.previousCheckpoint,role:`assistant`}],...capToolResults(e.older),...e.recent],e.conversation,e.config.threshold);return evaluateThreshold(t,e.config,`should-compact`,e.tokenEstimateAdjustment).type===`within-limit`?{messages:t,type:`within-limit`}:{type:`insufficient`}}function evaluateThreshold(e,t,n,r=0){let i=n===`should-compact`?COMPACTION_PROMPT_OVERHEAD_TOKENS:0,a=estimateTokens(e)+i+r;return{estimatedTokens:a,type:a<=t.threshold?`within-limit`:`over-limit`}}async function compactMessages(e,t,n,r=!1,i){let{conversation:a,previousCheckpoint:o}=extractPreviousCheckpoint(e),s=selectRecentWindowSize(a,r?{...t,recentWindowSize:1}:t);if(!r){let{older:n,recent:r}=splitMessagesForCompaction(a,s);if(n.length===0&&o===void 0)return keepNonToolResultMessages(r);let c=Math.max(0,(i??getInputTokenCount(e,t))-estimateTokens(e));for(let e of COMPACTION_HEURISTICS){let i=e({config:t,conversation:a,older:n,previousCheckpoint:o,recent:r,tokenEstimateAdjustment:c});if(i.type===`within-limit`)return i.messages}}for(;;){let{older:e,recent:r}=splitMessagesForCompaction(a,s),i=createCompactionPrompt({messages:e,previousCheckpoint:o,transcriptBudgetTokens:t.threshold}),c=await n({messages:[createFrameworkUserMessage(`context.compaction`,i.prompt)],system:i.system}),l=[createFrameworkUserMessage(`context.compaction`,COMPACTION_CHECKPOINT_MARKER),{content:c,role:`assistant`}],u=withResumptionGuard([...l,...r],a,t.threshold);if(evaluateThreshold(u,t,`estimate`).type===`within-limit`)return u;let d=withResumptionGuard([...l,...keepNonToolResultMessages(r)],a,t.threshold);if(evaluateThreshold(d,t,`estimate`).type===`within-limit`||s===0)return d;--s}}function capToolResults(e){return e.map(e=>{if(e.role!==`tool`||typeof e.content==`string`)return e;let t=!1,n=e.content.map(e=>{if(e.type!==`tool-result`)return e;let n=stubContentOutputFileParts(e.output),r=serializeToolResultOutput(n);return r.length<=TRANSCRIPT_PAYLOAD_LIMIT?n===e.output?e:(t=!0,{...e,output:n}):(t=!0,{...e,output:{type:`text`,value:`[Truncated by eve: tool result reduced during context compaction. Re-run the tool if you need the full output.]
|
|
2
|
+
|
|
3
|
+
${sliceUtf16Safe(r,TRANSCRIPT_PAYLOAD_LIMIT-113)}`}})});return t?{...e,content:n}:e})}function withResumptionGuard(e,t,n){let r=e.at(-1)?.role,i=findLastRealUserMessage(t),a=i!==void 0&&e.some(e=>e.role===`user`&&e.content===i.content);return r!==void 0&&r!==`assistant`?r===`tool`&&i!==void 0&&!a&&estimateTokens([i])<=n?[...e,i]:e:[...e,i!==void 0&&!a?i:createFrameworkUserMessage(`execution.continuation`,COMPACTION_RESUMPTION_MESSAGE)]}function findLastRealUserMessage(e){for(let t=e.length-1;t>=0;--t){let n=e[t];if(n?.role===`user`&&typeof n.content==`string`&&!isFrameworkUserMessage(n))return n}}function extractPreviousCheckpoint(e){let t=e[0],n=e[1];return t?.role!==`user`||t.content!==COMPACTION_CHECKPOINT_MARKER||n?.role!==`assistant`?{conversation:[...e],previousCheckpoint:void 0}:{conversation:e.slice(2),previousCheckpoint:assistantMessageText(n)}}function keepNonToolResultMessages(e){let t=[];for(let n of e)if(n.role!==`tool`){if(n.role===`assistant`){let e=assistantMessageText(n);e.length>0&&t.push({content:e,role:`assistant`});continue}t.push(n)}return t}function assistantMessageText(e){return typeof e.content==`string`?e.content.trim():e.content.filter(e=>e.type===`text`).map(e=>e.text).join(``).trim()}function selectRecentWindowSize(e,t){let n=Math.min(t.recentWindowSize,Math.max(e.length-1,0)),r=resolveCompactionSummaryReserve(t),i=0,a=0;for(let o=e.length-1;o>=0&&i<n;--o){let n=e[o];if(n===void 0)continue;let s=estimateTokens([n]);if(a+s+r>t.threshold)break;a+=s,i+=1}return i}function resolveCompactionSummaryReserve(e){return Math.min(2048,Math.max(64,Math.floor(e.threshold/4)))}function splitMessagesForCompaction(e,t){if(t<=0)return{older:[...e],recent:[]};let n=e.length-t;for(;n<e.length&&e[n]?.role===`tool`;)n+=1;return{older:e.slice(0,n),recent:e.slice(n)}}export{compactMessages,getInputTokenCount,shouldCompact};
|
|
@@ -26,6 +26,13 @@ export declare function createCompactionPrompt(input: {
|
|
|
26
26
|
readonly transcriptBudgetTokens?: number;
|
|
27
27
|
}): CompactionPrompt;
|
|
28
28
|
export declare const TRANSCRIPT_PAYLOAD_LIMIT = 2000;
|
|
29
|
+
/**
|
|
30
|
+
* The text a tool-result output is measured and clipped by, in history
|
|
31
|
+
* capping and in the summarizer transcript alike: a text output is its
|
|
32
|
+
* value, any other output its JSON. Sharing it keeps a capped history
|
|
33
|
+
* result whole when the summarizer renders it.
|
|
34
|
+
*/
|
|
35
|
+
export declare function serializeToolResultOutput(output: unknown): string;
|
|
29
36
|
/**
|
|
30
37
|
* Replaces the file parts of a `content` tool output with their text stubs,
|
|
31
38
|
* leaving every other output shape untouched. History capping uses this so a
|
|
@@ -23,4 +23,4 @@ Make completed work explicit so the next model does not repeat it. Keep complete
|
|
|
23
23
|
Large tool outputs are the main thing to compress: reduce each to the findings the next model needs — what was searched or read, what it established, and the exact identifiers involved — rather than reproducing the output. The next model cannot see the originals, so nothing it would need to act on may be lost.`}function formatCompactionTranscript(e){let t=e.filter(e=>e.content.trim().length>0).map(e=>`### ${e.role}\n${e.content.trim()}`);return t.length===0?`(empty)`:t.join(`
|
|
24
24
|
|
|
25
25
|
`)}function renderCompactionMessageContent(e,t){return typeof e.content==`string`?renderConversationText(e.content,t):e.content.map(e=>renderCompactionContentPart(e,t)).filter(e=>e.length>0).join(`
|
|
26
|
-
`).trim()}function renderCompactionContentPart(e,t){switch(e.type){case`text`:return renderConversationText(e.text,t);case`reasoning`:return``;case`file`:return renderAttachedFileStub(e.filename,e.mediaType);case`tool-call`:return renderTranscriptToolCall(e,t);case`tool-result`:return renderTranscriptToolResult(e,t);default:return``}}const TRANSCRIPT_PAYLOAD_LIMIT=2e3;function renderTranscriptToolCall(e,t){return renderToolCall(e,t===void 0?TRANSCRIPT_PAYLOAD_LIMIT:280)}function renderTranscriptToolResult(e,t){let n=t===void 0?TRANSCRIPT_PAYLOAD_LIMIT:280,r=e.isError?`errored`:`returned`,i=renderToolResultOutput(e.output,n);return i?`Tool ${e.toolName} ${r} ${i}`:`Tool ${e.toolName} ${r}`}function renderToolResultOutput(e,t){let n=contentToolOutputParts(e);return n===void 0?
|
|
26
|
+
`).trim()}function renderCompactionContentPart(e,t){switch(e.type){case`text`:return renderConversationText(e.text,t);case`reasoning`:return``;case`file`:return renderAttachedFileStub(e.filename,e.mediaType);case`tool-call`:return renderTranscriptToolCall(e,t);case`tool-result`:return renderTranscriptToolResult(e,t);default:return``}}const TRANSCRIPT_PAYLOAD_LIMIT=2e3;function renderTranscriptToolCall(e,t){return renderToolCall(e,t===void 0?TRANSCRIPT_PAYLOAD_LIMIT:280)}function renderTranscriptToolResult(e,t){let n=t===void 0?TRANSCRIPT_PAYLOAD_LIMIT:280,r=e.isError?`errored`:`returned`,i=renderToolResultOutput(e.output,n);return i?`Tool ${e.toolName} ${r} ${i}`:`Tool ${e.toolName} ${r}`}function renderToolResultOutput(e,t){let n=contentToolOutputParts(e);return capText(n===void 0?serializeToolResultOutput(e):n.map(e=>renderContentToolOutputPart(e,t)).filter(e=>e.length>0).join(` `),t)}function serializeToolResultOutput(e){if(typeof e==`object`&&e){let t=e;if(t.type===`text`&&typeof t.value==`string`)return t.value}return JSON.stringify(e)??``}function contentToolOutputParts(e){if(typeof e!=`object`||!e)return;let t=e;return t.type===`content`&&Array.isArray(t.value)?t.value:void 0}function stubContentOutputFileParts(e){let t=contentToolOutputParts(e);if(t===void 0)return e;let n=!1,r=t.map(e=>{if(typeof e!=`object`||!e)return e;let t=e;return t.type!==`file`&&t.type!==`media`?e:(n=!0,{text:renderAttachedFileStub(contentFileName(e),typeof t.mediaType==`string`?t.mediaType:`unknown`),type:`text`})});return n?{type:`content`,value:r}:e}function renderContentToolOutputPart(e,t){if(typeof e!=`object`||!e)return renderPayload(e,t);let n=e;return n.type===`text`&&typeof n.text==`string`?n.text:n.type===`file`||n.type===`media`?renderAttachedFileStub(contentFileName(e),typeof n.mediaType==`string`?n.mediaType:`unknown`):renderPayload(e,t)}function contentFileName(e){let{data:t,filename:n}=e,r=t;return r?.type===`url`&&isSandboxRefUrl(r.url)?decodeSandboxRef(r.url).path:typeof n==`string`?n:void 0}function renderToolCall(e,t){let n=renderPayload(e.input,t);return n?`Called ${e.toolName} with ${n}`:`Called ${e.toolName}`}function renderPayload(e,t){return e===void 0?``:capText(JSON.stringify(e)??``,t)}function renderAttachedFileStub(e,t){return`Attached file ${e??`attachment`} (${t})`}function renderConversationText(e,t){return t===void 0?e.trim():capText(e,t)}function sliceUtf16Safe(e,t){if(t<=0)return``;if(e.length<=t)return e;let n=t,r=e.charCodeAt(n-1);return r>=55296&&r<=56319&&--n,e.slice(0,n)}function capText(e,t){let n=e.replace(/\s+/g,` `).trim();return n.length<=t?n:`${sliceUtf16Safe(n,t).trimEnd()}…`}export{COMPACTION_CHECKPOINT_MARKER,COMPACTION_PROMPT_ENVELOPE,COMPACTION_RESUMPTION_MESSAGE,TRANSCRIPT_PAYLOAD_LIMIT,createCompactionPrompt,serializeToolResultOutput,sliceUtf16Safe,stubContentOutputFileParts};
|