@namzu/sdk 60.1.0 → 60.2.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.
- package/CHANGELOG.md +28 -0
- package/dist/bridge/a2a/mapper.d.ts.map +1 -1
- package/dist/bridge/a2a/mapper.js +3 -0
- package/dist/bridge/a2a/mapper.js.map +1 -1
- package/dist/bridge/sse/mapper.d.ts.map +1 -1
- package/dist/bridge/sse/mapper.js +16 -0
- package/dist/bridge/sse/mapper.js.map +1 -1
- package/dist/contracts/session/api.d.ts +1 -1
- package/dist/contracts/session/api.d.ts.map +1 -1
- package/dist/manager/session/turn-recorder.d.ts +7 -1
- package/dist/manager/session/turn-recorder.d.ts.map +1 -1
- package/dist/manager/session/turn-recorder.js +19 -0
- package/dist/manager/session/turn-recorder.js.map +1 -1
- package/dist/peers/dir.d.ts.map +1 -1
- package/dist/peers/dir.js +3 -0
- package/dist/peers/dir.js.map +1 -1
- package/dist/public-runtime.d.ts +1 -0
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +1 -0
- package/dist/public-runtime.js.map +1 -1
- package/dist/runtime/query/events.d.ts.map +1 -1
- package/dist/runtime/query/events.js +17 -0
- package/dist/runtime/query/events.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +23 -0
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +88 -9
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +13 -0
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +3 -2
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +6 -0
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/request-void-turns.d.ts +19 -0
- package/dist/runtime/query/request-void-turns.d.ts.map +1 -0
- package/dist/runtime/query/request-void-turns.js +26 -0
- package/dist/runtime/query/request-void-turns.js.map +1 -0
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +12 -2
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/runtime/query/tooling.d.ts +2 -0
- package/dist/runtime/query/tooling.d.ts.map +1 -1
- package/dist/runtime/query/tooling.js +1 -0
- package/dist/runtime/query/tooling.js.map +1 -1
- package/dist/sandbox/provider/local.d.ts.map +1 -1
- package/dist/sandbox/provider/local.js +6 -5
- package/dist/sandbox/provider/local.js.map +1 -1
- package/dist/session/paths.d.ts +15 -22
- package/dist/session/paths.d.ts.map +1 -1
- package/dist/session/paths.js +19 -46
- package/dist/session/paths.js.map +1 -1
- package/dist/store/session-log/core.d.ts +43 -0
- package/dist/store/session-log/core.d.ts.map +1 -1
- package/dist/store/session-log/core.js +190 -3
- package/dist/store/session-log/core.js.map +1 -1
- package/dist/store/session-log/disk.d.ts +1 -1
- package/dist/store/session-log/disk.d.ts.map +1 -1
- package/dist/store/session-log/disk.js +1 -0
- package/dist/store/session-log/disk.js.map +1 -1
- package/dist/store/session-log/index.d.ts +1 -1
- package/dist/store/session-log/index.d.ts.map +1 -1
- package/dist/store/session-log/index.js +1 -1
- package/dist/store/session-log/index.js.map +1 -1
- package/dist/tools/builtins/bash-cwd.d.ts.map +1 -1
- package/dist/tools/builtins/bash-cwd.js +2 -3
- package/dist/tools/builtins/bash-cwd.js.map +1 -1
- package/dist/tools/builtins/read-media.js +3 -3
- package/dist/tools/builtins/read-media.js.map +1 -1
- package/dist/turn/reporter.d.ts.map +1 -1
- package/dist/turn/reporter.js +2 -0
- package/dist/turn/reporter.js.map +1 -1
- package/dist/types/hitl/index.d.ts +8 -0
- package/dist/types/hitl/index.d.ts.map +1 -1
- package/dist/types/hitl/index.js.map +1 -1
- package/dist/types/session/events.d.ts +38 -2
- package/dist/types/session/events.d.ts.map +1 -1
- package/dist/types/session/events.js +4 -0
- package/dist/types/session/events.js.map +1 -1
- package/dist/types/session/records.d.ts +10 -10
- package/dist/types/session/records.d.ts.map +1 -1
- package/dist/types/session/records.js +2 -0
- package/dist/types/session/records.js.map +1 -1
- package/dist/utils/temp.d.ts +82 -0
- package/dist/utils/temp.d.ts.map +1 -0
- package/dist/utils/temp.js +196 -0
- package/dist/utils/temp.js.map +1 -0
- package/package.json +1 -1
- package/src/bridge/a2a/mapper.ts +3 -0
- package/src/bridge/sse/mapper.ts +16 -0
- package/src/contracts/session/api.ts +2 -0
- package/src/manager/session/turn-recorder.ts +21 -0
- package/src/peers/dir.ts +3 -0
- package/src/public-runtime.ts +13 -0
- package/src/runtime/query/events.ts +19 -0
- package/src/runtime/query/executor.ts +92 -8
- package/src/runtime/query/index.ts +12 -0
- package/src/runtime/query/iteration/index.ts +3 -2
- package/src/runtime/query/iteration/phases/tool-review.ts +6 -0
- package/src/runtime/query/request-void-turns.ts +28 -0
- package/src/runtime/query/review-policy.ts +13 -2
- package/src/runtime/query/tooling.ts +3 -0
- package/src/sandbox/provider/local.ts +8 -5
- package/src/session/paths.ts +32 -57
- package/src/store/session-log/core.ts +235 -3
- package/src/store/session-log/disk.ts +7 -1
- package/src/store/session-log/index.ts +4 -0
- package/src/tools/builtins/bash-cwd.ts +2 -3
- package/src/tools/builtins/read-media.ts +3 -3
- package/src/turn/reporter.ts +2 -0
- package/src/types/hitl/index.ts +8 -0
- package/src/types/session/events.ts +41 -1
- package/src/types/session/records.ts +2 -0
- package/src/utils/temp.ts +250 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
|
-
import { join, resolve } from 'node:path';
|
|
2
|
+
import { isAbsolute, join, resolve } from 'node:path';
|
|
3
3
|
import { unknownProgramInLine } from '../../authorization/program.js';
|
|
4
4
|
import { compileSkillGrant } from '../../authorization/skill-grant.js';
|
|
5
5
|
import { extractFromToolCall, extractFromToolResult } from '../../compaction/extractor.js';
|
|
@@ -15,7 +15,7 @@ import { fingerprintContent } from '../../tools/builtins/content-fingerprint.js'
|
|
|
15
15
|
import { sandboxShellSpawn, withoutBashStartup } from '../../tools/command-shell.js';
|
|
16
16
|
import { isAlwaysDestructive } from '../../tools/defineTool.js';
|
|
17
17
|
import { createFileReadTracker } from '../../tools/file-read-tracker.js';
|
|
18
|
-
import { pathOutsideRoots, toolRoots } from '../../tools/paths.js';
|
|
18
|
+
import { pathOutsideRoots, resolveWithinAnyReal, toolRoots } from '../../tools/paths.js';
|
|
19
19
|
import { resolveRetainedOutput } from '../../tools/retained-output.js';
|
|
20
20
|
import { createToolMessage, } from '../../types/message/index.js';
|
|
21
21
|
import { abortReasonText } from '../../utils/abort.js';
|
|
@@ -25,6 +25,7 @@ import { toErrorMessage } from '../../utils/error.js';
|
|
|
25
25
|
import { generateToolCallId } from '../../utils/id.js';
|
|
26
26
|
import { compressShellOutput } from '../../utils/shell-compress.js';
|
|
27
27
|
import { parseStructuredResultJson } from '../../utils/structured-result-json.js';
|
|
28
|
+
import { ensureScratchpadDirectory } from '../../utils/temp.js';
|
|
28
29
|
import { bindOwner } from '../jobs/registry.js';
|
|
29
30
|
import { stillRunningResult } from './detached-calls.js';
|
|
30
31
|
import { formatFailedToolOutput, hookNote, isUnregistered, prepareDirectCall, runPreToolHook, unknownToolMessage, } from './executor/tool-call-admission.js';
|
|
@@ -316,6 +317,71 @@ export class ToolExecutor {
|
|
|
316
317
|
await this.sandboxGate?.();
|
|
317
318
|
}
|
|
318
319
|
/** True once the turn has a sandbox, or is certain to get one before a tool runs. */
|
|
320
|
+
/** The scratch folder, once a call has named it and it has been made and checked. */
|
|
321
|
+
scratchpadReady;
|
|
322
|
+
/** The tools' roots now: the turn's, plus the scratch folder once it is ready. */
|
|
323
|
+
rootsNow() {
|
|
324
|
+
return toolRoots({
|
|
325
|
+
workingDirectory: this.config.workingDirectory,
|
|
326
|
+
additionalDirectories: this.additionalDirectoriesNow(),
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
additionalDirectoriesNow() {
|
|
330
|
+
if (this.scratchpadReady === undefined)
|
|
331
|
+
return this.config.additionalDirectories;
|
|
332
|
+
return [...(this.config.additionalDirectories ?? []), this.scratchpadReady];
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Make the session's scratch folder a root when a call names it. Lazy: a
|
|
336
|
+
* session that never uses it leaves nothing on disk. The folder must be
|
|
337
|
+
* inside the private temporary root with no link on the way; otherwise it
|
|
338
|
+
* stays outside the roots and a path in it is asked about like any other.
|
|
339
|
+
*/
|
|
340
|
+
admitScratchpad(call) {
|
|
341
|
+
const directory = this.config.scratchpadDirectory;
|
|
342
|
+
if (directory === undefined || this.scratchpadReady !== undefined || this.sandboxed)
|
|
343
|
+
return;
|
|
344
|
+
if (call.kind === 'synthetic')
|
|
345
|
+
return;
|
|
346
|
+
let named = false;
|
|
347
|
+
try {
|
|
348
|
+
named = JSON.stringify(call.input)?.includes(JSON.stringify(directory).slice(1, -1)) === true;
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
// An input that cannot be serialised names nothing.
|
|
352
|
+
}
|
|
353
|
+
if (!named)
|
|
354
|
+
return;
|
|
355
|
+
try {
|
|
356
|
+
this.scratchpadReady = ensureScratchpadDirectory(directory);
|
|
357
|
+
}
|
|
358
|
+
catch (error) {
|
|
359
|
+
this.log.warn('The session scratch folder could not be made, so it stays outside the roots', {
|
|
360
|
+
'exception.message': error instanceof Error ? error.message : String(error),
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/** Whether `call` writes a file inside the ready scratch folder and nothing else about it is notable. */
|
|
365
|
+
async writesScratchpad(call, escalation) {
|
|
366
|
+
const root = this.scratchpadReady;
|
|
367
|
+
if (root === undefined || escalation !== undefined || call.kind === 'synthetic')
|
|
368
|
+
return false;
|
|
369
|
+
if (call.toolName !== 'write' && call.toolName !== 'edit')
|
|
370
|
+
return false;
|
|
371
|
+
const tool = this.config.tools.get(call.toolName);
|
|
372
|
+
if (!tool?.pathArgument || call.input === null || typeof call.input !== 'object')
|
|
373
|
+
return false;
|
|
374
|
+
const value = call.input[tool.pathArgument];
|
|
375
|
+
if (typeof value !== 'string' || !isAbsolute(value))
|
|
376
|
+
return false;
|
|
377
|
+
try {
|
|
378
|
+
await resolveWithinAnyReal([root], value);
|
|
379
|
+
return true;
|
|
380
|
+
}
|
|
381
|
+
catch {
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
319
385
|
get sandboxed() {
|
|
320
386
|
return this.config.sandbox !== undefined || this.sandboxGate !== undefined;
|
|
321
387
|
}
|
|
@@ -585,6 +651,7 @@ export class ToolExecutor {
|
|
|
585
651
|
await this.awaitSandbox();
|
|
586
652
|
const calls = new Map();
|
|
587
653
|
const escalations = new Map();
|
|
654
|
+
const scratchpadWrites = new Set();
|
|
588
655
|
const earlierPaths = [];
|
|
589
656
|
for (const toolCall of response.message.toolCalls ?? []) {
|
|
590
657
|
const prepared = await prepareDirectCall(this.admissionHost(), toolCall, !hostModifiedCallIds?.has(toolCall.id));
|
|
@@ -593,12 +660,15 @@ export class ToolExecutor {
|
|
|
593
660
|
if (path !== undefined)
|
|
594
661
|
earlierPaths.push(path);
|
|
595
662
|
calls.set(toolCall.id, call);
|
|
663
|
+
this.admitScratchpad(call);
|
|
596
664
|
const escalation = await this.escalationOrUnfinished(call);
|
|
597
665
|
if (escalation)
|
|
598
666
|
escalations.set(toolCall.id, escalation);
|
|
667
|
+
if (await this.writesScratchpad(call, escalation))
|
|
668
|
+
scratchpadWrites.add(toolCall.id);
|
|
599
669
|
}
|
|
600
670
|
this.config.abortSignal.throwIfAborted();
|
|
601
|
-
return this.publishPreparedBatch(calls, escalations);
|
|
671
|
+
return this.publishPreparedBatch(calls, escalations, scratchpadWrites);
|
|
602
672
|
}
|
|
603
673
|
/**
|
|
604
674
|
* A ready call the tool already knows cannot run, answered now instead of
|
|
@@ -703,7 +773,7 @@ export class ToolExecutor {
|
|
|
703
773
|
// This session's own retained output is not "outside": it is where the
|
|
704
774
|
// result that was cut told the model to look.
|
|
705
775
|
const retained = tool.name === 'read' && (await resolveRetainedOutput(this.outputDirectory(), value));
|
|
706
|
-
const outside = retained ? undefined : await pathOutsideRoots(
|
|
776
|
+
const outside = retained ? undefined : await pathOutsideRoots(this.rootsNow(), value);
|
|
707
777
|
if (outside !== undefined)
|
|
708
778
|
outsidePaths = [outside];
|
|
709
779
|
}
|
|
@@ -745,7 +815,7 @@ export class ToolExecutor {
|
|
|
745
815
|
* file tools' own does.
|
|
746
816
|
*/
|
|
747
817
|
async pathEscalationsOf(tool, input, sandboxed, shellCwd) {
|
|
748
|
-
const roots =
|
|
818
|
+
const roots = this.rootsNow();
|
|
749
819
|
const protectedPaths = [];
|
|
750
820
|
let outsidePaths = [];
|
|
751
821
|
let removal;
|
|
@@ -804,16 +874,22 @@ export class ToolExecutor {
|
|
|
804
874
|
}
|
|
805
875
|
const calls = new Map(previous.calls);
|
|
806
876
|
const escalations = new Map(previous.escalations);
|
|
877
|
+
const scratchpadWrites = new Set(previous.scratchpadWrites);
|
|
807
878
|
const earlierPaths = [];
|
|
808
879
|
for (const toolCall of response.message.toolCalls ?? []) {
|
|
809
880
|
if (changedCallIds.has(toolCall.id)) {
|
|
810
881
|
const call = await this.refusedBeforeReview(await prepareDirectCall(this.admissionHost(), toolCall, false), earlierPaths);
|
|
811
882
|
calls.set(toolCall.id, call);
|
|
883
|
+
this.admitScratchpad(call);
|
|
812
884
|
const escalation = await this.escalationOrUnfinished(call);
|
|
813
885
|
if (escalation)
|
|
814
886
|
escalations.set(toolCall.id, escalation);
|
|
815
887
|
else
|
|
816
888
|
escalations.delete(toolCall.id);
|
|
889
|
+
if (await this.writesScratchpad(call, escalation))
|
|
890
|
+
scratchpadWrites.add(toolCall.id);
|
|
891
|
+
else
|
|
892
|
+
scratchpadWrites.delete(toolCall.id);
|
|
817
893
|
}
|
|
818
894
|
const prepared = calls.get(toolCall.id);
|
|
819
895
|
const path = prepared ? inputPathOf(prepared) : undefined;
|
|
@@ -821,9 +897,9 @@ export class ToolExecutor {
|
|
|
821
897
|
earlierPaths.push(path);
|
|
822
898
|
}
|
|
823
899
|
this.config.abortSignal.throwIfAborted();
|
|
824
|
-
return this.publishPreparedBatch(calls, escalations);
|
|
900
|
+
return this.publishPreparedBatch(calls, escalations, scratchpadWrites);
|
|
825
901
|
}
|
|
826
|
-
publishPreparedBatch(calls, escalations) {
|
|
902
|
+
publishPreparedBatch(calls, escalations, scratchpadWrites) {
|
|
827
903
|
const reviewCalls = [...calls.values()]
|
|
828
904
|
.filter((call) => call.kind !== 'synthetic')
|
|
829
905
|
.map((call) => {
|
|
@@ -835,12 +911,14 @@ export class ToolExecutor {
|
|
|
835
911
|
input: call.input,
|
|
836
912
|
...(escalation ? { escalation } : {}),
|
|
837
913
|
...(hookPermission ? { hookPermission } : {}),
|
|
914
|
+
...(scratchpadWrites.has(call.toolCall.id) ? { scratchpadWrite: true } : {}),
|
|
838
915
|
};
|
|
839
916
|
});
|
|
840
917
|
const batch = Object.freeze({
|
|
841
918
|
reviewCalls: Object.freeze(reviewCalls),
|
|
842
919
|
calls: new Map(calls),
|
|
843
920
|
escalations: new Map(escalations),
|
|
921
|
+
scratchpadWrites: new Set(scratchpadWrites),
|
|
844
922
|
});
|
|
845
923
|
this.preparedBatches.add(batch);
|
|
846
924
|
return batch;
|
|
@@ -1409,6 +1487,7 @@ export class ToolExecutor {
|
|
|
1409
1487
|
catch {
|
|
1410
1488
|
needsApproval = true;
|
|
1411
1489
|
}
|
|
1490
|
+
this.admitScratchpad(preparedCall);
|
|
1412
1491
|
const nestedEscalation = await this.escalationOrUnfinished(preparedCall);
|
|
1413
1492
|
if (nestedEscalation || needsApproval || (gateResult && gateResult.decision !== 'allow')) {
|
|
1414
1493
|
const reason = nestedEscalation
|
|
@@ -1617,8 +1696,8 @@ export class ToolExecutor {
|
|
|
1617
1696
|
sessionId: this.config.sessionId,
|
|
1618
1697
|
turnId: this.config.turnId,
|
|
1619
1698
|
workingDirectory: this.config.workingDirectory,
|
|
1620
|
-
...(this.
|
|
1621
|
-
? { additionalDirectories: this.
|
|
1699
|
+
...(this.additionalDirectoriesNow()?.length
|
|
1700
|
+
? { additionalDirectories: this.additionalDirectoriesNow() }
|
|
1622
1701
|
: {}),
|
|
1623
1702
|
...(this.config.authorizationGate
|
|
1624
1703
|
? {
|