@namzu/sdk 39.0.0 → 40.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/CHANGELOG.md +151 -0
  2. package/dist/connector/mcp/adapter.d.ts.map +1 -1
  3. package/dist/connector/mcp/adapter.js +20 -6
  4. package/dist/connector/mcp/adapter.js.map +1 -1
  5. package/dist/manager/run/persistence.d.ts +8 -0
  6. package/dist/manager/run/persistence.d.ts.map +1 -1
  7. package/dist/manager/run/persistence.js +12 -0
  8. package/dist/manager/run/persistence.js.map +1 -1
  9. package/dist/public-runtime.d.ts +3 -1
  10. package/dist/public-runtime.d.ts.map +1 -1
  11. package/dist/public-runtime.js +5 -1
  12. package/dist/public-runtime.js.map +1 -1
  13. package/dist/public-tools.d.ts +11 -0
  14. package/dist/public-tools.d.ts.map +1 -1
  15. package/dist/public-tools.js +14 -0
  16. package/dist/public-tools.js.map +1 -1
  17. package/dist/registry/tool/execute.d.ts.map +1 -1
  18. package/dist/registry/tool/execute.js +2 -3
  19. package/dist/registry/tool/execute.js.map +1 -1
  20. package/dist/registry/tool/portable.d.ts +65 -0
  21. package/dist/registry/tool/portable.d.ts.map +1 -0
  22. package/dist/registry/tool/portable.js +244 -0
  23. package/dist/registry/tool/portable.js.map +1 -0
  24. package/dist/registry/tool/schema.d.ts +32 -5
  25. package/dist/registry/tool/schema.d.ts.map +1 -1
  26. package/dist/registry/tool/schema.js +35 -9
  27. package/dist/registry/tool/schema.js.map +1 -1
  28. package/dist/registry/toolset/catalog.js +8 -8
  29. package/dist/registry/toolset/catalog.js.map +1 -1
  30. package/dist/runtime/jobs/awaited-jobs.d.ts +215 -0
  31. package/dist/runtime/jobs/awaited-jobs.d.ts.map +1 -0
  32. package/dist/runtime/jobs/awaited-jobs.js +259 -0
  33. package/dist/runtime/jobs/awaited-jobs.js.map +1 -0
  34. package/dist/runtime/jobs/registry.d.ts +33 -2
  35. package/dist/runtime/jobs/registry.d.ts.map +1 -1
  36. package/dist/runtime/jobs/registry.js +37 -0
  37. package/dist/runtime/jobs/registry.js.map +1 -1
  38. package/dist/runtime/query/executor.d.ts +28 -0
  39. package/dist/runtime/query/executor.d.ts.map +1 -1
  40. package/dist/runtime/query/executor.js +39 -1
  41. package/dist/runtime/query/executor.js.map +1 -1
  42. package/dist/runtime/query/file-evidence-context.d.ts.map +1 -1
  43. package/dist/runtime/query/file-evidence-context.js +159 -43
  44. package/dist/runtime/query/file-evidence-context.js.map +1 -1
  45. package/dist/runtime/query/file-evidence-replay.d.ts +260 -0
  46. package/dist/runtime/query/file-evidence-replay.d.ts.map +1 -0
  47. package/dist/runtime/query/file-evidence-replay.js +647 -0
  48. package/dist/runtime/query/file-evidence-replay.js.map +1 -0
  49. package/dist/runtime/query/file-evidence-seed.d.ts +50 -0
  50. package/dist/runtime/query/file-evidence-seed.d.ts.map +1 -0
  51. package/dist/runtime/query/file-evidence-seed.js +100 -0
  52. package/dist/runtime/query/file-evidence-seed.js.map +1 -0
  53. package/dist/runtime/query/index.d.ts.map +1 -1
  54. package/dist/runtime/query/index.js +94 -2
  55. package/dist/runtime/query/index.js.map +1 -1
  56. package/dist/runtime/query/iteration/index.d.ts +87 -9
  57. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  58. package/dist/runtime/query/iteration/index.js +193 -28
  59. package/dist/runtime/query/iteration/index.js.map +1 -1
  60. package/dist/runtime/query/iteration/phases/context.d.ts +10 -0
  61. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  62. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  63. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  64. package/dist/runtime/query/iteration/phases/tool-review.js +5 -1
  65. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  66. package/dist/runtime/query/plugin-hooks.d.ts +14 -0
  67. package/dist/runtime/query/plugin-hooks.d.ts.map +1 -1
  68. package/dist/runtime/query/plugin-hooks.js +18 -0
  69. package/dist/runtime/query/plugin-hooks.js.map +1 -1
  70. package/dist/runtime/query/repeat-call.d.ts +17 -4
  71. package/dist/runtime/query/repeat-call.d.ts.map +1 -1
  72. package/dist/runtime/query/repeat-call.js +26 -19
  73. package/dist/runtime/query/repeat-call.js.map +1 -1
  74. package/dist/runtime/query/steering.d.ts +11 -1
  75. package/dist/runtime/query/steering.d.ts.map +1 -1
  76. package/dist/runtime/query/steering.js +12 -1
  77. package/dist/runtime/query/steering.js.map +1 -1
  78. package/dist/runtime/query/tooling.d.ts +2 -0
  79. package/dist/runtime/query/tooling.d.ts.map +1 -1
  80. package/dist/runtime/query/tooling.js +1 -0
  81. package/dist/runtime/query/tooling.js.map +1 -1
  82. package/dist/scheduler/completion-inbox.d.ts +48 -2
  83. package/dist/scheduler/completion-inbox.d.ts.map +1 -1
  84. package/dist/scheduler/completion-inbox.js +102 -10
  85. package/dist/scheduler/completion-inbox.js.map +1 -1
  86. package/dist/tools/builtins/bash.d.ts.map +1 -1
  87. package/dist/tools/builtins/bash.js +4 -10
  88. package/dist/tools/builtins/bash.js.map +1 -1
  89. package/dist/tools/builtins/edit-apply.d.ts +126 -0
  90. package/dist/tools/builtins/edit-apply.d.ts.map +1 -0
  91. package/dist/tools/builtins/edit-apply.js +360 -0
  92. package/dist/tools/builtins/edit-apply.js.map +1 -0
  93. package/dist/tools/builtins/edit.d.ts +143 -1
  94. package/dist/tools/builtins/edit.d.ts.map +1 -1
  95. package/dist/tools/builtins/edit.js +37 -219
  96. package/dist/tools/builtins/edit.js.map +1 -1
  97. package/dist/tools/builtins/index.d.ts +1 -0
  98. package/dist/tools/builtins/index.d.ts.map +1 -1
  99. package/dist/tools/builtins/index.js +9 -3
  100. package/dist/tools/builtins/index.js.map +1 -1
  101. package/dist/tools/builtins/job.js +1 -1
  102. package/dist/tools/builtins/job.js.map +1 -1
  103. package/dist/tools/builtins/read-file.d.ts +2 -2
  104. package/dist/tools/builtins/read-file.d.ts.map +1 -1
  105. package/dist/tools/builtins/read-file.js +50 -65
  106. package/dist/tools/builtins/read-file.js.map +1 -1
  107. package/dist/tools/builtins/read-render.d.ts +56 -0
  108. package/dist/tools/builtins/read-render.d.ts.map +1 -0
  109. package/dist/tools/builtins/read-render.js +73 -0
  110. package/dist/tools/builtins/read-render.js.map +1 -0
  111. package/dist/tools/builtins/wait-for-job-bounds.d.ts +67 -0
  112. package/dist/tools/builtins/wait-for-job-bounds.d.ts.map +1 -0
  113. package/dist/tools/builtins/wait-for-job-bounds.js +108 -0
  114. package/dist/tools/builtins/wait-for-job-bounds.js.map +1 -0
  115. package/dist/tools/builtins/wait-for-job.d.ts +6 -0
  116. package/dist/tools/builtins/wait-for-job.d.ts.map +1 -0
  117. package/dist/tools/builtins/wait-for-job.js +162 -0
  118. package/dist/tools/builtins/wait-for-job.js.map +1 -0
  119. package/dist/tools/builtins/write-file.js +5 -0
  120. package/dist/tools/builtins/write-file.js.map +1 -1
  121. package/dist/tools/coordinator/index.d.ts.map +1 -1
  122. package/dist/tools/coordinator/index.js +1 -7
  123. package/dist/tools/coordinator/index.js.map +1 -1
  124. package/dist/tools/file-read-tracker.d.ts.map +1 -1
  125. package/dist/tools/file-read-tracker.js +88 -10
  126. package/dist/tools/file-read-tracker.js.map +1 -1
  127. package/dist/types/message/index.d.ts +1 -1
  128. package/dist/types/message/index.d.ts.map +1 -1
  129. package/dist/types/message/index.js +2 -0
  130. package/dist/types/message/index.js.map +1 -1
  131. package/dist/types/run/entity.d.ts +13 -0
  132. package/dist/types/run/entity.d.ts.map +1 -1
  133. package/dist/types/sandbox/index.d.ts +15 -14
  134. package/dist/types/sandbox/index.d.ts.map +1 -1
  135. package/dist/types/sandbox/index.js.map +1 -1
  136. package/dist/types/tool/index.d.ts +109 -0
  137. package/dist/types/tool/index.d.ts.map +1 -1
  138. package/dist/types/tool/index.js.map +1 -1
  139. package/dist/utils/env.d.ts +19 -0
  140. package/dist/utils/env.d.ts.map +1 -0
  141. package/dist/utils/env.js +25 -0
  142. package/dist/utils/env.js.map +1 -0
  143. package/package.json +1 -1
  144. package/src/connector/mcp/adapter.ts +20 -6
  145. package/src/manager/run/persistence.ts +12 -0
  146. package/src/public-runtime.ts +9 -1
  147. package/src/public-tools.ts +18 -0
  148. package/src/registry/tool/execute.ts +2 -4
  149. package/src/registry/tool/portable.ts +264 -0
  150. package/src/registry/tool/schema.ts +38 -8
  151. package/src/registry/toolset/catalog.ts +8 -9
  152. package/src/runtime/jobs/awaited-jobs.ts +271 -0
  153. package/src/runtime/jobs/registry.ts +50 -0
  154. package/src/runtime/query/executor.ts +49 -1
  155. package/src/runtime/query/file-evidence-context.ts +190 -46
  156. package/src/runtime/query/file-evidence-replay.ts +776 -0
  157. package/src/runtime/query/file-evidence-seed.ts +126 -0
  158. package/src/runtime/query/index.ts +104 -2
  159. package/src/runtime/query/iteration/index.ts +202 -28
  160. package/src/runtime/query/iteration/phases/context.ts +10 -0
  161. package/src/runtime/query/iteration/phases/tool-review.ts +4 -0
  162. package/src/runtime/query/plugin-hooks.ts +20 -0
  163. package/src/runtime/query/repeat-call.ts +28 -18
  164. package/src/runtime/query/steering.ts +11 -0
  165. package/src/runtime/query/tooling.ts +3 -0
  166. package/src/scheduler/completion-inbox.ts +105 -9
  167. package/src/tools/builtins/bash.ts +4 -10
  168. package/src/tools/builtins/edit-apply.ts +456 -0
  169. package/src/tools/builtins/edit.ts +39 -270
  170. package/src/tools/builtins/index.ts +9 -3
  171. package/src/tools/builtins/job.ts +1 -1
  172. package/src/tools/builtins/read-file.ts +56 -77
  173. package/src/tools/builtins/read-render.ts +104 -0
  174. package/src/tools/builtins/wait-for-job-bounds.ts +179 -0
  175. package/src/tools/builtins/wait-for-job.ts +184 -0
  176. package/src/tools/builtins/write-file.ts +5 -0
  177. package/src/tools/coordinator/index.ts +1 -7
  178. package/src/tools/file-read-tracker.ts +85 -7
  179. package/src/types/message/index.ts +2 -0
  180. package/src/types/run/entity.ts +14 -0
  181. package/src/types/sandbox/index.ts +15 -14
  182. package/src/types/tool/index.ts +104 -0
  183. package/src/utils/env.ts +23 -0
