@namzu/sdk 52.7.0 → 53.1.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 (135) hide show
  1. package/CHANGELOG.md +45 -26
  2. package/dist/authorization/protected-paths.d.ts +2 -4
  3. package/dist/authorization/protected-paths.d.ts.map +1 -1
  4. package/dist/authorization/protected-paths.js +2 -4
  5. package/dist/authorization/protected-paths.js.map +1 -1
  6. package/dist/authorization/readonly-commands.d.ts +4 -4
  7. package/dist/authorization/readonly-commands.js +7 -7
  8. package/dist/authorization/readonly-commands.js.map +1 -1
  9. package/dist/authorization/readonly-flags.d.ts +1 -2
  10. package/dist/authorization/readonly-flags.d.ts.map +1 -1
  11. package/dist/authorization/readonly-flags.js +1 -2
  12. package/dist/authorization/readonly-flags.js.map +1 -1
  13. package/dist/authorization/removal.d.ts +2 -3
  14. package/dist/authorization/removal.d.ts.map +1 -1
  15. package/dist/authorization/removal.js +3 -4
  16. package/dist/authorization/removal.js.map +1 -1
  17. package/dist/authorization/shell-paths.d.ts +5 -5
  18. package/dist/authorization/shell-paths.js +6 -6
  19. package/dist/authorization/shell-paths.js.map +1 -1
  20. package/dist/compaction/context-window.d.ts +1 -1
  21. package/dist/compaction/context-window.js +1 -1
  22. package/dist/compaction/verifier.js +2 -2
  23. package/dist/compaction/verifier.js.map +1 -1
  24. package/dist/connector/web/page.d.ts +2 -3
  25. package/dist/connector/web/page.d.ts.map +1 -1
  26. package/dist/connector/web/page.js +2 -3
  27. package/dist/connector/web/page.js.map +1 -1
  28. package/dist/execution/workflow/prelude.d.ts.map +1 -1
  29. package/dist/execution/workflow/prelude.js +29 -5
  30. package/dist/execution/workflow/prelude.js.map +1 -1
  31. package/dist/execution/workflow/runtime.d.ts +2 -0
  32. package/dist/execution/workflow/runtime.d.ts.map +1 -1
  33. package/dist/execution/workflow/runtime.js +8 -3
  34. package/dist/execution/workflow/runtime.js.map +1 -1
  35. package/dist/execution/workflow/types.d.ts +3 -3
  36. package/dist/execution/workflow/types.d.ts.map +1 -1
  37. package/dist/manager/agent/lifecycle.d.ts +1 -1
  38. package/dist/manager/agent/lifecycle.js +1 -1
  39. package/dist/plugin/shell-hook.d.ts +1 -1
  40. package/dist/plugin/shell-hook.js +4 -4
  41. package/dist/plugin/shell-hook.js.map +1 -1
  42. package/dist/provider/errors.js +2 -2
  43. package/dist/provider/errors.js.map +1 -1
  44. package/dist/public-runtime.d.ts +1 -0
  45. package/dist/public-runtime.d.ts.map +1 -1
  46. package/dist/public-runtime.js.map +1 -1
  47. package/dist/runtime/jobs/monitor-stream.d.ts +1 -2
  48. package/dist/runtime/jobs/monitor-stream.d.ts.map +1 -1
  49. package/dist/runtime/jobs/monitor-stream.js +1 -2
  50. package/dist/runtime/jobs/monitor-stream.js.map +1 -1
  51. package/dist/runtime/jobs/websocket-source.d.ts +1 -1
  52. package/dist/runtime/jobs/websocket-source.d.ts.map +1 -1
  53. package/dist/runtime/jobs/websocket-source.js +1 -1
  54. package/dist/runtime/jobs/websocket-source.js.map +1 -1
  55. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  56. package/dist/runtime/query/checkpoint.js +3 -1
  57. package/dist/runtime/query/checkpoint.js.map +1 -1
  58. package/dist/runtime/query/iteration/index.js +3 -3
  59. package/dist/runtime/query/iteration/index.js.map +1 -1
  60. package/dist/runtime/query/iteration/outstanding-work.d.ts.map +1 -1
  61. package/dist/runtime/query/iteration/outstanding-work.js +10 -2
  62. package/dist/runtime/query/iteration/outstanding-work.js.map +1 -1
  63. package/dist/runtime/query/iteration/phases/compaction-breaker.d.ts +2 -2
  64. package/dist/runtime/query/iteration/phases/compaction-breaker.js +2 -2
  65. package/dist/runtime/query/iteration/phases/compaction.d.ts +3 -5
  66. package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
  67. package/dist/runtime/query/iteration/phases/compaction.js +6 -8
  68. package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
  69. package/dist/runtime/query/iteration/request-repair.d.ts +1 -1
  70. package/dist/runtime/query/iteration/request-repair.js +2 -2
  71. package/dist/runtime/query/iteration/request-repair.js.map +1 -1
  72. package/dist/runtime/query/path-escalation.d.ts.map +1 -1
  73. package/dist/runtime/query/path-escalation.js +2 -3
  74. package/dist/runtime/query/path-escalation.js.map +1 -1
  75. package/dist/scheduler/completion-inbox.d.ts +21 -1
  76. package/dist/scheduler/completion-inbox.d.ts.map +1 -1
  77. package/dist/scheduler/completion-inbox.js +20 -1
  78. package/dist/scheduler/completion-inbox.js.map +1 -1
  79. package/dist/session/workspace/driver.d.ts +1 -1
  80. package/dist/store/checkpoint/memory.d.ts +1 -1
  81. package/dist/store/checkpoint/memory.js +1 -1
  82. package/dist/store/memory/markdown-format.d.ts +1 -1
  83. package/dist/store/memory/markdown-format.js +1 -1
  84. package/dist/store/memory/markdown.js +1 -1
  85. package/dist/store/session-log/core.d.ts.map +1 -1
  86. package/dist/store/session-log/core.js +28 -0
  87. package/dist/store/session-log/core.js.map +1 -1
  88. package/dist/store/session-log/spilled-input.d.ts +34 -0
  89. package/dist/store/session-log/spilled-input.d.ts.map +1 -0
  90. package/dist/store/session-log/spilled-input.js +68 -0
  91. package/dist/store/session-log/spilled-input.js.map +1 -0
  92. package/dist/tools/builtins/bash.d.ts.map +1 -1
  93. package/dist/tools/builtins/bash.js +1 -2
  94. package/dist/tools/builtins/bash.js.map +1 -1
  95. package/dist/tools/builtins/edit-match.d.ts +5 -6
  96. package/dist/tools/builtins/edit-match.d.ts.map +1 -1
  97. package/dist/tools/builtins/edit-match.js +5 -6
  98. package/dist/tools/builtins/edit-match.js.map +1 -1
  99. package/dist/types/provider/errors.js +1 -1
  100. package/dist/types/provider/errors.js.map +1 -1
  101. package/package.json +1 -1
  102. package/src/authorization/protected-paths.ts +2 -4
  103. package/src/authorization/readonly-commands.ts +7 -7
  104. package/src/authorization/readonly-flags.ts +1 -2
  105. package/src/authorization/removal.ts +3 -4
  106. package/src/authorization/shell-paths.ts +6 -6
  107. package/src/compaction/context-window.ts +1 -1
  108. package/src/compaction/verifier.ts +2 -2
  109. package/src/connector/web/page.ts +2 -3
  110. package/src/execution/workflow/prelude.ts +29 -5
  111. package/src/execution/workflow/runtime.ts +9 -3
  112. package/src/execution/workflow/types.ts +3 -3
  113. package/src/manager/agent/lifecycle.ts +1 -1
  114. package/src/plugin/shell-hook.ts +4 -4
  115. package/src/provider/errors.ts +2 -2
  116. package/src/public-runtime.ts +1 -0
  117. package/src/runtime/jobs/monitor-stream.ts +1 -2
  118. package/src/runtime/jobs/websocket-source.ts +1 -1
  119. package/src/runtime/query/checkpoint.ts +6 -1
  120. package/src/runtime/query/iteration/index.ts +3 -3
  121. package/src/runtime/query/iteration/outstanding-work.ts +9 -2
  122. package/src/runtime/query/iteration/phases/compaction-breaker.ts +2 -2
  123. package/src/runtime/query/iteration/phases/compaction.ts +6 -8
  124. package/src/runtime/query/iteration/request-repair.ts +3 -3
  125. package/src/runtime/query/path-escalation.ts +2 -3
  126. package/src/scheduler/completion-inbox.ts +31 -1
  127. package/src/session/workspace/driver.ts +1 -1
  128. package/src/store/checkpoint/memory.ts +1 -1
  129. package/src/store/memory/markdown-format.ts +1 -1
  130. package/src/store/memory/markdown.ts +1 -1
  131. package/src/store/session-log/core.ts +28 -0
  132. package/src/store/session-log/spilled-input.ts +90 -0
  133. package/src/tools/builtins/bash.ts +1 -2
  134. package/src/tools/builtins/edit-match.ts +5 -6
  135. package/src/types/provider/errors.ts +1 -1
