deepline 0.1.149 → 0.1.150

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.
@@ -84,6 +84,7 @@ import type { EnrichCompiledConfig } from './cli/enrich-play-compiler.js';
84
84
  const TERMINAL_PLAY_STATUSES = new Set(['completed', 'failed', 'cancelled']);
85
85
  const INCLUDE_TOOL_METADATA_HEADER = 'x-deepline-include-tool-metadata';
86
86
  const EXECUTE_RESPONSE_CONTRACT_HEADER = 'x-deepline-execute-response-contract';
87
+ const EXECUTE_RESPONSE_INTENT_HEADER = 'x-deepline-execute-response-intent';
87
88
  const V2_EXECUTE_RESPONSE_CONTRACT = 'v2-tool-response';
88
89
  const COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1_000];
89
90
  const REGISTER_PLAY_ARTIFACTS_COMPILE_CONCURRENCY = 3;
@@ -163,6 +164,7 @@ function chunkRegisterPlayArtifacts<T>(artifacts: T[]): T[][] {
163
164
 
164
165
  type ExecuteToolRawOptions = {
165
166
  includeToolMetadata?: boolean;
167
+ responseIntent?: 'raw' | 'row_artifact';
166
168
  };
167
169
 
168
170
  /**
@@ -1156,6 +1158,9 @@ export class DeeplineClient {
1156
1158
  ...(options?.includeToolMetadata
1157
1159
  ? { [INCLUDE_TOOL_METADATA_HEADER]: 'true' }
1158
1160
  : {}),
1161
+ ...(options?.responseIntent
1162
+ ? { [EXECUTE_RESPONSE_INTENT_HEADER]: options.responseIntent }
1163
+ : {}),
1159
1164
  };
1160
1165
  return this.http.post<ToolExecution<TData, TMeta>>(
1161
1166
  `/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
@@ -102,10 +102,10 @@ export const SDK_RELEASE = {
102
102
  // the SDK enrich generator's one-second stale policy.
103
103
  // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
104
104
  // 0.1.111 ships dataset-native tool list getters and result row datasets.
105
- version: '0.1.149',
105
+ version: '0.1.150',
106
106
  apiContract: '2026-06-dataset-handle-results-hard-cutover',
107
107
  supportPolicy: {
108
- latest: '0.1.149',
108
+ latest: '0.1.150',
109
109
  minimumSupported: '0.1.53',
110
110
  deprecatedBelow: '0.1.53',
111
111
  commandMinimumSupported: [
@@ -23,7 +23,13 @@
23
23
  *
24
24
  * @module
25
25
  */
26
- import { mkdirSync, writeFileSync } from 'node:fs';
26
+ import {
27
+ closeSync,
28
+ mkdirSync,
29
+ openSync,
30
+ writeFileSync,
31
+ writeSync,
32
+ } from 'node:fs';
27
33
  import { homedir } from 'node:os';
28
34
  import { dirname, join } from 'node:path';
29
35
 
@@ -54,6 +60,22 @@ export type ListConversionResult = {
54
60
  sourcePath: string | null;
55
61
  };
56
62
 
63
+ export type RowOutputProjection = {
64
+ rows: Array<Record<string, unknown>>;
65
+ rowCount: number;
66
+ columns: string[];
67
+ previewRows: Array<Record<string, unknown>>;
68
+ strategy: ListConversionResult['strategy'];
69
+ sourcePath: string | null;
70
+ };
71
+
72
+ export type CsvOutputArtifact = {
73
+ path: string;
74
+ rowCount: number;
75
+ columns: string[];
76
+ preview: string;
77
+ };
78
+
57
79
  type Scalar = string | number | boolean | null;
58
80
 
59
81
  function isPlainObject(value: unknown): value is Record<string, unknown> {
@@ -109,6 +131,20 @@ function normalizeRows(value: unknown): Array<Record<string, unknown>> | null {
109
131
  });
110
132
  }
111
133
 
134
+ function columnsForRows(rows: readonly Record<string, unknown>[]): string[] {
135
+ const seen = new Set<string>();
136
+ const columns: string[] = [];
137
+ for (const row of rows) {
138
+ for (const key of Object.keys(row)) {
139
+ if (!seen.has(key)) {
140
+ seen.add(key);
141
+ columns.push(key);
142
+ }
143
+ }
144
+ }
145
+ return columns;
146
+ }
147
+
112
148
  /**
113
149
  * Generate candidate root objects to search for lists.
114
150
  * Tries: raw payload → V2 toolResponse.raw → legacy payload.output.body → legacy payload.result → legacy payload.result.data.
@@ -271,6 +307,19 @@ export function tryConvertToList(
271
307
  return null;
272
308
  }
273
309
 
310
+ export function projectRowOutput(
311
+ conversion: ListConversionResult,
312
+ ): RowOutputProjection {
313
+ return {
314
+ rows: conversion.rows,
315
+ rowCount: conversion.rows.length,
316
+ columns: columnsForRows(conversion.rows),
317
+ previewRows: conversion.rows.slice(0, 5),
318
+ strategy: conversion.strategy,
319
+ sourcePath: conversion.sourcePath,
320
+ };
321
+ }
322
+
274
323
  /** Ensure the shared output directory exists. Returns its path. */