@@ -3,10 +3,22 @@ import { extname } from 'node:path';
3
3
  import { z } from 'zod';
4
4
  import { defineTool } from '../defineTool.js';
5
5
  import { resolveWithinAnyReal, toolRoots } from '../paths.js';
6
+ import { fingerprintContent } from './content-fingerprint.js';
7
+ import { renderNumberedRead } from './read-render.js';
6
8
  const inputSchema = z.object({
7
9
  path: z.string().describe('Path to the file to read (absolute or relative)'),
10
+ // A two-element ARRAY, not a `z.tuple`, and the distinction is the whole
11
+ // reason this comment exists. Both members carry the identical constraint,
12
+ // so the tuple bought nothing — and it rendered as the draft-07 tuple
13
+ // `items: [a, b]`, which a wire that validates against JSON Schema 2020-12
14
+ // refuses outright. It was the only tuple in the first-party tool surface,
15
+ // and it took down every other tool in the same request with it. The
16
+ // spelling below means the same thing to the model (`[10, 40]` either way)
17
+ // and to the parser, and reads identically in both dialects. See
18
+ // `registry/tool/portable.ts`.
8
19
  readRange: z
9
- .tuple([z.coerce.number().int().min(1), z.coerce.number().int().min(1)])
20
+ .array(z.coerce.number().int().min(1))
21
+ .length(2)
10
22
  .optional()
11
23
  .describe('Optional 1-indexed inclusive line range, e.g. [10, 40]. When provided it takes precedence over offset/limit.'),
12
24
  offset: z.coerce
@@ -53,22 +65,15 @@ export const ReadFileTool = defineTool({
53
65
  };
54
66
  }
55
67
  const content = buffer.toString('utf-8');
56
- const lines = content.split('\n');
57
- const { start, end } = resolveReadWindow(input, lines.length);
58
- const selectedLines = lines.slice(start, end);
59
- const numberedLines = selectedLines.map((line, i) => `${start + i + 1}\t${line}`).join('\n');
60
- // The WHOLE body, not the selected window: a later edit is checked
61
- // against the file, and a partial read must not fingerprint a
62
- // fragment as if it were the file.
63
- context.fileReadTracker?.recordRead(input.path, content);
64
- const partial = selectedLines.length < lines.length;
68
+ const rendered = renderNumberedRead(content, input);
69
+ recordObservedRead(context, input.path, content, rendered);
65
70
  return {
66
71
  success: true,
67
- output: numberedLines + partialViewNotice(start, selectedLines.length, lines.length),
72
+ output: rendered.output,
68
73
  data: {
69
- totalLines: lines.length,
70
- returnedLines: selectedLines.length,
71
- truncated: partial,
74
+ totalLines: rendered.totalLines,
75
+ returnedLines: rendered.returnedLines,
76
+ truncated: rendered.partial,
72
77
  path: input.path,
73
78
  sandboxed: true,
74
79
  },
@@ -88,24 +93,45 @@ export const ReadFileTool = defineTool({
88
93
  };
89
94
  }
90
95
  const content = buffer.toString('utf-8');
91
- const lines = content.split('\n');
92
- const { start, end } = resolveReadWindow(input, lines.length);
93
- const selectedLines = lines.slice(start, end);
94
- const numberedLines = selectedLines.map((line, i) => `${start + i + 1}\t${line}`).join('\n');
95
- context.fileReadTracker?.recordRead(filePath, content);
96
- const isPartial = selectedLines.length < lines.length;
96
+ const rendered = renderNumberedRead(content, input);
97
+ recordObservedRead(context, filePath, content, rendered);
97
98
  return {
98
99
  success: true,
99
- output: numberedLines + partialViewNotice(start, selectedLines.length, lines.length),
100
+ output: rendered.output,
100
101
  data: {
101
- totalLines: lines.length,
102
- returnedLines: selectedLines.length,
103
- truncated: isPartial,
102
+ totalLines: rendered.totalLines,
103
+ returnedLines: rendered.returnedLines,
104
+ truncated: rendered.partial,
104
105
  path: filePath,
105
106
  },
106
107
  };
107
108
  },
108
109
  });
