deepline 0.3.151 → 0.3.152

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.
@@ -200,7 +200,7 @@ export const SDK_RELEASE = {
200
200
  // getters keep their established compatibility behavior.
201
201
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
202
202
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
203
- version: '0.3.151',
203
+ version: '0.3.152',
204
204
  updateSummary:
205
205
  'Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.',
206
206
  packageCapabilities: {
@@ -40,7 +40,8 @@ export type DlqPathAction =
40
40
  | 'retry'
41
41
  | 'quarantine'
42
42
  | 'release'
43
- | 'settle';
43
+ | 'settle'
44
+ | 'cancel';
44
45
 
45
46
  export type DlqLookupIndex = {
46
47
  readonly table: string;
@@ -302,6 +303,7 @@ export function normalizeQueueItemAction(
302
303
  quarantine: 'quarantine',
303
304
  release: 'cancel',
304
305
  settle: 'resume',
306
+ cancel: 'cancel',
305
307
  };
306
308
  return action in aliases
307
309
  ? aliases[action as QueueItemLegacyAction]
@@ -343,6 +345,17 @@ export type QueueItemFailedTimeRange = {
343
345
  readonly snapshotAt: string;
344
346
  };
345
347
 
348
+ /** Server attestation for a bounded source-indexed creation-time plan. */
349
+ export type QueueItemCreatedTimeRange = {
350
+ readonly kind: 'created-time-range';
351
+ readonly after: string | null;
352
+ readonly before: string;
353
+ readonly index: string;
354
+ readonly indexed: true;
355
+ /** Stable across every page in the same cursor-bound plan. */
356
+ readonly snapshotAt: string;
357
+ };
358
+
346
359
  export type QueueItemList = {
347
360
  readonly contractVersion: typeof QUEUE_ITEM_CONTROL_CONTRACT_VERSION;
348
361
  readonly queueId: string;
@@ -354,6 +367,8 @@ export type QueueItemList = {
354
367
  readonly cursor: string | null;
355
368
  /** Present only for a successfully measured indexed failure-time range. */
356
369
  readonly failedTimeRange?: QueueItemFailedTimeRange;
370
+ /** Present only for a successfully measured indexed creation-time range. */
371
+ readonly createdTimeRange?: QueueItemCreatedTimeRange;
357
372
  readonly unavailable?: QueueItemUnavailable;
358
373
  };
359
374
 
@@ -470,6 +485,11 @@ export type QueueItemConnector = {
470
485
  context: QueueItemConnectorContext,
471
486
  range: { after?: string; before: string },
472
487
  ) => Promise<QueueItemList>;
488
+ /** Indexed creation-time listing for owner-declared retirement plans. */
489
+ readonly listCreatedInRange?: (
490
+ context: QueueItemConnectorContext,
491
+ range: { after?: string; before: string },
492
+ ) => Promise<QueueItemList>;
473
493
  readonly get: (
474
494
  context: QueueItemConnectorContext,
475
495
  itemId: string,
@@ -810,6 +830,15 @@ const DLQ_PATH_METADATA: Readonly<Record<string, DlqPathMetadata>> = {
810
830
  bounded: true,
811
831
  },
812
832
  transitions: [
833
+ {
834
+ action: 'cancel',
835
+ fromStates: ['ready'],
836
+ toState: 'cancelled',
837
+ enabled: true,
838
+ requiresApproval: true,
839
+ reason:
840
+ 'Cancellation is owner-controlled and revision-fenced; retirement can be recorded only after the job reaches this terminal state.',
841
+ },
813
842
  {
814
843
  action: 'retry',
815
844
  fromStates: ['failed'],
@@ -215,6 +215,7 @@ import {
215
215
  buildDurableToolPayloadProviderIdempotencyKey,
216
216
  buildProviderOperationIdempotencyKey,
217
217
  buildDurableToolReceiptPrefix,
218
+ scopeToolReceiptToInvocation,
218
219
  resolveDurableCallCachePolicy,
219
220
  } from './durable-call-cache';
220
221
  import {
@@ -12531,6 +12532,27 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
12531
12532
  (await this.resolveToolAuthScopeDigest(toolId))?.trim() ?? null;
12532
12533
  const eventWaitHandler =
12533
12534
  (await this.#options.getIntegrationEventWaitHandler?.(toolId)) ?? null;
12535
+ const invocationScoped =
12536
+ !eventWaitHandler &&
12537
+ (await this.#options.getToolIdempotencyScope?.(toolId)) === 'invocation';
12538
+ const invocationIdentity = `${this.currentRunId}:${logicalCallId}`;
12539
+ const scopeReceipt = (receiptKey: string): string =>
12540
+ invocationScoped
12541
+ ? scopeToolReceiptToInvocation({
12542
+ orgId: this.#options.orgId,
12543
+ toolId,
12544
+ receiptKey,
12545
+ invocationIdentity,
12546
+ })
12547
+ : receiptKey;
12548
+ const scopeOperation = (operationKey: string): string =>
12549
+ invocationScoped
12550
+ ? buildProviderOperationIdempotencyKey({
12551
+ operationKey,
12552
+ force: true,
12553
+ fallbackAttemptId: invocationIdentity,
12554
+ })
12555
+ : operationKey;
12534
12556
  const explicitForce =
12535
12557
  options?.force === true ||
12536
12558
  toolExecutionOverrides.getStore()?.force === true;
@@ -12545,6 +12567,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
12545
12567
  executionAuthScopeDigest,
12546
12568
  staleAfterSeconds: toolCachePolicy.staleAfterSeconds,
12547
12569
  });
12570
+ compatibleDurableCacheKeys = compatibleDurableCacheKeys.map(scopeReceipt);
12548
12571
  let durableCacheKey = compatibleDurableCacheKeys[0];
12549
12572
  if (!durableCacheKey) {
12550
12573
  throw new Error(`Tool ${toolId} is missing a primary durable cache key.`);
@@ -12567,6 +12590,9 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
12567
12590
  providerActionVersion,
12568
12591
  payload: input,
12569
12592
  });
12593
+ if (legacyDurableCacheKey)
12594
+ legacyDurableCacheKey = scopeReceipt(legacyDurableCacheKey);
12595
+ providerIdempotencyKeyBase = scopeOperation(providerIdempotencyKeyBase);
12570
12596
  let directResultReceiptKey = durableCacheKey;
12571
12597
  // A raw-v2 artifact must never read an older receipt that cannot render
12572
12598
  // raw-v2. If both the primary and its revisioned recovery receipt are
@@ -12589,12 +12615,13 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
12589
12615
  input,
12590
12616
  eventWaitHandler,
12591
12617
  explicitForce,
12618
+ logicalCallId,
12592
12619
  );
12593
12620
  }
12594
12621
  if (toolId === 'run_javascript') {
12595
12622
  throw new Error(DISALLOWED_RUN_JAVASCRIPT_TOOL_MESSAGE);
12596
12623
  }
12597
- if (cacheableToolResult && !toolCachePolicy.force) {
12624
+ if (cacheableToolResult && !toolCachePolicy.force && !invocationScoped) {
12598
12625
  const sourceRunRecovered = await this.recoverSourceRunToolReceipt({
12599
12626
  toolId,
12600
12627
  logicalCallId,
@@ -13315,6 +13342,8 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13315
13342
  executionAuthScopeDigest,
13316
13343
  staleAfterSeconds: toolCachePolicy.staleAfterSeconds,
13317
13344
  });
13345
+ compatibleDurableCacheKeys =
13346
+ compatibleDurableCacheKeys.map(scopeReceipt);
13318
13347
  durableCacheKey = compatibleDurableCacheKeys[0];
13319
13348
  if (!durableCacheKey) {
13320
13349
  throw new Error(
@@ -13335,6 +13364,9 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13335
13364
  providerActionVersion,
13336
13365
  payload: input,
13337
13366
  });
13367
+ if (legacyDurableCacheKey)
13368
+ legacyDurableCacheKey = scopeReceipt(legacyDurableCacheKey);
13369
+ providerIdempotencyKeyBase = scopeOperation(providerIdempotencyKeyBase);
13338
13370
  directResultReceiptKey = durableCacheKey;
13339
13371
  bypassDirectResultCache = false;
13340
13372
  checkpointCacheKeys.splice(
@@ -13354,6 +13386,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13354
13386
  input: Record<string, unknown>,
13355
13387
  handler: IntegrationEventWaitHandler,
13356
13388
  force = false,
13389
+ toolCallId?: string,
13357
13390
  ): Promise<unknown> {
13358
13391
  this.assertInlineChildContract('suspending_child');
13359
13392
  if (!this.#options.durableBoundaries) {
@@ -13367,6 +13400,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
13367
13400
  workflowId: this.#options.workflowId,
13368
13401
  orgId: this.#options.orgId,
13369
13402
  executorToken: this.#options.executorToken,
13403
+ toolCallId,
13370
13404
  slackHitlDefaultTimeoutMs:
13371
13405
  this.currentRuntimeSemantics.slackHitl.defaultTimeoutMs,
13372
13406
  slackHitlTimeoutOutcome:
@@ -670,6 +670,8 @@ export type IntegrationEventWaitRuntimeContext = {
670
670
  workflowId?: string;
671
671
  orgId?: string;
672
672
  executorToken?: string;
673
+ /** Stable runtime identity for one logical tools.execute invocation. */
674
+ toolCallId?: string;
673
675
  slackHitlDefaultTimeoutMs?: number;
674
676
  /** Behavior selected by the admitted Play artifact, never worker version. */
675
677
  slackHitlTimeoutOutcome?: 'park' | 'error';
@@ -981,6 +983,9 @@ export interface ContextOptions {
981
983
  getToolQueueHints?: (toolId: string) => Promise<readonly PlayQueueHint[]>;
982
984
  getToolProvider?: (toolId: string) => Promise<string | null>;
983
985
  getToolOperation?: (toolId: string) => Promise<string | null>;
986
+ /** Identity policy is required before reading receipts; lookup errors are
987
+ * fatal, unlike the legacy best-effort retry advice below. */
988
+ getToolIdempotencyScope?: (toolId: string) => Promise<'invocation' | null>;
984
989
  getToolRetryPolicy?: (
985
990
  toolId: string,
986
991
  input: Record<string, unknown>,
@@ -226,6 +226,24 @@ export function buildDurableToolReceiptPrefix(input: {
226
226
  return `ctx:${orgId}:call:tool:${normalizeTableNamespace(toolId)}:`;
227
227
  }
228
228
 
229
+ /** Partition a completed-result receipt without changing its accepted wire
230
+ * shape. The semantic key still includes payload/auth/action/presentation. */
231
+ export function scopeToolReceiptToInvocation(input: {
232
+ orgId?: string | null;
233
+ toolId: string;
234
+ receiptKey: string;
235
+ invocationIdentity: string;
236
+ }): string {
237
+ if (!input.invocationIdentity.trim())
238
+ throw new Error('Missing tool invocation identity.');
239
+ return `${buildDurableToolReceiptPrefix(input)}${sha256Hex(
240
+ stableStringify({
241
+ receiptKey: input.receiptKey,
242
+ invocationIdentity: input.invocationIdentity,
243
+ }),
244
+ )}`;
245
+ }
246
+
229
247
  export function buildProviderOperationIdempotencyKey(input: {
230
248
  operationKey: string;
231
249
  force?: boolean;
@@ -1,5 +1,6 @@
1
1
  export const EVENT_WAIT_TOOL_IDS: ReadonlySet<string> = new Set([
2
2
  'slack_message_with_hitl',
3
+ 'slack_wait_for_action',
3
4
  'slack_send_message_with_hitl',
4
5
  'test_wait_for_event',
5
6
  ]);
@@ -285,7 +285,14 @@ const RUNTIME_RECEIPT_GATEWAY_BATCH_SIZE = 200;
285
285
  const RUNTIME_RECEIPT_GATEWAY_BATCH_MAX_WAIT_MS = 15;
286
286
  const RUNTIME_RECEIPT_GATEWAY_REQUEST_TIMEOUT_MS =
287
287
  RUNTIME_CAPACITY_POLICY.receiptGateway.requestTimeoutMs;
288
- const RETRY_SAFE_EVENT_WAIT_ARM_TOOLS = new Set(['test_wait_for_event']);
288
+ // Slack's native action wait persists its interaction intent before posting or
289
+ // updating a card. Replaying the same boundary either reuses its bound message
290
+ // or refuses an ambiguous unbound post, so transient gateway responses are safe
291
+ // to retry without creating a second card.
292
+ const RETRY_SAFE_EVENT_WAIT_ARM_TOOLS = new Set([
293
+ 'test_wait_for_event',
294
+ 'slack_wait_for_action',
295
+ ]);
289
296
 
290
297
  /**
291
298
  * The Context already bounds receipt completion to sixteen flights. The
@@ -329,6 +336,7 @@ type RuntimeToolMetadata = {
329
336
  actionCacheReadVersions?: string[];
330
337
  queueHints?: unknown;
331
338
  retry?: {
339
+ idempotencyScope?: 'invocation';
332
340
  retrySafeTransientHttp?: boolean;
333
341
  requiresExecutionFence?: boolean;
334
342
  };
@@ -2184,6 +2192,12 @@ async function run(
2184
2192
  ? operation.trim()
2185
2193
  : null;
2186
2194
  },
2195
+ getToolIdempotencyScope: async (toolId) => {
2196
+ const metadata = await getRuntimeToolMetadata(toolId);
2197
+ return metadata.retry?.idempotencyScope === 'invocation'
2198
+ ? 'invocation'
2199
+ : null;
2200
+ },
2187
2201
  getToolRetryPolicy: async (toolId) => {
2188
2202
  const metadata = await getRuntimeToolMetadata(toolId);
2189
2203
  return {
package/dist/cli/index.js CHANGED
@@ -3068,7 +3068,7 @@ var SDK_RELEASE = {
3068
3068
  // getters keep their established compatibility behavior.
3069
3069
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3070
3070
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3071
- version: "0.3.151",
3071
+ version: "0.3.152",
3072
3072
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
3073
3073
  packageCapabilities: {
3074
3074
  updatePreferences: 1
@@ -3063,7 +3063,7 @@ var SDK_RELEASE = {
3063
3063
  // getters keep their established compatibility behavior.
3064
3064
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3065
3065
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3066
- version: "0.3.151",
3066
+ version: "0.3.152",
3067
3067
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
3068
3068
  packageCapabilities: {
3069
3069
  updatePreferences: 1
package/dist/index.js CHANGED
@@ -864,7 +864,7 @@ var SDK_RELEASE = {
864
864
  // getters keep their established compatibility behavior.
865
865
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
866
866
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
867
- version: "0.3.151",
867
+ version: "0.3.152",
868
868
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
869
869
  packageCapabilities: {
870
870
  updatePreferences: 1
package/dist/index.mjs CHANGED
@@ -768,7 +768,7 @@ var SDK_RELEASE = {
768
768
  // getters keep their established compatibility behavior.
769
769
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
770
770
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
771
- version: "0.3.151",
771
+ version: "0.3.152",
772
772
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
773
773
  packageCapabilities: {
774
774
  updatePreferences: 1
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.151";
152
+ readonly version: "0.3.152";
153
153
  readonly updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.";
154
154
  readonly packageCapabilities: {
155
155
  readonly updatePreferences: 1;
package/dist/release.d.ts CHANGED
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.151";
152
+ readonly version: "0.3.152";
153
153
  readonly updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.";
154
154
  readonly packageCapabilities: {
155
155
  readonly updatePreferences: 1;
package/dist/release.js CHANGED
@@ -74,7 +74,7 @@ var SDK_RELEASE = {
74
74
  // getters keep their established compatibility behavior.
75
75
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
76
76
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
77
- version: "0.3.151",
77
+ version: "0.3.152",
78
78
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
79
79
  packageCapabilities: {
80
80
  updatePreferences: 1
package/dist/release.mjs CHANGED
@@ -48,7 +48,7 @@ var SDK_RELEASE = {
48
48
  // getters keep their established compatibility behavior.
49
49
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
50
50
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
51
- version: "0.3.151",
51
+ version: "0.3.152",
52
52
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
53
53
  packageCapabilities: {
54
54
  updatePreferences: 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.3.151",
3
+ "version": "0.3.152",
4
4
  "description": "GTM data CLI and TypeScript SDK for coding agents",
5
5
  "license": "MIT",
6
6
  "homepage": "https://code.deepline.com",