@graphorin/agent 0.5.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 (72) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +159 -0
  4. package/dist/errors/index.d.ts +170 -0
  5. package/dist/errors/index.d.ts.map +1 -0
  6. package/dist/errors/index.js +204 -0
  7. package/dist/errors/index.js.map +1 -0
  8. package/dist/evaluator-optimizer/index.d.ts +91 -0
  9. package/dist/evaluator-optimizer/index.d.ts.map +1 -0
  10. package/dist/evaluator-optimizer/index.js +85 -0
  11. package/dist/evaluator-optimizer/index.js.map +1 -0
  12. package/dist/factory.d.ts +13 -0
  13. package/dist/factory.d.ts.map +1 -0
  14. package/dist/factory.js +1853 -0
  15. package/dist/factory.js.map +1 -0
  16. package/dist/fallback/index.d.ts +52 -0
  17. package/dist/fallback/index.d.ts.map +1 -0
  18. package/dist/fallback/index.js +53 -0
  19. package/dist/fallback/index.js.map +1 -0
  20. package/dist/fanout/index.d.ts +142 -0
  21. package/dist/fanout/index.d.ts.map +1 -0
  22. package/dist/fanout/index.js +252 -0
  23. package/dist/fanout/index.js.map +1 -0
  24. package/dist/filters/index.d.ts +137 -0
  25. package/dist/filters/index.d.ts.map +1 -0
  26. package/dist/filters/index.js +273 -0
  27. package/dist/filters/index.js.map +1 -0
  28. package/dist/index.d.ts +51 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +49 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/internal/ids.js +46 -0
  33. package/dist/internal/ids.js.map +1 -0
  34. package/dist/internal/usage-accumulator.js +62 -0
  35. package/dist/internal/usage-accumulator.js.map +1 -0
  36. package/dist/lateral-leak/causality-monitor.d.ts +97 -0
  37. package/dist/lateral-leak/causality-monitor.d.ts.map +1 -0
  38. package/dist/lateral-leak/causality-monitor.js +139 -0
  39. package/dist/lateral-leak/causality-monitor.js.map +1 -0
  40. package/dist/lateral-leak/index.d.ts +4 -0
  41. package/dist/lateral-leak/index.js +5 -0
  42. package/dist/lateral-leak/merge-guard.d.ts +89 -0
  43. package/dist/lateral-leak/merge-guard.d.ts.map +1 -0
  44. package/dist/lateral-leak/merge-guard.js +65 -0
  45. package/dist/lateral-leak/merge-guard.js.map +1 -0
  46. package/dist/lateral-leak/protocol-guard.d.ts +76 -0
  47. package/dist/lateral-leak/protocol-guard.d.ts.map +1 -0
  48. package/dist/lateral-leak/protocol-guard.js +147 -0
  49. package/dist/lateral-leak/protocol-guard.js.map +1 -0
  50. package/dist/preferred-model/index.d.ts +53 -0
  51. package/dist/preferred-model/index.d.ts.map +1 -0
  52. package/dist/preferred-model/index.js +141 -0
  53. package/dist/preferred-model/index.js.map +1 -0
  54. package/dist/progress/index.d.ts +62 -0
  55. package/dist/progress/index.d.ts.map +1 -0
  56. package/dist/progress/index.js +150 -0
  57. package/dist/progress/index.js.map +1 -0
  58. package/dist/run-state/index.d.ts +152 -0
  59. package/dist/run-state/index.d.ts.map +1 -0
  60. package/dist/run-state/index.js +311 -0
  61. package/dist/run-state/index.js.map +1 -0
  62. package/dist/tooling/adapters.js +154 -0
  63. package/dist/tooling/adapters.js.map +1 -0
  64. package/dist/tooling/catalogue.js +37 -0
  65. package/dist/tooling/catalogue.js.map +1 -0
  66. package/dist/tooling/dataflow.js +99 -0
  67. package/dist/tooling/dataflow.js.map +1 -0
  68. package/dist/tooling/registry-build.js +85 -0
  69. package/dist/tooling/registry-build.js.map +1 -0
  70. package/dist/types.d.ts +413 -0
  71. package/dist/types.d.ts.map +1 -0
  72. package/package.json +115 -0
