zelari-code 1.46.1 → 1.47.1

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 (43) hide show
  1. package/dist/cli/app.js +4 -1
  2. package/dist/cli/app.js.map +1 -1
  3. package/dist/cli/budget/tokenBudget.js +14 -12
  4. package/dist/cli/budget/tokenBudget.js.map +1 -1
  5. package/dist/cli/hooks/conversationContext.js +7 -4
  6. package/dist/cli/hooks/conversationContext.js.map +1 -1
  7. package/dist/cli/hooks/observationStore.js +219 -0
  8. package/dist/cli/hooks/observationStore.js.map +1 -0
  9. package/dist/cli/hooks/observationStore.test.js +135 -0
  10. package/dist/cli/hooks/observationStore.test.js.map +1 -0
  11. package/dist/cli/hooks/sessionSurface.js +171 -0
  12. package/dist/cli/hooks/sessionSurface.js.map +1 -0
  13. package/dist/cli/hooks/sessionSurface.test.js +112 -0
  14. package/dist/cli/hooks/sessionSurface.test.js.map +1 -0
  15. package/dist/cli/hooks/useChatTurn.js +25 -0
  16. package/dist/cli/hooks/useChatTurn.js.map +1 -1
  17. package/dist/cli/hooks/useSession.js +5 -3
  18. package/dist/cli/hooks/useSession.js.map +1 -1
  19. package/dist/cli/main.bundled.js +1680 -808
  20. package/dist/cli/main.bundled.js.map +4 -4
  21. package/dist/cli/metrics.js +4 -0
  22. package/dist/cli/metrics.js.map +1 -1
  23. package/dist/cli/provider/capabilities.js +53 -0
  24. package/dist/cli/provider/capabilities.js.map +1 -0
  25. package/dist/cli/provider/capabilities.test.js +46 -0
  26. package/dist/cli/provider/capabilities.test.js.map +1 -0
  27. package/dist/cli/provider/openai-compatible.js +2 -1
  28. package/dist/cli/provider/openai-compatible.js.map +1 -1
  29. package/dist/cli/toolRegistry.js +28 -0
  30. package/dist/cli/toolRegistry.js.map +1 -1
  31. package/dist/cli/tools/observeBatch.js +254 -0
  32. package/dist/cli/tools/observeBatch.js.map +1 -0
  33. package/dist/cli/tools/observeBatch.test.js +329 -0
  34. package/dist/cli/tools/observeBatch.test.js.map +1 -0
  35. package/dist/cli/tools/retrieveObservation.js +82 -0
  36. package/dist/cli/tools/retrieveObservation.js.map +1 -0
  37. package/dist/cli/utils/contextGrowthSummary.js +55 -0
  38. package/dist/cli/utils/contextGrowthSummary.js.map +1 -0
  39. package/dist/cli/utils/contextGrowthSummary.test.js +74 -0
  40. package/dist/cli/utils/contextGrowthSummary.test.js.map +1 -0
  41. package/dist/cli/utils/doctor.js +26 -0
  42. package/dist/cli/utils/doctor.js.map +1 -1
  43. package/package.json +2 -2
