zames_pro 2.70.0 → 2.72.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.
@@ -7,7 +7,7 @@
7
7
  // theme palette (src/theme.ts) with the DejaVu Sans Mono font that the
8
8
  // container actually ships, then screenshots it with headless Chromium.
9
9
  //
10
- // Run: node scripts/render-demo.mjs
10
+ // Run: npm run render-demo (tsx scripts/render-demo.mts)
11
11
  //
12
12
  // Isolation: chromium.launch() uses a THROWAWAY profile, never ~/.zames/profile
13
13
  // (see AGENTS.md — never touch the live agent's browser/profile).
@@ -33,9 +33,9 @@ const C = {
33
33
  toggleOn: '#6fd0b0',
34
34
  }
35
35
 
36
- const esc = (s) =>
36
+ const esc = (s: unknown): string =>
37
37
  String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
38
- const span = (color, text, bold = false) =>
38
+ const span = (color: string, text: string, bold = false): string =>
39
39
  '<span style="color:' +
40
40
  color +
41
41
  (bold ? ';font-weight:700' : '') +
@@ -44,13 +44,18 @@ const span = (color, text, bold = false) =>
44
44
  '</span>'
45
45
 
46
46
  // One rendered session, line by line (mirrors the real banner + answer flow).
47
- const lines = []
48
- const push = (html) => lines.push('<div class="l">' + html + '</div>')
47
+ const lines: string[] = []
48
+ const push = (html: string): void => {
49
+ lines.push('<div class="l">' + html + '</div>')
50
+ }
49
51
  const blank = () => push('&nbsp;')
50
52
 
51
53
  push(span(C.system, 'Working directory: ') + span(C.dir, '/home/dev/zames_pro'))
52
54
  push(span(C.system, 'Version: ') + span(C.user, '2.64.1'))
53
- push(span(C.system, 'Transcript: ') + span(C.dim, '~/.zames/logs/zames_pro-2026-10-07.log'))
55
+ push(
56
+ span(C.system, 'Transcript: ') +
57
+ span(C.dim, '~/.zames/logs/zames_pro-2026-10-07.log'),
58
+ )
54
59
  blank()
