deepline 0.1.277 → 0.1.278

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.
@@ -155,7 +155,7 @@ export const SDK_RELEASE = {
155
155
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
156
156
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
157
157
  // Operators use the checkout-local deepline-admin binary instead.
158
- version: '0.1.277',
158
+ version: '0.1.278',
159
159
  contracts: {
160
160
  api: {
161
161
  name: 'sdk-http-api',
@@ -1225,6 +1225,16 @@ export class PlayContextImpl {
1225
1225
  private readonly executionScope: RunExecutionScope;
1226
1226
  private logBuffer: string[] = [];
1227
1227
  private checkpoint: PlayCheckpoint;
1228
+ /**
1229
+ * Durable tool receipts are the replay/cache authority for the execution
1230
+ * paths the host supports. Keeping the same completed result in this
1231
+ * checkpoint retained every provider payload for the lifetime of a run and
1232
+ * copied it again while serializing the terminal. Paths without a matching
1233
+ * receipt API keep the legacy checkpoint cache so local/in-process replay
1234
+ * and bulk-only hosts' direct calls still work.
1235
+ */
1236
+ private readonly durableMappedToolResultsBackedByReceipts: boolean;
1237
+ private readonly durableDirectToolResultsBackedByReceipts: boolean;
1228
1238
  private steps: PlayStep[] = [];
1229
1239
  private explicitMapInvocationKeys = new Set<string>();
1230
1240
  /** The map step currently being built — substeps go here instead of top-level. */
@@ -1383,6 +1393,24 @@ export class PlayContextImpl {
1383
1393
  constructor(options: ContextOptions) {
1384
1394
  this.#options = options;
1385
1395
  this.checkpoint = options.checkpoint ?? emptyCheckpoint();
1396
+ this.durableMappedToolResultsBackedByReceipts = Boolean(
1397
+ (options.claimRuntimeStepReceipt || options.claimRuntimeStepReceipts) &&
1398
+ (options.getRuntimeStepReceipt || options.getRuntimeStepReceipts) &&
1399
+ (options.completeRuntimeStepReceipt ||
1400
+ options.completeRuntimeStepReceipts),
1401
+ );
1402
+ this.durableDirectToolResultsBackedByReceipts = Boolean(
1403
+ options.claimRuntimeStepReceipt &&
1404
+ options.getRuntimeStepReceipt &&
1405
+ options.completeRuntimeStepReceipt,
1406
+ );
1407
+ if (this.durableDirectToolResultsBackedByReceipts) {
1408
+ // A resumed durable runner may receive a legacy checkpoint containing
1409
+ // full tool results. Drop that redundant copy immediately and recover
1410
+ // through the receipt store below. Bulk-only receipt contexts retain the
1411
+ // checkpoint because direct tool calls cannot use the bulk claim path.
1412
+ this.checkpoint.completedToolBatches = {};
1413
+ }
1386
1414
  // The governance play id keys durable ctx receipts (durableCtxKey), the
1387
1415
  // cycle guard, and per-parent child-call counters. It must be the STABLE
1388
1416
  // play name — not the per-run workflow id — so receipts written by one
@@ -3077,16 +3105,25 @@ export class PlayContextImpl {
3077
3105
  private getCachedToolResult(
3078
3106
  toolId: string,
3079
3107
  rowCacheKey: string,
3108
+ path: 'mapped' | 'direct' = 'mapped',
3080
3109
  ): ToolBatchResult | undefined {
3110
+ if (
3111
+ path === 'direct'
3112
+ ? this.durableDirectToolResultsBackedByReceipts
3113
+ : this.durableMappedToolResultsBackedByReceipts
3114
+ ) {
3115
+ return undefined;
3116
+ }
3081
3117
  return this.checkpoint.completedToolBatches[toolId]?.[rowCacheKey];
3082
3118
  }
3083
3119
 
3084
3120
  private getCachedToolResultCandidate(
3085
3121
  toolId: string,
3086
3122
  rowCacheKeys: readonly string[],
3123
+ path: 'mapped' | 'direct' = 'mapped',
3087
3124
  ): { cacheKey: string; result: ToolBatchResult } | null {
3088
3125
  for (const rowCacheKey of rowCacheKeys) {
3089
- const cached = this.getCachedToolResult(toolId, rowCacheKey);
3126
+ const cached = this.getCachedToolResult(toolId, rowCacheKey, path);
3090
3127
  if (cached?.done) {
3091
3128
  return { cacheKey: rowCacheKey, result: cached };
3092
3129
  }
@@ -3098,7 +3135,15 @@ export class PlayContextImpl {
3098
3135
  toolId: string,
3099
3136
  rowCacheKey: string,
3100
3137
  result: unknown | null,
3138
+ path: 'mapped' | 'direct' = 'mapped',
3101
3139
  ): void {
3140
+ if (
3141
+ path === 'direct'
3142
+ ? this.durableDirectToolResultsBackedByReceipts
3143
+ : this.durableMappedToolResultsBackedByReceipts
3144
+ ) {
3145
+ return;
3146
+ }
3102
3147
  if (!this.checkpoint.completedToolBatches[toolId]) {
3103
3148
  this.checkpoint.completedToolBatches[toolId] = {};
3104
3149
  }
@@ -6349,7 +6394,11 @@ export class PlayContextImpl {
6349
6394
  ? null
6350
6395
  : toolCachePolicy.force
6351
6396
  ? null
6352
- : this.getCachedToolResultCandidate(toolId, checkpointCacheKeys);
6397
+ : this.getCachedToolResultCandidate(
6398
+ toolId,
6399
+ checkpointCacheKeys,
6400
+ 'direct',
6401
+ );
6353
6402
  if (cached) {
6354
6403
  this.log(`Calling tool: ${toolId} recovered from checkpoint`);
6355
6404
  return await this.wrapToolExecutionResult({
@@ -6429,13 +6478,7 @@ export class PlayContextImpl {
6429
6478
  }),
6430
6479
  });
6431
6480
  if (cacheableToolResult) {
6432
- this.checkpoint.completedToolBatches[toolId] = {
6433
- ...(this.checkpoint.completedToolBatches[toolId] ?? {}),
6434
- [directCacheKey]: {
6435
- done: true,
6436
- result: wrapped,
6437
- },
6438
- };
6481
+ this.cacheToolResult(toolId, directCacheKey, wrapped, 'direct');
6439
6482
  this.#options.onBatchComplete?.(this.checkpoint);
6440
6483
  }
6441
6484
  return wrapped;
@@ -7348,23 +7391,27 @@ export class PlayContextImpl {
7348
7391
  const toolSettlements = await Promise.allSettled(
7349
7392
  [...byTool.entries()].map(async ([toolId, requests]) => {
7350
7393
  this.log(`Executing tool batch ${toolId}: ${requests.length} calls`);
7351
- const liveStepResults = new Map<string, unknown>();
7394
+ const successfulLiveStepCallIds = new Set<string>();
7352
7395
 
7353
7396
  const recordToolStep = (stepRequests: ToolCallRequest[]): void => {
7354
7397
  if (stepRequests.length === 0) return;
7355
7398
  const stepResults: PlayStepRowResult[] = stepRequests.map((req) => {
7356
- const hasLiveResult = liveStepResults.has(req.callId);
7357
- const result = hasLiveResult
7358
- ? liveStepResults.get(req.callId)
7359
- : this.getCachedToolResult(toolId, req.cacheKey)?.result;
7399
+ const success =
7400
+ successfulLiveStepCallIds.has(req.callId) ||
7401
+ this.getCachedToolResult(toolId, req.cacheKey)?.result != null;
7360
7402
  return {
7361
7403
  rowId: req.rowId,
7362
- status: result != null ? 'completed' : 'failed',
7363
- success: result != null,
7364
- value: result,
7365
- error: result != null ? null : 'Tool call failed',
7404
+ status: success ? 'completed' : 'failed',
7405
+ success,
7406
+ error: success ? null : 'Tool call failed',
7366
7407
  };
7367
7408
  });
7409
+ // Step traces are lifecycle observability, not a second row/receipt
7410
+ // store. Keep only call ids long enough to record their bounded
7411
+ // status preview.
7412
+ for (const request of stepRequests) {
7413
+ successfulLiveStepCallIds.delete(request.callId);
7414
+ }
7368
7415
  const toolStep = {
7369
7416
  type: 'tool' as const,
7370
7417
  toolId,
@@ -7643,6 +7690,7 @@ export class PlayContextImpl {
7643
7690
  });
7644
7691
  this.cacheToolResult(toolId, request.cacheKey, wrapped);
7645
7692
  for (const waitingRequest of requestsForKey) {
7693
+ successfulLiveStepCallIds.add(waitingRequest.callId);
7646
7694
  const resolver = this.toolCallResolvers.get(
7647
7695
  waitingRequest.callId,
7648
7696
  );
@@ -7822,7 +7870,9 @@ export class PlayContextImpl {
7822
7870
  execution?.jobId,
7823
7871
  execution?.meta,
7824
7872
  );
7825
- liveStepResults.set(owner.callId, result);
7873
+ if (result != null) {
7874
+ successfulLiveStepCallIds.add(owner.callId);
7875
+ }
7826
7876
  resolveLiveFollowers(owner, result);
7827
7877
  recordToolStep([owner]);
7828
7878
  this.#options.onBatchComplete?.(this.checkpoint);
@@ -8110,7 +8160,9 @@ export class PlayContextImpl {
8110
8160
  index += 1
8111
8161
  ) {
8112
8162
  const request = entry.request.memberRequests[index]!;
8113
- liveStepResults.set(request.callId, resolvedResults[index]);
8163
+ if (resolvedResults[index] != null) {
8164
+ successfulLiveStepCallIds.add(request.callId);
8165
+ }
8114
8166
  resolveLiveFollowers(request, resolvedResults[index]);
8115
8167
  }
8116
8168
  }
@@ -8150,7 +8202,9 @@ export class PlayContextImpl {
8150
8202
  for (let index = 0; index < entries.length; index += 1) {
8151
8203
  const entry = entries[index]!;
8152
8204
  const result = resolvedResults[index];
8153
- liveStepResults.set(entry.request.callId, result);
8205
+ if (result != null) {
8206
+ successfulLiveStepCallIds.add(entry.request.callId);
8207
+ }
8154
8208
  resolveLiveFollowers(entry.request, result);
8155
8209
  entry.resolve(result);
8156
8210
  }
package/dist/cli/index.js CHANGED
@@ -718,7 +718,7 @@ var SDK_RELEASE = {
718
718
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
719
719
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
720
720
  // Operators use the checkout-local deepline-admin binary instead.
721
- version: "0.1.277",
721
+ version: "0.1.278",
722
722
  contracts: {
723
723
  api: {
724
724
  name: "sdk-http-api",
@@ -703,7 +703,7 @@ var SDK_RELEASE = {
703
703
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
704
704
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
705
705
  // Operators use the checkout-local deepline-admin binary instead.
706
- version: "0.1.277",
706
+ version: "0.1.278",
707
707
  contracts: {
708
708
  api: {
709
709
  name: "sdk-http-api",
package/dist/index.js CHANGED
@@ -438,7 +438,7 @@ var SDK_RELEASE = {
438
438
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
439
439
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
440
440
  // Operators use the checkout-local deepline-admin binary instead.
441
- version: "0.1.277",
441
+ version: "0.1.278",
442
442
  contracts: {
443
443
  api: {
444
444
  name: "sdk-http-api",
package/dist/index.mjs CHANGED
@@ -367,7 +367,7 @@ var SDK_RELEASE = {
367
367
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
368
368
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
369
369
  // Operators use the checkout-local deepline-admin binary instead.
370
- version: "0.1.277",
370
+ version: "0.1.278",
371
371
  contracts: {
372
372
  api: {
373
373
  name: "sdk-http-api",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.1.277",
3
+ "version": "0.1.278",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {