@segmentstream/agent 0.8.4 → 0.8.5

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/README.md CHANGED
@@ -447,6 +447,14 @@ Building the package needs Node.js 24, as eve does: `npm run build` runs `eve ex
447
447
  which writes the agent-shaped `dist/extension` tree, its declarations and eve's compatibility
448
448
  manifest.
449
449
 
450
+ SDK-authored tool results and conversation archive events normalize runtime values to JSON
451
+ before returning or encoding them. Exact decimal/bigint strings and binary byte views are
452
+ preserved; conversion diagnostics identify the boundary and value path without logging payloads.
453
+ Maps use entry arrays so distinct key types and object keys retain every entry. Native brand and
454
+ binary getters avoid provider accessors; projection failures retain their redacted cause graph
455
+ through the shared operator diagnostics reporter.
456
+ This guard does not intercept Eve's own workflow streams or third-party tools.
457
+
450
458
  ## Environment
451
459
 
452
460
  The platform sets every variable on the workspace's Vercel project. None of them is a model key or
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- var version = "0.8.4";
7
+ var version = "0.8.5";
8
8
  function agentBuild(environment = process.env) {
9
9
  return {
10
10
  agent: version,
@@ -0,0 +1,715 @@
1
+ import { fileURLToPath as __eveFileURLToPath } from "node:url";
2
+ import { dirname as __eveDirname } from "node:path";
3
+ import { createRequire as __eveCreateRequire } from "node:module";
4
+ const __filename = __eveFileURLToPath(import.meta.url);
5
+ __eveDirname(__filename);
6
+ __eveCreateRequire(import.meta.url);
7
+ import { createHash, randomUUID } from "node:crypto";
8
+ import { Buffer as Buffer$1 } from "node:buffer";
9
+ import { types } from "node:util";
10
+ function makeRedactor(values = []) {
11
+ const secrets = [...new Set(values.filter((v) => typeof v === "string" && v.length > 0))].sort((a, b) => b.length - a.length);
12
+ return (input) => {
13
+ let text = input;
14
+ for (const value of secrets) text = text.replaceAll(value, "[REDACTED]");
15
+ return redactPrivateKeys(text).replace(/\bsscli_(?:access_)?v1\.[a-f0-9-]{36}\.[A-Za-z0-9_-]{43}\b/gi, "[REDACTED CLI CREDENTIAL]").replace(/\b(?:Bearer|Basic)\s+[A-Za-z0-9+/_=.:~-]+/gi, "[REDACTED AUTHORIZATION]").replace(/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g, "[REDACTED JWT]").replace(/\b(?:sk|rk|vercel_blob_rw|vercel_blob_r|access_token|refresh_token)_[A-Za-z0-9._~-]{8,}/g, "[REDACTED]").replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^\s/@]+@/gi, "$1[REDACTED]@").replace(/([?&](?:access_token|api_key|apikey|key|password|refresh_token|secret|token|signature|sig)=)[^&#\s]*/gi, "$1[REDACTED]").replace(/((?:["']?)(?:password|passwd|credential|secret|client_secret|api_key|access_token|refresh_token|authorization|cookie|set-cookie|token)(?:["']?)\s*[:=]\s*)(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[^\s,;})]+)/gi, "$1[REDACTED]").replace(/(Key\s*\([^)]*\)\s*=\s*)\([^)]*\)/gi, "$1([REDACTED])").replace(/(invalid input syntax for [^:]+:\s*)"[^"]*"/gi, "$1[REDACTED]");
16
+ };
17
+ }
18
+ function environmentSecrets(env) {
19
+ return Object.entries(env).filter(([key]) => /(?:TOKEN|SECRET|PASSWORD|PRIVATE_KEY|API_KEY|COOKIE|SIGNING_KEY|DATABASE_URL|POSTGRES_URL|GRANT)/i.test(key)).map(([, value]) => value);
20
+ }
21
+ function isSensitiveField(key) {
22
+ return /password|passwd|credential|secret|token|authorization|cookie|private[_-]?key|api[_-]?key|grant/i.test(key);
23
+ }
24
+ function redactPrivateKeys(text) {
25
+ const begin = /-----BEGIN [^-]*PRIVATE KEY-----/g;
26
+ const end = /-----END [^-]*PRIVATE KEY-----/g;
27
+ const parts = [];
28
+ let copiedThrough = 0;
29
+ let opening;
30
+ while ((opening = begin.exec(text)) !== null) {
31
+ end.lastIndex = begin.lastIndex;
32
+ if (end.exec(text) === null) break;
33
+ parts.push(text.slice(copiedThrough, opening.index), "[REDACTED PRIVATE KEY]");
34
+ copiedThrough = end.lastIndex;
35
+ begin.lastIndex = copiedThrough;
36
+ }
37
+ parts.push(text.slice(copiedThrough));
38
+ return parts.join("");
39
+ }
40
+ const failureRedactions = new WeakMap();
41
+ const MAX_BYTES = 1048576;
42
+ const MAX_NODES = 1024;
43
+ const FIELDS = [
44
+ "fiberId",
45
+ "code",
46
+ "status",
47
+ "statusCode",
48
+ "provider",
49
+ "providerCode",
50
+ "providerRequestId",
51
+ "method",
52
+ "host",
53
+ "path",
54
+ "retryable",
55
+ "constraint",
56
+ "sqlState",
57
+ "field",
58
+ "expected",
59
+ "actual",
60
+ "setting",
61
+ "resourceId",
62
+ "runtimeAttemptId",
63
+ "sandboxId",
64
+ "sessionId",
65
+ "remoteErrorId",
66
+ "endpoint",
67
+ "requestId",
68
+ "providerMessage",
69
+ "providerDescription",
70
+ "stderr",
71
+ "exitCode"
72
+ ];
73
+ const links = Symbol.for("segmentstream.diagnostic.links");
74
+ const incomplete = Symbol.for("segmentstream.diagnostic.omissions");
75
+ const RELATIONS = [
76
+ "cause",
77
+ "aggregate",
78
+ "primary",
79
+ "cleanup",
80
+ "concurrent"
81
+ ];
82
+ const MAX_EDGES = 8192;
83
+ function property(value, key) {
84
+ if ((typeof value !== "object" || value === null) && typeof value !== "function") return void 0;
85
+ try {
86
+ return Reflect.get(value, key);
87
+ } catch {
88
+ return;
89
+ }
90
+ }
91
+ function scalar(value) {
92
+ return typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value);
93
+ }
94
+ function ownValues(value) {
95
+ if (!value || typeof value !== "object") return [];
96
+ try {
97
+ return Object.values(Object.getOwnPropertyDescriptors(value)).filter((descriptor) => "value" in descriptor).map((descriptor) => descriptor.value);
98
+ } catch {
99
+ return [];
100
+ }
101
+ }
102
+ function schemaInputRedactions(root) {
103
+ const values = new Set();
104
+ const seen = new Set();
105
+ const errors = [root];
106
+ const issues = [];
107
+ let limited = false;
108
+ let traversed = 0;
109
+ while (errors.length && seen.size < MAX_NODES) {
110
+ if (++traversed > MAX_EDGES || errors.length > MAX_EDGES) {
111
+ limited = true;
112
+ break;
113
+ }
114
+ const value = errors.shift();
115
+ if (seen.has(value)) continue;
116
+ seen.add(value);
117
+ if (value !== null && (typeof value === "object" || typeof value === "function")) {
118
+ for (const secret of failureRedactions.get(value) ?? []) if (secret) values.add(secret);
119
+ }
120
+ if (property(value, "_tag") === "SchemaError" || property(value, "name") === "SchemaError") issues.push(property(value, "issue"));
121
+ const explicit = property(value, links);
122
+ if (Array.isArray(explicit)) {
123
+ if (explicit.length > MAX_NODES) limited = true;
124
+ errors.push(...explicit.slice(0, MAX_NODES).map((item) => property(item, "error")));
125
+ }
126
+ const cause = property(value, "cause");
127
+ if (cause !== void 0) errors.push(cause);
128
+ const aggregate = property(value, "errors");
129
+ if (property(value, "name") === "AggregateError" && Array.isArray(aggregate)) {
130
+ if (aggregate.length > MAX_NODES) limited = true;
131
+ errors.push(...aggregate.slice(0, MAX_NODES));
132
+ }
133
+ }
134
+ if (errors.length) limited = true;
135
+ seen.clear();
136
+ const inputs = [];
137
+ while (issues.length && seen.size < MAX_NODES) {
138
+ if (++traversed > MAX_EDGES || issues.length > MAX_EDGES) {
139
+ limited = true;
140
+ break;
141
+ }
142
+ const issue = issues.pop();
143
+ if (!issue || seen.has(issue)) continue;
144
+ seen.add(issue);
145
+ for (const key of ["input", "actual"]) {
146
+ const input = property(issue, key);
147
+ if (input !== void 0) inputs.push(input);
148
+ }
149
+ const child = property(issue, "issue");
150
+ if (child !== void 0) issues.push(child);
151
+ const children = property(issue, "issues");
152
+ if (Array.isArray(children)) {
153
+ if (children.length > MAX_NODES) limited = true;
154
+ issues.push(...children.slice(0, MAX_NODES));
155
+ }
156
+ }
157
+ if (issues.length) limited = true;
158
+ seen.clear();
159
+ let characters = 0;
160
+ while (inputs.length && seen.size < 4096 && characters < MAX_BYTES) {
161
+ if (++traversed > MAX_EDGES || inputs.length > MAX_EDGES) {
162
+ limited = true;
163
+ break;
164
+ }
165
+ const value = inputs.pop();
166
+ if (seen.has(value)) continue;
167
+ seen.add(value);
168
+ if (scalar(value) && String(value)) {
169
+ const text = String(value);
170
+ characters += text.length;
171
+ values.add(text);
172
+ if (typeof value === "string") values.add(JSON.stringify(value).slice(1, -1));
173
+ } else {
174
+ const children = ownValues(value);
175
+ if (children.length > 4096) limited = true;
176
+ inputs.push(...children.slice(0, 4096));
177
+ }
178
+ }
179
+ if (inputs.length) limited = true;
180
+ return {
181
+ values: [...values],
182
+ limited
183
+ };
184
+ }
185
+ function createFailureReport(error, options) {
186
+ const schemaInputs = schemaInputRedactions(error);
187
+ if (schemaInputs.limited) return redactionLimitReport();
188
+ const redact = makeRedactor([...options.redactedValues ?? [], ...schemaInputs.values]);
189
+ let remaining = 1044480;
190
+ const omissions = new Set();
191
+ const clean = (value) => {
192
+ const safe = redact(value.slice(0, MAX_BYTES));
193
+ if (value.length > MAX_BYTES) omissions.add("field input exceeded 1 MiB");
194
+ const bytes = Buffer.from(JSON.stringify(safe));
195
+ const allowance = Math.max(0, remaining);
196
+ if (bytes.length > allowance) {
197
+ omissions.add("report exceeded 1 MiB");
198
+ remaining = 0;
199
+ let low = 0;
200
+ let high = safe.length;
201
+ while (low < high) {
202
+ const middle = Math.ceil((low + high) / 2);
203
+ if (Buffer.byteLength(JSON.stringify(safe.slice(0, middle))) + 20 <= allowance) low = middle;
204
+ else high = middle - 1;
205
+ }
206
+ return safe.slice(0, low).replace(/[\uD800-\uDBFF]$/, "") + " [TRUNCATED]";
207
+ }
208
+ remaining -= bytes.length;
209
+ return safe;
210
+ };
211
+ const report = {
212
+ version: 1,
213
+ errorId: options.errorId && /^[A-Za-z0-9_.:-]{1,200}$/.test(options.errorId) ? options.errorId : `err_${randomUUID().replaceAll("-", "")}`,
214
+ timestamp: options.timestamp?.slice(0, 100) ?? new Date().toISOString(),
215
+ service: clean(options.service),
216
+ context: {},
217
+ roots: [],
218
+ nodes: [],
219
+ complete: true,
220
+ omissions: []
221
+ };
222
+ const contextEntries = Object.entries(options.context ?? {});
223
+ if (contextEntries.length > 128) omissions.add("context exceeded 128 fields");
224
+ for (const [key, value] of contextEntries.slice(0, 128)) if (scalar(value)) report.context[clean(key)] = isSensitiveField(key) ? "[REDACTED]" : typeof value === "string" ? clean(value) : value;
225
+ const seen = new Map();
226
+ const queue = [];
227
+ const add = (value) => {
228
+ const object = typeof value === "object" && value !== null || typeof value === "function";
229
+ if (object && seen.has(value)) return seen.get(value);
230
+ if (queue.length >= MAX_NODES || remaining < 1024) {
231
+ omissions.add(queue.length >= MAX_NODES ? "report exceeded 1024 nodes" : "report exceeded 1 MiB");
232
+ return;
233
+ }
234
+ const id = `n${queue.length + 1}`;
235
+ if (object) seen.set(value, id);
236
+ queue.push({
237
+ value,
238
+ id
239
+ });
240
+ remaining -= 512;
241
+ return id;
242
+ };
243
+ const root = add(error);
244
+ if (root) report.roots.push(root);
245
+ let edges = 0;
246
+ for (let index = 0; index < queue.length; index++) {
247
+ const { value, id } = queue[index];
248
+ const inheritedOmissions = property(value, incomplete);
249
+ if (Array.isArray(inheritedOmissions)) {
250
+ for (const reason of inheritedOmissions.slice(0, 128)) if (typeof reason === "string") omissions.add(clean(reason));
251
+ }
252
+ const name = property(value, "_tag") ?? property(value, "name");
253
+ const message = property(value, "message");
254
+ const node = {
255
+ id,
256
+ type: typeof name === "string" ? clean(name) : "NonErrorThrow",
257
+ message: clean(typeof message === "string" && message ? message : typeof value === "string" ? value : `Thrown ${typeof value} value`),
258
+ causes: []
259
+ };
260
+ for (const key of [
261
+ "stack",
262
+ "operation",
263
+ "diagnostic"
264
+ ]) {
265
+ const field = property(value, key);
266
+ if (typeof field === "string") node[key] = clean(field);
267
+ }
268
+ const details = {};
269
+ for (const key of FIELDS) {
270
+ const field = property(value, key);
271
+ if (scalar(field)) details[key] = (key === "expected" || key === "actual") && isSensitiveField(String(property(value, "field") ?? "")) ? "[REDACTED]" : typeof field === "string" ? clean(field) : field;
272
+ }
273
+ if (Object.keys(details).length) node.details = details;
274
+ const children = [];
275
+ const explicit = property(value, links);
276
+ if (Array.isArray(explicit)) {
277
+ for (const item of explicit.slice(0, MAX_NODES)) {
278
+ const relation = property(item, "relation");
279
+ if (typeof relation === "string" && RELATIONS.includes(relation)) children.push({
280
+ error: property(item, "error"),
281
+ relation
282
+ });
283
+ else omissions.add("invalid diagnostic cause link");
284
+ }
285
+ if (explicit.length > MAX_NODES) omissions.add("cause links exceeded 1024 children");
286
+ }
287
+ const cause = property(value, "cause");
288
+ if (cause !== void 0) children.push({
289
+ error: cause,
290
+ relation: "cause"
291
+ });
292
+ if (value instanceof AggregateError || property(value, "name") === "AggregateError") {
293
+ const errors = property(value, "errors");
294
+ if (Array.isArray(errors)) {
295
+ for (const item of errors.slice(0, MAX_NODES)) children.push({
296
+ error: item,
297
+ relation: "aggregate"
298
+ });
299
+ if (errors.length > MAX_NODES) omissions.add("aggregate exceeded 1024 children");
300
+ }
301
+ }
302
+ for (const child of children) {
303
+ if (edges >= MAX_EDGES || remaining < 100) {
304
+ omissions.add(edges >= MAX_EDGES ? "report exceeded 8192 cause links" : "report exceeded 1 MiB");
305
+ break;
306
+ }
307
+ edges++;
308
+ remaining -= 100;
309
+ const childId = add(child.error);
310
+ if (childId) node.causes.push({
311
+ id: childId,
312
+ relation: child.relation
313
+ });
314
+ }
315
+ report.nodes.push(node);
316
+ }
317
+ report.omissions = [...omissions];
318
+ report.complete = !report.omissions.length;
319
+ return fitReport(report);
320
+ }
321
+ function redactionLimitReport() {
322
+ return {
323
+ version: 1,
324
+ errorId: `err_${randomUUID().replaceAll("-", "")}`,
325
+ timestamp: new Date().toISOString(),
326
+ service: "diagnostics",
327
+ context: {},
328
+ roots: ["n1"],
329
+ nodes: [{
330
+ id: "n1",
331
+ type: "RedactionLimitError",
332
+ message: "Failure details omitted because secret-redaction traversal was incomplete.",
333
+ causes: []
334
+ }],
335
+ complete: false,
336
+ omissions: ["secret redaction traversal exceeded its defensive budget (1024 graph/issue nodes, 4096 input values, 8192 traversal steps, 1 MiB)"]
337
+ };
338
+ }
339
+ function fitReport(report) {
340
+ const wireBytes = () => Buffer.byteLength(JSON.stringify(report));
341
+ if (wireBytes() <= MAX_BYTES) return report;
342
+ report.complete = false;
343
+ report.omissions.push("serialized report exceeded 1 MiB");
344
+ while (wireBytes() > MAX_BYTES && report.nodes.length > 1) report.nodes.pop();
345
+ const retained = new Set(report.nodes.map((node) => node.id));
346
+ report.roots = report.roots.filter((id) => retained.has(id));
347
+ for (const node of report.nodes) node.causes = node.causes.filter((edge) => retained.has(edge.id));
348
+ if (wireBytes() > MAX_BYTES) {
349
+ report.context = {};
350
+ report.service = report.service.slice(0, 200);
351
+ report.omissions = report.omissions.map((message) => message.slice(0, 1e3)).slice(0, 128);
352
+ report.nodes = report.nodes.map((node) => ({
353
+ id: node.id,
354
+ type: node.type.slice(0, 200),
355
+ message: node.message.slice(0, 1e3) + " [TRUNCATED]",
356
+ causes: node.causes
357
+ }));
358
+ }
359
+ return report;
360
+ }
361
+ function renderFailure(report, maxBytes = 8192) {
362
+ const nodes = new Map(report.nodes.map((node) => [node.id, node]));
363
+ const seen = new Set();
364
+ const pending = report.roots.map((id) => ({
365
+ id,
366
+ depth: 0,
367
+ relation: "root"
368
+ }));
369
+ const lines = [`Failure ${report.errorId} (${report.service})`];
370
+ while (pending.length) {
371
+ const item = pending.pop();
372
+ const prefix = `${" ".repeat(Math.min(item.depth, 32))}${item.relation}: `;
373
+ if (seen.has(item.id)) {
374
+ lines.push(`${prefix}[reference ${item.id}]`);
375
+ continue;
376
+ }
377
+ seen.add(item.id);
378
+ const node = nodes.get(item.id);
379
+ if (!node) {
380
+ lines.push(`${prefix}[missing ${item.id}]`);
381
+ continue;
382
+ }
383
+ lines.push(`${prefix}${node.type}${node.diagnostic ? `:${node.diagnostic}` : ""}${node.operation ? ` at ${node.operation}` : ""}: ${node.message}`);
384
+ if (node.details) lines.push(`${prefix}${JSON.stringify(node.details)}`);
385
+ for (const child of [...node.causes].reverse()) pending.push({
386
+ ...child,
387
+ depth: item.depth + 1
388
+ });
389
+ }
390
+ if (!report.complete) lines.push(`Incomplete: ${report.omissions.join("; ")}`);
391
+ const text = lines.join("\n");
392
+ if (Buffer.byteLength(text) <= maxBytes) return text;
393
+ const suffix = `\n[Journal shortened; complete report in diagnostics logs: ${report.errorId}]`;
394
+ return Buffer.from(text).subarray(0, Math.max(0, maxBytes - Buffer.byteLength(suffix) - 3)).toString("utf8").replace(/\uFFFD$/, "") + suffix;
395
+ }
396
+ function encodeReport(report) {
397
+ const direct = JSON.stringify({
398
+ event: "diagnostics.report",
399
+ report
400
+ });
401
+ if (Buffer.byteLength(direct) <= 4096) return [direct];
402
+ const bytes = Buffer.from(JSON.stringify(report));
403
+ const checksum = createHash("sha256").update(bytes).digest("hex");
404
+ const size = 2e3;
405
+ const correlation = Object.fromEntries([
406
+ "workflowRunId",
407
+ "requestId",
408
+ "pipelineRunId"
409
+ ].flatMap((key) => typeof report.context[key] === "string" && /^[A-Za-z0-9_.:-]{1,200}$/.test(String(report.context[key])) ? [[key, String(report.context[key]).slice(0, 200)]] : []));
410
+ const total = Math.ceil(bytes.length / size);
411
+ return Array.from({ length: total }, (_, i) => JSON.stringify({
412
+ event: "diagnostics.chunk",
413
+ errorId: report.errorId,
414
+ part: i + 1,
415
+ total,
416
+ checksum,
417
+ correlation,
418
+ encoding: "base64",
419
+ data: bytes.subarray(i * size, (i + 1) * size).toString("base64")
420
+ }));
421
+ }
422
+ function makeErrorReporter({ configuration, generateId = randomUUID, now = () => new Date(), observe, write = (severity, line) => severity === "warning" ? console.warn(line) : console.error(line) }) {
423
+ function capture(error, context) {
424
+ let report;
425
+ const errorId = context.errorReference ?? `err_${randomUUID().replaceAll("-", "")}`;
426
+ try {
427
+ report = createFailureReport(error, {
428
+ service: configuration.service,
429
+ context: {
430
+ environment: configuration.environment,
431
+ release: configuration.release,
432
+ region: configuration.region,
433
+ ...context
434
+ },
435
+ errorId: context.errorReference ?? `err_${generateId().replaceAll("-", "").toLowerCase()}`,
436
+ timestamp: now().toISOString(),
437
+ redactedValues: configuration.redactedValues
438
+ });
439
+ } catch {
440
+ report = createFailureReport(error, {
441
+ service: configuration.service,
442
+ errorId,
443
+ redactedValues: configuration.redactedValues,
444
+ context: { reportingFailure: true }
445
+ });
446
+ }
447
+ try {
448
+ const lines = encodeReport(report);
449
+ if (lines.length > 1) {
450
+ let budget = 2e3;
451
+ let summary;
452
+ do {
453
+ summary = JSON.stringify({
454
+ event: "diagnostics.summary",
455
+ errorId: report.errorId,
456
+ tree: renderFailure(report, budget),
457
+ completeReport: "Reconstruct diagnostics.chunk entries by errorId"
458
+ });
459
+ budget = Math.floor(budget / 2);
460
+ } while (Buffer.byteLength(summary) > 4096 && budget > 128);
461
+ if (Buffer.byteLength(summary) <= 4096) write(context.severity ?? "error", summary);
462
+ }
463
+ for (const line of lines) write(context.severity ?? "error", line);
464
+ } catch {
465
+ report.context.reportingFailure = true;
466
+ try {
467
+ for (const line of encodeReport(report)) process.stderr.write(line + "\n");
468
+ } catch {}
469
+ }
470
+ try {
471
+ observe?.(report);
472
+ } catch {}
473
+ return report;
474
+ }
475
+ return {
476
+ capture,
477
+ report: (error, context) => capture(error, context).errorId
478
+ };
479
+ }
480
+ function reportRuntimeFailure(error, context, environment = process.env) {
481
+ const { service, ...details } = context;
482
+ return makeErrorReporter({ configuration: {
483
+ service,
484
+ redactedValues: environmentSecrets(environment)
485
+ } }).report(error, details);
486
+ }
487
+ const errorStackGetter = Object.getOwnPropertyDescriptor(new Error(), "stack")?.get;
488
+ function intrinsicGetter(prototype, name) {
489
+ return Object.getOwnPropertyDescriptor(prototype, name)?.get;
490
+ }
491
+ const binaryGetters = [Object.getPrototypeOf(Uint8Array.prototype), DataView.prototype].map((prototype) => ({
492
+ buffer: intrinsicGetter(prototype, "buffer"),
493
+ offset: intrinsicGetter(prototype, "byteOffset"),
494
+ length: intrinsicGetter(prototype, "byteLength")
495
+ }));
496
+ function binaryBytes(item) {
497
+ if (!ArrayBuffer.isView(item)) return new Uint8Array(item);
498
+ const getters = binaryGetters[types.isDataView(item) ? 1 : 0];
499
+ return new Uint8Array(getters.buffer.call(item), getters.offset.call(item), getters.length.call(item));
500
+ }
501
+ function toWorkflowSerializable(value, report = () => {}) {
502
+ const ancestors = new WeakSet();
503
+ let remaining = 5e4;
504
+ const issue = (path, reason, cause) => {
505
+ try {
506
+ report({
507
+ path,
508
+ reason,
509
+ ...cause === void 0 ? {} : { cause }
510
+ });
511
+ } catch {}
512
+ };
513
+ const property = (output, key, item) => {
514
+ Object.defineProperty(output, key, {
515
+ value: item,
516
+ enumerable: true,
517
+ configurable: true
518
+ });
519
+ };
520
+ const dropped = (item) => item === void 0 || typeof item === "function" || typeof item === "symbol";
521
+ const dataProperty = (item, key) => {
522
+ let current = item;
523
+ for (let depth = 0; current !== null && depth <= 64; depth++) {
524
+ const descriptor = Object.getOwnPropertyDescriptor(current, key);
525
+ if (descriptor) return "value" in descriptor ? descriptor.value : void 0;
526
+ current = Object.getPrototypeOf(current);
527
+ }
528
+ };
529
+ function visit(item, path, depth) {
530
+ if (--remaining < 0 || depth > 64) {
531
+ issue(path, "limit");
532
+ return null;
533
+ }
534
+ if (item === null || typeof item === "string" || typeof item === "boolean") return item;
535
+ if (typeof item === "number") {
536
+ if (Number.isFinite(item)) return item;
537
+ issue(path, "non-finite number");
538
+ return null;
539
+ }
540
+ if (typeof item === "bigint") {
541
+ issue(path, "bigint");
542
+ return String(item);
543
+ }
544
+ if (typeof item !== "object") {
545
+ issue(path, typeof item);
546
+ return null;
547
+ }
548
+ if (ancestors.has(item)) {
549
+ issue(path, "cycle");
550
+ return null;
551
+ }
552
+ ancestors.add(item);
553
+ try {
554
+ if (types.isDate(item)) {
555
+ issue(path, "Date");
556
+ const time = Date.prototype.getTime.call(item);
557
+ return Number.isFinite(time) ? new Date(time).toISOString() : null;
558
+ }
559
+ if (ArrayBuffer.isView(item) || types.isAnyArrayBuffer(item)) {
560
+ issue(path, "binary");
561
+ const bytes = binaryBytes(item);
562
+ return Buffer$1.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64");
563
+ }
564
+ if (types.isMap(item)) {
565
+ issue(path, "Map");
566
+ const output = [];
567
+ for (const [key, entry] of Map.prototype.entries.call(item)) {
568
+ if (remaining <= 0) {
569
+ issue(path, "map limit");
570
+ break;
571
+ }
572
+ const index = output.length;
573
+ output.push([visit(key, `${path}[${index}][0]`, depth + 1), visit(entry, `${path}[${index}][1]`, depth + 1)]);
574
+ }
575
+ return output;
576
+ }
577
+ if (types.isSet(item)) {
578
+ issue(path, "Set");
579
+ const output = [];
580
+ for (const entry of Set.prototype.values.call(item)) {
581
+ if (remaining <= 0) {
582
+ issue(path, "set limit");
583
+ break;
584
+ }
585
+ output.push(visit(entry, `${path}[${output.length}]`, depth + 1));
586
+ }
587
+ return output;
588
+ }
589
+ if (Array.isArray(item)) {
590
+ const count = Object.getOwnPropertyDescriptor(item, "length")?.value;
591
+ if (typeof count !== "number" || !Number.isSafeInteger(count) || count < 0) {
592
+ issue(path, "invalid array length");
593
+ return null;
594
+ }
595
+ const length = Math.min(count, Math.max(remaining, 0));
596
+ if (length !== count) issue(path, "array limit");
597
+ return Array.from({ length }, (_, index) => {
598
+ const descriptor = Object.getOwnPropertyDescriptor(item, String(index));
599
+ if (descriptor?.get) {
600
+ issue(`${path}[${index}]`, "accessor");
601
+ return null;
602
+ }
603
+ return visit(descriptor?.value, `${path}[${index}]`, depth + 1);
604
+ });
605
+ }
606
+ const prototype = Object.getPrototypeOf(item);
607
+ const plain = prototype === null || Object.getPrototypeOf(prototype) === null;
608
+ const nativeError = types.isNativeError(item);
609
+ if (!plain) issue(path, nativeError ? "Error" : "class instance");
610
+ if (nativeError) {
611
+ const name = dataProperty(item, "name");
612
+ const message = dataProperty(item, "message");
613
+ const output = {
614
+ name: typeof name === "string" ? name : "Error",
615
+ message: typeof message === "string" ? message : ""
616
+ };
617
+ for (const key of Object.getOwnPropertyNames(item)) {
618
+ if (remaining <= 0) {
619
+ issue(path, "error limit");
620
+ break;
621
+ }
622
+ const descriptor = Object.getOwnPropertyDescriptor(item, key);
623
+ if (key === "stack" && errorStackGetter && descriptor?.get) {
624
+ property(output, key, visit(errorStackGetter.call(item), `${path}.stack`, depth + 1));
625
+ continue;
626
+ }
627
+ if (key !== "__proto__" && descriptor && "value" in descriptor && !dropped(descriptor.value)) property(output, key, visit(descriptor.value, `${path}[${JSON.stringify(key)}]`, depth + 1));
628
+ }
629
+ return output;
630
+ }
631
+ if (!plain) {
632
+ let current = prototype;
633
+ const prototypes = new WeakSet();
634
+ for (let prototypeDepth = 0; current !== null; prototypeDepth++) {
635
+ if (prototypeDepth >= 64 || prototypes.has(current)) {
636
+ issue(path, "prototype limit");
637
+ break;
638
+ }
639
+ prototypes.add(current);
640
+ const json = Object.getOwnPropertyDescriptor(current, "toJSON");
641
+ if (typeof json?.value === "function") return visit(json.value.call(item), path, depth + 1);
642
+ current = Object.getPrototypeOf(current);
643
+ }
644
+ }
645
+ const output = {};
646
+ for (const key of Reflect.ownKeys(item)) {
647
+ if (remaining <= 0) {
648
+ issue(path, "object limit");
649
+ break;
650
+ }
651
+ const descriptor = Object.getOwnPropertyDescriptor(item, key);
652
+ if (!descriptor?.enumerable) continue;
653
+ const childPath = `${path}[${JSON.stringify(String(key))}]`;
654
+ if (typeof key === "symbol" || key === "__proto__" || descriptor.get) {
655
+ issue(childPath, descriptor.get ? "accessor" : "unsupported key");
656
+ continue;
657
+ }
658
+ if (dropped(descriptor.value)) {
659
+ if (descriptor.value !== void 0) issue(childPath, typeof descriptor.value);
660
+ continue;
661
+ }
662
+ property(output, key, visit(descriptor.value, childPath, depth + 1));
663
+ }
664
+ return output;
665
+ } catch (cause) {
666
+ issue(path, "unreadable value", cause);
667
+ return null;
668
+ } finally {
669
+ ancestors.delete(item);
670
+ }
671
+ }
672
+ return visit(value, "$", 0);
673
+ }
674
+ let diagnosticSequence = 0;
675
+ function workflowValue(value, context) {
676
+ const issues = [];
677
+ const failures = [];
678
+ let count = 0;
679
+ const output = toWorkflowSerializable(value, (issue) => {
680
+ count++;
681
+ if ("cause" in issue) failures.push(issue.cause);
682
+ if (issues.length < 20) issues.push({
683
+ reason: issue.reason,
684
+ path: issue.path.replace(/\["(?:[^"\\]|\\.)*"\]/g, "[field]")
685
+ });
686
+ });
687
+ if (count > 0) try {
688
+ const errorId = globalThis.crypto?.randomUUID?.() ?? `serialization-${Date.now()}-${++diagnosticSequence}`;
689
+ if (failures.length > 0) reportRuntimeFailure(failures.length === 1 ? failures[0] : new AggregateError(failures, "Workflow value projections failed"), {
690
+ service: "segmentstream-agent",
691
+ boundary: context.boundary,
692
+ operation: "workflow.normalize",
693
+ severity: "warning",
694
+ errorReference: errorId
695
+ });
696
+ console.warn("[workflow] normalized non-JSON value", {
697
+ errorId,
698
+ boundary: context.boundary,
699
+ toolName: context.toolName,
700
+ toolCallId: context.toolCallId,
701
+ eventType: context.eventType,
702
+ issues,
703
+ issueCount: count
704
+ });
705
+ } catch {}
706
+ return output;
707
+ }
708
+ function workflowToolResult(value, context) {
709
+ return workflowValue(value, {
710
+ boundary: "SDK tool result",
711
+ toolName: context.toolName,
712
+ toolCallId: context.callId
713
+ });
714
+ }
715
+ export { workflowToolResult as n, workflowValue as r, toWorkflowSerializable as t };
@@ -4,5 +4,5 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { t as agentBuild } from "../../_chunks/build-metadata-ByEgTqDs.mjs";
7
+ import { t as agentBuild } from "../../_chunks/build-metadata-BYl-5kFi.mjs";
8
8
  export { agentBuild };
@@ -6,6 +6,7 @@ __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { proxyEnvironment } from "./environment.mjs";
8
8
  import { runtimeToken } from "./runtime-token.mjs";
9
+ import { r as workflowValue } from "../../_chunks/workflow-serializable-BwttWNmY.mjs";
9
10
  function collapseConversationEvents(events) {
10
11
  const latest = new Map();
11
12
  for (const event of events) {
@@ -20,7 +21,7 @@ function collapseConversationEvents(events) {
20
21
  return [...latest.values()];
21
22
  }
22
23
  function conversationEvent(input) {
23
- return {
24
+ return workflowValue({
24
25
  threadId: null,
25
26
  participantIds: [],
26
27
  senderId: null,
@@ -40,7 +41,12 @@ function conversationEvent(input) {
40
41
  attachments: [],
41
42
  at: new Date().toISOString(),
42
43
  ...input
43
- };
44
+ }, {
45
+ boundary: "SDK conversation event",
46
+ eventType: input.kind,
47
+ toolName: input.toolName ?? void 0,
48
+ toolCallId: input.toolCallId ?? void 0
49
+ });
44
50
  }
45
51
  function conversations(input = {}) {
46
52
  const environment = input.environment ?? process.env;
@@ -58,7 +64,7 @@ function conversations(input = {}) {
58
64
  "x-segmentstream-organization-id": env.organizationId,
59
65
  "x-segmentstream-runtime-identity": identity
60
66
  },
61
- body: JSON.stringify(body),
67
+ body: JSON.stringify(workflowValue(body, { boundary: "conversation archive" })),
62
68
  signal: AbortSignal.timeout(15e3)
63
69
  });
64
70
  if (!response.ok) throw new Error(`Conversation archive ${path} failed (${response.status}); request ${response.headers.get("x-request-id") ?? "unknown"}.`);
@@ -88,7 +94,7 @@ function summarizeArguments(value) {
88
94
  if (item !== null && typeof item === "object") return Object.fromEntries(Object.entries(item).slice(0, 30).map(([key, entry]) => [key, sensitive.test(key) ? "[redacted]" : visit(entry, depth + 1)]));
89
95
  return typeof item === "string" ? item.replace(/(https?:\/\/)[^/@\s]+:[^/@\s]+@/gu, "$1[redacted]@").replace(/([?&](?:token|access_token|api_key|signature|secret|password)=)[^&#\s]*/giu, "$1[redacted]").replace(/\bBearer [A-Za-z0-9_.~+/-]+=*/giu, "Bearer [redacted]").slice(0, 500) : item;
90
96
  };
91
- return (JSON.stringify(visit(value, 0)) ?? "{}").slice(0, 4e3);
97
+ return JSON.stringify(workflowValue(visit(value, 0), { boundary: "conversation arguments" })).slice(0, 4e3);
92
98
  }
93
99
  function retainedInboundEvidence(event) {
94
100
  if (event.kind !== "inbound") return;
@@ -8,7 +8,7 @@ import { manifestOf } from "../../config.mjs";
8
8
  import { appOrigin, channelsEnabled, proxyEnvironment, runtimeIdentityEnvironment, webhookSecret } from "../environment.mjs";
9
9
  import { conversationLanguage, telegramPrincipal } from "./principal.mjs";
10
10
  import { chooseModel } from "../../model.mjs";
11
- import { t as agentBuild } from "../../../_chunks/build-metadata-ByEgTqDs.mjs";
11
+ import { t as agentBuild } from "../../../_chunks/build-metadata-BYl-5kFi.mjs";
12
12
  import { confirmationLocale } from "./confirmation-text.mjs";
13
13
  import { telegramSendScope } from "./send-queue.mjs";
14
14
  import { d as failureText, h as withDeliveryLocale, i as withReplacedText, m as safeTelegramFetch, n as currentInboundRequest, p as reportTelegramError, r as runInboundRequest, t as InboundRequest } from "../../../_chunks/inbound-request-B98tr4Pd.mjs";
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { t as agentBuild } from "../../../_chunks/build-metadata-ByEgTqDs.mjs";
7
+ import { t as agentBuild } from "../../../_chunks/build-metadata-BYl-5kFi.mjs";
8
8
  import { runtimeRequestFailure } from "./runtime-request.mjs";
9
9
  import { GET } from "eve/channels";
10
10
  const HEALTH_ROUTE = "/eve/v1/telegram/health";
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
- import { t as agentBuild } from "../../../_chunks/build-metadata-ByEgTqDs.mjs";
7
+ import { t as agentBuild } from "../../../_chunks/build-metadata-BYl-5kFi.mjs";
8
8
  import { object } from "../confirmation-description.mjs";
9
9
  import { n as currentInboundRequest, p as reportTelegramError } from "../../../_chunks/inbound-request-B98tr4Pd.mjs";
10
10
  import { needsConfirmation } from "../confirmations.mjs";
@@ -0,0 +1,29 @@
1
+ /** JSON data produced by SDK tools and conversation archive events. */
2
+ export type WorkflowSerializable = null | boolean | number | string | WorkflowSerializable[] | {
3
+ [key: string]: WorkflowSerializable;
4
+ };
5
+ export interface SerializationIssue {
6
+ readonly path: string;
7
+ readonly reason: string;
8
+ readonly cause?: unknown;
9
+ }
10
+ export interface SerializationContext {
11
+ readonly boundary: string;
12
+ readonly toolName?: string;
13
+ readonly toolCallId?: string;
14
+ readonly eventType?: string;
15
+ }
16
+ /**
17
+ * Never mutate a provider result; read own data fields without invoking their getters.
18
+ * Undefined/functions/symbols disappear from
19
+ * objects and become null in arrays. An active-ancestor set breaks cycles without losing shared
20
+ * references. Limits also protect the durable writer from hostile proxies or excessively deep data.
21
+ */
22
+ export declare function toWorkflowSerializable(value: unknown, report?: (issue: SerializationIssue) => void): WorkflowSerializable;
23
+ /** Log paths and types, never payloads, provider bodies or credential values. */
24
+ export declare function workflowValue(value: unknown, context: SerializationContext): WorkflowSerializable;
25
+ /** Normalize only results authored by this SDK; leave Eve's execution and approval policy intact. */
26
+ export declare function workflowToolResult(value: unknown, context: {
27
+ readonly toolName: string;
28
+ readonly callId: string;
29
+ }): WorkflowSerializable;
@@ -0,0 +1,8 @@
1
+ import { fileURLToPath as __eveFileURLToPath } from "node:url";
2
+ import { dirname as __eveDirname } from "node:path";
3
+ import { createRequire as __eveCreateRequire } from "node:module";
4
+ const __filename = __eveFileURLToPath(import.meta.url);
5
+ __eveDirname(__filename);
6
+ __eveCreateRequire(import.meta.url);
7
+ import { n as workflowToolResult, r as workflowValue, t as toWorkflowSerializable } from "../../_chunks/workflow-serializable-BwttWNmY.mjs";
8
+ export { toWorkflowSerializable, workflowToolResult, workflowValue };
@@ -2,29 +2,7 @@
2
2
  * `segmentstream__attachments_discard`: drops an attachment at once. It can no longer be read or
3
3
  * promoted, and its file is deleted by the platform's maintenance.
4
4
  */
5
- declare const _default: import("eve/tools").ToolDefinition<Record<string, unknown>, {
6
- attachment: {
7
- promotion?: {} | undefined;
8
- expires_at?: string | undefined;
9
- state?: string | undefined;
10
- id: string;
11
- filename: string;
12
- content_type: string;
13
- size: number;
14
- sha256: string;
15
- };
16
- }> & {
17
- execute(input: Record<string, unknown>, ctx: import("eve/tools").ToolContext): Promise<{
18
- attachment: {
19
- promotion?: {} | undefined;
20
- expires_at?: string | undefined;
21
- state?: string | undefined;
22
- id: string;
23
- filename: string;
24
- content_type: string;
25
- size: number;
26
- sha256: string;
27
- };
28
- }>;
5
+ declare const _default: import("eve/tools").ToolDefinition<Record<string, unknown>, import("../lib/workflow-serializable.js").WorkflowSerializable> & {
6
+ execute(input: Record<string, unknown>, ctx: import("eve/tools").ToolContext): Promise<import("../lib/workflow-serializable.js").WorkflowSerializable>;
29
7
  };
30
8
  export default _default;
@@ -4,6 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
+ import { n as workflowToolResult } from "../../_chunks/workflow-serializable-BwttWNmY.mjs";
7
8
  import { ID_INPUT, attachmentForModel, attachmentOwner, stringArgument, toolAttachments } from "../lib/attachment-tools.mjs";
8
9
  import { defineTool } from "eve/tools";
9
10
  var attachments_discard_default = defineTool({
@@ -16,7 +17,7 @@ var attachments_discard_default = defineTool({
16
17
  sessionId: ctx.session.id
17
18
  });
18
19
  const attachment = await toolAttachments().discard(owner, stringArgument(input, "id"));
19
- return { attachment: attachmentForModel(attachment) };
20
+ return workflowToolResult({ attachment: attachmentForModel(attachment) }, ctx);
20
21
  }
21
22
  });
22
23
  export { attachments_discard_default as default };
@@ -2,29 +2,7 @@
2
2
  * `segmentstream__attachments_list`: the files the member sent in this chat and session that are
3
3
  * still available. Mounted with the extension, so it is there even with `defaultTools: false`.
4
4
  */
5
- declare const _default: import("eve/tools").ToolDefinition<Record<string, unknown>, {
6
- attachments: {
7
- promotion?: {} | undefined;
8
- expires_at?: string | undefined;
9
- state?: string | undefined;
10
- id: string;
11
- filename: string;
12
- content_type: string;
13
- size: number;
14
- sha256: string;
15
- }[];
16
- }> & {
17
- execute(input: Record<string, unknown>, ctx: import("eve/tools").ToolContext): Promise<{
18
- attachments: {
19
- promotion?: {} | undefined;
20
- expires_at?: string | undefined;
21
- state?: string | undefined;
22
- id: string;
23
- filename: string;
24
- content_type: string;
25
- size: number;
26
- sha256: string;
27
- }[];
28
- }>;
5
+ declare const _default: import("eve/tools").ToolDefinition<Record<string, unknown>, import("../lib/workflow-serializable.js").WorkflowSerializable> & {
6
+ execute(input: Record<string, unknown>, ctx: import("eve/tools").ToolContext): Promise<import("../lib/workflow-serializable.js").WorkflowSerializable>;
29
7
  };
30
8
  export default _default;
@@ -4,6 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
+ import { n as workflowToolResult } from "../../_chunks/workflow-serializable-BwttWNmY.mjs";
7
8
  import { attachmentForModel, attachmentOwner, toolAttachments } from "../lib/attachment-tools.mjs";
8
9
  import { defineTool } from "eve/tools";
9
10
  var attachments_list_default = defineTool({
@@ -19,7 +20,8 @@ var attachments_list_default = defineTool({
19
20
  principal: ctx.session.auth.current,
20
21
  sessionId: ctx.session.id
21
22
  });
22
- return { attachments: (await toolAttachments().list(owner)).map(attachmentForModel) };
23
+ const attachments = await toolAttachments().list(owner);
24
+ return workflowToolResult({ attachments: attachments.map(attachmentForModel) }, ctx);
23
25
  }
24
26
  });
25
27
  export { attachments_list_default as default };
@@ -4,33 +4,7 @@
4
4
  * hands the action the file already stored, so nothing is uploaded again, and a file whose SHA-256
5
5
  * was already promoted through the same action is not stored twice.
6
6
  */
7
- declare const _default: import("eve/tools").ToolDefinition<Record<string, unknown>, {
8
- attachment: {
9
- promotion?: {} | undefined;
10
- expires_at?: string | undefined;
11
- state?: string | undefined;
12
- id: string;
13
- filename: string;
14
- content_type: string;
15
- size: number;
16
- sha256: string;
17
- };
18
- deduplicated: boolean;
19
- result: unknown;
20
- }> & {
21
- execute(input: Record<string, unknown>, ctx: import("eve/tools").ToolContext): Promise<{
22
- attachment: {
23
- promotion?: {} | undefined;
24
- expires_at?: string | undefined;
25
- state?: string | undefined;
26
- id: string;
27
- filename: string;
28
- content_type: string;
29
- size: number;
30
- sha256: string;
31
- };
32
- deduplicated: boolean;
33
- result: unknown;
34
- }>;
7
+ declare const _default: import("eve/tools").ToolDefinition<Record<string, unknown>, import("../lib/workflow-serializable.js").WorkflowSerializable> & {
8
+ execute(input: Record<string, unknown>, ctx: import("eve/tools").ToolContext): Promise<import("../lib/workflow-serializable.js").WorkflowSerializable>;
35
9
  };
36
10
  export default _default;
@@ -6,6 +6,7 @@ __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { actionApproval } from "../lib/confirmations.mjs";
8
8
  import { ontologyTools, promotionTarget } from "../lib/ontology-tools.mjs";
9
+ import { n as workflowToolResult } from "../../_chunks/workflow-serializable-BwttWNmY.mjs";
9
10
  import { attachmentForModel, attachmentOwner, optionalObject, optionalString, stringArgument, toolAttachments } from "../lib/attachment-tools.mjs";
10
11
  import { defineTool } from "eve/tools";
11
12
  var attachments_promote_default = defineTool({
@@ -76,11 +77,11 @@ var attachments_promote_default = defineTool({
76
77
  ...field === void 0 ? {} : { field },
77
78
  ...recordId === void 0 ? {} : { recordId }
78
79
  });
79
- return {
80
+ return workflowToolResult({
80
81
  attachment: attachmentForModel(promoted.attachment),
81
82
  deduplicated: promoted.deduplicated,
82
83
  result: promoted.result
83
- };
84
+ }, ctx);
84
85
  }
85
86
  });
86
87
  export { attachments_promote_default as default };
@@ -4,6 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
+ import { n as workflowToolResult } from "../../_chunks/workflow-serializable-BwttWNmY.mjs";
7
8
  import { ID_INPUT, attachmentOwner, headerArgument, optionalString, pageInteger, readOutput, stringArgument, toolAttachments } from "../lib/attachment-tools.mjs";
8
9
  import { readStoredFile } from "../lib/stored-files.mjs";
9
10
  import { defineTool } from "eve/tools";
@@ -64,14 +65,14 @@ var attachments_read_default = defineTool({
64
65
  id: stringArgument(input, "id"),
65
66
  ...optionalString(input, "property") === void 0 ? {} : { property: optionalString(input, "property") }
66
67
  }, ctx.session.auth.current);
67
- return readOutput(attachment, bytes, {
68
+ return workflowToolResult(await readOutput(attachment, bytes, {
68
69
  sheet: optionalString(input, "sheet"),
69
70
  offset: pageInteger(input.offset, 0),
70
71
  ...input.limit === void 0 ? {} : { limit: pageInteger(input.limit, 100, 5e4) },
71
72
  character_offset: pageInteger(input.character_offset, 0),
72
73
  ...input.header_row === void 0 ? {} : { header_row: headerArgument(input.header_row) },
73
74
  ...input.date_order === "day_first" || input.date_order === "month_first" ? { date_order: input.date_order } : {}
74
- });
75
+ }), ctx);
75
76
  },
76
77
  toModelOutput(output) {
77
78
  if (output.kind !== "file") return {
@@ -1,8 +1,2 @@
1
- declare const _default: import("eve/tools").ToolDefinition<Record<string, unknown>, {
2
- readonly files: ReadonlyArray<import("../lib/telegram/attachments-send.js").SentFile>;
3
- } | {
4
- readonly error: string;
5
- readonly detail: string;
6
- readonly reference: string;
7
- }>;
1
+ declare const _default: import("eve/tools").ToolDefinition<Record<string, unknown>, import("../lib/workflow-serializable.js").WorkflowSerializable>;
8
2
  export default _default;
@@ -5,6 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import segmentstream from "../extension.mjs";
8
+ import { n as workflowToolResult } from "../../_chunks/workflow-serializable-BwttWNmY.mjs";
8
9
  import { sendAttachments, sendAttachmentsInput } from "../lib/telegram/attachments-send.mjs";
9
10
  import { defineTool } from "eve/tools";
10
11
  var attachments_send_default = defineTool({
@@ -47,13 +48,13 @@ var attachments_send_default = defineTool({
47
48
  additionalProperties: false
48
49
  },
49
50
  label: { start: () => "Send stored attachments to Telegram" },
50
- execute(input, ctx) {
51
- return sendAttachments({
51
+ async execute(input, ctx) {
52
+ return workflowToolResult(await sendAttachments({
52
53
  input: sendAttachmentsInput(input),
53
54
  principal: ctx.session.auth.current,
54
55
  sessionId: ctx.session.id,
55
56
  connection: segmentstream.config.channels.telegram?.connection
56
- });
57
+ }), ctx);
57
58
  }
58
59
  });
59
60
  export { attachments_send_default as default };
@@ -1,64 +1,4 @@
1
- declare const _default: import("eve/tools").ToolDefinition<Record<string, unknown>, {
2
- results: Record<string, string | number | null>[];
3
- pagination: {
4
- offset: number;
5
- limit: number;
6
- total_pages: number;
7
- next_offset: number | null;
8
- };
9
- attachment: {
10
- promotion?: {} | undefined;
11
- expires_at?: string | undefined;
12
- state?: string | undefined;
13
- id: string;
14
- filename: string;
15
- content_type: string;
16
- size: number;
17
- sha256: string;
18
- };
19
- sheet: string;
20
- sheets: readonly {
21
- readonly name: string;
22
- readonly total_rows: number;
23
- }[];
24
- header_row: number;
25
- columns: import("../lib/attachment-tables.js").Column[];
26
- warnings: string[];
27
- total_rows: number;
28
- matched_rows: number;
29
- total_results: number;
30
- decimal_note: string;
31
- }> & {
32
- execute(input: Record<string, unknown>, ctx: import("eve/tools").ToolContext): Promise<{
33
- results: Record<string, string | number | null>[];
34
- pagination: {
35
- offset: number;
36
- limit: number;
37
- total_pages: number;
38
- next_offset: number | null;
39
- };
40
- attachment: {
41
- promotion?: {} | undefined;
42
- expires_at?: string | undefined;
43
- state?: string | undefined;
44
- id: string;
45
- filename: string;
46
- content_type: string;
47
- size: number;
48
- sha256: string;
49
- };
50
- sheet: string;
51
- sheets: readonly {
52
- readonly name: string;
53
- readonly total_rows: number;
54
- }[];
55
- header_row: number;
56
- columns: import("../lib/attachment-tables.js").Column[];
57
- warnings: string[];
58
- total_rows: number;
59
- matched_rows: number;
60
- total_results: number;
61
- decimal_note: string;
62
- }>;
1
+ declare const _default: import("eve/tools").ToolDefinition<Record<string, unknown>, import("../lib/workflow-serializable.js").WorkflowSerializable> & {
2
+ execute(input: Record<string, unknown>, ctx: import("eve/tools").ToolContext): Promise<import("../lib/workflow-serializable.js").WorkflowSerializable>;
63
3
  };
64
4
  export default _default;
@@ -4,6 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
4
4
  const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
+ import { n as workflowToolResult } from "../../_chunks/workflow-serializable-BwttWNmY.mjs";
7
8
  import { readSheets, typedTable } from "../lib/attachment-tables.mjs";
8
9
  import { queryTable } from "../lib/attachment-query.mjs";
9
10
  import { ID_INPUT, attachmentForModel, attachmentOwner, boundedResultPage, headerArgument, optionalString, pageInteger, stringArgument, toolAttachments } from "../lib/attachment-tools.mjs";
@@ -183,7 +184,7 @@ var attachments_table_default = defineTool({
183
184
  resultOffset += boundedResultPage(queried.results, resultOffset, limit, envelope).length;
184
185
  totalPages++;
185
186
  }
186
- return {
187
+ return workflowToolResult({
187
188
  ...envelope,
188
189
  results,
189
190
  pagination: {
@@ -192,7 +193,7 @@ var attachments_table_default = defineTool({
192
193
  total_pages: totalPages,
193
194
  next_offset: offset + results.length < queried.results.length ? offset + results.length : null
194
195
  }
195
- };
196
+ }, ctx);
196
197
  }
197
198
  });
198
199
  export { attachments_table_default as default };
@@ -1,14 +1,4 @@
1
- declare const _default: import("eve/tools").ToolDefinition<Record<string, unknown>, {
2
- pendingQuestion: {
3
- address: string;
4
- taskId?: string | undefined;
5
- replyToMessageId?: string | undefined;
6
- id: string;
7
- question: string;
8
- task: string;
9
- memberId: string;
10
- chatId: string;
11
- messageThreadId: string;
12
- };
13
- }>;
1
+ declare const _default: import("eve/tools").ToolDefinition<Record<string, unknown>, string | number | boolean | import("../lib/workflow-serializable.js").WorkflowSerializable[] | {
2
+ [key: string]: import("../lib/workflow-serializable.js").WorkflowSerializable;
3
+ } | null>;
14
4
  export default _default;
@@ -5,6 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
5
5
  __eveDirname(__filename);
6
6
  __eveCreateRequire(import.meta.url);
7
7
  import { memberIdOf } from "../lib/telegram/principal.mjs";
8
+ import { n as workflowToolResult } from "../../_chunks/workflow-serializable-BwttWNmY.mjs";
8
9
  import { pendingQuestions, questionKey } from "../lib/questions.mjs";
9
10
  import { stringArgument } from "../lib/attachment-tools.mjs";
10
11
  import { defineTool } from "eve/tools";
@@ -46,7 +47,7 @@ var questions_ask_default = defineTool({
46
47
  ...all,
47
48
  [questionKey(question)]: question
48
49
  }));
49
- return { pendingQuestion: question };
50
+ return workflowToolResult({ pendingQuestion: question }, ctx);
50
51
  }
51
52
  });
52
53
  export { questions_ask_default as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@segmentstream/agent",
3
- "version": "0.8.4",
3
+ "version": "0.8.5",
4
4
  "description": "Mount a SegmentStream workspace's agent on eve: the ontology as tools, acting as the member who writes, and Telegram through the workspace's connection.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "SegmentStream",