@@ -0,0 +1,254 @@
1
+ /**
2
+ * observe_batch — N independent read-only observations in ONE round-trip.
3
+ * 2026-07 context-growth plan, Fase 1 ("micro Code Mode").
4
+ *
5
+ * Instead of 3+ sequential read_file/grep_content/list_files calls (each
6
+ * dumping a full payload into the context), the model declares a batch of
7
+ * independent observe operations; this tool executes them in parallel
8
+ * (chunked, like AgentHarness.executePendingTools) and returns, by default,
9
+ * a DETERMINISTIC evidence projection per op (counts, ranges, top matches)
10
+ * built from the Fase-0 Ground Truth meta — zero LLM summarization involved.
11
+ *
12
+ * Guarantees:
13
+ * - failures are isolated per operation (batch never throws for op errors);
14
+ * - every op's args are validated against the underlying tool's zod schema
15
+ * (defaults applied) before execution;
16
+ * - reuses the sandbox + permission + result-cache wrapped tools from
17
+ * toolRegistry, so path checks/audit/dedup come for free;
18
+ * - aggregate output cap with EXPLICIT truncation markers (never silent);
19
+ * - evidence projection is pure: same (args, value, meta) → byte-identical
20
+ * JSON (prefix-cache safe, Fase 2 will rely on this).
21
+ *
22
+ * Env: ZELARI_OBSERVE_BATCH=0 disables registration (A/B vs Fase M baseline);
23
+ * ZELARI_OBSERVE_OP_TIMEOUT_MS per-op timeout (default 15000);
24
+ * ZELARI_MAX_PARALLEL_TOOLS chunk width (default 6, shared with harness).
25
+ */
26
+ import { z } from 'zod';
27
+ import { typedOk } from '@zelari/core/harness/tools/toolTypes';
28
+ export const MAX_OPERATIONS = 8;
29
+ export const AGGREGATE_CAP_BYTES = 48 * 1024;
30
+ export const DEFAULT_PER_OP_TIMEOUT_MS = 15_000;
31
+ const TOP_MATCHES = 5;
32
+ const LIST_SAMPLE = 10;
33
+ /**
34
+ * Pure projection of a tool result onto compact evidence. Reads Fase-0 meta
35
+ * counts first, falls back to the value. Same inputs → byte-identical output.
36
+ */
37
+ export function projectEvidence(tool, parsedArgs, value, meta) {
38
+ switch (tool) {
39
+ case 'grep_content': {
40
+ const v = (value ?? {});
41
+ const ev = {
42
+ tool: 'grep_content',
43
+ pattern: typeof parsedArgs.pattern === 'string' ? parsedArgs.pattern : '',
44
+ matches: meta?.counts?.matches ?? v.totalMatches ?? v.matches?.length ?? 0,
45
+ top: (v.matches ?? [])
46
+ .slice(0, TOP_MATCHES)
47
+ .map((m) => `${m.relPath ?? '?'}:${m.line ?? '?'}`),
48
+ };
49
+ const fw = meta?.counts?.filesWalked ?? v.filesWalked;
50
+ if (fw !== undefined)
51
+ ev.filesWalked = fw;
52
+ if (meta?.truncated || v.truncated)
53
+ ev.truncated = true;
54
+ return ev;
55
+ }
56
+ case 'read_file': {
57
+ const v = (value ?? {});
58
+ const ev = {
59
+ tool: 'read_file',
60
+ path: typeof v.path === 'string' ? v.path : String(parsedArgs.path ?? ''),
61
+ totalLines: v.totalLines ?? -1,
62
+ readLines: { start: v.readLines?.start ?? -1, end: v.readLines?.end ?? -1 },
63
+ sizeBytes: v.sizeBytes ?? 0,
64
+ };
65
+ if (meta?.truncated)
66
+ ev.truncated = true;
67
+ return ev;
68
+ }
69
+ case 'list_files': {
70
+ const v = (value ?? {});
71
+ const ev = {
72
+ tool: 'list_files',
73
+ dir: typeof v.dir === 'string' ? v.dir : String(parsedArgs.path ?? ''),
74
+ entries: meta?.counts?.filesWalked ?? v.entries?.length ?? 0,
75
+ sample: (v.entries ?? [])
76
+ .slice(0, LIST_SAMPLE)
77
+ .map((e) => (e.type === 'directory' ? `${e.name}/` : String(e.name))),
78
+ };
79
+ if (meta?.truncated || v.truncated)
80
+ ev.truncated = true;
81
+ return ev;
82
+ }
83
+ }
84
+ }
85
+ // ---------------------------------------------------------------------------
86
+ // Schema
87
+ // ---------------------------------------------------------------------------
88
+ const OperationSchema = z.object({
89
+ /** Caller-chosen identifier, echoed in results (unique within the batch). */
90
+ id: z.string().min(1).max(64).regex(/^[A-Za-z0-9._-]+$/, 'id: only [A-Za-z0-9._-] allowed'),
91
+ tool: z.enum(['read_file', 'grep_content', 'list_files']),
92
+ /** Args of the underlying tool; validated by that tool's own schema. */
93
+ args: z.record(z.string(), z.unknown()).optional(),
94
+ });
95
+ export const ObserveBatchArgsSchema = z.object({
96
+ operations: z
97
+ .array(OperationSchema)
98
+ .min(1, 'at least one operation required')
99
+ .max(MAX_OPERATIONS, `at most ${MAX_OPERATIONS} operations per batch`)
100
+ .refine((ops) => new Set(ops.map((o) => o.id)).size === ops.length, {
101
+ message: 'operation ids must be unique within the batch',
102
+ }),
103
+ /**
104
+ * 'evidence' (default): only the compact deterministic projection enters
105
+ * the context. 'raw': full payloads, under the aggregate byte cap.
106
+ */
107
+ resultMode: z.enum(['raw', 'evidence']).default('evidence'),
108
+ });
109
+ // ---------------------------------------------------------------------------
110
+ // Execution
111
+ // ---------------------------------------------------------------------------
112
+ const encoder = new TextEncoder();
113
+ function utf8Bytes(s) {
114
+ return encoder.encode(s).length;
115
+ }
116
+ function zodMessage(err) {
117
+ if (err instanceof z.ZodError)
118
+ return err.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');
119
+ return err instanceof Error ? err.message : String(err);
120
+ }
121
+ async function runOperation(op, idx, ctx, deps, perOpTimeoutMs) {
122
+ const tool = deps.tools[op.tool];
123
+ let parsed;
124
+ try {
125
+ parsed = tool.inputSchema.parse(op.args ?? {});
126
+ }
127
+ catch (err) {
128
+ return { idx, failure: { id: op.id, tool: op.tool, error: `invalid args: ${zodMessage(err)}` } };
129
+ }
130
+ const ac = new AbortController();
131
+ const onParentAbort = () => ac.abort();
132
+ if (ctx.signal.aborted)
133
+ return { idx, failure: { id: op.id, tool: op.tool, error: 'cancelled: parent signal aborted' } };
134
+ ctx.signal.addEventListener('abort', onParentAbort, { once: true });
135
+ let timer;
136
+ const started = Date.now();
137
+ try {
138
+ timer = setTimeout(() => ac.abort(), perOpTimeoutMs);
139
+ const execP = tool.execute(parsed, { ...ctx, signal: ac.signal });
140
+ execP.catch(() => { }); // a post-timeout AbortError must not become unhandled
141
+ const timeoutP = new Promise((_, reject) => {
142
+ timer = setTimeout(() => reject(new Error(`TIMEOUT after ${perOpTimeoutMs}ms`)), perOpTimeoutMs);
143
+ });
144
+ const result = await Promise.race([execP, timeoutP]);
145
+ if (!result.ok) {
146
+ return { idx, failure: { id: op.id, tool: op.tool, error: result.error } };
147
+ }
148
+ const meta = result.meta;
149
+ const evidence = projectEvidence(op.tool, parsed, result.value, meta);
150
+ const rawStr = JSON.stringify(result.value) ?? 'null';
151
+ return {
152
+ idx,
153
+ observation: {
154
+ id: op.id,
155
+ tool: op.tool,
156
+ status: meta?.status ?? 'unknown',
157
+ durationMs: Date.now() - started,
158
+ warnings: meta?.warnings,
159
+ truncated: meta?.truncated,
160
+ evidence,
161
+ raw: result.value,
162
+ rawBytes: utf8Bytes(rawStr),
163
+ },
164
+ };
165
+ }
166
+ catch (err) {
167
+ const msg = err instanceof Error ? err.message : String(err);
168
+ const error = /TIMEOUT/.test(msg) || Date.now() - started >= perOpTimeoutMs
169
+ ? `TIMEOUT after ${perOpTimeoutMs}ms`
170
+ : msg;
171
+ return { idx, failure: { id: op.id, tool: op.tool, error } };
172
+ }
173
+ finally {
174
+ if (timer !== undefined)
175
+ clearTimeout(timer);
176
+ ctx.signal.removeEventListener('abort', onParentAbort);
177
+ }
178
+ }
179
+ /** Build the observe_batch tool from the registry's safe wrapped tools. */
180
+ export function createObserveBatchTool(deps) {
181
+ return {
182
+ name: 'observe_batch',
183
+ description: 'Run multiple independent read-only observations (read_file, grep_content, list_files) in ONE round-trip. ' +
184
+ 'PREFER this over 3+ sequential read/grep/list calls when exploring multiple targets at once ' +
185
+ '(e.g. map a subsystem: list a dir + grep a symbol + read two line ranges). ' +
186
+ 'Default resultMode "evidence" keeps only compact deterministic evidence in context (counts, ranges, top matches); ' +
187
+ 'resultMode "raw" returns full payloads under an aggregate byte cap (truncation is explicit, never silent). ' +
188
+ 'Operations run in parallel and MUST be independent (no ordering between them); per-operation failures are ' +
189
+ 'isolated and reported in `failures`. Not for writes or ordered steps — use the single tools for those.',
190
+ permissions: ['read'],
191
+ timeoutMs: 60_000,
192
+ inputSchema: ObserveBatchArgsSchema,
193
+ execute: async (input, ctx) => {
194
+ const t0 = Date.now();
195
+ const maxParallel = Math.max(1, Number.parseInt(process.env.ZELARI_MAX_PARALLEL_TOOLS ?? '6', 10) || 6);
196
+ const perOpTimeout = Math.max(100, Number.parseInt(process.env.ZELARI_OBSERVE_OP_TIMEOUT_MS ?? String(DEFAULT_PER_OP_TIMEOUT_MS), 10) || DEFAULT_PER_OP_TIMEOUT_MS);
197
+ const outcomes = [];
198
+ const ops = input.operations;
199
+ for (let i = 0; i < ops.length; i += maxParallel) {
200
+ const chunk = ops.slice(i, i + maxParallel);
201
+ const results = await Promise.all(chunk.map((op, j) => runOperation(op, i + j, ctx, deps, perOpTimeout)));
202
+ outcomes.push(...results);
203
+ }
204
+ outcomes.sort((a, b) => a.idx - b.idx);
205
+ const observations = [];
206
+ const failures = [];
207
+ // Aggregate cap: raw payloads included in input order while the budget
208
+ // lasts; later ones get an explicit rawOmitted marker (never silent).
209
+ let budget = AGGREGATE_CAP_BYTES;
210
+ let truncated = false;
211
+ for (const o of outcomes) {
212
+ if ('failure' in o) {
213
+ failures.push(o.failure);
214
+ continue;
215
+ }
216
+ // Strip the transport-only raw fields: what enters the result entry
217
+ // (and therefore the context) is decided HERE, explicitly.
218
+ const { raw, rawBytes, ...rest } = o.observation;
219
+ const evBytes = utf8Bytes(JSON.stringify(rest.evidence) ?? 'null');
220
+ if (input.resultMode === 'raw' && !truncated && rawBytes <= budget) {
221
+ budget -= rawBytes;
222
+ observations.push({ ...rest, bytes: rawBytes, raw });
223
+ }
224
+ else if (input.resultMode === 'raw') {
225
+ truncated = true;
226
+ observations.push({ ...rest, bytes: evBytes, rawOmitted: true });
227
+ }
228
+ else {
229
+ observations.push({ ...rest, bytes: evBytes });
230
+ }
231
+ }
232
+ const totalBytes = observations.reduce((s, o) => s + o.bytes, 0);
233
+ const status = failures.length === 0 ? 'complete' : observations.length === 0 ? 'failed' : 'partial';
234
+ return typedOk({
235
+ resultMode: input.resultMode,
236
+ observations,
237
+ failures,
238
+ totals: {
239
+ ops: ops.length,
240
+ ok: observations.length,
241
+ failed: failures.length,
242
+ bytes: totalBytes,
243
+ wallMs: Date.now() - t0,
244
+ },
245
+ truncated,
246
+ }, {
247
+ status,
248
+ counts: { bytes: totalBytes },
249
+ ...(truncated ? { truncated: true } : {}),
250
+ });
251
+ },
252
+ };
253
+ }
254
+ //# sourceMappingURL=observeBatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observeBatch.js","sourceRoot":"","sources":["../../../src/cli/tools/observeBatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,329 @@
1
+ /**
2
+ * observe_batch — tests (2026-07 context-growth plan, Fase 1 acceptance).
3
+ *
4
+ * Covers: aggregation + input order, isolated failures, per-op args
5
+ * validation, schema limits (max ops, dup ids), evidence determinism,
6
+ * evidence/raw modes, aggregate cap with explicit truncation, per-op
7
+ * timeout, Ground Truth batch meta.
8
+ */
9
+ import { fileURLToPath } from 'node:url';
10
+ import path from 'node:path';
11
+ import { describe, it, expect, afterEach } from 'vitest';
12
+ import { z } from 'zod';
13
+ import { createObserveBatchTool, projectEvidence, ObserveBatchArgsSchema, AGGREGATE_CAP_BYTES, MAX_OPERATIONS, } from './observeBatch.js';
14
+ import { typedOk, typedErr } from '@zelari/core/harness/tools/toolTypes';
15
+ // Pin repo root: npm test --workspace=@zelari/core runs with cwd packages/core
16
+ // (same as the publish workflow). Do NOT use process.cwd() / path.resolve().
17
+ const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', '..');
18
+ function fakeCtx() {
19
+ return {
20
+ signal: new AbortController().signal,
21
+ cwd: '/tmp',
22
+ audit: () => { },
23
+ sessionId: 'test',
24
+ };
25
+ }
26
+ function sleep(ms) {
27
+ return new Promise((r) => setTimeout(r, ms));
28
+ }
29
+ function okGrepTool(behavior) {
30
+ return {
31
+ name: 'grep_content',
32
+ description: 'fake',
33
+ permissions: ['read'],
34
+ timeoutMs: 5000,
35
+ inputSchema: z.record(z.string(), z.unknown()),
36
+ execute: async (args) => {
37
+ const value = behavior
38
+ ? behavior(args)
39
+ : {
40
+ matches: [
41
+ { relPath: 'src/a.ts', line: 10, text: 'x' },
42
+ { relPath: 'src/b.ts', line: 22, text: 'y' },
43
+ ],
44
+ totalMatches: 2,
45
+ truncated: false,
46
+ };
47
+ return typedOk(value, { status: 'complete', counts: { matches: 2, filesWalked: 7 } });
48
+ },
49
+ };
50
+ }
51
+ const okReadTool = {
52
+ name: 'read_file',
53
+ description: 'fake',
54
+ permissions: ['read'],
55
+ timeoutMs: 5000,
56
+ inputSchema: z.record(z.string(), z.unknown()),
57
+ execute: async () => typedOk({ path: 'src/a.ts', content: 'line1\nline2', totalLines: 120, readLines: { start: 1, end: 2 }, sizeBytes: 4000 }, { status: 'complete', counts: { lines: 120, bytes: 4000 } }),
58
+ };
59
+ const okListTool = {
60
+ name: 'list_files',
61
+ description: 'fake',
62
+ permissions: ['read'],
63
+ timeoutMs: 5000,
64
+ inputSchema: z.record(z.string(), z.unknown()),
65
+ execute: async () => typedOk({ dir: '/tmp', entries: [{ name: 'src', type: 'directory' }, { name: 'a.ts', type: 'file' }], truncated: false }, { status: 'complete', counts: { filesWalked: 2 } }),
66
+ };
67
+ function deps(over = {}) {
68
+ return {
69
+ tools: {
70
+ read_file: okReadTool,
71
+ grep_content: okGrepTool(),
72
+ list_files: okListTool,
73
+ ...over,
74
+ },
75
+ };
76
+ }
77
+ async function run(depsArg, args) {
78
+ const tool = createObserveBatchTool(depsArg);
79
+ const parsed = tool.inputSchema.parse(args);
80
+ const res = await tool.execute(parsed, fakeCtx());
81
+ expect(res.ok).toBe(true);
82
+ return res.value;
83
+ }
84
+ function stripDynamic(result) {
85
+ const clone = JSON.parse(JSON.stringify(result));
86
+ for (const o of clone.observations)
87
+ delete o.durationMs;
88
+ delete clone.totals.wallMs;
89
+ return clone;
90
+ }
91
+ afterEach(() => {
92
+ delete process.env.ZELARI_OBSERVE_OP_TIMEOUT_MS;
93
+ });
94
+ describe('observe_batch schema', () => {
95
+ it('rejects more than MAX_OPERATIONS', () => {
96
+ const ops = Array.from({ length: MAX_OPERATIONS + 1 }, (_, i) => ({ id: `op${i}`, tool: 'read_file' }));
97
+ expect(() => ObserveBatchArgsSchema.parse({ operations: ops })).toThrow(/at most/);
98
+ });
99
+ it('rejects duplicate ids', () => {
100
+ expect(() => ObserveBatchArgsSchema.parse({ operations: [{ id: 'a', tool: 'read_file' }, { id: 'a', tool: 'list_files' }] })).toThrow(/unique/);
101
+ });
102
+ it('defaults resultMode to evidence and args to undefined', () => {
103
+ const parsed = ObserveBatchArgsSchema.parse({ operations: [{ id: 'a', tool: 'read_file' }] });
104
+ expect(parsed.resultMode).toBe('evidence');
105
+ });
106
+ });
107
+ describe('observe_batch execution', () => {
108
+ it('aggregates independent ops and preserves input order', async () => {
109
+ const slowFirst = {
110
+ ...okGrepTool(),
111
+ execute: async () => {
112
+ await sleep(60);
113
+ return typedOk({ matches: [], totalMatches: 0, truncated: false }, { status: 'complete', counts: { matches: 0 } });
114
+ },
115
+ };
116
+ const result = await run(deps({ grep_content: slowFirst }), {
117
+ operations: [
118
+ { id: 'first', tool: 'grep_content', args: { pattern: 'x' } },
119
+ { id: 'second', tool: 'read_file', args: { path: 'a.ts' } },
120
+ { id: 'third', tool: 'list_files' },
121
+ ],
122
+ });
123
+ expect(result.failures).toEqual([]);
124
+ expect(result.observations.map((o) => o.id)).toEqual(['first', 'second', 'third']);
125
+ expect(result.totals).toMatchObject({ ops: 3, ok: 3, failed: 0 });
126
+ expect(result.truncated).toBe(false);
127
+ });
128
+ it('isolates per-op failures (typedErr + throw) without failing the batch', async () => {
129
+ const boom = {
130
+ ...okGrepTool(),
131
+ execute: async () => typedErr('boom'),
132
+ };
133
+ const thrower = {
134
+ ...okReadTool,
135
+ execute: async () => {
136
+ throw new Error('kaboom');
137
+ },
138
+ };
139
+ const result = await run(deps({ grep_content: boom, read_file: thrower }), {
140
+ operations: [
141
+ { id: 'ok', tool: 'list_files' },
142
+ { id: 'err', tool: 'grep_content' },
143
+ { id: 'thr', tool: 'read_file' },
144
+ ],
145
+ });
146
+ expect(result.observations.map((o) => o.id)).toEqual(['ok']);
147
+ const errIds = result.failures.map((f) => f.id).sort();
148
+ expect(errIds).toEqual(['err', 'thr']);
149
+ expect(result.failures.find((f) => f.id === 'err')?.error).toContain('boom');
150
+ expect(result.totals).toMatchObject({ ops: 3, ok: 1, failed: 2 });
151
+ });
152
+ it('validates each op args against the underlying schema (defaults + rejection)', async () => {
153
+ const strict = {
154
+ ...okReadTool,
155
+ inputSchema: z.object({ path: z.string() }),
156
+ execute: async () => typedOk({ path: 'x', content: '', totalLines: 0, readLines: { start: 1, end: 1 }, sizeBytes: 0 }),
157
+ };
158
+ const result = await run(deps({ read_file: strict }), {
159
+ operations: [
160
+ { id: 'bad', tool: 'read_file', args: {} },
161
+ { id: 'good', tool: 'read_file', args: { path: 'ok.ts' } },
162
+ ],
163
+ });
164
+ expect(result.failures).toHaveLength(1);
165
+ expect(result.failures[0]?.error).toMatch(/invalid args.*path/);
166
+ expect(result.observations.map((o) => o.id)).toEqual(['good']);
167
+ });
168
+ it('times out a stuck op (env knob) instead of hanging the batch', async () => {
169
+ process.env.ZELARI_OBSERVE_OP_TIMEOUT_MS = '50';
170
+ const stuck = {
171
+ ...okReadTool,
172
+ execute: async () => {
173
+ await sleep(500);
174
+ return typedOk({ path: 'x', content: '', totalLines: 0, readLines: { start: 1, end: 1 }, sizeBytes: 0 });
175
+ },
176
+ };
177
+ const result = await run(deps({ read_file: stuck }), { operations: [{ id: 'stuck', tool: 'read_file' }, { id: 'ok', tool: 'list_files' }] });
178
+ expect(result.failures[0]?.error).toMatch(/TIMEOUT after \d+ms/);
179
+ expect(result.observations.map((o) => o.id)).toEqual(['ok']);
180
+ });
181
+ });
182
+ describe('observe_batch result modes + caps', () => {
183
+ it('evidence mode (default): no raw payload, compact deterministic evidence', async () => {
184
+ const result = await run(deps(), {
185
+ operations: [
186
+ { id: 'g', tool: 'grep_content', args: { pattern: 'refreshSession' } },
187
+ { id: 'r', tool: 'read_file', args: { path: 'src/a.ts' } },
188
+ { id: 'l', tool: 'list_files' },
189
+ ],
190
+ });
191
+ for (const o of result.observations) {
192
+ expect(o.raw).toBeUndefined();
193
+ expect(o.rawOmitted).toBeUndefined();
194
+ expect(o.bytes).toBeLessThan(400);
195
+ }
196
+ const g = result.observations.find((o) => o.id === 'g');
197
+ expect(g?.evidence).toMatchObject({ tool: 'grep_content', pattern: 'refreshSession', matches: 2, filesWalked: 7 });
198
+ const r = result.observations.find((o) => o.id === 'r');
199
+ expect(r?.evidence).toMatchObject({ tool: 'read_file', path: 'src/a.ts', totalLines: 120 });
200
+ expect(result.totals.bytes).toBeLessThan(1200);
201
+ });
202
+ it('raw mode includes payloads until the aggregate cap, then omits explicitly', async () => {
203
+ const bigPayload = { path: 'big.ts', content: 'x'.repeat(AGGREGATE_CAP_BYTES - 2048), totalLines: 1, readLines: { start: 1, end: 1 }, sizeBytes: AGGREGATE_CAP_BYTES };
204
+ const bigRead = {
205
+ ...okReadTool,
206
+ execute: async () => typedOk(bigPayload, { status: 'complete' }),
207
+ };
208
+ const result = await run(deps({ read_file: bigRead }), {
209
+ resultMode: 'raw',
210
+ operations: [
211
+ { id: 'first', tool: 'read_file' },
212
+ { id: 'second', tool: 'read_file' },
213
+ ],
214
+ });
215
+ const first = result.observations.find((o) => o.id === 'first');
216
+ const second = result.observations.find((o) => o.id === 'second');
217
+ expect(first?.raw).toBeDefined();
218
+ expect(first?.rawOmitted).toBeUndefined();
219
+ expect(second?.raw).toBeUndefined();
220
+ expect(second?.rawOmitted).toBe(true);
221
+ expect(second?.evidence).toBeDefined();
222
+ expect(result.truncated).toBe(true);
223
+ });
224
+ it('batch meta reflects Ground Truth status (partial on mixed outcome)', async () => {
225
+ const boom = { ...okGrepTool(), execute: async () => typedErr('x') };
226
+ const tool = createObserveBatchTool(deps({ grep_content: boom }));
227
+ const parsed = tool.inputSchema.parse({ operations: [{ id: 'a', tool: 'grep_content' }, { id: 'b', tool: 'list_files' }] });
228
+ const res = await tool.execute(parsed, fakeCtx());
229
+ expect(res.ok).toBe(true);
230
+ if (res.ok)
231
+ expect(res.meta?.status).toBe('partial');
232
+ });
233
+ });
234
+ describe('observe_batch integration (real registry + real builtins)', () => {
235
+ it('runs real read-only tools through the wrapped registry and projects evidence', async () => {
236
+ const { createBuiltinToolRegistry } = await import('../toolRegistry.js');
237
+ const { registry } = createBuiltinToolRegistry({ lspProvider: null, root: repoRoot });
238
+ expect(registry.list().includes('observe_batch')).toBe(true);
239
+ const toolsDir = path.join(repoRoot, 'src', 'cli', 'tools');
240
+ const pkgJson = path.join(repoRoot, 'package.json');
241
+ const res = await registry.invoke('observe_batch', {
242
+ operations: [
243
+ { id: 'l', tool: 'list_files', args: { path: toolsDir, maxDepth: 1 } },
244
+ {
245
+ id: 'g',
246
+ tool: 'grep_content',
247
+ args: { pattern: 'observe_batch', path: toolsDir, include: ['*.ts'], contextLines: 0, maxMatches: 3 },
248
+ },
249
+ { id: 'r', tool: 'read_file', args: { path: pkgJson, startLine: 1, endLine: 5 } },
250
+ ],
251
+ });
252
+ expect(res.ok).toBe(true);
253
+ if (!res.ok)
254
+ return;
255
+ const v = res.value;
256
+ expect(v.failures).toEqual([]);
257
+ expect(v.observations).toHaveLength(3);
258
+ const l = v.observations.find((o) => o.id === 'l');
259
+ expect(l?.evidence).toMatchObject({ tool: 'list_files', entries: expect.any(Number) });
260
+ const sample = (l?.evidence).sample ?? [];
261
+ expect(sample.length).toBeGreaterThan(0);
262
+ expect(sample.some((n) => n.endsWith('.ts'))).toBe(true);
263
+ const g = v.observations.find((o) => o.id === 'g');
264
+ expect(g?.evidence).toMatchObject({ tool: 'grep_content', pattern: 'observe_batch' });
265
+ expect((g?.evidence).matches).toBeGreaterThan(0);
266
+ expect((g?.evidence).top?.[0]).toMatch(/observeBatch(\.test)?\.ts:\d+/);
267
+ const r = v.observations.find((o) => o.id === 'r');
268
+ expect(r?.evidence).toMatchObject({ tool: 'read_file' });
269
+ expect(String((r?.evidence).path ?? '')).toMatch(/package\.json$/);
270
+ expect(r?.raw).toBeUndefined(); // evidence mode: no payload in context
271
+ });
272
+ it('is registered in readOnly sub-agent registries and disabled by the kill switch', async () => {
273
+ const { createBuiltinToolRegistry } = await import('../toolRegistry.js');
274
+ const ro = createBuiltinToolRegistry({ lspProvider: null, readOnly: true });
275
+ expect(ro.registry.list().includes('observe_batch')).toBe(true);
276
+ process.env.ZELARI_OBSERVE_BATCH = '0';
277
+ try {
278
+ const off = createBuiltinToolRegistry({ lspProvider: null });
279
+ expect(off.registry.list().includes('observe_batch')).toBe(false);
280
+ }
281
+ finally {
282
+ delete process.env.ZELARI_OBSERVE_BATCH;
283
+ }
284
+ });
285
+ });
286
+ describe('projectEvidence determinism', () => {
287
+ it('is byte-identical for the same inputs', () => {
288
+ const args = { pattern: 'foo' };
289
+ const value = {
290
+ matches: Array.from({ length: 9 }, (_, i) => ({ relPath: `f${i}.ts`, line: i + 1, text: 'foo' })),
291
+ totalMatches: 9,
292
+ truncated: false,
293
+ };
294
+ const meta = { status: 'partial', counts: { matches: 9, filesWalked: 40 }, truncated: true };
295
+ const a = JSON.stringify(projectEvidence('grep_content', args, value, meta));
296
+ const b = JSON.stringify(projectEvidence('grep_content', args, value, meta));
297
+ expect(a).toBe(b);
298
+ const ev = JSON.parse(a);
299
+ expect(ev.matches).toBe(9);
300
+ expect(ev.filesWalked).toBe(40);
301
+ expect(ev.top).toHaveLength(5);
302
+ expect(ev.top[0]).toBe('f0.ts:1');
303
+ });
304
+ it('two identical batch executions yield identical results modulo timings', async () => {
305
+ const ops = {
306
+ operations: [
307
+ { id: 'g', tool: 'grep_content', args: { pattern: 'p' } },
308
+ { id: 'r', tool: 'read_file', args: { path: 'a' } },
309
+ { id: 'l', tool: 'list_files' },
310
+ ],
311
+ };
312
+ const a = await run(deps(), ops);
313
+ const b = await run(deps(), ops);
314
+ expect(stripDynamic(a)).toEqual(stripDynamic(b));
315
+ });
316
+ it('list_files evidence reports count + sample with dir suffix', () => {
317
+ const ev = projectEvidence('list_files', {}, {
318
+ dir: '/x',
319
+ entries: [
320
+ { name: 'src', type: 'directory' },
321
+ { name: 'a.ts', type: 'file' },
322
+ { name: 'b.ts', type: 'file' },
323
+ ],
324
+ truncated: false,
325
+ });
326
+ expect(ev).toMatchObject({ tool: 'list_files', dir: '/x', entries: 3, sample: ['src/', 'a.ts', 'b.ts'] });
327
+ });
328
+ });
329
+ //# sourceMappingURL=observeBatch.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observeBatch.test.js","sourceRoot":"","sources":["../../../src/cli/tools/observeBatch.test.ts"],"names":[],"mappings":"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"}