55
60
  push(
56
61
  span(
@@ -78,11 +83,7 @@ push(
78
83
  span(C.user, 'Show the version from package.json.'),
79
84
  )
80
85
  blank()
81
- push(
82
- span(C.tool, '🔧 Read') +
83
- ' ' +
84
- span(C.dim, '{"path":"package.json"}'),
85
- )
86
+ push(span(C.tool, '🔧 Read') + ' ' + span(C.dim, '{"path":"package.json"}'))
86
87
  push(
87
88
  span(C.toolResult, ' → ') +
88
89
  span(
@@ -42,13 +42,19 @@ fs.mkdirSync(WORK, { recursive: true })
42
42
 
43
43
  // --- project modules (dynamic: they read HOME at import) --------------------
44
44
  const { DeepSeekBrowser } = await import('../src/browser.ts')
45
- const { createTools } = await import('../src/tools.ts')
45
+ const { createTools, filterToolsForReadOnly } = await import('../src/tools.ts')
46
46
  const { runAgentLoop } = await import('../src/agent-loop.ts')
47
+ const { createSubagentRunner } = await import('../src/subagent.ts')
47
48
  const { loadConfig } = await import('../src/config.ts')
48
49
  const { Transcript } = await import('../src/transcript.ts')
49
50
 
50
- const results = []
51
- const record = (name, ok, note) => {
51
+ interface SmokeResult {
52
+ name: string
53
+ ok: boolean
54
+ note?: string
55
+ }
56
+ const results: SmokeResult[] = []
57
+ const record = (name: string, ok: boolean, note?: string): void => {
52
58
  results.push({ name, ok, note })
53
59
  console.log((ok ? 'PASS ' : 'FAIL ') + name + (note ? ' — ' + note : ''))
54
60
  }
@@ -148,14 +154,89 @@ async function main() {
148
154
  askDeadlineMs: cfg.browser.askDeadlineMs,
149
155
  maxAfterToolRetries: cfg.browser.maxAfterToolRetries,
150
156
  })
151
- record('follow-up answered', outC.trim().length > 0, JSON.stringify(outC.slice(0, 80)))
157
+ record(
158
+ 'follow-up answered',
159
+ outC.trim().length > 0,
160
+ JSON.stringify(outC.slice(0, 80)),
161
+ )
162
+ const onSubagent = createSubagentRunner({
163
+ browser,
164
+ workdir: WORK,
165
+ locale: 'ru',
166
+ runAgentLoop,
167
+ buildTools: (readOnly) => {
168
+ const base = createTools(WORK, {})
169
+ return readOnly ? filterToolsForReadOnly(base) : base
170
+ },
171
+ transcript,
172
+ maxSubagents: 2,
173
+ askDeadlineMs: cfg.browser.askDeadlineMs,
174
+ maxAfterToolRetries: cfg.browser.maxAfterToolRetries,
175
+ })
176
+
177
+ // Scenario D — subagents (N36): the model delegates via Task; the runner
178
+ // opens a separate chat, returns only the report, and restores the parent
179
+ // chat. Requires browser.subagents (off by default).
180
+ const subTools = createTools(WORK, { subagents: true })
181
+ const outD = await runAgentLoop({
182
+ browser,
183
+ tools: subTools,
184
+ task:
185
+ 'Use the Task tool with subagent_type "explore" to find which word is written in the file smoke.txt. ' +
186
+ 'prompt the subagent in a self-contained way. Then, based on its report, call respond with that word.',
187
+ workdir: WORK,
188
+ maxIterations: 20,
189
+ freshChat: true,
190
+ sendSystemPrompt: true,
191
+ transcript,
192
+ onSubagent,
193
+ onToolCall: (n) => console.log(' tool: ' + n),
194
+ onAssistantMessage: (m) => console.log(' answer: ' + m),
195
+ onWarning: (m) => console.log(' warn: ' + m),
196
+ locale: 'ru',
197
+ askDeadlineMs: cfg.browser.askDeadlineMs,
198
+ maxAfterToolRetries: cfg.browser.maxAfterToolRetries,
199
+ })
200
+ record(
201
+ 'subagent: parent used the report',
202
+ /HELLO_SMOKE/i.test(outD),
203
+ JSON.stringify(outD.slice(0, 120)),
204
+ )
205
+
206
+ // Scenario E — background Bash + BashOutput (N33): start a process that
207
+ // keeps running, poll its output, then kill it.
208
+ const outE = await runAgentLoop({
209
+ browser,
210
+ tools,
211
+ task:
212
+ 'Do exactly this, then report: (1) Start the Bash command ' +
213
+ '`echo BG_MARKER_7 && sleep 120` in the BACKGROUND (run_in_background=true). ' +
214
+ '(2) Poll it once with BashOutput. (3) Kill it with BashOutput kill=true. ' +
215
+ 'Then call respond with one short line containing BG_MARKER_7.',
216
+ workdir: WORK,
217
+ maxIterations: 20,
218
+ freshChat: true,
219
+ sendSystemPrompt: true,
220
+ transcript,
221
+ onToolCall: (n) => console.log(' tool: ' + n),
222
+ onAssistantMessage: (m) => console.log(' answer: ' + m),
223
+ onWarning: (m) => console.log(' warn: ' + m),
224
+ locale: 'ru',
225
+ askDeadlineMs: cfg.browser.askDeadlineMs,
226
+ maxAfterToolRetries: cfg.browser.maxAfterToolRetries,
227
+ })
228
+ record(
229
+ 'background bash: started, polled and killed',
230
+ /BG_MARKER_7/.test(outE),
231
+ JSON.stringify(outE.slice(0, 120)),
232
+ )
152
233
  }
153
234
 
154
235
  let failed = false
155
236
  try {
156
237
  await main()
157
238
  } catch (e) {
158
- record('run', false, e.message)
239
+ record('run', false, (e as Error).message)
159
240
  failed = true
160
241
  } finally {
161
242
  await browser.close().catch(() => {})
File without changes