eve 0.70.0 → 0.70.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 +37 -0
- package/dist/src/channel/adapter.js +1 -1
- package/dist/src/channel/channel-operations.js +1 -1
- package/dist/src/channel/resolve-text.d.ts +8 -0
- package/dist/src/channel/resolve-text.js +2 -1
- package/dist/src/cli/banner.d.ts +2 -2
- package/dist/src/cli/banner.js +1 -1
- package/dist/src/cli/commands/init-agent-workspace.js +1 -1
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/dev/tui/prompt-commands.d.ts +7 -7
- package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +4 -3
- package/dist/src/cli/dev/tui/runner.js +2 -2
- package/dist/src/cli/dev/tui/task-activity.d.ts +0 -17
- package/dist/src/cli/dev/tui/task-activity.js +1 -1
- package/dist/src/cli/dev/tui/task-records.d.ts +17 -0
- package/dist/src/cli/dev/tui/task-records.js +1 -0
- package/dist/src/cli/dev/tui/terminal-renderer.js +2 -2
- package/dist/src/cli/dev/tui/test/mock-terminal.d.ts +7 -1
- package/dist/src/cli/dev/tui/test/mock-terminal.js +4 -3
- package/dist/src/cli/dev/tui/theme.d.ts +1 -1
- package/dist/src/cli/dev/tui/theme.js +1 -1
- package/dist/src/cli/dev/tui/tool-presentation.d.ts +15 -2
- package/dist/src/cli/dev/tui/tool-presentation.js +1 -1
- package/dist/src/cli/dev/tui/transcript-parts.d.ts +10 -2
- package/dist/src/cli/dev/tui/transcript-parts.js +2 -2
- package/dist/src/cli/dev/tui/transcript.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +8 -8
- package/dist/src/compiled/@photon-ai/chat-adapter-imessage/index.js +1 -1
- package/dist/src/compiled/@vercel/sandbox/index.js +1 -1
- package/dist/src/compiled/@workflow/core/index.js +2 -2
- package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +15 -0
- package/dist/src/compiled/@workflow/core/runtime/dynamic-workflow.d.ts +182 -0
- package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +7 -0
- package/dist/src/compiled/@workflow/core/runtime/helpers.js +1 -1
- package/dist/src/compiled/@workflow/core/runtime/quickjs-assets.generated.d.ts +7 -0
- package/dist/src/compiled/@workflow/core/runtime/quickjs-entrypoint.d.ts +2 -30
- package/dist/src/compiled/@workflow/core/runtime/quickjs-log-view.d.ts +27 -4
- package/dist/src/compiled/@workflow/core/runtime/quickjs-runtime.d.ts +55 -3
- package/dist/src/compiled/@workflow/core/runtime/quickjs-snapshot-codec.d.ts +74 -0
- package/dist/src/compiled/@workflow/core/runtime/start.d.ts +4 -0
- package/dist/src/compiled/@workflow/core/runtime/vm-mode.d.ts +44 -0
- package/dist/src/compiled/@workflow/core/runtime.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/runtime.js +4 -4
- package/dist/src/compiled/@workflow/core/schemas.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/serialization/compression.d.ts +27 -2
- package/dist/src/compiled/@workflow/core/serialization/hardened.d.ts +8 -0
- package/dist/src/compiled/@workflow/core/serialization/types.d.ts +1 -0
- package/dist/src/compiled/@workflow/core/serialization.d.ts +48 -0
- package/dist/src/compiled/@workflow/core/serialization.js +1 -1
- package/dist/src/compiled/@workflow/core/set-error-stack.d.ts +12 -0
- package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +47 -0
- package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/world/events.d.ts +10 -0
- package/dist/src/compiled/@workflow/world/index.d.ts +2 -0
- package/dist/src/compiled/@workflow/world/interfaces.d.ts +127 -0
- package/dist/src/compiled/@workflow/world/queue.d.ts +6 -0
- package/dist/src/compiled/@workflow/world/runs.d.ts +9 -2
- package/dist/src/compiled/@workflow/world/snapshots.d.ts +60 -0
- package/dist/src/compiled/@workflow/world-local/index.js +5 -5
- package/dist/src/compiled/@workflow/world-vercel/index.js +19 -17
- package/dist/src/compiled/_chunks/node/undici-B61sz6UT.js +95 -0
- package/dist/src/compiled/_chunks/workflow/{attribute-changes-D721NpZv.js → attribute-changes-VaTKT4K8.js} +3 -3
- package/dist/src/compiled/_chunks/workflow/dist-B7NC1c9-.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{functions-DpZiBxgQ.js → functions-CKkqf9V6.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/helpers-CP9TjeO8.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{logger-D4GJNTk4.js → logger-oqfblE3p.js} +2 -2
- package/dist/src/compiled/_chunks/workflow/resume-hook-yq-NAdBu.js +1 -0
- package/dist/src/compiled/_chunks/workflow/run-DYKeqbob.js +32 -0
- package/dist/src/compiled/_chunks/workflow/serialization-APSKphN5.js +3 -0
- package/dist/src/compiled/_chunks/workflow/signal-exit-iIdjQcCK.js +95 -0
- package/dist/src/compiled/_chunks/workflow/sleep-Ba8SExMt.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{token-BhlnqoHM.js → token-BKeK6DmC.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/token-Cv2GYj9A.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{token-util-DaeRTzDa.js → token-util-CddTZ_ef.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{wait-until-3_1djUuL.js → wait-until-Dc9s3yyP.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{wrapper-CzrF_dmI.js → wrapper-Dq4OeGmJ.js} +4 -4
- package/dist/src/compiled/{gray-matter → js-yaml}/LICENSE +2 -2
- package/dist/src/compiled/js-yaml/index.d.ts +12 -0
- package/dist/src/compiled/js-yaml/index.js +34 -0
- package/dist/src/compiled/shadcn-registry/index.js +4 -4
- package/dist/src/context/serialize.d.ts +5 -1
- package/dist/src/context/serialize.js +1 -1
- package/dist/src/discover/discover-agent.js +1 -1
- package/dist/src/discover/extension-specifier.d.ts +1 -0
- package/dist/src/discover/extension-specifier.js +1 -1
- package/dist/src/discover/extensions.d.ts +1 -1
- package/dist/src/discover/extensions.js +1 -1
- package/dist/src/discover/project-source.d.ts +5 -0
- package/dist/src/discover/project-source.js +1 -1
- package/dist/src/evals/loaders/yaml.js +1 -1
- package/dist/src/evals/session.d.ts +1 -0
- package/dist/src/evals/session.js +1 -1
- package/dist/src/evals/types.d.ts +6 -0
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/legacy-remote-agent/protocol.d.ts +8 -0
- package/dist/src/execution/legacy-remote-agent/protocol.js +1 -1
- package/dist/src/execution/legacy-session/turn-workflow.js +1 -1
- package/dist/src/execution/proxied-deliver-step.d.ts +11 -0
- package/dist/src/execution/proxied-deliver-step.js +1 -1
- package/dist/src/execution/sandbox/read-file.d.ts +8 -1
- package/dist/src/execution/sandbox/read-file.js +3 -3
- package/dist/src/execution/session/active-turn.d.ts +4 -1
- package/dist/src/execution/session/active-turn.js +1 -1
- package/dist/src/execution/session/checkpoint-migrations.d.ts +23 -0
- package/dist/src/execution/session/checkpoint-migrations.js +1 -0
- package/dist/src/execution/session/entry-input.d.ts +23 -5
- package/dist/src/execution/session/entry.js +1 -1
- package/dist/src/execution/session/finalization.js +1 -1
- package/dist/src/execution/session/handoff-steps.d.ts +24 -5
- package/dist/src/execution/session/handoff-steps.js +1 -1
- package/dist/src/execution/session/handoff.d.ts +40 -16
- package/dist/src/execution/session/handoff.js +1 -1
- package/dist/src/execution/session/pending-turn-state.d.ts +2 -0
- package/dist/src/execution/session/pending-turn-state.js +1 -1
- package/dist/src/execution/session/program.d.ts +16 -3
- package/dist/src/execution/session/program.js +1 -1
- package/dist/src/execution/session/turn-step-result.js +1 -1
- package/dist/src/execution/session/turn-step-types.d.ts +13 -1
- package/dist/src/execution/session/turn-step.js +1 -1
- package/dist/src/execution/session/turn.d.ts +14 -2
- package/dist/src/execution/session/turn.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/workflow-runtime.d.ts +4 -4
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/harness/attachment-staging.d.ts +27 -7
- package/dist/src/harness/attachment-staging.js +1 -1
- package/dist/src/harness/compaction-prompt.js +2 -2
- package/dist/src/harness/input-requests.js +1 -1
- package/dist/src/harness/messages.js +1 -1
- package/dist/src/harness/token-estimate.d.ts +5 -3
- package/dist/src/harness/token-estimate.js +1 -1
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/attachments/media-metadata.d.ts +25 -0
- package/dist/src/internal/attachments/media-metadata.js +1 -0
- package/dist/src/internal/attachments/sandbox-refs.d.ts +12 -7
- package/dist/src/internal/attachments/sandbox-refs.js +1 -1
- package/dist/src/internal/authored-module-loader.js +1 -1
- package/dist/src/internal/bundler/extension-mount-plugin.d.ts +4 -0
- package/dist/src/internal/bundler/extension-mount-plugin.js +1 -1
- package/dist/src/internal/bundler/extension-scope-plugin.js +2 -2
- package/dist/src/internal/helpers/frontmatter.d.ts +24 -0
- package/dist/src/internal/helpers/frontmatter.js +1 -0
- package/dist/src/internal/helpers/markdown.js +1 -3
- package/dist/src/internal/input-text.d.ts +12 -0
- package/dist/src/internal/input-text.js +1 -0
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/nitro/host/nitro-bundler-config.js +1 -1
- package/dist/src/internal/node-esm-compat-banner.js +1 -1
- package/dist/src/internal/workflow/vercel-world-defaults.d.ts +1 -1
- package/dist/src/internal/workflow/vercel-world-defaults.js +1 -1
- package/dist/src/public/channels/chat-sdk/input-actions.d.ts +8 -2
- package/dist/src/public/channels/chat-sdk/input-actions.js +4 -1
- package/dist/src/public/channels/github/defaults.js +2 -3
- package/dist/src/public/channels/linear/hitl.js +2 -3
- package/dist/src/public/channels/slack/action-status.d.ts +10 -5
- package/dist/src/public/channels/slack/action-status.js +1 -1
- package/dist/src/public/channels/slack/defaults.js +3 -3
- package/dist/src/public/channels/slack/limits.d.ts +1 -1
- package/dist/src/public/channels/slack/limits.js +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +11 -9
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/slack/task-card.js +1 -1
- package/dist/src/public/channels/slack/thread-status.d.ts +33 -0
- package/dist/src/public/channels/slack/thread-status.js +1 -0
- package/dist/src/public/channels/twilio/defaults.js +4 -2
- package/dist/src/public/definitions/state.d.ts +2 -0
- package/dist/src/public/definitions/state.js +1 -1
- package/dist/src/runtime/connections/openapi-spec.d.ts +1 -4
- package/dist/src/runtime/connections/openapi-spec.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +4 -4
- package/dist/src/setup/scaffold/create/web-template.js +33 -26
- package/dist/src/subagents/callback-route.js +1 -1
- package/dist/src/subagents/hitl-proxy.d.ts +2 -2
- package/dist/src/subagents/hitl-proxy.js +1 -1
- package/dist/src/subagents/parent-notification.d.ts +7 -7
- package/dist/src/subagents/parent-notification.js +1 -1
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/read-file.d.ts +7 -0
- package/dist/src/tools/provided/read-file.js +2 -2
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/docs/agent-config.md +2 -2
- package/docs/channels/chat-sdk.mdx +1 -1
- package/docs/channels/slack.mdx +21 -15
- package/docs/channels/twilio.mdx +1 -1
- package/docs/concepts/built-in-tools.md +1 -1
- package/docs/concepts/default-harness.md +4 -0
- package/docs/concepts/execution-model-and-durability.mdx +9 -1
- package/docs/concepts/sessions-runs-and-streaming.md +3 -3
- package/docs/evals/cases.mdx +1 -0
- package/docs/extensions.md +6 -3
- package/docs/guides/dev-tui.md +5 -3
- package/docs/guides/dynamic-capabilities.md +1 -1
- package/docs/sandbox/index.mdx +11 -0
- package/docs/tools/overview.mdx +4 -2
- package/package.json +8 -8
- package/dist/src/compiled/_chunks/node/undici-h5GH4RBM.js +0 -95
- package/dist/src/compiled/_chunks/workflow/debug-log-CVPstO1D.js +0 -1
- package/dist/src/compiled/_chunks/workflow/dist-BUFGAKRb.js +0 -1
- package/dist/src/compiled/_chunks/workflow/frames-Dr9fHWdo.js +0 -3
- package/dist/src/compiled/_chunks/workflow/helpers-DkKxg_yn.js +0 -1
- package/dist/src/compiled/_chunks/workflow/resume-hook-uTW-jBYz.js +0 -1
- package/dist/src/compiled/_chunks/workflow/run-5DmiMN9b.js +0 -1
- package/dist/src/compiled/_chunks/workflow/serialization-CNIYl1D3.js +0 -3
- package/dist/src/compiled/_chunks/workflow/signal-exit-DZKTacNU.js +0 -95
- package/dist/src/compiled/_chunks/workflow/sleep-DFKgN7UG.js +0 -1
- package/dist/src/compiled/_chunks/workflow/token-1wSBbi5N.js +0 -1
- package/dist/src/compiled/_chunks/workflow/token-util-Cm4Ec1Bg.js +0 -1
- package/dist/src/compiled/_chunks/workflow/ws-transport--rYOVIaf.js +0 -1
- package/dist/src/compiled/gray-matter/index.d.ts +0 -62
- package/dist/src/compiled/gray-matter/index.js +0 -48
- package/dist/src/internal/helpers/gray-matter.d.ts +0 -25
- package/dist/src/internal/helpers/gray-matter.js +0 -1
|
@@ -12,4 +12,8 @@ export declare function serializeContext(ctx: AlsContext): Record<string, unknow
|
|
|
12
12
|
* Each entry is matched to a registered {@link ContextKey} by name.
|
|
13
13
|
* Unknown entries (no registered key) are dropped with a warning.
|
|
14
14
|
*/
|
|
15
|
-
export declare function deserializeContext(
|
|
15
|
+
export declare function deserializeContext(serialized: Record<string, unknown>): Promise<ContextContainer>;
|
|
16
|
+
/** A context whose saved state this deployment cannot place; retrying never changes the answer. */
|
|
17
|
+
export declare class IncompatibleStateLayoutError extends Error {
|
|
18
|
+
constructor(key?: string);
|
|
19
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{ContextContainer}from"#context/container.js";import{resolveKey}from"#context/key.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{loadCompiledManifest}from"#runtime/loaders/manifest.js";const log=createLogger(`context.serialize`),STATE_LAYOUT_KEY=`eve.stateLayout`;function serializeContext(e){let t={};for(let[n,r]of e.entries())try{t[n.name]=n.codec?n.codec.serialize(r):r}catch(e){throw logError(log,`failed to serialize context key`,e,{key:n.name}),e}return(t[BundleKey.name]!==void 0||Object.keys(t).some(e=>e.startsWith(`eve:mount.`)))&&(t[STATE_LAYOUT_KEY]=1),t}async function deserializeContext(e){let t=new ContextContainer,
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{ContextContainer}from"#context/container.js";import{resolveKey}from"#context/key.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{loadCompiledManifest}from"#runtime/loaders/manifest.js";import{mountedStateKeyName}from"#public/definitions/state.js";const log=createLogger(`context.serialize`),STATE_LAYOUT_KEY=`eve.stateLayout`;function serializeContext(e){let t={};for(let[n,r]of e.entries())try{t[n.name]=n.codec?n.codec.serialize(r):r}catch(e){throw logError(log,`failed to serialize context key`,e,{key:n.name}),e}return(t[BundleKey.name]!==void 0||Object.keys(t).some(e=>e.startsWith(`eve:mount.`)))&&(t[STATE_LAYOUT_KEY]=1),t}async function deserializeContext(e){let t=e,n=new ContextContainer,r=t[BundleKey.name];if(t[STATE_LAYOUT_KEY]!==void 0&&t[STATE_LAYOUT_KEY]!==1||t[STATE_LAYOUT_KEY]===void 0&&Object.keys(t).some(e=>t[e]!==void 0&&e.startsWith(`eve:mount.`)))throw new IncompatibleStateLayoutError;if(r!==void 0){let e=BundleKey.codec;if(e===void 0)throw Error(`Context key "eve.bundle" is missing a codec.`);let i=await e.deserialize(r,n);t[STATE_LAYOUT_KEY]===void 0&&(t=await adoptLegacyStateLayout(t,i)),n.set(BundleKey,i)}for(let[e,r]of Object.entries(t)){if(r===void 0||e===BundleKey.name||e===STATE_LAYOUT_KEY)continue;let t=resolveKey(e);if(t===void 0){log.warn(`dropping unknown context key during deserialization`,{key:e});continue}try{n.set(t,t.codec?await t.codec.deserialize(r,n):r)}catch(t){throw logError(log,`failed to deserialize context key`,t,{key:e}),t}}return n}async function adoptLegacyStateLayout(e,t){let n=await loadCompiledManifest({compiledArtifactsSource:t.compiledArtifactsSource}),r=[n,...n.subagents.map(e=>e.agent)].flatMap(e=>e.extensionMounts),i={};for(let[t,n]of Object.entries(e)){if(n===void 0)continue;if(t===BundleKey.name||resolveKey(t)!==void 0){i[t]=n;continue}let e=r.flatMap(e=>{let n=`${legacyPackageStateNamespace(e.packageName)}.`;if(!t.startsWith(n))return[];let r=mountedStateKeyName(e.mountId,t.slice(n.length));return resolveKey(r)===void 0?[]:[r]});if(e.length>1||e.length===0&&t.startsWith(`eve.`))throw new IncompatibleStateLayoutError(t);i[e[0]??t]=n}return i}function legacyPackageStateNamespace(e){return e.replace(/^@/,``).replace(/[^a-zA-Z0-9._-]+/g,`-`).replace(/^-+|-+$/g,``)||`extension`}var IncompatibleStateLayoutError=class extends Error{constructor(e){super(`Incompatible context state layout${e===void 0?``:` for key "${e}"`}. This deployment cannot read the saved state. Continue this session on its original deployment or start a new session.`),this.name=`IncompatibleStateLayoutError`}};export{IncompatibleStateLayoutError,deserializeContext,serializeContext};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{join,resolve}from"node:path";import{classifyAgentRootEntry,normalizeLogicalPath}from"#discover/filesystem.js";import{createDiskProjectSource}from"#discover/project-source.js";import{DISCOVER_EXTENSION_AGENT_CONFIG_UNSUPPORTED,DISCOVER_EXTENSION_INSTRUMENTATION_UNSUPPORTED,DISCOVER_EXTENSION_MEMORY_UNSUPPORTED,DISCOVER_EXTENSION_MOUNT_AMBIGUOUS,DISCOVER_EXTENSION_MOUNT_MISSING_DECLARATION,DISCOVER_EXTENSION_NESTED_MOUNT_UNSUPPORTED,DISCOVER_EXTENSION_SANDBOX_UNSUPPORTED,locateExtensionMount,mountNamespace}from"#discover/extensions.js";import{createDiscoverErrorDiagnostic}from"#discover/diagnostics.js";import{DISCOVER_CHANNELS_DIRECTORY_INVALID,DISCOVER_EXTENSIONS_DIRECTORY_INVALID,DISCOVER_HOOKS_DIRECTORY_INVALID,DISCOVER_TOOLS_DIRECTORY_INVALID,createChannelNameDiagnostic,createExtensionNameDiagnostic,createHookNameDiagnostic,createToolNameDiagnostic,createUnsupportedRootDirectoryDiagnostics,discoverFlatModuleSource,discoverInstructionsSource,discoverNamedSourceDirectory,readSortedDirectoryEntries}from"#discover/grammar.js";import{createAgentSourceManifest,createModuleSourceRef}from"#discover/manifest.js";import{discoverConnectionSources}from"#discover/connections.js";import{discoverSubagents}from"#discover/discover-subagent.js";import{discoverLibSources}from"#discover/lib.js";import{discoverMemorySources}from"#discover/memory.js";import{discoverSandboxSource}from"#discover/sandbox.js";import{discoverScheduleSources}from"#discover/schedules.js";import{discoverSkills}from"#discover/skills.js";import{stripNpmPackageScope}from"#shared/package-name.js";async function discoverAgent(e){let t=e.source??createDiskProjectSource(),n=resolve(e.appRoot),r=resolve(e.agentRoot),i=e.role??`agent`,a=[],o=await tryReadPackageJsonName(t,n),s=await readSortedDirectoryEntries(t,r);a.push(...createUnsupportedRootDirectoryDiagnostics({classifyEntry:classifyAgentRootEntry,createUnsupportedDirectoryMessage(e){return`Ignoring unsupported directory "${e}/" in the agent root.`},rootEntries:s,rootPath:r}));let c=await discoverInstructionsSource({rootEntries:s,rootPath:r,source:t,required:i!==`extension`});a.push(...c.diagnostics);let l=discoverFlatModuleSource({rootEntries:s,rootPath:r,slotName:`agent`});a.push(...l.diagnostics);let u=await discoverNamedSourceDirectory({directoryName:`channels`,invalidDirectoryCode:DISCOVER_CHANNELS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(r,`channels`)}" to be a directory of authored channels.`,recursive:!0,rootEntries:s,rootPath:r,source:t,validateSegment:createChannelNameDiagnostic});a.push(...u.diagnostics);let d=await discoverLibSources({agentRoot:r,rootEntries:s,source:t});a.push(...d.diagnostics);let f=await discoverScheduleSources({agentRoot:r,rootEntries:s,source:t});a.push(...f.diagnostics);let p=await discoverConnectionSources({rootEntries:s,rootPath:r,source:t});a.push(...p.diagnostics);let m=await discoverMemorySources({rootEntries:s,rootPath:r,source:t});a.push(...m.diagnostics);let h=await discoverSandboxSource({rootEntries:s,rootPath:r,source:t});if(a.push(...h.diagnostics),i===`extension`){l.module!==void 0&&a.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_AGENT_CONFIG_UNSUPPORTED,message:`An extension may not declare agent config (agent.ts) — model, limits, and sandbox are the consuming agent's to own.`,sourcePath:join(r,l.module.logicalPath)}));let e=s.find(e=>e.name===`instrumentation`&&e.isDirectory());e!==void 0&&a.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_INSTRUMENTATION_UNSUPPORTED,message:`An extension may not declare instrumentation providers — process-wide observability belongs to the consuming agent.`,sourcePath:join(r,e.name)}));let[t]=m.memories;t!==void 0&&a.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MEMORY_UNSUPPORTED,message:`An extension may not declare memory — scope and lifecycle state belong to the consuming application.`,sourcePath:join(r,t.logicalPath)})),h.sandbox!==null&&a.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_SANDBOX_UNSUPPORTED,message:`An extension may not declare a sandbox — it is the consuming agent's to own.`,sourcePath:join(r,h.sandbox.logicalPath)}))}let g=await discoverNamedSourceDirectory({directoryName:`tools`,invalidDirectoryCode:DISCOVER_TOOLS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(r,`tools`)}" to be a directory of authored tools.`,recursive:!0,rootEntries:s,rootPath:r,source:t,validateSegment:createToolNameDiagnostic});a.push(...g.diagnostics);let _=await discoverNamedSourceDirectory({directoryName:`hooks`,invalidDirectoryCode:DISCOVER_HOOKS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(r,`hooks`)}" to be a directory of authored hooks.`,recursive:!0,rootEntries:s,rootPath:r,source:t,validateSegment:createHookNameDiagnostic});a.push(..._.diagnostics);let v=await discoverNamedSourceDirectory({directoryName:`extensions`,invalidDirectoryCode:DISCOVER_EXTENSIONS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(r,`extensions`)}" to be a directory of extension mounts.`,recursive:!1,rootEntries:s,rootPath:r,source:t,validateSegment:createExtensionNameDiagnostic});a.push(...v.diagnostics);let y=await discoverSkills({agentRoot:r,source:t});a.push(...y.diagnostics);let b=await discoverSubagents({agentRoot:r,appRoot:n,source:t});a.push(...b.diagnostics);let x=await collectExtensionMounts({agentRoot:r,fileMounts:v.sources,rootEntries:s,source:t});a.push(...x.diagnostics);let S=[];if(i!==`agent`)for(let e of x.mounts)a.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_NESTED_MOUNT_UNSUPPORTED,message:`"${e.mountRef.logicalPath}" mounts an extension from inside an extension, which is not supported yet. Extensions cannot mount other extensions; remove the "extensions/" slot.`,sourcePath:join(r,e.mountRef.logicalPath)}));else{let e=await resolveExtensionMounts({agentRoot:r,appRoot:n,mounts:x.mounts,source:t});a.push(...e.diagnostics),S=e.mounts}let C={agentRoot:r,appRoot:n,channels:u.sources,connections:p.connections,packageName:o,diagnostics:a,extensions:i===`extension`?[]:x.mounts.map(e=>e.mountRef),resolvedExtensions:S,hooks:_.sources,memories:i===`extension`?[]:m.memories,lib:d.lib,instructions:c.instructions,sandbox:i===`extension`?null:h.sandbox,sandboxWorkspaces:i===`extension`||h.sandboxWorkspace===null?[]:[h.sandboxWorkspace],schedules:f.schedules,skills:y.skills,tools:g.sources,subagents:b.subagents};return i!==`extension`&&l.module!==void 0&&(C.configModule=l.module),{diagnostics:a,manifest:createAgentSourceManifest(C)}}async function resolveExtensionMounts(e){let t=[],n=[];for(let r of e.mounts){let i=await locateExtensionMount({source:e.source,agentRoot:e.agentRoot,appRoot:e.appRoot,mount:r.mountRef,namespace:r.namespace});if(t.push(...i.diagnostics),i.location===void 0)continue;let a=await discoverAgent({agentRoot:i.location.sourceRoot,appRoot:i.location.packageRoot,source:e.source,role:`extension`});t.push(...a.diagnostics);let o;if(r.overridesRoot!==void 0){let n=await discoverAgent({agentRoot:r.overridesRoot,appRoot:e.appRoot,source:e.source,role:`extension`});t.push(...n.diagnostics),o=n.manifest}n.push({namespace:i.location.namespace,specifier:i.location.specifier,packageName:i.location.packageName,packageRoot:i.location.packageRoot,sourceRoot:i.location.sourceRoot,manifest:a.manifest,externalDependencies:i.location.externalDependencies,overrides:o})}return{diagnostics:t,mounts:n}}async function discoverExtensionMountDeclarations(e){let t=e.source??createDiskProjectSource(),n=resolve(e.agentRoot),r=await readSortedDirectoryEntries(t,n),i=await discoverNamedSourceDirectory({directoryName:`extensions`,invalidDirectoryCode:DISCOVER_EXTENSIONS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(n,`extensions`)}" to be a directory of extension mounts.`,recursive:!1,rootEntries:r,rootPath:n,source:t,validateSegment:createExtensionNameDiagnostic}),a=await collectExtensionMounts({agentRoot:n,fileMounts:i.sources,rootEntries:r,source:t});return{diagnostics:[...i.diagnostics,...a.diagnostics],mounts:a.mounts}}async function collectExtensionMounts(e){let t=[],n=join(e.agentRoot,`extensions`),r=e.fileMounts.map(e=>({namespace:mountNamespace(e.logicalPath),mountRef:e})),i=new Set(r.map(e=>e.namespace)),a=e.rootEntries.find(e=>e.name===`extensions`),o=[],s=new Set;if(a?.isDirectory()===!0){let r=await readSortedDirectoryEntries(e.source,n);for(let a of r){if(!a.isDirectory())continue;let r=a.name,c=join(n,r),l=createExtensionNameDiagnostic(r,c);if(l!==null){t.push(l);continue}let u=discoverFlatModuleSource({rootEntries:await readSortedDirectoryEntries(e.source,c),rootPath:c,slotName:`extension`});if(t.push(...u.diagnostics),u.module===void 0){t.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_MISSING_DECLARATION,message:`Extension mount directory "extensions/${r}/" must declare its mount in "extension.ts" (or another supported module extension).`,sourcePath:c}));continue}i.has(r)&&s.add(r),o.push({namespace:r,mountRef:createModuleSourceRef({logicalPath:normalizeLogicalPath(join(`extensions`,r,u.module.logicalPath))}),overridesRoot:c})}}for(let e of s)t.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_AMBIGUOUS,message:`Extension namespace "${e}" is claimed by both a file mount ("extensions/${e}.ts") and a directory mount ("extensions/${e}/"). Keep only one.`,sourcePath:n}));return{diagnostics:t,mounts:[...r,...o].filter(e=>!s.has(e.namespace))}}async function tryReadPackageJsonName(e,t){
|
|
1
|
+
import{join,resolve}from"node:path";import{classifyAgentRootEntry,normalizeLogicalPath}from"#discover/filesystem.js";import{createDiskProjectSource,readPackageJsonName}from"#discover/project-source.js";import{DISCOVER_EXTENSION_AGENT_CONFIG_UNSUPPORTED,DISCOVER_EXTENSION_INSTRUMENTATION_UNSUPPORTED,DISCOVER_EXTENSION_MEMORY_UNSUPPORTED,DISCOVER_EXTENSION_MOUNT_AMBIGUOUS,DISCOVER_EXTENSION_MOUNT_MISSING_DECLARATION,DISCOVER_EXTENSION_NESTED_MOUNT_UNSUPPORTED,DISCOVER_EXTENSION_SANDBOX_UNSUPPORTED,locateExtensionMount,mountNamespace}from"#discover/extensions.js";import{createDiscoverErrorDiagnostic}from"#discover/diagnostics.js";import{DISCOVER_CHANNELS_DIRECTORY_INVALID,DISCOVER_EXTENSIONS_DIRECTORY_INVALID,DISCOVER_HOOKS_DIRECTORY_INVALID,DISCOVER_TOOLS_DIRECTORY_INVALID,createChannelNameDiagnostic,createExtensionNameDiagnostic,createHookNameDiagnostic,createToolNameDiagnostic,createUnsupportedRootDirectoryDiagnostics,discoverFlatModuleSource,discoverInstructionsSource,discoverNamedSourceDirectory,readSortedDirectoryEntries}from"#discover/grammar.js";import{createAgentSourceManifest,createModuleSourceRef}from"#discover/manifest.js";import{discoverConnectionSources}from"#discover/connections.js";import{discoverSubagents}from"#discover/discover-subagent.js";import{discoverLibSources}from"#discover/lib.js";import{discoverMemorySources}from"#discover/memory.js";import{discoverSandboxSource}from"#discover/sandbox.js";import{discoverScheduleSources}from"#discover/schedules.js";import{discoverSkills}from"#discover/skills.js";import{stripNpmPackageScope}from"#shared/package-name.js";async function discoverAgent(e){let t=e.source??createDiskProjectSource(),n=resolve(e.appRoot),r=resolve(e.agentRoot),i=e.role??`agent`,a=[],o=await tryReadPackageJsonName(t,n),s=await readSortedDirectoryEntries(t,r);a.push(...createUnsupportedRootDirectoryDiagnostics({classifyEntry:classifyAgentRootEntry,createUnsupportedDirectoryMessage(e){return`Ignoring unsupported directory "${e}/" in the agent root.`},rootEntries:s,rootPath:r}));let c=await discoverInstructionsSource({rootEntries:s,rootPath:r,source:t,required:i!==`extension`});a.push(...c.diagnostics);let l=discoverFlatModuleSource({rootEntries:s,rootPath:r,slotName:`agent`});a.push(...l.diagnostics);let u=await discoverNamedSourceDirectory({directoryName:`channels`,invalidDirectoryCode:DISCOVER_CHANNELS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(r,`channels`)}" to be a directory of authored channels.`,recursive:!0,rootEntries:s,rootPath:r,source:t,validateSegment:createChannelNameDiagnostic});a.push(...u.diagnostics);let d=await discoverLibSources({agentRoot:r,rootEntries:s,source:t});a.push(...d.diagnostics);let f=await discoverScheduleSources({agentRoot:r,rootEntries:s,source:t});a.push(...f.diagnostics);let p=await discoverConnectionSources({rootEntries:s,rootPath:r,source:t});a.push(...p.diagnostics);let m=await discoverMemorySources({rootEntries:s,rootPath:r,source:t});a.push(...m.diagnostics);let h=await discoverSandboxSource({rootEntries:s,rootPath:r,source:t});if(a.push(...h.diagnostics),i===`extension`){l.module!==void 0&&a.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_AGENT_CONFIG_UNSUPPORTED,message:`An extension may not declare agent config (agent.ts) — model, limits, and sandbox are the consuming agent's to own.`,sourcePath:join(r,l.module.logicalPath)}));let e=s.find(e=>e.name===`instrumentation`&&e.isDirectory());e!==void 0&&a.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_INSTRUMENTATION_UNSUPPORTED,message:`An extension may not declare instrumentation providers — process-wide observability belongs to the consuming agent.`,sourcePath:join(r,e.name)}));let[t]=m.memories;t!==void 0&&a.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MEMORY_UNSUPPORTED,message:`An extension may not declare memory — scope and lifecycle state belong to the consuming application.`,sourcePath:join(r,t.logicalPath)})),h.sandbox!==null&&a.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_SANDBOX_UNSUPPORTED,message:`An extension may not declare a sandbox — it is the consuming agent's to own.`,sourcePath:join(r,h.sandbox.logicalPath)}))}let g=await discoverNamedSourceDirectory({directoryName:`tools`,invalidDirectoryCode:DISCOVER_TOOLS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(r,`tools`)}" to be a directory of authored tools.`,recursive:!0,rootEntries:s,rootPath:r,source:t,validateSegment:createToolNameDiagnostic});a.push(...g.diagnostics);let _=await discoverNamedSourceDirectory({directoryName:`hooks`,invalidDirectoryCode:DISCOVER_HOOKS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(r,`hooks`)}" to be a directory of authored hooks.`,recursive:!0,rootEntries:s,rootPath:r,source:t,validateSegment:createHookNameDiagnostic});a.push(..._.diagnostics);let v=await discoverNamedSourceDirectory({directoryName:`extensions`,invalidDirectoryCode:DISCOVER_EXTENSIONS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(r,`extensions`)}" to be a directory of extension mounts.`,recursive:!1,rootEntries:s,rootPath:r,source:t,validateSegment:createExtensionNameDiagnostic});a.push(...v.diagnostics);let y=await discoverSkills({agentRoot:r,source:t});a.push(...y.diagnostics);let b=await discoverSubagents({agentRoot:r,appRoot:n,source:t});a.push(...b.diagnostics);let x=await collectExtensionMounts({agentRoot:r,fileMounts:v.sources,rootEntries:s,source:t});a.push(...x.diagnostics);let S=[];if(i!==`agent`)for(let e of x.mounts)a.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_NESTED_MOUNT_UNSUPPORTED,message:`"${e.mountRef.logicalPath}" mounts an extension from inside an extension, which is not supported yet. Extensions cannot mount other extensions; remove the "extensions/" slot.`,sourcePath:join(r,e.mountRef.logicalPath)}));else{let e=await resolveExtensionMounts({agentRoot:r,appRoot:n,mounts:x.mounts,source:t});a.push(...e.diagnostics),S=e.mounts}let C={agentRoot:r,appRoot:n,channels:u.sources,connections:p.connections,packageName:o,diagnostics:a,extensions:i===`extension`?[]:x.mounts.map(e=>e.mountRef),resolvedExtensions:S,hooks:_.sources,memories:i===`extension`?[]:m.memories,lib:d.lib,instructions:c.instructions,sandbox:i===`extension`?null:h.sandbox,sandboxWorkspaces:i===`extension`||h.sandboxWorkspace===null?[]:[h.sandboxWorkspace],schedules:f.schedules,skills:y.skills,tools:g.sources,subagents:b.subagents};return i!==`extension`&&l.module!==void 0&&(C.configModule=l.module),{diagnostics:a,manifest:createAgentSourceManifest(C)}}async function resolveExtensionMounts(e){let t=[],n=[];for(let r of e.mounts){let i=await locateExtensionMount({source:e.source,agentRoot:e.agentRoot,appRoot:e.appRoot,mount:r.mountRef,namespace:r.namespace});if(t.push(...i.diagnostics),i.location===void 0)continue;let a=await discoverAgent({agentRoot:i.location.sourceRoot,appRoot:i.location.packageRoot,source:e.source,role:`extension`});t.push(...a.diagnostics);let o;if(r.overridesRoot!==void 0){let n=await discoverAgent({agentRoot:r.overridesRoot,appRoot:e.appRoot,source:e.source,role:`extension`});t.push(...n.diagnostics),o=n.manifest}n.push({namespace:i.location.namespace,specifier:i.location.specifier,packageName:i.location.packageName,packageRoot:i.location.packageRoot,sourceRoot:i.location.sourceRoot,manifest:a.manifest,externalDependencies:i.location.externalDependencies,overrides:o})}return{diagnostics:t,mounts:n}}async function discoverExtensionMountDeclarations(e){let t=e.source??createDiskProjectSource(),n=resolve(e.agentRoot),r=await readSortedDirectoryEntries(t,n),i=await discoverNamedSourceDirectory({directoryName:`extensions`,invalidDirectoryCode:DISCOVER_EXTENSIONS_DIRECTORY_INVALID,invalidDirectoryMessage:`Expected "${join(n,`extensions`)}" to be a directory of extension mounts.`,recursive:!1,rootEntries:r,rootPath:n,source:t,validateSegment:createExtensionNameDiagnostic}),a=await collectExtensionMounts({agentRoot:n,fileMounts:i.sources,rootEntries:r,source:t});return{diagnostics:[...i.diagnostics,...a.diagnostics],mounts:a.mounts}}async function collectExtensionMounts(e){let t=[],n=join(e.agentRoot,`extensions`),r=e.fileMounts.map(e=>({namespace:mountNamespace(e.logicalPath),mountRef:e})),i=new Set(r.map(e=>e.namespace)),a=e.rootEntries.find(e=>e.name===`extensions`),o=[],s=new Set;if(a?.isDirectory()===!0){let r=await readSortedDirectoryEntries(e.source,n);for(let a of r){if(!a.isDirectory())continue;let r=a.name,c=join(n,r),l=createExtensionNameDiagnostic(r,c);if(l!==null){t.push(l);continue}let u=discoverFlatModuleSource({rootEntries:await readSortedDirectoryEntries(e.source,c),rootPath:c,slotName:`extension`});if(t.push(...u.diagnostics),u.module===void 0){t.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_MISSING_DECLARATION,message:`Extension mount directory "extensions/${r}/" must declare its mount in "extension.ts" (or another supported module extension).`,sourcePath:c}));continue}i.has(r)&&s.add(r),o.push({namespace:r,mountRef:createModuleSourceRef({logicalPath:normalizeLogicalPath(join(`extensions`,r,u.module.logicalPath))}),overridesRoot:c})}}for(let e of s)t.push(createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_AMBIGUOUS,message:`Extension namespace "${e}" is claimed by both a file mount ("extensions/${e}.ts") and a directory mount ("extensions/${e}/"). Keep only one.`,sourcePath:n}));return{diagnostics:t,mounts:[...r,...o].filter(e=>!s.has(e.namespace))}}async function tryReadPackageJsonName(e,t){let n=await readPackageJsonName(e,t);return n===void 0?void 0:stripNpmPackageScope(n)}export{discoverAgent,discoverExtensionMountDeclarations,resolveExtensionMounts};
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* - `export { default } from "@acme/crm";`
|
|
9
9
|
* - `import { crm } from "@acme/crm"; export default crm({ ... });`
|
|
10
10
|
* - `import crm from "@acme/crm"; export default crm();`
|
|
11
|
+
* - `import crm from "@acme/crm"; const mount = crm(); export { mount as default };`
|
|
11
12
|
*
|
|
12
13
|
* Returns the specifier string, or `null` when the file does not match a
|
|
13
14
|
* recognized mount shape.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function escapeRegExp(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function parseExtensionMountSpecifier(e){let t=e.match(/export\s*\{[^}]*\bdefault\b[^}]*\}\s*from\s*['"]([^'"]+)['"]/);if(t!==null)return t[1]??null;let n=e.match(/export\s+default\s+([A-Za-z_$][\w$]*)\s*[(;\n]/)?.[1];if(n===void 0)return null;let r=e.match(RegExp(`import\\s+${escapeRegExp(n)}\\s*(?:,\\s*\\{[^}]*\\})?\\s*from\\s*['"]([^'"]+)['"]`));if(r!==null)return r[1]??null;let i=/import\s*(?:[A-Za-z_$][\w$]*\s*,\s*)?\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/g;for(let t=i.exec(e);t!==null;t=i.exec(e)){let e=t[1]??``;for(let r of e.split(`,`)){let e=r.trim().split(/\s+as\s+/);if((e[1]??e[0]??``).trim()===n)return t[2]??null}}return null}export{parseExtensionMountSpecifier};
|
|
1
|
+
function escapeRegExp(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function parseExtensionMountSpecifier(e){let t=e.match(/export\s*\{[^}]*\bdefault\b[^}]*\}\s*from\s*['"]([^'"]+)['"]/);if(t!==null)return t[1]??null;let n=e.match(/export\s+default\s+([A-Za-z_$][\w$]*)\s*[(;\n]/)?.[1]??emittedMountFactory(e);if(n===void 0)return null;let r=e.match(RegExp(`import\\s+${escapeRegExp(n)}\\s*(?:,\\s*\\{[^}]*\\})?\\s*from\\s*['"]([^'"]+)['"]`));if(r!==null)return r[1]??null;let i=/import\s*(?:[A-Za-z_$][\w$]*\s*,\s*)?\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/g;for(let t=i.exec(e);t!==null;t=i.exec(e)){let e=t[1]??``;for(let r of e.split(`,`)){let e=r.trim().split(/\s+as\s+/);if((e[1]??e[0]??``).trim()===n)return t[2]??null}}return null}function emittedMountFactory(e){for(let t of e.matchAll(/export\s*\{([^}]*)\}\s*(?:;|$)/g))for(let n of(t[1]??``).split(`,`)){let t=n.trim().match(/^([A-Za-z_$][\w$]*)\s+as\s+default$/);if(t!==null)return e.match(RegExp(`\\b(?:const|let|var)\\s+${escapeRegExp(t[1])}\\s*=\\s*([A-Za-z_$][\\w$]*)\\s*\\(`))?.[1]}}export{parseExtensionMountSpecifier};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type DiscoverDiagnostic } from "#discover/diagnostics.js";
|
|
2
2
|
import type { ExtensionSourceRef } from "#discover/manifest.js";
|
|
3
|
-
import type
|
|
3
|
+
import { type ProjectSource } from "#discover/project-source.js";
|
|
4
4
|
/**
|
|
5
5
|
* Emitted when one namespace is claimed by both a file mount
|
|
6
6
|
* (`extensions/<ns>.ts`) and a directory mount (`extensions/<ns>/`).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dirname,isAbsolute,join,resolve}from"node:path";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"#discover/filesystem.js";import{createDiscoverErrorDiagnostic}from"#discover/diagnostics.js";import{EXTENSION_COMPATIBILITY_MANIFEST_FILENAME,findUnsupportedExtensionCapabilities,parseExtensionCompatibilityManifest}from"#compiler/extension-compatibility.js";import{parseExtensionMountSpecifier}from"#discover/extension-specifier.js";import{parseBuiltInExtensionPackageRoots,parseExtensionPackageRoots}from"#shared/extension-package-contract.js";const DISCOVER_EXTENSION_MOUNT_UNRESOLVED=`discover/extension-mount-unresolved`,DISCOVER_EXTENSION_MOUNT_AMBIGUOUS=`discover/extension-mount-ambiguous`,DISCOVER_EXTENSION_MOUNT_MISSING_DECLARATION=`discover/extension-mount-missing-declaration`,DISCOVER_EXTENSION_NESTED_MOUNT_UNSUPPORTED=`discover/extension-nested-mount-unsupported`,DISCOVER_EXTENSION_PACKAGE_INVALID=`discover/extension-package-invalid`,DISCOVER_EXTENSION_COMPATIBILITY_INVALID=`discover/extension-compatibility-invalid`,DISCOVER_EXTENSION_CAPABILITY_INCOMPATIBLE=`discover/extension-capability-incompatible`,DISCOVER_EXTENSION_AGENT_CONFIG_UNSUPPORTED=`discover/extension-agent-config-unsupported`,DISCOVER_EXTENSION_SANDBOX_UNSUPPORTED=`discover/extension-sandbox-unsupported`,DISCOVER_EXTENSION_MEMORY_UNSUPPORTED=`discover/extension-memory-unsupported`,DISCOVER_EXTENSION_INSTRUMENTATION_UNSUPPORTED=`discover/extension-instrumentation-unsupported`;function mountNamespace(e){let t=e.slice(e.lastIndexOf(`/`)+1);for(let e of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)if(t.toLowerCase().endsWith(e))return t.slice(0,t.length-e.length);return t}function mountRefNamespace(e){let t=e.replace(/^extensions\//,``),n=t.indexOf(`/`);return n===-1?mountNamespace(e):t.slice(0,n)}async function locateExtensionMount(e){let t=await locateExtensionMountPackage(e);if(t.location===void 0)return{diagnostics:t.diagnostics};let{location:n}=t;if(n.builtIn)return{location:{namespace:n.namespace,specifier:n.specifier,packageName:n.packageName,packageRoot:n.packageRoot,sourceRoot:n.distRoot,externalDependencies:[]},diagnostics:[]};let r=join(n.distRoot,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME),i;try{i=parseExtensionCompatibilityManifest(await e.source.readTextFile(r),r)}catch(e){return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_COMPATIBILITY_INVALID,message:`Extension "${n.packageName}" has no valid compatibility manifest at "${r}". Rebuild or reinstall the extension. ${e instanceof Error?e.message:String(e)}`,sourcePath:r})]}}let a=findUnsupportedExtensionCapabilities(i);return a.length>0?{diagnostics:a.map(e=>createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_CAPABILITY_INCOMPATIBLE,message:`Extension "${n.packageName}" requires ${e.capability} contract v${e.requiredVersion}, but this eve supports ${e.capability} contract ${formatSupportedVersions(e.supportedVersions)}. Upgrade eve or install an extension release that requires a supported ${e.capability} contract.`,sourcePath:r}))}:{location:{namespace:n.namespace,specifier:n.specifier,packageName:n.packageName,packageRoot:n.packageRoot,sourceRoot:n.distRoot,externalDependencies:i.build?.externalDependencies??[]},diagnostics:[]}}async function locateExtensionMountPackage(e){let t=join(e.agentRoot,e.mount.logicalPath),{namespace:n}=e,r;try{r=await e.source.readTextFile(t)}catch{return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_UNRESOLVED,message:`Could not read extension mount "${e.mount.logicalPath}".`,sourcePath:t})]}}let i=parseExtensionMountSpecifier(r);if(i===null)return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_UNRESOLVED,message:`Extension mount "${e.mount.logicalPath}" must default-export a mounted extension, e.g. \`export default crm({ ... })\` or \`export { default } from "@acme/crm"\`.`,sourcePath:t})]};let a=await resolvePackageRoot({source:e.source,appRoot:e.appRoot,mountDirectory:dirname(t),specifier:i});if(a===null)return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_UNRESOLVED,message:`Could not resolve extension package "${i}" mounted by "${e.mount.logicalPath}".`,sourcePath:t})]};let o=join(a,`package.json`),s;try{s=JSON.parse(await e.source.readTextFile(o))}catch{return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_PACKAGE_INVALID,message:`Extension package "${i}" has no readable package.json at "${o}".`,sourcePath:o})]}}let c=parseBuiltInExtensionPackageRoots(s.eve?.builtInExtensions,packageSpecifierSubpath(i)),l=c??parseExtensionPackageRoots(s.eve?.extension);return l===null?{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_PACKAGE_INVALID,message:`Package "${i}" is not an eve extension: its package.json must declare \`eve.extension.dist\`.`,sourcePath:o})]}:{location:{namespace:n,specifier:i,packageName:typeof s.name==`string`&&s.name.length>0?s.name:i,packageRoot:a,...l.source===void 0?{}:{authoredSourceRoot:resolve(a,l.source)},builtIn:c!==null,distRoot:resolve(a,l.dist)},diagnostics:[]}}function formatSupportedVersions(e){return e.length===0?`versions: none`:`versions: ${e.map(e=>`v${e}`).join(`, `)}`}async function resolvePackageRoot(e){if(e.specifier.startsWith(`.`)){let t=resolve(e.mountDirectory,e.specifier);return await hasPackageJson(e.source,t)?t:null}if(isAbsolute(e.specifier))return await hasPackageJson(e.source,e.specifier)?e.specifier:null;let t=bareSpecifierPackagePath(e.specifier),n=resolve(e.appRoot);for(;;){let r=join(n,`node_modules`,t);if(await hasPackageJson(e.source,r))return r;let i=dirname(n);if(i===n)return null;n=i}}function packageSpecifierSubpath(e){let t=e.slice(bareSpecifierPackagePath(e).length);return t.length===0?`.`:`.${t}`}function bareSpecifierPackagePath(e){let t=e.split(`/`);return e.startsWith(`@`)?t.slice(0,2).join(`/`):t[0]??e}async function hasPackageJson(e,t){return await e.stat(join(t,`package.json`))===`file`}export{DISCOVER_EXTENSION_AGENT_CONFIG_UNSUPPORTED,DISCOVER_EXTENSION_CAPABILITY_INCOMPATIBLE,DISCOVER_EXTENSION_COMPATIBILITY_INVALID,DISCOVER_EXTENSION_INSTRUMENTATION_UNSUPPORTED,DISCOVER_EXTENSION_MEMORY_UNSUPPORTED,DISCOVER_EXTENSION_MOUNT_AMBIGUOUS,DISCOVER_EXTENSION_MOUNT_MISSING_DECLARATION,DISCOVER_EXTENSION_NESTED_MOUNT_UNSUPPORTED,DISCOVER_EXTENSION_SANDBOX_UNSUPPORTED,locateExtensionMount,locateExtensionMountPackage,mountNamespace,mountRefNamespace};
|
|
1
|
+
import{dirname,isAbsolute,join,resolve}from"node:path";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"#discover/filesystem.js";import{readPackageJsonName}from"#discover/project-source.js";import{createDiscoverErrorDiagnostic}from"#discover/diagnostics.js";import{EXTENSION_COMPATIBILITY_MANIFEST_FILENAME,findUnsupportedExtensionCapabilities,parseExtensionCompatibilityManifest}from"#compiler/extension-compatibility.js";import{parseExtensionMountSpecifier}from"#discover/extension-specifier.js";import{parseBuiltInExtensionPackageRoots,parseExtensionPackageRoots}from"#shared/extension-package-contract.js";const DISCOVER_EXTENSION_MOUNT_UNRESOLVED=`discover/extension-mount-unresolved`,DISCOVER_EXTENSION_MOUNT_AMBIGUOUS=`discover/extension-mount-ambiguous`,DISCOVER_EXTENSION_MOUNT_MISSING_DECLARATION=`discover/extension-mount-missing-declaration`,DISCOVER_EXTENSION_NESTED_MOUNT_UNSUPPORTED=`discover/extension-nested-mount-unsupported`,DISCOVER_EXTENSION_PACKAGE_INVALID=`discover/extension-package-invalid`,DISCOVER_EXTENSION_COMPATIBILITY_INVALID=`discover/extension-compatibility-invalid`,DISCOVER_EXTENSION_CAPABILITY_INCOMPATIBLE=`discover/extension-capability-incompatible`,DISCOVER_EXTENSION_AGENT_CONFIG_UNSUPPORTED=`discover/extension-agent-config-unsupported`,DISCOVER_EXTENSION_SANDBOX_UNSUPPORTED=`discover/extension-sandbox-unsupported`,DISCOVER_EXTENSION_MEMORY_UNSUPPORTED=`discover/extension-memory-unsupported`,DISCOVER_EXTENSION_INSTRUMENTATION_UNSUPPORTED=`discover/extension-instrumentation-unsupported`;function mountNamespace(e){let t=e.slice(e.lastIndexOf(`/`)+1);for(let e of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)if(t.toLowerCase().endsWith(e))return t.slice(0,t.length-e.length);return t}function mountRefNamespace(e){let t=e.replace(/^extensions\//,``),n=t.indexOf(`/`);return n===-1?mountNamespace(e):t.slice(0,n)}async function locateExtensionMount(e){let t=await locateExtensionMountPackage(e);if(t.location===void 0)return{diagnostics:t.diagnostics};let{location:n}=t;if(n.builtIn)return{location:{namespace:n.namespace,specifier:n.specifier,packageName:n.packageName,packageRoot:n.packageRoot,sourceRoot:n.distRoot,externalDependencies:[]},diagnostics:[]};let r=join(n.distRoot,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME),i;try{i=parseExtensionCompatibilityManifest(await e.source.readTextFile(r),r)}catch(e){return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_COMPATIBILITY_INVALID,message:`Extension "${n.packageName}" has no valid compatibility manifest at "${r}". Rebuild or reinstall the extension. ${e instanceof Error?e.message:String(e)}`,sourcePath:r})]}}let a=findUnsupportedExtensionCapabilities(i);return a.length>0?{diagnostics:a.map(e=>createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_CAPABILITY_INCOMPATIBLE,message:`Extension "${n.packageName}" requires ${e.capability} contract v${e.requiredVersion}, but this eve supports ${e.capability} contract ${formatSupportedVersions(e.supportedVersions)}. Upgrade eve or install an extension release that requires a supported ${e.capability} contract.`,sourcePath:r}))}:{location:{namespace:n.namespace,specifier:n.specifier,packageName:n.packageName,packageRoot:n.packageRoot,sourceRoot:n.distRoot,externalDependencies:i.build?.externalDependencies??[]},diagnostics:[]}}async function locateExtensionMountPackage(e){let t=join(e.agentRoot,e.mount.logicalPath),{namespace:n}=e,r;try{r=await e.source.readTextFile(t)}catch{return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_UNRESOLVED,message:`Could not read extension mount "${e.mount.logicalPath}".`,sourcePath:t})]}}let i=parseExtensionMountSpecifier(r);if(i===null)return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_UNRESOLVED,message:`Extension mount "${e.mount.logicalPath}" must default-export a mounted extension, e.g. \`export default crm({ ... })\` or \`export { default } from "@acme/crm"\`.`,sourcePath:t})]};let a=await resolvePackageRoot({source:e.source,appRoot:e.appRoot,mountDirectory:dirname(t),specifier:i});if(a===null)return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_MOUNT_UNRESOLVED,message:`Could not resolve extension package "${i}" mounted by "${e.mount.logicalPath}".`,sourcePath:t})]};let o=join(a,`package.json`),s;try{s=JSON.parse(await e.source.readTextFile(o))}catch{return{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_PACKAGE_INVALID,message:`Extension package "${i}" has no readable package.json at "${o}".`,sourcePath:o})]}}let c=parseBuiltInExtensionPackageRoots(s.eve?.builtInExtensions,packageSpecifierSubpath(i)),l=c??parseExtensionPackageRoots(s.eve?.extension);return l===null?{diagnostics:[createDiscoverErrorDiagnostic({code:DISCOVER_EXTENSION_PACKAGE_INVALID,message:`Package "${i}" is not an eve extension: its package.json must declare \`eve.extension.dist\`.`,sourcePath:o})]}:{location:{namespace:n,specifier:i,packageName:typeof s.name==`string`&&s.name.length>0?s.name:i,packageRoot:a,...l.source===void 0?{}:{authoredSourceRoot:resolve(a,l.source)},builtIn:c!==null,distRoot:resolve(a,l.dist)},diagnostics:[]}}function formatSupportedVersions(e){return e.length===0?`versions: none`:`versions: ${e.map(e=>`v${e}`).join(`, `)}`}async function resolvePackageRoot(e){if(e.specifier.startsWith(`.`)){let t=resolve(e.mountDirectory,e.specifier);return await hasPackageJson(e.source,t)?t:null}if(isAbsolute(e.specifier))return await hasPackageJson(e.source,e.specifier)?e.specifier:null;let t=bareSpecifierPackagePath(e.specifier);if(await readPackageJsonName(e.source,e.appRoot)===t)return resolve(e.appRoot);let n=resolve(e.appRoot);for(;;){let r=join(n,`node_modules`,t);if(await hasPackageJson(e.source,r))return r;let i=dirname(n);if(i===n)return null;n=i}}function packageSpecifierSubpath(e){let t=e.slice(bareSpecifierPackagePath(e).length);return t.length===0?`.`:`.${t}`}function bareSpecifierPackagePath(e){let t=e.split(`/`);return e.startsWith(`@`)?t.slice(0,2).join(`/`):t[0]??e}async function hasPackageJson(e,t){return await e.stat(join(t,`package.json`))===`file`}export{DISCOVER_EXTENSION_AGENT_CONFIG_UNSUPPORTED,DISCOVER_EXTENSION_CAPABILITY_INCOMPATIBLE,DISCOVER_EXTENSION_COMPATIBILITY_INVALID,DISCOVER_EXTENSION_INSTRUMENTATION_UNSUPPORTED,DISCOVER_EXTENSION_MEMORY_UNSUPPORTED,DISCOVER_EXTENSION_MOUNT_AMBIGUOUS,DISCOVER_EXTENSION_MOUNT_MISSING_DECLARATION,DISCOVER_EXTENSION_NESTED_MOUNT_UNSUPPORTED,DISCOVER_EXTENSION_SANDBOX_UNSUPPORTED,locateExtensionMount,locateExtensionMountPackage,mountNamespace,mountRefNamespace};
|
|
@@ -105,4 +105,9 @@ interface MemoryProjectSourceInput {
|
|
|
105
105
|
* enough for all discovery code paths.
|
|
106
106
|
*/
|
|
107
107
|
export declare function createMemoryProjectSource(input: MemoryProjectSourceInput): ProjectSource;
|
|
108
|
+
/**
|
|
109
|
+
* Reads the non-empty string `name` field from `root/package.json`, or
|
|
110
|
+
* `undefined` when the file is missing, unparseable, or has no usable name.
|
|
111
|
+
*/
|
|
112
|
+
export declare function readPackageJsonName(source: ProjectSource, root: string): Promise<string | undefined>;
|
|
108
113
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFile,readdir,stat}from"node:fs/promises";import{posix,sep}from"node:path";function createDiskProjectSource(){return{kind:`disk`,async readDirectory(e){return await readdir(e,{withFileTypes:!0})},async readTextFile(e){return await readFile(e,`utf8`)},async stat(e){try{let t=await stat(e);return t.isDirectory()?`directory`:t.isFile()?`file`:`other`}catch{return`missing`}}}}function createMemoryProjectSource(e){let t=new Map,n=new Map;function registerDirectory(e){let t=n.get(e);return t===void 0&&(t=new Map,n.set(e,t)),t}function registerChildOfDirectory(e,t,n){if(registerDirectory(e).get(t)===`file`&&n===`directory`)throw TypeError(`MemoryProjectSource: path "${posix.join(e,t)}" registered as both a file and a directory.`);registerDirectory(e).set(t,n)}for(let[n,r]of Object.entries(e.files)){let e=normalizeToPosix(n),i=typeof r==`string`?r:r.content;t.set(e,i);let a=splitPosixPath(e);if(a.length===0)throw TypeError(`MemoryProjectSource: cannot register root path "${n}" as a file.`);let o=a[a.length-1];if(o===void 0)throw TypeError(`MemoryProjectSource: empty file name in "${n}".`);let s=`/`;for(let e=0;e<a.length-1;e+=1){let t=a[e];t!==void 0&&(registerChildOfDirectory(s,t,`directory`),s=s===`/`?`/${t}`:`${s}/${t}`)}registerChildOfDirectory(s,o,`file`)}for(let t of e.directories??[]){let e=normalizeToPosix(t),n=splitPosixPath(e);registerDirectory(e);let r=`/`;for(let e=0;e<n.length;e+=1){let t=n[e];t!==void 0&&(registerChildOfDirectory(r,t,`directory`),r=r===`/`?`/${t}`:`${r}/${t}`)}}return{kind:`memory`,async readDirectory(t){let r=normalizeToPosix(t),i=n.get(r);if(i===void 0)throw Error(`MemoryProjectSource: directory "${t}" does not exist${e.rootDir===void 0?``:` (root: ${e.rootDir})`}.`);return[...i.entries()].map(([e,t])=>createMemoryEntry(e,t))},async readTextFile(n){let r=normalizeToPosix(n),i=t.get(r);if(i===void 0)throw Error(`MemoryProjectSource: file "${n}" does not exist${e.rootDir===void 0?``:` (root: ${e.rootDir})`}.`);return i},async stat(e){let r=normalizeToPosix(e);return t.has(r)?`file`:n.has(r)?`directory`:`missing`}}}function createMemoryEntry(e,t){return{name:e,isDirectory(){return t===`directory`},isFile(){return t===`file`}}}function normalizeToPosix(e){let t=sep===`/`?e:e.replaceAll(sep,`/`);if(t.length===0)return`/`;let n=t.replace(/^[A-Za-z]:/,``),r=n.startsWith(`/`)?n:`/${n}`;return posix.normalize(r).replace(/\/+$/,``)||`/`}function splitPosixPath(e){return e.split(`/`).filter(e=>e.length>0)}export{createDiskProjectSource,createMemoryProjectSource};
|
|
1
|
+
import{readFile,readdir,stat}from"node:fs/promises";import{join,posix,sep}from"node:path";function createDiskProjectSource(){return{kind:`disk`,async readDirectory(e){return await readdir(e,{withFileTypes:!0})},async readTextFile(e){return await readFile(e,`utf8`)},async stat(e){try{let t=await stat(e);return t.isDirectory()?`directory`:t.isFile()?`file`:`other`}catch{return`missing`}}}}function createMemoryProjectSource(e){let t=new Map,n=new Map;function registerDirectory(e){let t=n.get(e);return t===void 0&&(t=new Map,n.set(e,t)),t}function registerChildOfDirectory(e,t,n){if(registerDirectory(e).get(t)===`file`&&n===`directory`)throw TypeError(`MemoryProjectSource: path "${posix.join(e,t)}" registered as both a file and a directory.`);registerDirectory(e).set(t,n)}for(let[n,r]of Object.entries(e.files)){let e=normalizeToPosix(n),i=typeof r==`string`?r:r.content;t.set(e,i);let a=splitPosixPath(e);if(a.length===0)throw TypeError(`MemoryProjectSource: cannot register root path "${n}" as a file.`);let o=a[a.length-1];if(o===void 0)throw TypeError(`MemoryProjectSource: empty file name in "${n}".`);let s=`/`;for(let e=0;e<a.length-1;e+=1){let t=a[e];t!==void 0&&(registerChildOfDirectory(s,t,`directory`),s=s===`/`?`/${t}`:`${s}/${t}`)}registerChildOfDirectory(s,o,`file`)}for(let t of e.directories??[]){let e=normalizeToPosix(t),n=splitPosixPath(e);registerDirectory(e);let r=`/`;for(let e=0;e<n.length;e+=1){let t=n[e];t!==void 0&&(registerChildOfDirectory(r,t,`directory`),r=r===`/`?`/${t}`:`${r}/${t}`)}}return{kind:`memory`,async readDirectory(t){let r=normalizeToPosix(t),i=n.get(r);if(i===void 0)throw Error(`MemoryProjectSource: directory "${t}" does not exist${e.rootDir===void 0?``:` (root: ${e.rootDir})`}.`);return[...i.entries()].map(([e,t])=>createMemoryEntry(e,t))},async readTextFile(n){let r=normalizeToPosix(n),i=t.get(r);if(i===void 0)throw Error(`MemoryProjectSource: file "${n}" does not exist${e.rootDir===void 0?``:` (root: ${e.rootDir})`}.`);return i},async stat(e){let r=normalizeToPosix(e);return t.has(r)?`file`:n.has(r)?`directory`:`missing`}}}function createMemoryEntry(e,t){return{name:e,isDirectory(){return t===`directory`},isFile(){return t===`file`}}}async function readPackageJsonName(e,t){try{let{name:n}=JSON.parse(await e.readTextFile(join(t,`package.json`)));return typeof n==`string`&&n.length>0?n:void 0}catch{return}}function normalizeToPosix(e){let t=sep===`/`?e:e.replaceAll(sep,`/`);if(t.length===0)return`/`;let n=t.replace(/^[A-Za-z]:/,``),r=n.startsWith(`/`)?n:`/${n}`;return posix.normalize(r).replace(/\/+$/,``)||`/`}function splitPosixPath(e){return e.split(`/`).filter(e=>e.length>0)}export{createDiskProjectSource,createMemoryProjectSource,readPackageJsonName};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFile}from"node:fs/promises";import{isAbsolute,resolve}from"node:path";import{
|
|
1
|
+
import{readFile}from"node:fs/promises";import{isAbsolute,resolve}from"node:path";import{parseYaml}from"#internal/helpers/frontmatter.js";async function loadYaml(e){let t=isAbsolute(e)?e:resolve(process.cwd(),e),n=await readFile(t,`utf-8`);return parseYaml(n)}export{loadYaml};
|
|
@@ -39,6 +39,7 @@ export declare class EvalSessionDriver implements EveEvalSession {
|
|
|
39
39
|
get sessionId(): string;
|
|
40
40
|
get state(): ClientSessionState;
|
|
41
41
|
cancel(): Promise<CancelSessionResult>;
|
|
42
|
+
compact(): Promise<EveEvalTurn>;
|
|
42
43
|
agent(started: AgentStartedStreamEvent): EveEvalAgentSession;
|
|
43
44
|
/** @internal */
|
|
44
45
|
cleanup(signal: AbortSignal): Promise<void>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readFile}from"node:fs/promises";import{basename}from"node:path";import{TurnSegment,summarizeTurnEvents}from"#client/session-utils.js";import{isTurnFailureEvent}from"#protocol/message.js";import{createTextWithFileContent}from"#client/file-parts.js";import{extractCompletedResult}from"#client/output-schema.js";import{inputRequestMatches,matchesValue,toolCallMatches}from"#evals/match.js";import"#evals/assertions/collector.js";import{createOutputAssertions,createScopedAssertions}from"#evals/assertions/scoped.js";import{EvalRequirementFailed}from"#evals/control-flow.js";import{deriveRunFacts}from"#evals/runner/derive-run-facts.js";import{formatEvalTranscript,inferMediaType}from"#evals/session-content.js";var EveEvalTurnFailedError=class extends Error{event;turn;constructor(e){let t=e.events.find(isTurnFailureEvent),n=t===void 0?`turn ended with status "${e.status}"`:`${t.type}: ${t.data.code} ${t.data.message}`.trim();super(`Eval turn failed: ${n}`),this.name=`EveEvalTurnFailedError`,this.event=t,this.turn=e}},EvalSessionDriver=class{#e;#t;#n=``;#r;#i;#a=[];#o;#s;#c=[];#l=new Set;#u;#d=!1;#f=[];constructor(e){this.#i=e.collector,this.#s=e.onSessionStart,this.#o=e.primary,this.#e=e.session,this.#t=e.onTurn,this.#r=e.signal,Object.assign(this,createScopedAssertions(this.#i,{timing:`snapshot`,select:()=>this.#_()}),createOutputAssertions(this.#i,{timing:`snapshot`,select:()=>this.#_()}))}get events(){return this.#a}get transcript(){return formatEvalTranscript(this.#a)}get lastInput(){return this.#n}get lastTurn(){return this.#u}get pendingInputRequests(){return this.#f}get sessionId(){return this.#e.state.sessionId}get state(){return this.#e.state}async cancel(){return await this.#e.cancel()}agent(e){let t=this.#e.agent(e),n=this.#r;return{name:t.name,sessionId:t.sessionId,stream:(e={})=>t.stream({...e,signal:e.signal??n}),taskId:t.taskId}}async cleanup(e){await this.#e.reset({reason:`Eval timed out`,signal:e})}requireInputRequest(e={}){this.#f.length===0&&this.#v(`requireInputRequest`,`expected one pending input request, but the last turn did not park`);let t=this.#f.filter(t=>inputRequestMatches(t,e));return(this.#f.length!==1||t.length!==1)&&this.#v(`requireInputRequest`,`expected exactly one pending input request matching ${formatInputRequestFilter(e)}, found ${t.length} match(es) across ${this.#f.length} pending request(s)`),this.#i.recordOutcome({name:`requireInputRequest`,outcome:{score:1}}),t[0]}async respond(e,t={}){if(e.length===0)throw Error(`respond() requires at least one input response.`);return await(await this.#p({...t,inputResponses:e})).result()}async startRespond(e,t={}){if(e.length===0)throw Error(`startRespond() requires input responses.`);return await this.#p({...t,inputResponses:e})}async respondAll(e){let t=this.#f;if(t.length===0)throw Error(`respondAll() requires at least one pending input request.`);for(let n of t)assertRequestHasOption(n,e);return await this.respond(t.map(t=>({optionId:e,requestId:t.requestId})))}async send(e,t={}){return await(await this.#p({turnPolicy:`queue`,...t,message:e})).result()}async start(e,t={}){return await this.#p({turnPolicy:`queue`,...t,message:e})}async#p(e){let{inputResponses:t,message:n,...r}=attachSignal(e,this.#r),i=t===void 0?await this.#e.send(n,r):await this.#e.respond(t,r);return this.consume(i,n)}consume(e,t){let n=this.sessionId;return new EvalLiveTurn({events:e,observe:e=>this.#m(n,e),record:e=>(t!==void 0&&(this.#n=typeof t==`string`?t:t.filter(e=>e.type===`text`).map(e=>e.text).join(`
|
|
1
|
+
import{readFile}from"node:fs/promises";import{basename}from"node:path";import{TurnSegment,summarizeTurnEvents}from"#client/session-utils.js";import{isTurnFailureEvent}from"#protocol/message.js";import{createTextWithFileContent}from"#client/file-parts.js";import{extractCompletedResult}from"#client/output-schema.js";import{inputRequestMatches,matchesValue,toolCallMatches}from"#evals/match.js";import"#evals/assertions/collector.js";import{createOutputAssertions,createScopedAssertions}from"#evals/assertions/scoped.js";import{EvalRequirementFailed}from"#evals/control-flow.js";import{deriveRunFacts}from"#evals/runner/derive-run-facts.js";import{formatEvalTranscript,inferMediaType}from"#evals/session-content.js";var EveEvalTurnFailedError=class extends Error{event;turn;constructor(e){let t=e.events.find(isTurnFailureEvent),n=t===void 0?`turn ended with status "${e.status}"`:`${t.type}: ${t.data.code} ${t.data.message}`.trim();super(`Eval turn failed: ${n}`),this.name=`EveEvalTurnFailedError`,this.event=t,this.turn=e}},EvalSessionDriver=class{#e;#t;#n=``;#r;#i;#a=[];#o;#s;#c=[];#l=new Set;#u;#d=!1;#f=[];constructor(e){this.#i=e.collector,this.#s=e.onSessionStart,this.#o=e.primary,this.#e=e.session,this.#t=e.onTurn,this.#r=e.signal,Object.assign(this,createScopedAssertions(this.#i,{timing:`snapshot`,select:()=>this.#_()}),createOutputAssertions(this.#i,{timing:`snapshot`,select:()=>this.#_()}))}get events(){return this.#a}get transcript(){return formatEvalTranscript(this.#a)}get lastInput(){return this.#n}get lastTurn(){return this.#u}get pendingInputRequests(){return this.#f}get sessionId(){return this.#e.state.sessionId}get state(){return this.#e.state}async cancel(){return await this.#e.cancel()}async compact(){if((await this.#e.compact()).status!==`accepted`)throw Error(`compact() found no active session for "${this.sessionId}".`);return await this.readTurn()}agent(e){let t=this.#e.agent(e),n=this.#r;return{name:t.name,sessionId:t.sessionId,stream:(e={})=>t.stream({...e,signal:e.signal??n}),taskId:t.taskId}}async cleanup(e){await this.#e.reset({reason:`Eval timed out`,signal:e})}requireInputRequest(e={}){this.#f.length===0&&this.#v(`requireInputRequest`,`expected one pending input request, but the last turn did not park`);let t=this.#f.filter(t=>inputRequestMatches(t,e));return(this.#f.length!==1||t.length!==1)&&this.#v(`requireInputRequest`,`expected exactly one pending input request matching ${formatInputRequestFilter(e)}, found ${t.length} match(es) across ${this.#f.length} pending request(s)`),this.#i.recordOutcome({name:`requireInputRequest`,outcome:{score:1}}),t[0]}async respond(e,t={}){if(e.length===0)throw Error(`respond() requires at least one input response.`);return await(await this.#p({...t,inputResponses:e})).result()}async startRespond(e,t={}){if(e.length===0)throw Error(`startRespond() requires input responses.`);return await this.#p({...t,inputResponses:e})}async respondAll(e){let t=this.#f;if(t.length===0)throw Error(`respondAll() requires at least one pending input request.`);for(let n of t)assertRequestHasOption(n,e);return await this.respond(t.map(t=>({optionId:e,requestId:t.requestId})))}async send(e,t={}){return await(await this.#p({turnPolicy:`queue`,...t,message:e})).result()}async start(e,t={}){return await this.#p({turnPolicy:`queue`,...t,message:e})}async#p(e){let{inputResponses:t,message:n,...r}=attachSignal(e,this.#r),i=t===void 0?await this.#e.send(n,r):await this.#e.respond(t,r);return this.consume(i,n)}consume(e,t){let n=this.sessionId;return new EvalLiveTurn({events:e,observe:e=>this.#m(n,e),record:e=>(t!==void 0&&(this.#n=typeof t==`string`?t:t.filter(e=>e.type===`text`).map(e=>e.text).join(`
|
|
2
2
|
`)),this.#g(n,e)),session:this,sessionId:n})}async sendFile(e,t,n){let r=await readFile(t),i=createTextWithFileContent({bytes:r,filename:basename(t),mediaType:n??inferMediaType(t),text:e});return await this.send(i)}async readTurn(e){return await this.watchTurn(e).result()}watchTurn(e){return this.consume(this.#e.stream({signal:this.#r,startIndex:e?.startIndex}))}snapshot(){let e=this.sessionId;return{derived:deriveRunFacts(this.#a,{sessionId:e}),events:[...this.#a],primary:this.#o,sessionId:e,state:this.#e.state,traceContexts:[...this.#c]}}#m(e,t){if(t.type!==`session.started`&&t.type!==`turn.started`)return;let n=t.data.trace;if(n===void 0)return;let r=`${n.traceId}:${n.spanId}`;this.#l.has(r)||(this.#l.add(r),this.#c.push(n),!this.#d&&(this.#d=!0,this.#s?.({primary:this.#o,sessionId:e,startedAt:t.meta.at,traceContext:n})))}#h(e){this.#a.push(...e.events),this.#f=e.status===`waiting`?e.inputRequests:[];let t=deriveRunFacts(e.events,{sessionId:e.sessionId}),n=new EvalTurn({collector:this.#i,data:e.data,derived:t,events:e.events,inputRequests:e.inputRequests,message:e.message,session:this,sessionId:e.sessionId,status:e.status,toolCalls:t.toolCalls});return this.#u=n,this.#t(this),n}#g(e,t){let n=summarizeTurnEvents(t);return this.#h({data:extractCompletedResult(t),events:t,inputRequests:n.inputRequests,message:n.message,sessionId:e,status:n.status})}#_(){let e=this.sessionId;return{derived:deriveRunFacts(this.#a,{sessionId:e}),events:[...this.#a],output:outputOf(this.#u),status:this.#u?.status??`completed`}}#v(e,t){throw this.#i.recordOutcome({name:e,outcome:{score:0,message:t}}),new EvalRequirementFailed}},EvalLiveTurn=class{session;sessionId;#e;#t=[];#n=new Set;#r;constructor(e){this.session=e.session,this.sessionId=e.sessionId,this.#e=this.#i(e.events,e.observe,e.record),this.#e.catch(()=>{})}get events(){return this.#t}async cancel(){return await this.session.cancel()}async result(){return await this.#e}async waitForEvent(e,t){let matches=n=>n.type===e&&(t?.data===void 0||matchesValue(t.data,`data`in n?n.data:void 0)),n=this.#t.find(matches);if(n!==void 0)return n;if(this.#r!==void 0)throw this.#r;return await new Promise((e,t)=>{let n={matches,reject:t,resolve:t=>e(t)};this.#n.add(n)})}async#i(e,t,n){try{let r=!1,i=new TurnSegment;for await(let n of e){this.#t.push(n);let e=i.observe(n);if(t(n),this.#a(n),isTurnFailureEvent(n)&&this.#o(Error(`Session ${this.sessionId} failed before the expected event (${n.type}).`)),e){r=!0,this.#o(Error(`Session ${this.sessionId} reached ${n.type} before the expected event.`));break}}if(!r)throw Error(`Stream for session "${this.sessionId}" closed before a turn boundary.`);return n(this.#t)}catch(e){let t=e instanceof Error?e:Error(String(e));throw this.#o(t),e}}#a(e){for(let t of this.#n)t.matches(e)&&(this.#n.delete(t),t.resolve(e))}#o(e){if(this.#r===void 0){this.#r=e;for(let t of this.#n)t.reject(e);this.#n.clear()}}},EvalTurn=class{data;events;inputRequests;message;session;sessionId;status;toolCalls;#e;#t;constructor(e){this.data=e.data,this.events=e.events,this.inputRequests=e.inputRequests,this.message=e.message,this.sessionId=e.sessionId,this.session=e.session,this.status=e.status,this.toolCalls=e.toolCalls,this.#e=e.collector,this.#t=e.derived,Object.assign(this,createScopedAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}),createOutputAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}))}expectOk(){if(this.status!==`failed`)return this;throw new EveEvalTurnFailedError(this)}requireToolCall(e,t={}){let n=this.toolCalls.filter(n=>n.name===e&&toolCallMatches(n,t));return n.length!==1&&inputRequirementFailed(this.#e,`requireToolCall`,`expected exactly one matching "${e}" tool call in this turn, found ${n.length}; observed [${this.toolCalls.map(e=>e.name).join(`, `)}]`),this.#e.recordOutcome({name:`requireToolCall`,outcome:{score:1}}),n[0]}#n(){return{derived:this.#t,events:this.events,output:outputOf(this),status:this.status}}};function attachSignal(e,t){return t===void 0?e:e.signal===void 0?{...e,signal:t}:e}function formatInputRequestFilter(e){return JSON.stringify(e)}function inputRequirementFailed(e,t,n){throw e.recordOutcome({name:t,outcome:{score:0,message:n}}),new EvalRequirementFailed}function outputOf(e){return e===void 0?null:e.data===void 0?e.message??null:e.data}function assertRequestHasOption(e,t){if(e.options===void 0||e.options.length===0)throw Error(`Input request "${e.requestId}" has no selectable options.`);if(!e.options.some(e=>e.id===t))throw Error(`Input request "${e.requestId}" does not offer option "${t}".`)}export{EvalSessionDriver,EveEvalTurnFailedError};
|
|
@@ -277,6 +277,12 @@ interface EveEvalSessionDriver {
|
|
|
277
277
|
readonly sessionId: string;
|
|
278
278
|
/** Request cooperative cancellation of this session's active turn. */
|
|
279
279
|
cancel(): Promise<CancelSessionResult>;
|
|
280
|
+
/**
|
|
281
|
+
* Compact this session's history between turns and wait for it to finish.
|
|
282
|
+
* Returns the compaction events through `session.waiting`; throws when the
|
|
283
|
+
* session is no longer active.
|
|
284
|
+
*/
|
|
285
|
+
compact(): Promise<EveEvalTurn>;
|
|
280
286
|
/** Require exactly one pending input request matching `filter`, or abort dependent control flow. */
|
|
281
287
|
requireInputRequest(filter?: EveEvalInputRequestMatchOptions): InputRequest;
|
|
282
288
|
/** Resolve specific pending requests and run the resumed turn. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{runJsProgram}from"#execution/dynamic-workflow/workflow.js";async function runWorkflowProgramTask(e,t){"use workflow";return runJsProgram(e.js,t,{maxSubagents:e.maxSubagents??0})}runWorkflowProgramTask.workflowId=`workflow//eve@0.70.
|
|
1
|
+
import{runJsProgram}from"#execution/dynamic-workflow/workflow.js";async function runWorkflowProgramTask(e,t){"use workflow";return runJsProgram(e.js,t,{maxSubagents:e.maxSubagents??0})}runWorkflowProgramTask.workflowId=`workflow//eve@0.70.2//runWorkflowProgramTask`;export{runWorkflowProgramTask};
|
|
@@ -27,6 +27,14 @@ export declare function splitLegacyTaskFields(input: Record<string, unknown>): {
|
|
|
27
27
|
* must stay off this session's own channel.
|
|
28
28
|
*/
|
|
29
29
|
export declare function forwardLegacySessionInput(ctx: ContextContainer, caller: LegacyRemoteAgentCaller, event: UnstampedMessageStreamEvent): Promise<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Renames a `task.*` callback that a remote agent sends a protocol-1 caller to
|
|
32
|
+
* the payload kind the caller's session reads. The callback URL resolves to the
|
|
33
|
+
* caller's newest deployment, while the session waiting on it may still run on
|
|
34
|
+
* an eve 0.66–0.68 build; both read the renamed kinds. The caller still
|
|
35
|
+
* validates the result.
|
|
36
|
+
*/
|
|
37
|
+
export declare function renameLegacyTaskCallback(body: unknown): unknown;
|
|
30
38
|
/** Route a protocol-1 caller posts its answers to a remote agent's question or approval. */
|
|
31
39
|
export declare const legacyTaskInputRoute: {
|
|
32
40
|
readonly handler: typeof handleLegacyTaskInputRequest;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{isInputResponse}from"#shared/input.js";import{ContinuationTokenKey,SessionCallbackKey,SessionIdKey}from"#context/keys.js";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{resumeSessionInbox}from"#execution/session-inbox/resume.js";import{postSessionCallbackRequest}from"#execution/session-callback-request.js";import{HookNotFoundError}from"#compiled/@workflow/errors/index.js";const log=createLogger(`execution.legacy-remote-agent`),LEGACY_REMOTE_AGENT_PROTOCOL_VERSION=1,TASK_INPUT_TOKEN_RE=/^eve:task-input:([a-f0-9]{32})$/;function splitLegacyTaskFields(e){let{callback:t}=e;if(!isObject(t)||!(`taskId`in t))return{payload:e};let{taskId:n,...r}=t,i={...e,callback:r};return typeof n==`string`&&n.length>0?{payload:i,taskId:n}:{payload:i}}async function forwardLegacySessionInput(e,t,n){let r=e.get(SessionCallbackKey),i=e.get(ContinuationTokenKey);if(t.taskId===void 0||r===void 0||!i)return!1;let a;if(n.type===`input.requested`)a={event:n.data,kind:`task.input-requested`};else if(n.type===`authorization.required`||n.type===`authorization.completed`)a={event:n,kind:`task.authorization`};else return!1;let o=await postSessionCallbackRequest({body:{callId:r.callId,childContinuationToken:i,childSessionId:e.require(SessionIdKey),event:a.event,kind:a.kind,subagentName:r.subagentName,taskId:t.taskId},url:r.url});if(!o.ok)throw Error(`Remote task event callback failed with HTTP ${o.status}.`);return!0}const legacyTaskInputRoute={handler:handleLegacyTaskInputRequest,path:`${EVE_ROUTE_PREFIX}/task-input/:token`};async function handleLegacyTaskInputRequest(e,t){let n=TASK_INPUT_TOKEN_RE.exec(t.params.token??``)?.[1];if(n===void 0)return Response.json({error:`Invalid task input token.`,ok:!1},{status:403});let r;try{r=await e.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}let i=isObject(r)?r.inputResponses:void 0;if(!Array.isArray(i)||i.length===0||!i.every(isInputResponse))return Response.json({error:`Expected a non-empty inputResponses array.`,ok:!1},{status:400});try{await resumeSessionInbox(`eve:eve:op:${n}`,{kind:`send`,payload:{inputResponses:i}})}catch(e){if(HookNotFoundError.is(e))return Response.json({error:`Task input target is not pending.`,ok:!1},{status:404});let t=logError(log,`legacy task input delivery failed`,e);return Response.json({error:`Failed to deliver the task input.`,errorId:t,ok:!1},{status:500})}return Response.json({ok:!0},{status:202})}export{LEGACY_REMOTE_AGENT_PROTOCOL_VERSION,forwardLegacySessionInput,legacyTaskInputRoute,splitLegacyTaskFields};
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{isInputResponse}from"#shared/input.js";import{ContinuationTokenKey,SessionCallbackKey,SessionIdKey}from"#context/keys.js";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{resumeSessionInbox}from"#execution/session-inbox/resume.js";import{postSessionCallbackRequest}from"#execution/session-callback-request.js";import{HookNotFoundError}from"#compiled/@workflow/errors/index.js";const log=createLogger(`execution.legacy-remote-agent`),LEGACY_REMOTE_AGENT_PROTOCOL_VERSION=1,TASK_INPUT_TOKEN_RE=/^eve:task-input:([a-f0-9]{32})$/;function splitLegacyTaskFields(e){let{callback:t}=e;if(!isObject(t)||!(`taskId`in t))return{payload:e};let{taskId:n,...r}=t,i={...e,callback:r};return typeof n==`string`&&n.length>0?{payload:i,taskId:n}:{payload:i}}async function forwardLegacySessionInput(e,t,n){let r=e.get(SessionCallbackKey),i=e.get(ContinuationTokenKey);if(t.taskId===void 0||r===void 0||!i)return!1;let a;if(n.type===`input.requested`)a={event:n.data,kind:`task.input-requested`};else if(n.type===`authorization.required`||n.type===`authorization.completed`)a={event:n,kind:`task.authorization`};else return!1;let o=await postSessionCallbackRequest({body:{callId:r.callId,childContinuationToken:i,childSessionId:e.require(SessionIdKey),event:a.event,kind:a.kind,subagentName:r.subagentName,taskId:t.taskId},url:r.url});if(!o.ok)throw Error(`Remote task event callback failed with HTTP ${o.status}.`);return!0}function renameLegacyTaskCallback(e){if(!isObject(e))return e;let{taskId:t,...n}=e;return e.kind===`task.input-requested`?{...n,kind:`subagent-input-request`}:e.kind===`task.authorization`?{...n,kind:`subagent-authorization-event`}:e}const legacyTaskInputRoute={handler:handleLegacyTaskInputRequest,path:`${EVE_ROUTE_PREFIX}/task-input/:token`};async function handleLegacyTaskInputRequest(e,t){let n=TASK_INPUT_TOKEN_RE.exec(t.params.token??``)?.[1];if(n===void 0)return Response.json({error:`Invalid task input token.`,ok:!1},{status:403});let r;try{r=await e.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}let i=isObject(r)?r.inputResponses:void 0;if(!Array.isArray(i)||i.length===0||!i.every(isInputResponse))return Response.json({error:`Expected a non-empty inputResponses array.`,ok:!1},{status:400});try{await resumeSessionInbox(`eve:eve:op:${n}`,{kind:`send`,payload:{inputResponses:i}})}catch(e){if(HookNotFoundError.is(e))return Response.json({error:`Task input target is not pending.`,ok:!1},{status:404});let t=logError(log,`legacy task input delivery failed`,e);return Response.json({error:`Failed to deliver the task input.`,errorId:t,ok:!1},{status:500})}return Response.json({ok:!0},{status:202})}export{LEGACY_REMOTE_AGENT_PROTOCOL_VERSION,forwardLegacySessionInput,legacyTaskInputRoute,renameLegacyTaskCallback,splitLegacyTaskFields};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{completeLegacyDriverStep}from"./completion-step.js";import{interruptLegacySessionStep}from"./interrupt-step.js";import{prepareLegacySessionStep}from"./prepare-step.js";import{sessionCommandHookToken}from"#execution/session-inbox/address.js";import{isHookConflictError}from"#execution/hook-ownership.js";import{sessionTimeoutDeadline}from"#execution/session/timeout.js";import{sessionHookTokens}from"#execution/session/hook-tokens.js";import{createSessionInbox}from"#execution/session-inbox/inbox.js";import{failSession,runPreparedSession}from"#execution/session/program.js";async function turnWorkflow(e){"use workflow";let t=await prepareLegacySessionStep(e),{sessionId:n}=t.sessionState,r=createSessionInbox(n);try{await r.claimSessionHook(sessionCommandHookToken(n))}catch(e){if(isHookConflictError(e))return;throw e}let{sessionWritable:i}=t.input,a;try{await r.claimSessionHooks(sessionHookTokens(t)),a=await interruptLegacySessionStep(t)}catch(e){return await r.dispose(),await failSession({error:e,serializedContext:t.serializedContext,sessionId:n,sessionState:t.sessionState,sessionWritable:i})}await runPreparedSession({anchor:{kind:`self`,notify:e=>completeLegacyDriverStep({completionToken:t.input.completionToken,history:t.history,result:e,serializedContext:t.serializedContext,sessionState:t.sessionState,sessionWritable:i})},caller:void 0,capabilities:t.input.capabilities,deploymentId:t.deploymentId,history:a.history,
|
|
1
|
+
import{completeLegacyDriverStep}from"./completion-step.js";import{interruptLegacySessionStep}from"./interrupt-step.js";import{prepareLegacySessionStep}from"./prepare-step.js";import{sessionCommandHookToken}from"#execution/session-inbox/address.js";import{isHookConflictError}from"#execution/hook-ownership.js";import{sessionTimeoutDeadline}from"#execution/session/timeout.js";import{sessionHookTokens}from"#execution/session/hook-tokens.js";import{createSessionInbox}from"#execution/session-inbox/inbox.js";import{failSession,runPreparedSession}from"#execution/session/program.js";async function turnWorkflow(e){"use workflow";let t=await prepareLegacySessionStep(e),{sessionId:n}=t.sessionState,r=createSessionInbox(n);try{await r.claimSessionHook(sessionCommandHookToken(n))}catch(e){if(isHookConflictError(e))return;throw e}let{sessionWritable:i}=t.input,a;try{await r.claimSessionHooks(sessionHookTokens(t)),a=await interruptLegacySessionStep(t)}catch(e){return await r.dispose(),await failSession({error:e,serializedContext:t.serializedContext,sessionId:n,sessionState:t.sessionState,sessionWritable:i})}await runPreparedSession({anchor:{kind:`self`,notify:e=>completeLegacyDriverStep({completionToken:t.input.completionToken,history:t.history,result:e,serializedContext:t.serializedContext,sessionState:t.sessionState,sessionWritable:i})},caller:void 0,capabilities:t.input.capabilities,deploymentId:t.deploymentId,history:a.history,start:{input:t.input.delivery===void 0?void 0:{...t.input.delivery,caller:void 0},kind:`turn`},retention:t.input.retention,serializedContext:a.serializedContext,sessionId:n,sessionState:a.sessionState,sessionTimeoutMs:t.sessionTimeoutMs,sessionTimeoutDeadline:sessionTimeoutDeadline(t.sessionTimeoutMs,Date.now()),sessionWritable:i},r)}turnWorkflow.workflowId=`workflow//eve//turnWorkflow`;export{turnWorkflow};
|
|
@@ -20,3 +20,14 @@ export type RoutedDeliverResult = {
|
|
|
20
20
|
export declare function routeProxiedDeliverStep(input: SessionStepState & {
|
|
21
21
|
readonly delivery: DeliverHookPayload;
|
|
22
22
|
}): Promise<WithSessionStateDelta<RoutedDeliverResult>>;
|
|
23
|
+
/**
|
|
24
|
+
* Maps a delivery's channel-specific answers to the requests a held turn waits
|
|
25
|
+
* on, so the turn can tell they answer it. Returns the mapped delivery, or
|
|
26
|
+
* `undefined` when the channel maps none of them to one of `requestIds`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function mapHeldInputResponsesStep(input: SessionStepState & {
|
|
29
|
+
readonly delivery: DeliverHookPayload;
|
|
30
|
+
readonly requestIds: readonly string[];
|
|
31
|
+
}): Promise<WithSessionStateDelta<{
|
|
32
|
+
readonly delivery: DeliverHookPayload | undefined;
|
|
33
|
+
}>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuthKey}from"#context/keys.js";import{createInputResolvedEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{resolveRemoteAgentStreamHeaders,respondToRemoteAgentSession}from"#execution/agent-sessions/remote.js";import{readDurableSession,replaceDurableSessionSnapshot}from"#execution/durable-session-store.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{resumeSessionInbox}from"#execution/session-inbox/resume.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{relaySessionEvents}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{getProxyInputRequests,retireProxyInputRequests}from"#harness/proxy-input-requests.js";import{coalesceDeliverPayloads}from"#execution/deliver-payloads.js";import{hasDelegatedSessionContext}from"#execution/delegated-session-context.js";import{setChannelContext}from"#execution/channel-context.js";import{routeDeliverPayload}from"#subagents/hitl-proxy.js";import{sendWorkflowAskAnswers,toToolInputResponseResponder}from"#execution/tools/workflow/answer.js";async function routeProxiedDeliverStep(e){"use step";return await withSessionStateDelta(e,routeProxiedDeliver)}async function routeProxiedDeliver(e){let{delivery:
|
|
1
|
+
import{AuthKey}from"#context/keys.js";import{createInputResolvedEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{resolveRemoteAgentStreamHeaders,respondToRemoteAgentSession}from"#execution/agent-sessions/remote.js";import{readDurableSession,replaceDurableSessionSnapshot}from"#execution/durable-session-store.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{resumeSessionInbox}from"#execution/session-inbox/resume.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{relaySessionEvents}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{getProxyInputRequests,retireProxyInputRequests}from"#harness/proxy-input-requests.js";import{coalesceDeliverPayloads}from"#execution/deliver-payloads.js";import{hasDelegatedSessionContext}from"#execution/delegated-session-context.js";import{setChannelContext}from"#execution/channel-context.js";import{routeDeliverPayload}from"#subagents/hitl-proxy.js";import{sendWorkflowAskAnswers,toToolInputResponseResponder}from"#execution/tools/workflow/answer.js";async function routeProxiedDeliverStep(e){"use step";return await withSessionStateDelta(e,routeProxiedDeliver)}async function routeProxiedDeliver(e){let t=getProxyInputRequests(readDurableSession(e.sessionState).state),{delivery:n,serializedContext:r}=await deliverChannelInputResponses({...e,routable:e=>t.has(e.requestId)}),i=readDurableSession(e.sessionState),a=new Map,o=new Map,s,c=!hasDelegatedSessionContext(r)&&n.caller===void 0,l=new Set;for(let[e,t]of n.payloads.entries()){let r=routeDeliverPayload({allowRoute:e=>!l.has(e),payload:t,resolveMessage:c,state:i.state});s??=r.parentAction,r.forSelf!==void 0&&a.set(e,r.forSelf);for(let[t,i]of r.forChildren.entries()){if(i.workflowAsk!==void 0)for(let{requestId:e}of i.resolved.resolutions)l.add(e);let a=JSON.stringify([i.childContinuationToken,i.childSessionInbox?.sessionId??``,i.remote?.sessionId??``,i.resolved.event.sequence,i.resolved.event.stepIndex,i.resolved.event.turnId,i.inputSource??null]),s=o.get(a)??{workflowAsk:i.workflowAsk,remote:i.remote,childContinuationToken:i.childContinuationToken,childSessionInbox:i.childSessionInbox,event:i.resolved.event,metadata:[],payloads:[],resolutions:new Map},c=s.payloads.length;s.payloads.push(i.payload);for(let e of i.resolved.resolutions)s.resolutions.has(e.requestId)||s.resolutions.set(e.requestId,e);if(r.forSelf===void 0&&t===0)for(let t of n.deliveryMetadata??[])t.payloadIndex===e&&s.metadata.push({...t,payloadIndex:c});o.set(a,s)}}let u=!1,d=[];for(let e of o.values()){if(e.workflowAsk!==void 0){let t=coalesceDeliverPayloads(e.payloads).inputResponses??[];await sendWorkflowAskAnswers(e.workflowAsk,t,toToolInputResponseResponder(n.auth))}else{let t={...n,deliveryMetadata:e.metadata.length===0?void 0:e.metadata,payloads:e.payloads},i=e.remote;if(i!==void 0){let t=await deserializeContext(r),a=await resolveRemoteAgentStreamHeaders({bundle:t.require(BundleKey),name:i.name,resolverId:i.resolverId,url:i.url});await respondToRemoteAgentSession({remote:i,headers:a,auth:n.auth,responses:coalesceDeliverPayloads(e.payloads).inputResponses??[]})}else await resumeSessionInbox(e.childSessionInbox??e.childContinuationToken,t)}e.resolutions.size>0&&d.push(createInputResolvedEvent({resolutions:[...e.resolutions.values()],...e.event})),i=retireProxyInputRequests(i,[...e.resolutions.keys()]),u=!0}let f=await relaySessionEvents({serializedContext:r,sessionState:u?replaceDurableSessionSnapshot({session:i,state:e.sessionState}):e.sessionState,sessionWritable:e.sessionWritable},d);if(s!==void 0)return{...f,...s};let p=[...a].sort(([e],[t])=>e-t),m=p.flatMap(([e],t)=>(n.deliveryMetadata??[]).filter(t=>t.payloadIndex===e).map(e=>({...e,payloadIndex:t}))),h=p.length===0?void 0:{...n,deliveryMetadata:m.length===0?void 0:m,payloads:p.map(([,e])=>e)};return{...f,kind:`continue`,remainder:h}}async function mapHeldInputResponsesStep(e){"use step";return await withSessionStateDelta(e,async()=>{let t=new Set(e.requestIds),n=await deliverChannelInputResponses({...e,routable:e=>t.has(e.requestId)});return n.delivery===e.delivery?{delivery:void 0}:{delivery:n.delivery,serializedContext:n.serializedContext}})}async function deliverChannelInputResponses(e){let{routable:t}=e;if(!e.delivery.payloads.some(e=>e.inputResponses?.some(e=>!t(e))===!0))return e;let n=await deserializeContext(e.serializedContext),r=n.require(ChannelKey);if(r.deliver===void 0)return e;e.delivery.auth!==void 0&&n.set(AuthKey,e.delivery.auth??null);let i=r.state??{},a=!1,o=[];for(let s of e.delivery.payloads){if(s.inputResponses===void 0){o.push(s);continue}let e=[];for(let o of s.inputResponses){if(t(o)){e.push(o);continue}let c=buildAdapterContext({...r,state:structuredClone(i)},n),l=(await r.deliver({...s,inputResponses:[o],message:void 0},c))?.inputResponses?.filter(t)??[];if(l.length===0){e.push(o);continue}a=!0,i=c.state,e.push(...l)}o.push({...s,inputResponses:e})}if(!a)return e;let s=await deserializeContext(e.serializedContext);return setChannelContext(s,{...r,state:i}),{delivery:{...e.delivery,payloads:o},serializedContext:serializeContext(s)}}export{mapHeldInputResponsesStep,routeProxiedDeliverStep};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type MediaMetadata } from "#internal/attachments/media-metadata.js";
|
|
1
2
|
import type { SandboxSession } from "#shared/sandbox-session.js";
|
|
2
3
|
/**
|
|
3
4
|
* Typed input accepted by {@link executeReadFileOnSandbox}.
|
|
@@ -12,6 +13,11 @@ export interface ReadFileInput {
|
|
|
12
13
|
*/
|
|
13
14
|
export interface ReadFileResult {
|
|
14
15
|
readonly content: string;
|
|
16
|
+
/**
|
|
17
|
+
* Set when the file is a PNG, JPEG, GIF, or WebP image the model sees as
|
|
18
|
+
* an image. Carries no bytes, so `action.result` stays small.
|
|
19
|
+
*/
|
|
20
|
+
readonly image?: MediaMetadata;
|
|
15
21
|
readonly nextOffset?: number;
|
|
16
22
|
readonly path: string;
|
|
17
23
|
readonly totalLines: number;
|
|
@@ -20,7 +26,8 @@ export interface ReadFileResult {
|
|
|
20
26
|
/**
|
|
21
27
|
* Reads one text file from the sandbox, applies output shaping
|
|
22
28
|
* (offset, limit, line numbering, truncation), and persists a full-file
|
|
23
|
-
* stamp into durable read-file state for stale-write detection.
|
|
29
|
+
* stamp into durable read-file state for stale-write detection. Image
|
|
30
|
+
* files return their bytes for the model to view instead.
|
|
24
31
|
*
|
|
25
32
|
* Used by the framework `read_file` tool and authored wrappers around its
|
|
26
33
|
* exported definition.
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{loadContext}from"#context/container.js";import{MAX_OUTPUT_BYTES,capLineLength}from"#execution/sandbox/truncate-output.js";import{buildReadFileTargetKey,createReadFileStamp,normalizeModelPath,setReadFileStamp}from"#execution/tools/file-state.js";import{resolveAbsoluteFilePath}from"#execution/sandbox/require-sandbox.js";async function executeReadFileOnSandbox(e,t){let{filePath:n,offset:r,limit:i}=t,a=await resolveAbsoluteFilePath(e,n),o=normalizeModelPath(a),s=r??1,
|
|
2
|
-
`),d
|
|
3
|
-
`),
|
|
1
|
+
import{loadContext}from"#context/container.js";import{MAX_OUTPUT_BYTES,capLineLength}from"#execution/sandbox/truncate-output.js";import{buildReadFileTargetKey,createReadFileStamp,normalizeModelPath,setReadFileStamp}from"#execution/tools/file-state.js";import{resolveAbsoluteFilePath}from"#execution/sandbox/require-sandbox.js";import{readMediaMetadata}from"#internal/attachments/media-metadata.js";const IMAGE_MEDIA_TYPES={gif:`image/gif`,jpeg:`image/jpeg`,jpg:`image/jpeg`,png:`image/png`,webp:`image/webp`};async function executeReadFileOnSandbox(e,t){let{filePath:n,offset:r,limit:i}=t,a=await resolveAbsoluteFilePath(e,n),o=normalizeModelPath(a),s=IMAGE_MEDIA_TYPES[o.split(`.`).pop()?.toLowerCase()??``];if(s!==void 0)return await readImageFile(e,a,o,s);let c=r??1,l=i??2e3;if(c<1)throw Error(`offset must be >= 1. Received: ${c}.`);let u=await e.readTextFile({path:a});if(u===null)throw Error(`File not found: ${n}. Verify the path exists and is accessible in the sandbox.`);if(u.includes(`\0`))throw Error(`File "${n}" contains NUL bytes and appears to be a binary file. read_file only supports text files.`);let d=u.split(`
|
|
2
|
+
`),f=d.length>0&&d[d.length-1]===``?d.length-1:d.length;if(f===0){if(c>1)throw Error(`offset ${c} is past the end of the file (0 lines). Use the default offset to read an empty file.`)}else if(c>f)throw Error(`offset ${c} is past the end of the file (${f} lines).`);let p=createReadFileStamp({content:u,filePath:o}),m=buildReadFileTargetKey(o);if(setReadFileStamp(loadContext(),m,p),f===0)return{content:``,path:o,totalLines:0,truncated:!1};let h=c-1,g=Math.min(h+l,f),_=d.slice(h,g),v=[],y=0,b=!1;for(let e=0;e<_.length;e++){let t=`${c+e}: ${capLineLength(_[e]??``)}`,n=Buffer.byteLength(t,`utf8`)+1;if(y+n>MAX_OUTPUT_BYTES&&v.length>0){b=!0;break}v.push(t),y+=n}let x=v.join(`
|
|
3
|
+
`),S=c+v.length-1;return S<f||b?{content:x,nextOffset:S+1,path:o,totalLines:f,truncated:!0}:{content:x,path:o,totalLines:f,truncated:!1}}async function readImageFile(e,t,n,r){let i=await e.readBinaryFile({path:t});if(i===null)throw Error(`File not found: ${n}. Verify the path exists and is accessible in the sandbox.`);if(i.byteLength>3145728)throw Error(`Image "${n}" is ${i.byteLength} bytes; read_file shows images up to 3 MiB. Resize or crop it in the sandbox first.`);return{content:`Image ${n} (${r}, ${i.byteLength} bytes).`,image:readMediaMetadata(i,r),path:n,totalLines:0,truncated:!1}}export{executeReadFileOnSandbox};
|
|
@@ -36,6 +36,7 @@ export type RuntimeEvent = {
|
|
|
36
36
|
export declare class ActiveTurn {
|
|
37
37
|
private readonly admitted;
|
|
38
38
|
private readonly routedToChildren;
|
|
39
|
+
private readonly mappedForHeldRequest;
|
|
39
40
|
private readonly runtimeResults;
|
|
40
41
|
private readonly controller;
|
|
41
42
|
private readonly expectedTurnId;
|
|
@@ -47,6 +48,8 @@ export declare class ActiveTurn {
|
|
|
47
48
|
private steeringController;
|
|
48
49
|
/** The delegated caller of the latest message the turn read. */
|
|
49
50
|
caller: TurnCaller | undefined;
|
|
51
|
+
/** A step of this turn compacted the history. */
|
|
52
|
+
compacted: boolean;
|
|
50
53
|
constructor(input: SessionExecutionInput, owner: {
|
|
51
54
|
readonly caller: TurnCaller | undefined;
|
|
52
55
|
readonly principal: string;
|
|
@@ -81,7 +84,7 @@ export declare class ActiveTurn {
|
|
|
81
84
|
* responder: an approver need not be the turn's own person. Returns
|
|
82
85
|
* `undefined` when no admitted delivery answers one.
|
|
83
86
|
*/
|
|
84
|
-
takeInputResponses(requestIds: ReadonlySet<string>): DeliverHookPayload | undefined
|
|
87
|
+
takeInputResponses(requestIds: ReadonlySet<string>): Promise<DeliverHookPayload | undefined>;
|
|
85
88
|
/** Resolves with the id of the call whose timer won, or `undefined` once inbox input is ready. */
|
|
86
89
|
private waitForInboxOrTimer;
|
|
87
90
|
private cancelsThisTurn;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{coalesceDeliveries}from"#harness/messages.js";import{activeTurnId}from"#harness/active-turn-id.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{admitSessionInboxPayload}from"#execution/session/admission.js";import{isSteeringMessage}from"#execution/session/input-queue.js";import{routeSelectedDelivery}from"#execution/session/route-selected-delivery.js";import{decodeSessionInboxPayload}from"#execution/session-inbox/protocol.js";import{TurnCancelledError}from"#harness/turn-cancellation.js";var ActiveTurn=class{admitted=new Set;routedToChildren=new Set;runtimeResults=[];controller=new AbortController;expectedTurnId;input;identity;unsubscribe;unsubscribeDelivery;steeringController=new AbortController;caller;constructor(e,t){this.input=e,this.caller=t.caller,this.identity={callerCallId:t.caller?.callId,principal:t.principal},this.expectedTurnId=activeTurnId(e.cursor.sessionState.emissionState),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}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`}}}takeInputResponses(e){for(let t of this.admitted){let n=this.input.queue.delivery(t);if(n
|
|
1
|
+
import{coalesceDeliveries}from"#harness/messages.js";import{activeTurnId}from"#harness/active-turn-id.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{isSteeringMessage}from"#execution/session/input-queue.js";import{routeSelectedDelivery}from"#execution/session/route-selected-delivery.js";import{decodeSessionInboxPayload}from"#execution/session-inbox/protocol.js";import{TurnCancelledError}from"#harness/turn-cancellation.js";var ActiveTurn=class{admitted=new Set;routedToChildren=new Set;mappedForHeldRequest=new Set;runtimeResults=[];controller=new AbortController;expectedTurnId;input;identity;unsubscribe;unsubscribeDelivery;steeringController=new AbortController;caller;compacted=!1;constructor(e,t){this.input=e,this.caller=t.caller,this.identity={callerCallId:t.caller?.callId,principal:t.principal},this.expectedTurnId=activeTurnId(e.cursor.sessionState.emissionState),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}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){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}return this.admitted.delete(t),this.input.queue.replaceDelivery(t,void 0),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`?!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}export{ActiveTurn};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type SessionCheckpoint } from "#execution/session/handoff.js";
|
|
2
|
+
/**
|
|
3
|
+
* Oldest checkpoint a successor upgrades (eve 0.66.0). Earlier checkpoints
|
|
4
|
+
* predate the sandbox provider and dynamic skill manifest contracts and lack
|
|
5
|
+
* data the current reader requires.
|
|
6
|
+
*/
|
|
7
|
+
export declare const MIN_SESSION_CHECKPOINT_VERSION = 8;
|
|
8
|
+
export type SessionCheckpointMigration = {
|
|
9
|
+
readonly kind: "current";
|
|
10
|
+
readonly checkpoint: SessionCheckpoint;
|
|
11
|
+
/** Idle child sessions the current build no longer tracks; the successor stops them. */
|
|
12
|
+
readonly childRunIdsToStop: readonly string[];
|
|
13
|
+
} | {
|
|
14
|
+
readonly kind: "incompatible";
|
|
15
|
+
readonly detail: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Upgrades a checkpoint written by an older eve build to the current shape.
|
|
19
|
+
* Pure, so the session workflow can run it before validation. Newer
|
|
20
|
+
* checkpoints and those older than {@link MIN_SESSION_CHECKPOINT_VERSION} are
|
|
21
|
+
* incompatible.
|
|
22
|
+
*/
|
|
23
|
+
export declare function migrateSessionCheckpoint(checkpoint: unknown): SessionCheckpointMigration;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isObject}from"#shared/guards.js";import{SESSION_CHECKPOINT_VERSION}from"#execution/session/handoff.js";const MIN_SESSION_CHECKPOINT_VERSION=8,CHECKPOINT_UPGRADES={8:e=>{let{mode:t,...n}=e;return{...n,serializedContext:omitKeys(readRecord(n,`serializedContext`),[`eve.mode`])}},9:(e,t)=>{let n=readRecord(e,`sessionState`),r=readRecord(n,`snapshot`),{taskId:i,...a}=readRecord(r,`session`);return{...e,serializedContext:upgradeLegacyCaller(omitKeys(readRecord(e,`serializedContext`),[`eve.activityObserver`,`eve.activityPendingBlockers`,`eve.activityRootTurnId`,`eve.connectionSearchResults`,`eve.internal.backgroundToolExecution`,`eve.runtime.taskDeliveryPolicy`,`eve.turnTaskDelivery`])),sessionState:{...n,snapshot:{...r,session:{...a,history:readArray(a,`history`).map(renameBackgroundTaskMessage),state:upgradeSessionState(a.state,t)}}}}},10:e=>{let t=readRecord(e,`sessionState`),n=readRecord(t,`snapshot`),{history:r,...i}=readRecord(n,`session`);return t.version!==1&&refuse(`durable session version is not 1`),Array.isArray(r)||refuse(`session history is missing`),{...e,history:r,sessionState:{...t,snapshot:{...n,session:i},version:2}}}};function migrateSessionCheckpoint(e){if(!isObject(e))return{kind:`incompatible`,detail:`checkpoint is not an object`};let{version:t}=e;if(typeof t!=`number`||!Number.isSafeInteger(t)||t<8||t>SESSION_CHECKPOINT_VERSION)return{kind:`incompatible`,detail:`checkpoint version ${JSON.stringify(t)} is outside the supported range 8-${SESSION_CHECKPOINT_VERSION}`};let n={childRunIdsToStop:[]},r=e;try{for(let e=t;e<SESSION_CHECKPOINT_VERSION;e++){let t=CHECKPOINT_UPGRADES[e];t===void 0&&refuse(`no upgrade from checkpoint version ${e}`),r={...t(r,n),version:e+1}}}catch(e){if(!(e instanceof CheckpointRefusal))throw e;return{kind:`incompatible`,detail:`checkpoint version ${t}: ${e.message}`}}return isCurrentCheckpoint(r)?{kind:`current`,checkpoint:r,childRunIdsToStop:n.childRunIdsToStop}:{kind:`incompatible`,detail:`checkpoint version ${t} is incomplete`}}function isCurrentCheckpoint(e){return isObject(e)&&e.version===SESSION_CHECKPOINT_VERSION&&Array.isArray(e.history)&&isObject(e.serializedContext)&&isObject(e.sessionState)}var CheckpointRefusal=class extends Error{};function refuse(e){throw new CheckpointRefusal(e)}function readRecord(e,t){let n=e[t];return isObject(n)||refuse(`${t} is not an object`),n}function readArray(e,t){let n=e[t];return Array.isArray(n)||refuse(`${t} is not an array`),n}function omitKeys(e,t){return Object.fromEntries(Object.entries(e).filter(([e])=>!t.includes(e)))}function upgradeLegacyCaller(e){let t=e[`eve.sessionCallback`];if(!isObject(t))return e;let{taskId:n,...r}=t;return{...e,"eve.legacyRemoteAgentCaller":typeof n==`string`&&n.length>0?{taskId:n}:{},"eve.sessionCallback":r}}function renameBackgroundTaskMessage(e){return isObject(e)&&e.role===`user`&&e.kind===`execution.background_task`?{...e,kind:`task.result`}:e}function upgradeSessionState(e,t){return isObject(e)?omitKeys(e,[...dropSettledWorkflowToolRuns(e),...stopIdleSubagents(e,t)]):e}function dropSettledWorkflowToolRuns(e){let t=e[`eve.workflowTool`];if(!isObject(t)||t.version!==3)return[];let n=t.runs;return(!Array.isArray(n)||!n.every(e=>isObject(e)&&e.lifetime===`session`&&isObject(e.task)&&e.task.outcome!==void 0))&&refuse(`workflow tool run registry version 3 holds unsettled runs`),[`eve.workflowTool`]}function stopIdleSubagents(e,t){let n=e[`eve.agent.handles`];if(n===void 0)return[];(!isObject(n)||!Array.isArray(n.handles))&&refuse(`subagent handles are malformed`);for(let e of n.handles){(!isObject(e)||e.phase!==`parked`&&e.phase!==`available`)&&refuse(`a subagent session is still working`);let n=e.address;isObject(n)&&(n.kind===`agent/local`||n.kind===`agent/self`)&&typeof n.sessionId==`string`&&n.sessionId.length>0&&t.childRunIdsToStop.push(n.sessionId)}return[`eve.agent.handles`]}export{MIN_SESSION_CHECKPOINT_VERSION,migrateSessionCheckpoint};
|
|
@@ -21,12 +21,30 @@ export interface InitialWorkflowEntryInput {
|
|
|
21
21
|
readonly sessionTimeoutMs?: number | false;
|
|
22
22
|
readonly serializedContext: Record<string, unknown>;
|
|
23
23
|
}
|
|
24
|
-
/**
|
|
25
|
-
export
|
|
24
|
+
/** Why a previous owner started a successor, and what the successor does first. */
|
|
25
|
+
export type SessionHandoffStart = {
|
|
26
|
+
/** The one delivery that triggered a deployment handoff; processed before any later arrival. */
|
|
27
|
+
readonly delivery: DeliverHookPayload;
|
|
28
|
+
readonly reason?: undefined;
|
|
29
|
+
} | {
|
|
30
|
+
/**
|
|
31
|
+
* The previous owner compacted the session and moved it to a fresh run on
|
|
32
|
+
* its own deployment, so no single run's event log grows with the
|
|
33
|
+
* session.
|
|
34
|
+
*/
|
|
35
|
+
readonly reason: "compaction";
|
|
36
|
+
/**
|
|
37
|
+
* The lone delivery that arrived before the owner could move, processed
|
|
38
|
+
* first. Without one, the successor parks until the next input arrives.
|
|
39
|
+
*/
|
|
40
|
+
readonly delivery?: DeliverHookPayload;
|
|
41
|
+
/** Compaction does not extend the session's lifetime. */
|
|
42
|
+
readonly sessionTimeoutDeadline?: Date;
|
|
43
|
+
};
|
|
44
|
+
/** A successor owner started by a previous owner during a handoff. */
|
|
45
|
+
export type HandoffWorkflowEntryInput = SessionHandoffStart & {
|
|
26
46
|
readonly activationToken: string;
|
|
27
47
|
readonly checkpoint: SessionCheckpoint;
|
|
28
|
-
/** The one delivery that triggered the handoff; processed before any later arrival. */
|
|
29
|
-
readonly delivery: DeliverHookPayload;
|
|
30
48
|
/** Omitted by version 1 sources, whose hooks cannot safely be force-claimed. */
|
|
31
49
|
readonly handoffVersion?: number;
|
|
32
50
|
readonly kind: "handoff";
|
|
@@ -34,7 +52,7 @@ export interface HandoffWorkflowEntryInput {
|
|
|
34
52
|
readonly sessionWritable: WritableStream<Uint8Array>;
|
|
35
53
|
/** Stable public identity; also the original run that anchors the stream. */
|
|
36
54
|
readonly sessionId: string;
|
|
37
|
-
}
|
|
55
|
+
};
|
|
38
56
|
export type WorkflowEntryInput = InitialWorkflowEntryInput | HandoffWorkflowEntryInput;
|
|
39
57
|
export interface WorkflowEntryResult {
|
|
40
58
|
readonly isError?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{attachClientContext,readClientContext}from"#internal/client-context.js";import{SESSION_INBOX_CONTEXT_KEY,sessionCommandHookToken}from"#execution/session-inbox/address.js";import{getWorkflowMetadata,getWritable}from"#compiled/@workflow/core/index.js";import{isHookConflictError}from"#execution/hook-ownership.js";import{DEFAULT_SESSION_TIMEOUT_MS,sessionTimeoutDeadline}from"#execution/session/timeout.js";import{sessionHookTokens}from"#execution/session/hook-tokens.js";import{createSessionInbox}from"#execution/session-inbox/inbox.js";import{failSession,runPreparedSession}from"#execution/session/program.js";import{hasDelegatedSessionContext}from"#execution/delegated-session-context.js";import{readChannelRequestId,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{resolveInitialTurnCallerStep}from"#subagents/parent-notification.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{createSessionStep}from"#execution/create-session-step.js";import{settleContinuationConflictStep}from"#execution/continuation-conflict-step.js";import{signalSessionOwnerActivationStep,validateSessionCheckpointStep}from"#execution/session/handoff-steps.js";async function workflowEntry(e){"use workflow";let t=e.kind===`initial`?await bootInitialOwner(e,getWorkflowMetadata().workflowRunId):await bootHandoffOwner(e);return t===void 0?{output:``}:{output:(await runPreparedSession(t.session,t.inbox)).output}}function stampSessionIdentity(e,t){return{...e,"eve.sessionId":t,[SESSION_INBOX_CONTEXT_KEY]:{sessionId:t}}}async function bootInitialOwner(e,t){let n=stampSessionIdentity(e.serializedContext,t),r=getWritable(),i=createSessionInbox(t),{workflowStartedAt:a}=getWorkflowMetadata(),o=e.sessionTimeoutMs??DEFAULT_SESSION_TIMEOUT_MS,s=n[`eve.continuationToken`]||``,c=n[`eve.bundle`];try{let[l,u,d]=await Promise.allSettled([createSessionStep({compiledArtifactsSource:c.source,continuationToken:s,dynamicSubagentAgentConfig:n[`eve.dynamicSubagentAgentConfig`],inheritedLimits:e.limits,nodeId:c.nodeId,outputSchema:e.input.outputSchema,rootSessionId:readRootSessionId(n),sessionId:t}),i.claimSessionHook(sessionCommandHookToken(t)),s===``?Promise.resolve():i.claimSessionHook(s)]);if(l.status===`rejected`)throw l.reason;if(u.status===`rejected`)throw u.reason;if(d.status===`rejected`){if(!isHookConflictError(d.reason))throw d.reason;e.continuationConflictCommand!==void 0&&await settleContinuationConflictStep({command:e.continuationConflictCommand,continuationToken:s}),await i.dispose();return}return{inbox:i,session:{anchor:{kind:`self`},caller:
|
|
1
|
+
import{attachClientContext,readClientContext}from"#internal/client-context.js";import{SESSION_INBOX_CONTEXT_KEY,sessionCommandHookToken}from"#execution/session-inbox/address.js";import{getWorkflowMetadata,getWritable}from"#compiled/@workflow/core/index.js";import{isHookConflictError}from"#execution/hook-ownership.js";import{DEFAULT_SESSION_TIMEOUT_MS,sessionTimeoutDeadline}from"#execution/session/timeout.js";import{sessionHookTokens}from"#execution/session/hook-tokens.js";import{createSessionInbox}from"#execution/session-inbox/inbox.js";import{failSession,runPreparedSession}from"#execution/session/program.js";import{hasDelegatedSessionContext}from"#execution/delegated-session-context.js";import{readChannelRequestId,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{resolveInitialTurnCallerStep}from"#subagents/parent-notification.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{createSessionStep}from"#execution/create-session-step.js";import{settleContinuationConflictStep}from"#execution/continuation-conflict-step.js";import{signalSessionOwnerActivationStep,stopUntrackedChildSessionsStep,validateSessionCheckpointStep}from"#execution/session/handoff-steps.js";import{migrateSessionCheckpoint}from"#execution/session/checkpoint-migrations.js";async function workflowEntry(e){"use workflow";let t=e.kind===`initial`?await bootInitialOwner(e,getWorkflowMetadata().workflowRunId):await bootHandoffOwner(e);return t===void 0?{output:``}:{output:(await runPreparedSession(t.session,t.inbox)).output}}function stampSessionIdentity(e,t){return{...e,"eve.sessionId":t,[SESSION_INBOX_CONTEXT_KEY]:{sessionId:t}}}async function bootInitialOwner(e,t){let n=stampSessionIdentity(e.serializedContext,t),r=getWritable(),i=createSessionInbox(t),{workflowStartedAt:a}=getWorkflowMetadata(),o=e.sessionTimeoutMs??DEFAULT_SESSION_TIMEOUT_MS,s=n[`eve.continuationToken`]||``,c=n[`eve.bundle`];try{let[l,u,d,f]=await Promise.allSettled([createSessionStep({compiledArtifactsSource:c.source,continuationToken:s,dynamicSubagentAgentConfig:n[`eve.dynamicSubagentAgentConfig`],inheritedLimits:e.limits,nodeId:c.nodeId,outputSchema:e.input.outputSchema,rootSessionId:readRootSessionId(n),sessionId:t}),i.claimSessionHook(sessionCommandHookToken(t)),s===``?Promise.resolve():i.claimSessionHook(s),hasDelegatedSessionContext(n)?resolveInitialTurnCallerStep({serializedContext:n}):Promise.resolve(void 0)]);if(l.status===`rejected`)throw l.reason;if(u.status===`rejected`)throw u.reason;if(d.status===`rejected`){if(!isHookConflictError(d.reason))throw d.reason;e.continuationConflictCommand!==void 0&&await settleContinuationConflictStep({command:e.continuationConflictCommand,continuationToken:s}),await i.dispose();return}if(f.status===`rejected`)throw f.reason;return{inbox:i,session:{anchor:{kind:`self`},caller:f.value,capabilities:n[`eve.capabilities`],deploymentId:e.ownerDeploymentId,history:l.value.history,start:e.input.message===void 0?{kind:`first-message`}:{input:createInitialDelivery(e,n),kind:`turn`},retention:e.retention,serializedContext:n,sessionId:t,sessionState:l.value.state,sessionTimeoutMs:o,sessionTimeoutDeadline:sessionTimeoutDeadline(o,a.getTime()),sessionWritable:r}}}catch(e){return await i.dispose(),await failSession({error:e,serializedContext:n,sessionId:t,sessionState:void 0,sessionWritable:r})}}async function bootHandoffOwner(e){let{sessionId:t}=e,n=createSessionInbox(t),r,i,a;try{let o=migrateSessionCheckpoint(e.checkpoint),s=await validateSessionCheckpointStep({migration:o,sessionId:t});if(o.kind===`incompatible`||s.kind===`incompatible`){let t=await n.release();await signalSessionOwnerActivationStep({activation:{kind:`incompatible`,payloads:t,reason:`checkpoint-version`},token:e.activationToken});return}({checkpoint:r,childRunIdsToStop:i}=o),a=stampSessionIdentity(r.serializedContext,t),await n.claimSessionHooks(sessionHookTokens({serializedContext:a,sessionState:r.sessionState})),await signalSessionOwnerActivationStep({activation:{kind:`active`},token:e.activationToken})}catch(t){let r=await n.release();await signalSessionOwnerActivationStep({activation:{error:normalizeSerializableError(t),kind:`failed`,payloads:r},token:e.activationToken});return}i.length>0&&await stopUntrackedChildSessionsStep({runIds:i,sessionId:t});let o=e.reason===`compaction`;return{inbox:n,session:{anchor:{kind:`successor`},caller:e.delivery?.caller,capabilities:r.capabilities,deploymentId:e.ownerDeploymentId,history:r.history,start:e.delivery===void 0?{kind:`parked`}:{input:e.delivery,kind:`turn`},retention:r.retention,serializedContext:a,sessionId:t,sessionState:r.sessionState,sessionTimeoutMs:r.sessionTimeoutMs,sessionTimeoutDeadline:o?e.sessionTimeoutDeadline:sessionTimeoutDeadline(r.sessionTimeoutMs,Date.now()),sessionWritable:e.sessionWritable}}}function createInitialDelivery(e,t){if(e.input.message!==void 0)return{deliveryMetadata:t[`eve.channelDelivery`]===void 0?void 0:[{...t[`eve.channelDelivery`],payloadIndex:0}],kind:`deliver`,payloads:[attachClientContext({message:e.input.message,context:e.input.context,outputSchema:e.input.outputSchema,state:e.input.state},readClientContext(e.input))],requestId:readChannelRequestId(t)}}workflowEntry.workflowId=`workflow//eve//workflowEntry`;export{workflowEntry};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getSessionUsage,takeSessionUsageDelta}from"#harness/turn-tag-state.js";import{terminateChildSessionsStep}from"#execution/terminate-child-sessions-step.js";import{notifyTurnCallerStep}from"#subagents/parent-notification.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{emitTerminalSessionCompletionStep}from"#execution/terminal-session-completion-step.js";import{emitTerminalSessionFailureStep}from"#execution/terminal-session-failure-step.js";async function finalizeSession(e,t){let{serializedContext:n,sessionState:r}=t.cursor;r!==void 0&&await terminateChildSessionsStep({sessionState:r});let i=r?.snapshot.session,a=i===void 0?void 0:getSessionUsage(i);e.kind===`expired`?await emitTerminalSessionCompletionStep({sessionWritable:t.sessionWritable,serializedContext:n,usage:a}):e.kind===`failed`&&await emitTerminalSessionFailureStep({error:normalizeSerializableError(e.error),sessionWritable:t.sessionWritable,serializedContext:n,turnId:e.turnId,usage:a});let o=settledResult(e,t);if(t.caller!==void 0){let e={output:o.output,usage:o.turnUsage};o.isError&&(e.isError=!0),await notifyTurnCallerStep({caller:t.caller,lifecycle:`terminal`,sessionId:r?.sessionId??n[`eve.sessionId`],settled:e})}return e.kind===`done`?{isError:e.action.isError,output:e.action.output,usage:e.action.usage,usageDelta:e.action.usageDelta}:{isError:o.isError,output:o.output,usage:o.sessionUsage,usageDelta:o.turnUsage}}function settledResult(e,t){let n=t.cursor.sessionState?.snapshot.session,r=n===void 0||t.caller===void 0?{}:{sessionUsage:getSessionUsage(n),turnUsage:takeSessionUsageDelta(n).delta};switch(e.kind){case`done`:return{isError:e.action.isError===!0,output:e.action.output,sessionUsage:e.action.usage,turnUsage:e.action.usageDelta};case`expired`:return t.caller===void 0?{isError:!1,output:``}:{isError:!0,output:`The session ended before the delegated task completed.`,...r};case`failed`:return{isError:!0,output:normalizeSerializableError(e.error),...r}}}export{finalizeSession};
|
|
1
|
+
import{liveTaskRuns,readTaskTable}from"#execution/tasks/table.js";import{getSessionUsage,takeSessionUsageDelta}from"#harness/turn-tag-state.js";import{terminateChildSessionsStep}from"#execution/terminate-child-sessions-step.js";import{notifyTurnCallerStep}from"#subagents/parent-notification.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{emitTerminalSessionCompletionStep}from"#execution/terminal-session-completion-step.js";import{emitTerminalSessionFailureStep}from"#execution/terminal-session-failure-step.js";async function finalizeSession(e,t){let{serializedContext:n,sessionState:r}=t.cursor;r!==void 0&&liveTaskRuns(readTaskTable(r.snapshot?.session?.state)).length>0&&await terminateChildSessionsStep({sessionState:r});let i=r?.snapshot.session,a=i===void 0?void 0:getSessionUsage(i);e.kind===`expired`?await emitTerminalSessionCompletionStep({sessionWritable:t.sessionWritable,serializedContext:n,usage:a}):e.kind===`failed`&&await emitTerminalSessionFailureStep({error:normalizeSerializableError(e.error),sessionWritable:t.sessionWritable,serializedContext:n,turnId:e.turnId,usage:a});let o=settledResult(e,t);if(t.caller!==void 0){let e={output:o.output,usage:o.turnUsage};o.isError&&(e.isError=!0),await notifyTurnCallerStep({caller:t.caller,lifecycle:`terminal`,sessionId:r?.sessionId??n[`eve.sessionId`],settled:e})}return e.kind===`done`?{isError:e.action.isError,output:e.action.output,usage:e.action.usage,usageDelta:e.action.usageDelta}:{isError:o.isError,output:o.output,usage:o.sessionUsage,usageDelta:o.turnUsage}}function settledResult(e,t){let n=t.cursor.sessionState?.snapshot.session,r=n===void 0||t.caller===void 0?{}:{sessionUsage:getSessionUsage(n),turnUsage:takeSessionUsageDelta(n).delta};switch(e.kind){case`done`:return{isError:e.action.isError===!0,output:e.action.output,sessionUsage:e.action.usage,turnUsage:e.action.usageDelta};case`expired`:return t.caller===void 0?{isError:!1,output:``}:{isError:!0,output:`The session ended before the delegated task completed.`,...r};case`failed`:return{isError:!0,output:normalizeSerializableError(e.error),...r}}}export{finalizeSession};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { SessionCheckpointMigration } from "#execution/session/checkpoint-migrations.js";
|
|
1
2
|
import { type DurableSessionState } from "#execution/durable-session-store.js";
|
|
2
|
-
import { type
|
|
3
|
+
import { type SessionOwnerActivation } from "#execution/session/handoff.js";
|
|
3
4
|
/** Parses retained work with this deployment's code before deciding whether it can move. */
|
|
4
5
|
export declare function isSessionStateIdleForHandoff(sessionState: DurableSessionState): boolean;
|
|
5
6
|
/** Reads durable work using the source deployment's handoff contract. */
|
|
@@ -13,14 +14,32 @@ export type SessionCheckpointValidation = {
|
|
|
13
14
|
readonly reason: "checkpoint-version";
|
|
14
15
|
};
|
|
15
16
|
/**
|
|
16
|
-
* Validates
|
|
17
|
+
* Validates an upgraded checkpoint and resolves the target deployment's
|
|
18
|
+
* compiled bundle.
|
|
17
19
|
*
|
|
18
|
-
* A
|
|
19
|
-
* it returns rather than throws: retrying the step can never change it.
|
|
20
|
+
* A checkpoint this deployment cannot read is a settled answer, not a fault,
|
|
21
|
+
* so it returns rather than throws: retrying the step can never change it.
|
|
20
22
|
*/
|
|
21
23
|
export declare function validateSessionCheckpointStep(input: {
|
|
22
|
-
readonly
|
|
24
|
+
readonly migration: SessionCheckpointMigration;
|
|
25
|
+
readonly sessionId: string;
|
|
23
26
|
}): Promise<SessionCheckpointValidation>;
|
|
27
|
+
/**
|
|
28
|
+
* Stops idle subagent sessions an older owner kept resumable, after this owner
|
|
29
|
+
* activates. Best effort: a child that cannot be stopped ends at its own timeout.
|
|
30
|
+
*/
|
|
31
|
+
export declare function stopUntrackedChildSessionsStep(input: {
|
|
32
|
+
readonly runIds: readonly string[];
|
|
33
|
+
readonly sessionId: string;
|
|
34
|
+
}): Promise<void>;
|
|
35
|
+
/** Records why the owner kept a session it tried to move, so a stuck handoff is visible. */
|
|
36
|
+
export declare function reportSessionHandoffRetainedStep(input: {
|
|
37
|
+
readonly error?: string;
|
|
38
|
+
readonly reason: "activation-failed" | "checkpoint-incompatible";
|
|
39
|
+
readonly sessionId: string;
|
|
40
|
+
readonly sourceDeploymentId: string;
|
|
41
|
+
readonly targetDeploymentId: string;
|
|
42
|
+
}): Promise<void>;
|
|
24
43
|
export declare function signalSessionOwnerActivationStep(input: {
|
|
25
44
|
readonly activation: SessionOwnerActivation;
|
|
26
45
|
readonly token: string;
|