@@ -0,0 +1,141 @@
1
+ //#region src/preferred-model/index.ts
2
+ const TIER_ORDER = {
3
+ fast: 0,
4
+ balanced: 1,
5
+ smart: 2
6
+ };
7
+ function isModelHint(value) {
8
+ return value === "fast" || value === "balanced" || value === "smart";
9
+ }
10
+ function specToProvider(spec) {
11
+ if ("provider" in spec) return spec.provider;
12
+ return spec;
13
+ }
14
+ function modelIdFromSpec(spec) {
15
+ if ("provider" in spec) return spec.model;
16
+ return spec.modelId;
17
+ }
18
+ /**
19
+ * Pick the highest-cost tier across the supplied per-tool hints.
20
+ * Explicit `ModelSpec` entries are treated as the highest tier
21
+ * (`'smart'`) for tie-breaking — the conservative-correctness rule
22
+ * documented in DEC-169 / suggested ADR-057.
23
+ *
24
+ * Returns the picked hint together with the original `ModelSpec`
25
+ * (when an explicit spec won the tie-break).
26
+ *
27
+ * @stable
28
+ */
29
+ function pickTopTierAcrossTools(hints) {
30
+ let bestRank = -1;
31
+ let bestSpec;
32
+ let bestHint;
33
+ for (const h of hints) {
34
+ if (h === void 0) continue;
35
+ if (isModelHint(h)) {
36
+ const rank = TIER_ORDER[h];
37
+ if (rank > bestRank) {
38
+ bestRank = rank;
39
+ bestSpec = void 0;
40
+ bestHint = h;
41
+ }
42
+ } else {
43
+ const rank = TIER_ORDER.smart;
44
+ if (rank >= bestRank) {
45
+ bestRank = rank;
46
+ bestSpec = h;
47
+ bestHint = "smart";
48
+ }
49
+ }
50
+ }
51
+ if (bestHint === void 0) return void 0;
52
+ if (bestSpec !== void 0) return {
53
+ hint: bestHint,
54
+ spec: bestSpec
55
+ };
56
+ return { hint: bestHint };
57
+ }
58
+ /**
59
+ * Walk the precedence ladder and return the resolved provider for a
60
+ * single agent step. Pure function — no side effects.
61
+ *
62
+ * @stable
63
+ */
64
+ function resolvePreferredModel(input) {
65
+ if (input.prepareStepProvider !== void 0) return {
66
+ resolvedProvider: input.prepareStepProvider,
67
+ resolvedModelId: input.prepareStepProvider.modelId,
68
+ source: "prepare-step"
69
+ };
70
+ const top = pickTopTierAcrossTools(input.toolPreferredModels);
71
+ if (top !== void 0) {
72
+ if (top.spec !== void 0) return {
73
+ resolvedProvider: specToProvider(top.spec),
74
+ resolvedModelId: modelIdFromSpec(top.spec),
75
+ source: "spec"
76
+ };
77
+ const mapped = input.modelTierMap?.[top.hint];
78
+ if (mapped !== void 0) return {
79
+ resolvedProvider: specToProvider(mapped),
80
+ resolvedModelId: modelIdFromSpec(mapped),
81
+ source: "tier-map",
82
+ hintApplied: top.hint
83
+ };
84
+ const agent$1 = input.agentPreferredModel;
85
+ if (agent$1 !== void 0) if (isModelHint(agent$1)) {
86
+ const agentMapped = input.modelTierMap?.[agent$1];
87
+ if (agentMapped !== void 0) return {
88
+ resolvedProvider: specToProvider(agentMapped),
89
+ resolvedModelId: modelIdFromSpec(agentMapped),
90
+ source: "agent-preferred",
91
+ hintApplied: agent$1,
92
+ fallthroughReason: "tier-not-mapped"
93
+ };
94
+ } else return {
95
+ resolvedProvider: specToProvider(agent$1),
96
+ resolvedModelId: modelIdFromSpec(agent$1),
97
+ source: "agent-preferred",
98
+ fallthroughReason: "tier-not-mapped"
99
+ };
100
+ return {
101
+ resolvedProvider: input.agentDefaultProvider,
102
+ resolvedModelId: input.agentDefaultProvider.modelId,
103
+ source: "fallthrough-default",
104
+ hintApplied: top.hint,
105
+ fallthroughReason: "tier-not-mapped"
106
+ };
107
+ }
108
+ const agent = input.agentPreferredModel;
109
+ if (agent !== void 0) {
110
+ if (isModelHint(agent)) {
111
+ const mapped = input.modelTierMap?.[agent];
112
+ if (mapped !== void 0) return {
113
+ resolvedProvider: specToProvider(mapped),
114
+ resolvedModelId: modelIdFromSpec(mapped),
115
+ source: "agent-preferred",
116
+ hintApplied: agent
117
+ };
118
+ return {
119
+ resolvedProvider: input.agentDefaultProvider,
120
+ resolvedModelId: input.agentDefaultProvider.modelId,
121
+ source: "fallthrough-default",
122
+ hintApplied: agent,
123
+ fallthroughReason: "tier-not-mapped"
124
+ };
125
+ }
126
+ return {
127
+ resolvedProvider: specToProvider(agent),
128
+ resolvedModelId: modelIdFromSpec(agent),
129
+ source: "agent-preferred"
130
+ };
131
+ }
132
+ return {
133
+ resolvedProvider: input.agentDefaultProvider,
134
+ resolvedModelId: input.agentDefaultProvider.modelId,
135
+ source: "fallthrough-default"
136
+ };
137
+ }
138
+
139
+ //#endregion
140
+ export { pickTopTierAcrossTools, resolvePreferredModel };
141
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["TIER_ORDER: Record<ModelHint, number>","bestSpec: ModelSpec | undefined","bestHint: ModelHint | undefined","agent"],"sources":["../../src/preferred-model/index.ts"],"sourcesContent":["/**\n * Per-tool / per-agent preferred-model resolution. Pure functions\n * consulted by the agent loop AFTER the model has decided which\n * tool(s) to call but BEFORE `provider.stream(...)` is invoked.\n *\n * The four-step precedence ladder (highest wins):\n *\n * 1. `prepareStep({ provider })` — the operator's explicit per-step\n * override always wins.\n * 2. `Tool.preferredModel` — the tool author's per-tool hint.\n * Only the tools the model actually CALLED on the previous step\n * are consulted (AG-15) — an advertised-but-uncalled hint never\n * escalates the run. Multi-tool ties resolve to the highest cost\n * tier (`'smart' > 'balanced' > 'fast'`; explicit `ModelSpec` is\n * treated as the highest tier).\n * 3. `Agent.preferredModel?` — the per-agent default.\n * 4. `Agent` default `provider` — the v0.1-alpha behaviour.\n *\n * Cost-tier resolution against `Agent.modelTierMap` is documented\n * as a hint: when the requested tier is unmapped, the resolver\n * falls through to the next precedence step rather than throwing.\n *\n * @packageDocumentation\n */\n\nimport type { ModelHint, ModelSpec, Provider } from '@graphorin/core';\n\nconst TIER_ORDER: Record<ModelHint, number> = { fast: 0, balanced: 1, smart: 2 };\n\n/**\n * Result returned by {@link resolvePreferredModel}.\n *\n * @stable\n */\nexport interface PreferredModelResolution {\n readonly resolvedProvider: Provider;\n readonly resolvedModelId: string;\n readonly source: 'prepare-step' | 'tier-map' | 'spec' | 'agent-preferred' | 'fallthrough-default';\n readonly hintApplied?: ModelHint;\n readonly fallthroughReason?:\n | 'tier-not-mapped'\n | 'provider-unavailable'\n | 'override-takes-precedence';\n}\n\n/**\n * Pure inputs to {@link resolvePreferredModel}.\n *\n * @stable\n */\nexport interface ResolvePreferredModelInput {\n readonly prepareStepProvider?: Provider;\n readonly toolPreferredModels: ReadonlyArray<ModelHint | ModelSpec | undefined>;\n readonly agentPreferredModel?: ModelHint | ModelSpec;\n readonly agentDefaultProvider: Provider;\n readonly modelTierMap?: Partial<Record<ModelHint, ModelSpec>>;\n}\n\nfunction isModelHint(value: ModelHint | ModelSpec | undefined): value is ModelHint {\n return value === 'fast' || value === 'balanced' || value === 'smart';\n}\n\nfunction specToProvider(spec: ModelSpec): Provider {\n if ('provider' in spec) return spec.provider as Provider;\n return spec as Provider;\n}\n\nfunction modelIdFromSpec(spec: ModelSpec): string {\n if ('provider' in spec) return spec.model;\n return (spec as Provider).modelId;\n}\n\n/**\n * Pick the highest-cost tier across the supplied per-tool hints.\n * Explicit `ModelSpec` entries are treated as the highest tier\n * (`'smart'`) for tie-breaking — the conservative-correctness rule\n * documented in DEC-169 / suggested ADR-057.\n *\n * Returns the picked hint together with the original `ModelSpec`\n * (when an explicit spec won the tie-break).\n *\n * @stable\n */\nexport function pickTopTierAcrossTools(\n hints: ReadonlyArray<ModelHint | ModelSpec | undefined>,\n): { readonly hint: ModelHint; readonly spec?: ModelSpec } | undefined {\n let bestRank = -1;\n let bestSpec: ModelSpec | undefined;\n let bestHint: ModelHint | undefined;\n for (const h of hints) {\n if (h === undefined) continue;\n if (isModelHint(h)) {\n const rank = TIER_ORDER[h];\n if (rank > bestRank) {\n bestRank = rank;\n bestSpec = undefined;\n bestHint = h;\n }\n } else {\n // Explicit `ModelSpec` -> treat as the highest tier.\n const rank = TIER_ORDER.smart;\n if (rank >= bestRank) {\n bestRank = rank;\n bestSpec = h;\n bestHint = 'smart';\n }\n }\n }\n if (bestHint === undefined) return undefined;\n if (bestSpec !== undefined) return { hint: bestHint, spec: bestSpec };\n return { hint: bestHint };\n}\n\n/**\n * Walk the precedence ladder and return the resolved provider for a\n * single agent step. Pure function — no side effects.\n *\n * @stable\n */\nexport function resolvePreferredModel(input: ResolvePreferredModelInput): PreferredModelResolution {\n if (input.prepareStepProvider !== undefined) {\n return {\n resolvedProvider: input.prepareStepProvider,\n resolvedModelId: input.prepareStepProvider.modelId,\n source: 'prepare-step',\n };\n }\n const top = pickTopTierAcrossTools(input.toolPreferredModels);\n if (top !== undefined) {\n if (top.spec !== undefined) {\n return {\n resolvedProvider: specToProvider(top.spec),\n resolvedModelId: modelIdFromSpec(top.spec),\n source: 'spec',\n };\n }\n const mapped = input.modelTierMap?.[top.hint];\n if (mapped !== undefined) {\n return {\n resolvedProvider: specToProvider(mapped),\n resolvedModelId: modelIdFromSpec(mapped),\n source: 'tier-map',\n hintApplied: top.hint,\n };\n }\n // Fall through to agent-preferred / default.\n const agent = input.agentPreferredModel;\n if (agent !== undefined) {\n if (isModelHint(agent)) {\n const agentMapped = input.modelTierMap?.[agent];\n if (agentMapped !== undefined) {\n return {\n resolvedProvider: specToProvider(agentMapped),\n resolvedModelId: modelIdFromSpec(agentMapped),\n source: 'agent-preferred',\n hintApplied: agent,\n fallthroughReason: 'tier-not-mapped',\n };\n }\n } else {\n return {\n resolvedProvider: specToProvider(agent),\n resolvedModelId: modelIdFromSpec(agent),\n source: 'agent-preferred',\n fallthroughReason: 'tier-not-mapped',\n };\n }\n }\n return {\n resolvedProvider: input.agentDefaultProvider,\n resolvedModelId: input.agentDefaultProvider.modelId,\n source: 'fallthrough-default',\n hintApplied: top.hint,\n fallthroughReason: 'tier-not-mapped',\n };\n }\n // No per-tool hints. Honour `Agent.preferredModel` next.\n const agent = input.agentPreferredModel;\n if (agent !== undefined) {\n if (isModelHint(agent)) {\n const mapped = input.modelTierMap?.[agent];\n if (mapped !== undefined) {\n return {\n resolvedProvider: specToProvider(mapped),\n resolvedModelId: modelIdFromSpec(mapped),\n source: 'agent-preferred',\n hintApplied: agent,\n };\n }\n // Agent-default tier not mapped: fall through.\n return {\n resolvedProvider: input.agentDefaultProvider,\n resolvedModelId: input.agentDefaultProvider.modelId,\n source: 'fallthrough-default',\n hintApplied: agent,\n fallthroughReason: 'tier-not-mapped',\n };\n }\n return {\n resolvedProvider: specToProvider(agent),\n resolvedModelId: modelIdFromSpec(agent),\n source: 'agent-preferred',\n };\n }\n return {\n resolvedProvider: input.agentDefaultProvider,\n resolvedModelId: input.agentDefaultProvider.modelId,\n source: 'fallthrough-default',\n };\n}\n"],"mappings":";AA2BA,MAAMA,aAAwC;CAAE,MAAM;CAAG,UAAU;CAAG,OAAO;CAAG;AA+BhF,SAAS,YAAY,OAA8D;AACjF,QAAO,UAAU,UAAU,UAAU,cAAc,UAAU;;AAG/D,SAAS,eAAe,MAA2B;AACjD,KAAI,cAAc,KAAM,QAAO,KAAK;AACpC,QAAO;;AAGT,SAAS,gBAAgB,MAAyB;AAChD,KAAI,cAAc,KAAM,QAAO,KAAK;AACpC,QAAQ,KAAkB;;;;;;;;;;;;;AAc5B,SAAgB,uBACd,OACqE;CACrE,IAAI,WAAW;CACf,IAAIC;CACJ,IAAIC;AACJ,MAAK,MAAM,KAAK,OAAO;AACrB,MAAI,MAAM,OAAW;AACrB,MAAI,YAAY,EAAE,EAAE;GAClB,MAAM,OAAO,WAAW;AACxB,OAAI,OAAO,UAAU;AACnB,eAAW;AACX,eAAW;AACX,eAAW;;SAER;GAEL,MAAM,OAAO,WAAW;AACxB,OAAI,QAAQ,UAAU;AACpB,eAAW;AACX,eAAW;AACX,eAAW;;;;AAIjB,KAAI,aAAa,OAAW,QAAO;AACnC,KAAI,aAAa,OAAW,QAAO;EAAE,MAAM;EAAU,MAAM;EAAU;AACrE,QAAO,EAAE,MAAM,UAAU;;;;;;;;AAS3B,SAAgB,sBAAsB,OAA6D;AACjG,KAAI,MAAM,wBAAwB,OAChC,QAAO;EACL,kBAAkB,MAAM;EACxB,iBAAiB,MAAM,oBAAoB;EAC3C,QAAQ;EACT;CAEH,MAAM,MAAM,uBAAuB,MAAM,oBAAoB;AAC7D,KAAI,QAAQ,QAAW;AACrB,MAAI,IAAI,SAAS,OACf,QAAO;GACL,kBAAkB,eAAe,IAAI,KAAK;GAC1C,iBAAiB,gBAAgB,IAAI,KAAK;GAC1C,QAAQ;GACT;EAEH,MAAM,SAAS,MAAM,eAAe,IAAI;AACxC,MAAI,WAAW,OACb,QAAO;GACL,kBAAkB,eAAe,OAAO;GACxC,iBAAiB,gBAAgB,OAAO;GACxC,QAAQ;GACR,aAAa,IAAI;GAClB;EAGH,MAAMC,UAAQ,MAAM;AACpB,MAAIA,YAAU,OACZ,KAAI,YAAYA,QAAM,EAAE;GACtB,MAAM,cAAc,MAAM,eAAeA;AACzC,OAAI,gBAAgB,OAClB,QAAO;IACL,kBAAkB,eAAe,YAAY;IAC7C,iBAAiB,gBAAgB,YAAY;IAC7C,QAAQ;IACR,aAAaA;IACb,mBAAmB;IACpB;QAGH,QAAO;GACL,kBAAkB,eAAeA,QAAM;GACvC,iBAAiB,gBAAgBA,QAAM;GACvC,QAAQ;GACR,mBAAmB;GACpB;AAGL,SAAO;GACL,kBAAkB,MAAM;GACxB,iBAAiB,MAAM,qBAAqB;GAC5C,QAAQ;GACR,aAAa,IAAI;GACjB,mBAAmB;GACpB;;CAGH,MAAM,QAAQ,MAAM;AACpB,KAAI,UAAU,QAAW;AACvB,MAAI,YAAY,MAAM,EAAE;GACtB,MAAM,SAAS,MAAM,eAAe;AACpC,OAAI,WAAW,OACb,QAAO;IACL,kBAAkB,eAAe,OAAO;IACxC,iBAAiB,gBAAgB,OAAO;IACxC,QAAQ;IACR,aAAa;IACd;AAGH,UAAO;IACL,kBAAkB,MAAM;IACxB,iBAAiB,MAAM,qBAAqB;IAC5C,QAAQ;IACR,aAAa;IACb,mBAAmB;IACpB;;AAEH,SAAO;GACL,kBAAkB,eAAe,MAAM;GACvC,iBAAiB,gBAAgB,MAAM;GACvC,QAAQ;GACT;;AAEH,QAAO;EACL,kBAAkB,MAAM;EACxB,iBAAiB,MAAM,qBAAqB;EAC5C,QAAQ;EACT"}
@@ -0,0 +1,62 @@
1
+ import { ProgressArtifactRef, Sensitivity } from "@graphorin/core";
2
+
3
+ //#region src/progress/index.d.ts
4
+
5
+ /**
6
+ * Optional configuration accepted by {@link createProgressIO}.
7
+ *
8
+ * @stable
9
+ */
10
+ interface ProgressIOConfig {
11
+ /** Filesystem root under which `<runId>/progress/<role>.<seq>.txt` files live. */
12
+ readonly artifactRoot?: string;
13
+ /** Default `Sensitivity` applied when the caller does not override. */
14
+ readonly defaultSensitivity?: Sensitivity;
15
+ /** Optional redaction transform applied to content before write. */
16
+ readonly redact?: (content: string) => string;
17
+ }
18
+ /**
19
+ * Per-call options for {@link ProgressIO.write}.
20
+ *
21
+ * @stable
22
+ */
23
+ interface ProgressWriteOptions {
24
+ readonly role?: string;
25
+ /** Explicit sequence number; default auto-increments per `(runId, role)`. */
26
+ readonly seq?: number;
27
+ readonly sensitivity?: Sensitivity;
28
+ readonly tags?: ReadonlyArray<string>;
29
+ }
30
+ /**
31
+ * Per-call options for {@link ProgressIO.read}.
32
+ *
33
+ * @stable
34
+ */
35
+ interface ProgressReadOptions {
36
+ readonly runId?: string;
37
+ readonly role?: string;
38
+ /** Skip artifacts whose `seq <= sinceSeq`. */
39
+ readonly sinceSeq?: number;
40
+ /** Default `100`. */
41
+ readonly maxArtifacts?: number;
42
+ }
43
+ /**
44
+ * Public surface returned by {@link createProgressIO}. Used by the
45
+ * agent runtime to back `agent.progress.write / read`.
46
+ *
47
+ * @stable
48
+ */
49
+ interface ProgressIO {
50
+ write(runId: string, content: string, options?: ProgressWriteOptions): Promise<ProgressArtifactRef>;
51
+ read(currentRunId: string, options?: ProgressReadOptions): Promise<ReadonlyArray<ProgressArtifactRef>>;
52
+ rootFor(runId: string): string;
53
+ }
54
+ /**
55
+ * Build a {@link ProgressIO} bound to a particular artifact root.
56
+ *
57
+ * @stable
58
+ */
59
+ declare function createProgressIO(config?: ProgressIOConfig): ProgressIO;
60
+ //#endregion
61
+ export { ProgressIO, ProgressIOConfig, ProgressReadOptions, ProgressWriteOptions, createProgressIO };
62
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/progress/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;UAoCiB,gBAAA;;;;gCAIe;;;;;;;;;UAUf,oBAAA;;;;yBAIQ;kBACP;;;;;;;UAQD,mBAAA;;;;;;;;;;;;;;UAeA,UAAA;kDAIH,uBACT,QAAQ;uCAGC,sBACT,QAAQ,cAAc;;;;;;;;iBAkBX,gBAAA,UAAyB,mBAAwB"}
@@ -0,0 +1,150 @@
1
+ import { ProgressWriteError } from "../errors/index.js";
2
+ import { createHash } from "node:crypto";
3
+ import { mkdir, readFile, readdir, rename, stat, unlink, writeFile } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+
7
+ //#region src/progress/index.ts
8
+ /**
9
+ * Structured progress-artifact IO. Persists UTF-8 text artifacts
10
+ * under `<artifactRoot>/<runId>/progress/<role>.<seqPadded>.txt`
11
+ * via atomic-write `.tmp + rename` discipline.
12
+ *
13
+ * Cross-session continuity flow:
14
+ *
15
+ * 1. The current agent calls `agent.progress.write(content)` —
16
+ * runtime persists the file and queues the
17
+ * `agent.progress.written` event (drained into the active or
18
+ * next consumed stream).
19
+ * 2. A sibling / future agent calls
20
+ * `agent.progress.read({ runId: priorRunId })` — runtime
21
+ * discovers existing files (no implicit auto-discovery; the
22
+ * operator must supply the `runId` cursor).
23
+ *
24
+ * Auto-discovery across runs is deferred to v0.2.
25
+ *
26
+ * @packageDocumentation
27
+ */
28
+ const DEFAULT_ARTIFACT_DIR = "graphorin-progress";
29
+ const SEQ_PAD_WIDTH = 3;
30
+ const seqWidth = (n) => String(n).padStart(SEQ_PAD_WIDTH, "0");
31
+ const sha256Hex = (input) => createHash("sha256").update(input, "utf8").digest("hex");
32
+ /**
33
+ * Build a {@link ProgressIO} bound to a particular artifact root.
34
+ *
35
+ * @stable
36
+ */
37
+ function createProgressIO(config = {}) {
38
+ const root = config.artifactRoot ?? join(tmpdir(), DEFAULT_ARTIFACT_DIR);
39
+ const defaultSensitivity = config.defaultSensitivity ?? "internal";
40
+ const redact = config.redact ?? ((s) => s);
41
+ const seqState = /* @__PURE__ */ new Map();
42
+ const directoryFor = (runId) => join(root, runId, "progress");
43
+ const seqKey = (runId, role) => `${runId}::${role}`;
44
+ const ensureSeqState = async (runId, role) => {
45
+ const key = seqKey(runId, role);
46
+ let state = seqState.get(key);
47
+ if (state !== void 0) return state;
48
+ state = { next: 1 };
49
+ try {
50
+ const entries = await readdir(directoryFor(runId));
51
+ let max = 0;
52
+ const prefix = `${role}.`;
53
+ for (const entry of entries) {
54
+ if (!entry.startsWith(prefix) || !entry.endsWith(".txt")) continue;
55
+ const seqStr = entry.slice(prefix.length, entry.length - 4);
56
+ const n = Number(seqStr);
57
+ if (Number.isFinite(n) && n > max) max = n;
58
+ }
59
+ state.next = max + 1;
60
+ } catch {}
61
+ seqState.set(key, state);
62
+ return state;
63
+ };
64
+ const write = async (runId, rawContent, options = {}) => {
65
+ const role = options.role ?? "agent";
66
+ const sensitivity = options.sensitivity ?? defaultSensitivity;
67
+ const tags = options.tags ?? [];
68
+ const seqSource = await ensureSeqState(runId, role);
69
+ const seq = options.seq ?? seqSource.next;
70
+ seqSource.next = Math.max(seqSource.next, seq + 1);
71
+ const content = redact(rawContent);
72
+ const dir = directoryFor(runId);
73
+ const finalPath = join(dir, `${role}.${seqWidth(seq)}.txt`);
74
+ const tmpPath = `${finalPath}.tmp`;
75
+ try {
76
+ await mkdir(dir, { recursive: true });
77
+ await writeFile(tmpPath, content, { encoding: "utf8" });
78
+ await rename(tmpPath, finalPath);
79
+ } catch (cause) {
80
+ try {
81
+ await unlink(tmpPath);
82
+ } catch {}
83
+ throw new ProgressWriteError(finalPath, cause);
84
+ }
85
+ const stats = await stat(finalPath);
86
+ const sha256 = sha256Hex(content);
87
+ return {
88
+ path: finalPath,
89
+ role,
90
+ seq,
91
+ sizeBytes: stats.size,
92
+ sensitivity,
93
+ ...tags.length > 0 ? { tags } : {},
94
+ writtenAtIso: (/* @__PURE__ */ new Date()).toISOString(),
95
+ sha256
96
+ };
97
+ };
98
+ const read = async (currentRunId, options = {}) => {
99
+ const runId = options.runId ?? currentRunId;
100
+ const max = options.maxArtifacts ?? 100;
101
+ const sinceSeq = options.sinceSeq ?? 0;
102
+ const dir = directoryFor(runId);
103
+ let entries;
104
+ try {
105
+ entries = await readdir(dir);
106
+ } catch {
107
+ return [];
108
+ }
109
+ const out = [];
110
+ const role = options.role;
111
+ for (const entry of entries) {
112
+ if (!entry.endsWith(".txt")) continue;
113
+ const dot = entry.indexOf(".");
114
+ if (dot < 0) continue;
115
+ const entryRole = entry.slice(0, dot);
116
+ const seqStr = entry.slice(dot + 1, entry.length - 4);
117
+ const seq = Number(seqStr);
118
+ if (!Number.isFinite(seq)) continue;
119
+ if (role !== void 0 && entryRole !== role) continue;
120
+ if (seq <= sinceSeq) continue;
121
+ const fullPath = join(dir, entry);
122
+ const stats = await stat(fullPath);
123
+ const sha256 = sha256Hex(await readFile(fullPath, { encoding: "utf8" }));
124
+ out.push({
125
+ path: fullPath,
126
+ role: entryRole,
127
+ seq,
128
+ sizeBytes: stats.size,
129
+ sensitivity: "internal",
130
+ writtenAtIso: stats.mtime.toISOString(),
131
+ sha256
132
+ });
133
+ if (out.length >= max) break;
134
+ }
135
+ out.sort((a, b) => {
136
+ if (a.role !== b.role) return a.role.localeCompare(b.role);
137
+ return a.seq - b.seq;
138
+ });
139
+ return out;
140
+ };
141
+ return {
142
+ write,
143
+ read,
144
+ rootFor: (runId) => directoryFor(runId)
145
+ };
146
+ }
147
+
148
+ //#endregion
149
+ export { createProgressIO };
150
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["defaultSensitivity: Sensitivity","redact: (s: string) => string","entries: string[]","out: ProgressArtifactRef[]"],"sources":["../../src/progress/index.ts"],"sourcesContent":["/**\n * Structured progress-artifact IO. Persists UTF-8 text artifacts\n * under `<artifactRoot>/<runId>/progress/<role>.<seqPadded>.txt`\n * via atomic-write `.tmp + rename` discipline.\n *\n * Cross-session continuity flow:\n *\n * 1. The current agent calls `agent.progress.write(content)` —\n * runtime persists the file and queues the\n * `agent.progress.written` event (drained into the active or\n * next consumed stream).\n * 2. A sibling / future agent calls\n * `agent.progress.read({ runId: priorRunId })` — runtime\n * discovers existing files (no implicit auto-discovery; the\n * operator must supply the `runId` cursor).\n *\n * Auto-discovery across runs is deferred to v0.2.\n *\n * @packageDocumentation\n */\n\nimport { createHash } from 'node:crypto';\nimport { mkdir, readdir, readFile, rename, stat, unlink, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport type { ProgressArtifactRef, Sensitivity } from '@graphorin/core';\nimport { ProgressWriteError } from '../errors/index.js';\n\nconst DEFAULT_ARTIFACT_DIR = 'graphorin-progress';\nconst SEQ_PAD_WIDTH = 3;\n\n/**\n * Optional configuration accepted by {@link createProgressIO}.\n *\n * @stable\n */\nexport interface ProgressIOConfig {\n /** Filesystem root under which `<runId>/progress/<role>.<seq>.txt` files live. */\n readonly artifactRoot?: string;\n /** Default `Sensitivity` applied when the caller does not override. */\n readonly defaultSensitivity?: Sensitivity;\n /** Optional redaction transform applied to content before write. */\n readonly redact?: (content: string) => string;\n}\n\n/**\n * Per-call options for {@link ProgressIO.write}.\n *\n * @stable\n */\nexport interface ProgressWriteOptions {\n readonly role?: string;\n /** Explicit sequence number; default auto-increments per `(runId, role)`. */\n readonly seq?: number;\n readonly sensitivity?: Sensitivity;\n readonly tags?: ReadonlyArray<string>;\n}\n\n/**\n * Per-call options for {@link ProgressIO.read}.\n *\n * @stable\n */\nexport interface ProgressReadOptions {\n readonly runId?: string;\n readonly role?: string;\n /** Skip artifacts whose `seq <= sinceSeq`. */\n readonly sinceSeq?: number;\n /** Default `100`. */\n readonly maxArtifacts?: number;\n}\n\n/**\n * Public surface returned by {@link createProgressIO}. Used by the\n * agent runtime to back `agent.progress.write / read`.\n *\n * @stable\n */\nexport interface ProgressIO {\n write(\n runId: string,\n content: string,\n options?: ProgressWriteOptions,\n ): Promise<ProgressArtifactRef>;\n read(\n currentRunId: string,\n options?: ProgressReadOptions,\n ): Promise<ReadonlyArray<ProgressArtifactRef>>;\n rootFor(runId: string): string;\n}\n\ninterface InternalSeqState {\n next: number;\n}\n\nconst seqWidth = (n: number): string => String(n).padStart(SEQ_PAD_WIDTH, '0');\n\nconst sha256Hex = (input: string): string =>\n createHash('sha256').update(input, 'utf8').digest('hex');\n\n/**\n * Build a {@link ProgressIO} bound to a particular artifact root.\n *\n * @stable\n */\nexport function createProgressIO(config: ProgressIOConfig = {}): ProgressIO {\n const root = config.artifactRoot ?? join(tmpdir(), DEFAULT_ARTIFACT_DIR);\n const defaultSensitivity: Sensitivity = config.defaultSensitivity ?? 'internal';\n const redact: (s: string) => string = config.redact ?? ((s) => s);\n const seqState = new Map<string, InternalSeqState>();\n\n const directoryFor = (runId: string): string => join(root, runId, 'progress');\n\n const seqKey = (runId: string, role: string): string => `${runId}::${role}`;\n\n const ensureSeqState = async (runId: string, role: string): Promise<InternalSeqState> => {\n const key = seqKey(runId, role);\n let state = seqState.get(key);\n if (state !== undefined) return state;\n state = { next: 1 };\n try {\n const dir = directoryFor(runId);\n const entries = await readdir(dir);\n let max = 0;\n const prefix = `${role}.`;\n for (const entry of entries) {\n if (!entry.startsWith(prefix) || !entry.endsWith('.txt')) continue;\n const seqStr = entry.slice(prefix.length, entry.length - 4);\n const n = Number(seqStr);\n if (Number.isFinite(n) && n > max) max = n;\n }\n state.next = max + 1;\n } catch {\n // Directory does not exist yet — first write will create it.\n }\n seqState.set(key, state);\n return state;\n };\n\n const write = async (\n runId: string,\n rawContent: string,\n options: ProgressWriteOptions = {},\n ): Promise<ProgressArtifactRef> => {\n const role = options.role ?? 'agent';\n const sensitivity = options.sensitivity ?? defaultSensitivity;\n const tags = options.tags ?? [];\n const seqSource = await ensureSeqState(runId, role);\n const seq = options.seq ?? seqSource.next;\n seqSource.next = Math.max(seqSource.next, seq + 1);\n\n const content = redact(rawContent);\n const dir = directoryFor(runId);\n const filename = `${role}.${seqWidth(seq)}.txt`;\n const finalPath = join(dir, filename);\n const tmpPath = `${finalPath}.tmp`;\n\n try {\n await mkdir(dir, { recursive: true });\n await writeFile(tmpPath, content, { encoding: 'utf8' });\n await rename(tmpPath, finalPath);\n } catch (cause) {\n try {\n await unlink(tmpPath);\n } catch {\n // Best-effort cleanup; the write error is the operator-facing signal.\n }\n throw new ProgressWriteError(finalPath, cause);\n }\n\n const stats = await stat(finalPath);\n const sha256 = sha256Hex(content);\n return {\n path: finalPath,\n role,\n seq,\n sizeBytes: stats.size,\n sensitivity,\n ...(tags.length > 0 ? { tags } : {}),\n writtenAtIso: new Date().toISOString(),\n sha256,\n };\n };\n\n const read = async (\n currentRunId: string,\n options: ProgressReadOptions = {},\n ): Promise<ReadonlyArray<ProgressArtifactRef>> => {\n const runId = options.runId ?? currentRunId;\n const max = options.maxArtifacts ?? 100;\n const sinceSeq = options.sinceSeq ?? 0;\n const dir = directoryFor(runId);\n let entries: string[];\n try {\n entries = await readdir(dir);\n } catch {\n return [];\n }\n const out: ProgressArtifactRef[] = [];\n const role = options.role;\n for (const entry of entries) {\n if (!entry.endsWith('.txt')) continue;\n const dot = entry.indexOf('.');\n if (dot < 0) continue;\n const entryRole = entry.slice(0, dot);\n const seqStr = entry.slice(dot + 1, entry.length - 4);\n const seq = Number(seqStr);\n if (!Number.isFinite(seq)) continue;\n if (role !== undefined && entryRole !== role) continue;\n if (seq <= sinceSeq) continue;\n const fullPath = join(dir, entry);\n const stats = await stat(fullPath);\n const content = await readFile(fullPath, { encoding: 'utf8' });\n const sha256 = sha256Hex(content);\n out.push({\n path: fullPath,\n role: entryRole,\n seq,\n sizeBytes: stats.size,\n sensitivity: 'internal',\n writtenAtIso: stats.mtime.toISOString(),\n sha256,\n });\n if (out.length >= max) break;\n }\n out.sort((a, b) => {\n if (a.role !== b.role) return a.role.localeCompare(b.role);\n return a.seq - b.seq;\n });\n return out;\n };\n\n return {\n write,\n read,\n rootFor: (runId) => directoryFor(runId),\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,152 @@
1
+ import { CompletedToolCall, HandoffRecord, Message, RunState, RunStateUsageByModel, RunStatus, RunStep, RunTaintSummary, ToolApproval, Usage } from "@graphorin/core";
2
+
3
+ //#region src/run-state/index.d.ts
4
+
5
+ /**
6
+ * Canonical schema id for serialized {@link RunState} payloads.
7
+ *
8
+ * @stable
9
+ */
10
+ declare const RUN_STATE_SCHEMA_VERSION: "graphorin-run-state/1.1";
11
+ /**
12
+ * Reader-supported schema id range. Major version 1 only for v0.1.
13
+ *
14
+ * @stable
15
+ */
16
+ declare const RUN_STATE_SCHEMA_MAJOR_SUPPORTED = 1;
17
+ /**
18
+ * On-disk payload returned by {@link serializeRunState} and accepted
19
+ * by {@link deserializeRunState}. The shape is JSON-stable.
20
+ *
21
+ * @stable
22
+ */
23
+ interface SerializedRunState {
24
+ readonly version: typeof RUN_STATE_SCHEMA_VERSION;
25
+ readonly id: string;
26
+ readonly agentId: string;
27
+ readonly currentAgentId: string;
28
+ readonly sessionId: string;
29
+ readonly userId?: string;
30
+ readonly status: RunStatus;
31
+ readonly steps: ReadonlyArray<RunStep>;
32
+ readonly messages: ReadonlyArray<Message>;
33
+ readonly pendingApprovals: ReadonlyArray<ToolApproval>;
34
+ readonly handoffs: ReadonlyArray<HandoffRecord>;
35
+ readonly usage: Usage;
36
+ readonly usageByModel?: RunStateUsageByModel;
37
+ /** AG-19: coarse data-flow taint summary (no untrusted text). */
38
+ readonly taintSummary?: RunTaintSummary;
39
+ /** AG-19: deferred tools promoted by `tool_search` this run. */
40
+ readonly promotedTools?: ReadonlyArray<string>;
41
+ readonly startedAt: string;
42
+ readonly finishedAt?: string;
43
+ readonly error?: {
44
+ readonly message: string;
45
+ readonly code: string;
46
+ readonly details?: unknown;
47
+ };
48
+ }
49
+ /**
50
+ * Options accepted by {@link serializeRunState}.
51
+ *
52
+ * @stable
53
+ */
54
+ interface SerializeRunStateOptions {
55
+ /**
56
+ * Deep-redact secret-named keys (`apiKey`, `authorization`,
57
+ * `bearerToken` / `accessToken` / `refreshToken`, `password`,
58
+ * `secret`, …) anywhere in the snapshot — tool results and messages
59
+ * included — replacing their values with `'[redacted]'`. Defaults to
60
+ * `false` for the round-trip canonical helper; the agent runtime
61
+ * passes `true` when persisting through the checkpoint store
62
+ * (AG-23). Redaction is best-effort by key name: secrets stored
63
+ * under unrelated keys are not detected.
64
+ */
65
+ readonly stripTracingApiKey?: boolean;
66
+ }
67
+ /**
68
+ * Render a JSON-stable snapshot of the supplied {@link RunState}.
69
+ * The returned value is plain JSON (no `Map`, `Set`, `Date`, ...).
70
+ *
71
+ * @stable
72
+ */
73
+ declare function serializeRunState(state: RunState, options?: SerializeRunStateOptions): SerializedRunState;
74
+ /**
75
+ * Render the canonical JSON string representation of the supplied
76
+ * {@link RunState}. `JSON.stringify(serializeRunState(state))` —
77
+ * provided as a convenience.
78
+ *
79
+ * @stable
80
+ */
81
+ declare function runStateToJSON(state: RunState, options?: SerializeRunStateOptions): string;
82
+ interface DeserializeOptions {
83
+ /**
84
+ * Synthesize `usageByModel` from a v0.1-alpha state that omits
85
+ * the field. Defaults to `true` so callers can rehydrate older
86
+ * states without explicit migration.
87
+ */
88
+ readonly synthesizeUsageByModel?: boolean;
89
+ /**
90
+ * Logger callback for one-time INFO messages emitted on
91
+ * backwards-compat synthesis. Defaults to a no-op.
92
+ */
93
+ readonly logger?: (message: string) => void;
94
+ }
95
+ /**
96
+ * Rehydrate a {@link RunState} from the on-disk payload. Throws
97
+ * {@link RunStateVersionUnsupportedError} when the payload version
98
+ * is from a future major; throws
99
+ * {@link RunStateMalformedError} when the payload is structurally
100
+ * invalid.
101
+ *
102
+ * Backwards-compat: a payload that omits `usageByModel` is accepted
103
+ * and the field is synthesized from the aggregate `usage` with
104
+ * `attemptCount: 1` for the primary model.
105
+ *
106
+ * @stable
107
+ */
108
+ declare function deserializeRunState(payload: unknown, options?: DeserializeOptions): RunState;
109
+ /** Convenience JSON-string parser pairing with {@link runStateToJSON}. */
110
+ declare function runStateFromJSON(serialized: string, options?: DeserializeOptions): RunState;
111
+ /**
112
+ * Build a fresh, minimal {@link RunState} for a new run. Helper used
113
+ * by `createAgent({...})` so consumers can construct deterministic
114
+ * run state in tests.
115
+ *
116
+ * @stable
117
+ */
118
+ declare function createInitialRunState(args: {
119
+ readonly id: string;
120
+ readonly agentId: string;
121
+ readonly sessionId: string;
122
+ readonly userId?: string;
123
+ readonly startedAt?: string;
124
+ }): RunState;
125
+ /**
126
+ * Append a per-model usage entry to {@link RunState.usageByModel}.
127
+ * Mutates the supplied state in place — used by the agent runtime's
128
+ * per-step retry loop. Pure callers that need an immutable update
129
+ * should clone the state first.
130
+ *
131
+ * @stable
132
+ */
133
+ declare function addModelUsage(state: RunState, modelId: string, delta: Usage): void;
134
+ /**
135
+ * Recompute the aggregate usage from `usageByModel`. Returns the
136
+ * sum that callers can compare against `state.usage` to verify the
137
+ * per-step retry loop maintained the documented invariant.
138
+ *
139
+ * @stable
140
+ */
141
+ declare function aggregateUsageFromByModel(byModel: RunStateUsageByModel | undefined): Usage;
142
+ /**
143
+ * The "tools used" surface of a completed run. Cheap to compute
144
+ * from `RunState.steps`; surfaced as a stand-alone helper for
145
+ * Phase 17 example apps and operator-facing dashboards.
146
+ *
147
+ * @stable
148
+ */
149
+ declare function completedToolCallsFromState(state: RunState): ReadonlyArray<CompletedToolCall>;
150
+ //#endregion
151
+ export { RUN_STATE_SCHEMA_MAJOR_SUPPORTED, RUN_STATE_SCHEMA_VERSION, SerializeRunStateOptions, SerializedRunState, addModelUsage, aggregateUsageFromByModel, completedToolCallsFromState, createInitialRunState, deserializeRunState, runStateFromJSON, runStateToJSON, serializeRunState };
152
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/run-state/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AA4D0B,cA5Bb,wBA4Ba,EAAA,yBAAA;;;;AAe1B;AAoBA;AACS,cAzDI,gCAAA,GAyDJ,CAAA;;;;AAmFT;AAEC;AAiCD;AAoJgB,UA3TC,kBAAA,CA2T8C;EAkB/C,SAAA,OAAA,EAAA,OA5UW,wBAkVf;EAyBI,SAAA,EAAA,EAAA,MAAa;EA8Bb,SAAA,OAAA,EAAA,MAAA;EA+BA,SAAA,cAAA,EAAA,MAA2B;EAAQ,SAAA,SAAA,EAAA,MAAA;EAAyB,SAAA,MAAA,CAAA,EAAA,MAAA;EAAd,SAAA,MAAA,EAla3C,SAka2C;EAAa,SAAA,KAAA,EAjazD,aAiayD,CAja3C,OAia2C,CAAA;qBAhatD,cAAc;6BACN,cAAc;qBACtB,cAAc;kBACjB;0BACQ;;0BAEA;;2BAEC;;;;;;;;;;;;;;UAWV,wBAAA;;;;;;;;;;;;;;;;;;;iBAoBD,iBAAA,QACP,oBACE,2BACR;;;;;;;;iBAiFa,cAAA,QAAsB,oBAAoB;UAIhD,kBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+BM,mBAAA,6BAA+C,qBAA0B;;iBAoJzE,gBAAA,+BAA+C,qBAAqB;;;;;;;;iBAkBpE,qBAAA;;;;;;IAMZ;;;;;;;;;iBAyBY,aAAA,QAAqB,kCAAkC;;;;;;;;iBA8BvD,yBAAA,UAAmC,mCAAmC;;;;;;;;iBA+BtE,2BAAA,QAAmC,WAAW,cAAc"}