@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,415 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run-variable references — `${{name}}` and `${{name.dotted.path}}` — in guards,
|
|
3
|
+
* prompts and the arguments the agent writes. One resolver serves the kernel,
|
|
4
|
+
* disclosure, validation and substitution, so a reference means one thing.
|
|
5
|
+
*
|
|
6
|
+
* Three invariants carry the feature's safety: a substituted value is
|
|
7
|
+
* glob-escaped where the output is a *pattern* and verbatim where it is a
|
|
8
|
+
* *value*; resolution fails closed (never the literal `${{…}}` text, never `*`);
|
|
9
|
+
* and traversal reads own properties only (`resolvePath`), so `tags.length` and
|
|
10
|
+
* `constructor` never resolve.
|
|
11
|
+
*/
|
|
12
|
+
import { guardReferences } from "./allow.js";
|
|
13
|
+
import { SET_VARIABLES_TOOL } from "./tool-names.js";
|
|
14
|
+
import { declaredVariableNames } from "./triggers.js";
|
|
15
|
+
/** The shape a run-variable name must take: a snake_case identifier, never dotted. */
|
|
16
|
+
export const VARIABLE_NAME_PATTERN = /^[a-z][a-z0-9_]*$/;
|
|
17
|
+
/**
|
|
18
|
+
* The built-in variable holding the run's trigger id. Reserved: it is set by the
|
|
19
|
+
* harness at run start, locked, and needs no seed — so a guard may reference
|
|
20
|
+
* `${{trigger}}` without anything supplying it.
|
|
21
|
+
*/
|
|
22
|
+
export const TRIGGER_VARIABLE = "trigger";
|
|
23
|
+
/**
|
|
24
|
+
* The built-in variable holding a short label for the task the run is doing.
|
|
25
|
+
* Agent-owned, unlike `trigger`: nothing sets it until the agent does. Two rules
|
|
26
|
+
* follow it everywhere it is written — it is **never locked** (a seed stores it
|
|
27
|
+
* unlocked; `set_variables` refuses `lock: true`), and it is **shape-checked on
|
|
28
|
+
* write** ({@link titleWriteError}). Unrelated to the spec's static `title`
|
|
29
|
+
* fields.
|
|
30
|
+
*/
|
|
31
|
+
export const TITLE_VARIABLE = "title";
|
|
32
|
+
/**
|
|
33
|
+
* The longest a title may be. A bound, not a style guide — the system prompt asks
|
|
34
|
+
* for something short, and this only stops something unusable from being stored.
|
|
35
|
+
*/
|
|
36
|
+
export const TITLE_MAX_LENGTH = 200;
|
|
37
|
+
/**
|
|
38
|
+
* Check a value destined for {@link TITLE_VARIABLE}, returning the refusal reason
|
|
39
|
+
* or `undefined` when it passes. Shared by both write routes (a seed throws, the
|
|
40
|
+
* agent's `set_variables` is refused). Refuses rather than coerces; trimming is
|
|
41
|
+
* the one coercion allowed.
|
|
42
|
+
*/
|
|
43
|
+
export function titleWriteError(value) {
|
|
44
|
+
const shape = `'${TITLE_VARIABLE}' is reserved for a short label naming the task this run is doing. ` +
|
|
45
|
+
`It must be a non-empty single-line string of at most ${TITLE_MAX_LENGTH} characters`;
|
|
46
|
+
if (typeof value !== "string") {
|
|
47
|
+
return `${shape}, but a ${value === null ? "null" : typeof value} was given.`;
|
|
48
|
+
}
|
|
49
|
+
if (/[\r\n]/.test(value))
|
|
50
|
+
return `${shape}; this one spans more than one line.`;
|
|
51
|
+
const trimmed = value.trim();
|
|
52
|
+
if (trimmed === "")
|
|
53
|
+
return `${shape}; this one is empty.`;
|
|
54
|
+
if (trimmed.length > TITLE_MAX_LENGTH) {
|
|
55
|
+
return `${shape}; this one is ${trimmed.length}. Shorten it and retry.`;
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The value to store for a title that has passed {@link titleWriteError} — the
|
|
61
|
+
* trimmed string. Separate from the check so a caller cannot store the untrimmed
|
|
62
|
+
* original by forgetting to.
|
|
63
|
+
*/
|
|
64
|
+
export function normalizeTitle(value) {
|
|
65
|
+
return value.trim();
|
|
66
|
+
}
|
|
67
|
+
/** Thrown when a seeded (or written) variable name is not a valid identifier. */
|
|
68
|
+
export class InvalidVariableNameError extends Error {
|
|
69
|
+
variable;
|
|
70
|
+
source;
|
|
71
|
+
constructor(variable,
|
|
72
|
+
/** Where the name came from, for a message that points at the fix. */
|
|
73
|
+
source = "seeded") {
|
|
74
|
+
super(`'${variable}' is not a valid variable name (${source}). Use lowercase letters, digits ` +
|
|
75
|
+
`and underscores, starting with a letter (e.g. 'from_email').`);
|
|
76
|
+
this.variable = variable;
|
|
77
|
+
this.source = source;
|
|
78
|
+
this.name = "InvalidVariableNameError";
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Thrown when a seeded `title` is not a usable label — a throw rather than the
|
|
83
|
+
* agent's string refusal, because a bad seed is a host defect that should
|
|
84
|
+
* surface at assembly.
|
|
85
|
+
*/
|
|
86
|
+
export class InvalidTitleError extends Error {
|
|
87
|
+
detail;
|
|
88
|
+
source;
|
|
89
|
+
constructor(
|
|
90
|
+
/** The shape problem, in the same words the agent's refusal uses. */
|
|
91
|
+
detail,
|
|
92
|
+
/** Where the value came from, for a message that points at the fix. */
|
|
93
|
+
source = "seeded") {
|
|
94
|
+
super(`${detail} (${source})`);
|
|
95
|
+
this.detail = detail;
|
|
96
|
+
this.source = source;
|
|
97
|
+
this.name = "InvalidTitleError";
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Turn a caller's seeds into locked variable entries — the one way a run's
|
|
102
|
+
* opening facts are established, whether by a host's `variables` option, a
|
|
103
|
+
* delivery's seeds, or the arguments a delegation hands a sub-run. Locked because
|
|
104
|
+
* a `${{name}}` guard bound to a seed is worthless if the agent can rewrite it.
|
|
105
|
+
*/
|
|
106
|
+
export function buildSeededVariables(seeds,
|
|
107
|
+
/** Where the names came from, for a message that points at the fix. */
|
|
108
|
+
source = "seeded") {
|
|
109
|
+
const store = {};
|
|
110
|
+
for (const [name, value] of Object.entries(seeds ?? {})) {
|
|
111
|
+
if (!VARIABLE_NAME_PATTERN.test(name))
|
|
112
|
+
throw new InvalidVariableNameError(name, source);
|
|
113
|
+
// `title` is the one seed stored unlocked: a seeded title is an *opening*
|
|
114
|
+
// label the agent may refine (see TITLE_VARIABLE).
|
|
115
|
+
if (name === TITLE_VARIABLE) {
|
|
116
|
+
const problem = titleWriteError(value);
|
|
117
|
+
if (problem)
|
|
118
|
+
throw new InvalidTitleError(problem, source);
|
|
119
|
+
store[name] = { value: normalizeTitle(value), locked: false };
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
store[name] = { value, locked: true };
|
|
123
|
+
}
|
|
124
|
+
return store;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Matches a `${{…}}` reference, or the **escaped** form `$${{…}}` that writes the
|
|
128
|
+
* braces as text (`$$` rather than a backslash, which would not survive JSON
|
|
129
|
+
* encoding on the model's side). The inner text is captured loosely and
|
|
130
|
+
* validated separately so a malformed reference is reported, never ignored.
|
|
131
|
+
*/
|
|
132
|
+
const REFERENCE_RE = /(\$?)\$\{\{([^}]*)\}\}/g;
|
|
133
|
+
/**
|
|
134
|
+
* Every `${{…}}` and `$${{…}}` span in a string, in order. One scan so a
|
|
135
|
+
* reference and its escaped twin can never be found by different rules.
|
|
136
|
+
*/
|
|
137
|
+
function scan(glob) {
|
|
138
|
+
const spans = [];
|
|
139
|
+
REFERENCE_RE.lastIndex = 0;
|
|
140
|
+
let match;
|
|
141
|
+
while ((match = REFERENCE_RE.exec(glob)) !== null) {
|
|
142
|
+
const inner = (match[2] ?? "").trim();
|
|
143
|
+
const segments = inner.split(".");
|
|
144
|
+
spans.push({
|
|
145
|
+
raw: match[0],
|
|
146
|
+
name: segments[0] ?? "",
|
|
147
|
+
path: segments.slice(1),
|
|
148
|
+
index: match.index,
|
|
149
|
+
escaped: match[1] === "$",
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return spans;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Whether a glob contains reference **syntax** — a `${{…}}` reference or an
|
|
156
|
+
* escaped `$${{…}}` literal. Callers use this to skip resolution entirely for the
|
|
157
|
+
* common reference-free glob, so an escape has to answer `true` here: it resolves
|
|
158
|
+
* nothing, but it still needs the pass that turns `$${{x}}` into `${{x}}`.
|
|
159
|
+
*/
|
|
160
|
+
export function hasVariableReference(glob) {
|
|
161
|
+
return scan(glob).length > 0;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Every `${{…}}` reference in a glob, in order. A syntactically malformed
|
|
165
|
+
* reference still appears here (with an empty `name`), so callers can report it
|
|
166
|
+
* rather than skip it. An escaped `$${{…}}` is omitted — it is literal text, and
|
|
167
|
+
* reporting it as a reference would make `validate` warn about a variable the
|
|
168
|
+
* author deliberately spelled out.
|
|
169
|
+
*/
|
|
170
|
+
export function parseReferences(glob) {
|
|
171
|
+
return scan(glob)
|
|
172
|
+
.filter((span) => !span.escaped)
|
|
173
|
+
// Drop `escaped`: it is this module's discriminator, not part of a reference.
|
|
174
|
+
.map(({ raw, name, path, index }) => ({ raw, name, path, index }));
|
|
175
|
+
}
|
|
176
|
+
/** Whether a reference is structurally usable (name shape, no empty segments). */
|
|
177
|
+
export function referenceError(ref) {
|
|
178
|
+
if (ref.name === "")
|
|
179
|
+
return "malformed";
|
|
180
|
+
if (ref.path.some((segment) => segment === ""))
|
|
181
|
+
return "malformed";
|
|
182
|
+
if (!VARIABLE_NAME_PATTERN.test(ref.name))
|
|
183
|
+
return "invalid-name";
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* A path segment that addresses an array element from the end (`-1` last, `-2`
|
|
188
|
+
* second-to-last). Deliberately canonical-only: `-0` and `-01` do not match, so
|
|
189
|
+
* there is exactly one spelling of each index and any other `-`-prefixed segment
|
|
190
|
+
* stays an ordinary key.
|
|
191
|
+
*/
|
|
192
|
+
const FROM_END_RE = /^-[1-9][0-9]*$/;
|
|
193
|
+
/** A canonical non-negative index — no leading zeros, so one spelling per index. */
|
|
194
|
+
const INDEX_RE = /^(0|[1-9][0-9]*)$/;
|
|
195
|
+
/**
|
|
196
|
+
* Descend one level. An **array** is addressed by index only — canonical
|
|
197
|
+
* non-negative, or negative from the end; `Object.hasOwn` alone would let
|
|
198
|
+
* `${{tags.length}}` resolve, since `length` is an own property. Any other
|
|
199
|
+
* object is an own-property lookup, so `constructor`, `toString` and `__proto__`
|
|
200
|
+
* stay unreachable while a data key of the same name still resolves.
|
|
201
|
+
*/
|
|
202
|
+
function step(container, segment) {
|
|
203
|
+
if (container === null || typeof container !== "object")
|
|
204
|
+
return undefined;
|
|
205
|
+
if (Array.isArray(container)) {
|
|
206
|
+
if (FROM_END_RE.test(segment)) {
|
|
207
|
+
const fromEnd = container.length + Number(segment);
|
|
208
|
+
return fromEnd >= 0 ? container[fromEnd] : undefined;
|
|
209
|
+
}
|
|
210
|
+
return INDEX_RE.test(segment) ? container[Number(segment)] : undefined;
|
|
211
|
+
}
|
|
212
|
+
return Object.hasOwn(container, segment)
|
|
213
|
+
? container[segment]
|
|
214
|
+
: undefined;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Resolve a dotted path against a value, reading own properties only. Returns
|
|
218
|
+
* `undefined` when any segment misses — indistinguishable from a stored
|
|
219
|
+
* `undefined`, which is fine: both are unresolvable for a guard.
|
|
220
|
+
*/
|
|
221
|
+
export function resolvePath(value, path) {
|
|
222
|
+
let current = value;
|
|
223
|
+
for (const segment of path) {
|
|
224
|
+
current = step(current, segment);
|
|
225
|
+
if (current === undefined)
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
228
|
+
return current;
|
|
229
|
+
}
|
|
230
|
+
/** Values a guard may substitute: exactly the scalars a glob can match against. */
|
|
231
|
+
function isScalar(value) {
|
|
232
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Escape every picomatch metacharacter so a substituted value is matched as
|
|
236
|
+
* literal text; without it a variable holding `*` or `{a,b}` widens the guard.
|
|
237
|
+
*/
|
|
238
|
+
export function escapeGlobLiteral(value) {
|
|
239
|
+
return value.replace(/[\\*?[\]{}()!+@|^$]/g, (char) => `\\${char}`);
|
|
240
|
+
}
|
|
241
|
+
/** Explain an unresolved reference in the words a block reason should use. */
|
|
242
|
+
function explain(reason, ref) {
|
|
243
|
+
const target = ref.path.length > 0 ? `'${ref.name}' at path '${ref.path.join(".")}'` : `'${ref.name}'`;
|
|
244
|
+
switch (reason) {
|
|
245
|
+
case "malformed":
|
|
246
|
+
return `${ref.raw} is not a valid reference — use \${{name}} or \${{name.path.to.value}}`;
|
|
247
|
+
case "invalid-name":
|
|
248
|
+
return `${ref.raw} names '${ref.name}', which is not a valid variable name (lowercase letters, digits and underscores, starting with a letter)`;
|
|
249
|
+
case "unset":
|
|
250
|
+
return `variable '${ref.name}' is not set`;
|
|
251
|
+
case "path-missing":
|
|
252
|
+
return `${target} does not resolve — the value has no such path`;
|
|
253
|
+
case "non-scalar":
|
|
254
|
+
return `${target} resolves to a non-scalar value; only strings, numbers and booleans can be substituted into a guard`;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Substitute every reference in a glob against the run's variables. Returns the
|
|
259
|
+
* resolved pattern, or the first unresolved reference and why — a glob with an
|
|
260
|
+
* unresolved reference matches nothing at all, so the caller must not fall back
|
|
261
|
+
* to the original text.
|
|
262
|
+
*/
|
|
263
|
+
export function resolveGlob(glob, variables) {
|
|
264
|
+
return substitute(glob, variables, escapeGlobLiteral);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Shared substitution. `render` decides how a resolved value enters the output:
|
|
268
|
+
* glob-escaped for enforcement (where the result is a *pattern*), verbatim for
|
|
269
|
+
* disclosure (where the result is *prose the model reads*) — showing an author's
|
|
270
|
+
* email as `a\@b.c` would teach the model to pass the backslash.
|
|
271
|
+
*/
|
|
272
|
+
function substitute(glob, variables, render) {
|
|
273
|
+
const refs = scan(glob);
|
|
274
|
+
if (refs.length === 0)
|
|
275
|
+
return { ok: true, pattern: glob };
|
|
276
|
+
let out = "";
|
|
277
|
+
let cursor = 0;
|
|
278
|
+
for (const ref of refs) {
|
|
279
|
+
// `$${{…}}`: the braces are meant as text. Emit the span with one `$`
|
|
280
|
+
// dropped and resolve nothing.
|
|
281
|
+
if (ref.escaped) {
|
|
282
|
+
out += glob.slice(cursor, ref.index) + ref.raw.slice(1);
|
|
283
|
+
cursor = ref.index + ref.raw.length;
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
const structural = referenceError(ref);
|
|
287
|
+
if (structural) {
|
|
288
|
+
return { ok: false, reason: structural, reference: ref.raw, detail: explain(structural, ref) };
|
|
289
|
+
}
|
|
290
|
+
const entry = variables[ref.name];
|
|
291
|
+
if (entry === undefined) {
|
|
292
|
+
return { ok: false, reason: "unset", reference: ref.raw, detail: explain("unset", ref) };
|
|
293
|
+
}
|
|
294
|
+
const resolved = resolvePath(entry.value, ref.path);
|
|
295
|
+
if (resolved === undefined) {
|
|
296
|
+
const reason = ref.path.length === 0 ? "unset" : "path-missing";
|
|
297
|
+
return { ok: false, reason, reference: ref.raw, detail: explain(reason, ref) };
|
|
298
|
+
}
|
|
299
|
+
if (!isScalar(resolved)) {
|
|
300
|
+
return {
|
|
301
|
+
ok: false,
|
|
302
|
+
reason: "non-scalar",
|
|
303
|
+
reference: ref.raw,
|
|
304
|
+
detail: explain("non-scalar", ref),
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
out += glob.slice(cursor, ref.index) + render(String(resolved));
|
|
308
|
+
cursor = ref.index + ref.raw.length;
|
|
309
|
+
}
|
|
310
|
+
return { ok: true, pattern: out + glob.slice(cursor) };
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Substitute every reference in a piece of **prose** (a sub-workflow prompt)
|
|
314
|
+
* verbatim: a prompt is text a model reads, where glob-escaping would teach it
|
|
315
|
+
* to emit backslashes. Failure is still closed — a literal `${{…}}` reaching a
|
|
316
|
+
* model is an instruction it cannot follow.
|
|
317
|
+
*/
|
|
318
|
+
export function resolveText(text, variables) {
|
|
319
|
+
return substitute(text, variables, (value) => value);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Whether a value is a plain JSON object this walk may rebuild. Anything with its
|
|
323
|
+
* own prototype (`Date`, `Map`, a class instance) is left alone rather than
|
|
324
|
+
* flattened into `{}`.
|
|
325
|
+
*/
|
|
326
|
+
function isDataObject(value) {
|
|
327
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
328
|
+
return false;
|
|
329
|
+
const prototype = Object.getPrototypeOf(value);
|
|
330
|
+
return prototype === Object.prototype || prototype === null;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Substitute every reference in the **arguments the agent wrote**, verbatim.
|
|
334
|
+
* Walks deep (non-string leaves pass through), fails first-wins and totally (the
|
|
335
|
+
* tool never receives a half-resolved structure), and only reports. Objects are
|
|
336
|
+
* rebuilt with `Object.fromEntries`, which *defines* each key, so a model-emitted
|
|
337
|
+
* `__proto__` becomes a property rather than a prototype.
|
|
338
|
+
*/
|
|
339
|
+
export function resolveArguments(args, variables) {
|
|
340
|
+
let failure;
|
|
341
|
+
const walk = (value) => {
|
|
342
|
+
if (failure)
|
|
343
|
+
return value;
|
|
344
|
+
if (typeof value === "string") {
|
|
345
|
+
// The same verbatim rendering a prompt gets — an argument is a value too.
|
|
346
|
+
const result = resolveText(value, variables);
|
|
347
|
+
if (result.ok)
|
|
348
|
+
return result.pattern;
|
|
349
|
+
failure = result;
|
|
350
|
+
return value;
|
|
351
|
+
}
|
|
352
|
+
if (Array.isArray(value))
|
|
353
|
+
return value.map(walk);
|
|
354
|
+
if (isDataObject(value)) {
|
|
355
|
+
const entries = [];
|
|
356
|
+
for (const [key, member] of Object.entries(value)) {
|
|
357
|
+
entries.push([key, walk(member)]);
|
|
358
|
+
if (failure)
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
return Object.fromEntries(entries);
|
|
362
|
+
}
|
|
363
|
+
return value;
|
|
364
|
+
};
|
|
365
|
+
const resolved = walk(args);
|
|
366
|
+
return failure ?? { ok: true, args: resolved };
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Render a guard glob for the model: the resolved pattern when it resolves, or a
|
|
370
|
+
* short unresolved marker naming the reference. The model is told a constraint
|
|
371
|
+
* exists and what it is waiting on, rather than being shown a placeholder it
|
|
372
|
+
* might try to pass literally into a call that would end the run.
|
|
373
|
+
*/
|
|
374
|
+
export function describeGlob(glob, variables) {
|
|
375
|
+
const result = substitute(glob, variables, (value) => value);
|
|
376
|
+
return result.ok ? result.pattern : `${glob} (unresolved: ${result.detail})`;
|
|
377
|
+
}
|
|
378
|
+
// --- What the assembly can guarantee a guard reference resolves ----------------
|
|
379
|
+
/**
|
|
380
|
+
* Warn about every `${{…}}` guard reference the assembly cannot *guarantee* is
|
|
381
|
+
* set — named by neither the host's seeds, any state's `requires`, nor the
|
|
382
|
+
* built-in `trigger`. A warning, not a throw: `archmax_set_variables` can create
|
|
383
|
+
* any name at runtime, so an upstream state may legitimately establish it; the
|
|
384
|
+
* enforcement is the runtime failure when the guard cannot resolve.
|
|
385
|
+
*/
|
|
386
|
+
export function unguaranteedReferenceWarnings(machine, seededVariables) {
|
|
387
|
+
const guaranteed = new Set([
|
|
388
|
+
TRIGGER_VARIABLE,
|
|
389
|
+
...Object.keys(seededVariables),
|
|
390
|
+
...declaredVariableNames(machine.spec),
|
|
391
|
+
]);
|
|
392
|
+
const messages = [];
|
|
393
|
+
const seen = new Set();
|
|
394
|
+
for (const ref of guardReferences(machine.spec)) {
|
|
395
|
+
const name = ref.reference.name;
|
|
396
|
+
if (name === "" || guaranteed.has(name))
|
|
397
|
+
continue;
|
|
398
|
+
const where = ref.state ? `state '${ref.state}'` : "tools.allow_always";
|
|
399
|
+
const key = `${where}|${ref.tool}|${ref.arg}|${name}`;
|
|
400
|
+
if (seen.has(key))
|
|
401
|
+
continue;
|
|
402
|
+
seen.add(key);
|
|
403
|
+
messages.push(`${where} guards '${ref.tool ?? "?"}' on '${ref.reference.raw}' (argument ` +
|
|
404
|
+
`'${ref.arg}'), but nothing guarantees '${name}' is set: it is not seeded ` +
|
|
405
|
+
`as a seeded variable and no state requires it. The guard then depends on ` +
|
|
406
|
+
`the agent having called ${SET_VARIABLES_TOOL} first — if it has not, the session fails ` +
|
|
407
|
+
`at that call. Name '${name}' in the 'requires' of a state that runs first, ` +
|
|
408
|
+
`or seed it.` +
|
|
409
|
+
(ref.state
|
|
410
|
+
? ""
|
|
411
|
+
: " An allow_always entry is evaluated in every state, including states reached before anything sets it."));
|
|
412
|
+
}
|
|
413
|
+
return messages;
|
|
414
|
+
}
|
|
415
|
+
//# sourceMappingURL=variables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variables.js","sourceRoot":"","sources":["../../src/machine/variables.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@archmax-ai/harness/cli` — the state-flow renderer and its styling.
|
|
3
|
+
*
|
|
4
|
+
* A subpath of its own so a third-party frontend of the typed event stream can
|
|
5
|
+
* render sessions the way `archmax run` does — and suites the way `archmax test`
|
|
6
|
+
* does — without importing the CLI itself.
|
|
7
|
+
*/
|
|
8
|
+
/** Render one lifecycle event as the CLI's own console line, or `null` for none. */
|
|
9
|
+
export { renderEventLine } from "../core/events.js";
|
|
10
|
+
/** The CLI's colour and glyph vocabulary, honouring `NO_COLOR`. */
|
|
11
|
+
export { createStyle, icons } from "../cli/style.js";
|
|
12
|
+
export type { Style } from "../cli/style.js";
|
|
13
|
+
/** The live state flow `archmax run` builds from the event stream, and the test view `archmax test` builds on it. */
|
|
14
|
+
export { createStateFlowRenderer, createTestView, caseVerdictLine } from "../cli/state-flow.js";
|
|
15
|
+
export type { StateFlowRenderer, StateFlowWriter, TestView } from "../cli/state-flow.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@archmax-ai/harness/cli` — the state-flow renderer and its styling.
|
|
3
|
+
*
|
|
4
|
+
* A subpath of its own so a third-party frontend of the typed event stream can
|
|
5
|
+
* render sessions the way `archmax run` does — and suites the way `archmax test`
|
|
6
|
+
* does — without importing the CLI itself.
|
|
7
|
+
*/
|
|
8
|
+
/** Render one lifecycle event as the CLI's own console line, or `null` for none. */
|
|
9
|
+
export { renderEventLine } from "../core/events.js";
|
|
10
|
+
/** The CLI's colour and glyph vocabulary, honouring `NO_COLOR`. */
|
|
11
|
+
export { createStyle, icons } from "../cli/style.js";
|
|
12
|
+
/** The live state flow `archmax run` builds from the event stream, and the test view `archmax test` builds on it. */
|
|
13
|
+
export { createStateFlowRenderer, createTestView, caseVerdictLine } from "../cli/state-flow.js";
|
|
14
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/public/cli.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,oFAAoF;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,mEAAmE;AACnE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAGrD,qHAAqH;AACrH,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@archmax-ai/harness/messages` — reading a transcript without the runtime.
|
|
3
|
+
*
|
|
4
|
+
* Every reader is duck-typed over the shapes a message takes — a LangChain class
|
|
5
|
+
* instance, a checkpoint's serialized form, a raw `{ role, content }` — and this
|
|
6
|
+
* module imports nothing, so an API request path that renders or slices a
|
|
7
|
+
* transcript loads no LangGraph. A unit test walks the import graph to keep it
|
|
8
|
+
* that way. The root exports the readers a governed host needs most
|
|
9
|
+
* (`contentToString`, `isAiMessage`, `isRuntimeNote`, `runtimeNoteKind`); they
|
|
10
|
+
* are the same bindings here.
|
|
11
|
+
*/
|
|
12
|
+
export {
|
|
13
|
+
/** A message's text, whatever content-block shape it arrived in. */
|
|
14
|
+
contentToString,
|
|
15
|
+
/** The LangChain message kind (`ai`, `human`, `tool`, `system`, …). */
|
|
16
|
+
messageTypeOf,
|
|
17
|
+
/** Whether a message is the assistant's. */
|
|
18
|
+
isAiMessage,
|
|
19
|
+
/** Whether a message is a person's (or a human-role runtime note — see `isRuntimeNote`). */
|
|
20
|
+
isHumanMessage,
|
|
21
|
+
/** Whether the runtime wrote this message rather than a person. */
|
|
22
|
+
isRuntimeNote,
|
|
23
|
+
/** Which kind of runtime note a message is, or `null` if a person wrote it. */
|
|
24
|
+
runtimeNoteKind,
|
|
25
|
+
/** The last thing the agent said to the person; tool results and runtime notes are skipped. */
|
|
26
|
+
lastAgentText,
|
|
27
|
+
/** Whether a message opens a turn: something the session was told. */
|
|
28
|
+
opensTurn,
|
|
29
|
+
/** The messages appended since a count read earlier — what one `invoke` added. */
|
|
30
|
+
messagesSince,
|
|
31
|
+
/** The trailing turn: from the last thing the session was told to the end. */
|
|
32
|
+
lastTurn, } from "../core/message-readers.js";
|
|
33
|
+
export type { RuntimeNoteKind } from "../core/message-readers.js";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@archmax-ai/harness/messages` — reading a transcript without the runtime.
|
|
3
|
+
*
|
|
4
|
+
* Every reader is duck-typed over the shapes a message takes — a LangChain class
|
|
5
|
+
* instance, a checkpoint's serialized form, a raw `{ role, content }` — and this
|
|
6
|
+
* module imports nothing, so an API request path that renders or slices a
|
|
7
|
+
* transcript loads no LangGraph. A unit test walks the import graph to keep it
|
|
8
|
+
* that way. The root exports the readers a governed host needs most
|
|
9
|
+
* (`contentToString`, `isAiMessage`, `isRuntimeNote`, `runtimeNoteKind`); they
|
|
10
|
+
* are the same bindings here.
|
|
11
|
+
*/
|
|
12
|
+
export {
|
|
13
|
+
/** A message's text, whatever content-block shape it arrived in. */
|
|
14
|
+
contentToString,
|
|
15
|
+
/** The LangChain message kind (`ai`, `human`, `tool`, `system`, …). */
|
|
16
|
+
messageTypeOf,
|
|
17
|
+
/** Whether a message is the assistant's. */
|
|
18
|
+
isAiMessage,
|
|
19
|
+
/** Whether a message is a person's (or a human-role runtime note — see `isRuntimeNote`). */
|
|
20
|
+
isHumanMessage,
|
|
21
|
+
/** Whether the runtime wrote this message rather than a person. */
|
|
22
|
+
isRuntimeNote,
|
|
23
|
+
/** Which kind of runtime note a message is, or `null` if a person wrote it. */
|
|
24
|
+
runtimeNoteKind,
|
|
25
|
+
/** The last thing the agent said to the person; tool results and runtime notes are skipped. */
|
|
26
|
+
lastAgentText,
|
|
27
|
+
/** Whether a message opens a turn: something the session was told. */
|
|
28
|
+
opensTurn,
|
|
29
|
+
/** The messages appended since a count read earlier — what one `invoke` added. */
|
|
30
|
+
messagesSince,
|
|
31
|
+
/** The trailing turn: from the last thing the session was told to the end. */
|
|
32
|
+
lastTurn, } from "../core/message-readers.js";
|
|
33
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/public/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO;AACL,oEAAoE;AACpE,eAAe;AACf,uEAAuE;AACvE,aAAa;AACb,4CAA4C;AAC5C,WAAW;AACX,4FAA4F;AAC5F,cAAc;AACd,mEAAmE;AACnE,aAAa;AACb,+EAA+E;AAC/E,eAAe;AACf,+FAA+F;AAC/F,aAAa;AACb,sEAAsE;AACtE,SAAS;AACT,kFAAkF;AAClF,aAAa;AACb,8EAA8E;AAC9E,QAAQ,GACT,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@archmax-ai/harness/sandbox` — the typed authoring surface for lifecycle hook
|
|
3
|
+
* scripts. Inside the QuickJS sandbox these names are provided by the prelude
|
|
4
|
+
* and the import line is stripped before evaluation; importing from here buys
|
|
5
|
+
* IDE completion for the hook input, nothing at runtime.
|
|
6
|
+
*
|
|
7
|
+
* ```js
|
|
8
|
+
* import { veto, ok } from "@archmax-ai/harness/sandbox";
|
|
9
|
+
* /** Vetoes a refund the policy forbids. *\/
|
|
10
|
+
* export default async function hook({ state, phase, variables, messages, tools }) {
|
|
11
|
+
* const refund = JSON.parse(await tools.readFile({ file_path: "scratchpad/refund.json" }));
|
|
12
|
+
* if (refund.decision !== "denied") return veto(`order ${refund.orderId} is not eligible`);
|
|
13
|
+
* return ok();
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* Returning nothing is `ok`; throwing is a veto (hooks are fail-closed).
|
|
18
|
+
*/
|
|
19
|
+
/** What a hook answers with. */
|
|
20
|
+
export interface HookVerdict {
|
|
21
|
+
verdict: "ok" | "correct" | "veto";
|
|
22
|
+
reason: string;
|
|
23
|
+
}
|
|
24
|
+
/** One transcript message, as plain data. `role` is `user`, `assistant`, `tool`, `system`, or `runtime`. */
|
|
25
|
+
export interface HookMessage {
|
|
26
|
+
role: string;
|
|
27
|
+
text: string;
|
|
28
|
+
toolCalls?: {
|
|
29
|
+
name: string;
|
|
30
|
+
args: unknown;
|
|
31
|
+
}[];
|
|
32
|
+
/** Tool results: the tool that produced the text. */
|
|
33
|
+
tool?: string;
|
|
34
|
+
/** Runtime notes: which kind of note (an arrival, a decision, an error route). */
|
|
35
|
+
note?: string;
|
|
36
|
+
}
|
|
37
|
+
/** The machine context a lifecycle hook receives (also the global `args`). */
|
|
38
|
+
export interface HookArgs {
|
|
39
|
+
state: string;
|
|
40
|
+
phase: "before" | "after";
|
|
41
|
+
/** Which trigger started the run — its id. A run's input is in `variables`. */
|
|
42
|
+
trigger?: string;
|
|
43
|
+
/** The session's variables as a plain `name → value` map. Read-only: assigning changes nothing. */
|
|
44
|
+
variables: Record<string, unknown>;
|
|
45
|
+
/** The recent transcript, newest last. */
|
|
46
|
+
messages: HookMessage[];
|
|
47
|
+
/** `after` hooks on an advance: the transition being attempted and the agent's reason. */
|
|
48
|
+
from?: string;
|
|
49
|
+
to?: string;
|
|
50
|
+
reason?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The privileged tool-call bridge (`tools.*`): the agent's tools as async
|
|
54
|
+
* functions keyed by camelCase name (`tools.readFile({ file_path })`). A hook
|
|
55
|
+
* runs on runtime authority, so the state's allow list does not bind it; the
|
|
56
|
+
* safety rules, the workflow `policy`, and consumer rules do. A refused call
|
|
57
|
+
* rejects with the governance reason.
|
|
58
|
+
*/
|
|
59
|
+
export type SandboxTools = Record<string, (input?: unknown) => Promise<unknown>>;
|
|
60
|
+
/**
|
|
61
|
+
* One committed traversal step of a session's audit trail: the state entered,
|
|
62
|
+
* the kind of edge that committed it, the recorded rationale when one was given
|
|
63
|
+
* (on `trigger` steps, the trigger id), and — on `sub-workflow` steps — the
|
|
64
|
+
* child workflow and whether it completed. Each turn begins with a `trigger`
|
|
65
|
+
* step; the order read back is the order committed.
|
|
66
|
+
*/
|
|
67
|
+
export interface TrailStep {
|
|
68
|
+
to: string;
|
|
69
|
+
kind: "trigger" | "agent" | "human" | "sub-workflow" | "reset" | "on_error";
|
|
70
|
+
reason?: string;
|
|
71
|
+
workflow?: string;
|
|
72
|
+
status?: "ok" | "error";
|
|
73
|
+
/** Epoch milliseconds at commit. */
|
|
74
|
+
ts: number;
|
|
75
|
+
}
|
|
76
|
+
/** The single object a hook function is called with. */
|
|
77
|
+
export interface HookInput extends HookArgs {
|
|
78
|
+
tools: SandboxTools;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* A hook's return: a verdict, `false` (veto), or nothing (`ok`).
|
|
82
|
+
*
|
|
83
|
+
* Nothing else is read as an opinion. A hook's return value *is* its verdict,
|
|
84
|
+
* so any other object — a misspelled `verdict`, a retired shape like
|
|
85
|
+
* `{ ok: false, reason }` — is a verdict the author got wrong and fails closed
|
|
86
|
+
* with its keys named, rather than being read as `ok` and silently permitting
|
|
87
|
+
* what the hook meant to block. Non-object values (`true`, a number, a bare
|
|
88
|
+
* body's incidental completion value) stay `ok`.
|
|
89
|
+
*
|
|
90
|
+
* These rules are the whole verdict vocabulary, and every hook kind is read
|
|
91
|
+
* through them — a custom kind registered via `hookExecutors` included.
|
|
92
|
+
*/
|
|
93
|
+
export type HookResult = HookVerdict | false | void | undefined;
|
|
94
|
+
export type HookFn = (input: HookInput) => HookResult | Promise<HookResult>;
|
|
95
|
+
export declare function ok(reason?: string): HookVerdict;
|
|
96
|
+
export declare function veto(reason: string): HookVerdict;
|
|
97
|
+
export declare function correct(reason: string): HookVerdict;
|
|
98
|
+
/** Alias for `export default`: `export default defineHook(async (input) => …)`. Identity at runtime. */
|
|
99
|
+
export declare function defineHook(fn: HookFn): HookFn;
|