110
+ /**
111
+ * Put this read on the observation ledger.
112
+ *
113
+ * Always the WHOLE body, not the selected window: a later edit is checked
114
+ * against the file, and a partial read must not fingerprint a fragment as if it
115
+ * were the file.
116
+ *
117
+ * A read that returned the file whole additionally witnesses itself, so the
118
+ * derived work context can reference the body without the model reading it
119
+ * again. The witness is the fingerprint of the RENDERING — this call's own
120
+ * `output`, byte for byte — because the rendering is what the receipt carries,
121
+ * and the body is in front of the model only while the receipt is still exactly
122
+ * that. A read whose window left any of the file out witnesses nothing: it
123
+ * shows a fragment, and the fingerprint of the file cannot say which one.
124
+ */
125
+ function recordObservedRead(context, key, content, rendered) {
126
+ const tracker = context.fileReadTracker;
127
+ if (!tracker)
128
+ return;
129
+ if (!rendered.partial && tracker.recordFullRead && context.toolUseId) {
130
+ tracker.recordFullRead(key, content, context.toolUseId, fingerprintContent(rendered.output));
131
+ return;
132
+ }
133
+ tracker.recordRead(key, content);
134
+ }
109
135
  function describeStructuredBinaryRead(path, buffer) {
110
136
  const ext = extname(path).toLowerCase();
111
137
  if (ext === '.docx')
@@ -130,45 +156,4 @@ function buildStructuredBinaryGuidance(path, format, extractor) {
130
156
  'If extraction fails, report the exact filename and extraction error instead of claiming the attachment is unavailable.',
131
157
  ].join('\n');
132
158
  }
