pilotswarm-sdk 0.5.11 → 0.5.12
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/artifact-tools.d.ts +22 -16
- package/dist/artifact-tools.d.ts.map +1 -1
- package/dist/artifact-tools.js +252 -100
- package/dist/artifact-tools.js.map +1 -1
- package/dist/blob-store.d.ts +50 -8
- package/dist/blob-store.d.ts.map +1 -1
- package/dist/blob-store.js +128 -16
- package/dist/blob-store.js.map +1 -1
- package/dist/orchestration/agents.js +2 -2
- package/dist/orchestration/agents.js.map +1 -1
- package/dist/session-proxy.d.ts.map +1 -1
- package/dist/session-proxy.js +2 -1
- package/dist/session-proxy.js.map +1 -1
- package/dist/session-store.d.ts +28 -1
- package/dist/session-store.d.ts.map +1 -1
- package/dist/session-store.js +110 -0
- package/dist/session-store.js.map +1 -1
- package/package.json +1 -1
- package/plugins/system/agents/default.agent.md +19 -16
package/dist/artifact-tools.d.ts
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Artifact Tools —
|
|
2
|
+
* Artifact Tools — agent-facing surface over the artifact store.
|
|
3
3
|
*
|
|
4
|
-
* Three tools
|
|
5
|
-
*
|
|
6
|
-
* - `read_artifact` — read a file from another session's artifacts
|
|
7
|
-
* - `export_artifact` — return an artifact:// URI for TUI on-demand download
|
|
4
|
+
* Three tools, consolidated along the source/destination axis so the model's
|
|
5
|
+
* mental picture stays "read and write":
|
|
8
6
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* - `write_artifact` — store bytes from exactly one of three sources:
|
|
8
|
+
* content (inline, model-authored — the only path where bytes
|
|
9
|
+
* transit the context window)
|
|
10
|
+
* fromFile (worker-local path → streamed; zero payload tokens)
|
|
11
|
+
* fromArtifact (server-side copy from another session, with optional
|
|
12
|
+
* SHA-256 precondition)
|
|
13
|
+
* - `read_artifact` — fetch metadata (`metaOnly`), stream to a worker-local
|
|
14
|
+
* file (`toFile`), or return content inline (utf-8 or base64, bounded).
|
|
15
|
+
* - `list_artifacts` — discovery, with full provenance metadata.
|
|
11
16
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
17
|
+
* Every result carries { sha256, sizeBytes, contentType, isBinary,
|
|
18
|
+
* artifactLink, … } so provenance verification never requires a transfer.
|
|
19
|
+
*
|
|
20
|
+
* DESIGN RULE (born from the 2026-07-12 Diagon Alley incident): the model is
|
|
21
|
+
* a control plane, not a wire. Payloads that already exist as bytes must move
|
|
22
|
+
* via `fromFile` / `fromArtifact` / `toFile`, never by being reproduced as
|
|
23
|
+
* model tokens. Inline reads are size-guarded for the same reason.
|
|
16
24
|
*
|
|
17
25
|
* @module
|
|
18
26
|
* @internal
|
|
@@ -20,11 +28,9 @@
|
|
|
20
28
|
import type { Tool } from "@github/copilot-sdk";
|
|
21
29
|
import type { ArtifactStore } from "./session-store.js";
|
|
22
30
|
/**
|
|
23
|
-
* Create artifact tools bound to the given
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* (FilesystemArtifactStore). The `sessionId` for write/export operations
|
|
27
|
-
* is injected by the tool handler via the session context.
|
|
31
|
+
* Create the artifact tools bound to the given store. The store can be Azure
|
|
32
|
+
* Blob (SessionBlobStore) or local filesystem (FilesystemArtifactStore); the
|
|
33
|
+
* `sessionId` for writes is injected via the session context.
|
|
28
34
|
*/
|
|
29
35
|
export declare function createArtifactTools(opts: {
|
|
30
36
|
blobStore: ArtifactStore;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-tools.d.ts","sourceRoot":"","sources":["../src/artifact-tools.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"artifact-tools.d.ts","sourceRoot":"","sources":["../src/artifact-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAOH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AA6DxD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACtC,SAAS,EAAE,aAAa,CAAC;CAC5B,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAoUd"}
|
package/dist/artifact-tools.js
CHANGED
|
@@ -1,132 +1,327 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Artifact Tools —
|
|
2
|
+
* Artifact Tools — agent-facing surface over the artifact store.
|
|
3
3
|
*
|
|
4
|
-
* Three tools
|
|
5
|
-
*
|
|
6
|
-
* - `read_artifact` — read a file from another session's artifacts
|
|
7
|
-
* - `export_artifact` — return an artifact:// URI for TUI on-demand download
|
|
4
|
+
* Three tools, consolidated along the source/destination axis so the model's
|
|
5
|
+
* mental picture stays "read and write":
|
|
8
6
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* - `write_artifact` — store bytes from exactly one of three sources:
|
|
8
|
+
* content (inline, model-authored — the only path where bytes
|
|
9
|
+
* transit the context window)
|
|
10
|
+
* fromFile (worker-local path → streamed; zero payload tokens)
|
|
11
|
+
* fromArtifact (server-side copy from another session, with optional
|
|
12
|
+
* SHA-256 precondition)
|
|
13
|
+
* - `read_artifact` — fetch metadata (`metaOnly`), stream to a worker-local
|
|
14
|
+
* file (`toFile`), or return content inline (utf-8 or base64, bounded).
|
|
15
|
+
* - `list_artifacts` — discovery, with full provenance metadata.
|
|
11
16
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
17
|
+
* Every result carries { sha256, sizeBytes, contentType, isBinary,
|
|
18
|
+
* artifactLink, … } so provenance verification never requires a transfer.
|
|
19
|
+
*
|
|
20
|
+
* DESIGN RULE (born from the 2026-07-12 Diagon Alley incident): the model is
|
|
21
|
+
* a control plane, not a wire. Payloads that already exist as bytes must move
|
|
22
|
+
* via `fromFile` / `fromArtifact` / `toFile`, never by being reproduced as
|
|
23
|
+
* model tokens. Inline reads are size-guarded for the same reason.
|
|
16
24
|
*
|
|
17
25
|
* @module
|
|
18
26
|
* @internal
|
|
19
27
|
*/
|
|
28
|
+
import crypto from "node:crypto";
|
|
29
|
+
import fs from "node:fs";
|
|
30
|
+
import os from "node:os";
|
|
31
|
+
import path from "node:path";
|
|
20
32
|
import { defineTool } from "@github/copilot-sdk";
|
|
33
|
+
const INLINE_READ_DEFAULT_BYTES = 65_536;
|
|
34
|
+
const INLINE_READ_MAX_BYTES = 262_144;
|
|
35
|
+
function artifactLink(sessionId, filename) {
|
|
36
|
+
return `artifact://${sessionId}/${filename}`;
|
|
37
|
+
}
|
|
38
|
+
function toolError(code, message, hint) {
|
|
39
|
+
return JSON.stringify({ error: code, message, ...(hint ? { hint } : {}) });
|
|
40
|
+
}
|
|
21
41
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
|
|
26
|
-
|
|
42
|
+
* Worker-local paths handed to fromFile/toFile are jailed to a set of allowed
|
|
43
|
+
* roots (default: the process working directory and the OS temp dir, where
|
|
44
|
+
* session `bash` work lands). Symlink escapes are rejected via realpath.
|
|
45
|
+
*/
|
|
46
|
+
function allowedFileRoots() {
|
|
47
|
+
const configured = (process.env.PILOTSWARM_ARTIFACT_FILE_ROOTS || "")
|
|
48
|
+
.split(path.delimiter)
|
|
49
|
+
.map((entry) => entry.trim())
|
|
50
|
+
.filter(Boolean);
|
|
51
|
+
const roots = configured.length > 0 ? configured : [process.cwd(), os.tmpdir()];
|
|
52
|
+
return roots.map((root) => {
|
|
53
|
+
const resolved = path.resolve(root);
|
|
54
|
+
try {
|
|
55
|
+
return fs.realpathSync(resolved);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return resolved;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function resolveJailedPath(candidate, mustExist) {
|
|
63
|
+
const resolved = path.resolve(String(candidate || ""));
|
|
64
|
+
// realpath the deepest existing ancestor so symlinks can't tunnel out.
|
|
65
|
+
let probe = mustExist ? resolved : path.dirname(resolved);
|
|
66
|
+
while (!fs.existsSync(probe)) {
|
|
67
|
+
const parent = path.dirname(probe);
|
|
68
|
+
if (parent === probe)
|
|
69
|
+
break;
|
|
70
|
+
probe = parent;
|
|
71
|
+
}
|
|
72
|
+
let real;
|
|
73
|
+
try {
|
|
74
|
+
real = fs.realpathSync(probe);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return { error: `Path is not accessible: ${candidate}` };
|
|
78
|
+
}
|
|
79
|
+
const effective = mustExist ? real : path.join(real, path.relative(probe, resolved));
|
|
80
|
+
const roots = allowedFileRoots();
|
|
81
|
+
const inJail = roots.some((root) => effective === root || effective.startsWith(root + path.sep));
|
|
82
|
+
if (!inJail) {
|
|
83
|
+
return { error: `Path is outside the allowed roots (${roots.join(", ")}): ${candidate}` };
|
|
84
|
+
}
|
|
85
|
+
if (mustExist && !fs.existsSync(effective)) {
|
|
86
|
+
return { error: `File not found: ${candidate}` };
|
|
87
|
+
}
|
|
88
|
+
return { path: effective };
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create the artifact tools bound to the given store. The store can be Azure
|
|
92
|
+
* Blob (SessionBlobStore) or local filesystem (FilesystemArtifactStore); the
|
|
93
|
+
* `sessionId` for writes is injected via the session context.
|
|
27
94
|
*/
|
|
28
95
|
export function createArtifactTools(opts) {
|
|
29
96
|
const { blobStore } = opts;
|
|
30
97
|
// ── write_artifact ─────────────────────────────────────────
|
|
31
98
|
const writeTool = defineTool("write_artifact", {
|
|
32
|
-
description: "Write
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
99
|
+
description: "Write an artifact from EXACTLY ONE of three sources: inline `content` (text you are authoring), " +
|
|
100
|
+
"`fromFile` (a worker-local file path — streamed server-side, use this for anything that already " +
|
|
101
|
+
"exists as a file, especially binaries and archives), or `fromArtifact` (server-side copy from " +
|
|
102
|
+
"another session's artifact, optionally verified against an expected SHA-256). " +
|
|
103
|
+
"Returns full metadata including sha256 and an artifact:// link — include the link in your " +
|
|
104
|
+
"response when the user should see it. Never read a file just to re-send its bytes as `content`; " +
|
|
105
|
+
"pass the path via `fromFile` instead.",
|
|
37
106
|
parameters: {
|
|
38
107
|
type: "object",
|
|
39
108
|
properties: {
|
|
40
109
|
filename: {
|
|
41
110
|
type: "string",
|
|
42
|
-
description: "
|
|
43
|
-
"
|
|
111
|
+
description: "Destination filename, e.g. 'report.md'. No path separators. " +
|
|
112
|
+
"Optional for fromFile/fromArtifact (defaults to the source basename).",
|
|
44
113
|
},
|
|
45
114
|
content: {
|
|
46
115
|
type: "string",
|
|
47
|
-
description: "
|
|
116
|
+
description: "Inline content to write (source 1 of 3). Max 1MB.",
|
|
117
|
+
},
|
|
118
|
+
encoding: {
|
|
119
|
+
type: "string",
|
|
120
|
+
enum: ["utf-8", "base64"],
|
|
121
|
+
description: "Encoding of `content`. Default 'utf-8'; 'base64' for small binary payloads.",
|
|
122
|
+
},
|
|
123
|
+
fromFile: {
|
|
124
|
+
type: "string",
|
|
125
|
+
description: "Worker-local file path to upload (source 2 of 3). Streamed — bytes never enter " +
|
|
126
|
+
"the conversation. Preferred for files created with bash/tar/build steps.",
|
|
127
|
+
},
|
|
128
|
+
fromArtifact: {
|
|
129
|
+
type: "object",
|
|
130
|
+
description: "Copy another session's artifact server-side (source 3 of 3). " +
|
|
131
|
+
"Bytes move store-to-store.",
|
|
132
|
+
properties: {
|
|
133
|
+
sessionId: { type: "string", description: "Session that owns the source artifact." },
|
|
134
|
+
filename: { type: "string", description: "Source artifact filename." },
|
|
135
|
+
expectedSha256: {
|
|
136
|
+
type: "string",
|
|
137
|
+
description: "Optional precondition: fail with SHA_MISMATCH if the copied bytes hash differently.",
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
required: ["sessionId", "filename"],
|
|
48
141
|
},
|
|
49
142
|
contentType: {
|
|
50
143
|
type: "string",
|
|
51
|
-
description: "MIME type. Default: 'text/markdown'
|
|
144
|
+
description: "MIME type. Default: 'text/markdown' for inline text; sniffed for fromFile.",
|
|
52
145
|
},
|
|
53
146
|
content_type: {
|
|
54
147
|
type: "string",
|
|
55
148
|
description: "Alias for contentType. Supported for compatibility; contentType is preferred.",
|
|
56
149
|
},
|
|
57
|
-
|
|
58
|
-
type: "
|
|
59
|
-
|
|
60
|
-
description: "Encoding for the content field. Default: 'utf-8'. Use 'base64' for binary artifacts.",
|
|
150
|
+
pin: {
|
|
151
|
+
type: "boolean",
|
|
152
|
+
description: "Pin the artifact so it survives session cleanup (deliverables).",
|
|
61
153
|
},
|
|
62
154
|
},
|
|
63
|
-
required: [
|
|
155
|
+
required: [],
|
|
64
156
|
},
|
|
65
157
|
handler: async (params, context) => {
|
|
66
158
|
const sessionId = context?.durableSessionId;
|
|
67
159
|
if (!sessionId) {
|
|
68
|
-
return
|
|
160
|
+
return toolError("NO_SESSION_CONTEXT", "No session context — cannot determine artifact path.");
|
|
161
|
+
}
|
|
162
|
+
const sources = [params.content !== undefined, !!params.fromFile, !!params.fromArtifact]
|
|
163
|
+
.filter(Boolean).length;
|
|
164
|
+
if (sources !== 1) {
|
|
165
|
+
return toolError("EXCLUSIVE_SOURCE", `write_artifact needs exactly one byte source; you provided ${sources}.`, "Pass exactly one of: content (inline text), fromFile (worker-local path), fromArtifact ({sessionId, filename}).");
|
|
69
166
|
}
|
|
167
|
+
const contentType = params.contentType ?? params.content_type;
|
|
168
|
+
const pinned = params.pin === true;
|
|
70
169
|
try {
|
|
71
|
-
|
|
170
|
+
if (params.fromFile) {
|
|
171
|
+
const jailed = resolveJailedPath(params.fromFile, true);
|
|
172
|
+
if (jailed.error)
|
|
173
|
+
return toolError("PATH_OUTSIDE_WORKDIR", jailed.error);
|
|
174
|
+
const filename = params.filename || path.basename(jailed.path);
|
|
175
|
+
const metadata = await blobStore.uploadArtifactFromFile(sessionId, filename, jailed.path, contentType, { pinned });
|
|
176
|
+
return JSON.stringify({
|
|
177
|
+
success: true,
|
|
178
|
+
sessionId,
|
|
179
|
+
...metadata,
|
|
180
|
+
artifactLink: artifactLink(sessionId, metadata.filename),
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
if (params.fromArtifact) {
|
|
184
|
+
const from = params.fromArtifact;
|
|
185
|
+
const filename = params.filename || path.basename(from.filename);
|
|
186
|
+
const metadata = await blobStore.copyArtifact(from.sessionId, from.filename, sessionId, filename, { pinned });
|
|
187
|
+
if (from.expectedSha256 && metadata.sha256 !== from.expectedSha256) {
|
|
188
|
+
await blobStore.deleteArtifact(sessionId, metadata.filename);
|
|
189
|
+
return toolError("SHA_MISMATCH", `Copied bytes hash ${metadata.sha256}, expected ${from.expectedSha256}. The copy was deleted.`, "The source artifact is not the bytes you believed. Re-verify the source with read_artifact({metaOnly: true}).");
|
|
190
|
+
}
|
|
191
|
+
return JSON.stringify({
|
|
192
|
+
success: true,
|
|
193
|
+
sessionId,
|
|
194
|
+
...metadata,
|
|
195
|
+
artifactLink: artifactLink(sessionId, metadata.filename),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
if (!params.filename) {
|
|
199
|
+
return toolError("FILENAME_REQUIRED", "filename is required when writing inline content.");
|
|
200
|
+
}
|
|
201
|
+
const metadata = await blobStore.uploadArtifact(sessionId, params.filename, params.content, contentType, { encoding: params.encoding, pinned });
|
|
72
202
|
return JSON.stringify({
|
|
73
203
|
success: true,
|
|
74
204
|
sessionId,
|
|
75
205
|
...metadata,
|
|
206
|
+
artifactLink: artifactLink(sessionId, metadata.filename),
|
|
76
207
|
});
|
|
77
208
|
}
|
|
78
209
|
catch (err) {
|
|
79
|
-
return
|
|
210
|
+
return toolError(err?.code || "ARTIFACT_WRITE_FAILED", err.message);
|
|
80
211
|
}
|
|
81
212
|
},
|
|
82
213
|
});
|
|
83
214
|
// ── read_artifact ──────────────────────────────────────────
|
|
84
215
|
const readTool = defineTool("read_artifact", {
|
|
85
|
-
description: "Read a
|
|
86
|
-
"
|
|
87
|
-
"
|
|
216
|
+
description: "Read a session artifact (yours or another session's). Three modes: default returns text content " +
|
|
217
|
+
"inline (bounded by maxBytes, use offset to page); `toFile` streams the artifact to a worker-local " +
|
|
218
|
+
"path without the bytes entering the conversation (REQUIRED for large or binary artifacts you want " +
|
|
219
|
+
"to process with bash); `metaOnly` returns just metadata (size, sha256, contentType) — use it to " +
|
|
220
|
+
"verify provenance cheaply. Small binary artifacts can be read inline with encoding='base64'.",
|
|
88
221
|
parameters: {
|
|
89
222
|
type: "object",
|
|
90
223
|
properties: {
|
|
91
224
|
sessionId: {
|
|
92
225
|
type: "string",
|
|
93
|
-
description: "The session
|
|
94
|
-
"or another agent's session ID to read their files.",
|
|
226
|
+
description: "The session that owns the artifact (your own session ID for your files).",
|
|
95
227
|
},
|
|
96
|
-
filename: {
|
|
228
|
+
filename: { type: "string", description: "The artifact filename, e.g. 'report.md'." },
|
|
229
|
+
metaOnly: {
|
|
230
|
+
type: "boolean",
|
|
231
|
+
description: "Return metadata only — no content transfer.",
|
|
232
|
+
},
|
|
233
|
+
toFile: {
|
|
97
234
|
type: "string",
|
|
98
|
-
description: "
|
|
235
|
+
description: "Write the artifact to this worker-local path instead of returning content. " +
|
|
236
|
+
"Zero context cost; works for any size and any content type.",
|
|
237
|
+
},
|
|
238
|
+
encoding: {
|
|
239
|
+
type: "string",
|
|
240
|
+
enum: ["utf-8", "base64"],
|
|
241
|
+
description: "Inline content encoding. 'base64' permits reading small binary artifacts inline.",
|
|
242
|
+
},
|
|
243
|
+
maxBytes: {
|
|
244
|
+
type: "number",
|
|
245
|
+
description: `Max bytes returned inline (default ${INLINE_READ_DEFAULT_BYTES}, hard cap ${INLINE_READ_MAX_BYTES}). Result sets truncated=true when the artifact is larger.`,
|
|
246
|
+
},
|
|
247
|
+
offset: {
|
|
248
|
+
type: "number",
|
|
249
|
+
description: "Byte offset for inline reads — page through large text artifacts.",
|
|
99
250
|
},
|
|
100
251
|
},
|
|
101
252
|
required: ["sessionId", "filename"],
|
|
102
253
|
},
|
|
103
254
|
handler: async (params) => {
|
|
255
|
+
if (params.metaOnly && params.toFile) {
|
|
256
|
+
return toolError("EXCLUSIVE_MODE", "metaOnly and toFile are mutually exclusive.", "Use metaOnly for metadata, toFile to materialize bytes, or neither for inline content.");
|
|
257
|
+
}
|
|
104
258
|
try {
|
|
105
|
-
|
|
259
|
+
if (params.metaOnly) {
|
|
260
|
+
const metadata = await blobStore.statArtifact(params.sessionId, params.filename);
|
|
261
|
+
if (!metadata) {
|
|
262
|
+
return toolError("ARTIFACT_NOT_FOUND", `Artifact not found: ${params.filename} in session ${params.sessionId}`);
|
|
263
|
+
}
|
|
264
|
+
return JSON.stringify({
|
|
265
|
+
success: true,
|
|
266
|
+
sessionId: params.sessionId,
|
|
267
|
+
...metadata,
|
|
268
|
+
artifactLink: artifactLink(params.sessionId, metadata.filename),
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
if (params.toFile) {
|
|
272
|
+
const jailed = resolveJailedPath(params.toFile, false);
|
|
273
|
+
if (jailed.error)
|
|
274
|
+
return toolError("PATH_OUTSIDE_WORKDIR", jailed.error);
|
|
275
|
+
const result = await blobStore.downloadArtifact(params.sessionId, params.filename);
|
|
276
|
+
fs.mkdirSync(path.dirname(jailed.path), { recursive: true });
|
|
277
|
+
fs.writeFileSync(jailed.path, result.body);
|
|
278
|
+
const { body: _body, ...metadata } = result;
|
|
279
|
+
return JSON.stringify({
|
|
280
|
+
success: true,
|
|
281
|
+
sessionId: params.sessionId,
|
|
282
|
+
path: jailed.path,
|
|
283
|
+
...metadata,
|
|
284
|
+
sha256: metadata.sha256 || crypto.createHash("sha256").update(result.body).digest("hex"),
|
|
285
|
+
artifactLink: artifactLink(params.sessionId, metadata.filename),
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
const result = await blobStore.downloadArtifact(params.sessionId, params.filename);
|
|
289
|
+
const encoding = params.encoding || "utf-8";
|
|
290
|
+
if (result.isBinary && encoding !== "base64") {
|
|
291
|
+
return JSON.stringify({
|
|
292
|
+
error: "ARTIFACT_IS_BINARY",
|
|
293
|
+
message: `Artifact '${params.filename}' is binary (${result.contentType}, ${result.sizeBytes} bytes) and cannot be returned as text.`,
|
|
294
|
+
hint: "Use toFile to materialize it on the worker filesystem, or encoding='base64' if it is small enough to inspect inline.",
|
|
295
|
+
contentType: result.contentType,
|
|
296
|
+
sizeBytes: result.sizeBytes,
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
const maxBytes = Math.min(Math.max(1, Math.floor(params.maxBytes ?? INLINE_READ_DEFAULT_BYTES)), INLINE_READ_MAX_BYTES);
|
|
300
|
+
const offset = Math.max(0, Math.floor(params.offset ?? 0));
|
|
301
|
+
const slice = result.body.subarray(offset, offset + maxBytes);
|
|
302
|
+
const truncated = offset > 0 || offset + slice.length < result.body.length;
|
|
303
|
+
const { body: _body, ...metadata } = result;
|
|
106
304
|
return JSON.stringify({
|
|
107
305
|
success: true,
|
|
108
306
|
sessionId: params.sessionId,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
307
|
+
...metadata,
|
|
308
|
+
sha256: metadata.sha256 || crypto.createHash("sha256").update(result.body).digest("hex"),
|
|
309
|
+
content: slice.toString(encoding === "base64" ? "base64" : "utf8"),
|
|
310
|
+
truncated,
|
|
311
|
+
...(truncated ? { range: { offset, length: slice.length } } : {}),
|
|
312
|
+
artifactLink: artifactLink(params.sessionId, metadata.filename),
|
|
112
313
|
});
|
|
113
314
|
}
|
|
114
315
|
catch (err) {
|
|
115
|
-
|
|
116
|
-
return JSON.stringify({
|
|
117
|
-
error: "ARTIFACT_IS_BINARY",
|
|
118
|
-
contentType: err.contentType,
|
|
119
|
-
sizeBytes: err.sizeBytes,
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
return JSON.stringify({ error: err.message });
|
|
316
|
+
return toolError(err?.code || "ARTIFACT_READ_FAILED", err.message);
|
|
123
317
|
}
|
|
124
318
|
},
|
|
125
319
|
});
|
|
126
320
|
// ── list_artifacts ─────────────────────────────────────────
|
|
127
321
|
const listTool = defineTool("list_artifacts", {
|
|
128
|
-
description: "List all artifact files in a session's storage folder
|
|
129
|
-
"Returns filenames that can be read
|
|
322
|
+
description: "List all artifact files in a session's storage folder, with full metadata " +
|
|
323
|
+
"(sizeBytes, contentType, sha256, pinned). Returns filenames that can be read " +
|
|
324
|
+
"with `read_artifact`.",
|
|
130
325
|
parameters: {
|
|
131
326
|
type: "object",
|
|
132
327
|
properties: {
|
|
@@ -141,7 +336,7 @@ export function createArtifactTools(opts) {
|
|
|
141
336
|
handler: async (params, context) => {
|
|
142
337
|
const targetId = params.sessionId || context?.durableSessionId;
|
|
143
338
|
if (!targetId) {
|
|
144
|
-
return
|
|
339
|
+
return toolError("NO_SESSION_CONTEXT", "No session ID provided or available from context.");
|
|
145
340
|
}
|
|
146
341
|
try {
|
|
147
342
|
const files = await blobStore.listArtifacts(targetId);
|
|
@@ -154,53 +349,10 @@ export function createArtifactTools(opts) {
|
|
|
154
349
|
});
|
|
155
350
|
}
|
|
156
351
|
catch (err) {
|
|
157
|
-
return
|
|
158
|
-
}
|
|
159
|
-
},
|
|
160
|
-
});
|
|
161
|
-
// ── export_artifact ────────────────────────────────────────
|
|
162
|
-
const exportTool = defineTool("export_artifact", {
|
|
163
|
-
description: "Make a file available for the TUI user to download. " +
|
|
164
|
-
"Returns an artifact:// link that the TUI renders as a clickable download. " +
|
|
165
|
-
"You MUST include the returned artifact:// link in your response text " +
|
|
166
|
-
"so the user can see and download it.\n\n" +
|
|
167
|
-
"You must have written the file with `write_artifact` first.",
|
|
168
|
-
parameters: {
|
|
169
|
-
type: "object",
|
|
170
|
-
properties: {
|
|
171
|
-
filename: {
|
|
172
|
-
type: "string",
|
|
173
|
-
description: "The filename to export, e.g. 'report.md'.",
|
|
174
|
-
},
|
|
175
|
-
},
|
|
176
|
-
required: ["filename"],
|
|
177
|
-
},
|
|
178
|
-
handler: async (params, context) => {
|
|
179
|
-
const sessionId = context?.durableSessionId;
|
|
180
|
-
if (!sessionId) {
|
|
181
|
-
return JSON.stringify({ error: "No session context — cannot determine artifact path." });
|
|
182
|
-
}
|
|
183
|
-
try {
|
|
184
|
-
// Verify the file exists
|
|
185
|
-
const exists = await blobStore.artifactExists(sessionId, params.filename);
|
|
186
|
-
if (!exists) {
|
|
187
|
-
return JSON.stringify({
|
|
188
|
-
error: `Artifact '${params.filename}' not found. Write it first with write_artifact.`,
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
const artifactUri = `artifact://${sessionId}/${params.filename}`;
|
|
192
|
-
return JSON.stringify({
|
|
193
|
-
success: true,
|
|
194
|
-
filename: params.filename,
|
|
195
|
-
artifactLink: artifactUri,
|
|
196
|
-
message: "Include the artifactLink in your response. The TUI will render it as a downloadable link.",
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
catch (err) {
|
|
200
|
-
return JSON.stringify({ error: err.message });
|
|
352
|
+
return toolError(err?.code || "ARTIFACT_LIST_FAILED", err.message);
|
|
201
353
|
}
|
|
202
354
|
},
|
|
203
355
|
});
|
|
204
|
-
return [writeTool, readTool, listTool
|
|
356
|
+
return [writeTool, readTool, listTool];
|
|
205
357
|
}
|
|
206
358
|
//# sourceMappingURL=artifact-tools.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-tools.js","sourceRoot":"","sources":["../src/artifact-tools.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"artifact-tools.js","sourceRoot":"","sources":["../src/artifact-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAIjD,MAAM,yBAAyB,GAAG,MAAM,CAAC;AACzC,MAAM,qBAAqB,GAAG,OAAO,CAAC;AAEtC,SAAS,YAAY,CAAC,SAAiB,EAAE,QAAgB;IACrD,OAAO,cAAc,SAAS,IAAI,QAAQ,EAAE,CAAC;AACjD,CAAC;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,OAAe,EAAE,IAAa;IAC3D,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB;IACrB,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,8BAA8B,IAAI,EAAE,CAAC;SAChE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;SACrB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,OAAO,CAAC,CAAC;IACrB,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAChF,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC;YACD,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,QAAQ,CAAC;QACpB,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,iBAAiB,CAAC,SAAiB,EAAE,SAAkB;IAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC;IACvD,uEAAuE;IACvE,IAAI,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,MAAM,KAAK,KAAK;YAAE,MAAM;QAC5B,KAAK,GAAG,MAAM,CAAC;IACnB,CAAC;IACD,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACD,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,KAAK,EAAE,2BAA2B,SAAS,EAAE,EAAE,CAAC;IAC7D,CAAC;IACD,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IACrF,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,KAAK,IAAI,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACjG,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,EAAE,KAAK,EAAE,sCAAsC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,SAAS,EAAE,EAAE,CAAC;IAC9F,CAAC;IACD,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACzC,OAAO,EAAE,KAAK,EAAE,mBAAmB,SAAS,EAAE,EAAE,CAAC;IACrD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAC/B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAEnC;IACG,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAE3B,8DAA8D;IAE9D,MAAM,SAAS,GAAG,UAAU,CAAC,gBAAgB,EAAE;QAC3C,WAAW,EACP,kGAAkG;YAClG,kGAAkG;YAClG,gGAAgG;YAChG,gFAAgF;YAChF,4FAA4F;YAC5F,kGAAkG;YAClG,uCAAuC;QAC3C,UAAU,EAAE;YACR,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACR,QAAQ,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EACP,8DAA8D;wBAC9D,uEAAuE;iBAC9E;gBACD,OAAO,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,mDAAmD;iBACnE;gBACD,QAAQ,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;oBACzB,WAAW,EAAE,6EAA6E;iBAC7F;gBACD,QAAQ,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EACP,iFAAiF;wBACjF,0EAA0E;iBACjF;gBACD,YAAY,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,WAAW,EACP,+DAA+D;wBAC/D,4BAA4B;oBAChC,UAAU,EAAE;wBACR,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wCAAwC,EAAE;wBACpF,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2BAA2B,EAAE;wBACtE,cAAc,EAAE;4BACZ,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,qFAAqF;yBACrG;qBACJ;oBACD,QAAQ,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC;iBACtC;gBACD,WAAW,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,4EAA4E;iBAC5F;gBACD,YAAY,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,+EAA+E;iBAC/F;gBACD,GAAG,EAAE;oBACD,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,iEAAiE;iBACjF;aACJ;YACD,QAAQ,EAAE,EAAE;SACf;QACD,OAAO,EAAE,KAAK,EAAE,MASf,EAAE,OAAY,EAAE,EAAE;YACf,MAAM,SAAS,GAAG,OAAO,EAAE,gBAAgB,CAAC;YAC5C,IAAI,CAAC,SAAS,EAAE,CAAC;gBACb,OAAO,SAAS,CAAC,oBAAoB,EAAE,sDAAsD,CAAC,CAAC;YACnG,CAAC;YAED,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;iBACnF,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;YAC5B,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;gBAChB,OAAO,SAAS,CACZ,kBAAkB,EAClB,8DAA8D,OAAO,GAAG,EACxE,iHAAiH,CACpH,CAAC;YACN,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,YAAY,CAAC;YAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,KAAK,IAAI,CAAC;YAEnC,IAAI,CAAC;gBACD,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBAClB,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;oBACxD,IAAI,MAAM,CAAC,KAAK;wBAAE,OAAO,SAAS,CAAC,sBAAsB,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;oBACzE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAK,CAAC,CAAC;oBAChE,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,sBAAsB,CACnD,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAK,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,CAC7D,CAAC;oBACF,OAAO,IAAI,CAAC,SAAS,CAAC;wBAClB,OAAO,EAAE,IAAI;wBACb,SAAS;wBACT,GAAG,QAAQ;wBACX,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC;qBAC3D,CAAC,CAAC;gBACP,CAAC;gBAED,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;oBACtB,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC;oBACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACjE,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,YAAY,CACzC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,CACjE,CAAC;oBACF,IAAI,IAAI,CAAC,cAAc,IAAI,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,cAAc,EAAE,CAAC;wBACjE,MAAM,SAAS,CAAC,cAAc,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;wBAC7D,OAAO,SAAS,CACZ,cAAc,EACd,qBAAqB,QAAQ,CAAC,MAAM,cAAc,IAAI,CAAC,cAAc,yBAAyB,EAC9F,+GAA+G,CAClH,CAAC;oBACN,CAAC;oBACD,OAAO,IAAI,CAAC,SAAS,CAAC;wBAClB,OAAO,EAAE,IAAI;wBACb,SAAS;wBACT,GAAG,QAAQ;wBACX,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC;qBAC3D,CAAC,CAAC;gBACP,CAAC;gBAED,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACnB,OAAO,SAAS,CACZ,mBAAmB,EACnB,mDAAmD,CACtD,CAAC;gBACN,CAAC;gBACD,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,cAAc,CAC3C,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAQ,EAAE,WAAW,EACxD,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,CACxC,CAAC;gBACF,OAAO,IAAI,CAAC,SAAS,CAAC;oBAClB,OAAO,EAAE,IAAI;oBACb,SAAS;oBACT,GAAG,QAAQ;oBACX,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC;iBAC3D,CAAC,CAAC;YACP,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAChB,OAAO,SAAS,CAAC,GAAG,EAAE,IAAI,IAAI,uBAAuB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YACxE,CAAC;QACL,CAAC;KACJ,CAAC,CAAC;IAEH,8DAA8D;IAE9D,MAAM,QAAQ,GAAG,UAAU,CAAC,eAAe,EAAE;QACzC,WAAW,EACP,kGAAkG;YAClG,oGAAoG;YACpG,oGAAoG;YACpG,kGAAkG;YAClG,8FAA8F;QAClG,UAAU,EAAE;YACR,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACR,SAAS,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,0EAA0E;iBAC1F;gBACD,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0CAA0C,EAAE;gBACrF,QAAQ,EAAE;oBACN,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,6CAA6C;iBAC7D;gBACD,MAAM,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EACP,6EAA6E;wBAC7E,6DAA6D;iBACpE;gBACD,QAAQ,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;oBACzB,WAAW,EAAE,kFAAkF;iBAClG;gBACD,QAAQ,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,sCAAsC,yBAAyB,cAAc,qBAAqB,4DAA4D;iBAC9K;gBACD,MAAM,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,mEAAmE;iBACnF;aACJ;YACD,QAAQ,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC;SACtC;QACD,OAAO,EAAE,KAAK,EAAE,MAQf,EAAE,EAAE;YACD,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBACnC,OAAO,SAAS,CACZ,gBAAgB,EAChB,6CAA6C,EAC7C,wFAAwF,CAC3F,CAAC;YACN,CAAC;YAED,IAAI,CAAC;gBACD,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBAClB,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACjF,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACZ,OAAO,SAAS,CAAC,oBAAoB,EAAE,uBAAuB,MAAM,CAAC,QAAQ,eAAe,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;oBACpH,CAAC;oBACD,OAAO,IAAI,CAAC,SAAS,CAAC;wBAClB,OAAO,EAAE,IAAI;wBACb,SAAS,EAAE,MAAM,CAAC,SAAS;wBAC3B,GAAG,QAAQ;wBACX,YAAY,EAAE,YAAY,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC;qBAClE,CAAC,CAAC;gBACP,CAAC;gBAED,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;oBAChB,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;oBACvD,IAAI,MAAM,CAAC,KAAK;wBAAE,OAAO,SAAS,CAAC,sBAAsB,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;oBACzE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACnF,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC9D,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,IAAK,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;oBAC5C,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,CAAC;oBAC5C,OAAO,IAAI,CAAC,SAAS,CAAC;wBAClB,OAAO,EAAE,IAAI;wBACb,SAAS,EAAE,MAAM,CAAC,SAAS;wBAC3B,IAAI,EAAE,MAAM,CAAC,IAAI;wBACjB,GAAG,QAAQ;wBACX,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;wBACxF,YAAY,EAAE,YAAY,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC;qBAClE,CAAC,CAAC;gBACP,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACnF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,OAAO,CAAC;gBAC5C,IAAI,MAAM,CAAC,QAAQ,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBAC3C,OAAO,IAAI,CAAC,SAAS,CAAC;wBAClB,KAAK,EAAE,oBAAoB;wBAC3B,OAAO,EAAE,aAAa,MAAM,CAAC,QAAQ,gBAAgB,MAAM,CAAC,WAAW,KAAK,MAAM,CAAC,SAAS,yCAAyC;wBACrI,IAAI,EAAE,sHAAsH;wBAC5H,WAAW,EAAE,MAAM,CAAC,WAAW;wBAC/B,SAAS,EAAE,MAAM,CAAC,SAAS;qBAC9B,CAAC,CAAC;gBACP,CAAC;gBAED,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CACrB,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,IAAI,yBAAyB,CAAC,CAAC,EACrE,qBAAqB,CACxB,CAAC;gBACF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC;gBAC9D,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC3E,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,CAAC;gBAC5C,OAAO,IAAI,CAAC,SAAS,CAAC;oBAClB,OAAO,EAAE,IAAI;oBACb,SAAS,EAAE,MAAM,CAAC,SAAS;oBAC3B,GAAG,QAAQ;oBACX,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;oBACxF,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;oBAClE,SAAS;oBACT,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACjE,YAAY,EAAE,YAAY,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC;iBAClE,CAAC,CAAC;YACP,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAChB,OAAO,SAAS,CAAC,GAAG,EAAE,IAAI,IAAI,sBAAsB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YACvE,CAAC;QACL,CAAC;KACJ,CAAC,CAAC;IAEH,8DAA8D;IAE9D,MAAM,QAAQ,GAAG,UAAU,CAAC,gBAAgB,EAAE;QAC1C,WAAW,EACP,4EAA4E;YAC5E,+EAA+E;YAC/E,uBAAuB;QAC3B,UAAU,EAAE;YACR,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACR,SAAS,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EACP,wCAAwC;wBACxC,2DAA2D;iBAClE;aACJ;YACD,QAAQ,EAAE,EAAE;SACf;QACD,OAAO,EAAE,KAAK,EAAE,MAA8B,EAAE,OAAY,EAAE,EAAE;YAC5D,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,IAAI,OAAO,EAAE,gBAAgB,CAAC;YAC/D,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACZ,OAAO,SAAS,CAAC,oBAAoB,EAAE,mDAAmD,CAAC,CAAC;YAChG,CAAC;YAED,IAAI,CAAC;gBACD,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;gBACtD,OAAO,IAAI,CAAC,SAAS,CAAC;oBAClB,OAAO,EAAE,IAAI;oBACb,SAAS,EAAE,QAAQ;oBACnB,KAAK;oBACL,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;oBAC7C,KAAK,EAAE,KAAK,CAAC,MAAM;iBACtB,CAAC,CAAC;YACP,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAChB,OAAO,SAAS,CAAC,GAAG,EAAE,IAAI,IAAI,sBAAsB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YACvE,CAAC;QACL,CAAC;KACJ,CAAC,CAAC;IAEH,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC3C,CAAC"}
|