@archmax-ai/harness 0.9.0 → 1.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.
Files changed (207) hide show
  1. package/README.md +58 -14
  2. package/dist/agent.d.ts +4 -6
  3. package/dist/agent.js +4 -6
  4. package/dist/agent.js.map +1 -1
  5. package/dist/assembly/compose.d.ts +5 -24
  6. package/dist/assembly/compose.js +28 -42
  7. package/dist/assembly/compose.js.map +1 -1
  8. package/dist/assembly/delegation-registry.js +3 -14
  9. package/dist/assembly/delegation-registry.js.map +1 -1
  10. package/dist/assembly/index.d.ts +8 -15
  11. package/dist/assembly/index.js +21 -28
  12. package/dist/assembly/index.js.map +1 -1
  13. package/dist/assembly/plain.js +1 -2
  14. package/dist/assembly/plain.js.map +1 -1
  15. package/dist/authoring-skill/archmax-harness/README.md +5 -5
  16. package/dist/authoring-skill/archmax-harness/SKILL.md +72 -30
  17. package/dist/authoring-skill/archmax-harness/references/backend-integration.md +33 -24
  18. package/dist/authoring-skill/archmax-harness/references/cases.md +41 -8
  19. package/dist/authoring-skill/archmax-harness/references/{hook-and-test-scripts.md → code-state-and-test-scripts.md} +599 -339
  20. package/dist/authoring-skill/archmax-harness/references/code-states-and-scripts.md +115 -0
  21. package/dist/authoring-skill/archmax-harness/references/diagnostics.md +40 -7
  22. package/dist/authoring-skill/archmax-harness/references/wiring.md +19 -10
  23. package/dist/authoring-skill/archmax-harness/references/workflow-schema.md +404 -293
  24. package/dist/authoring-skill/archmax-harness/references/workflow-yaml.md +151 -62
  25. package/dist/cli/state-flow.d.ts +1 -1
  26. package/dist/cli/state-flow.js +18 -28
  27. package/dist/cli/state-flow.js.map +1 -1
  28. package/dist/cli/turn.d.ts +1 -1
  29. package/dist/cli/turn.js +1 -1
  30. package/dist/core/code-description.d.ts +3 -3
  31. package/dist/core/code-description.js +3 -3
  32. package/dist/core/deepagents.d.ts +5 -12
  33. package/dist/core/deepagents.js +4 -17
  34. package/dist/core/deepagents.js.map +1 -1
  35. package/dist/core/events.d.ts +23 -42
  36. package/dist/core/events.js +21 -24
  37. package/dist/core/events.js.map +1 -1
  38. package/dist/core/message-readers.d.ts +4 -5
  39. package/dist/core/message-readers.js +3 -8
  40. package/dist/core/message-readers.js.map +1 -1
  41. package/dist/core/messages.d.ts +0 -22
  42. package/dist/core/messages.js +1 -32
  43. package/dist/core/messages.js.map +1 -1
  44. package/dist/core/mounts.js +3 -3
  45. package/dist/core/platform-prompt.generated.js +1 -1
  46. package/dist/core/platform-prompt.generated.js.map +1 -1
  47. package/dist/core/session-zone.d.ts +1 -1
  48. package/dist/core/session-zone.js +1 -1
  49. package/dist/core/workspace-context.d.ts +1 -1
  50. package/dist/core/workspace.d.ts +1 -1
  51. package/dist/core/workspace.js +1 -1
  52. package/dist/core/zones.d.ts +4 -4
  53. package/dist/core/zones.js +5 -5
  54. package/dist/core/zones.js.map +1 -1
  55. package/dist/env.d.ts +9 -9
  56. package/dist/index.d.ts +3 -7
  57. package/dist/index.js +2 -4
  58. package/dist/index.js.map +1 -1
  59. package/dist/kernel/kernel.d.ts +31 -61
  60. package/dist/kernel/kernel.js +54 -112
  61. package/dist/kernel/kernel.js.map +1 -1
  62. package/dist/machine/lint-spec.js +53 -12
  63. package/dist/machine/lint-spec.js.map +1 -1
  64. package/dist/machine/machine.d.ts +36 -18
  65. package/dist/machine/machine.js +62 -51
  66. package/dist/machine/machine.js.map +1 -1
  67. package/dist/machine/spec-schema.d.ts +32 -180
  68. package/dist/machine/spec-schema.js +52 -113
  69. package/dist/machine/spec-schema.js.map +1 -1
  70. package/dist/machine/tool-names.d.ts +34 -16
  71. package/dist/machine/tool-names.js +41 -16
  72. package/dist/machine/tool-names.js.map +1 -1
  73. package/dist/machine/types.d.ts +14 -46
  74. package/dist/machine/types.js +0 -2
  75. package/dist/machine/types.js.map +1 -1
  76. package/dist/machine/validate-spec.d.ts +1 -1
  77. package/dist/public/sandbox.d.ts +59 -95
  78. package/dist/public/sandbox.js +22 -23
  79. package/dist/public/sandbox.js.map +1 -1
  80. package/dist/public/spec.d.ts +13 -20
  81. package/dist/public/spec.js +12 -20
  82. package/dist/public/spec.js.map +1 -1
  83. package/dist/runtime/contract.d.ts +11 -12
  84. package/dist/runtime/contract.js +16 -16
  85. package/dist/runtime/contract.js.map +1 -1
  86. package/dist/sandbox/assets/parts/code-state.js +17 -0
  87. package/dist/sandbox/executor.d.ts +25 -7
  88. package/dist/sandbox/executor.js +56 -57
  89. package/dist/sandbox/executor.js.map +1 -1
  90. package/dist/sandbox/imports.d.ts +10 -10
  91. package/dist/sandbox/imports.js +11 -11
  92. package/dist/sandbox/imports.js.map +1 -1
  93. package/dist/sandbox/prelude.d.ts +5 -6
  94. package/dist/sandbox/prelude.js +38 -35
  95. package/dist/sandbox/prelude.js.map +1 -1
  96. package/dist/sandbox/ptc-gateway.d.ts +19 -18
  97. package/dist/sandbox/ptc-gateway.js +26 -22
  98. package/dist/sandbox/ptc-gateway.js.map +1 -1
  99. package/dist/sessions/resume.d.ts +2 -2
  100. package/dist/sessions/resume.js +1 -1
  101. package/dist/sessions/resume.js.map +1 -1
  102. package/dist/sessions/scope.d.ts +0 -10
  103. package/dist/sessions/scope.js +0 -17
  104. package/dist/sessions/scope.js.map +1 -1
  105. package/dist/sessions/summary.d.ts +1 -1
  106. package/dist/testing/assertions.js +9 -4
  107. package/dist/testing/assertions.js.map +1 -1
  108. package/dist/testing/driver.js +3 -0
  109. package/dist/testing/driver.js.map +1 -1
  110. package/dist/testing/interpreter.d.ts +2 -2
  111. package/dist/testing/runner.d.ts +2 -2
  112. package/dist/validate/validate.d.ts +1 -1
  113. package/dist/validate/validate.js +39 -70
  114. package/dist/validate/validate.js.map +1 -1
  115. package/dist/workflow/automated-controls.d.ts +63 -0
  116. package/dist/workflow/automated-controls.js +158 -0
  117. package/dist/workflow/automated-controls.js.map +1 -0
  118. package/dist/workflow/automated.d.ts +112 -0
  119. package/dist/workflow/automated.js +163 -0
  120. package/dist/workflow/automated.js.map +1 -0
  121. package/dist/workflow/code-state.d.ts +46 -0
  122. package/dist/workflow/code-state.js +26 -0
  123. package/dist/workflow/code-state.js.map +1 -0
  124. package/dist/workflow/control-tools.d.ts +54 -23
  125. package/dist/workflow/control-tools.js +99 -79
  126. package/dist/workflow/control-tools.js.map +1 -1
  127. package/dist/workflow/file-values.d.ts +4 -4
  128. package/dist/workflow/file-values.js +1 -1
  129. package/dist/workflow/file-values.js.map +1 -1
  130. package/dist/workflow/governance.d.ts +11 -22
  131. package/dist/workflow/governance.js +47 -104
  132. package/dist/workflow/governance.js.map +1 -1
  133. package/dist/workflow/grader-state.d.ts +55 -0
  134. package/dist/workflow/grader-state.js +182 -0
  135. package/dist/workflow/grader-state.js.map +1 -0
  136. package/dist/workflow/history.d.ts +11 -0
  137. package/dist/{lifecycle/transcript.js → workflow/history.js} +24 -8
  138. package/dist/workflow/history.js.map +1 -0
  139. package/dist/workflow/middleware.d.ts +14 -17
  140. package/dist/workflow/middleware.js +109 -95
  141. package/dist/workflow/middleware.js.map +1 -1
  142. package/dist/workflow/move-events.d.ts +21 -0
  143. package/dist/workflow/move-events.js +20 -0
  144. package/dist/workflow/move-events.js.map +1 -0
  145. package/dist/workflow/on-error.js +0 -2
  146. package/dist/workflow/on-error.js.map +1 -1
  147. package/dist/workflow/parks.d.ts +9 -2
  148. package/dist/workflow/parks.js +16 -10
  149. package/dist/workflow/parks.js.map +1 -1
  150. package/dist/workflow/paths.d.ts +9 -9
  151. package/dist/workflow/paths.js +19 -19
  152. package/dist/workflow/paths.js.map +1 -1
  153. package/dist/workflow/render-prompt.d.ts +7 -5
  154. package/dist/workflow/render-prompt.js +22 -37
  155. package/dist/workflow/render-prompt.js.map +1 -1
  156. package/dist/workflow/signature-checks.d.ts +2 -2
  157. package/dist/workflow/snapshot.js +5 -29
  158. package/dist/workflow/snapshot.js.map +1 -1
  159. package/dist/workflow/state.d.ts +14 -42
  160. package/dist/workflow/state.js +20 -33
  161. package/dist/workflow/state.js.map +1 -1
  162. package/dist/workflow/sub-workflow.d.ts +3 -3
  163. package/dist/workflow/sub-workflow.js +3 -7
  164. package/dist/workflow/sub-workflow.js.map +1 -1
  165. package/dist/workflow/tool-service.d.ts +1 -9
  166. package/dist/workflow/tool-service.js +21 -24
  167. package/dist/workflow/tool-service.js.map +1 -1
  168. package/dist/workflow/turn-boundary.d.ts +2 -2
  169. package/dist/workflow/turn-boundary.js +10 -15
  170. package/dist/workflow/turn-boundary.js.map +1 -1
  171. package/dist/workflow/turn-runner.js +5 -6
  172. package/dist/workflow/turn-runner.js.map +1 -1
  173. package/package.json +1 -1
  174. package/skills/archmax-harness/README.md +5 -5
  175. package/skills/archmax-harness/SKILL.md +72 -30
  176. package/skills/archmax-harness/references/backend-integration.md +33 -24
  177. package/skills/archmax-harness/references/cases.md +41 -8
  178. package/skills/archmax-harness/references/{hook-and-test-scripts.md → code-state-and-test-scripts.md} +599 -339
  179. package/skills/archmax-harness/references/code-states-and-scripts.md +115 -0
  180. package/skills/archmax-harness/references/diagnostics.md +40 -7
  181. package/skills/archmax-harness/references/wiring.md +19 -10
  182. package/skills/archmax-harness/references/workflow-schema.md +404 -293
  183. package/skills/archmax-harness/references/workflow-yaml.md +151 -62
  184. package/dist/authoring-skill/archmax-harness/references/hooks-and-scripts.md +0 -89
  185. package/dist/lifecycle/hook-shape.d.ts +0 -44
  186. package/dist/lifecycle/hook-shape.js +0 -66
  187. package/dist/lifecycle/hook-shape.js.map +0 -1
  188. package/dist/lifecycle/runner.d.ts +0 -197
  189. package/dist/lifecycle/runner.js +0 -419
  190. package/dist/lifecycle/runner.js.map +0 -1
  191. package/dist/lifecycle/tool-calls.d.ts +0 -9
  192. package/dist/lifecycle/tool-calls.js +0 -57
  193. package/dist/lifecycle/tool-calls.js.map +0 -1
  194. package/dist/lifecycle/transcript.d.ts +0 -31
  195. package/dist/lifecycle/transcript.js.map +0 -1
  196. package/dist/rubrics/rubrics.d.ts +0 -135
  197. package/dist/rubrics/rubrics.js +0 -145
  198. package/dist/rubrics/rubrics.js.map +0 -1
  199. package/dist/sandbox/assets/parts/core.js +0 -22
  200. package/dist/sandbox/assets/parts/lifecycle-hook.js +0 -47
  201. package/dist/sandbox/bridge.d.ts +0 -16
  202. package/dist/sandbox/bridge.js +0 -95
  203. package/dist/sandbox/bridge.js.map +0 -1
  204. package/dist/workflow/visits.d.ts +0 -21
  205. package/dist/workflow/visits.js +0 -45
  206. package/dist/workflow/visits.js.map +0 -1
  207. 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[];
@@ -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
- };
@@ -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"];
@@ -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[];
@@ -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