@namzu/sdk 42.0.0 → 42.0.2

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 +222 -0
  2. package/dist/manager/resident/outbox.d.ts +8 -8
  3. package/dist/manager/resident/store.d.ts +4 -4
  4. package/dist/runtime/query/cancelled-before-start.d.ts +34 -0
  5. package/dist/runtime/query/cancelled-before-start.d.ts.map +1 -0
  6. package/dist/runtime/query/cancelled-before-start.js +152 -0
  7. package/dist/runtime/query/cancelled-before-start.js.map +1 -0
  8. package/dist/runtime/query/checkpoint.d.ts +21 -0
  9. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  10. package/dist/runtime/query/checkpoint.js +23 -0
  11. package/dist/runtime/query/checkpoint.js.map +1 -1
  12. package/dist/runtime/query/executor/tool-call-admission.d.ts +57 -0
  13. package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -0
  14. package/dist/runtime/query/executor/tool-call-admission.js +373 -0
  15. package/dist/runtime/query/executor/tool-call-admission.js.map +1 -0
  16. package/dist/runtime/query/executor.d.ts +70 -35
  17. package/dist/runtime/query/executor.d.ts.map +1 -1
  18. package/dist/runtime/query/executor.js +46 -380
  19. package/dist/runtime/query/executor.js.map +1 -1
  20. package/dist/runtime/query/finalize-run.d.ts +55 -0
  21. package/dist/runtime/query/finalize-run.d.ts.map +1 -0
  22. package/dist/runtime/query/finalize-run.js +113 -0
  23. package/dist/runtime/query/finalize-run.js.map +1 -0
  24. package/dist/runtime/query/index.d.ts +4 -9
  25. package/dist/runtime/query/index.d.ts.map +1 -1
  26. package/dist/runtime/query/index.js +238 -893
  27. package/dist/runtime/query/index.js.map +1 -1
  28. package/dist/runtime/query/iteration/index.d.ts +6 -161
  29. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  30. package/dist/runtime/query/iteration/index.js +23 -523
  31. package/dist/runtime/query/iteration/index.js.map +1 -1
  32. package/dist/runtime/query/iteration/outstanding-work.d.ts +158 -0
  33. package/dist/runtime/query/iteration/outstanding-work.d.ts.map +1 -0
  34. package/dist/runtime/query/iteration/outstanding-work.js +365 -0
  35. package/dist/runtime/query/iteration/outstanding-work.js.map +1 -0
  36. package/dist/runtime/query/iteration/phases/plan.d.ts.map +1 -1
  37. package/dist/runtime/query/iteration/phases/plan.js +13 -2
  38. package/dist/runtime/query/iteration/phases/plan.js.map +1 -1
  39. package/dist/runtime/query/iteration/step-shaping.d.ts +41 -0
  40. package/dist/runtime/query/iteration/step-shaping.d.ts.map +1 -0
  41. package/dist/runtime/query/iteration/step-shaping.js +184 -0
  42. package/dist/runtime/query/iteration/step-shaping.js.map +1 -0
  43. package/dist/runtime/query/prepare-run.d.ts +94 -0
  44. package/dist/runtime/query/prepare-run.d.ts.map +1 -0
  45. package/dist/runtime/query/prepare-run.js +589 -0
  46. package/dist/runtime/query/prepare-run.js.map +1 -0
  47. package/dist/runtime/query/release-run.d.ts +56 -0
  48. package/dist/runtime/query/release-run.d.ts.map +1 -0
  49. package/dist/runtime/query/release-run.js +101 -0
  50. package/dist/runtime/query/release-run.js.map +1 -0
  51. package/dist/runtime/query/resume-pending.d.ts +112 -1
  52. package/dist/runtime/query/resume-pending.d.ts.map +1 -1
  53. package/dist/runtime/query/resume-pending.js +133 -0
  54. package/dist/runtime/query/resume-pending.js.map +1 -1
  55. package/dist/store/evidence/compaction-archive.d.ts +2 -2
  56. package/dist/types/run/config.d.ts +12 -5
  57. package/dist/types/run/config.d.ts.map +1 -1
  58. package/package.json +4 -4
  59. package/src/runtime/query/cancelled-before-start.ts +189 -0
  60. package/src/runtime/query/checkpoint.ts +22 -0
  61. package/src/runtime/query/executor/tool-call-admission.ts +473 -0
  62. package/src/runtime/query/executor.ts +63 -442
  63. package/src/runtime/query/finalize-run.ts +192 -0
  64. package/src/runtime/query/index.ts +270 -1011
  65. package/src/runtime/query/iteration/index.ts +40 -586
  66. package/src/runtime/query/iteration/outstanding-work.ts +386 -0
  67. package/src/runtime/query/iteration/phases/plan.ts +18 -2
  68. package/src/runtime/query/iteration/step-shaping.ts +271 -0
  69. package/src/runtime/query/prepare-run.ts +718 -0
  70. package/src/runtime/query/release-run.ts +168 -0
  71. package/src/runtime/query/resume-pending.ts +158 -0
  72. package/src/types/run/config.ts +12 -5
