@tangle-network/agent-app 0.60.191 → 0.60.192
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/dist/assistant/index.js +5 -5
- package/dist/chat-react/index.js +2 -2
- package/dist/chat-routes/attachment-upload.d.ts +1 -1
- package/dist/chat-routes/attachment-validation.d.ts +50 -1
- package/dist/chat-routes/index.js +10 -79
- package/dist/chat-routes/index.js.map +1 -1
- package/dist/chat-routes/resolve-attachments.d.ts +1 -25
- package/dist/chat-store/index.js +2 -2
- package/dist/{chunk-MSAGTFN4.js → chunk-6RFNLZCK.js} +2 -2
- package/dist/{chunk-TNWDYAFX.js → chunk-E6UTFXKQ.js} +4 -4
- package/dist/{chunk-Y2SOQOJE.js → chunk-KNTRS7OZ.js} +2 -2
- package/dist/{chunk-WTC6AOPL.js → chunk-PBQYVAB6.js} +82 -2
- package/dist/chunk-PBQYVAB6.js.map +1 -0
- package/dist/{chunk-J26IXWFK.js → chunk-Q2H5FKVG.js} +2 -2
- package/dist/operator/chat-adapter.d.ts +9 -0
- package/dist/operator/contract.d.ts +11 -1
- package/dist/operator/index.js +18 -4
- package/dist/operator/index.js.map +1 -1
- package/dist/operator/server.d.ts +7 -0
- package/dist/public-consultation/index.js +3 -3
- package/dist/web-react/index.js +5 -5
- package/package.json +1 -1
- package/dist/chunk-WTC6AOPL.js.map +0 -1
- /package/dist/{chunk-MSAGTFN4.js.map → chunk-6RFNLZCK.js.map} +0 -0
- /package/dist/{chunk-TNWDYAFX.js.map → chunk-E6UTFXKQ.js.map} +0 -0
- /package/dist/{chunk-Y2SOQOJE.js.map → chunk-KNTRS7OZ.js.map} +0 -0
- /package/dist/{chunk-J26IXWFK.js.map → chunk-Q2H5FKVG.js.map} +0 -0
package/dist/assistant/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ReasoningRow,
|
|
3
3
|
chatToolCallPart
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-KNTRS7OZ.js";
|
|
5
5
|
import "../chunk-3HUFJ5LO.js";
|
|
6
6
|
import "../chunk-KMIDRUUH.js";
|
|
7
7
|
import "../chunk-FBVLEGEG.js";
|
|
8
8
|
import "../chunk-Y6PRDUFJ.js";
|
|
9
9
|
import {
|
|
10
10
|
ChatComposer
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-6RFNLZCK.js";
|
|
12
12
|
import "../chunk-L7MB2LLM.js";
|
|
13
13
|
import "../chunk-GNBBY3KN.js";
|
|
14
14
|
import "../chunk-A2GG4D4A.js";
|
|
@@ -28,14 +28,14 @@ import {
|
|
|
28
28
|
AsyncView
|
|
29
29
|
} from "../chunk-AVP5SNIG.js";
|
|
30
30
|
import "../chunk-FQYAJYPW.js";
|
|
31
|
-
import "../chunk-
|
|
31
|
+
import "../chunk-PBQYVAB6.js";
|
|
32
32
|
import "../chunk-VBRUG4N5.js";
|
|
33
33
|
import "../chunk-B7CL7ENS.js";
|
|
34
34
|
import "../chunk-PV33JZKV.js";
|
|
35
35
|
import "../chunk-AMUXRAUO.js";
|
|
36
|
-
import "../chunk-
|
|
37
|
-
import "../chunk-YHRWZZJN.js";
|
|
36
|
+
import "../chunk-E6UTFXKQ.js";
|
|
38
37
|
import "../chunk-ZVEEWGDK.js";
|
|
38
|
+
import "../chunk-YHRWZZJN.js";
|
|
39
39
|
import "../chunk-TXD5HXLE.js";
|
|
40
40
|
import "../chunk-ZGUXI5SI.js";
|
|
41
41
|
import "../chunk-6VQCFJWP.js";
|
package/dist/chat-react/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ComposerModeControls,
|
|
3
3
|
EntryComposer
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-6RFNLZCK.js";
|
|
5
5
|
import "../chunk-L7MB2LLM.js";
|
|
6
6
|
import "../chunk-SJWIZT7B.js";
|
|
7
7
|
import "../chunk-5IS3GCMR.js";
|
|
8
8
|
import "../chunk-HEPEGY6Q.js";
|
|
9
9
|
import "../chunk-XG6FODYO.js";
|
|
10
10
|
import "../chunk-RASGKEAL.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-PBQYVAB6.js";
|
|
12
12
|
import "../chunk-VBRUG4N5.js";
|
|
13
13
|
import "../chunk-AMUXRAUO.js";
|
|
14
14
|
import "../chunk-YHRWZZJN.js";
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
*/
|
|
30
30
|
import type { ChatAttachmentKind } from './wire';
|
|
31
31
|
import { type AtomicAttachmentWriter, type WriteAttachmentFn } from './attachment-store';
|
|
32
|
-
import { type AttachmentPathCheck } from './
|
|
32
|
+
import { type AttachmentPathCheck } from './attachment-validation';
|
|
33
33
|
/** Stable authorization result for the original writer contract. */
|
|
34
34
|
export type AttachmentUploadAuthorization = {
|
|
35
35
|
ok: true;
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
* Shared attachment validation core — constants, type-gate, and filename
|
|
3
3
|
* sanitization used by BOTH the (server) attachment upload route and the
|
|
4
4
|
* (browser) composer's client-side pre-validation, so a rejection never
|
|
5
|
-
* differs depending on which side classified the bytes first.
|
|
5
|
+
* differs depending on which side classified the bytes first. The structural
|
|
6
|
+
* `attachments` parser lives here too, so the chat route and the operator API
|
|
7
|
+
* refuse the same turn bodies without either pulling in the chat store.
|
|
6
8
|
*
|
|
7
9
|
* ≈ gtm-agent's `src/lib/attachment-limits.ts`, minus what agent-app already
|
|
8
10
|
* has (`ATTACHMENT_MAX_COUNT`/`MAX_ATTACHMENT_TOTAL_BYTES`/
|
|
@@ -14,6 +16,7 @@
|
|
|
14
16
|
* (`tests/browser-safe-subpaths.test.ts` walks the graph), so nothing here
|
|
15
17
|
* may reach a Node builtin or an engine package.
|
|
16
18
|
*/
|
|
19
|
+
import { type ChatAttachmentInput } from './wire';
|
|
17
20
|
import type { SniffResult } from './binary-sniff';
|
|
18
21
|
/** Ceiling on a binary attachment's raw (pre-encoding) byte size. */
|
|
19
22
|
export declare const MAX_BINARY_ATTACHMENT_BYTES: number;
|
|
@@ -93,3 +96,49 @@ export declare function attachmentSizeErrorMessage(name: string, actualBytes: nu
|
|
|
93
96
|
/** Human-readable error for a chat message whose combined attachments exceed
|
|
94
97
|
* the aggregate raw-byte ceiling. */
|
|
95
98
|
export declare function attachmentTotalSizeErrorMessage(totalBytes: number, limitBytes: number): string;
|
|
99
|
+
/** Verdict of a path check: OK, or a rejection naming why. Mirrors
|
|
100
|
+
* `SandboxMentionPathCheck` in `./wire`. */
|
|
101
|
+
export type AttachmentPathCheck = {
|
|
102
|
+
succeeded: true;
|
|
103
|
+
} | {
|
|
104
|
+
succeeded: false;
|
|
105
|
+
error: string;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Default path validator when a caller supplies none. Rejects the ways a path
|
|
109
|
+
* picked in a client can escape the store root — traversal (`..` segment),
|
|
110
|
+
* absolute (leading `/`), backslashes, null bytes, control characters (see
|
|
111
|
+
* {@link CONTROL_CHARS} — a path also feeds {@link buildAttachmentPromptBlock}'s
|
|
112
|
+
* `(vault: ${path})` pointer, so it is exposed to the same injection surface as
|
|
113
|
+
* `name`) — plus a dotfile/hidden segment (a leading `.` on any segment).
|
|
114
|
+
* Generalized from gtm's `validateVaultFilePath`, in the spirit of
|
|
115
|
+
* `validateSandboxMentionPath` (`/chat-routes`'s wire mention-path validator) —
|
|
116
|
+
* but the dotfile rejection here is INTENTIONALLY stricter than that sibling:
|
|
117
|
+
* an uploaded attachment path is sanitized store-relative storage the product
|
|
118
|
+
* itself assigned, whereas a mention path points at a file that already exists
|
|
119
|
+
* in the sandbox and may legitimately live under a dotfile segment. A caller
|
|
120
|
+
* that needs gtm's exact (looser) rule can supply `validatePath` to override
|
|
121
|
+
* this default entirely.
|
|
122
|
+
*/
|
|
123
|
+
export declare function defaultValidateAttachmentPath(path: string): AttachmentPathCheck;
|
|
124
|
+
/** Structural limits for {@link parseChatAttachmentInputs}. */
|
|
125
|
+
export interface ParseChatAttachmentInputsOptions {
|
|
126
|
+
/** Most attachments one request may carry. Default {@link ATTACHMENT_MAX_COUNT}. */
|
|
127
|
+
maxCount?: number;
|
|
128
|
+
/** Path validator override. Default {@link defaultValidateAttachmentPath}. */
|
|
129
|
+
validatePath?: (path: string) => AttachmentPathCheck;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Validate an `attachments` value's shape without reading the store: an
|
|
133
|
+
* array of at most `maxCount` {@link ChatAttachmentInput}s with valid,
|
|
134
|
+
* distinct paths. Absent (`undefined`/`null`) is an empty list. Sizes are
|
|
135
|
+
* still client-reported here; {@link resolveChatAttachments} re-derives them
|
|
136
|
+
* from the store.
|
|
137
|
+
*/
|
|
138
|
+
export declare function parseChatAttachmentInputs(value: unknown, options?: ParseChatAttachmentInputsOptions): {
|
|
139
|
+
succeeded: true;
|
|
140
|
+
value: ChatAttachmentInput[];
|
|
141
|
+
} | {
|
|
142
|
+
succeeded: false;
|
|
143
|
+
error: string;
|
|
144
|
+
};
|
|
@@ -22,9 +22,11 @@ import {
|
|
|
22
22
|
attachmentSizeErrorMessage,
|
|
23
23
|
attachmentTotalSizeErrorMessage,
|
|
24
24
|
checkAttachmentType,
|
|
25
|
+
defaultValidateAttachmentPath,
|
|
26
|
+
parseChatAttachmentInputs,
|
|
25
27
|
sanitizeAttachmentFileName,
|
|
26
28
|
sniffBinary
|
|
27
|
-
} from "../chunk-
|
|
29
|
+
} from "../chunk-PBQYVAB6.js";
|
|
28
30
|
import {
|
|
29
31
|
DEFAULT_STALE_TURN_LOCK_GRACE_MS,
|
|
30
32
|
DEFAULT_TERMINAL_TURN_LOCK_GRACE_MS,
|
|
@@ -72,7 +74,7 @@ import {
|
|
|
72
74
|
rowIdOf,
|
|
73
75
|
storeSupportsDraftPersistence,
|
|
74
76
|
streamChatRouteAsSandboxEvents
|
|
75
|
-
} from "../chunk-
|
|
77
|
+
} from "../chunk-Q2H5FKVG.js";
|
|
76
78
|
import "../chunk-Q7WEEN7P.js";
|
|
77
79
|
import "../chunk-UTAIRVOK.js";
|
|
78
80
|
import "../chunk-RN4WPTBH.js";
|
|
@@ -87,7 +89,8 @@ import {
|
|
|
87
89
|
attachmentInputToPart,
|
|
88
90
|
attachmentKindForMime,
|
|
89
91
|
toChatMessageParts
|
|
90
|
-
} from "../chunk-
|
|
92
|
+
} from "../chunk-E6UTFXKQ.js";
|
|
93
|
+
import "../chunk-ZVEEWGDK.js";
|
|
91
94
|
import {
|
|
92
95
|
ChatTurnInputError,
|
|
93
96
|
DISPATCH_MAX_MEDIA_PARTS,
|
|
@@ -121,7 +124,6 @@ import {
|
|
|
121
124
|
turnResponseEventFor,
|
|
122
125
|
validateSandboxMentionPath
|
|
123
126
|
} from "../chunk-YHRWZZJN.js";
|
|
124
|
-
import "../chunk-ZVEEWGDK.js";
|
|
125
127
|
import {
|
|
126
128
|
isWorkspaceFileExportable
|
|
127
129
|
} from "../chunk-TXD5HXLE.js";
|
|
@@ -2465,83 +2467,11 @@ function createAtomicAttachmentWriter(input) {
|
|
|
2465
2467
|
}
|
|
2466
2468
|
|
|
2467
2469
|
// src/chat-routes/resolve-attachments.ts
|
|
2468
|
-
var MAX_ATTACHMENT_NAME_LENGTH = 256;
|
|
2469
|
-
function isAttachmentKind(value) {
|
|
2470
|
-
return value === "image" || value === "file";
|
|
2471
|
-
}
|
|
2472
|
-
var CONTROL_CHARS = /[\x00-\x1F\x7F]/;
|
|
2473
|
-
function defaultValidateAttachmentPath(path) {
|
|
2474
|
-
if (path.includes("\0")) return { succeeded: false, error: "attachment path must not contain null bytes" };
|
|
2475
|
-
if (path.includes("\\")) return { succeeded: false, error: "attachment path must not contain backslashes" };
|
|
2476
|
-
if (CONTROL_CHARS.test(path)) return { succeeded: false, error: "attachment path must not contain control characters" };
|
|
2477
|
-
if (path.startsWith("/")) return { succeeded: false, error: "attachment path must be store-relative, not absolute" };
|
|
2478
|
-
const segments = path.split("/");
|
|
2479
|
-
if (segments.some((segment) => segment === "..")) {
|
|
2480
|
-
return { succeeded: false, error: 'attachment path must not contain ".." segments' };
|
|
2481
|
-
}
|
|
2482
|
-
if (segments.some((segment) => segment.startsWith("."))) {
|
|
2483
|
-
return { succeeded: false, error: "attachment path must not contain a hidden (dotfile) segment" };
|
|
2484
|
-
}
|
|
2485
|
-
return { succeeded: true };
|
|
2486
|
-
}
|
|
2487
|
-
function parseAttachmentInput(value, index, validatePath) {
|
|
2488
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
2489
|
-
return { succeeded: false, error: `attachments[${index}] must be an object` };
|
|
2490
|
-
}
|
|
2491
|
-
const record2 = value;
|
|
2492
|
-
const path = record2.path;
|
|
2493
|
-
if (typeof path !== "string" || !path) {
|
|
2494
|
-
return { succeeded: false, error: `attachments[${index}].path must be a non-empty string` };
|
|
2495
|
-
}
|
|
2496
|
-
const name = record2.name;
|
|
2497
|
-
if (typeof name !== "string" || !name.trim()) {
|
|
2498
|
-
return { succeeded: false, error: `attachments[${index}].name must be a non-empty string` };
|
|
2499
|
-
}
|
|
2500
|
-
if (name.length > MAX_ATTACHMENT_NAME_LENGTH) {
|
|
2501
|
-
return { succeeded: false, error: `attachments[${index}].name must not exceed ${MAX_ATTACHMENT_NAME_LENGTH} characters` };
|
|
2502
|
-
}
|
|
2503
|
-
if (CONTROL_CHARS.test(name)) {
|
|
2504
|
-
return { succeeded: false, error: `attachments[${index}].name must not contain control characters` };
|
|
2505
|
-
}
|
|
2506
|
-
const size = record2.size;
|
|
2507
|
-
if (typeof size !== "number" || !Number.isFinite(size)) {
|
|
2508
|
-
return { succeeded: false, error: `attachments[${index}].size must be a finite number` };
|
|
2509
|
-
}
|
|
2510
|
-
if (size < 0) {
|
|
2511
|
-
return { succeeded: false, error: `attachments[${index}].size must not be negative` };
|
|
2512
|
-
}
|
|
2513
|
-
const mediaType = record2.mediaType;
|
|
2514
|
-
if (typeof mediaType !== "string") {
|
|
2515
|
-
return { succeeded: false, error: `attachments[${index}].mediaType must be a string` };
|
|
2516
|
-
}
|
|
2517
|
-
const kind = record2.kind;
|
|
2518
|
-
if (!isAttachmentKind(kind)) {
|
|
2519
|
-
return { succeeded: false, error: `attachments[${index}].kind must be "image" or "file"` };
|
|
2520
|
-
}
|
|
2521
|
-
const pathCheck = validatePath(path);
|
|
2522
|
-
if (!pathCheck.succeeded) return { succeeded: false, error: pathCheck.error };
|
|
2523
|
-
return { succeeded: true, value: { path, name, size, mediaType, kind } };
|
|
2524
|
-
}
|
|
2525
2470
|
async function resolveChatAttachments(value, options) {
|
|
2526
|
-
const maxCount = options.maxCount ?? ATTACHMENT_MAX_COUNT;
|
|
2527
2471
|
const maxTotalBytes = options.maxTotalBytes ?? MAX_ATTACHMENT_TOTAL_BYTES;
|
|
2528
|
-
const
|
|
2529
|
-
if (
|
|
2530
|
-
|
|
2531
|
-
if (value.length > maxCount) {
|
|
2532
|
-
return { succeeded: false, error: `attachments must not exceed ${maxCount} entries` };
|
|
2533
|
-
}
|
|
2534
|
-
const inputs = [];
|
|
2535
|
-
const seenPaths = /* @__PURE__ */ new Set();
|
|
2536
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
2537
|
-
const parsed = parseAttachmentInput(value[index], index, validatePath);
|
|
2538
|
-
if (!parsed.succeeded) return parsed;
|
|
2539
|
-
if (seenPaths.has(parsed.value.path)) {
|
|
2540
|
-
return { succeeded: false, error: `attachments must not repeat a path: ${parsed.value.path}` };
|
|
2541
|
-
}
|
|
2542
|
-
seenPaths.add(parsed.value.path);
|
|
2543
|
-
inputs.push(parsed.value);
|
|
2544
|
-
}
|
|
2472
|
+
const parsed = parseChatAttachmentInputs(value, options);
|
|
2473
|
+
if (!parsed.succeeded) return parsed;
|
|
2474
|
+
const inputs = parsed.value;
|
|
2545
2475
|
const advisoryTotal = inputs.reduce((sum2, input) => sum2 + input.size, 0);
|
|
2546
2476
|
if (advisoryTotal > maxTotalBytes) {
|
|
2547
2477
|
return { succeeded: false, error: attachmentTotalSizeErrorMessage(advisoryTotal, maxTotalBytes) };
|
|
@@ -3636,6 +3566,7 @@ export {
|
|
|
3636
3566
|
normalizeChatPromptForSandbox,
|
|
3637
3567
|
observeChatTurnStream,
|
|
3638
3568
|
observeNativeCompletion,
|
|
3569
|
+
parseChatAttachmentInputs,
|
|
3639
3570
|
parseChatTurnParts,
|
|
3640
3571
|
parseFileMentions,
|
|
3641
3572
|
parsePlanFollowUpAttach,
|