@@ -53,7 +53,7 @@ import { MemoryRevisionConflictError, assertMemoryRevision, memoryRevision } fro
53
53
 
54
54
  /**
55
55
  * Versioned like every other record this SDK persists. A memory file carries
56
- * no `schemaVersion` while it is at version 1 — the reference shape has no
56
+ * no `schemaVersion` while it is at version 1 — the canonical shape has no
57
57
  * such field and a hand-written file should not need one — so the stamp only
58
58
  * appears once a later build writes a later version, and THIS build refuses
59
59
  * that file rather than reading it partially and writing the difference away.
@@ -51,6 +51,7 @@ import {
51
51
  isLeaseLive,
52
52
  } from './lease.js'
53
53
  import type { SpillReadOptions, SpillRef, SpillStore } from './spill.js'
54
+ import { TOOL_INPUT_RECORD_TYPES, spilledInput, toolInputSlots } from './spilled-input.js'
54
55
 
55
56
  // ─── public types ─────────────────────────────────────────────────────────
56
57
 
@@ -666,6 +667,9 @@ export class SessionLogCore implements SessionLog {
666
667
  ? await this.#spillStructuredResults(original)
667
668
  : original
668
669
  const type = candidate.type
670
+ if (typeof type === 'string' && TOOL_INPUT_RECORD_TYPES.has(type)) {
671
+ return this.#spillToolInputs(candidate)
672
+ }
669
673
  if (
670
674
  type !== 'message' &&
671
675
  type !== 'message_replaced' &&
@@ -715,6 +719,30 @@ export class SessionLogCore implements SessionLog {
715
719
  return { ...candidate, content: preview, spill: ref }
716
720
  }
717
721
 
722
+ /**
723
+ * A record that carries tool inputs and would not fit a line: each large
724
+ * input goes to `tool-results/` and the record keeps a stand-in, so the
725
+ * person is still asked and the call is still restored on resume.
726
+ */
727
+ async #spillToolInputs(candidate: Record<string, unknown>): Promise<Record<string, unknown>> {
728
+ const sizeOf = (record: Record<string, unknown>): number =>
729
+ Buffer.byteLength(`${JSON.stringify(record)}\n`, 'utf8')
730
+ if (sizeOf(candidate) <= this.#spillAbove) return candidate
731
+ const copy = structuredClone(candidate)
732
+ const slots = toolInputSlots(copy)
733
+ const bodies = slots.map(({ holder, key }) => JSON.stringify(holder[key]) ?? 'null')
734
+ // Largest first, and only as many as it takes to fit.
735
+ const order = slots.map((_, i) => i).sort((a, b) => bodies[b]!.length - bodies[a]!.length)
736
+ for (const index of order) {
737
+ const slot = slots[index]!
738
+ const body = bodies[index]!
739
+ const ref = await this.#spills.write(`input:${String(candidate.id)}:${index}`, 'text', body)
740
+ slot.holder[slot.key] = spilledInput(ref, body)
741
+ if (sizeOf(copy) <= this.#spillAbove) break
742
+ }
743
+ return copy
744
+ }
745
+
718
746
  async #spillStructuredResults(
719
747
  candidate: Record<string, unknown>,
720
748
  ): Promise<Record<string, unknown>> {
@@ -0,0 +1,90 @@
1
+ import type { SpillRef } from './spill.js'
2
+
3
+ /**
4
+ * A tool call's input can be larger than a session-log record may be (a
5
+ * write of a few megabytes, a batch of large writes). The record that carries
6
+ * it then holds this stand-in, and the input itself sits in `tool-results/`
7
+ * under the same rules as any other spilled body.
8
+ */
9
+ export const SPILLED_INPUT_KEY = '$spilledInput'
10
+
11
+ /** Characters of the input kept inline beside the reference. */
12
+ const INPUT_PREVIEW_CHARS = 200
13
+
14
+ export interface SpilledInput {
15
+ readonly [SPILLED_INPUT_KEY]: SpillRef
16
+ readonly preview: string
17
+ }
18
+
19
+ export function spilledInput(ref: SpillRef, json: string): SpilledInput {
20
+ return { [SPILLED_INPUT_KEY]: ref, preview: json.slice(0, INPUT_PREVIEW_CHARS) }
21
+ }
22
+
23
+ export function isSpilledInput(value: unknown): value is SpilledInput {
24
+ return (
25
+ typeof value === 'object' &&
26
+ value !== null &&
27
+ SPILLED_INPUT_KEY in value &&
28
+ typeof (value as Record<string, unknown>)[SPILLED_INPUT_KEY] === 'object'
29
+ )
30
+ }
31
+
32
+ /** Where a record keeps tool inputs: the holder object and the key of the input in it. */
33
+ export interface InputSlot {
34
+ readonly holder: Record<string, unknown>
35
+ readonly key: string
36
+ }
37
+
38
+ function callSlots(calls: unknown): InputSlot[] {
39
+ if (!Array.isArray(calls)) return []
40
+ const slots: InputSlot[] = []
41
+ for (const call of calls) {
42
+ if (typeof call === 'object' && call !== null && 'input' in call) {
43
+ slots.push({ holder: call as Record<string, unknown>, key: 'input' })
44
+ }
45
+ }
46
+ return slots
47
+ }
48
+
49
+ /** Record types that carry a tool call's whole input. */
50
+ export const TOOL_INPUT_RECORD_TYPES: ReadonlySet<string> = new Set([
51
+ 'tool_review_requested',
52
+ 'decision_requested',
53
+ 'tool_executing',
54
+ 'tool_input_completed',
55
+ ])
56
+
57
+ /**
58
+ * The input slots of one record. The record is read, never changed; the
59
+ * caller copies what it replaces.
60
+ */
61
+ export function toolInputSlots(record: Record<string, unknown>): InputSlot[] {
62
+ switch (record.type) {
63
+ case 'tool_review_requested':
64
+ return callSlots(record.toolCalls)
65
+ case 'decision_requested': {
66
+ const request = record.request as { toolCalls?: unknown } | undefined
67
+ return request ? callSlots(request.toolCalls) : []
68
+ }
69
+ case 'tool_executing':
70
+ case 'tool_input_completed':
71
+ return 'input' in record ? [{ holder: record, key: 'input' }] : []
72
+ default:
73
+ return []
74
+ }
75
+ }
76
+
77
+ /**
78
+ * The input slots of a request read back from a log, with any stand-in
79
+ * replaced by the input it stands for. Mutates and returns `request`.
80
+ */
81
+ export async function restoreSpilledRequestInputs<T extends { toolCalls?: unknown }>(
82
+ request: T,
83
+ read: (ref: SpillRef) => Promise<string>,
84
+ ): Promise<T> {
85
+ for (const { holder, key } of callSlots(request.toolCalls)) {
86
+ const value = holder[key]
87
+ if (isSpilledInput(value)) holder[key] = JSON.parse(await read(value[SPILLED_INPUT_KEY]))
88
+ }
89
+ return request
90
+ }
@@ -52,8 +52,7 @@ const DEFAULT_BASH_MAX_BUFFER_BYTES = readPositiveIntEnv(
52
52
  *
53
53
  * So the tool declares a ceiling and the executor is given a deadline above
54
54
  * it (see `timeoutMs` on the definition), which makes this the only clock
55
- * that can fire in practice. A request past the ceiling is CLAMPED to it, as
56
- * the reference terminal does: the command still runs, and a timeout reports
55
+ * that can fire in practice. A request past the ceiling is CLAMPED to it: the command still runs, and a timeout reports
57
56
  * the deadline that was actually applied, so the number the model sees on a
58
57
  * timeout is the one that fired.
59
58
  */
@@ -9,18 +9,17 @@
9
9
  * carries the same transformation across to `new_string` so the replacement
10
10
  * stays consistent with what it replaced.
11
11
  *
12
- * The strategies and their order are a faithful port of the reference client's
13
- * file-edit resolver (the `lje`/`b`/`_`/`L`/`k`/`R`/`C`/`cDs`/`ipt`/`H`/`Q`/`N`
14
- * functions in its shipped bundle), so an edit that lands there lands here:
12
+ * The strategies and their order are fixed as follows, so an edit that matches
13
+ * under one of them matches here:
15
14
  *
16
15
  * 1. exact
17
16
  * 2. curly vs straight quotes, both directions
18
17
  * 3. `\uXXXX` escape in `old_string`, character in the file
19
18
  * 4. character in `old_string`, `\uXXXX` escape in the file
20
19
  *
21
- * The reference also expands a map of its own prompt delimiters (`<fnr>` →
22
- * `<function_results>`, `\n\nH:` → `\n\nHuman:`, …). That is deliberately NOT
23
- * ported: those tokens are artifacts of that client's own transcript format,
20
+ * Prompt delimiters from a transcript format (`<fnr>` →
21
+ * `<function_results>`, `\n\nH:` → `\n\nHuman:`, …) are deliberately NOT
22
+ * expanded: those tokens are artifacts of a transcript format,
24
23
  * not a mismatch a Namzu model produces against a real source file.
25
24
  *
26
25
  * Pure by construction, like `edit-apply`: every function here is from strings
@@ -337,7 +337,7 @@ function codeFromMessage(message: string, status?: number): ProviderErrorCode |
337
337
  // overflow rescue tests for by exact equality. The turn died holding
338
338
  // the remedy.
339
339
  m.includes('too long for') ||
340
- // The reference terminal's own wordings (its `context window` and
340
+ // Known wordings: `context window` and
341
341
  // `input length and max_tokens exceed context limit` matchers).
342
342
  // Only where the status cannot say otherwise: a 429, 5xx or 401 that
343
343
  // mentions the window is still a rate limit, a server fault or an auth