133
- /**
134
- * Lines returned when the caller specifies no window.
135
- *
136
- * Chosen to cover the overwhelming majority of source files whole while
137
- * bounding the pathological case.
138
- */
139
- const DEFAULT_READ_LINES = 2000;
140
- /**
141
- * Tell the model, explicitly, when it is looking at a window rather than
142
- * the file.
143
- *
144
- * Without this a truncated read is indistinguishable from a short file, and
145
- * the agent reasons about a fragment as if it were the whole thing — the
146
- * most expensive silent failure a read tool can have. The notice names the
147
- * exact next call rather than describing it.
148
- */
149
- function partialViewNotice(start, returned, total) {
150
- if (returned >= total)
151
- return '';
152
- const shownTo = start + returned;
153
- return [
154
- '',
155
- '',
156
- `[PARTIAL view — lines ${start + 1}-${shownTo} of ${total}.`,
157
- `Continue with read({ offset: ${shownTo}, limit: N }), or narrow with grep.]`,
158
- ].join('\n');
159
- }
160
- function resolveReadWindow(input, totalLines) {
161
- if (input.readRange) {
162
- const [first, last] = input.readRange;
163
- const start = Math.max(0, first - 1);
164
- const end = Math.min(totalLines, Math.max(start, last));
165
- return { start, end };
166
- }
167
- const start = Math.max(0, input.offset ?? 0);
168
- // A bare `read({ path })` used to return the entire file, so a 2 MB
169
- // lockfile became ~500k tokens in one tool_result. Default to a window
170
- // and say so in the output; the model asks for more when it needs it.
171
- const end = input.limit ? start + input.limit : Math.min(totalLines, start + DEFAULT_READ_LINES);
172
- return { start, end };
173
- }
174
159
  //# sourceMappingURL=read-file.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"read-file.js","sourceRoot":"","sources":["../../../src/tools/builtins/read-file.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"read-file.js","sourceRoot":"","sources":["../../../src/tools/builtins/read-file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * How `read` turns a file's body into the text the model sees.
