@archmax-ai/harness 0.0.0
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/LICENSE +21 -0
- package/README.md +219 -0
- package/dist/agent.d.ts +174 -0
- package/dist/agent.js +140 -0
- package/dist/agent.js.map +1 -0
- package/dist/assembly/compose.d.ts +170 -0
- package/dist/assembly/compose.js +391 -0
- package/dist/assembly/compose.js.map +1 -0
- package/dist/assembly/delegation-registry.d.ts +5 -0
- package/dist/assembly/delegation-registry.js +118 -0
- package/dist/assembly/delegation-registry.js.map +1 -0
- package/dist/assembly/index.d.ts +192 -0
- package/dist/assembly/index.js +265 -0
- package/dist/assembly/index.js.map +1 -0
- package/dist/assembly/plain.d.ts +7 -0
- package/dist/assembly/plain.js +41 -0
- package/dist/assembly/plain.js.map +1 -0
- package/dist/authoring-skill/archmax-harness/README.md +76 -0
- package/dist/authoring-skill/archmax-harness/SKILL.md +241 -0
- package/dist/authoring-skill/archmax-harness/references/backend-integration.md +626 -0
- package/dist/authoring-skill/archmax-harness/references/cases.md +41 -0
- package/dist/authoring-skill/archmax-harness/references/diagnostics.md +51 -0
- package/dist/authoring-skill/archmax-harness/references/hook-and-test-scripts.md +1070 -0
- package/dist/authoring-skill/archmax-harness/references/hooks-and-scripts.md +82 -0
- package/dist/authoring-skill/archmax-harness/references/wiring.md +101 -0
- package/dist/authoring-skill/archmax-harness/references/workflow-schema.md +1631 -0
- package/dist/authoring-skill/archmax-harness/references/workflow-yaml.md +241 -0
- package/dist/behaviour/support.d.ts +232 -0
- package/dist/behaviour/support.js +339 -0
- package/dist/behaviour/support.js.map +1 -0
- package/dist/cli/banner.d.ts +11 -0
- package/dist/cli/banner.js +29 -0
- package/dist/cli/banner.js.map +1 -0
- package/dist/cli/bootstrap.d.ts +33 -0
- package/dist/cli/bootstrap.js +153 -0
- package/dist/cli/bootstrap.js.map +1 -0
- package/dist/cli/command.d.ts +39 -0
- package/dist/cli/command.js +97 -0
- package/dist/cli/command.js.map +1 -0
- package/dist/cli/state-flow.d.ts +46 -0
- package/dist/cli/state-flow.js +268 -0
- package/dist/cli/state-flow.js.map +1 -0
- package/dist/cli/style.d.ts +41 -0
- package/dist/cli/style.js +64 -0
- package/dist/cli/style.js.map +1 -0
- package/dist/cli/turn.d.ts +41 -0
- package/dist/cli/turn.js +161 -0
- package/dist/cli/turn.js.map +1 -0
- package/dist/cli.d.ts +10 -0
- package/dist/cli.js +426 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/code-description.d.ts +22 -0
- package/dist/core/code-description.js +38 -0
- package/dist/core/code-description.js.map +1 -0
- package/dist/core/deepagents.d.ts +183 -0
- package/dist/core/deepagents.js +128 -0
- package/dist/core/deepagents.js.map +1 -0
- package/dist/core/events.d.ts +350 -0
- package/dist/core/events.js +205 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/frontmatter.d.ts +15 -0
- package/dist/core/frontmatter.js +32 -0
- package/dist/core/frontmatter.js.map +1 -0
- package/dist/core/listing-redact.d.ts +37 -0
- package/dist/core/listing-redact.js +88 -0
- package/dist/core/listing-redact.js.map +1 -0
- package/dist/core/match.d.ts +26 -0
- package/dist/core/match.js +75 -0
- package/dist/core/match.js.map +1 -0
- package/dist/core/message-readers.d.ts +84 -0
- package/dist/core/message-readers.js +159 -0
- package/dist/core/message-readers.js.map +1 -0
- package/dist/core/messages.d.ts +49 -0
- package/dist/core/messages.js +85 -0
- package/dist/core/messages.js.map +1 -0
- package/dist/core/mount-prompt.d.ts +28 -0
- package/dist/core/mount-prompt.js +55 -0
- package/dist/core/mount-prompt.js.map +1 -0
- package/dist/core/mount-redact.d.ts +28 -0
- package/dist/core/mount-redact.js +32 -0
- package/dist/core/mount-redact.js.map +1 -0
- package/dist/core/mounts.d.ts +88 -0
- package/dist/core/mounts.js +147 -0
- package/dist/core/mounts.js.map +1 -0
- package/dist/core/path-mapping.d.ts +52 -0
- package/dist/core/path-mapping.js +113 -0
- package/dist/core/path-mapping.js.map +1 -0
- package/dist/core/platform-prompt.generated.d.ts +2 -0
- package/dist/core/platform-prompt.generated.js +4 -0
- package/dist/core/platform-prompt.generated.js.map +1 -0
- package/dist/core/prompt.d.ts +42 -0
- package/dist/core/prompt.js +75 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/session-id.d.ts +38 -0
- package/dist/core/session-id.js +61 -0
- package/dist/core/session-id.js.map +1 -0
- package/dist/core/session-store.d.ts +85 -0
- package/dist/core/session-store.js +149 -0
- package/dist/core/session-store.js.map +1 -0
- package/dist/core/session-zone.d.ts +54 -0
- package/dist/core/session-zone.js +82 -0
- package/dist/core/session-zone.js.map +1 -0
- package/dist/core/skill-prompt.d.ts +31 -0
- package/dist/core/skill-prompt.js +54 -0
- package/dist/core/skill-prompt.js.map +1 -0
- package/dist/core/skill-redact.d.ts +15 -0
- package/dist/core/skill-redact.js +27 -0
- package/dist/core/skill-redact.js.map +1 -0
- package/dist/core/skills.d.ts +172 -0
- package/dist/core/skills.js +214 -0
- package/dist/core/skills.js.map +1 -0
- package/dist/core/tool-mocks.d.ts +23 -0
- package/dist/core/tool-mocks.js +39 -0
- package/dist/core/tool-mocks.js.map +1 -0
- package/dist/core/tool-telemetry.d.ts +16 -0
- package/dist/core/tool-telemetry.js +40 -0
- package/dist/core/tool-telemetry.js.map +1 -0
- package/dist/core/usage.d.ts +114 -0
- package/dist/core/usage.js +226 -0
- package/dist/core/usage.js.map +1 -0
- package/dist/core/workspace-context.d.ts +136 -0
- package/dist/core/workspace-context.js +178 -0
- package/dist/core/workspace-context.js.map +1 -0
- package/dist/core/workspace-prompt.d.ts +7 -0
- package/dist/core/workspace-prompt.js +102 -0
- package/dist/core/workspace-prompt.js.map +1 -0
- package/dist/core/workspace-router.d.ts +61 -0
- package/dist/core/workspace-router.js +145 -0
- package/dist/core/workspace-router.js.map +1 -0
- package/dist/core/workspace.d.ts +85 -0
- package/dist/core/workspace.js +193 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/core/zones.d.ts +181 -0
- package/dist/core/zones.js +202 -0
- package/dist/core/zones.js.map +1 -0
- package/dist/env.d.ts +99 -0
- package/dist/env.js +271 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +265 -0
- package/dist/index.js +197 -0
- package/dist/index.js.map +1 -0
- package/dist/kernel/kernel.d.ts +192 -0
- package/dist/kernel/kernel.js +751 -0
- package/dist/kernel/kernel.js.map +1 -0
- package/dist/lifecycle/hook-shape.d.ts +44 -0
- package/dist/lifecycle/hook-shape.js +66 -0
- package/dist/lifecycle/hook-shape.js.map +1 -0
- package/dist/lifecycle/runner.d.ts +177 -0
- package/dist/lifecycle/runner.js +372 -0
- package/dist/lifecycle/runner.js.map +1 -0
- package/dist/lifecycle/transcript.d.ts +27 -0
- package/dist/lifecycle/transcript.js +43 -0
- package/dist/lifecycle/transcript.js.map +1 -0
- package/dist/machine/allow.d.ts +65 -0
- package/dist/machine/allow.js +107 -0
- package/dist/machine/allow.js.map +1 -0
- package/dist/machine/delegation.d.ts +9 -0
- package/dist/machine/delegation.js +10 -0
- package/dist/machine/delegation.js.map +1 -0
- package/dist/machine/diagnostic.d.ts +14 -0
- package/dist/machine/diagnostic.js +2 -0
- package/dist/machine/diagnostic.js.map +1 -0
- package/dist/machine/lint-spec.d.ts +4 -0
- package/dist/machine/lint-spec.js +266 -0
- package/dist/machine/lint-spec.js.map +1 -0
- package/dist/machine/load-spec.d.ts +90 -0
- package/dist/machine/load-spec.js +120 -0
- package/dist/machine/load-spec.js.map +1 -0
- package/dist/machine/machine.d.ts +273 -0
- package/dist/machine/machine.js +551 -0
- package/dist/machine/machine.js.map +1 -0
- package/dist/machine/mount-grants.d.ts +25 -0
- package/dist/machine/mount-grants.js +24 -0
- package/dist/machine/mount-grants.js.map +1 -0
- package/dist/machine/slug.d.ts +14 -0
- package/dist/machine/slug.js +17 -0
- package/dist/machine/slug.js.map +1 -0
- package/dist/machine/spec-schema.d.ts +662 -0
- package/dist/machine/spec-schema.js +717 -0
- package/dist/machine/spec-schema.js.map +1 -0
- package/dist/machine/tool-names.d.ts +98 -0
- package/dist/machine/tool-names.js +144 -0
- package/dist/machine/tool-names.js.map +1 -0
- package/dist/machine/triggers.d.ts +114 -0
- package/dist/machine/triggers.js +165 -0
- package/dist/machine/triggers.js.map +1 -0
- package/dist/machine/types.d.ts +186 -0
- package/dist/machine/types.js +12 -0
- package/dist/machine/types.js.map +1 -0
- package/dist/machine/validate-spec.d.ts +42 -0
- package/dist/machine/validate-spec.js +29 -0
- package/dist/machine/validate-spec.js.map +1 -0
- package/dist/machine/variables.d.ts +196 -0
- package/dist/machine/variables.js +415 -0
- package/dist/machine/variables.js.map +1 -0
- package/dist/public/cli.d.ts +15 -0
- package/dist/public/cli.js +14 -0
- package/dist/public/cli.js.map +1 -0
- package/dist/public/messages.d.ts +33 -0
- package/dist/public/messages.js +33 -0
- package/dist/public/messages.js.map +1 -0
- package/dist/public/sandbox.d.ts +99 -0
- package/dist/public/sandbox.js +32 -0
- package/dist/public/sandbox.js.map +1 -0
- package/dist/public/spec.d.ts +147 -0
- package/dist/public/spec.js +149 -0
- package/dist/public/spec.js.map +1 -0
- package/dist/public/testing.d.ts +71 -0
- package/dist/public/testing.js +39 -0
- package/dist/public/testing.js.map +1 -0
- package/dist/rubrics/rubrics.d.ts +135 -0
- package/dist/rubrics/rubrics.js +145 -0
- package/dist/rubrics/rubrics.js.map +1 -0
- package/dist/runtime/contract.d.ts +73 -0
- package/dist/runtime/contract.js +96 -0
- package/dist/runtime/contract.js.map +1 -0
- package/dist/sandbox/assets/parts/core.js +22 -0
- package/dist/sandbox/assets/parts/lifecycle-hook.js +47 -0
- package/dist/sandbox/bridge.d.ts +16 -0
- package/dist/sandbox/bridge.js +95 -0
- package/dist/sandbox/bridge.js.map +1 -0
- package/dist/sandbox/executor.d.ts +46 -0
- package/dist/sandbox/executor.js +119 -0
- package/dist/sandbox/executor.js.map +1 -0
- package/dist/sandbox/imports.d.ts +33 -0
- package/dist/sandbox/imports.js +67 -0
- package/dist/sandbox/imports.js.map +1 -0
- package/dist/sandbox/prelude.d.ts +12 -0
- package/dist/sandbox/prelude.js +51 -0
- package/dist/sandbox/prelude.js.map +1 -0
- package/dist/sandbox/ptc-gateway.d.ts +104 -0
- package/dist/sandbox/ptc-gateway.js +167 -0
- package/dist/sandbox/ptc-gateway.js.map +1 -0
- package/dist/sandbox/runtime.d.ts +59 -0
- package/dist/sandbox/runtime.js +51 -0
- package/dist/sandbox/runtime.js.map +1 -0
- package/dist/sandbox/tools.d.ts +34 -0
- package/dist/sandbox/tools.js +147 -0
- package/dist/sandbox/tools.js.map +1 -0
- package/dist/sessions/operations.d.ts +79 -0
- package/dist/sessions/operations.js +121 -0
- package/dist/sessions/operations.js.map +1 -0
- package/dist/sessions/resolve.d.ts +97 -0
- package/dist/sessions/resolve.js +145 -0
- package/dist/sessions/resolve.js.map +1 -0
- package/dist/sessions/resume.d.ts +242 -0
- package/dist/sessions/resume.js +288 -0
- package/dist/sessions/resume.js.map +1 -0
- package/dist/sessions/scope.d.ts +99 -0
- package/dist/sessions/scope.js +145 -0
- package/dist/sessions/scope.js.map +1 -0
- package/dist/sessions/summary.d.ts +65 -0
- package/dist/sessions/summary.js +56 -0
- package/dist/sessions/summary.js.map +1 -0
- package/dist/testing/assertions.d.ts +30 -0
- package/dist/testing/assertions.js +231 -0
- package/dist/testing/assertions.js.map +1 -0
- package/dist/testing/case-document.d.ts +141 -0
- package/dist/testing/case-document.js +51 -0
- package/dist/testing/case-document.js.map +1 -0
- package/dist/testing/case-schema.d.ts +29 -0
- package/dist/testing/case-schema.js +519 -0
- package/dist/testing/case-schema.js.map +1 -0
- package/dist/testing/discovery.d.ts +10 -0
- package/dist/testing/discovery.js +24 -0
- package/dist/testing/discovery.js.map +1 -0
- package/dist/testing/driver.d.ts +78 -0
- package/dist/testing/driver.js +117 -0
- package/dist/testing/driver.js.map +1 -0
- package/dist/testing/grade.d.ts +116 -0
- package/dist/testing/grade.js +261 -0
- package/dist/testing/grade.js.map +1 -0
- package/dist/testing/interpreter.d.ts +55 -0
- package/dist/testing/interpreter.js +103 -0
- package/dist/testing/interpreter.js.map +1 -0
- package/dist/testing/mock-middleware.d.ts +5 -0
- package/dist/testing/mock-middleware.js +33 -0
- package/dist/testing/mock-middleware.js.map +1 -0
- package/dist/testing/runner.d.ts +205 -0
- package/dist/testing/runner.js +266 -0
- package/dist/testing/runner.js.map +1 -0
- package/dist/testing/target.d.ts +27 -0
- package/dist/testing/target.js +21 -0
- package/dist/testing/target.js.map +1 -0
- package/dist/validate/validate.d.ts +41 -0
- package/dist/validate/validate.js +669 -0
- package/dist/validate/validate.js.map +1 -0
- package/dist/workflow/agent-tools.d.ts +10 -0
- package/dist/workflow/agent-tools.js +10 -0
- package/dist/workflow/agent-tools.js.map +1 -0
- package/dist/workflow/checkpointer.d.ts +52 -0
- package/dist/workflow/checkpointer.js +200 -0
- package/dist/workflow/checkpointer.js.map +1 -0
- package/dist/workflow/control-tools.d.ts +174 -0
- package/dist/workflow/control-tools.js +468 -0
- package/dist/workflow/control-tools.js.map +1 -0
- package/dist/workflow/governance.d.ts +104 -0
- package/dist/workflow/governance.js +546 -0
- package/dist/workflow/governance.js.map +1 -0
- package/dist/workflow/middleware.d.ts +85 -0
- package/dist/workflow/middleware.js +283 -0
- package/dist/workflow/middleware.js.map +1 -0
- package/dist/workflow/on-error.d.ts +25 -0
- package/dist/workflow/on-error.js +58 -0
- package/dist/workflow/on-error.js.map +1 -0
- package/dist/workflow/parks.d.ts +46 -0
- package/dist/workflow/parks.js +513 -0
- package/dist/workflow/parks.js.map +1 -0
- package/dist/workflow/paths.d.ts +67 -0
- package/dist/workflow/paths.js +108 -0
- package/dist/workflow/paths.js.map +1 -0
- package/dist/workflow/prompt-cache.d.ts +70 -0
- package/dist/workflow/prompt-cache.js +103 -0
- package/dist/workflow/prompt-cache.js.map +1 -0
- package/dist/workflow/prompt-pruning.d.ts +20 -0
- package/dist/workflow/prompt-pruning.js +83 -0
- package/dist/workflow/prompt-pruning.js.map +1 -0
- package/dist/workflow/render-prompt.d.ts +45 -0
- package/dist/workflow/render-prompt.js +140 -0
- package/dist/workflow/render-prompt.js.map +1 -0
- package/dist/workflow/runtime-config.d.ts +7 -0
- package/dist/workflow/runtime-config.js +9 -0
- package/dist/workflow/runtime-config.js.map +1 -0
- package/dist/workflow/session-artifacts.d.ts +90 -0
- package/dist/workflow/session-artifacts.js +134 -0
- package/dist/workflow/session-artifacts.js.map +1 -0
- package/dist/workflow/session-view.d.ts +31 -0
- package/dist/workflow/session-view.js +94 -0
- package/dist/workflow/session-view.js.map +1 -0
- package/dist/workflow/snapshot.d.ts +14 -0
- package/dist/workflow/snapshot.js +97 -0
- package/dist/workflow/snapshot.js.map +1 -0
- package/dist/workflow/state.d.ts +347 -0
- package/dist/workflow/state.js +322 -0
- package/dist/workflow/state.js.map +1 -0
- package/dist/workflow/sub-workflow.d.ts +174 -0
- package/dist/workflow/sub-workflow.js +392 -0
- package/dist/workflow/sub-workflow.js.map +1 -0
- package/dist/workflow/tool-service.d.ts +48 -0
- package/dist/workflow/tool-service.js +291 -0
- package/dist/workflow/tool-service.js.map +1 -0
- package/dist/workflow/turn-boundary.d.ts +39 -0
- package/dist/workflow/turn-boundary.js +128 -0
- package/dist/workflow/turn-boundary.js.map +1 -0
- package/dist/workflow/turn-runner.d.ts +40 -0
- package/dist/workflow/turn-runner.js +122 -0
- package/dist/workflow/turn-runner.js.map +1 -0
- package/dist/workflow/workflow-tools.d.ts +46 -0
- package/dist/workflow/workflow-tools.js +90 -0
- package/dist/workflow/workflow-tools.js.map +1 -0
- package/package.json +119 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tools the runtime services itself inside `wrapToolCall`: the control
|
|
3
|
+
* tools (with checkpointed state in hand) and delegations (through the
|
|
4
|
+
* dispatcher, with the calling state known). Every serviced call is bracketed
|
|
5
|
+
* with the same `tool-called`/`tool-result` pair an ordinary call gets.
|
|
6
|
+
*/
|
|
7
|
+
import { ToolMessage } from "@langchain/core/messages";
|
|
8
|
+
import { Command } from "@langchain/langgraph";
|
|
9
|
+
import type { LifecycleContext, LifecycleRunner } from "../lifecycle/runner.js";
|
|
10
|
+
import type { WorkflowMachine } from "../machine/machine.js";
|
|
11
|
+
import type { WorkflowEventEmitter } from "../core/events.js";
|
|
12
|
+
import type { MountPrefixes } from "../core/mounts.js";
|
|
13
|
+
import type { WorkflowToolCallRequest } from "../core/deepagents.js";
|
|
14
|
+
import { type PendingDecision, type TrailStep } from "./state.js";
|
|
15
|
+
import { type SubWorkflowDispatcher } from "./sub-workflow.js";
|
|
16
|
+
export interface ToolServiceContext {
|
|
17
|
+
machine: WorkflowMachine;
|
|
18
|
+
emit: WorkflowEventEmitter;
|
|
19
|
+
lifecycle: LifecycleRunner;
|
|
20
|
+
mountPrefixes: MountPrefixes;
|
|
21
|
+
subWorkflows?: SubWorkflowDispatcher;
|
|
22
|
+
lifecycleCtx(sessionId: string, state: unknown, messages: unknown[]): LifecycleContext;
|
|
23
|
+
}
|
|
24
|
+
/** The identities of one call being serviced. */
|
|
25
|
+
export interface ServicedCall {
|
|
26
|
+
sessionId: string;
|
|
27
|
+
workflowState: string;
|
|
28
|
+
toolName: string;
|
|
29
|
+
/** The id the call is reported under: the provider's, else a generated fallback. */
|
|
30
|
+
callId: string;
|
|
31
|
+
/** The provider's tool-call id, echoed on the tool message. */
|
|
32
|
+
toolCallId: string;
|
|
33
|
+
}
|
|
34
|
+
/** A governance refusal: an error-status tool message the model self-corrects on, marked for the session view. */
|
|
35
|
+
export declare function blockedMessage(toolName: string, toolCallId: string, content: string): ToolMessage;
|
|
36
|
+
export declare function createToolService(ctx: ToolServiceContext): {
|
|
37
|
+
emitToolCalled: (state: string, toolName: string, callId: string, args: Record<string, unknown>) => void;
|
|
38
|
+
dispatchSteps: (sessionId: string, workflowState: string) => TrailStep[];
|
|
39
|
+
withDispatchSteps: (result: Command | ToolMessage, steps: TrailStep[]) => Command | ToolMessage;
|
|
40
|
+
reportMove: (sessionId: string, moved: {
|
|
41
|
+
from: string;
|
|
42
|
+
to: string;
|
|
43
|
+
park?: PendingDecision;
|
|
44
|
+
}) => void;
|
|
45
|
+
serviceDelegation: (request: WorkflowToolCallRequest, dispatcher: SubWorkflowDispatcher, call: ServicedCall, args: Record<string, unknown>) => Promise<Command | ToolMessage>;
|
|
46
|
+
serviceControlTool: (request: WorkflowToolCallRequest, call: ServicedCall, args: Record<string, unknown>) => Promise<Command | ToolMessage | undefined>;
|
|
47
|
+
releaseSession(sessionId: string): void;
|
|
48
|
+
};
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tools the runtime services itself inside `wrapToolCall`: the control
|
|
3
|
+
* tools (with checkpointed state in hand) and delegations (through the
|
|
4
|
+
* dispatcher, with the calling state known). Every serviced call is bracketed
|
|
5
|
+
* with the same `tool-called`/`tool-result` pair an ordinary call gets.
|
|
6
|
+
*/
|
|
7
|
+
import { ToolMessage } from "@langchain/core/messages";
|
|
8
|
+
import { Command } from "@langchain/langgraph";
|
|
9
|
+
import { toolCallDetail, toolOutputPreview } from "../core/tool-telemetry.js";
|
|
10
|
+
import { TITLE_VARIABLE } from "../machine/variables.js";
|
|
11
|
+
import { workflowSlugFromToolName } from "../machine/tool-names.js";
|
|
12
|
+
import { ADVANCE_TOOL, GET_VARIABLES_TOOL, handleAdvance, handleGetVariables, handleReset, handleSetVariables, handleWait, refusal, RESET_TOOL, SET_VARIABLES_TOOL, setVariablesCommand, WAIT_TOOL, } from "./control-tools.js";
|
|
13
|
+
import { readVariables } from "./state.js";
|
|
14
|
+
import { subWorkflowParkOf } from "./sub-workflow.js";
|
|
15
|
+
import { delegationCallResult } from "./workflow-tools.js";
|
|
16
|
+
import { buildRunnableConfig } from "./runtime-config.js";
|
|
17
|
+
/**
|
|
18
|
+
* Which model step a serviced call belongs to: the id of the assistant message
|
|
19
|
+
* that made it. Every tool call in one assistant message shares it, and the
|
|
20
|
+
* next model call mints a new one — so it is exactly the scope within which a
|
|
21
|
+
* second transition is a duplicate rather than a further step.
|
|
22
|
+
*
|
|
23
|
+
* Without an id (a fake model in a test, a provider that omits one) the message
|
|
24
|
+
* count stands in: sibling calls still read one step-start snapshot, so they
|
|
25
|
+
* still agree, and a later step has appended at least the previous results.
|
|
26
|
+
*/
|
|
27
|
+
function stepIdOf(state) {
|
|
28
|
+
const messages = state?.messages;
|
|
29
|
+
if (!Array.isArray(messages))
|
|
30
|
+
return "0";
|
|
31
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
32
|
+
const msg = messages[i];
|
|
33
|
+
const calls = msg?.tool_calls;
|
|
34
|
+
if (!Array.isArray(calls) || calls.length === 0)
|
|
35
|
+
continue;
|
|
36
|
+
return typeof msg?.id === "string" && msg.id ? msg.id : `#${messages.length}`;
|
|
37
|
+
}
|
|
38
|
+
return `#${messages.length}`;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The refusal a second transition in one assistant message gets. Phrased as the
|
|
42
|
+
* mistake it is, so the model drops the extra call rather than retrying it: the
|
|
43
|
+
* first transition already landed and this step is over.
|
|
44
|
+
*/
|
|
45
|
+
function duplicateMoveRefusal(toolName, toolCallId, landedAt) {
|
|
46
|
+
return refusal(toolName, toolCallId, `${toolName} rejected: this message already moved the workflow, which is now in ` +
|
|
47
|
+
`state '${landedAt}'. One transition per message — decide where to go from ` +
|
|
48
|
+
`there on your next turn.`);
|
|
49
|
+
}
|
|
50
|
+
/** A governance refusal: an error-status tool message the model self-corrects on, marked for the session view. */
|
|
51
|
+
export function blockedMessage(toolName, toolCallId, content) {
|
|
52
|
+
return new ToolMessage({
|
|
53
|
+
content,
|
|
54
|
+
tool_call_id: toolCallId,
|
|
55
|
+
name: toolName,
|
|
56
|
+
status: "error",
|
|
57
|
+
additional_kwargs: { governance_blocked: true },
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/** The tool message a serviced handler settled with: bare, or carried in a `Command`'s update. */
|
|
61
|
+
function settledMessage(result) {
|
|
62
|
+
if (result instanceof ToolMessage)
|
|
63
|
+
return result;
|
|
64
|
+
const update = result?.update;
|
|
65
|
+
return update?.messages?.find((m) => m instanceof ToolMessage);
|
|
66
|
+
}
|
|
67
|
+
export function createToolService(ctx) {
|
|
68
|
+
const { machine, emit, lifecycle, mountPrefixes, subWorkflows } = ctx;
|
|
69
|
+
function emitToolCalled(state, toolName, callId, args) {
|
|
70
|
+
const detail = toolCallDetail(args);
|
|
71
|
+
emit({ type: "tool-called", state, tool: toolName, callId, args, ...(detail ? { detail } : {}) });
|
|
72
|
+
}
|
|
73
|
+
/** Bracket a serviced call with its `tool-called`/`tool-result` pair: every announced call has to settle. */
|
|
74
|
+
async function withPairedEvents(call, args, handle, statusOf) {
|
|
75
|
+
const { workflowState, toolName, callId } = call;
|
|
76
|
+
emitToolCalled(workflowState, toolName, callId, args);
|
|
77
|
+
const startedAt = Date.now();
|
|
78
|
+
const settle = (status, preview) => emit({ type: "tool-result", state: workflowState, tool: toolName, callId, status, durationMs: Date.now() - startedAt, ...preview });
|
|
79
|
+
try {
|
|
80
|
+
const result = await handle();
|
|
81
|
+
const message = settledMessage(result.message);
|
|
82
|
+
settle(statusOf ? statusOf(result) : message?.status === "error" ? "error" : "ok", toolOutputPreview(message ?? result.message));
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
settle("error", toolOutputPreview(err?.message ?? String(err)));
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The model step each session last moved in, keyed by session id. One step may
|
|
92
|
+
* commit one transition: sibling `archmax_advance` calls in a single assistant
|
|
93
|
+
* message each read the same step-start position, so each would pass edge
|
|
94
|
+
* validation, run the leaving state's `after` hook, and write a position to a
|
|
95
|
+
* last-value channel — double-running a governance hook and landing wherever
|
|
96
|
+
* the last writer said (issue #66).
|
|
97
|
+
*/
|
|
98
|
+
const movedAtStep = new Map();
|
|
99
|
+
/**
|
|
100
|
+
* The sub-runs a call caused, drained from the dispatcher's ledger as trail
|
|
101
|
+
* steps. Drained after every call: a script's dispatches arrive during the
|
|
102
|
+
* `archmax_run` call that ran it.
|
|
103
|
+
*/
|
|
104
|
+
function dispatchSteps(sessionId, workflowState) {
|
|
105
|
+
return (subWorkflows?.drainDispatches(sessionId) ?? []).map((d) => ({
|
|
106
|
+
to: workflowState,
|
|
107
|
+
kind: "sub-workflow",
|
|
108
|
+
workflow: d.workflow,
|
|
109
|
+
status: d.status,
|
|
110
|
+
...(d.reason ? { reason: d.reason } : {}),
|
|
111
|
+
ts: Date.now(),
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
function withDispatchSteps(result, steps) {
|
|
115
|
+
if (steps.length === 0)
|
|
116
|
+
return result;
|
|
117
|
+
if (result instanceof ToolMessage) {
|
|
118
|
+
return new Command({ update: { messages: [result], auditTrail: steps } });
|
|
119
|
+
}
|
|
120
|
+
const update = result.update ?? {};
|
|
121
|
+
return new Command({
|
|
122
|
+
update: { ...update, auditTrail: [...(update.auditTrail ?? []), ...steps] },
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/** Report a move: the state left, the state entered, and the park it opened. */
|
|
126
|
+
function reportMove(sessionId, moved) {
|
|
127
|
+
emit({ type: "state-leave", state: moved.from, next: moved.to });
|
|
128
|
+
emit({ type: "state-enter", state: moved.to });
|
|
129
|
+
if (moved.park) {
|
|
130
|
+
emit({ type: "parked", node: moved.to, state: moved.to, sessionId, awaiting: "decision" });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/** Service a delegation through the dispatcher; refused as a blocked call when nothing may run. */
|
|
134
|
+
async function serviceDelegation(request, dispatcher, call, args) {
|
|
135
|
+
const { sessionId, workflowState, toolName, callId, toolCallId } = call;
|
|
136
|
+
const workflow = workflowSlugFromToolName(toolName);
|
|
137
|
+
const dispatchInput = {
|
|
138
|
+
workflow,
|
|
139
|
+
params: args,
|
|
140
|
+
variables: readVariables(request.state),
|
|
141
|
+
config: buildRunnableConfig(request.runtime ?? {}),
|
|
142
|
+
state: workflowState,
|
|
143
|
+
toolCallId: callId,
|
|
144
|
+
};
|
|
145
|
+
const refused = await dispatcher.refusal(dispatchInput);
|
|
146
|
+
if (refused) {
|
|
147
|
+
emit({ type: "tool-blocked", state: workflowState, tool: toolName, reason: refused.message, callId, args });
|
|
148
|
+
return blockedMessage(toolName, toolCallId, refused.message);
|
|
149
|
+
}
|
|
150
|
+
const outcome = await withPairedEvents(call, args, async () => {
|
|
151
|
+
try {
|
|
152
|
+
const output = delegationCallResult(await dispatcher.dispatch(dispatchInput));
|
|
153
|
+
return {
|
|
154
|
+
message: new ToolMessage({
|
|
155
|
+
content: typeof output === "string" ? output : JSON.stringify(output),
|
|
156
|
+
tool_call_id: toolCallId,
|
|
157
|
+
name: toolName,
|
|
158
|
+
}),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
// The child stopped for a person. Recorded here, where checkpointed state
|
|
163
|
+
// is reachable, rather than propagated: the suspension would otherwise
|
|
164
|
+
// unwind the whole turn and replay every sibling call.
|
|
165
|
+
const parked = subWorkflowParkOf(err);
|
|
166
|
+
if (parked) {
|
|
167
|
+
const decision = parked.decision;
|
|
168
|
+
return {
|
|
169
|
+
message: new Command({
|
|
170
|
+
update: {
|
|
171
|
+
pendingDelegations: [
|
|
172
|
+
{
|
|
173
|
+
state: workflowState,
|
|
174
|
+
node: workflowState,
|
|
175
|
+
workflow,
|
|
176
|
+
toolCallId,
|
|
177
|
+
identity: parked.identity,
|
|
178
|
+
dispatchId: parked.dispatchId,
|
|
179
|
+
decision,
|
|
180
|
+
},
|
|
181
|
+
],
|
|
182
|
+
messages: [
|
|
183
|
+
new ToolMessage({
|
|
184
|
+
content: `The '${workflow}' sub-workflow stopped for a person at its ` +
|
|
185
|
+
`'${decision?.state ?? decision?.node}' step. This run is now waiting on ` +
|
|
186
|
+
`that decision and will continue here once it is made.`,
|
|
187
|
+
tool_call_id: toolCallId,
|
|
188
|
+
name: toolName,
|
|
189
|
+
}),
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
}),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
// A child that ran and did not finish is this state's failure: committed as
|
|
196
|
+
// `rejected`, so the run routes through `on_error` once the model has finished.
|
|
197
|
+
const message = err?.message ?? String(err);
|
|
198
|
+
return {
|
|
199
|
+
message: new Command({
|
|
200
|
+
update: { rejected: message, messages: [refusal(toolName, toolCallId, message)] },
|
|
201
|
+
}),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
return withDispatchSteps(outcome.message, dispatchSteps(sessionId, workflowState));
|
|
206
|
+
}
|
|
207
|
+
/** Service a control tool, or `undefined` when `toolName` is not one. */
|
|
208
|
+
async function serviceControlTool(request, call, args) {
|
|
209
|
+
const { sessionId, workflowState, toolName, callId, toolCallId } = call;
|
|
210
|
+
const state = request.state;
|
|
211
|
+
const step = stepIdOf(state);
|
|
212
|
+
// One transition per model step. Only a move that landed claims the step, so
|
|
213
|
+
// a refused attempt (invalid edge, hook veto) leaves a sibling free to try.
|
|
214
|
+
const claimed = movedAtStep.get(sessionId);
|
|
215
|
+
const alreadyMovedTo = claimed?.step === step ? claimed.to : undefined;
|
|
216
|
+
const claimStep = (moved) => {
|
|
217
|
+
if (!moved)
|
|
218
|
+
return;
|
|
219
|
+
movedAtStep.set(sessionId, { step, to: moved.to });
|
|
220
|
+
reportMove(sessionId, moved);
|
|
221
|
+
};
|
|
222
|
+
switch (toolName) {
|
|
223
|
+
case ADVANCE_TOOL: {
|
|
224
|
+
if (alreadyMovedTo)
|
|
225
|
+
return duplicateMoveRefusal(toolName, toolCallId, alreadyMovedTo);
|
|
226
|
+
const outcome = await withPairedEvents(call, args, () => handleAdvance({ machine, lifecycle, mountPrefixes }, { toolCallId, callId, args, state, ctx: ctx.lifecycleCtx(sessionId, state, state?.messages ?? []) }),
|
|
227
|
+
// A refused transition replies without erroring the message, so the outcome is read off the move.
|
|
228
|
+
(result) => (result.moved ? "ok" : "error"));
|
|
229
|
+
claimStep(outcome.moved);
|
|
230
|
+
return outcome.message;
|
|
231
|
+
}
|
|
232
|
+
case RESET_TOOL: {
|
|
233
|
+
if (alreadyMovedTo)
|
|
234
|
+
return duplicateMoveRefusal(toolName, toolCallId, alreadyMovedTo);
|
|
235
|
+
const outcome = await withPairedEvents(call, args, () => handleReset(machine, { toolCallId, args, state }));
|
|
236
|
+
claimStep(outcome.moved);
|
|
237
|
+
return outcome.message;
|
|
238
|
+
}
|
|
239
|
+
case WAIT_TOOL: {
|
|
240
|
+
const outcome = await withPairedEvents(call, args, () => handleWait(machine, { toolCallId, args, state }));
|
|
241
|
+
if (outcome.park) {
|
|
242
|
+
emit({
|
|
243
|
+
type: "parked",
|
|
244
|
+
node: workflowState,
|
|
245
|
+
state: workflowState,
|
|
246
|
+
sessionId,
|
|
247
|
+
awaiting: "input",
|
|
248
|
+
reason: outcome.park.reason,
|
|
249
|
+
...(outcome.park.resumeAt ? { resumeAt: outcome.park.resumeAt } : {}),
|
|
250
|
+
callId,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
return outcome.message;
|
|
254
|
+
}
|
|
255
|
+
case GET_VARIABLES_TOOL: {
|
|
256
|
+
const outcome = await withPairedEvents(call, args, () => ({
|
|
257
|
+
message: handleGetVariables({ toolCallId, args, state }),
|
|
258
|
+
}));
|
|
259
|
+
return outcome.message;
|
|
260
|
+
}
|
|
261
|
+
case SET_VARIABLES_TOOL: {
|
|
262
|
+
const outcome = await withPairedEvents(call, args, () => {
|
|
263
|
+
const written = handleSetVariables({ toolCallId, args, state });
|
|
264
|
+
// Only a write that landed is announced; a refusal is visible as the tool's error result.
|
|
265
|
+
if (written.written) {
|
|
266
|
+
emit({ type: "variables-set", state: workflowState, names: written.written, locked: written.locked === true, callId });
|
|
267
|
+
const title = written.delta?.[TITLE_VARIABLE]?.value;
|
|
268
|
+
if (typeof title === "string")
|
|
269
|
+
emit({ type: "title-set", title, state: workflowState, callId });
|
|
270
|
+
}
|
|
271
|
+
return { message: setVariablesCommand(written) };
|
|
272
|
+
});
|
|
273
|
+
return outcome.message;
|
|
274
|
+
}
|
|
275
|
+
default:
|
|
276
|
+
return undefined;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
emitToolCalled,
|
|
281
|
+
dispatchSteps,
|
|
282
|
+
withDispatchSteps,
|
|
283
|
+
reportMove,
|
|
284
|
+
serviceDelegation,
|
|
285
|
+
serviceControlTool,
|
|
286
|
+
releaseSession(sessionId) {
|
|
287
|
+
movedAtStep.delete(sessionId);
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=tool-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-service.js","sourceRoot":"","sources":["../../src/workflow/tool-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The turn boundary: what happens once per invoke, before any model call.
|
|
3
|
+
*
|
|
4
|
+
* A turn boundary resets the turn's mechanics (rejected, iterations,
|
|
5
|
+
* beforeDone, parkCounts, park records and phase, replyOnly, the turn budget)
|
|
6
|
+
* and retains the conversation (position, entryState, variables, transcript,
|
|
7
|
+
* trail, files). Every ingress that begins a turn arrives here; a park
|
|
8
|
+
* resumption re-enters at its own suspension through a `Command` and never
|
|
9
|
+
* crosses this boundary — which is what makes "a disabled machine starts
|
|
10
|
+
* nothing, finishes what it started" a property of the graph's shape.
|
|
11
|
+
*/
|
|
12
|
+
import { type WorkflowEventEmitter, type WorkflowEventHandler } from "../core/events.js";
|
|
13
|
+
import type { Workspace } from "../core/workspace.js";
|
|
14
|
+
import type { WorkflowMachine } from "../machine/machine.js";
|
|
15
|
+
import { type VariableStore } from "../machine/variables.js";
|
|
16
|
+
import { type WorkflowUpdate } from "./state.js";
|
|
17
|
+
export interface TurnBoundaryContext {
|
|
18
|
+
machine: WorkflowMachine;
|
|
19
|
+
emit: WorkflowEventEmitter;
|
|
20
|
+
/** The lifecycle event subscriber, for the spec snapshot's own diagnostics. */
|
|
21
|
+
onEvent?: WorkflowEventHandler;
|
|
22
|
+
/** Workspace backend for writing the spec snapshot into the session zone. */
|
|
23
|
+
workspace?: Workspace;
|
|
24
|
+
/** The `workflows/<slug>/` name, used only to name the machine in a refusal. */
|
|
25
|
+
workflowName?: string;
|
|
26
|
+
/** The assembly-time default trigger, used when an invocation supplies none. */
|
|
27
|
+
defaultTrigger?: {
|
|
28
|
+
id: string;
|
|
29
|
+
};
|
|
30
|
+
/** Host-seeded run variables, applied at each turn boundary (already locked). */
|
|
31
|
+
seededVariables?: VariableStore;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Open a turn: resolve where it begins, refuse it if the machine cannot serve
|
|
35
|
+
* it, and commit the opening. A refused turn carries `jumpTo: "end"` so no model runs.
|
|
36
|
+
*/
|
|
37
|
+
export declare function openTurn(ctx: TurnBoundaryContext, state: unknown, runtime: {
|
|
38
|
+
configurable?: Record<string, unknown>;
|
|
39
|
+
} | undefined): Promise<WorkflowUpdate>;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The turn boundary: what happens once per invoke, before any model call.
|
|
3
|
+
*
|
|
4
|
+
* A turn boundary resets the turn's mechanics (rejected, iterations,
|
|
5
|
+
* beforeDone, parkCounts, park records and phase, replyOnly, the turn budget)
|
|
6
|
+
* and retains the conversation (position, entryState, variables, transcript,
|
|
7
|
+
* trail, files). Every ingress that begins a turn arrives here; a park
|
|
8
|
+
* resumption re-enters at its own suspension through a `Command` and never
|
|
9
|
+
* crosses this boundary — which is what makes "a disabled machine starts
|
|
10
|
+
* nothing, finishes what it started" a property of the graph's shape.
|
|
11
|
+
*/
|
|
12
|
+
import { SESSION_ORIGIN } from "../core/events.js";
|
|
13
|
+
import { MANUAL_TRIGGER } from "../machine/triggers.js";
|
|
14
|
+
import { buildSeededVariables, TITLE_VARIABLE, TRIGGER_VARIABLE, } from "../machine/variables.js";
|
|
15
|
+
import { decisionRecordFor } from "./parks.js";
|
|
16
|
+
import { writeSpecSnapshotIfAbsent } from "./snapshot.js";
|
|
17
|
+
import { readVariables, readWorkflowState, reseedAll, WORKFLOW_STATUSES, } from "./state.js";
|
|
18
|
+
import { sessionScopeFrom, seedVariablesFrom } from "../sessions/scope.js";
|
|
19
|
+
/**
|
|
20
|
+
* Open a turn: resolve where it begins, refuse it if the machine cannot serve
|
|
21
|
+
* it, and commit the opening. A refused turn carries `jumpTo: "end"` so no model runs.
|
|
22
|
+
*/
|
|
23
|
+
export async function openTurn(ctx, state, runtime) {
|
|
24
|
+
const { machine, emit } = ctx;
|
|
25
|
+
const fields = readWorkflowState(state);
|
|
26
|
+
// The trigger is per invoke, falling back to the assembly's default; its id maps
|
|
27
|
+
// to a declared start state, or the machine's entry when unmatched.
|
|
28
|
+
const trigger = fields.trigger ?? ctx.defaultTrigger ?? { id: MANUAL_TRIGGER };
|
|
29
|
+
const startState = machine.startStateForTrigger(trigger.id) ?? machine.entry;
|
|
30
|
+
// A session's first turn enters the state its trigger declares; every later turn
|
|
31
|
+
// continues where the conversation is. A retained position the current
|
|
32
|
+
// definition no longer declares reopens at the trigger's entry.
|
|
33
|
+
const retained = fields.workflowState;
|
|
34
|
+
const reopening = retained == null || !Object.hasOwn(machine.spec.states, retained);
|
|
35
|
+
const position = reopening ? startState : retained;
|
|
36
|
+
const entryState = fields.entryState ?? position;
|
|
37
|
+
// A refused turn commits `rejected` with a reason rather than throwing, before
|
|
38
|
+
// any event narrates a turn beginning: nothing is entered, no hook runs.
|
|
39
|
+
const refuse = (reason, extra = {}) => {
|
|
40
|
+
emit({ type: "warning", scope: "workflow", message: reason });
|
|
41
|
+
return {
|
|
42
|
+
workflowState: position,
|
|
43
|
+
entryState,
|
|
44
|
+
specHash: machine.specHash,
|
|
45
|
+
status: WORKFLOW_STATUSES.rejected,
|
|
46
|
+
rejected: reason,
|
|
47
|
+
trigger,
|
|
48
|
+
...extra,
|
|
49
|
+
jumpTo: "end",
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
if (machine.disabled) {
|
|
53
|
+
const named = ctx.workflowName ? `workflow '${ctx.workflowName}'` : "this workflow";
|
|
54
|
+
return refuse(`Refusing to start: ${named} is disabled.`);
|
|
55
|
+
}
|
|
56
|
+
// A reset means "opened at an entry state": a first turn, or a reopening on a dropped position.
|
|
57
|
+
if (reopening)
|
|
58
|
+
emit({ type: "workflow-reset", entry: position });
|
|
59
|
+
// Every turn announces where it begins; the trail records the same arrival below.
|
|
60
|
+
emit({ type: "advance", from: SESSION_ORIGIN, to: position });
|
|
61
|
+
// A definition may change between turns; the snapshot must exist for the recorded hash to mean anything.
|
|
62
|
+
if (fields.specHash !== machine.specHash && ctx.workspace) {
|
|
63
|
+
await writeSpecSnapshotIfAbsent(ctx.workspace, machine.specHash, machine.spec, ctx.onEvent);
|
|
64
|
+
}
|
|
65
|
+
// This turn's opening variables: the host's seeds, this invocation's seeds (a
|
|
66
|
+
// sub-run's params), and the built-in `trigger`, locked. Marked `reseed`: a turn
|
|
67
|
+
// boundary is a host seeding boundary exactly as a delivery is.
|
|
68
|
+
const openingVariables = reseedAll({
|
|
69
|
+
...(ctx.seededVariables ?? {}),
|
|
70
|
+
...buildSeededVariables(seedVariablesFrom(runtime?.configurable), "supplied to a sub-workflow"),
|
|
71
|
+
[TRIGGER_VARIABLE]: { value: trigger.id, locked: true },
|
|
72
|
+
});
|
|
73
|
+
// A seeded `title` is an opening label: it loses to a title the session already
|
|
74
|
+
// holds, so the agent's refinement survives the next turn.
|
|
75
|
+
if (openingVariables[TITLE_VARIABLE] !== undefined &&
|
|
76
|
+
readVariables(state)[TITLE_VARIABLE] !== undefined) {
|
|
77
|
+
delete openingVariables[TITLE_VARIABLE];
|
|
78
|
+
}
|
|
79
|
+
const seededTitle = openingVariables[TITLE_VARIABLE]?.value;
|
|
80
|
+
if (typeof seededTitle === "string")
|
|
81
|
+
emit({ type: "title-set", title: seededTitle });
|
|
82
|
+
// The entry half of the trigger's signature: a run that cannot satisfy its own contract reaches no model.
|
|
83
|
+
const missingInputs = (machine.requiresForTrigger(trigger.id) ?? []).filter((name) => openingVariables[name] === undefined);
|
|
84
|
+
if (missingInputs.length > 0) {
|
|
85
|
+
return refuse(`Refusing to start: trigger '${trigger.id}' requires ` +
|
|
86
|
+
`${missingInputs.map((n) => `'${n}'`).join(", ")}, which this firing does not supply.`, { variables: openingVariables });
|
|
87
|
+
}
|
|
88
|
+
emit({ type: "state-enter", state: position });
|
|
89
|
+
// A turn opened on a session parked at a human state presents the decision
|
|
90
|
+
// again on a fresh record: the run owes the person a closing message, then
|
|
91
|
+
// suspends where it stood.
|
|
92
|
+
let reparked = {};
|
|
93
|
+
if (machine.isHumanState(position)) {
|
|
94
|
+
const seq = (fields.decisionCount ?? 0) + 1;
|
|
95
|
+
emit({ type: "parked", node: position, state: position, sessionId: sessionScopeFrom(runtime).sessionId, awaiting: "decision" });
|
|
96
|
+
reparked = {
|
|
97
|
+
pendingDecision: decisionRecordFor(machine, position, seq),
|
|
98
|
+
decisionCount: seq,
|
|
99
|
+
status: WORKFLOW_STATUSES.awaitingDecision,
|
|
100
|
+
parkPhase: "closing",
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
workflowState: position,
|
|
105
|
+
rejected: null,
|
|
106
|
+
iterations: {},
|
|
107
|
+
beforeDone: {},
|
|
108
|
+
parkCounts: {},
|
|
109
|
+
// A new turn is not a resumed park: every park channel is cleared, and a
|
|
110
|
+
// delegated child suspended on its own human state is abandoned by the turn
|
|
111
|
+
// that supersedes it — an orphaned child beats a caller wedged on an interrupt.
|
|
112
|
+
pendingInput: null,
|
|
113
|
+
pendingDecision: null,
|
|
114
|
+
pendingDelegations: null,
|
|
115
|
+
parkPhase: null,
|
|
116
|
+
replyOnly: null,
|
|
117
|
+
stateTurns: null,
|
|
118
|
+
// Where this session began: recorded once, so the reset tool has a fixed target.
|
|
119
|
+
entryState,
|
|
120
|
+
specHash: machine.specHash,
|
|
121
|
+
status: WORKFLOW_STATUSES.running,
|
|
122
|
+
trigger,
|
|
123
|
+
variables: openingVariables,
|
|
124
|
+
auditTrail: [{ to: position, kind: "trigger", reason: trigger.id, ts: Date.now() }],
|
|
125
|
+
...reparked,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=turn-boundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-boundary.js","sourceRoot":"","sources":["../../src/workflow/turn-boundary.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The turn runner: how one invocation on a session is driven. Every way a
|
|
3
|
+
* session is entered goes through here, so all of them bind the session's run
|
|
4
|
+
* zone and event context, stream the model's text as `agent-text-delta` events,
|
|
5
|
+
* and settle to the same state the graph's `invoke` would.
|
|
6
|
+
*/
|
|
7
|
+
import type { RunnableConfig } from "@langchain/core/runnables";
|
|
8
|
+
import type { WorkflowEventEmitter } from "../core/events.js";
|
|
9
|
+
import type { CompiledAgentGraph } from "../core/deepagents.js";
|
|
10
|
+
/** Drives one turn on a session: the graph's `invoke`/`stream`/`streamEvents`, session-bound. */
|
|
11
|
+
export interface TurnRunner {
|
|
12
|
+
invoke(input: unknown, config?: RunnableConfig): Promise<Record<string, unknown>>;
|
|
13
|
+
stream(input: unknown, config?: RunnableConfig): AsyncIterable<unknown>;
|
|
14
|
+
streamEvents(input: unknown, config: RunnableConfig, options?: unknown): AsyncIterable<unknown>;
|
|
15
|
+
}
|
|
16
|
+
/** What binds a call to a session: the session zone's view and the event context, refusing a bad id. */
|
|
17
|
+
export type SessionBinder = <T>(sessionId: string, fn: () => Promise<T>) => Promise<T>;
|
|
18
|
+
export interface TurnRunnerOptions {
|
|
19
|
+
graph: CompiledAgentGraph;
|
|
20
|
+
emit: WorkflowEventEmitter;
|
|
21
|
+
/** Bind `fn` to `sessionId` (session zone and event context); refuses an id that escapes its zone or shadows a reserved name. */
|
|
22
|
+
bindSession: SessionBinder;
|
|
23
|
+
/** The state deltas are attributed to before the graph reports one. */
|
|
24
|
+
entryState: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function sessionIdOfConfig(config: RunnableConfig | undefined): string;
|
|
27
|
+
export declare function createTurnRunner(opts: TurnRunnerOptions): TurnRunner;
|
|
28
|
+
/**
|
|
29
|
+
* The runner a **plain** (ungoverned) agent drives its graph through: the graph's
|
|
30
|
+
* own `invoke`/`stream`/`streamEvents`, each bound to the session named by
|
|
31
|
+
* `configurable.thread_id`. No machine means no state to attribute text deltas
|
|
32
|
+
* to and no park to settle, so nothing here reshapes the graph's results; what
|
|
33
|
+
* the binding buys is that the agent's `scratchpad/…` and offload paths land
|
|
34
|
+
* under `<sessionId>/` in the session store exactly as a governed session's do,
|
|
35
|
+
* and that a reserved or escaping id is refused before anything is written.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createPlainTurnRunner(opts: {
|
|
38
|
+
graph: CompiledAgentGraph;
|
|
39
|
+
bindSession: SessionBinder;
|
|
40
|
+
}): TurnRunner;
|