@cuylabs/agent-physical 5.0.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/LICENSE +201 -0
- package/README.md +107 -0
- package/dist/chunk-G7CGE7QH.js +539 -0
- package/dist/chunk-G7CGE7QH.js.map +1 -0
- package/dist/index-pM6qWmMq.d.ts +225 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.js +17 -0
- package/dist/tools/index.js.map +1 -0
- package/docs/README.md +25 -0
- package/docs/architecture.md +66 -0
- package/docs/safety.md +31 -0
- package/package.json +64 -0
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
// src/tools/index.ts
|
|
2
|
+
import { Tool } from "@cuylabs/agent-core/tool";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
// src/safety.ts
|
|
6
|
+
var defaultPhysicalSafetyPolicy = {
|
|
7
|
+
riskLevel: "dangerous",
|
|
8
|
+
requiresApproval: true,
|
|
9
|
+
requiresHumanPresence: true
|
|
10
|
+
};
|
|
11
|
+
function normalizePhysicalSafetyPolicy(policy) {
|
|
12
|
+
return {
|
|
13
|
+
...defaultPhysicalSafetyPolicy,
|
|
14
|
+
...policy ?? {}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function isModeAllowed(mode, policy) {
|
|
18
|
+
if (!policy?.allowedModes || policy.allowedModes.length === 0) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
if (!mode) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return policy.allowedModes.includes(mode);
|
|
25
|
+
}
|
|
26
|
+
function describePhysicalState(state) {
|
|
27
|
+
const parts = [`status=${state.status}`];
|
|
28
|
+
if (state.mode) {
|
|
29
|
+
parts.push(`mode=${state.mode}`);
|
|
30
|
+
}
|
|
31
|
+
if (state.task?.id) {
|
|
32
|
+
parts.push(`task=${state.task.id}`);
|
|
33
|
+
}
|
|
34
|
+
if (state.message) {
|
|
35
|
+
parts.push(`message=${state.message}`);
|
|
36
|
+
}
|
|
37
|
+
return parts.join(", ");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/tools/index.ts
|
|
41
|
+
function toolName(name, options) {
|
|
42
|
+
return `${options?.prefix ?? "physical"}_${name}`;
|
|
43
|
+
}
|
|
44
|
+
var MAX_OBSERVATION_ITEM_CHARS = 12e3;
|
|
45
|
+
var MAX_OBSERVATION_OUTPUT_CHARS = 6e4;
|
|
46
|
+
var MAX_EXECUTION_OUTPUT_CHARS = 8e3;
|
|
47
|
+
function truncateText(value, maxChars) {
|
|
48
|
+
if (value.length <= maxChars) {
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
return `${value.slice(0, maxChars)}
|
|
52
|
+
... (${value.length - maxChars} characters omitted from this observation item)`;
|
|
53
|
+
}
|
|
54
|
+
function stringifyObservationData(value) {
|
|
55
|
+
if (typeof value === "string") {
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
return JSON.stringify(value, null, 2) ?? String(value);
|
|
60
|
+
} catch {
|
|
61
|
+
return String(value);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function asRecord(value) {
|
|
65
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
66
|
+
}
|
|
67
|
+
function compactRawDepthDiagnostics(value) {
|
|
68
|
+
const rawDepth = asRecord(value);
|
|
69
|
+
if (!rawDepth) {
|
|
70
|
+
return void 0;
|
|
71
|
+
}
|
|
72
|
+
const compact = {};
|
|
73
|
+
for (const [camera, statsValue] of Object.entries(rawDepth)) {
|
|
74
|
+
const stats = asRecord(statsValue);
|
|
75
|
+
if (!stats) {
|
|
76
|
+
compact[camera] = statsValue;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
compact[camera] = {
|
|
80
|
+
shape: stats.shape,
|
|
81
|
+
dtype: stats.dtype,
|
|
82
|
+
min: stats.min,
|
|
83
|
+
max: stats.max,
|
|
84
|
+
finiteMin: stats.finiteMin,
|
|
85
|
+
finiteMax: stats.finiteMax,
|
|
86
|
+
nanCount: stats.nanCount,
|
|
87
|
+
infCount: stats.infCount,
|
|
88
|
+
belowZeroCount: stats.belowZeroCount,
|
|
89
|
+
aboveOneCount: stats.aboveOneCount,
|
|
90
|
+
outOfRangeCount: stats.outOfRangeCount,
|
|
91
|
+
error: stats.error
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return Object.keys(compact).length > 0 ? compact : void 0;
|
|
95
|
+
}
|
|
96
|
+
function formatExecutionOutput(trace) {
|
|
97
|
+
const outcome = trace.outcome;
|
|
98
|
+
const sandboxRc = outcome?.metadata?.sandboxRc;
|
|
99
|
+
const elapsedMs = outcome?.metadata?.elapsedMs;
|
|
100
|
+
const codePath = outcome?.metadata?.codePath;
|
|
101
|
+
const diagnostics = outcome?.metadata?.diagnostics;
|
|
102
|
+
const lines = [
|
|
103
|
+
outcome ? `executionOk=${outcome.success}, taskCompleted=${outcome.taskCompleted ?? "n/a"}, reward=${outcome.reward ?? "n/a"}` : "Execution completed without an outcome."
|
|
104
|
+
];
|
|
105
|
+
if (sandboxRc !== void 0) {
|
|
106
|
+
lines.push(`sandboxRc=${sandboxRc}`);
|
|
107
|
+
}
|
|
108
|
+
if (elapsedMs !== void 0) {
|
|
109
|
+
lines.push(`elapsedMs=${elapsedMs}`);
|
|
110
|
+
}
|
|
111
|
+
if (codePath !== void 0) {
|
|
112
|
+
lines.push(`codePath=${codePath}`);
|
|
113
|
+
}
|
|
114
|
+
if (diagnostics && typeof diagnostics === "object") {
|
|
115
|
+
lines.push(
|
|
116
|
+
`diagnostics:
|
|
117
|
+
${truncateText(
|
|
118
|
+
stringifyObservationData({
|
|
119
|
+
failurePhase: diagnostics.failurePhase,
|
|
120
|
+
exceptionType: diagnostics.exceptionType,
|
|
121
|
+
exceptionRepr: diagnostics.exceptionRepr,
|
|
122
|
+
observationPipeline: diagnostics.observationPipeline,
|
|
123
|
+
depthAssertion: diagnostics.depthAssertion,
|
|
124
|
+
perceptionApiFailure: diagnostics.perceptionApiFailure,
|
|
125
|
+
emptyPointCloud: diagnostics.emptyPointCloud,
|
|
126
|
+
trial: diagnostics.trial,
|
|
127
|
+
envClass: diagnostics.envClass,
|
|
128
|
+
lowLevelEnvClass: diagnostics.lowLevelEnvClass,
|
|
129
|
+
renderCameraNames: diagnostics.render_camera_names,
|
|
130
|
+
simStepCount: diagnostics._sim_step_count,
|
|
131
|
+
rawDepth: compactRawDepthDiagnostics(diagnostics.rawDepth),
|
|
132
|
+
sourceFiles: diagnostics.sourceFiles
|
|
133
|
+
}),
|
|
134
|
+
MAX_EXECUTION_OUTPUT_CHARS
|
|
135
|
+
)}`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
if (outcome?.terminated !== void 0 || outcome?.truncated !== void 0) {
|
|
139
|
+
lines.push(
|
|
140
|
+
`terminated=${outcome.terminated ?? "n/a"}, truncated=${outcome.truncated ?? "n/a"}`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
if (trace.stdout) {
|
|
144
|
+
lines.push(
|
|
145
|
+
`stdout:
|
|
146
|
+
${truncateText(trace.stdout, MAX_EXECUTION_OUTPUT_CHARS)}`
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
if (trace.stderr) {
|
|
150
|
+
lines.push(
|
|
151
|
+
`stderr:
|
|
152
|
+
${truncateText(trace.stderr, MAX_EXECUTION_OUTPUT_CHARS)}`
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
if (trace.artifacts?.length) {
|
|
156
|
+
lines.push(
|
|
157
|
+
`artifacts:
|
|
158
|
+
${trace.artifacts.map((artifact) => `${artifact.kind}: ${artifact.uri}`).join("\n")}`
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
return lines.join("\n\n");
|
|
162
|
+
}
|
|
163
|
+
function formatImageObservation(item) {
|
|
164
|
+
if (item.kind !== "rgb" && item.kind !== "depth") {
|
|
165
|
+
return "";
|
|
166
|
+
}
|
|
167
|
+
const details = [
|
|
168
|
+
item.width && item.height ? `size=${item.width}x${item.height}` : null,
|
|
169
|
+
item.mimeType ? `mime=${item.mimeType}` : null,
|
|
170
|
+
item.frame ? `frame=${item.frame}` : null,
|
|
171
|
+
item.uri ? `uri=${item.uri}` : null,
|
|
172
|
+
item.dataUrl ? "dataUrl=available in tool metadata" : null
|
|
173
|
+
].filter(Boolean);
|
|
174
|
+
return details.length > 0 ? details.join(", ") : "image captured";
|
|
175
|
+
}
|
|
176
|
+
function formatObservationItem(item, index) {
|
|
177
|
+
const header = `## Observation ${index + 1}: ${item.source} (${item.kind})`;
|
|
178
|
+
if (item.kind === "text") {
|
|
179
|
+
return `${header}
|
|
180
|
+
${truncateText(item.text, MAX_OBSERVATION_ITEM_CHARS)}`;
|
|
181
|
+
}
|
|
182
|
+
if (item.kind === "rgb" || item.kind === "depth") {
|
|
183
|
+
return `${header}
|
|
184
|
+
${formatImageObservation(item)}`;
|
|
185
|
+
}
|
|
186
|
+
if (!("data" in item)) {
|
|
187
|
+
return `${header}
|
|
188
|
+
No structured payload was provided.`;
|
|
189
|
+
}
|
|
190
|
+
return `${header}
|
|
191
|
+
${truncateText(
|
|
192
|
+
stringifyObservationData(item.data),
|
|
193
|
+
MAX_OBSERVATION_ITEM_CHARS
|
|
194
|
+
)}`;
|
|
195
|
+
}
|
|
196
|
+
function formatObservationOutput(observation) {
|
|
197
|
+
const summary = observation.summary ?? `${observation.items.length} observation item(s) captured.`;
|
|
198
|
+
if (observation.items.length === 0) {
|
|
199
|
+
return summary;
|
|
200
|
+
}
|
|
201
|
+
const sections = [
|
|
202
|
+
summary,
|
|
203
|
+
...observation.items.map(
|
|
204
|
+
(item, index) => formatObservationItem(item, index)
|
|
205
|
+
)
|
|
206
|
+
];
|
|
207
|
+
const output = sections.join("\n\n");
|
|
208
|
+
return truncateText(output, MAX_OBSERVATION_OUTPUT_CHARS);
|
|
209
|
+
}
|
|
210
|
+
function parseImageData(item) {
|
|
211
|
+
if (item.kind !== "rgb" && item.kind !== "depth") {
|
|
212
|
+
return void 0;
|
|
213
|
+
}
|
|
214
|
+
if (!item.dataUrl) {
|
|
215
|
+
return void 0;
|
|
216
|
+
}
|
|
217
|
+
const match = item.dataUrl.match(/^data:([^;,]+)(?:;[^,]*)?,(.*)$/s);
|
|
218
|
+
if (!match) {
|
|
219
|
+
return void 0;
|
|
220
|
+
}
|
|
221
|
+
return {
|
|
222
|
+
mediaType: item.mimeType ?? match[1] ?? "image/png",
|
|
223
|
+
data: match[2] ?? ""
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function createObservationModelOutput(observation, output) {
|
|
227
|
+
const parts = [{ type: "text", text: output }];
|
|
228
|
+
for (const item of observation.items) {
|
|
229
|
+
const image = parseImageData(item);
|
|
230
|
+
if (!image) {
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
parts.push({
|
|
234
|
+
type: "file-data",
|
|
235
|
+
data: image.data,
|
|
236
|
+
mediaType: image.mediaType
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
return parts.length > 1 ? {
|
|
240
|
+
type: "content",
|
|
241
|
+
value: parts
|
|
242
|
+
} : {
|
|
243
|
+
type: "text",
|
|
244
|
+
value: output
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
function createPhysicalStatusTool(session, options) {
|
|
248
|
+
return Tool.define(
|
|
249
|
+
toolName("status", options),
|
|
250
|
+
{
|
|
251
|
+
description: "Read the current physical session state and lifecycle status without moving or changing the environment.",
|
|
252
|
+
parameters: z.object({}),
|
|
253
|
+
capabilities: {
|
|
254
|
+
parallelSafe: true,
|
|
255
|
+
readOnly: true,
|
|
256
|
+
riskLevel: "safe"
|
|
257
|
+
},
|
|
258
|
+
execute: async () => {
|
|
259
|
+
const state = await session.getState();
|
|
260
|
+
return {
|
|
261
|
+
title: "Physical Session Status",
|
|
262
|
+
output: describePhysicalState(state),
|
|
263
|
+
metadata: {
|
|
264
|
+
physical: {
|
|
265
|
+
sessionId: session.id,
|
|
266
|
+
status: state.status,
|
|
267
|
+
state
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
capabilitiesHint: {
|
|
275
|
+
parallelSafe: true,
|
|
276
|
+
readOnly: true,
|
|
277
|
+
riskLevel: "safe"
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
function createPhysicalObserveTool(session, options) {
|
|
283
|
+
return Tool.define(
|
|
284
|
+
toolName("observe", options),
|
|
285
|
+
{
|
|
286
|
+
description: "Capture the latest physical-world observation and session context for the active robot or simulator without moving or changing the environment.",
|
|
287
|
+
parameters: z.object({
|
|
288
|
+
includeImages: z.boolean().optional().describe(
|
|
289
|
+
"Whether image observations should be included when available."
|
|
290
|
+
),
|
|
291
|
+
includeArtifacts: z.boolean().optional().describe(
|
|
292
|
+
"Whether artifact references should be included when available."
|
|
293
|
+
),
|
|
294
|
+
maxItems: z.number().int().positive().optional().describe("Maximum number of observation items to return.")
|
|
295
|
+
}),
|
|
296
|
+
capabilities: {
|
|
297
|
+
parallelSafe: true,
|
|
298
|
+
readOnly: true,
|
|
299
|
+
riskLevel: "safe"
|
|
300
|
+
},
|
|
301
|
+
execute: async (params) => {
|
|
302
|
+
if (!session.observe) {
|
|
303
|
+
return {
|
|
304
|
+
title: "Observation Unsupported",
|
|
305
|
+
output: "This physical session does not expose observations.",
|
|
306
|
+
metadata: {
|
|
307
|
+
physical: {
|
|
308
|
+
sessionId: session.id
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
const observeOptions = {
|
|
314
|
+
includeImages: params.includeImages,
|
|
315
|
+
includeArtifacts: params.includeArtifacts,
|
|
316
|
+
maxItems: params.maxItems
|
|
317
|
+
};
|
|
318
|
+
const observation = await session.observe(observeOptions);
|
|
319
|
+
const output = formatObservationOutput(observation);
|
|
320
|
+
return {
|
|
321
|
+
title: "Physical Observation",
|
|
322
|
+
output,
|
|
323
|
+
metadata: {
|
|
324
|
+
modelOutput: createObservationModelOutput(observation, output),
|
|
325
|
+
physical: {
|
|
326
|
+
sessionId: session.id,
|
|
327
|
+
status: observation.status,
|
|
328
|
+
observation
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
capabilitiesHint: {
|
|
336
|
+
parallelSafe: true,
|
|
337
|
+
readOnly: true,
|
|
338
|
+
riskLevel: "safe"
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
function createPhysicalRunCodeTool(session, options) {
|
|
344
|
+
return Tool.define(
|
|
345
|
+
toolName("run_policy_code", options),
|
|
346
|
+
{
|
|
347
|
+
description: "Execute policy code inside the active physical session after observing the current context. This can move a robot or mutate a simulator.",
|
|
348
|
+
parameters: z.object({
|
|
349
|
+
code: z.string().min(1).describe("Executable policy code."),
|
|
350
|
+
language: z.string().optional().describe("Code language. Defaults to the session runtime language."),
|
|
351
|
+
timeoutMs: z.number().int().positive().optional().describe("Optional execution timeout in milliseconds."),
|
|
352
|
+
dryRun: z.boolean().optional().describe(
|
|
353
|
+
"Validate or stage the code without executing if supported."
|
|
354
|
+
)
|
|
355
|
+
}),
|
|
356
|
+
capabilities: {
|
|
357
|
+
parallelSafe: false,
|
|
358
|
+
readOnly: false,
|
|
359
|
+
destructive: true,
|
|
360
|
+
riskLevel: "dangerous",
|
|
361
|
+
onInterrupt: "cancel"
|
|
362
|
+
},
|
|
363
|
+
replayPolicy: {
|
|
364
|
+
mode: "manual",
|
|
365
|
+
sideEffectLevel: "external",
|
|
366
|
+
reason: "Physical code execution may move hardware or mutate simulator state and must not be replayed automatically."
|
|
367
|
+
},
|
|
368
|
+
execute: async (params) => {
|
|
369
|
+
if (!session.executeCode) {
|
|
370
|
+
return {
|
|
371
|
+
title: "Policy Execution Unsupported",
|
|
372
|
+
output: "This physical session does not expose direct policy-code execution.",
|
|
373
|
+
metadata: {
|
|
374
|
+
physical: {
|
|
375
|
+
sessionId: session.id
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
const policy = normalizePhysicalSafetyPolicy({
|
|
381
|
+
riskLevel: "dangerous",
|
|
382
|
+
requiresApproval: true,
|
|
383
|
+
requiresHumanPresence: true
|
|
384
|
+
});
|
|
385
|
+
const trace = await session.executeCode({
|
|
386
|
+
code: params.code,
|
|
387
|
+
language: params.language,
|
|
388
|
+
timeoutMs: params.timeoutMs,
|
|
389
|
+
dryRun: params.dryRun,
|
|
390
|
+
metadata: { safety: policy }
|
|
391
|
+
});
|
|
392
|
+
return {
|
|
393
|
+
title: "Physical Policy Execution",
|
|
394
|
+
output: formatExecutionOutput(trace),
|
|
395
|
+
metadata: {
|
|
396
|
+
physical: {
|
|
397
|
+
sessionId: session.id,
|
|
398
|
+
trace
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
capabilitiesHint: {
|
|
406
|
+
parallelSafe: false,
|
|
407
|
+
readOnly: false,
|
|
408
|
+
destructive: true,
|
|
409
|
+
riskLevel: "dangerous",
|
|
410
|
+
onInterrupt: "cancel"
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
function createPhysicalStopTool(session, options) {
|
|
416
|
+
return Tool.define(
|
|
417
|
+
toolName("stop", options),
|
|
418
|
+
{
|
|
419
|
+
description: "Stop the active physical session as quickly as the backend supports. Use only when requested or when continuing would be unsafe.",
|
|
420
|
+
parameters: z.object({
|
|
421
|
+
reason: z.string().optional().describe("Reason for stopping the session.")
|
|
422
|
+
}),
|
|
423
|
+
capabilities: {
|
|
424
|
+
parallelSafe: false,
|
|
425
|
+
readOnly: false,
|
|
426
|
+
destructive: true,
|
|
427
|
+
riskLevel: "dangerous",
|
|
428
|
+
onInterrupt: "cancel"
|
|
429
|
+
},
|
|
430
|
+
replayPolicy: {
|
|
431
|
+
mode: "manual",
|
|
432
|
+
sideEffectLevel: "external",
|
|
433
|
+
reason: "Stopping a physical session is a control-plane side effect and should not be replayed automatically."
|
|
434
|
+
},
|
|
435
|
+
execute: async ({ reason }) => {
|
|
436
|
+
const state = await session.stop(reason);
|
|
437
|
+
return {
|
|
438
|
+
title: "Physical Session Stopped",
|
|
439
|
+
output: describePhysicalState(state),
|
|
440
|
+
metadata: {
|
|
441
|
+
physical: {
|
|
442
|
+
sessionId: session.id,
|
|
443
|
+
status: state.status,
|
|
444
|
+
state
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
capabilitiesHint: {
|
|
452
|
+
parallelSafe: false,
|
|
453
|
+
readOnly: false,
|
|
454
|
+
destructive: true,
|
|
455
|
+
riskLevel: "dangerous",
|
|
456
|
+
onInterrupt: "cancel"
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
function createPhysicalArtifactsTool(session, options) {
|
|
462
|
+
return Tool.define(
|
|
463
|
+
toolName("artifacts", options),
|
|
464
|
+
{
|
|
465
|
+
description: "List artifacts produced by the active physical session, such as logs, generated code, images, videos, or result directories.",
|
|
466
|
+
parameters: z.object({
|
|
467
|
+
kind: z.enum(["code", "log", "image", "video", "json", "directory", "other"]).optional().describe("Optional artifact kind filter."),
|
|
468
|
+
limit: z.number().int().positive().optional().describe("Maximum number of artifacts to return.")
|
|
469
|
+
}),
|
|
470
|
+
capabilities: {
|
|
471
|
+
parallelSafe: true,
|
|
472
|
+
readOnly: true,
|
|
473
|
+
riskLevel: "safe"
|
|
474
|
+
},
|
|
475
|
+
execute: async (params) => {
|
|
476
|
+
if (!session.listArtifacts) {
|
|
477
|
+
return {
|
|
478
|
+
title: "Artifacts Unsupported",
|
|
479
|
+
output: "This physical session does not expose artifacts.",
|
|
480
|
+
metadata: {
|
|
481
|
+
physical: {
|
|
482
|
+
sessionId: session.id
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
const listOptions = {
|
|
488
|
+
kind: params.kind,
|
|
489
|
+
limit: params.limit
|
|
490
|
+
};
|
|
491
|
+
const artifacts = await session.listArtifacts(listOptions);
|
|
492
|
+
const output = artifacts.length === 0 ? "No physical-session artifacts found." : artifacts.map((artifact) => `${artifact.kind}: ${artifact.uri}`).join("\n");
|
|
493
|
+
return {
|
|
494
|
+
title: "Physical Artifacts",
|
|
495
|
+
output,
|
|
496
|
+
metadata: {
|
|
497
|
+
physical: {
|
|
498
|
+
sessionId: session.id,
|
|
499
|
+
artifacts
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
capabilitiesHint: {
|
|
507
|
+
parallelSafe: true,
|
|
508
|
+
readOnly: true,
|
|
509
|
+
riskLevel: "safe"
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
function createPhysicalSessionTools(session, options) {
|
|
515
|
+
const tools = [
|
|
516
|
+
createPhysicalStatusTool(session, options),
|
|
517
|
+
createPhysicalObserveTool(session, options),
|
|
518
|
+
createPhysicalArtifactsTool(session, options),
|
|
519
|
+
createPhysicalStopTool(session, options)
|
|
520
|
+
];
|
|
521
|
+
if (session.executeCode) {
|
|
522
|
+
tools.splice(2, 0, createPhysicalRunCodeTool(session, options));
|
|
523
|
+
}
|
|
524
|
+
return tools;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
export {
|
|
528
|
+
defaultPhysicalSafetyPolicy,
|
|
529
|
+
normalizePhysicalSafetyPolicy,
|
|
530
|
+
isModeAllowed,
|
|
531
|
+
describePhysicalState,
|
|
532
|
+
createPhysicalStatusTool,
|
|
533
|
+
createPhysicalObserveTool,
|
|
534
|
+
createPhysicalRunCodeTool,
|
|
535
|
+
createPhysicalStopTool,
|
|
536
|
+
createPhysicalArtifactsTool,
|
|
537
|
+
createPhysicalSessionTools
|
|
538
|
+
};
|
|
539
|
+
//# sourceMappingURL=chunk-G7CGE7QH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tools/index.ts","../src/safety.ts"],"sourcesContent":["import { Tool } from \"@cuylabs/agent-core/tool\";\nimport type { ToolModelOutput } from \"@cuylabs/agent-core/tool\";\nimport { z } from \"zod\";\nimport {\n describePhysicalState,\n normalizePhysicalSafetyPolicy,\n} from \"../safety.js\";\nimport type {\n PhysicalExecutionTrace,\n PhysicalListArtifactsOptions,\n PhysicalObserveOptions,\n PhysicalObservation,\n PhysicalObservationItem,\n PhysicalSession,\n PhysicalToolMetadata,\n} from \"../types.js\";\n\ntype ToolModelContentPart = Extract<\n ToolModelOutput,\n { type: \"content\" }\n>[\"value\"][number];\n\nexport interface PhysicalToolOptions {\n /**\n * Prefix used for generated tool ids. Defaults to \"physical\".\n */\n prefix?: string;\n}\n\nfunction toolName(name: string, options?: PhysicalToolOptions): string {\n return `${options?.prefix ?? \"physical\"}_${name}`;\n}\n\nconst MAX_OBSERVATION_ITEM_CHARS = 12_000;\nconst MAX_OBSERVATION_OUTPUT_CHARS = 60_000;\nconst MAX_EXECUTION_OUTPUT_CHARS = 8_000;\n\nfunction truncateText(value: string, maxChars: number): string {\n if (value.length <= maxChars) {\n return value;\n }\n\n return `${value.slice(0, maxChars)}\\n... (${value.length - maxChars} characters omitted from this observation item)`;\n}\n\nfunction stringifyObservationData(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n\n try {\n return JSON.stringify(value, null, 2) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction compactRawDepthDiagnostics(\n value: unknown,\n): Record<string, unknown> | undefined {\n const rawDepth = asRecord(value);\n if (!rawDepth) {\n return undefined;\n }\n\n const compact: Record<string, unknown> = {};\n for (const [camera, statsValue] of Object.entries(rawDepth)) {\n const stats = asRecord(statsValue);\n if (!stats) {\n compact[camera] = statsValue;\n continue;\n }\n\n compact[camera] = {\n shape: stats.shape,\n dtype: stats.dtype,\n min: stats.min,\n max: stats.max,\n finiteMin: stats.finiteMin,\n finiteMax: stats.finiteMax,\n nanCount: stats.nanCount,\n infCount: stats.infCount,\n belowZeroCount: stats.belowZeroCount,\n aboveOneCount: stats.aboveOneCount,\n outOfRangeCount: stats.outOfRangeCount,\n error: stats.error,\n };\n }\n\n return Object.keys(compact).length > 0 ? compact : undefined;\n}\n\nfunction formatExecutionOutput(trace: PhysicalExecutionTrace): string {\n const outcome = trace.outcome;\n const sandboxRc = outcome?.metadata?.sandboxRc;\n const elapsedMs = outcome?.metadata?.elapsedMs;\n const codePath = outcome?.metadata?.codePath;\n const diagnostics = outcome?.metadata?.diagnostics as\n | Record<string, unknown>\n | undefined;\n const lines = [\n outcome\n ? `executionOk=${outcome.success}, taskCompleted=${outcome.taskCompleted ?? \"n/a\"}, reward=${outcome.reward ?? \"n/a\"}`\n : \"Execution completed without an outcome.\",\n ];\n\n if (sandboxRc !== undefined) {\n lines.push(`sandboxRc=${sandboxRc}`);\n }\n if (elapsedMs !== undefined) {\n lines.push(`elapsedMs=${elapsedMs}`);\n }\n if (codePath !== undefined) {\n lines.push(`codePath=${codePath}`);\n }\n if (diagnostics && typeof diagnostics === \"object\") {\n lines.push(\n `diagnostics:\\n${truncateText(\n stringifyObservationData({\n failurePhase: diagnostics.failurePhase,\n exceptionType: diagnostics.exceptionType,\n exceptionRepr: diagnostics.exceptionRepr,\n observationPipeline: diagnostics.observationPipeline,\n depthAssertion: diagnostics.depthAssertion,\n perceptionApiFailure: diagnostics.perceptionApiFailure,\n emptyPointCloud: diagnostics.emptyPointCloud,\n trial: diagnostics.trial,\n envClass: diagnostics.envClass,\n lowLevelEnvClass: diagnostics.lowLevelEnvClass,\n renderCameraNames: diagnostics.render_camera_names,\n simStepCount: diagnostics._sim_step_count,\n rawDepth: compactRawDepthDiagnostics(diagnostics.rawDepth),\n sourceFiles: diagnostics.sourceFiles,\n }),\n MAX_EXECUTION_OUTPUT_CHARS,\n )}`,\n );\n }\n if (outcome?.terminated !== undefined || outcome?.truncated !== undefined) {\n lines.push(\n `terminated=${outcome.terminated ?? \"n/a\"}, truncated=${outcome.truncated ?? \"n/a\"}`,\n );\n }\n if (trace.stdout) {\n lines.push(\n `stdout:\\n${truncateText(trace.stdout, MAX_EXECUTION_OUTPUT_CHARS)}`,\n );\n }\n if (trace.stderr) {\n lines.push(\n `stderr:\\n${truncateText(trace.stderr, MAX_EXECUTION_OUTPUT_CHARS)}`,\n );\n }\n if (trace.artifacts?.length) {\n lines.push(\n `artifacts:\\n${trace.artifacts\n .map((artifact) => `${artifact.kind}: ${artifact.uri}`)\n .join(\"\\n\")}`,\n );\n }\n\n return lines.join(\"\\n\\n\");\n}\n\nfunction formatImageObservation(item: PhysicalObservationItem): string {\n if (item.kind !== \"rgb\" && item.kind !== \"depth\") {\n return \"\";\n }\n\n const details = [\n item.width && item.height ? `size=${item.width}x${item.height}` : null,\n item.mimeType ? `mime=${item.mimeType}` : null,\n item.frame ? `frame=${item.frame}` : null,\n item.uri ? `uri=${item.uri}` : null,\n item.dataUrl ? \"dataUrl=available in tool metadata\" : null,\n ].filter(Boolean);\n\n return details.length > 0 ? details.join(\", \") : \"image captured\";\n}\n\nfunction formatObservationItem(\n item: PhysicalObservationItem,\n index: number,\n): string {\n const header = `## Observation ${index + 1}: ${item.source} (${item.kind})`;\n\n if (item.kind === \"text\") {\n return `${header}\\n${truncateText(item.text, MAX_OBSERVATION_ITEM_CHARS)}`;\n }\n\n if (item.kind === \"rgb\" || item.kind === \"depth\") {\n return `${header}\\n${formatImageObservation(item)}`;\n }\n\n if (!(\"data\" in item)) {\n return `${header}\\nNo structured payload was provided.`;\n }\n\n return `${header}\\n${truncateText(\n stringifyObservationData(item.data),\n MAX_OBSERVATION_ITEM_CHARS,\n )}`;\n}\n\nfunction formatObservationOutput(observation: PhysicalObservation): string {\n const summary =\n observation.summary ??\n `${observation.items.length} observation item(s) captured.`;\n if (observation.items.length === 0) {\n return summary;\n }\n\n const sections = [\n summary,\n ...observation.items.map((item, index) =>\n formatObservationItem(item, index),\n ),\n ];\n const output = sections.join(\"\\n\\n\");\n return truncateText(output, MAX_OBSERVATION_OUTPUT_CHARS);\n}\n\nfunction parseImageData(\n item: PhysicalObservationItem,\n): { data: string; mediaType: string } | undefined {\n if (item.kind !== \"rgb\" && item.kind !== \"depth\") {\n return undefined;\n }\n\n if (!item.dataUrl) {\n return undefined;\n }\n\n const match = item.dataUrl.match(/^data:([^;,]+)(?:;[^,]*)?,(.*)$/s);\n if (!match) {\n return undefined;\n }\n\n return {\n mediaType: item.mimeType ?? match[1] ?? \"image/png\",\n data: match[2] ?? \"\",\n };\n}\n\nfunction createObservationModelOutput(\n observation: PhysicalObservation,\n output: string,\n): ToolModelOutput {\n const parts: ToolModelContentPart[] = [{ type: \"text\", text: output }];\n\n for (const item of observation.items) {\n const image = parseImageData(item);\n if (!image) {\n continue;\n }\n parts.push({\n type: \"file-data\",\n data: image.data,\n mediaType: image.mediaType,\n });\n }\n\n return parts.length > 1\n ? {\n type: \"content\",\n value: parts,\n }\n : {\n type: \"text\",\n value: output,\n };\n}\n\nexport function createPhysicalStatusTool(\n session: PhysicalSession,\n options?: PhysicalToolOptions,\n) {\n return Tool.define(\n toolName(\"status\", options),\n {\n description:\n \"Read the current physical session state and lifecycle status without moving or changing the environment.\",\n parameters: z.object({}),\n capabilities: {\n parallelSafe: true,\n readOnly: true,\n riskLevel: \"safe\",\n },\n execute: async () => {\n const state = await session.getState();\n return {\n title: \"Physical Session Status\",\n output: describePhysicalState(state),\n metadata: {\n physical: {\n sessionId: session.id,\n status: state.status,\n state,\n },\n } as PhysicalToolMetadata,\n };\n },\n },\n {\n capabilitiesHint: {\n parallelSafe: true,\n readOnly: true,\n riskLevel: \"safe\",\n },\n },\n );\n}\n\nexport function createPhysicalObserveTool(\n session: PhysicalSession,\n options?: PhysicalToolOptions,\n) {\n return Tool.define(\n toolName(\"observe\", options),\n {\n description:\n \"Capture the latest physical-world observation and session context for the active robot or simulator without moving or changing the environment.\",\n parameters: z.object({\n includeImages: z\n .boolean()\n .optional()\n .describe(\n \"Whether image observations should be included when available.\",\n ),\n includeArtifacts: z\n .boolean()\n .optional()\n .describe(\n \"Whether artifact references should be included when available.\",\n ),\n maxItems: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Maximum number of observation items to return.\"),\n }),\n capabilities: {\n parallelSafe: true,\n readOnly: true,\n riskLevel: \"safe\",\n },\n execute: async (params) => {\n if (!session.observe) {\n return {\n title: \"Observation Unsupported\",\n output: \"This physical session does not expose observations.\",\n metadata: {\n physical: {\n sessionId: session.id,\n },\n } as PhysicalToolMetadata,\n };\n }\n\n const observeOptions: PhysicalObserveOptions = {\n includeImages: params.includeImages,\n includeArtifacts: params.includeArtifacts,\n maxItems: params.maxItems,\n };\n const observation = await session.observe(observeOptions);\n const output = formatObservationOutput(observation);\n return {\n title: \"Physical Observation\",\n output,\n metadata: {\n modelOutput: createObservationModelOutput(observation, output),\n physical: {\n sessionId: session.id,\n status: observation.status,\n observation,\n },\n } as PhysicalToolMetadata,\n };\n },\n },\n {\n capabilitiesHint: {\n parallelSafe: true,\n readOnly: true,\n riskLevel: \"safe\",\n },\n },\n );\n}\n\nexport function createPhysicalRunCodeTool(\n session: PhysicalSession,\n options?: PhysicalToolOptions,\n) {\n return Tool.define(\n toolName(\"run_policy_code\", options),\n {\n description:\n \"Execute policy code inside the active physical session after observing the current context. This can move a robot or mutate a simulator.\",\n parameters: z.object({\n code: z.string().min(1).describe(\"Executable policy code.\"),\n language: z\n .string()\n .optional()\n .describe(\"Code language. Defaults to the session runtime language.\"),\n timeoutMs: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Optional execution timeout in milliseconds.\"),\n dryRun: z\n .boolean()\n .optional()\n .describe(\n \"Validate or stage the code without executing if supported.\",\n ),\n }),\n capabilities: {\n parallelSafe: false,\n readOnly: false,\n destructive: true,\n riskLevel: \"dangerous\",\n onInterrupt: \"cancel\",\n },\n replayPolicy: {\n mode: \"manual\",\n sideEffectLevel: \"external\",\n reason:\n \"Physical code execution may move hardware or mutate simulator state and must not be replayed automatically.\",\n },\n execute: async (params) => {\n if (!session.executeCode) {\n return {\n title: \"Policy Execution Unsupported\",\n output:\n \"This physical session does not expose direct policy-code execution.\",\n metadata: {\n physical: {\n sessionId: session.id,\n },\n } as PhysicalToolMetadata,\n };\n }\n\n const policy = normalizePhysicalSafetyPolicy({\n riskLevel: \"dangerous\",\n requiresApproval: true,\n requiresHumanPresence: true,\n });\n const trace = await session.executeCode({\n code: params.code,\n language: params.language,\n timeoutMs: params.timeoutMs,\n dryRun: params.dryRun,\n metadata: { safety: policy },\n });\n\n return {\n title: \"Physical Policy Execution\",\n output: formatExecutionOutput(trace),\n metadata: {\n physical: {\n sessionId: session.id,\n trace,\n },\n } as PhysicalToolMetadata,\n };\n },\n },\n {\n capabilitiesHint: {\n parallelSafe: false,\n readOnly: false,\n destructive: true,\n riskLevel: \"dangerous\",\n onInterrupt: \"cancel\",\n },\n },\n );\n}\n\nexport function createPhysicalStopTool(\n session: PhysicalSession,\n options?: PhysicalToolOptions,\n) {\n return Tool.define(\n toolName(\"stop\", options),\n {\n description:\n \"Stop the active physical session as quickly as the backend supports. Use only when requested or when continuing would be unsafe.\",\n parameters: z.object({\n reason: z\n .string()\n .optional()\n .describe(\"Reason for stopping the session.\"),\n }),\n capabilities: {\n parallelSafe: false,\n readOnly: false,\n destructive: true,\n riskLevel: \"dangerous\",\n onInterrupt: \"cancel\",\n },\n replayPolicy: {\n mode: \"manual\",\n sideEffectLevel: \"external\",\n reason:\n \"Stopping a physical session is a control-plane side effect and should not be replayed automatically.\",\n },\n execute: async ({ reason }) => {\n const state = await session.stop(reason);\n return {\n title: \"Physical Session Stopped\",\n output: describePhysicalState(state),\n metadata: {\n physical: {\n sessionId: session.id,\n status: state.status,\n state,\n },\n } as PhysicalToolMetadata,\n };\n },\n },\n {\n capabilitiesHint: {\n parallelSafe: false,\n readOnly: false,\n destructive: true,\n riskLevel: \"dangerous\",\n onInterrupt: \"cancel\",\n },\n },\n );\n}\n\nexport function createPhysicalArtifactsTool(\n session: PhysicalSession,\n options?: PhysicalToolOptions,\n) {\n return Tool.define(\n toolName(\"artifacts\", options),\n {\n description:\n \"List artifacts produced by the active physical session, such as logs, generated code, images, videos, or result directories.\",\n parameters: z.object({\n kind: z\n .enum([\"code\", \"log\", \"image\", \"video\", \"json\", \"directory\", \"other\"])\n .optional()\n .describe(\"Optional artifact kind filter.\"),\n limit: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Maximum number of artifacts to return.\"),\n }),\n capabilities: {\n parallelSafe: true,\n readOnly: true,\n riskLevel: \"safe\",\n },\n execute: async (params) => {\n if (!session.listArtifacts) {\n return {\n title: \"Artifacts Unsupported\",\n output: \"This physical session does not expose artifacts.\",\n metadata: {\n physical: {\n sessionId: session.id,\n },\n } as PhysicalToolMetadata,\n };\n }\n\n const listOptions: PhysicalListArtifactsOptions = {\n kind: params.kind,\n limit: params.limit,\n };\n const artifacts = await session.listArtifacts(listOptions);\n const output =\n artifacts.length === 0\n ? \"No physical-session artifacts found.\"\n : artifacts\n .map((artifact) => `${artifact.kind}: ${artifact.uri}`)\n .join(\"\\n\");\n return {\n title: \"Physical Artifacts\",\n output,\n metadata: {\n physical: {\n sessionId: session.id,\n artifacts,\n },\n } as PhysicalToolMetadata,\n };\n },\n },\n {\n capabilitiesHint: {\n parallelSafe: true,\n readOnly: true,\n riskLevel: \"safe\",\n },\n },\n );\n}\n\nexport function createPhysicalSessionTools(\n session: PhysicalSession,\n options?: PhysicalToolOptions,\n) {\n const tools: Tool.AnyInfo[] = [\n createPhysicalStatusTool(session, options),\n createPhysicalObserveTool(session, options),\n createPhysicalArtifactsTool(session, options),\n createPhysicalStopTool(session, options),\n ];\n\n if (session.executeCode) {\n tools.splice(2, 0, createPhysicalRunCodeTool(session, options));\n }\n\n return tools;\n}\n","import type {\n PhysicalExecutionMode,\n PhysicalSafetyPolicy,\n PhysicalSessionState,\n} from \"./types.js\";\n\nexport const defaultPhysicalSafetyPolicy: Required<\n Pick<\n PhysicalSafetyPolicy,\n \"riskLevel\" | \"requiresApproval\" | \"requiresHumanPresence\"\n >\n> = {\n riskLevel: \"dangerous\",\n requiresApproval: true,\n requiresHumanPresence: true,\n};\n\nexport function normalizePhysicalSafetyPolicy(\n policy: PhysicalSafetyPolicy | undefined,\n): PhysicalSafetyPolicy {\n return {\n ...defaultPhysicalSafetyPolicy,\n ...(policy ?? {}),\n };\n}\n\nexport function isModeAllowed(\n mode: PhysicalExecutionMode | undefined,\n policy: PhysicalSafetyPolicy | undefined,\n): boolean {\n if (!policy?.allowedModes || policy.allowedModes.length === 0) {\n return true;\n }\n if (!mode) {\n return false;\n }\n return policy.allowedModes.includes(mode);\n}\n\nexport function describePhysicalState(state: PhysicalSessionState): string {\n const parts = [`status=${state.status}`];\n if (state.mode) {\n parts.push(`mode=${state.mode}`);\n }\n if (state.task?.id) {\n parts.push(`task=${state.task.id}`);\n }\n if (state.message) {\n parts.push(`message=${state.message}`);\n }\n return parts.join(\", \");\n}\n"],"mappings":";AAAA,SAAS,YAAY;AAErB,SAAS,SAAS;;;ACIX,IAAM,8BAKT;AAAA,EACF,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,uBAAuB;AACzB;AAEO,SAAS,8BACd,QACsB;AACtB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,UAAU,CAAC;AAAA,EACjB;AACF;AAEO,SAAS,cACd,MACA,QACS;AACT,MAAI,CAAC,QAAQ,gBAAgB,OAAO,aAAa,WAAW,GAAG;AAC7D,WAAO;AAAA,EACT;AACA,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AACA,SAAO,OAAO,aAAa,SAAS,IAAI;AAC1C;AAEO,SAAS,sBAAsB,OAAqC;AACzE,QAAM,QAAQ,CAAC,UAAU,MAAM,MAAM,EAAE;AACvC,MAAI,MAAM,MAAM;AACd,UAAM,KAAK,QAAQ,MAAM,IAAI,EAAE;AAAA,EACjC;AACA,MAAI,MAAM,MAAM,IAAI;AAClB,UAAM,KAAK,QAAQ,MAAM,KAAK,EAAE,EAAE;AAAA,EACpC;AACA,MAAI,MAAM,SAAS;AACjB,UAAM,KAAK,WAAW,MAAM,OAAO,EAAE;AAAA,EACvC;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ADtBA,SAAS,SAAS,MAAc,SAAuC;AACrE,SAAO,GAAG,SAAS,UAAU,UAAU,IAAI,IAAI;AACjD;AAEA,IAAM,6BAA6B;AACnC,IAAM,+BAA+B;AACrC,IAAM,6BAA6B;AAEnC,SAAS,aAAa,OAAe,UAA0B;AAC7D,MAAI,MAAM,UAAU,UAAU;AAC5B,WAAO;AAAA,EACT;AAEA,SAAO,GAAG,MAAM,MAAM,GAAG,QAAQ,CAAC;AAAA,OAAU,MAAM,SAAS,QAAQ;AACrE;AAEA,SAAS,yBAAyB,OAAwB;AACxD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI;AACF,WAAO,KAAK,UAAU,OAAO,MAAM,CAAC,KAAK,OAAO,KAAK;AAAA,EACvD,QAAQ;AACN,WAAO,OAAO,KAAK;AAAA,EACrB;AACF;AAEA,SAAS,SAAS,OAAqD;AACrE,SAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC5D,QACD;AACN;AAEA,SAAS,2BACP,OACqC;AACrC,QAAM,WAAW,SAAS,KAAK;AAC/B,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,QAAM,UAAmC,CAAC;AAC1C,aAAW,CAAC,QAAQ,UAAU,KAAK,OAAO,QAAQ,QAAQ,GAAG;AAC3D,UAAM,QAAQ,SAAS,UAAU;AACjC,QAAI,CAAC,OAAO;AACV,cAAQ,MAAM,IAAI;AAClB;AAAA,IACF;AAEA,YAAQ,MAAM,IAAI;AAAA,MAChB,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,MACb,KAAK,MAAM;AAAA,MACX,KAAK,MAAM;AAAA,MACX,WAAW,MAAM;AAAA,MACjB,WAAW,MAAM;AAAA,MACjB,UAAU,MAAM;AAAA,MAChB,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,MACtB,eAAe,MAAM;AAAA,MACrB,iBAAiB,MAAM;AAAA,MACvB,OAAO,MAAM;AAAA,IACf;AAAA,EACF;AAEA,SAAO,OAAO,KAAK,OAAO,EAAE,SAAS,IAAI,UAAU;AACrD;AAEA,SAAS,sBAAsB,OAAuC;AACpE,QAAM,UAAU,MAAM;AACtB,QAAM,YAAY,SAAS,UAAU;AACrC,QAAM,YAAY,SAAS,UAAU;AACrC,QAAM,WAAW,SAAS,UAAU;AACpC,QAAM,cAAc,SAAS,UAAU;AAGvC,QAAM,QAAQ;AAAA,IACZ,UACI,eAAe,QAAQ,OAAO,mBAAmB,QAAQ,iBAAiB,KAAK,YAAY,QAAQ,UAAU,KAAK,KAClH;AAAA,EACN;AAEA,MAAI,cAAc,QAAW;AAC3B,UAAM,KAAK,aAAa,SAAS,EAAE;AAAA,EACrC;AACA,MAAI,cAAc,QAAW;AAC3B,UAAM,KAAK,aAAa,SAAS,EAAE;AAAA,EACrC;AACA,MAAI,aAAa,QAAW;AAC1B,UAAM,KAAK,YAAY,QAAQ,EAAE;AAAA,EACnC;AACA,MAAI,eAAe,OAAO,gBAAgB,UAAU;AAClD,UAAM;AAAA,MACJ;AAAA,EAAiB;AAAA,QACf,yBAAyB;AAAA,UACvB,cAAc,YAAY;AAAA,UAC1B,eAAe,YAAY;AAAA,UAC3B,eAAe,YAAY;AAAA,UAC3B,qBAAqB,YAAY;AAAA,UACjC,gBAAgB,YAAY;AAAA,UAC5B,sBAAsB,YAAY;AAAA,UAClC,iBAAiB,YAAY;AAAA,UAC7B,OAAO,YAAY;AAAA,UACnB,UAAU,YAAY;AAAA,UACtB,kBAAkB,YAAY;AAAA,UAC9B,mBAAmB,YAAY;AAAA,UAC/B,cAAc,YAAY;AAAA,UAC1B,UAAU,2BAA2B,YAAY,QAAQ;AAAA,UACzD,aAAa,YAAY;AAAA,QAC3B,CAAC;AAAA,QACD;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACA,MAAI,SAAS,eAAe,UAAa,SAAS,cAAc,QAAW;AACzE,UAAM;AAAA,MACJ,cAAc,QAAQ,cAAc,KAAK,eAAe,QAAQ,aAAa,KAAK;AAAA,IACpF;AAAA,EACF;AACA,MAAI,MAAM,QAAQ;AAChB,UAAM;AAAA,MACJ;AAAA,EAAY,aAAa,MAAM,QAAQ,0BAA0B,CAAC;AAAA,IACpE;AAAA,EACF;AACA,MAAI,MAAM,QAAQ;AAChB,UAAM;AAAA,MACJ;AAAA,EAAY,aAAa,MAAM,QAAQ,0BAA0B,CAAC;AAAA,IACpE;AAAA,EACF;AACA,MAAI,MAAM,WAAW,QAAQ;AAC3B,UAAM;AAAA,MACJ;AAAA,EAAe,MAAM,UAClB,IAAI,CAAC,aAAa,GAAG,SAAS,IAAI,KAAK,SAAS,GAAG,EAAE,EACrD,KAAK,IAAI,CAAC;AAAA,IACf;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,MAAM;AAC1B;AAEA,SAAS,uBAAuB,MAAuC;AACrE,MAAI,KAAK,SAAS,SAAS,KAAK,SAAS,SAAS;AAChD,WAAO;AAAA,EACT;AAEA,QAAM,UAAU;AAAA,IACd,KAAK,SAAS,KAAK,SAAS,QAAQ,KAAK,KAAK,IAAI,KAAK,MAAM,KAAK;AAAA,IAClE,KAAK,WAAW,QAAQ,KAAK,QAAQ,KAAK;AAAA,IAC1C,KAAK,QAAQ,SAAS,KAAK,KAAK,KAAK;AAAA,IACrC,KAAK,MAAM,OAAO,KAAK,GAAG,KAAK;AAAA,IAC/B,KAAK,UAAU,uCAAuC;AAAA,EACxD,EAAE,OAAO,OAAO;AAEhB,SAAO,QAAQ,SAAS,IAAI,QAAQ,KAAK,IAAI,IAAI;AACnD;AAEA,SAAS,sBACP,MACA,OACQ;AACR,QAAM,SAAS,kBAAkB,QAAQ,CAAC,KAAK,KAAK,MAAM,KAAK,KAAK,IAAI;AAExE,MAAI,KAAK,SAAS,QAAQ;AACxB,WAAO,GAAG,MAAM;AAAA,EAAK,aAAa,KAAK,MAAM,0BAA0B,CAAC;AAAA,EAC1E;AAEA,MAAI,KAAK,SAAS,SAAS,KAAK,SAAS,SAAS;AAChD,WAAO,GAAG,MAAM;AAAA,EAAK,uBAAuB,IAAI,CAAC;AAAA,EACnD;AAEA,MAAI,EAAE,UAAU,OAAO;AACrB,WAAO,GAAG,MAAM;AAAA;AAAA,EAClB;AAEA,SAAO,GAAG,MAAM;AAAA,EAAK;AAAA,IACnB,yBAAyB,KAAK,IAAI;AAAA,IAClC;AAAA,EACF,CAAC;AACH;AAEA,SAAS,wBAAwB,aAA0C;AACzE,QAAM,UACJ,YAAY,WACZ,GAAG,YAAY,MAAM,MAAM;AAC7B,MAAI,YAAY,MAAM,WAAW,GAAG;AAClC,WAAO;AAAA,EACT;AAEA,QAAM,WAAW;AAAA,IACf;AAAA,IACA,GAAG,YAAY,MAAM;AAAA,MAAI,CAAC,MAAM,UAC9B,sBAAsB,MAAM,KAAK;AAAA,IACnC;AAAA,EACF;AACA,QAAM,SAAS,SAAS,KAAK,MAAM;AACnC,SAAO,aAAa,QAAQ,4BAA4B;AAC1D;AAEA,SAAS,eACP,MACiD;AACjD,MAAI,KAAK,SAAS,SAAS,KAAK,SAAS,SAAS;AAChD,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,KAAK,SAAS;AACjB,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,KAAK,QAAQ,MAAM,kCAAkC;AACnE,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,WAAW,KAAK,YAAY,MAAM,CAAC,KAAK;AAAA,IACxC,MAAM,MAAM,CAAC,KAAK;AAAA,EACpB;AACF;AAEA,SAAS,6BACP,aACA,QACiB;AACjB,QAAM,QAAgC,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC;AAErE,aAAW,QAAQ,YAAY,OAAO;AACpC,UAAM,QAAQ,eAAe,IAAI;AACjC,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AACA,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,MAAM,MAAM;AAAA,MACZ,WAAW,MAAM;AAAA,IACnB,CAAC;AAAA,EACH;AAEA,SAAO,MAAM,SAAS,IAClB;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,EACT,IACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AACN;AAEO,SAAS,yBACd,SACA,SACA;AACA,SAAO,KAAK;AAAA,IACV,SAAS,UAAU,OAAO;AAAA,IAC1B;AAAA,MACE,aACE;AAAA,MACF,YAAY,EAAE,OAAO,CAAC,CAAC;AAAA,MACvB,cAAc;AAAA,QACZ,cAAc;AAAA,QACd,UAAU;AAAA,QACV,WAAW;AAAA,MACb;AAAA,MACA,SAAS,YAAY;AACnB,cAAM,QAAQ,MAAM,QAAQ,SAAS;AACrC,eAAO;AAAA,UACL,OAAO;AAAA,UACP,QAAQ,sBAAsB,KAAK;AAAA,UACnC,UAAU;AAAA,YACR,UAAU;AAAA,cACR,WAAW,QAAQ;AAAA,cACnB,QAAQ,MAAM;AAAA,cACd;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,kBAAkB;AAAA,QAChB,cAAc;AAAA,QACd,UAAU;AAAA,QACV,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,0BACd,SACA,SACA;AACA,SAAO,KAAK;AAAA,IACV,SAAS,WAAW,OAAO;AAAA,IAC3B;AAAA,MACE,aACE;AAAA,MACF,YAAY,EAAE,OAAO;AAAA,QACnB,eAAe,EACZ,QAAQ,EACR,SAAS,EACT;AAAA,UACC;AAAA,QACF;AAAA,QACF,kBAAkB,EACf,QAAQ,EACR,SAAS,EACT;AAAA,UACC;AAAA,QACF;AAAA,QACF,UAAU,EACP,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,EACT,SAAS,gDAAgD;AAAA,MAC9D,CAAC;AAAA,MACD,cAAc;AAAA,QACZ,cAAc;AAAA,QACd,UAAU;AAAA,QACV,WAAW;AAAA,MACb;AAAA,MACA,SAAS,OAAO,WAAW;AACzB,YAAI,CAAC,QAAQ,SAAS;AACpB,iBAAO;AAAA,YACL,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,UAAU;AAAA,cACR,UAAU;AAAA,gBACR,WAAW,QAAQ;AAAA,cACrB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,cAAM,iBAAyC;AAAA,UAC7C,eAAe,OAAO;AAAA,UACtB,kBAAkB,OAAO;AAAA,UACzB,UAAU,OAAO;AAAA,QACnB;AACA,cAAM,cAAc,MAAM,QAAQ,QAAQ,cAAc;AACxD,cAAM,SAAS,wBAAwB,WAAW;AAClD,eAAO;AAAA,UACL,OAAO;AAAA,UACP;AAAA,UACA,UAAU;AAAA,YACR,aAAa,6BAA6B,aAAa,MAAM;AAAA,YAC7D,UAAU;AAAA,cACR,WAAW,QAAQ;AAAA,cACnB,QAAQ,YAAY;AAAA,cACpB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,kBAAkB;AAAA,QAChB,cAAc;AAAA,QACd,UAAU;AAAA,QACV,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,0BACd,SACA,SACA;AACA,SAAO,KAAK;AAAA,IACV,SAAS,mBAAmB,OAAO;AAAA,IACnC;AAAA,MACE,aACE;AAAA,MACF,YAAY,EAAE,OAAO;AAAA,QACnB,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,yBAAyB;AAAA,QAC1D,UAAU,EACP,OAAO,EACP,SAAS,EACT,SAAS,0DAA0D;AAAA,QACtE,WAAW,EACR,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,EACT,SAAS,6CAA6C;AAAA,QACzD,QAAQ,EACL,QAAQ,EACR,SAAS,EACT;AAAA,UACC;AAAA,QACF;AAAA,MACJ,CAAC;AAAA,MACD,cAAc;AAAA,QACZ,cAAc;AAAA,QACd,UAAU;AAAA,QACV,aAAa;AAAA,QACb,WAAW;AAAA,QACX,aAAa;AAAA,MACf;AAAA,MACA,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,iBAAiB;AAAA,QACjB,QACE;AAAA,MACJ;AAAA,MACA,SAAS,OAAO,WAAW;AACzB,YAAI,CAAC,QAAQ,aAAa;AACxB,iBAAO;AAAA,YACL,OAAO;AAAA,YACP,QACE;AAAA,YACF,UAAU;AAAA,cACR,UAAU;AAAA,gBACR,WAAW,QAAQ;AAAA,cACrB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,cAAM,SAAS,8BAA8B;AAAA,UAC3C,WAAW;AAAA,UACX,kBAAkB;AAAA,UAClB,uBAAuB;AAAA,QACzB,CAAC;AACD,cAAM,QAAQ,MAAM,QAAQ,YAAY;AAAA,UACtC,MAAM,OAAO;AAAA,UACb,UAAU,OAAO;AAAA,UACjB,WAAW,OAAO;AAAA,UAClB,QAAQ,OAAO;AAAA,UACf,UAAU,EAAE,QAAQ,OAAO;AAAA,QAC7B,CAAC;AAED,eAAO;AAAA,UACL,OAAO;AAAA,UACP,QAAQ,sBAAsB,KAAK;AAAA,UACnC,UAAU;AAAA,YACR,UAAU;AAAA,cACR,WAAW,QAAQ;AAAA,cACnB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,kBAAkB;AAAA,QAChB,cAAc;AAAA,QACd,UAAU;AAAA,QACV,aAAa;AAAA,QACb,WAAW;AAAA,QACX,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,uBACd,SACA,SACA;AACA,SAAO,KAAK;AAAA,IACV,SAAS,QAAQ,OAAO;AAAA,IACxB;AAAA,MACE,aACE;AAAA,MACF,YAAY,EAAE,OAAO;AAAA,QACnB,QAAQ,EACL,OAAO,EACP,SAAS,EACT,SAAS,kCAAkC;AAAA,MAChD,CAAC;AAAA,MACD,cAAc;AAAA,QACZ,cAAc;AAAA,QACd,UAAU;AAAA,QACV,aAAa;AAAA,QACb,WAAW;AAAA,QACX,aAAa;AAAA,MACf;AAAA,MACA,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,iBAAiB;AAAA,QACjB,QACE;AAAA,MACJ;AAAA,MACA,SAAS,OAAO,EAAE,OAAO,MAAM;AAC7B,cAAM,QAAQ,MAAM,QAAQ,KAAK,MAAM;AACvC,eAAO;AAAA,UACL,OAAO;AAAA,UACP,QAAQ,sBAAsB,KAAK;AAAA,UACnC,UAAU;AAAA,YACR,UAAU;AAAA,cACR,WAAW,QAAQ;AAAA,cACnB,QAAQ,MAAM;AAAA,cACd;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,kBAAkB;AAAA,QAChB,cAAc;AAAA,QACd,UAAU;AAAA,QACV,aAAa;AAAA,QACb,WAAW;AAAA,QACX,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,4BACd,SACA,SACA;AACA,SAAO,KAAK;AAAA,IACV,SAAS,aAAa,OAAO;AAAA,IAC7B;AAAA,MACE,aACE;AAAA,MACF,YAAY,EAAE,OAAO;AAAA,QACnB,MAAM,EACH,KAAK,CAAC,QAAQ,OAAO,SAAS,SAAS,QAAQ,aAAa,OAAO,CAAC,EACpE,SAAS,EACT,SAAS,gCAAgC;AAAA,QAC5C,OAAO,EACJ,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,EACT,SAAS,wCAAwC;AAAA,MACtD,CAAC;AAAA,MACD,cAAc;AAAA,QACZ,cAAc;AAAA,QACd,UAAU;AAAA,QACV,WAAW;AAAA,MACb;AAAA,MACA,SAAS,OAAO,WAAW;AACzB,YAAI,CAAC,QAAQ,eAAe;AAC1B,iBAAO;AAAA,YACL,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,UAAU;AAAA,cACR,UAAU;AAAA,gBACR,WAAW,QAAQ;AAAA,cACrB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,cAAM,cAA4C;AAAA,UAChD,MAAM,OAAO;AAAA,UACb,OAAO,OAAO;AAAA,QAChB;AACA,cAAM,YAAY,MAAM,QAAQ,cAAc,WAAW;AACzD,cAAM,SACJ,UAAU,WAAW,IACjB,yCACA,UACG,IAAI,CAAC,aAAa,GAAG,SAAS,IAAI,KAAK,SAAS,GAAG,EAAE,EACrD,KAAK,IAAI;AAClB,eAAO;AAAA,UACL,OAAO;AAAA,UACP;AAAA,UACA,UAAU;AAAA,YACR,UAAU;AAAA,cACR,WAAW,QAAQ;AAAA,cACnB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,kBAAkB;AAAA,QAChB,cAAc;AAAA,QACd,UAAU;AAAA,QACV,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,2BACd,SACA,SACA;AACA,QAAM,QAAwB;AAAA,IAC5B,yBAAyB,SAAS,OAAO;AAAA,IACzC,0BAA0B,SAAS,OAAO;AAAA,IAC1C,4BAA4B,SAAS,OAAO;AAAA,IAC5C,uBAAuB,SAAS,OAAO;AAAA,EACzC;AAEA,MAAI,QAAQ,aAAa;AACvB,UAAM,OAAO,GAAG,GAAG,0BAA0B,SAAS,OAAO,CAAC;AAAA,EAChE;AAEA,SAAO;AACT;","names":[]}
|