@@ -0,0 +1,192 @@
1
+ import type { Span } from '@opentelemetry/api'
2
+ import { consolidationEntry } from '../../compaction/consolidation.js'
3
+ import type { WorkingStateManager } from '../../compaction/manager.js'
4
+ import { NAMZU } from '../../constants/telemetry/index.js'
5
+ import type { RunEvent, StepResult } from '../../types/run/index.js'
6
+ import { toErrorMessage } from '../../utils/error.js'
7
+ import type { RunContext } from './context.js'
8
+ import type { EventTranslator } from './events.js'
9
+ import { runOutputGuardrails } from './guardrails.js'
10
+ import type { QueryParams } from './index.js'
11
+ import { applyLifecycleHookResults } from './plugin-hooks.js'
12
+ import type { ResultAssembler } from './result.js'
13
+
14
+ /**
15
+ * What a run does on its way out, once the loop has stopped.
16
+ *
17
+ * The loop returns for any of a dozen reasons — an answer, a budget, a stop
18
+ * condition, a cancelled signal — and this is the one place all of them pass
19
+ * through: the `run_end`/`subagent_stop` hooks, the step record, the output
20
+ * guardrails, consolidation into a memory store, and the terminal events.
21
+ *
22
+ * It is a generator because it emits, and it is reached with `yield*` so
23
+ * every one of those emits suspends the caller at exactly the point it did
24
+ * when the code lived inline.
25
+ *
26
+ * Two positions here are load-bearing, and they are stated where they happen.
27
+ * `markCancelled` runs before the assembler, because `completeRun` marks a
28
+ * `running` run `completed` — the reverse order would overwrite the
29
+ * cancellation the abort signal had already declared. And
30
+ * `memory_consolidated` precedes `run_completed`, so a host folding the
31
+ * stream in order has the memory before the run that produced it.
32
+ *
33
+ * `setSteps` keeps its position too, but on the move's terms rather than on
34
+ * its own. This file used to claim the assembler needed it first "or the
35
+ * returned `Run` loses the final turn's steps" — that is not true, and a
36
+ * mutation proves it: `completeRun` reads `result`, `stopReason` and the
37
+ * budget and never `steps`, the returned `Run` is built by `finalize()`
38
+ * (which runs after the whole `try`/`catch`/`finally`), and moving
39
+ * `setSteps` below the assembler leaves the suite green, including the test
40
+ * that asserts `run.steps` on a returned run. What holds `setSteps` where it
41
+ * is, is the byte-identity of this move: every position was preserved, not
42
+ * just the consequential ones. Its read is still deferred to the same
43
+ * moment — after the `run_end` hooks, immediately before the record is
44
+ * written — which is why the caller passes `takeSteps` rather than an array.
45
+ */
46
+ export interface RunFinalization {
47
+ readonly ctx: RunContext
48
+ readonly params: QueryParams
49
+ readonly eventTranslator: EventTranslator
50
+ /**
51
+ * The steps the loop recorded, read HERE rather than handed over as an
52
+ * array: it is read where it always was, after the `run_end` hooks and
53
+ * immediately before the record is written.
54
+ */
55
+ readonly takeSteps: () => readonly StepResult[]
56
+ readonly workingStateManager: WorkingStateManager | undefined
57
+ readonly resultAssembler: ResultAssembler
58
+ readonly rootSpan: Span
59
+ }
60
+
61
+ export async function* finalizeRun(finalization: RunFinalization): AsyncGenerator<RunEvent, void> {
62
+ const {
63
+ ctx,
64
+ params,
65
+ eventTranslator,
66
+ takeSteps,
67
+ workingStateManager,
68
+ resultAssembler,
69
+ rootSpan,
70
+ } = finalization
71
+
72
+ if (params.pluginManager) {
73
+ const hookResults = await params.pluginManager.executeHooks(
74
+ 'run_end',
75
+ { runId: ctx.runId, signal: ctx.abortController.signal },
76
+ eventTranslator.emitEvent,
77
+ )
78
+ applyLifecycleHookResults('run_end', hookResults)
79
+ yield* eventTranslator.drainPending()
80
+ // A delegated run says so once more, by name, so a hook that
81
+ // only cares when a subagent finishes need not read parent ids
82
+ // off every run_end.
83
+ if (params.parentRunId !== undefined) {
84
+ const stopResults = await params.pluginManager.executeHooks(
85
+ 'subagent_stop',
86
+ {
87
+ runId: ctx.runId,
88
+ parentRunId: params.parentRunId,
89
+ signal: ctx.abortController.signal,
90
+ },
91
+ eventTranslator.emitEvent,
92
+ )
93
+ applyLifecycleHookResults('subagent_stop', stopResults)
94
+ yield* eventTranslator.drainPending()
95
+ }
96
+ }
97
+
98
+ // Hand the step record to the run before it settles, so the
99
+ // returned `Run` carries it.
100
+ ctx.runMgr.setSteps(takeSteps())
101
+
102
+ // Gates the FINAL result, not the stream — `text_delta` already
103
+ // reached the host as the model produced it. A rewrite is
104
+ // therefore a correction, and the event says so; buffering every
105
+ // token to gate the stream itself would trade the streaming UX
106
+ // for the guarantee, which is the host's call, not the SDK's.
107
+ if (params.outputGuardrails && params.outputGuardrails.length > 0) {
108
+ // Read what the run produced WITHOUT settling it. This used to
109
+ // call `markCompleted()` just to materialize the text, which
110
+ // force-marked a cancelled or paused run `completed` merely
111
+ // because a guardrail was configured — the presence of a
112
+ // safety check silently rewrote the run's own outcome.
113
+ const produced = ctx.runMgr.materializeResult()
114
+ const outputVerdict = await runOutputGuardrails(
115
+ params.outputGuardrails,
116
+ { runId: ctx.runId, output: produced, messages: ctx.runMgr.messages },
117
+ ctx.log,
118
+ )
119
+
120
+ if (outputVerdict.blocked || outputVerdict.rewritten !== undefined) {
121
+ ctx.runMgr.clearStructuredOutput()
122
+ if (
123
+ params.structuredOutput &&
124
+ outputVerdict.rewritten !== undefined &&
125
+ ctx.runMgr.stopReason === 'end_turn'
126
+ )
127
+ ctx.runMgr.setStopReason('output_guardrail')
128
+ }
129
+
130
+ if (outputVerdict.blocked) {
131
+ await eventTranslator.emitEvent({
132
+ type: 'guardrail_triggered',
133
+ runId: ctx.runId,
134
+ stage: 'output',
135
+ action: 'block',
136
+ ...(outputVerdict.name ? { guardrail: outputVerdict.name } : {}),
137
+ ...(outputVerdict.reason ? { reason: outputVerdict.reason } : {}),
138
+ })
139
+ yield* eventTranslator.drainPending()
140
+ // Same reasoning as the input-guardrail branch above.
141
+ await ctx.runMgr.recordAudit({
142
+ what: { action: 'guardrail:output', resource: outputVerdict.name },
143
+ outcome: 'refused',
144
+ reason: outputVerdict.reason ?? 'blocked by an output guardrail',
145
+ ...(params.persona?.identity.role ? { persona: params.persona.identity.role } : {}),
146
+ })
147
+ ctx.runMgr.setStopReason('output_guardrail')
148
+ ctx.runMgr.setLastError(outputVerdict.reason ?? 'blocked by an output guardrail')
149
+ ctx.runMgr.setResult('')
150
+ } else if (outputVerdict.rewritten !== undefined) {
151
+ await eventTranslator.emitEvent({
152
+ type: 'guardrail_triggered',
153
+ runId: ctx.runId,
154
+ stage: 'output',
155
+ action: 'rewrite',
156
+ ...(outputVerdict.name ? { guardrail: outputVerdict.name } : {}),
157
+ ...(outputVerdict.reason ? { reason: outputVerdict.reason } : {}),
158
+ })
159
+ yield* eventTranslator.drainPending()
160
+ ctx.runMgr.setResult(outputVerdict.rewritten)
161
+ }
162
+ }
163
+
164
+ if (params.consolidateInto && workingStateManager) {
165
+ const entry = consolidationEntry(workingStateManager.getState(), {
166
+ runId: ctx.runId,
167
+ at: Date.now(),
168
+ })
169
+ if (entry) {
170
+ try {
171
+ const { entry: saved } = await params.consolidateInto.create(entry)
172
+ await eventTranslator.emitEvent({
173
+ type: 'memory_consolidated',
174
+ runId: ctx.runId,
175
+ memoryId: saved.id,
176
+ title: entry.title,
177
+ decisions: workingStateManager.getState().decisions.length,
178
+ discoveries: workingStateManager.getState().discoveries.length,
179
+ failures: workingStateManager.getState().failures.length,
180
+ })
181
+ yield* eventTranslator.drainPending()
182
+ } catch (error) {
183
+ ctx.log.warn('consolidation into the memory store failed', {
184
+ [NAMZU.RUN_ID]: ctx.runId,
185
+ 'namzu.memory.error': toErrorMessage(error),
186
+ })
187
+ }
188
+ }
189
+ }
190
+ if (ctx.abortController.signal.aborted) ctx.runMgr.markCancelled()
191
+ yield* resultAssembler.completeRun(rootSpan)
192
+ }