@archmax-ai/harness 0.9.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -14
- package/dist/agent.d.ts +4 -6
- package/dist/agent.js +4 -6
- package/dist/agent.js.map +1 -1
- package/dist/assembly/compose.d.ts +5 -24
- package/dist/assembly/compose.js +28 -42
- package/dist/assembly/compose.js.map +1 -1
- package/dist/assembly/delegation-registry.js +3 -14
- package/dist/assembly/delegation-registry.js.map +1 -1
- package/dist/assembly/index.d.ts +8 -15
- package/dist/assembly/index.js +21 -28
- package/dist/assembly/index.js.map +1 -1
- package/dist/assembly/plain.js +1 -2
- package/dist/assembly/plain.js.map +1 -1
- package/dist/authoring-skill/archmax-harness/README.md +5 -5
- package/dist/authoring-skill/archmax-harness/SKILL.md +72 -30
- package/dist/authoring-skill/archmax-harness/references/backend-integration.md +33 -24
- package/dist/authoring-skill/archmax-harness/references/cases.md +41 -8
- package/dist/authoring-skill/archmax-harness/references/{hook-and-test-scripts.md → code-state-and-test-scripts.md} +599 -339
- package/dist/authoring-skill/archmax-harness/references/code-states-and-scripts.md +115 -0
- package/dist/authoring-skill/archmax-harness/references/diagnostics.md +40 -7
- package/dist/authoring-skill/archmax-harness/references/wiring.md +19 -10
- package/dist/authoring-skill/archmax-harness/references/workflow-schema.md +404 -293
- package/dist/authoring-skill/archmax-harness/references/workflow-yaml.md +151 -62
- package/dist/cli/state-flow.d.ts +1 -1
- package/dist/cli/state-flow.js +18 -28
- package/dist/cli/state-flow.js.map +1 -1
- package/dist/cli/turn.d.ts +1 -1
- package/dist/cli/turn.js +1 -1
- package/dist/core/code-description.d.ts +3 -3
- package/dist/core/code-description.js +3 -3
- package/dist/core/deepagents.d.ts +5 -12
- package/dist/core/deepagents.js +4 -17
- package/dist/core/deepagents.js.map +1 -1
- package/dist/core/events.d.ts +23 -42
- package/dist/core/events.js +21 -24
- package/dist/core/events.js.map +1 -1
- package/dist/core/message-readers.d.ts +4 -5
- package/dist/core/message-readers.js +3 -8
- package/dist/core/message-readers.js.map +1 -1
- package/dist/core/messages.d.ts +0 -22
- package/dist/core/messages.js +1 -32
- package/dist/core/messages.js.map +1 -1
- package/dist/core/mounts.js +3 -3
- package/dist/core/platform-prompt.generated.js +1 -1
- package/dist/core/platform-prompt.generated.js.map +1 -1
- package/dist/core/session-zone.d.ts +1 -1
- package/dist/core/session-zone.js +1 -1
- package/dist/core/workspace-context.d.ts +1 -1
- package/dist/core/workspace.d.ts +1 -1
- package/dist/core/workspace.js +1 -1
- package/dist/core/zones.d.ts +4 -4
- package/dist/core/zones.js +5 -5
- package/dist/core/zones.js.map +1 -1
- package/dist/env.d.ts +9 -9
- package/dist/index.d.ts +3 -7
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/kernel/kernel.d.ts +31 -61
- package/dist/kernel/kernel.js +54 -112
- package/dist/kernel/kernel.js.map +1 -1
- package/dist/machine/lint-spec.js +53 -12
- package/dist/machine/lint-spec.js.map +1 -1
- package/dist/machine/machine.d.ts +36 -18
- package/dist/machine/machine.js +62 -51
- package/dist/machine/machine.js.map +1 -1
- package/dist/machine/spec-schema.d.ts +32 -180
- package/dist/machine/spec-schema.js +52 -113
- package/dist/machine/spec-schema.js.map +1 -1
- package/dist/machine/tool-names.d.ts +34 -16
- package/dist/machine/tool-names.js +41 -16
- package/dist/machine/tool-names.js.map +1 -1
- package/dist/machine/types.d.ts +14 -46
- package/dist/machine/types.js +0 -2
- package/dist/machine/types.js.map +1 -1
- package/dist/machine/validate-spec.d.ts +1 -1
- package/dist/public/sandbox.d.ts +59 -95
- package/dist/public/sandbox.js +22 -23
- package/dist/public/sandbox.js.map +1 -1
- package/dist/public/spec.d.ts +13 -20
- package/dist/public/spec.js +12 -20
- package/dist/public/spec.js.map +1 -1
- package/dist/runtime/contract.d.ts +11 -12
- package/dist/runtime/contract.js +16 -16
- package/dist/runtime/contract.js.map +1 -1
- package/dist/sandbox/assets/parts/code-state.js +17 -0
- package/dist/sandbox/executor.d.ts +25 -7
- package/dist/sandbox/executor.js +56 -57
- package/dist/sandbox/executor.js.map +1 -1
- package/dist/sandbox/imports.d.ts +10 -10
- package/dist/sandbox/imports.js +11 -11
- package/dist/sandbox/imports.js.map +1 -1
- package/dist/sandbox/prelude.d.ts +5 -6
- package/dist/sandbox/prelude.js +38 -35
- package/dist/sandbox/prelude.js.map +1 -1
- package/dist/sandbox/ptc-gateway.d.ts +19 -18
- package/dist/sandbox/ptc-gateway.js +26 -22
- package/dist/sandbox/ptc-gateway.js.map +1 -1
- package/dist/sessions/resume.d.ts +2 -2
- package/dist/sessions/resume.js +1 -1
- package/dist/sessions/resume.js.map +1 -1
- package/dist/sessions/scope.d.ts +0 -10
- package/dist/sessions/scope.js +0 -17
- package/dist/sessions/scope.js.map +1 -1
- package/dist/sessions/summary.d.ts +1 -1
- package/dist/testing/assertions.js +9 -4
- package/dist/testing/assertions.js.map +1 -1
- package/dist/testing/driver.js +3 -0
- package/dist/testing/driver.js.map +1 -1
- package/dist/testing/interpreter.d.ts +2 -2
- package/dist/testing/runner.d.ts +2 -2
- package/dist/validate/validate.d.ts +1 -1
- package/dist/validate/validate.js +39 -70
- package/dist/validate/validate.js.map +1 -1
- package/dist/workflow/automated-controls.d.ts +63 -0
- package/dist/workflow/automated-controls.js +158 -0
- package/dist/workflow/automated-controls.js.map +1 -0
- package/dist/workflow/automated.d.ts +112 -0
- package/dist/workflow/automated.js +163 -0
- package/dist/workflow/automated.js.map +1 -0
- package/dist/workflow/code-state.d.ts +46 -0
- package/dist/workflow/code-state.js +26 -0
- package/dist/workflow/code-state.js.map +1 -0
- package/dist/workflow/control-tools.d.ts +54 -23
- package/dist/workflow/control-tools.js +99 -79
- package/dist/workflow/control-tools.js.map +1 -1
- package/dist/workflow/file-values.d.ts +4 -4
- package/dist/workflow/file-values.js +1 -1
- package/dist/workflow/file-values.js.map +1 -1
- package/dist/workflow/governance.d.ts +11 -22
- package/dist/workflow/governance.js +47 -104
- package/dist/workflow/governance.js.map +1 -1
- package/dist/workflow/grader-state.d.ts +55 -0
- package/dist/workflow/grader-state.js +182 -0
- package/dist/workflow/grader-state.js.map +1 -0
- package/dist/workflow/history.d.ts +11 -0
- package/dist/{lifecycle/transcript.js → workflow/history.js} +24 -8
- package/dist/workflow/history.js.map +1 -0
- package/dist/workflow/middleware.d.ts +14 -17
- package/dist/workflow/middleware.js +109 -95
- package/dist/workflow/middleware.js.map +1 -1
- package/dist/workflow/move-events.d.ts +21 -0
- package/dist/workflow/move-events.js +20 -0
- package/dist/workflow/move-events.js.map +1 -0
- package/dist/workflow/on-error.js +0 -2
- package/dist/workflow/on-error.js.map +1 -1
- package/dist/workflow/parks.d.ts +9 -2
- package/dist/workflow/parks.js +16 -10
- package/dist/workflow/parks.js.map +1 -1
- package/dist/workflow/paths.d.ts +9 -9
- package/dist/workflow/paths.js +19 -19
- package/dist/workflow/paths.js.map +1 -1
- package/dist/workflow/render-prompt.d.ts +7 -5
- package/dist/workflow/render-prompt.js +22 -37
- package/dist/workflow/render-prompt.js.map +1 -1
- package/dist/workflow/signature-checks.d.ts +2 -2
- package/dist/workflow/snapshot.js +5 -29
- package/dist/workflow/snapshot.js.map +1 -1
- package/dist/workflow/state.d.ts +14 -42
- package/dist/workflow/state.js +20 -33
- package/dist/workflow/state.js.map +1 -1
- package/dist/workflow/sub-workflow.d.ts +3 -3
- package/dist/workflow/sub-workflow.js +3 -7
- package/dist/workflow/sub-workflow.js.map +1 -1
- package/dist/workflow/tool-service.d.ts +1 -9
- package/dist/workflow/tool-service.js +21 -24
- package/dist/workflow/tool-service.js.map +1 -1
- package/dist/workflow/turn-boundary.d.ts +2 -2
- package/dist/workflow/turn-boundary.js +10 -15
- package/dist/workflow/turn-boundary.js.map +1 -1
- package/dist/workflow/turn-runner.js +5 -6
- package/dist/workflow/turn-runner.js.map +1 -1
- package/package.json +2 -2
- package/skills/archmax-harness/README.md +5 -5
- package/skills/archmax-harness/SKILL.md +72 -30
- package/skills/archmax-harness/references/backend-integration.md +33 -24
- package/skills/archmax-harness/references/cases.md +41 -8
- package/skills/archmax-harness/references/{hook-and-test-scripts.md → code-state-and-test-scripts.md} +599 -339
- package/skills/archmax-harness/references/code-states-and-scripts.md +115 -0
- package/skills/archmax-harness/references/diagnostics.md +40 -7
- package/skills/archmax-harness/references/wiring.md +19 -10
- package/skills/archmax-harness/references/workflow-schema.md +404 -293
- package/skills/archmax-harness/references/workflow-yaml.md +151 -62
- package/dist/authoring-skill/archmax-harness/references/hooks-and-scripts.md +0 -89
- package/dist/lifecycle/hook-shape.d.ts +0 -44
- package/dist/lifecycle/hook-shape.js +0 -66
- package/dist/lifecycle/hook-shape.js.map +0 -1
- package/dist/lifecycle/runner.d.ts +0 -197
- package/dist/lifecycle/runner.js +0 -419
- package/dist/lifecycle/runner.js.map +0 -1
- package/dist/lifecycle/tool-calls.d.ts +0 -9
- package/dist/lifecycle/tool-calls.js +0 -57
- package/dist/lifecycle/tool-calls.js.map +0 -1
- package/dist/lifecycle/transcript.d.ts +0 -31
- package/dist/lifecycle/transcript.js.map +0 -1
- package/dist/rubrics/rubrics.d.ts +0 -135
- package/dist/rubrics/rubrics.js +0 -145
- package/dist/rubrics/rubrics.js.map +0 -1
- package/dist/sandbox/assets/parts/core.js +0 -22
- package/dist/sandbox/assets/parts/lifecycle-hook.js +0 -47
- package/dist/sandbox/bridge.d.ts +0 -16
- package/dist/sandbox/bridge.js +0 -95
- package/dist/sandbox/bridge.js.map +0 -1
- package/dist/workflow/visits.d.ts +0 -21
- package/dist/workflow/visits.js +0 -45
- package/dist/workflow/visits.js.map +0 -1
- package/skills/archmax-harness/references/hooks-and-scripts.md +0 -89
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `toolCalls`: a hook's query over the session's record of tool results. Built
|
|
3
|
-
* from the checkpointed transcript, which nobody edits, so a hook checks the
|
|
4
|
-
* result itself, never a copy the model made. Filtered here, outside the
|
|
5
|
-
* sandbox, so only the records a hook asks for are copied in.
|
|
6
|
-
*/
|
|
7
|
-
import { isRuntimeNote, messageTypeOf } from "../core/messages.js";
|
|
8
|
-
import { ALWAYS_ALLOWED_TOOLS } from "../machine/tool-names.js";
|
|
9
|
-
import { messagesToSessionView } from "../workflow/session-view.js";
|
|
10
|
-
import { visitAt } from "../workflow/visits.js";
|
|
11
|
-
/**
|
|
12
|
-
* The session's domain tool calls in the order they were made, narrowed by
|
|
13
|
-
* `filter`. The runtime's control tools are not domain calls, and runtime notes
|
|
14
|
-
* are not calls at all.
|
|
15
|
-
*/
|
|
16
|
-
export function queryToolCalls(messages, visits, filter = {}) {
|
|
17
|
-
const facts = messagesToSessionView([...messages]).toolCalls;
|
|
18
|
-
// The same walk the view makes, so the nth call it found is the nth made here.
|
|
19
|
-
const madeAt = [];
|
|
20
|
-
messages.forEach((message, index) => {
|
|
21
|
-
const type = messageTypeOf(message);
|
|
22
|
-
if (isRuntimeNote(message) || (type !== "ai" && type !== "assistant"))
|
|
23
|
-
return;
|
|
24
|
-
const calls = message.tool_calls;
|
|
25
|
-
if (Array.isArray(calls))
|
|
26
|
-
for (const _ of calls)
|
|
27
|
-
madeAt.push(index);
|
|
28
|
-
});
|
|
29
|
-
const current = visits.at(-1)?.number;
|
|
30
|
-
const visit = filter.visit === "current" ? current : filter.visit;
|
|
31
|
-
const records = facts.flatMap((fact, i) => {
|
|
32
|
-
if (ALWAYS_ALLOWED_TOOLS.has(fact.name))
|
|
33
|
-
return [];
|
|
34
|
-
const span = visits.length > 0 ? visitAt(visits, madeAt[i] ?? 0) : { state: "", number: 1 };
|
|
35
|
-
return [
|
|
36
|
-
{
|
|
37
|
-
...(fact.id ? { id: fact.id } : {}),
|
|
38
|
-
name: fact.name,
|
|
39
|
-
args: fact.input,
|
|
40
|
-
...(fact.status === "pending" ? {} : { result: fact.output }),
|
|
41
|
-
status: statusOf(fact),
|
|
42
|
-
state: span.state,
|
|
43
|
-
visit: span.number,
|
|
44
|
-
},
|
|
45
|
-
];
|
|
46
|
-
});
|
|
47
|
-
const matched = records.filter((r) => (filter.name === undefined || r.name === filter.name) &&
|
|
48
|
-
(filter.state === undefined || r.state === filter.state) &&
|
|
49
|
-
(visit === undefined || r.visit === visit) &&
|
|
50
|
-
(filter.status === undefined || r.status === filter.status));
|
|
51
|
-
return filter.last === undefined ? matched : matched.slice(-filter.last);
|
|
52
|
-
}
|
|
53
|
-
/** A fact's status in the four a hook is promised: LangChain marks a result that ran `success`. */
|
|
54
|
-
function statusOf(fact) {
|
|
55
|
-
return fact.status === "pending" || fact.status === "failed" || fact.status === "rejected" ? fact.status : "completed";
|
|
56
|
-
}
|
|
57
|
-
//# sourceMappingURL=tool-calls.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-calls.js","sourceRoot":"","sources":["../../src/lifecycle/tool-calls.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* One transcript message as a hook reads it: plain data, no LangChain classes.
|
|
3
|
-
* `role` is `user`, `assistant`, `tool`, `system`, or `runtime` — the last for
|
|
4
|
-
* a note the runtime wrote (an arrival, a decision, an error route), which a
|
|
5
|
-
* model cannot read as a person speaking and a hook should not either.
|
|
6
|
-
*/
|
|
7
|
-
export interface HookMessage {
|
|
8
|
-
role: string;
|
|
9
|
-
/** The message's text; empty on a tool result, whose result `toolCalls` returns. */
|
|
10
|
-
text: string;
|
|
11
|
-
/** Assistant messages only: the tool calls the message made. */
|
|
12
|
-
toolCalls?: {
|
|
13
|
-
id?: string;
|
|
14
|
-
name: string;
|
|
15
|
-
args: unknown;
|
|
16
|
-
}[];
|
|
17
|
-
/** Tool results only: the tool that answered. */
|
|
18
|
-
tool?: string;
|
|
19
|
-
/** Tool results only: the id of the call it answers. */
|
|
20
|
-
id?: string;
|
|
21
|
-
/** Runtime notes only: which kind of note this is. */
|
|
22
|
-
note?: string;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* A visit's transcript as a hook receives it in `messages`, newest last. A
|
|
26
|
-
* runtime note is carried in the transcript as a tool-call pair; only the half
|
|
27
|
-
* holding the text is kept, as one `runtime` entry. A tool result names its
|
|
28
|
-
* tool and call but carries no text: results are read through `toolCalls`, so
|
|
29
|
-
* the hook input stays small however large they are.
|
|
30
|
-
*/
|
|
31
|
-
export declare function hookTranscript(messages: unknown[]): HookMessage[];
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/lifecycle/transcript.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAsBtF,MAAM,YAAY,GAA2B;IAC3C,KAAK,EAAE,MAAM;IACb,EAAE,EAAE,WAAW;IACf,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,MAAM;CACjB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,QAAmB;IAChD,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC1D,MAAM,GAAG,GAAG,GAA8B,CAAC;QAC3C,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;gBAAE,SAAS;YACjC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1C,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC;QACvD,MAAM,KAAK,GAAgB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACvE,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC;QAC7B,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,WAAW,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxF,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBAChC,MAAM,IAAI,GAAG,CAA4B,CAAC;gBAC1C,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;YACvH,CAAC,CAAC,CAAC;QACL,CAAC;QACD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YACxD,IAAI,GAAG,CAAC,YAAY,IAAI,IAAI;gBAAE,KAAK,CAAC,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACpE,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Grading rubrics: the standards a state's exit is measured against, declared
|
|
3
|
-
* inline on the hook that applies them and dispatched by the runtime alone.
|
|
4
|
-
*
|
|
5
|
-
* This module is only the *vocabulary* — the verdict contract, the payload a
|
|
6
|
-
* grader receives, the rejection wording, and the projection from a loaded spec
|
|
7
|
-
* into a registry. There is deliberately no loader, no file format and no merge
|
|
8
|
-
* path: a rubric is spec content, so the spec's own schema is the one thing that
|
|
9
|
-
* has to accept it, and nothing outside assembly builds a registry.
|
|
10
|
-
*
|
|
11
|
-
* A rubric has no author-given name. Its identity is its **position** — the
|
|
12
|
-
* state, the phase, and its index in that phase's hook list — which is also how
|
|
13
|
-
* its retry budget is keyed, so two graders on one state can never share a
|
|
14
|
-
* budget or be confused for one another in an event.
|
|
15
|
-
*/
|
|
16
|
-
import type { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
|
17
|
-
import type { CreateDeepAgentParams } from "deepagents";
|
|
18
|
-
import type { MachineSpec, RubricDeclaration } from "../machine/types.js";
|
|
19
|
-
/** A grader in the Deep Agents shape, registered for the runtime's own `task` dispatch. */
|
|
20
|
-
export type LoadedRubric = NonNullable<CreateDeepAgentParams["subagents"]>[number];
|
|
21
|
-
/** The verdict vocabulary. `correct` asks for another iteration; `veto` blocks outright. */
|
|
22
|
-
export type RubricVerdict = "ok" | "correct" | "veto";
|
|
23
|
-
export interface RubricVerdictResult {
|
|
24
|
-
verdict: RubricVerdict;
|
|
25
|
-
reason: string;
|
|
26
|
-
/** The rubric that produced this verdict; absent for a script hook's own verdict. */
|
|
27
|
-
rubric?: string;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* The structured output a rubric with an iteration budget must return. Applied
|
|
31
|
-
* automatically, so a grader's output is a contract rather than a prompt
|
|
32
|
-
* convention.
|
|
33
|
-
*/
|
|
34
|
-
export declare const RUBRIC_VERDICT_SCHEMA: {
|
|
35
|
-
readonly type: "object";
|
|
36
|
-
readonly properties: {
|
|
37
|
-
readonly verdict: {
|
|
38
|
-
readonly type: "string";
|
|
39
|
-
readonly enum: readonly ["ok", "correct", "veto"];
|
|
40
|
-
};
|
|
41
|
-
readonly reason: {
|
|
42
|
-
readonly type: "string";
|
|
43
|
-
};
|
|
44
|
-
};
|
|
45
|
-
readonly required: readonly ["verdict", "reason"];
|
|
46
|
-
};
|
|
47
|
-
/**
|
|
48
|
-
* One registry entry: the declaration plus the positional id the runtime
|
|
49
|
-
* dispatches it under. The id is internal — it appears in operator-facing events
|
|
50
|
-
* and never in a prompt — so it is built for uniqueness, not for authoring.
|
|
51
|
-
*/
|
|
52
|
-
export interface Rubric extends RubricDeclaration {
|
|
53
|
-
id: string;
|
|
54
|
-
state: string;
|
|
55
|
-
phase: "before" | "after";
|
|
56
|
-
index: number;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* The id one inline rubric is registered and dispatched under. Positional
|
|
60
|
-
* because an inline rubric has no name: reordering a phase's hooks re-keys them,
|
|
61
|
-
* which is the same class of change as editing the spec at all (it moves the
|
|
62
|
-
* spec hash).
|
|
63
|
-
*/
|
|
64
|
-
export declare function rubricId(state: string, phase: "before" | "after", index: number): string;
|
|
65
|
-
/** Whether a value is a usable verdict. Anything else has graded nothing. */
|
|
66
|
-
export declare function isRubricVerdict(value: unknown): value is RubricVerdictResult;
|
|
67
|
-
/**
|
|
68
|
-
* The structured-output schema every dispatch requests: the verdict schema,
|
|
69
|
-
* unconditionally.
|
|
70
|
-
*
|
|
71
|
-
* Not conditional on `max_iterations`, as it was when a grader was a subagent
|
|
72
|
-
* that might also be a general-purpose helper. A rubric only ever grades, so a
|
|
73
|
-
* grader that needs no retries still has to answer in the verdict vocabulary —
|
|
74
|
-
* and without the schema its answer arrives as prose, parses to no verdict, and
|
|
75
|
-
* fails closed on a transition the author expected it to wave through.
|
|
76
|
-
*/
|
|
77
|
-
export declare function resolveRubricResponseFormat(_rubric: RubricDeclaration): Record<string, unknown> | undefined;
|
|
78
|
-
/** The compact task payload a grader is handed: the request, the transcript, and where it happened. */
|
|
79
|
-
export declare function buildRubricTaskDescription(args: Record<string, unknown>): string;
|
|
80
|
-
/**
|
|
81
|
-
* What an `after`-hook verdict does to an `archmax_advance` attempt.
|
|
82
|
-
*
|
|
83
|
-
* `reason` is `null` when the transition may proceed. The other two are decided
|
|
84
|
-
* here, together, because they are mutually exclusive and were not: a `correct`
|
|
85
|
-
* whose budget is already spent is `budgetExhausted` and bills nothing, while
|
|
86
|
-
* only a `correct` that actually got its retry is `consumesIteration`. Billing
|
|
87
|
-
* an attempt that was never granted costs the state its budget for good on
|
|
88
|
-
* re-entry (issue #62).
|
|
89
|
-
*/
|
|
90
|
-
export interface RubricTransitionOutcome {
|
|
91
|
-
reason: string | null;
|
|
92
|
-
/** A `correct` refused because the hook's `max_iterations` are already spent. */
|
|
93
|
-
budgetExhausted: boolean;
|
|
94
|
-
/** This block granted a retry, so it spends one of the hook's iterations. */
|
|
95
|
-
consumesIteration: boolean;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Map an `after`-hook verdict to an `archmax_advance` rejection outcome. One
|
|
99
|
-
* implementation for every hook kind: the retry flow (bounded iterations with
|
|
100
|
-
* remaining-attempt guidance) is identical whether the verdict came from a
|
|
101
|
-
* rubric or a script — only the label differs (`rubric` vs `hook`).
|
|
102
|
-
*/
|
|
103
|
-
export declare function rubricTransitionOutcome(verdict: RubricVerdictResult, opts: {
|
|
104
|
-
maxIterations: number;
|
|
105
|
-
iterationsUsed: number;
|
|
106
|
-
to?: string;
|
|
107
|
-
}): RubricTransitionOutcome;
|
|
108
|
-
/**
|
|
109
|
-
* The rejection reason alone, for callers that do not decide the retry budget.
|
|
110
|
-
*/
|
|
111
|
-
export declare function rubricTransitionReason(verdict: RubricVerdictResult, opts: {
|
|
112
|
-
maxIterations: number;
|
|
113
|
-
iterationsUsed: number;
|
|
114
|
-
to?: string;
|
|
115
|
-
}): string | null;
|
|
116
|
-
/**
|
|
117
|
-
* The rubric registry for one machine: every inline rubric its states declare,
|
|
118
|
-
* keyed by {@link rubricId}. Walks the spec rather than reading a root block,
|
|
119
|
-
* because a grader lives on the hook that applies it.
|
|
120
|
-
*
|
|
121
|
-
* Scoped to this spec, so a delegated child is graded by its own standards; two
|
|
122
|
-
* states declaring the same criteria produce two entries, which is the accepted
|
|
123
|
-
* cost of a state being legible on its own.
|
|
124
|
-
*/
|
|
125
|
-
export declare function rubricsFromSpec(spec: Pick<MachineSpec, "states">): Map<string, Rubric>;
|
|
126
|
-
/**
|
|
127
|
-
* Project the registry into the Deep Agents subagent shape so the framework
|
|
128
|
-
* registers the `task` tool the runtime dispatches through. These are never
|
|
129
|
-
* disclosed to the agent: `task` is withheld in every state and grantable by
|
|
130
|
-
* nothing, so registering a grader here gives the graded agent no reach.
|
|
131
|
-
*
|
|
132
|
-
* `model` resolves the grader's own model when it declared one, else the
|
|
133
|
-
* assembly's `rubric`-role model.
|
|
134
|
-
*/
|
|
135
|
-
export declare function rubricsAsSubagents(registry: Map<string, Rubric>, modelFor?: (rubric: Rubric) => BaseChatModel | undefined): LoadedRubric[];
|
package/dist/rubrics/rubrics.js
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import { normalizeHooks } from "../lifecycle/hook-shape.js";
|
|
2
|
-
import { ADVANCE_TOOL } from "../machine/tool-names.js";
|
|
3
|
-
/**
|
|
4
|
-
* The structured output a rubric with an iteration budget must return. Applied
|
|
5
|
-
* automatically, so a grader's output is a contract rather than a prompt
|
|
6
|
-
* convention.
|
|
7
|
-
*/
|
|
8
|
-
export const RUBRIC_VERDICT_SCHEMA = {
|
|
9
|
-
type: "object",
|
|
10
|
-
properties: {
|
|
11
|
-
verdict: { type: "string", enum: ["ok", "correct", "veto"] },
|
|
12
|
-
reason: { type: "string" },
|
|
13
|
-
},
|
|
14
|
-
required: ["verdict", "reason"],
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
17
|
-
* The id one inline rubric is registered and dispatched under. Positional
|
|
18
|
-
* because an inline rubric has no name: reordering a phase's hooks re-keys them,
|
|
19
|
-
* which is the same class of change as editing the spec at all (it moves the
|
|
20
|
-
* spec hash).
|
|
21
|
-
*/
|
|
22
|
-
export function rubricId(state, phase, index) {
|
|
23
|
-
return `${state}--${phase}--${index}`;
|
|
24
|
-
}
|
|
25
|
-
/** Whether a value is a usable verdict. Anything else has graded nothing. */
|
|
26
|
-
export function isRubricVerdict(value) {
|
|
27
|
-
if (!value || typeof value !== "object")
|
|
28
|
-
return false;
|
|
29
|
-
const v = value;
|
|
30
|
-
return v.verdict === "ok" || v.verdict === "correct" || v.verdict === "veto";
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* The structured-output schema every dispatch requests: the verdict schema,
|
|
34
|
-
* unconditionally.
|
|
35
|
-
*
|
|
36
|
-
* Not conditional on `max_iterations`, as it was when a grader was a subagent
|
|
37
|
-
* that might also be a general-purpose helper. A rubric only ever grades, so a
|
|
38
|
-
* grader that needs no retries still has to answer in the verdict vocabulary —
|
|
39
|
-
* and without the schema its answer arrives as prose, parses to no verdict, and
|
|
40
|
-
* fails closed on a transition the author expected it to wave through.
|
|
41
|
-
*/
|
|
42
|
-
export function resolveRubricResponseFormat(_rubric) {
|
|
43
|
-
return RUBRIC_VERDICT_SCHEMA;
|
|
44
|
-
}
|
|
45
|
-
/** The compact task payload a grader is handed: the request, the transcript, and where it happened. */
|
|
46
|
-
export function buildRubricTaskDescription(args) {
|
|
47
|
-
return JSON.stringify({
|
|
48
|
-
userRequest: args.userRequest ?? null,
|
|
49
|
-
history: args.history ?? [],
|
|
50
|
-
state: args.state ?? null,
|
|
51
|
-
phase: args.phase ?? null,
|
|
52
|
-
}, null, 2);
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Map an `after`-hook verdict to an `archmax_advance` rejection outcome. One
|
|
56
|
-
* implementation for every hook kind: the retry flow (bounded iterations with
|
|
57
|
-
* remaining-attempt guidance) is identical whether the verdict came from a
|
|
58
|
-
* rubric or a script — only the label differs (`rubric` vs `hook`).
|
|
59
|
-
*/
|
|
60
|
-
export function rubricTransitionOutcome(verdict, opts) {
|
|
61
|
-
const label = verdict.rubric ? "rubric" : "hook";
|
|
62
|
-
if (verdict.verdict === "ok") {
|
|
63
|
-
return { reason: null, budgetExhausted: false, consumesIteration: false };
|
|
64
|
-
}
|
|
65
|
-
if (verdict.verdict === "veto") {
|
|
66
|
-
// A deliberate veto charges nothing: no retry was offered to bill for.
|
|
67
|
-
return {
|
|
68
|
-
reason: `${label} veto: ${verdict.reason}`,
|
|
69
|
-
budgetExhausted: false,
|
|
70
|
-
consumesIteration: false,
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
const max = Math.max(0, opts.maxIterations);
|
|
74
|
-
if (opts.iterationsUsed >= max) {
|
|
75
|
-
return {
|
|
76
|
-
reason: `${label} veto: reply still incomplete after ${max} attempt(s) — ${verdict.reason}`,
|
|
77
|
-
budgetExhausted: true,
|
|
78
|
-
consumesIteration: false,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
const remaining = max - opts.iterationsUsed;
|
|
82
|
-
const target = opts.to ? `${ADVANCE_TOOL}({ to: "${opts.to}" })` : ADVANCE_TOOL;
|
|
83
|
-
return {
|
|
84
|
-
reason: `${label}: reply incomplete — ${verdict.reason}. ` +
|
|
85
|
-
`Update your answer and call ${target} again. (${remaining} attempt(s) remaining)`,
|
|
86
|
-
budgetExhausted: false,
|
|
87
|
-
consumesIteration: true,
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* The rejection reason alone, for callers that do not decide the retry budget.
|
|
92
|
-
*/
|
|
93
|
-
export function rubricTransitionReason(verdict, opts) {
|
|
94
|
-
return rubricTransitionOutcome(verdict, opts).reason;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* The rubric registry for one machine: every inline rubric its states declare,
|
|
98
|
-
* keyed by {@link rubricId}. Walks the spec rather than reading a root block,
|
|
99
|
-
* because a grader lives on the hook that applies it.
|
|
100
|
-
*
|
|
101
|
-
* Scoped to this spec, so a delegated child is graded by its own standards; two
|
|
102
|
-
* states declaring the same criteria produce two entries, which is the accepted
|
|
103
|
-
* cost of a state being legible on its own.
|
|
104
|
-
*/
|
|
105
|
-
export function rubricsFromSpec(spec) {
|
|
106
|
-
const registry = new Map();
|
|
107
|
-
for (const [state, declared] of Object.entries(spec.states ?? {})) {
|
|
108
|
-
for (const phase of ["before", "after"]) {
|
|
109
|
-
normalizeHooks(declared?.[phase]).forEach((hook, index) => {
|
|
110
|
-
const declaration = hook.rubric;
|
|
111
|
-
if (declaration === undefined || typeof declaration !== "object")
|
|
112
|
-
return;
|
|
113
|
-
const id = rubricId(state, phase, index);
|
|
114
|
-
registry.set(id, { ...declaration, id, state, phase, index });
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return registry;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Project the registry into the Deep Agents subagent shape so the framework
|
|
122
|
-
* registers the `task` tool the runtime dispatches through. These are never
|
|
123
|
-
* disclosed to the agent: `task` is withheld in every state and grantable by
|
|
124
|
-
* nothing, so registering a grader here gives the graded agent no reach.
|
|
125
|
-
*
|
|
126
|
-
* `model` resolves the grader's own model when it declared one, else the
|
|
127
|
-
* assembly's `rubric`-role model.
|
|
128
|
-
*/
|
|
129
|
-
export function rubricsAsSubagents(registry, modelFor) {
|
|
130
|
-
return [...registry.values()].map((rubric) => {
|
|
131
|
-
const responseFormat = resolveRubricResponseFormat(rubric);
|
|
132
|
-
const model = modelFor?.(rubric);
|
|
133
|
-
return {
|
|
134
|
-
name: rubric.id,
|
|
135
|
-
// A grader is dispatched by the runtime under its positional id, never
|
|
136
|
-
// chosen from a menu by the agent, so the description exists only for the
|
|
137
|
-
// framework's own tool schema — which no state is ever shown.
|
|
138
|
-
description: `Grading rubric on '${rubric.state}' (${rubric.phase}).`,
|
|
139
|
-
systemPrompt: rubric.instructions,
|
|
140
|
-
...(responseFormat !== undefined ? { responseFormat } : {}),
|
|
141
|
-
...(model !== undefined ? { model } : {}),
|
|
142
|
-
};
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
//# sourceMappingURL=rubrics.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rubrics.js","sourceRoot":"","sources":["../../src/rubrics/rubrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
// QuickJS sandbox core: the verdict helpers a lifecycle hook answers with.
|
|
2
|
-
//
|
|
3
|
-
// return ok(); // proceed
|
|
4
|
-
// return correct("why"); // the agent gets another attempt (after hooks)
|
|
5
|
-
// return veto("why"); // block, with the reason shown to the agent
|
|
6
|
-
//
|
|
7
|
-
// Returning nothing is `ok`; throwing is a veto (fail-closed). Nothing else is
|
|
8
|
-
// installed here — the hook reads its inputs from the object it is called with.
|
|
9
|
-
|
|
10
|
-
globalThis.__verdict = (verdict, reason, fallback) => ({
|
|
11
|
-
verdict,
|
|
12
|
-
reason: reason == null || String(reason).trim() === "" ? fallback : String(reason),
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
globalThis.ok = (reason) => globalThis.__verdict("ok", reason, "ok");
|
|
16
|
-
globalThis.veto = (reason) => globalThis.__verdict("veto", reason, "vetoed by hook");
|
|
17
|
-
globalThis.correct = (reason) => globalThis.__verdict("correct", reason, "correction requested");
|
|
18
|
-
|
|
19
|
-
globalThis.__isVerdict = (value) =>
|
|
20
|
-
value != null &&
|
|
21
|
-
typeof value === "object" &&
|
|
22
|
-
(value.verdict === "ok" || value.verdict === "veto" || value.verdict === "correct");
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
// Lifecycle-hook context: the contract marker, the `defineHook` authoring
|
|
2
|
-
// alias, and the reducer that turns whatever a hook produced into a verdict.
|
|
3
|
-
// These globals are absent from the PTC context.
|
|
4
|
-
|
|
5
|
-
globalThis.SANDBOX_CONTRACT = { context: "lifecycle-hook", version: globalThis.__SANDBOX_VERSION };
|
|
6
|
-
|
|
7
|
-
// `export default defineHook(fn)` and `export default async function hook(...)`
|
|
8
|
-
// both register the hook; the executor rewrites `export default` to an
|
|
9
|
-
// assignment of `__hookDef`, so `defineHook` is an identity that also registers.
|
|
10
|
-
globalThis.defineHook = (fn) => {
|
|
11
|
-
globalThis.__hookDef = fn;
|
|
12
|
-
return fn;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
// How an object that is not a verdict is named back to its author: by its keys,
|
|
16
|
-
// never its values, so a diagnostic cannot leak what the hook was inspecting.
|
|
17
|
-
globalThis.__hookShape = (value) => {
|
|
18
|
-
if (Array.isArray(value)) return "an array";
|
|
19
|
-
try {
|
|
20
|
-
const keys = Object.keys(value);
|
|
21
|
-
if (keys.length === 0) return "an object with no keys";
|
|
22
|
-
const shown = keys.slice(0, 6).map((key) => `'${key}'`).join(", ");
|
|
23
|
-
return `an object with ${keys.length > 6 ? "keys including " : "keys "}${shown}`;
|
|
24
|
-
} catch {
|
|
25
|
-
return "an object";
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// The verdict of a hook run. A verdict object is taken as is, a bare `false`
|
|
30
|
-
// vetoes, and returning nothing is `ok`.
|
|
31
|
-
//
|
|
32
|
-
// Any *other* object fails closed. A hook's return value is its verdict and
|
|
33
|
-
// nothing else, so an object that is not one is a verdict its author got wrong
|
|
34
|
-
// — a misspelled `verdict`, a retired shape like `{ ok: false, reason }`. Read
|
|
35
|
-
// as `ok` it would silently permit precisely what the hook meant to block, and
|
|
36
|
-
// the author would have no way to notice: the run just proceeds.
|
|
37
|
-
globalThis.__hookVerdict = (value) => {
|
|
38
|
-
if (globalThis.__isVerdict(value)) return value;
|
|
39
|
-
if (value === false) return globalThis.veto("precondition not met");
|
|
40
|
-
if (value !== null && typeof value === "object") {
|
|
41
|
-
throw new Error(
|
|
42
|
-
`hook returned ${globalThis.__hookShape(value)}, which is not a verdict — ` +
|
|
43
|
-
"return ok(), veto(reason), correct(reason), false, or nothing at all",
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
return globalThis.ok();
|
|
47
|
-
};
|
package/dist/sandbox/bridge.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { RunnableConfig } from "@langchain/core/runnables";
|
|
2
|
-
import type { StructuredTool } from "@langchain/core/tools";
|
|
3
|
-
import { type SubagentBridgeOptions } from "@langchain/quickjs";
|
|
4
|
-
import type { WorkflowEventEmitter } from "../core/events.js";
|
|
5
|
-
/** Recover the textual payload from whatever envelope `task()` returns. */
|
|
6
|
-
export declare function unwrapToolEnvelope(value: unknown): unknown;
|
|
7
|
-
/**
|
|
8
|
-
* Bridge the QuickJS `task()` global to the Deep Agents `task` tool. When
|
|
9
|
-
* `telemetry` is supplied, each dispatch is bracketed with
|
|
10
|
-
* `rubric-start`/`rubric-result` lifecycle events (this path bypasses the
|
|
11
|
-
* outer agent's tool middleware, so it must emit its own bracketing).
|
|
12
|
-
*/
|
|
13
|
-
export declare function createSubagentBridgeDispatch(taskTool: StructuredTool, config: RunnableConfig, telemetry?: {
|
|
14
|
-
emit: WorkflowEventEmitter;
|
|
15
|
-
state?: string;
|
|
16
|
-
}): SubagentBridgeOptions["dispatch"];
|
package/dist/sandbox/bridge.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { BaseMessage } from "@langchain/core/messages";
|
|
2
|
-
import { isCommand } from "@langchain/langgraph";
|
|
3
|
-
import { SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY } from "deepagents";
|
|
4
|
-
import { validateResponseSchema } from "@langchain/quickjs";
|
|
5
|
-
/** Recover the textual payload from whatever envelope `task()` returns. */
|
|
6
|
-
export function unwrapToolEnvelope(value) {
|
|
7
|
-
if (typeof value === "string")
|
|
8
|
-
return value;
|
|
9
|
-
if (isCommand(value)) {
|
|
10
|
-
const messages = value.update?.messages;
|
|
11
|
-
if (Array.isArray(messages)) {
|
|
12
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
13
|
-
const message = messages[i];
|
|
14
|
-
if (BaseMessage.isInstance(message) && message.content != null) {
|
|
15
|
-
return unwrapToolEnvelope(message.content);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return value;
|
|
20
|
-
}
|
|
21
|
-
if (BaseMessage.isInstance(value))
|
|
22
|
-
return unwrapToolEnvelope(value.content);
|
|
23
|
-
if (Array.isArray(value)) {
|
|
24
|
-
for (let i = value.length - 1; i >= 0; i--) {
|
|
25
|
-
const entry = value[i];
|
|
26
|
-
if (BaseMessage.isInstance(entry))
|
|
27
|
-
return unwrapToolEnvelope(entry.content);
|
|
28
|
-
if (isCommand(entry)) {
|
|
29
|
-
const inner = unwrapToolEnvelope(entry);
|
|
30
|
-
if (inner !== entry)
|
|
31
|
-
return inner;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return value;
|
|
36
|
-
}
|
|
37
|
-
/** Ids for bridge dispatches, which have no model-assigned tool-call id. */
|
|
38
|
-
let bridgeDispatchSeq = 0;
|
|
39
|
-
/**
|
|
40
|
-
* Bridge the QuickJS `task()` global to the Deep Agents `task` tool. When
|
|
41
|
-
* `telemetry` is supplied, each dispatch is bracketed with
|
|
42
|
-
* `rubric-start`/`rubric-result` lifecycle events (this path bypasses the
|
|
43
|
-
* outer agent's tool middleware, so it must emit its own bracketing).
|
|
44
|
-
*/
|
|
45
|
-
export function createSubagentBridgeDispatch(taskTool, config, telemetry) {
|
|
46
|
-
return async (input) => {
|
|
47
|
-
const hasSchema = input.responseSchema != null;
|
|
48
|
-
if (hasSchema)
|
|
49
|
-
validateResponseSchema(input.responseSchema);
|
|
50
|
-
const toolConfig = {
|
|
51
|
-
...config,
|
|
52
|
-
configurable: {
|
|
53
|
-
...config.configurable,
|
|
54
|
-
...(hasSchema && { [SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY]: input.responseSchema }),
|
|
55
|
-
},
|
|
56
|
-
};
|
|
57
|
-
const dispatchId = `bridge-${++bridgeDispatchSeq}`;
|
|
58
|
-
const state = telemetry?.state ?? "";
|
|
59
|
-
telemetry?.emit({
|
|
60
|
-
type: "rubric-start",
|
|
61
|
-
state,
|
|
62
|
-
name: input.subagentType,
|
|
63
|
-
dispatchId,
|
|
64
|
-
});
|
|
65
|
-
const startedAt = Date.now();
|
|
66
|
-
const settle = (status) => telemetry?.emit({
|
|
67
|
-
type: "rubric-result",
|
|
68
|
-
state,
|
|
69
|
-
name: input.subagentType,
|
|
70
|
-
dispatchId,
|
|
71
|
-
status,
|
|
72
|
-
durationMs: Date.now() - startedAt,
|
|
73
|
-
});
|
|
74
|
-
let raw;
|
|
75
|
-
try {
|
|
76
|
-
raw = await taskTool.invoke({ description: input.description, subagent_type: input.subagentType }, toolConfig);
|
|
77
|
-
}
|
|
78
|
-
catch (err) {
|
|
79
|
-
settle("error");
|
|
80
|
-
throw err;
|
|
81
|
-
}
|
|
82
|
-
settle("ok");
|
|
83
|
-
const content = unwrapToolEnvelope(raw);
|
|
84
|
-
if (hasSchema && typeof content === "string") {
|
|
85
|
-
try {
|
|
86
|
-
return JSON.parse(content);
|
|
87
|
-
}
|
|
88
|
-
catch {
|
|
89
|
-
return content;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return content;
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
//# sourceMappingURL=bridge.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/sandbox/bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { type VisitStart } from "./state.js";
|
|
2
|
-
/** One visit as found in a transcript: its number (from 1), its state and its first message's index. */
|
|
3
|
-
export interface VisitSpan {
|
|
4
|
-
number: number;
|
|
5
|
-
state: string;
|
|
6
|
-
start: number;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* The session's visits over `messages`, in order. A session from before the
|
|
10
|
-
* visit log has no entry for what precedes its first logged visit: that span
|
|
11
|
-
* is one visit, at the session's entry state.
|
|
12
|
-
*/
|
|
13
|
-
export declare function visitSpans(messages: readonly unknown[], state: unknown): VisitSpan[];
|
|
14
|
-
/** The visit holding the message at `index`. */
|
|
15
|
-
export declare function visitAt(spans: readonly VisitSpan[], index: number): VisitSpan;
|
|
16
|
-
/** The messages of the visit the session is in. */
|
|
17
|
-
export declare function currentVisitMessages(messages: readonly unknown[], state: unknown): unknown[];
|
|
18
|
-
/** The log entry for entering `target` with the transcript standing at `messages`. */
|
|
19
|
-
export declare function visitStart(target: string, messages: unknown): VisitStart[];
|
|
20
|
-
/** A checkpointed state's transcript. */
|
|
21
|
-
export declare function messagesIn(state: unknown): unknown[];
|
package/dist/workflow/visits.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Visits: the span of a session from its entry into a state until it next
|
|
3
|
-
* enters one. What a hook sees of the conversation is the current visit, and
|
|
4
|
-
* every tool call is attributed to the visit of the message that made it.
|
|
5
|
-
*/
|
|
6
|
-
import { anchorIndex, turnAnchorOf } from "../core/messages.js";
|
|
7
|
-
import { readWorkflowState } from "./state.js";
|
|
8
|
-
/**
|
|
9
|
-
* The session's visits over `messages`, in order. A session from before the
|
|
10
|
-
* visit log has no entry for what precedes its first logged visit: that span
|
|
11
|
-
* is one visit, at the session's entry state.
|
|
12
|
-
*/
|
|
13
|
-
export function visitSpans(messages, state) {
|
|
14
|
-
const fields = readWorkflowState(state);
|
|
15
|
-
const spans = (fields.visits ?? []).map((visit) => ({ state: visit.state, start: anchorIndex(messages, visit.from) }));
|
|
16
|
-
if (spans.length === 0 || spans[0].start > 0) {
|
|
17
|
-
spans.unshift({ state: fields.entryState ?? fields.workflowState ?? "", start: 0 });
|
|
18
|
-
}
|
|
19
|
-
return spans.map((span, i) => ({ number: i + 1, ...span }));
|
|
20
|
-
}
|
|
21
|
-
/** The visit holding the message at `index`. */
|
|
22
|
-
export function visitAt(spans, index) {
|
|
23
|
-
let found = spans[0];
|
|
24
|
-
for (const span of spans) {
|
|
25
|
-
if (span.start > index)
|
|
26
|
-
break;
|
|
27
|
-
found = span;
|
|
28
|
-
}
|
|
29
|
-
return found;
|
|
30
|
-
}
|
|
31
|
-
/** The messages of the visit the session is in. */
|
|
32
|
-
export function currentVisitMessages(messages, state) {
|
|
33
|
-
const spans = visitSpans(messages, state);
|
|
34
|
-
return messages.slice(spans[spans.length - 1].start);
|
|
35
|
-
}
|
|
36
|
-
/** The log entry for entering `target` with the transcript standing at `messages`. */
|
|
37
|
-
export function visitStart(target, messages) {
|
|
38
|
-
return [{ state: target, from: turnAnchorOf(messages) }];
|
|
39
|
-
}
|
|
40
|
-
/** A checkpointed state's transcript. */
|
|
41
|
-
export function messagesIn(state) {
|
|
42
|
-
const messages = state?.messages;
|
|
43
|
-
return Array.isArray(messages) ? messages : [];
|
|
44
|
-
}
|
|
45
|
-
//# sourceMappingURL=visits.js.map
|