@nathapp/nax-agent 0.91.7 → 0.91.8-canary.2
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 +8 -0
- package/dist/config/catalog-overrides.d.ts +13 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -0
- package/dist/internal/atomic-write.d.ts +22 -7
- package/dist/internal/atomic-write.js +107 -12
- package/dist/internal/pinned-directory-worker.d.ts +52 -0
- package/dist/internal/pinned-directory-worker.js +105 -0
- package/dist/internal/pinned-directory.d.ts +48 -0
- package/dist/internal/pinned-directory.js +168 -0
- package/dist/internal.d.ts +2 -0
- package/dist/internal.js +2 -0
- package/dist/memory/delivery.d.ts +38 -0
- package/dist/memory/delivery.js +28 -0
- package/dist/memory/index-render.d.ts +55 -0
- package/dist/memory/index-render.js +225 -0
- package/dist/memory/index.d.ts +12 -0
- package/dist/memory/index.js +11 -0
- package/dist/memory/local-provider.d.ts +3 -0
- package/dist/memory/local-provider.js +127 -0
- package/dist/memory/mirror-lock.d.ts +109 -0
- package/dist/memory/mirror-lock.js +334 -0
- package/dist/memory/note.d.ts +15 -0
- package/dist/memory/note.js +131 -0
- package/dist/memory/operations.d.ts +123 -0
- package/dist/memory/operations.js +471 -0
- package/dist/memory/outbox.d.ts +35 -0
- package/dist/memory/outbox.js +289 -0
- package/dist/memory/provider-types.d.ts +50 -0
- package/dist/memory/provider-types.js +1 -0
- package/dist/memory/records.d.ts +41 -0
- package/dist/memory/records.js +93 -0
- package/dist/memory/refusal.d.ts +36 -0
- package/dist/memory/refusal.js +25 -0
- package/dist/memory/search.d.ts +17 -0
- package/dist/memory/search.js +112 -0
- package/dist/memory/store.d.ts +106 -0
- package/dist/memory/store.js +459 -0
- package/dist/memory/support.d.ts +63 -0
- package/dist/memory/support.js +98 -0
- package/dist/memory/sync-flight.d.ts +25 -0
- package/dist/memory/sync-flight.js +65 -0
- package/dist/memory/sync.d.ts +82 -0
- package/dist/memory/sync.js +344 -0
- package/dist/memory/types.d.ts +108 -0
- package/dist/memory/types.js +51 -0
- package/dist/memory/validate.d.ts +31 -0
- package/dist/memory/validate.js +104 -0
- package/dist/native/adapter-deps.d.ts +9 -0
- package/dist/native/adapter-deps.js +9 -0
- package/dist/native/models.js +3 -0
- package/dist/native/session/compaction.d.ts +15 -1
- package/dist/native/session/compaction.js +90 -23
- package/dist/native/session/manual-compaction.d.ts +57 -0
- package/dist/native/session/manual-compaction.js +72 -0
- package/dist/native/session/session-summarizer.d.ts +75 -0
- package/dist/native/session/session-summarizer.js +73 -0
- package/dist/native/session/transcript-identity.d.ts +12 -0
- package/dist/native/session/transcript-identity.js +16 -0
- package/dist/native/session/turn-compaction-step.d.ts +30 -2
- package/dist/native/session/turn-compaction-step.js +7 -1
- package/dist/native/session/turn-loop-round-trip.js +71 -17
- package/dist/native/session/turn-loop.js +2 -6
- package/dist/native/session-adapter.d.ts +19 -0
- package/dist/native/session-adapter.js +42 -64
- package/dist/sandbox/srt-backend.js +9 -16
- package/dist/session/agent-session-options.js +1 -0
- package/dist/session/agent-session-turn.d.ts +6 -0
- package/dist/session/agent-session-turn.js +5 -4
- package/dist/session/agent-session-types.d.ts +38 -0
- package/dist/session/agent-session.d.ts +8 -0
- package/dist/session/agent-session.js +163 -20
- package/dist/session/native-backend.js +8 -0
- package/dist/session/session-backend.d.ts +19 -1
- package/dist/session/session-types.d.ts +6 -0
- package/dist/session/steer-channel.d.ts +36 -0
- package/dist/session/steer-channel.js +39 -0
- package/dist/session-store/index.d.ts +1 -1
- package/dist/session-store/index.js +1 -1
- package/dist/session-store/session-lock.d.ts +2 -2
- package/dist/session-store/session-lock.js +4 -2
- package/dist/tools/ask-request.d.ts +8 -0
- package/dist/tools/ask-request.js +34 -1
- package/dist/tools/provider-adapt.js +5 -1
- package/dist/tools/provider-types.d.ts +7 -0
- package/dist/tools/types.d.ts +16 -0
- package/package.json +4 -4
|
@@ -17,6 +17,14 @@ export const MAX_ASK_SUMMARY_CHARS = 200;
|
|
|
17
17
|
* a Write, a commit message, whatever a provider tool takes -- and an
|
|
18
18
|
* AskResolver is by definition an outbound channel to a human. A summary is
|
|
19
19
|
* what approval needs; the payload is what the audit sink already holds.
|
|
20
|
+
*
|
|
21
|
+
* Two kinds of declared field, and only these: the parts that say WHAT the
|
|
22
|
+
* call will do (command, argv, verb, paths), and the summary-only fields a tool
|
|
23
|
+
* adds for legibility (`ToolScope.summaryFields`) -- a memory tool's `slug`,
|
|
24
|
+
* so the person reads which note is about to be written instead of the same
|
|
25
|
+
* line the tool always rendered. Neither kind is grant-checked here, and
|
|
26
|
+
* neither is ever widened into the payload: a summary field renders only a
|
|
27
|
+
* string, number or boolean.
|
|
20
28
|
*/
|
|
21
29
|
export function askSummary(tool, scope, input) {
|
|
22
30
|
const fields = [scope.commandField, scope.argvField, scope.verbField, ...scope.pathFields];
|
|
@@ -30,13 +38,38 @@ export function askSummary(tool, scope, input) {
|
|
|
30
38
|
return [`${field}=${value.filter((v) => typeof v === "string").join(" ")}`];
|
|
31
39
|
return [];
|
|
32
40
|
});
|
|
41
|
+
// Summary fields FOLLOW the parts above, so a path-bearing tool keeps its
|
|
42
|
+
// existing line and gains the extra detail at the end.
|
|
43
|
+
const summaryParts = (scope.summaryFields ?? []).flatMap((field) => {
|
|
44
|
+
const rendered = summaryScalar(input[field]);
|
|
45
|
+
return rendered === undefined ? [] : [`${field}=${rendered}`];
|
|
46
|
+
});
|
|
33
47
|
// Mask the FULL line, then cut: cutting first can split a secret so no
|
|
34
48
|
// pattern matches what is left, and the partial secret would go out.
|
|
35
|
-
const masked = maskForPrompt(`${tool} ${parts.join(" ")}`.trim());
|
|
49
|
+
const masked = maskForPrompt(`${tool} ${[...parts, ...summaryParts].join(" ")}`.trim());
|
|
36
50
|
if (!masked.ok)
|
|
37
51
|
return { summary: `${tool} [arguments withheld: contains a secret]`, unshowable: true };
|
|
38
52
|
return { summary: masked.masked.slice(0, MAX_ASK_SUMMARY_CHARS), unshowable: false };
|
|
39
53
|
}
|
|
54
|
+
/** One line break, whichever convention wrote it: CRLF before CR and LF alone. */
|
|
55
|
+
const SUMMARY_LINE_BREAK = /\r\n|\r|\n/g;
|
|
56
|
+
/**
|
|
57
|
+
* The one-line form of a summary field's value, or undefined when the value is
|
|
58
|
+
* not renderable.
|
|
59
|
+
*
|
|
60
|
+
* Scalars only. An array or an object is SKIPPED rather than serialised: a
|
|
61
|
+
* summary line describes the call, and a serialised payload on it would be the
|
|
62
|
+
* very thing this function exists to avoid. A line break inside a value
|
|
63
|
+
* becomes one space, because the line is a single line -- an unstripped newline
|
|
64
|
+
* would let a field forge a second line of the approval card.
|
|
65
|
+
*/
|
|
66
|
+
function summaryScalar(value) {
|
|
67
|
+
if (typeof value === "string")
|
|
68
|
+
return value.replace(SUMMARY_LINE_BREAK, " ");
|
|
69
|
+
if (typeof value === "number" || typeof value === "boolean")
|
|
70
|
+
return String(value);
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
40
73
|
/** The clause `unsandboxedReasonSuffix` renders, before the reason itself. */
|
|
41
74
|
const UNSANDBOXED_PREFIX = " -- runs OUTSIDE the sandbox: ";
|
|
42
75
|
/** What the suffix says when the model gave no usable reason. */
|
|
@@ -26,7 +26,11 @@ export function adaptProviderTool(providerId, tool) {
|
|
|
26
26
|
inputSchema: tool.inputSchema,
|
|
27
27
|
// No path fields and no verb field: the grant lookup is the whole gate,
|
|
28
28
|
// which is the honest expression for a tool whose arguments are not paths.
|
|
29
|
-
|
|
29
|
+
// A declared summary field is carried through, summary-only — it names the
|
|
30
|
+
// call on an approval line and is never checked. Absent, the scope stays
|
|
31
|
+
// exactly `{ pathFields: [] }`, so a metadata-free provider tool adapts to
|
|
32
|
+
// the same shape it always did.
|
|
33
|
+
scope: tool.summaryFields === undefined ? { pathFields: [] } : { pathFields: [], summaryFields: tool.summaryFields },
|
|
30
34
|
run: (input, ctx) => tool.run(input, ctx),
|
|
31
35
|
};
|
|
32
36
|
}
|
|
@@ -24,6 +24,13 @@ export interface ProviderTool {
|
|
|
24
24
|
* trusted as stated and decides whether an ask-profile session asks first.
|
|
25
25
|
*/
|
|
26
26
|
readonly readOnly?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* US-003: plain input fields an approval line may SHOW, copied verbatim into
|
|
29
|
+
* the adapted tool's `scope.summaryFields`. Summary-only — never grant-checked
|
|
30
|
+
* and never rendered as a path (see `ToolScope.summaryFields`). Absent for
|
|
31
|
+
* every memory tool's note BODY, which is never shown on an approval line.
|
|
32
|
+
*/
|
|
33
|
+
readonly summaryFields?: readonly string[];
|
|
27
34
|
run(input: Record<string, unknown>, ctx: ToolRunContext): Promise<ToolResult>;
|
|
28
35
|
}
|
|
29
36
|
export interface ToolProvider {
|
package/dist/tools/types.d.ts
CHANGED
|
@@ -118,6 +118,22 @@ export interface ToolScope {
|
|
|
118
118
|
* option, and whether a call is PERMITTED is the runtime's decision.
|
|
119
119
|
*/
|
|
120
120
|
readonly unsandboxedField?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Plain input fields an approval line may SHOW, in declaration order
|
|
123
|
+
* (`askSummary`). Summary-only in the strictest sense: they are never
|
|
124
|
+
* grant-checked, never resolved as paths, never treated as a verb or a
|
|
125
|
+
* command, and never widen what an approval admits. They exist because a
|
|
126
|
+
* tool whose arguments are not paths — an MCP memory tool, say — otherwise
|
|
127
|
+
* renders an approval line naming nothing about the call.
|
|
128
|
+
*
|
|
129
|
+
* Only a string, number or boolean value is rendered (line breaks flattened
|
|
130
|
+
* to a space); an array or an object is skipped rather than serialised, since
|
|
131
|
+
* a summary is a one-line description and not a payload dump. Being
|
|
132
|
+
* summary-only, this field is deliberately absent from `isFieldlessScope`
|
|
133
|
+
* (policy.ts): a tool declaring summary fields is still fieldless, so an
|
|
134
|
+
* unconditional ask rule keeps asking exactly as it did before.
|
|
135
|
+
*/
|
|
136
|
+
readonly summaryFields?: readonly string[];
|
|
121
137
|
}
|
|
122
138
|
/**
|
|
123
139
|
* `breach` separates "you may not write there" from "that path is not in this
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nathapp/nax-agent",
|
|
3
|
-
"version": "0.91.
|
|
3
|
+
"version": "0.91.8-canary.2",
|
|
4
4
|
"description": "nax's native coding agent: session contract, native loop, tools, permissions, sandbox, command-safety.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "William Khoo",
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@anthropic-ai/sandbox-runtime": "0.0.77",
|
|
49
49
|
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
50
|
-
"@nathapp/nax-ai": "0.91.
|
|
51
|
-
"zod": "^4.
|
|
50
|
+
"@nathapp/nax-ai": "0.91.8-canary.2",
|
|
51
|
+
"zod": "^4.6.6"
|
|
52
52
|
},
|
|
53
53
|
"publishConfig": {
|
|
54
54
|
"access": "public",
|
|
55
55
|
"registry": "https://registry.npmjs.org/",
|
|
56
56
|
"provenance": true,
|
|
57
|
-
"tag": "
|
|
57
|
+
"tag": "canary"
|
|
58
58
|
}
|
|
59
59
|
}
|