3
+ *
4
+ * Pulled out of the tool for the reason `edit-apply` was: a second caller —
5
+ * the resume seed, deciding whether a `read` receipt in history shows exactly
6
+ * the body it already believes the file had — has to produce byte-for-byte
7
+ * what the tool produced, and a parallel implementation of the numbering or
8
+ * the window arithmetic would silently stop agreeing with it.
9
+ *
10
+ * Pure by construction: no filesystem access, no `ToolContext`.
11
+ */
12
+ /**
13
+ * Lines returned when the caller specifies no window.
14
+ *
15
+ * Chosen to cover the overwhelming majority of source files whole while
16
+ * bounding the pathological case.
17
+ */
18
+ export declare const DEFAULT_READ_LINES = 2000;
19
+ /** The window fields of `read`'s input; the path plays no part in rendering. */
20
+ export interface ReadWindowRequest {
21
+ /**
22
+ * `[start, end]`, 1-indexed inclusive.
23
+ *
24
+ * Typed as a number array rather than a pair because the tool's schema
25
+ * pins the length at two with `.length(2)` instead of a `z.tuple` — a
26
+ * tuple renders as draft-07 `items: [a, b]`, which a 2020-12 wire refuses.
27
+ * The parse still rejects any other length, so a caller reaching here has
28
+ * two numbers; `resolveReadWindow` reads them defensively anyway, because
29
+ * this interface is also implemented by hand elsewhere in the kernel.
30
+ */
31
+ readonly readRange?: readonly number[];
32
+ readonly offset?: number;
33
+ readonly limit?: number;
34
+ }
35
+ export interface RenderedRead {
36
+ /** Exactly what `read` returns as its output for this body and window. */
37
+ readonly output: string;
38
+ readonly totalLines: number;
39
+ readonly returnedLines: number;
40
+ /** Whether the window left any of the file out, which is what adds the notice. */
41
+ readonly partial: boolean;
42
+ }
43
+ /**
44
+ * Render `content` the way `read` renders it.
45
+ *
46
+ * The numbering is what makes this reversible enough to compare against: every
47
+ * line goes out behind its own `${n}\t`, so two different bodies cannot render
48
+ * to one string, and the partial-view notice below — whose lines carry no such
49
+ * prefix — cannot be mistaken for part of a body.
50
+ */
51
+ export declare function renderNumberedRead(content: string, input: ReadWindowRequest): RenderedRead;
52
+ export declare function resolveReadWindow(input: ReadWindowRequest, totalLines: number): {
53
+ start: number;
54
+ end: number;
55
+ };
56
+ //# sourceMappingURL=read-render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-render.d.ts","sourceRoot":"","sources":["../../../src/tools/builtins/read-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAA;AAEtC,gFAAgF;AAChF,MAAM,WAAW,iBAAiB;IACjC;;;;;;;;;OASG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,YAAY;IAC5B,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,kFAAkF;IAClF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAW1F;AAsBD,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,iBAAiB,EACxB,UAAU,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAahC"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * How `read` turns a file's body into the text the model sees.
3
+ *
4
+ * Pulled out of the tool for the reason `edit-apply` was: a second caller —
5
+ * the resume seed, deciding whether a `read` receipt in history shows exactly
6
+ * the body it already believes the file had — has to produce byte-for-byte
7
+ * what the tool produced, and a parallel implementation of the numbering or
8
+ * the window arithmetic would silently stop agreeing with it.
9
+ *
10
+ * Pure by construction: no filesystem access, no `ToolContext`.
11
+ */
12
+ /**
13
+ * Lines returned when the caller specifies no window.
14
+ *
15
+ * Chosen to cover the overwhelming majority of source files whole while
16
+ * bounding the pathological case.
17
+ */
18
+ export const DEFAULT_READ_LINES = 2000;
19
+ /**
20
+ * Render `content` the way `read` renders it.
21
+ *
22
+ * The numbering is what makes this reversible enough to compare against: every
23
+ * line goes out behind its own `${n}\t`, so two different bodies cannot render
24
+ * to one string, and the partial-view notice below — whose lines carry no such
25
+ * prefix — cannot be mistaken for part of a body.
26
+ */
27
+ export function renderNumberedRead(content, input) {
28
+ const lines = content.split('\n');
29
+ const { start, end } = resolveReadWindow(input, lines.length);
30
+ const selected = lines.slice(start, end);
31
+ const numbered = selected.map((line, i) => `${start + i + 1}\t${line}`).join('\n');
32
+ return {
33
+ output: numbered + partialViewNotice(start, selected.length, lines.length),
34
+ totalLines: lines.length,
35
+ returnedLines: selected.length,
36
+ partial: selected.length < lines.length,
37
+ };
38
+ }
39
+ /**
40
+ * Tell the model, explicitly, when it is looking at a window rather than
41
+ * the file.
42
+ *
43
+ * Without this a truncated read is indistinguishable from a short file, and
44
+ * the agent reasons about a fragment as if it were the whole thing — the
45
+ * most expensive silent failure a read tool can have. The notice names the
46
+ * exact next call rather than describing it.
47
+ */
48
+ function partialViewNotice(start, returned, total) {
49
+ if (returned >= total)
50
+ return '';
51
+ const shownTo = start + returned;
52
+ return [
53
+ '',
54
+ '',
55
+ `[PARTIAL view — lines ${start + 1}-${shownTo} of ${total}.`,
56
+ `Continue with read({ offset: ${shownTo}, limit: N }), or narrow with grep.]`,
57
+ ].join('\n');
58
+ }
59
+ export function resolveReadWindow(input, totalLines) {
60
+ const [first, last] = input.readRange ?? [];
61
+ if (first !== undefined && last !== undefined) {
62
+ const start = Math.max(0, first - 1);
63
+ const end = Math.min(totalLines, Math.max(start, last));
64
+ return { start, end };
65
+ }
66
+ const start = Math.max(0, input.offset ?? 0);
67
+ // A bare `read({ path })` used to return the entire file, so a 2 MB
68
+ // lockfile became ~500k tokens in one tool_result. Default to a window
69
+ // and say so in the output; the model asks for more when it needs it.
70
+ const end = input.limit ? start + input.limit : Math.min(totalLines, start + DEFAULT_READ_LINES);
71
+ return { start, end };
72
+ }
73
+ //# sourceMappingURL=read-render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-render.js","sourceRoot":"","sources":["../../../src/tools/builtins/read-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAA;AA4BtC;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,KAAwB;IAC3E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACjC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IAC7D,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACxC,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAClF,OAAO;QACN,MAAM,EAAE,QAAQ,GAAG,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;QAC1E,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,aAAa,EAAE,QAAQ,CAAC,MAAM;QAC9B,OAAO,EAAE,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;KACvC,CAAA;AACF,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,iBAAiB,CAAC,KAAa,EAAE,QAAgB,EAAE,KAAa;IACxE,IAAI,QAAQ,IAAI,KAAK;QAAE,OAAO,EAAE,CAAA;IAChC,MAAM,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAA;IAChC,OAAO;QACN,EAAE;QACF,EAAE;QACF,yBAAyB,KAAK,GAAG,CAAC,IAAI,OAAO,OAAO,KAAK,GAAG;QAC5D,gCAAgC,OAAO,sCAAsC;KAC7E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACb,CAAC;AAED,MAAM,UAAU,iBAAiB,CAChC,KAAwB,EACxB,UAAkB;IAElB,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC,SAAS,IAAI,EAAE,CAAA;IAC3C,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;QACvD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAA;IACtB,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAA;IAC5C,oEAAoE;IACpE,uEAAuE;IACvE,sEAAsE;IACtE,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,GAAG,kBAAkB,CAAC,CAAA;IAChG,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAA;AACtB,CAAC"}
@@ -0,0 +1,67 @@
1
+ import type { BackgroundJobRegistryRef } from '../../types/tool/index.js';
2
+ /**
3
+ * Waiting on a background job, bounded by two different questions — the
4
+ * shell-job counterpart to `waitForTaskWithBounds`
5
+ * (`../coordinator/wait-with-idle-bound.ts`), which this mirrors.
6
+ *
7
+ * A delegated agent task reports its own progress through
8
+ * `TaskScheduler.onTaskProgress`. A shell job has no such channel: the only
9
+ * signal it ever produces is bytes on stdout/stderr. So where the task
10
+ * version resets its idle clock on a progress EVENT, this one resets it on
11
+ * OBSERVED OUTPUT GROWTH — read on every tick, compared against the last
12
+ * tick's offset. A tick that finds nothing new is not progress; treating it
13
+ * as progress would make the idle bound unable to fire for a wedged job at
14
+ * all, which is the exact failure this exists to catch.
15
+ *
16
+ * - the **run bound** counts elapsed time and is never refreshed. It
17
+ * exists for a job that stays busy forever (a server, a stuck build).
18
+ * - the **idle bound** counts time since output last grew, and resets
19
+ * whenever it does. It exists for a job that stopped producing anything
20
+ * without exiting.
21
+ *
22
+ * Neither bound cancels the job. A wait that ran out is a statement about
23
+ * the WAITER, not the work — the job keeps running, and its output is still
24
+ * there to read with `job` or a later `wait_for_job` call.
25
+ */
26
+ export interface JobWaitOptions {
27
+ /** Elapsed-time ceiling, never refreshed. */
28
+ readonly runMs: number;
29
+ /**
30
+ * Time-without-new-output ceiling, refreshed whenever `read` returns
31
+ * more than it did last tick. Omit to bound by the run clock alone.
32
+ */
33
+ readonly idleMs?: number;
34
+ /** Resume from here rather than the start of what the job has retained. */
35
+ readonly fromOffset?: number;
36
+ /** Stop preempts a wait that has not resolved yet; the job is untouched. */
37
+ readonly signal?: AbortSignal;
38
+ }
39
+ interface JobWaitProgress {
40
+ readonly output: string;
41
+ readonly nextOffset: number;
42
+ readonly droppedBytes: number;
43
+ }
44
+ export type JobWaitOutcome = ({
45
+ readonly kind: 'exited';
46
+ readonly status: string;
47
+ readonly exitCode?: number;
48
+ } & JobWaitProgress) | ({
49
+ readonly kind: 'timeout';
50
+ /** Which clock ran out. */
51
+ readonly cause: 'idle' | 'run';
52
+ readonly elapsedMs: number;
53
+ } & JobWaitProgress);
54
+ /**
55
+ * Await a job under both bounds, accumulating its output as it goes.
56
+ *
57
+ * Returns the output gathered so far either way: a completed wait has all
58
+ * of it, and a timed-out one has everything read up to the moment it gave
59
+ * up, so the caller never has to throw away a partial answer.
60
+ */
61
+ export declare function waitForJobWithBounds(jobs: Pick<BackgroundJobRegistryRef, 'read' | 'waitForExit'>, id: string, options: JobWaitOptions, now?: () => number): Promise<JobWaitOutcome>;
62
+ /** What to tell the model, in the words that fit what actually happened. */
63
+ export declare function describeJobWaitTimeout(id: string, outcome: Extract<JobWaitOutcome, {
64
+ kind: 'timeout';
65
+ }>): string;
66
+ export {};
67
+ //# sourceMappingURL=wait-for-job-bounds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait-for-job-bounds.d.ts","sourceRoot":"","sources":["../../../src/tools/builtins/wait-for-job-bounds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AAEzE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,cAAc;IAC9B,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC7B;AAED,UAAU,eAAe;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,MAAM,cAAc,GACvB,CAAC;IACD,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CACzB,GAAG,eAAe,CAAC,GACpB,CAAC;IACD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAAA;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CACzB,GAAG,eAAe,CAAC,CAAA;AAYvB;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACzC,IAAI,EAAE,IAAI,CAAC,wBAAwB,EAAE,MAAM,GAAG,aAAa,CAAC,EAC5D,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,MAAM,MAAiB,GAC1B,OAAO,CAAC,cAAc,CAAC,CAoFzB;AAED,4EAA4E;AAC5E,wBAAgB,sBAAsB,CACrC,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,GACnD,MAAM,CAOR"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * How often the bounds are checked, and how often output is drained.
3
+ *
4
+ * Coarse on purpose, same reasoning as the task version's own interval:
5
+ * both bounds are measured in minutes, so a second of latency noticing
6
+ * either one is irrelevant, and this is an internal timer, not a model
7
+ * turn — it costs nothing external no matter how often it fires.
8
+ */
9
+ const POLL_INTERVAL_MS = 1_000;
10
+ /**
11
+ * Await a job under both bounds, accumulating its output as it goes.
12
+ *
13
+ * Returns the output gathered so far either way: a completed wait has all
14
+ * of it, and a timed-out one has everything read up to the moment it gave
15
+ * up, so the caller never has to throw away a partial answer.
16
+ */
17
+ export async function waitForJobWithBounds(jobs, id, options, now = Date.now) {
18
+ if (!jobs.waitForExit) {
19
+ throw new Error('This background job registry cannot wait for a job to exit.');
20
+ }
21
+ const waitForExit = jobs.waitForExit.bind(jobs);
22
+ const startedAt = now();
23
+ let lastProgressAt = startedAt;
24
+ let cursor = options.fromOffset ?? 0;
25
+ let output = '';
26
+ let droppedBytes = 0;
27
+ let settled = false;
28
+ /** Read whatever is new since `cursor`, and count it as progress if it is. */
29
+ const drain = () => {
30
+ const chunk = jobs.read(id, { fromOffset: cursor });
31
+ if (chunk.droppedBytes > 0)
32
+ droppedBytes += chunk.droppedBytes;
33
+ if (chunk.nextOffset > cursor)
34
+ lastProgressAt = now();
35
+ cursor = chunk.nextOffset;
36
+ if (chunk.chunk)
37
+ output += chunk.chunk;
38
+ };
39
+ try {
40
+ const exited = waitForExit(id, { signal: options.signal }).then((job) => {
41
+ // One last read: the job can exit between ticks, and the bytes
42
+ // it wrote in its final moment are exactly the ones a caller
43
+ // most wants — the error, the summary line, the exit trace.
44
+ drain();
45
+ return {
46
+ kind: 'exited',
47
+ status: job.status,
48
+ ...(job.exitCode === undefined ? {} : { exitCode: job.exitCode }),
49
+ output,
50
+ nextOffset: cursor,
51
+ droppedBytes,
52
+ };
53
+ });
54
+ const expiry = new Promise((resolve) => {
55
+ // Polled rather than scheduled, for the same reason the task
56
+ // version is: the idle deadline MOVES on every byte of new
57
+ // output, and a timer armed for it would have to be cleared and
58
+ // rearmed on every tick that mattered.
59
+ const tick = setInterval(() => {
60
+ if (settled)
61
+ return;
62
+ drain();
63
+ const elapsed = now() - startedAt;
64
+ if (elapsed >= options.runMs) {
65
+ clearInterval(tick);
66
+ resolve({
67
+ kind: 'timeout',
68
+ cause: 'run',
69
+ elapsedMs: elapsed,
70
+ output,
71
+ nextOffset: cursor,
72
+ droppedBytes,
73
+ });
74
+ return;
75
+ }
76
+ if (options.idleMs !== undefined) {
77
+ const quietFor = now() - lastProgressAt;
78
+ if (quietFor >= options.idleMs) {
79
+ clearInterval(tick);
80
+ resolve({
81
+ kind: 'timeout',
82
+ cause: 'idle',
83
+ elapsedMs: elapsed,
84
+ output,
85
+ nextOffset: cursor,
86
+ droppedBytes,
87
+ });
88
+ }
89
+ }
90
+ }, POLL_INTERVAL_MS);
91
+ tick.unref?.();
92
+ });
93
+ return await Promise.race([exited, expiry]);
94
+ }
95
+ finally {
96
+ settled = true;
97
+ }
98
+ }
99
+ /** What to tell the model, in the words that fit what actually happened. */
100
+ export function describeJobWaitTimeout(id, outcome) {
101
+ const seconds = Math.round(outcome.elapsedMs / 1000);
102
+ const resume = `call wait_for_job again, or job read with from_offset ${outcome.nextOffset}, to see what it does next`;
103
+ if (outcome.cause === 'idle') {
104
+ return `Job ${id} went quiet: no new output for a while, after ${seconds}s. It has not been stopped and may still be working — ${resume}.`;
105
+ }
106
+ return `Job ${id} has been running for ${seconds}s without finishing. It has not been stopped — ${resume}.`;
107
+ }
108
+ //# sourceMappingURL=wait-for-job-bounds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait-for-job-bounds.js","sourceRoot":"","sources":["../../../src/tools/builtins/wait-for-job-bounds.ts"],"names":[],"mappings":"AA2DA;;;;;;;GAOG;AACH,MAAM,gBAAgB,GAAG,KAAK,CAAA;AAE9B;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACzC,IAA4D,EAC5D,EAAU,EACV,OAAuB,EACvB,MAAoB,IAAI,CAAC,GAAG;IAE5B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAA;IAC/E,CAAC;IACD,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAE/C,MAAM,SAAS,GAAG,GAAG,EAAE,CAAA;IACvB,IAAI,cAAc,GAAG,SAAS,CAAA;IAC9B,IAAI,MAAM,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAA;IACpC,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,IAAI,YAAY,GAAG,CAAC,CAAA;IACpB,IAAI,OAAO,GAAG,KAAK,CAAA;IAEnB,8EAA8E;IAC9E,MAAM,KAAK,GAAG,GAAS,EAAE;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAA;QACnD,IAAI,KAAK,CAAC,YAAY,GAAG,CAAC;YAAE,YAAY,IAAI,KAAK,CAAC,YAAY,CAAA;QAC9D,IAAI,KAAK,CAAC,UAAU,GAAG,MAAM;YAAE,cAAc,GAAG,GAAG,EAAE,CAAA;QACrD,MAAM,GAAG,KAAK,CAAC,UAAU,CAAA;QACzB,IAAI,KAAK,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,KAAK,CAAA;IACvC,CAAC,CAAA;IAED,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAkB,EAAE;YACvF,+DAA+D;YAC/D,6DAA6D;YAC7D,4DAA4D;YAC5D,KAAK,EAAE,CAAA;YACP,OAAO;gBACN,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;gBACjE,MAAM;gBACN,UAAU,EAAE,MAAM;gBAClB,YAAY;aACZ,CAAA;QACF,CAAC,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,IAAI,OAAO,CAAiB,CAAC,OAAO,EAAE,EAAE;YACtD,6DAA6D;YAC7D,2DAA2D;YAC3D,gEAAgE;YAChE,uCAAuC;YACvC,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE;gBAC7B,IAAI,OAAO;oBAAE,OAAM;gBACnB,KAAK,EAAE,CAAA;gBACP,MAAM,OAAO,GAAG,GAAG,EAAE,GAAG,SAAS,CAAA;gBACjC,IAAI,OAAO,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;oBAC9B,aAAa,CAAC,IAAI,CAAC,CAAA;oBACnB,OAAO,CAAC;wBACP,IAAI,EAAE,SAAS;wBACf,KAAK,EAAE,KAAK;wBACZ,SAAS,EAAE,OAAO;wBAClB,MAAM;wBACN,UAAU,EAAE,MAAM;wBAClB,YAAY;qBACZ,CAAC,CAAA;oBACF,OAAM;gBACP,CAAC;gBACD,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBAClC,MAAM,QAAQ,GAAG,GAAG,EAAE,GAAG,cAAc,CAAA;oBACvC,IAAI,QAAQ,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;wBAChC,aAAa,CAAC,IAAI,CAAC,CAAA;wBACnB,OAAO,CAAC;4BACP,IAAI,EAAE,SAAS;4BACf,KAAK,EAAE,MAAM;4BACb,SAAS,EAAE,OAAO;4BAClB,MAAM;4BACN,UAAU,EAAE,MAAM;4BAClB,YAAY;yBACZ,CAAC,CAAA;oBACH,CAAC;gBACF,CAAC;YACF,CAAC,EAAE,gBAAgB,CAAC,CAInB;YAAC,IAA+B,CAAC,KAAK,EAAE,EAAE,CAAA;QAC5C,CAAC,CAAC,CAAA;QAEF,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC5C,CAAC;YAAS,CAAC;QACV,OAAO,GAAG,IAAI,CAAA;IACf,CAAC;AACF,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,sBAAsB,CACrC,EAAU,EACV,OAAqD;IAErD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAA;IACpD,MAAM,MAAM,GAAG,yDAAyD,OAAO,CAAC,UAAU,4BAA4B,CAAA;IACtH,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;QAC9B,OAAO,OAAO,EAAE,iDAAiD,OAAO,yDAAyD,MAAM,GAAG,CAAA;IAC3I,CAAC;IACD,OAAO,OAAO,EAAE,yBAAyB,OAAO,kDAAkD,MAAM,GAAG,CAAA;AAC5G,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare const WaitForJobTool: import("../../public-types.js").ToolDefinition<{
2
+ id: string;
3
+ timeout_ms?: number | undefined;
4
+ idle_timeout_ms?: number | undefined;
5
+ }>;
6
+ //# sourceMappingURL=wait-for-job.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait-for-job.d.ts","sourceRoot":"","sources":["../../../src/tools/builtins/wait-for-job.ts"],"names":[],"mappings":"AA2DA,eAAO,MAAM,cAAc;;;;EA4HzB,CAAA"}