275
324
  function ensureOutputDir(): string {
276
325
  const outputDir = join(homedir(), '.local', 'share', 'deepline', 'data');
@@ -330,21 +379,12 @@ export function writeCsvOutputFile(
330
379
  rows: Array<Record<string, unknown>>,
331
380
  stem: string,
332
381
  options?: { outPath?: string },
333
- ): { path: string; rowCount: number; columns: string[]; preview: string } {
382
+ ): CsvOutputArtifact {
334
383
  const outputPath = options?.outPath
335
384
  ? options.outPath
336
385
  : join(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
337
386
  mkdirSync(dirname(outputPath), { recursive: true });
338
- const seen = new Set<string>();
339
- const columns: string[] = [];
340
- for (const row of rows) {
341
- for (const key of Object.keys(row)) {
342
- if (!seen.has(key)) {
343
- seen.add(key);
344
- columns.push(key);
345
- }
346
- }
347
- }
387
+ const columns = columnsForRows(rows);
348
388
 
349
389
  const escapeCell = (value: unknown): string => {
350
390
  const normalized =
@@ -361,12 +401,18 @@ export function writeCsvOutputFile(
361
401
  return normalized;
362
402
  };
363
403
 
364
- const lines: string[] = [];
365
- lines.push(columns.map(escapeCell).join(','));
366
- for (const row of rows) {
367
- lines.push(columns.map((column) => escapeCell(row[column])).join(','));
404
+ const fd = openSync(outputPath, 'w');
405
+ try {
406
+ writeSync(fd, `${columns.map(escapeCell).join(',')}\n`);
407
+ for (const row of rows) {
408
+ writeSync(
409
+ fd,
410
+ `${columns.map((column) => escapeCell(row[column])).join(',')}\n`,
411
+ );
412
+ }
413
+ } finally {
414
+ closeSync(fd);
368
415
  }
369
- writeFileSync(outputPath, `${lines.join('\n')}\n`, 'utf-8');
370
416
 
371
417
  const previewRows = rows.slice(0, 5);
372
418
  const previewColumns = columns.slice(0, 5);
@@ -1,6 +1,6 @@
1
1
  import type { EmailStatusExtractorConfig } from './email-status';
2
2
  import type { DeeplineGetterValueMap } from './extractor-targets';
3
- import type { PlayDataset } from '../plays/dataset';
3
+ import type { PlayDataset, SerializedPlayDataset } from '../plays/dataset';
4
4
 
5
5
  export type ToolResultExecutionMetadata = {
6
6
  idempotent: true;
@@ -73,10 +73,22 @@ export type ToolResultEnvelope<
73
73
  export type SerializedToolExecuteResult = {
74
74
  __kind: 'deepline.tool_execute_result.v1';
75
75
  status: string;
76
+ job_id?: string;
77
+ /** Deepline-owned execution/result metadata. */
78
+ meta?: Record<string, unknown>;
76
79
  toolResponse: {
80
+ /**
81
+ * Raw provider/tool data with declared row-list payloads clipped to bounded
82
+ * previews. Use list getters for row-shaped data.
83
+ */
77
84
  raw: unknown;
78
85
  meta?: Record<string, unknown>;
79
86
  };
87
+ listDatasets?: Record<string, SerializedPlayDataset<Record<string, unknown>>>;
88
+ /** Full declared list rows used to rehydrate list Dataset Handles. */
89
+ listRows?: Record<string, Array<Record<string, unknown>>>;
90
+ /** Computed scalar/object getters preserved before raw list previews are clipped. */
91
+ targetValues?: Record<string, ToolResultTargetMetadata>;
80
92
  metadata: ToolResultMetadataInput;
81
93
  execution: ToolResultExecutionMetadata;
82
94
  };
@@ -142,9 +154,10 @@ export type ToolExecuteResultAccessors<
142
154
  * getters live under `extractedValues.<name>.get()`, and list getters live
143
155
  * under `extractedLists.<name>.get()`.
144
156
  *
145
- * Use extractors first when a tool contract exposes them. Drop to
146
- * `toolResponse.raw` when you need provider-specific fields or when debugging
147
- * from persisted run rows.
157
+ * Use extractors first when a tool contract exposes them. Use list getters for
158
+ * row-shaped data. Drop to `toolResponse.raw` only for provider-specific scalar
159
+ * fields or bounded debugging context; persisted rows may clip declared lists to
160
+ * previews.
148
161
  *
149
162
  * @sdkReference runtime 200
150
163
  */
@@ -38,12 +38,21 @@ import type {
38
38
  ToolResultTargetAccessor,
39
39
  ToolResultTargetMetadata,
40
40
  } from './tool-result-types';
41
- import { createPlayDataset, type PlayDataset } from '../plays/dataset';
41
+ import {
42
+ createDeferredPlayDataset,
43
+ createPlayDataset,
44
+ isSerializedPlayDataset,
45
+ trimSerializedPlayDatasetPreview,
46
+ type PlayDataset,
47
+ type SerializedPlayDataset,
48
+ } from '../plays/dataset';
42
49
  import { normalizeTableNamespace, sha256Hex } from '../plays/row-identity';
43
50
 
44
51
  type PathSegment = string | number | '*';
45
52
 
46
53
  const SERIALIZED_TOOL_EXECUTE_RESULT_KIND = 'deepline.tool_execute_result.v1';
54
+ const SERIALIZED_TOOL_RESULT_LIST_PREVIEW_LIMIT = 5;
55
+ const SERIALIZED_TOOL_LIST_ROWS = Symbol('deepline.serialized_tool_list_rows');
47
56
 
48
57
  const TARGET_FALLBACK_KEYS: Record<string, readonly RegExp[]> = {
49
58
  email: [/^email$/i, /^address$/i, /email/i],
@@ -949,6 +958,23 @@ function buildExtractedAccessors(
949
958
  );
950
959
  }
951
960
 
961
+ function serializedTargetValuesFromResult(
962
+ value: ToolExecuteResult,
963
+ ): Record<string, ToolResultTargetMetadata> | undefined {
964
+ const targets = value._metadata.targets;
965
+ return Object.keys(targets).length > 0 ? targets : undefined;
966
+ }
967
+
968
+ function applySerializedTargetValues(
969
+ result: ToolExecuteResult,
970
+ targetValues: Record<string, ToolResultTargetMetadata> | undefined,
971
+ ): ToolExecuteResult {
972
+ if (!targetValues || Object.keys(targetValues).length === 0) return result;
973
+ result._metadata.targets = targetValues;
974
+ result.extractedValues = buildExtractedAccessors(targetValues);
975
+ return result;
976
+ }
977
+
952
978
  function buildListAccessors(
953
979
  resolved: Record<string, { path: string; rows: Record<string, unknown>[] }>,
954
980
  lists: Record<string, ToolResultListMetadata>,
@@ -1142,13 +1168,286 @@ export function readList(
1142
1168
  ): PlayDataset<Record<string, unknown>> | Record<string, unknown>[] {
1143
1169
  if (selector) {
1144
1170
  const paths = Array.isArray(selector) ? selector : [selector];
1171
+ const declaredList = findDeclaredListAccessor(result, paths);
1145
1172
  const found = findFirstTargetByPath(resultRootOf(result), paths)?.value;
1146
1173
  const rows = normalizeRows(found);
1147
- if (rows) return rows;
1174
+ if (rows) {
1175
+ if (
1176
+ declaredList &&
1177
+ typeof declaredList.count === 'number' &&
1178
+ declaredList.count > rows.length
1179
+ ) {
1180
+ return declaredList.get();
1181
+ }
1182
+ return rows;
1183
+ }
1184
+ if (declaredList) return declaredList.get();
1148
1185
  }
1149
1186
  return Object.values(result.extractedLists)[0]?.get() ?? [];
1150
1187
  }
1151
1188
 
1189
+ function normalizeListPathForMatch(path: string): string {
1190
+ return path.replace(/\[(?:\*|\d+)\]$/g, '');
1191
+ }
1192
+
1193
+ function findDeclaredListAccessor(
1194
+ result: ToolExecuteResult,
1195
+ paths: readonly string[],
1196
+ ): ToolResultListAccessor | undefined {
1197
+ const candidates = new Set(
1198
+ paths.flatMap((path) =>
1199
+ candidateResultPaths(path).flatMap((candidate) => [
1200
+ candidate,
1201
+ normalizeListPathForMatch(candidate),
1202
+ ]),
1203
+ ),
1204
+ );
1205
+ return Object.values(result.extractedLists).find((list) =>
1206
+ candidates.has(normalizeListPathForMatch(list.path)),
1207
+ );
1208
+ }
1209
+
1210
+ function replaceAtPath(
1211
+ root: unknown,
1212
+ path: string,
1213
+ replacement: unknown,
1214
+ ): unknown {
1215
+ const segments = parsePath(path);
1216
+ if (segments.length === 0 || segments.includes('*')) return root;
1217
+ const replace = (current: unknown, index: number): unknown => {
1218
+ if (index >= segments.length) return replacement;
1219
+ const segment = segments[index]!;
1220
+ if (typeof segment === 'number') {
1221
+ if (!Array.isArray(current)) return current;
1222
+ const copy = [...current];
1223
+ copy[segment] = replace(copy[segment], index + 1);
1224
+ return copy;
1225
+ }
1226
+ if (!isRecord(current)) return current;
1227
+ return {
1228
+ ...current,
1229
+ [segment]: replace(current[segment], index + 1),
1230
+ };
1231
+ };
1232
+ return replace(root, 0);
1233
+ }
1234
+
1235
+ function serializedListDatasetsFromResult(
1236
+ value: ToolExecuteResult,
1237
+ ): Record<string, SerializedPlayDataset<Record<string, unknown>>> | undefined {
1238
+ const entries = Object.entries(value.extractedLists).flatMap(
1239
+ ([name, accessor]) => {
1240
+ const serialized = accessor.get().toJSON();
1241
+ if (!isSerializedPlayDataset<Record<string, unknown>>(serialized)) {
1242
+ return [];
1243
+ }
1244
+ return [
1245
+ [
1246
+ name,
1247
+ trimSerializedPlayDatasetPreview(
1248
+ serialized,
1249
+ SERIALIZED_TOOL_RESULT_LIST_PREVIEW_LIMIT,
1250
+ ),
1251
+ ],
1252
+ ] as const;
1253
+ },
1254
+ );
1255
+ return entries.length > 0 ? Object.fromEntries(entries) : undefined;
1256
+ }
1257
+
1258
+ function serializedListRowsFromRaw(input: {
1259
+ raw: unknown;
1260
+ metadata: ToolResultMetadataInput;
1261
+ }): Record<string, Array<Record<string, unknown>>> | undefined {
1262
+ const resolved = resolveListRows(
1263
+ { toolResponse: { raw: input.raw } },
1264
+ input.metadata.listExtractorPaths,
1265
+ );
1266
+ const entries = Object.entries(resolved).map(([name, list]) => [
1267
+ name,
1268
+ list.rows,
1269
+ ]);
1270
+ return entries.length > 0 ? Object.fromEntries(entries) : undefined;
1271
+ }
1272
+
1273
+ function preservedSerializedListRows(
1274
+ value: ToolExecuteResult,
1275
+ ): Record<string, Array<Record<string, unknown>>> | undefined {
1276
+ const rows = (value as ToolExecuteResult & {
1277
+ [SERIALIZED_TOOL_LIST_ROWS]?:
1278
+ | Record<string, Array<Record<string, unknown>>>
1279
+ | undefined;
1280
+ })[SERIALIZED_TOOL_LIST_ROWS];
1281
+ return rows && Object.keys(rows).length > 0 ? rows : undefined;
1282
+ }
1283
+
1284
+ function serializedListRowsFromResult(input: {
1285
+ value: ToolExecuteResult;
1286
+ metadata: ToolResultMetadataInput;
1287
+ listDatasets:
1288
+ | Record<string, SerializedPlayDataset<Record<string, unknown>>>
1289
+ | undefined;
1290
+ }): Record<string, Array<Record<string, unknown>>> | undefined {
1291
+ const preserved = preservedSerializedListRows(input.value);
1292
+ const rawRows = serializedListRowsFromRaw({
1293
+ raw: input.value.toolResponse.raw,
1294
+ metadata: input.metadata,
1295
+ });
1296
+ const names = new Set([
1297
+ ...Object.keys(input.listDatasets ?? {}),
1298
+ ...Object.keys(preserved ?? {}),
1299
+ ...Object.keys(rawRows ?? {}),
1300
+ ]);
1301
+ const entries = [...names].flatMap((name) => {
1302
+ const dataset = input.listDatasets?.[name];
1303
+ const preservedRows = preserved?.[name];
1304
+ if (
1305
+ preservedRows &&
1306
+ (!dataset || preservedRows.length >= dataset.count)
1307
+ ) {
1308
+ return [[name, preservedRows]] as const;
1309
+ }
1310
+ const rows = rawRows?.[name];
1311
+ if (rows && (!dataset || rows.length >= dataset.count)) {
1312
+ return [[name, rows]] as const;
1313
+ }
1314
+ return [];
1315
+ });
1316
+ return entries.length > 0 ? Object.fromEntries(entries) : undefined;
1317
+ }
1318
+
1319
+ function serializedRawWithListPreviews(input: {
1320
+ raw: unknown;
1321
+ metadata: ToolResultMetadataInput;
1322
+ listDatasets:
1323
+ | Record<string, SerializedPlayDataset<Record<string, unknown>>>
1324
+ | undefined;
1325
+ }): unknown {
1326
+ if (!input.listDatasets) return input.raw;
1327
+ let root: unknown = { toolResponse: { raw: input.raw } };
1328
+ const datasetsBySource = new Map(
1329
+ Object.values(input.listDatasets).flatMap((dataset) =>
1330
+ dataset.sourceLabel ? [[dataset.sourceLabel, dataset]] : [],
1331
+ ),
1332
+ );
1333
+ for (const rawPath of input.metadata.listExtractorPaths ?? []) {
1334
+ const candidates = [...candidateResultPaths(rawPath)].filter(
1335
+ (candidate, index, all) => all.indexOf(candidate) === index,
1336
+ );
1337
+ const dataset =
1338
+ candidates
1339
+ .map((candidate) => datasetsBySource.get(candidate))
1340
+ .find(Boolean) ?? Object.values(input.listDatasets)[0];
1341
+ if (!dataset) continue;
1342
+ for (const candidate of candidates) {
1343
+ if (!Array.isArray(getAtPath(root, candidate))) continue;
1344
+ root = replaceAtPath(root, candidate, dataset.preview);
1345
+ break;
1346
+ }
1347
+ }
1348
+ return isRecord(root) &&
1349
+ isRecord(root.toolResponse) &&
1350
+ Object.prototype.hasOwnProperty.call(root.toolResponse, 'raw')
1351
+ ? root.toolResponse.raw
1352
+ : input.raw;
1353
+ }
1354
+
1355
+ function createDatasetFromSerializedToolList(
1356
+ serialized: SerializedPlayDataset<Record<string, unknown>>,
1357
+ rows?: Array<Record<string, unknown>>,
1358
+ ): PlayDataset<Record<string, unknown>> {
1359
+ const preview = serialized.preview;
1360
+ const sourceRows = rows ?? preview;
1361
+ const isPartialPreview =
1362
+ rows === undefined && serialized.count > preview.length;
1363
+ const partialPreviewError = (): Error =>
1364
+ new Error(
1365
+ `Serialized tool list ${serialized.datasetId} only carries ${preview.length} preview row(s) for ${serialized.count} total row(s). ` +
1366
+ 'Return the Dataset Handle from play code or export rows through runs export for full data.',
1367
+ );
1368
+ const collectPreview = (limit?: number): Record<string, unknown>[] => {
1369
+ if (limit === undefined && isPartialPreview) {
1370
+ throw partialPreviewError();
1371
+ }
1372
+ const requested =
1373
+ limit === undefined ? sourceRows.length : Math.max(0, Math.floor(limit));
1374
+ if (requested > preview.length && isPartialPreview) {
1375
+ throw partialPreviewError();
1376
+ }
1377
+ return sourceRows.slice(0, requested);
1378
+ };
1379
+ return createDeferredPlayDataset({
1380
+ datasetKind: serialized.datasetKind,
1381
+ datasetId: serialized.datasetId,
1382
+ count: serialized.count,
1383
+ backing: serialized.backing,
1384
+ previewRows: preview,
1385
+ sourceLabel: serialized.sourceLabel ?? null,
1386
+ tableNamespace: serialized.tableNamespace ?? null,
1387
+ workProgress: serialized._metadata?.workProgress,
1388
+ resolvers: {
1389
+ count: async () => serialized.count,
1390
+ peek: async (limit) => collectPreview(limit),
1391
+ materialize: async (limit) => collectPreview(limit),
1392
+ iterate: () =>
1393
+ ({
1394
+ async *[Symbol.asyncIterator]() {
1395
+ if (isPartialPreview) {
1396
+ throw partialPreviewError();
1397
+ }
1398
+ yield* sourceRows;
1399
+ },
1400
+ }) as AsyncIterable<Record<string, unknown>>,
1401
+ },
1402
+ });
1403
+ }
1404
+
1405
+ function applySerializedListDatasets(
1406
+ result: ToolExecuteResult,
1407
+ listDatasets:
1408
+ | Record<string, SerializedPlayDataset<Record<string, unknown>>>
1409
+ | undefined,
1410
+ listRows: Record<string, Array<Record<string, unknown>>> | undefined,
1411
+ ): ToolExecuteResult {
1412
+ if (!listDatasets) return result;
1413
+ if (listRows && Object.keys(listRows).length > 0) {
1414
+ Object.defineProperty(result, SERIALIZED_TOOL_LIST_ROWS, {
1415
+ value: listRows,
1416
+ enumerable: false,
1417
+ configurable: false,
1418
+ writable: false,
1419
+ });
1420
+ }
1421
+ for (const [name, serialized] of Object.entries(listDatasets)) {
1422
+ if (!isSerializedPlayDataset<Record<string, unknown>>(serialized)) {
1423
+ continue;
1424
+ }
1425
+ const dataset = createDatasetFromSerializedToolList(
1426
+ serialized,
1427
+ listRows?.[name],
1428
+ );
1429
+ const existingMetadata = result._metadata.lists[name];
1430
+ result._metadata.lists[name] = {
1431
+ path: serialized.sourceLabel ?? existingMetadata?.path ?? name,
1432
+ count: serialized.count,
1433
+ keys: existingMetadata?.keys ?? {},
1434
+ };
1435
+ const accessor = {
1436
+ path: result._metadata.lists[name].path,
1437
+ count: serialized.count,
1438
+ keys: result._metadata.lists[name].keys,
1439
+ } as ToolResultListAccessor;
1440
+ Object.defineProperty(accessor, 'get', {
1441
+ value() {
1442
+ return dataset;
1443
+ },
1444
+ enumerable: false,
1445
+ });
1446
+ result.extractedLists[name] = accessor;
1447
+ }
1448
+ return result;
1449
+ }
1450
+
1152
1451
  function metadataInputFromToolExecuteResult(
1153
1452
  value: ToolExecuteResult,
1154
1453
  ): ToolResultMetadataInput {
@@ -1177,14 +1476,31 @@ function metadataInputFromToolExecuteResult(
1177
1476
  export function serializeToolExecuteResult(
1178
1477
  value: ToolExecuteResult,
1179
1478
  ): SerializedToolExecuteResult {
1479
+ const metadata = metadataInputFromToolExecuteResult(value);
1480
+ const listDatasets = serializedListDatasetsFromResult(value);
1481
+ const listRows = serializedListRowsFromResult({
1482
+ value,
1483
+ listDatasets,
1484
+ metadata,
1485
+ });
1486
+ const targetValues = serializedTargetValuesFromResult(value);
1180
1487
  return {
1181
1488
  __kind: SERIALIZED_TOOL_EXECUTE_RESULT_KIND,
1182
1489
  status: value.status,
1490
+ ...(typeof value.job_id === 'string' ? { job_id: value.job_id } : {}),
1491
+ ...(isRecord(value.meta) ? { meta: value.meta } : {}),
1183
1492
  toolResponse: {
1184
- raw: value.toolResponse.raw,
1493
+ raw: serializedRawWithListPreviews({
1494
+ raw: value.toolResponse.raw,
1495
+ metadata,
1496
+ listDatasets,
1497
+ }),
1185
1498
  ...(value.toolResponse.meta ? { meta: value.toolResponse.meta } : {}),
1186
1499
  },
1187
- metadata: metadataInputFromToolExecuteResult(value),
1500
+ ...(listDatasets ? { listDatasets } : {}),
1501
+ ...(listRows ? { listRows } : {}),
1502
+ ...(targetValues ? { targetValues } : {}),
1503
+ metadata,
1188
1504
  execution: value._metadata.execution,
1189
1505
  };
1190
1506
  }
@@ -1205,33 +1521,34 @@ export function isSerializedToolExecuteResult(
1205
1521
  export function deserializeToolExecuteResult(
1206
1522
  value: SerializedToolExecuteResult,
1207
1523
  ): ToolExecuteResult {
1208
- return createToolExecuteResult({
1209
- status: value.status,
1210
- result: {
1211
- data: value.toolResponse.raw,
1212
- ...(value.toolResponse.meta ? { meta: value.toolResponse.meta } : {}),
1213
- },
1214
- metadata: value.metadata,
1215
- execution: value.execution,
1216
- });
1524
+ return applySerializedListDatasets(
1525
+ applySerializedTargetValues(
1526
+ createToolExecuteResult({
1527
+ status: value.status,
1528
+ jobId: value.job_id,
1529
+ result: {
1530
+ data: value.toolResponse.raw,
1531
+ ...(value.toolResponse.meta
1532
+ ? { meta: value.toolResponse.meta }
1533
+ : {}),
1534
+ },
1535
+ metadata: value.metadata,
1536
+ execution: value.execution,
1537
+ meta: value.meta,
1538
+ }),
1539
+ value.targetValues,
1540
+ ),
1541
+ value.listDatasets,
1542
+ value.listRows,
1543
+ );
1217
1544
  }
1218
1545
 
1219
1546
  export function cloneToolExecuteResultWithExecution<TResult>(
1220
1547
  value: ToolExecuteResult<TResult>,
1221
1548
  execution: ToolResultExecutionMetadata,
1222
1549
  ): ToolExecuteResult<TResult> {
1223
- return createToolExecuteResult<TResult>({
1224
- status: value.status,
1225
- jobId:
1226
- typeof (value as unknown as { job_id?: unknown }).job_id === 'string'
1227
- ? (value as unknown as { job_id: string }).job_id
1228
- : undefined,
1229
- result: {
1230
- data: value.toolResponse.raw,
1231
- ...(value.toolResponse.meta ? { meta: value.toolResponse.meta } : {}),
1232
- } as TResult,
1233
- metadata: metadataInputFromToolExecuteResult(value),
1550
+ return deserializeToolExecuteResult({
1551
+ ...serializeToolExecuteResult(value),
1234
1552
  execution,
1235
- meta: isRecord(value.meta) ? value.meta : undefined,
1236
- });
1553
+ }) as ToolExecuteResult<TResult>;
1237
1554
  }