deepline 0.3.346 → 0.3.348

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.
Files changed (125) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +5 -0
  2. package/dist/bundling-sources/sdk/src/http.ts +14 -0
  3. package/dist/bundling-sources/sdk/src/index.ts +1 -0
  4. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  5. package/dist/bundling-sources/sdk/src/tool-calls.ts +78 -17
  6. package/dist/bundling-sources/shared_libs/integration-contracts/billing-entitlements.ts +29 -0
  7. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +32 -1
  8. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +17 -1
  9. package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +18 -0
  10. package/dist/bundling-sources/shared_libs/play-runtime/internal-bootstrap-token.ts +9 -0
  11. package/dist/bundling-sources/shared_libs/play-runtime/runtime-authority.ts +11 -0
  12. package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation-contract.ts +6 -0
  13. package/dist/bundling-sources/shared_libs/play-runtime/workflow-executor-auth.ts +3 -0
  14. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +13 -0
  15. package/dist/cli/{auth-HTWHQNMY.mjs → auth-ME53BGXD.mjs} +4 -4
  16. package/dist/cli/auth-YHS2NN4I.js +31 -0
  17. package/dist/cli/{billing-X56CVZWC.mjs → billing-466LUN65.mjs} +31 -4
  18. package/dist/cli/{billing-4DCHVGO5.js → billing-EMRJAWNG.js} +99 -72
  19. package/dist/cli/{chunk-MOVEHSNM.mjs → chunk-2G7KMDDI.mjs} +1 -1
  20. package/dist/cli/{chunk-T7EVEXHS.js → chunk-2JRKH263.js} +15 -15
  21. package/dist/cli/{chunk-KQCTQGUU.mjs → chunk-35PLGSH6.mjs} +52 -16
  22. package/dist/cli/{chunk-EJ2NVO5K.js → chunk-4JJN7BDI.js} +48 -48
  23. package/dist/cli/{chunk-2GRMXCLZ.mjs → chunk-5AZNXX2S.mjs} +1 -1
  24. package/dist/cli/{chunk-L2R72RQJ.js → chunk-5HLM2PGK.js} +8 -8
  25. package/dist/cli/{chunk-5NNSJTJ3.js → chunk-5IYFQJHX.js} +280 -244
  26. package/dist/cli/{chunk-FKKNYKDY.js → chunk-5O4B6AUN.js} +2 -0
  27. package/dist/cli/{chunk-XAM3XOUA.mjs → chunk-5UWZ52IW.mjs} +2 -2
  28. package/dist/cli/{chunk-2RJ7RMRM.js → chunk-6NM2IY4B.js} +8 -8
  29. package/dist/cli/{chunk-NTVTZAVZ.mjs → chunk-7E66A24V.mjs} +2 -0
  30. package/dist/cli/{chunk-3GLIYDIF.mjs → chunk-BAJXRIRP.mjs} +2 -2
  31. package/dist/cli/{chunk-62TKYGY6.mjs → chunk-CA7RR4UD.mjs} +3 -3
  32. package/dist/cli/{chunk-O4SXVVNQ.mjs → chunk-CEC3BXRV.mjs} +1 -1
  33. package/dist/cli/{chunk-IIOBMOMH.mjs → chunk-DSWSEHRX.mjs} +1 -1
  34. package/dist/cli/{chunk-4Q572AVS.js → chunk-EWYHXSV4.js} +6 -6
  35. package/dist/cli/{chunk-22GXXUTB.js → chunk-GVJPI7MB.js} +33 -27
  36. package/dist/cli/{chunk-SGBSQHXS.js → chunk-IICCYB57.js} +64 -62
  37. package/dist/cli/{chunk-5QG2UAYH.js → chunk-KGKPHGDT.js} +2 -2
  38. package/dist/cli/{chunk-GCBLVWDQ.mjs → chunk-L645OZEB.mjs} +17 -8
  39. package/dist/cli/{chunk-ZR4EHO62.mjs → chunk-MM6X5ADB.mjs} +2 -2
  40. package/dist/cli/{chunk-AFNEQ43J.js → chunk-MX53GIOB.js} +40 -1
  41. package/dist/cli/{chunk-YUKZHAFW.js → chunk-NX4WJO5P.js} +26 -26
  42. package/dist/cli/{chunk-GGSLHWTB.js → chunk-PQZURAHR.js} +1 -1
  43. package/dist/cli/{chunk-WKZTHHJI.mjs → chunk-Q37KLZXK.mjs} +10 -8
  44. package/dist/cli/{chunk-OJVAVQLB.js → chunk-QGKPTBRR.js} +3 -3
  45. package/dist/cli/{chunk-ZEUFYRUR.js → chunk-SIE7MILM.js} +257 -248
  46. package/dist/cli/{chunk-YEKAGC52.js → chunk-U5U2DJ3A.js} +60 -60
  47. package/dist/cli/{chunk-NVNHV73C.mjs → chunk-UCVFMPAO.mjs} +2 -2
  48. package/dist/cli/{chunk-VC7M2QR7.mjs → chunk-VWSEZMCR.mjs} +7 -1
  49. package/dist/cli/{chunk-P4IKGWYF.mjs → chunk-XVWOERRO.mjs} +4 -4
  50. package/dist/cli/{chunk-JOA6IKDE.mjs → chunk-Z6B4UPM4.mjs} +39 -0
  51. package/dist/cli/client-F47WSZBF.js +20 -0
  52. package/dist/cli/{client-C2KUT452.mjs → client-K3EFOESB.mjs} +3 -3
  53. package/dist/cli/{csv-3TAA2MTR.js → csv-4UFHUMIR.js} +12 -12
  54. package/dist/cli/{csv-SLACAH4F.mjs → csv-ZFH725GM.mjs} +3 -3
  55. package/dist/cli/{db-BT6Q3FE6.js → db-EJHH7IBM.js} +29 -29
  56. package/dist/cli/{db-IN4I6KJ5.mjs → db-KTJSJ6LJ.mjs} +4 -4
  57. package/dist/cli/{describe-EDXTYMOF.mjs → describe-2GXTRRSJ.mjs} +11 -11
  58. package/dist/cli/{describe-FJZXYKFH.js → describe-ZQXDXWKZ.js} +27 -27
  59. package/dist/cli/{executions-YYQC2TVR.js → executions-FEBZXTAI.js} +6 -6
  60. package/dist/cli/{executions-X36QA5NY.mjs → executions-ZFEW2R3V.mjs} +4 -4
  61. package/dist/cli/{feedback-KTEPHZ4S.mjs → feedback-BYMYIBHU.mjs} +3 -3
  62. package/dist/cli/{feedback-BS3S46O3.js → feedback-F3LKI327.js} +7 -7
  63. package/dist/cli/{git-3ZVYB63W.mjs → git-A3V2AKGA.mjs} +4 -4
  64. package/dist/cli/git-PWHYGNBR.js +23 -0
  65. package/dist/cli/index.js +79 -79
  66. package/dist/cli/index.mjs +31 -31
  67. package/dist/cli/{legacy-noops-VVBJXM2K.mjs → legacy-noops-IMOMP5NH.mjs} +4 -4
  68. package/dist/cli/{legacy-noops-V5R7ITER.js → legacy-noops-TYXWVLSD.js} +7 -7
  69. package/dist/cli/{monitors-J6XDE76B.js → monitors-BG2EP4M2.js} +85 -85
  70. package/dist/cli/{monitors-KYTMBNUQ.mjs → monitors-PJWHKJAG.mjs} +4 -4
  71. package/dist/cli/{org-RGABGQKP.mjs → org-CVCRHGQF.mjs} +4 -4
  72. package/dist/cli/{org-MHF2NGDV.js → org-NM7EROYH.js} +60 -60
  73. package/dist/cli/{play-UII4SSA7.mjs → play-ESB6ZDMP.mjs} +10 -10
  74. package/dist/cli/play-MYWKV6MH.js +153 -0
  75. package/dist/cli/{providers-LQOSKPUH.mjs → providers-BPDX7QBF.mjs} +4 -4
  76. package/dist/cli/{providers-3GDMD7T6.js → providers-EXITLSJG.js} +7 -7
  77. package/dist/cli/{quickstart-R34Z7EMU.js → quickstart-55MBPFRI.js} +5 -5
  78. package/dist/cli/{quickstart-GAMYLCLJ.mjs → quickstart-P5HLSTZB.mjs} +3 -3
  79. package/dist/cli/search-2JFDCWWK.js +26 -0
  80. package/dist/cli/{search-AOOMDVF5.mjs → search-UJ3KOFZV.mjs} +5 -5
  81. package/dist/cli/{secrets-T4XXIASK.js → secrets-TLV2Q4Z5.js} +13 -13
  82. package/dist/cli/{secrets-U7YGLUSX.mjs → secrets-XJCZM2M2.mjs} +4 -4
  83. package/dist/cli/{sessions-VPXR4DSZ.mjs → sessions-4XMG3DEE.mjs} +4 -4
  84. package/dist/cli/{sessions-JQGKWKJS.js → sessions-DJWLUVXM.js} +5 -5
  85. package/dist/cli/{settings-LP55G43L.mjs → settings-3ZGLOANJ.mjs} +7 -7
  86. package/dist/cli/{settings-LXF45R7X.js → settings-KBNCPN3E.js} +74 -74
  87. package/dist/cli/{setup-36QA4JI3.mjs → setup-R3UV4ZXN.mjs} +6 -6
  88. package/dist/cli/{setup-MA2GLU4N.js → setup-WZZXC7H5.js} +41 -41
  89. package/dist/cli/{skills-HB6PARLZ.mjs → skills-44RXNHZH.mjs} +4 -4
  90. package/dist/cli/skills-52WTBX7A.js +28 -0
  91. package/dist/cli/tools-4ESTBMSN.js +40 -0
  92. package/dist/cli/{tools-E7K7R4AO.mjs → tools-NLUPNYR3.mjs} +8 -8
  93. package/dist/cli/{update-IT63P3NV.mjs → update-57GQJRXF.mjs} +6 -6
  94. package/dist/cli/update-V2FZCYNP.js +28 -0
  95. package/dist/cli/{workflow-UO3PMX7R.mjs → workflow-ARCLSKBC.mjs} +5 -5
  96. package/dist/cli/{workflow-SJHASZ5C.js → workflow-XI7LZRTQ.js} +15 -15
  97. package/dist/{client-DW3zASj8.d.ts → client-4DbE-U6e.d.ts} +9 -1
  98. package/dist/{client-BHReRdWK.d.mts → client-DIJpwhl-.d.mts} +9 -1
  99. package/dist/{compiler-manifest-CButyeZ8.d.mts → compiler-manifest-DgdW0q0b.d.mts} +42 -1
  100. package/dist/{compiler-manifest-CButyeZ8.d.ts → compiler-manifest-DgdW0q0b.d.ts} +42 -1
  101. package/dist/{index-BMsNUoL5.d.mts → index-C3nQQTI-.d.mts} +1 -1
  102. package/dist/{index-LDRzwo09.d.ts → index-CEYQAfS0.d.ts} +1 -1
  103. package/dist/index.d.mts +6 -6
  104. package/dist/index.d.ts +6 -6
  105. package/dist/index.js +7 -7
  106. package/dist/index.mjs +4 -4
  107. package/dist/install-integrity.json +87 -86
  108. package/dist/plays/bundle-play-file.d.mts +3 -3
  109. package/dist/plays/bundle-play-file.d.ts +3 -3
  110. package/dist/plays/bundle-play-file.mjs +2 -2
  111. package/dist/plays/run-request.d.mts +2 -2
  112. package/dist/plays/run-request.d.ts +2 -2
  113. package/dist/release.d.mts +1 -1
  114. package/dist/release.d.ts +1 -1
  115. package/dist/release.js +2 -2
  116. package/dist/release.mjs +1 -1
  117. package/package.json +1 -1
  118. package/dist/cli/auth-5YTC2XH2.js +0 -31
  119. package/dist/cli/client-4RKYHB7Z.js +0 -20
  120. package/dist/cli/git-ZHAD5TJN.js +0 -23
  121. package/dist/cli/play-ZWAH3U44.js +0 -153
  122. package/dist/cli/search-FVB7ZNCO.js +0 -26
  123. package/dist/cli/skills-GUWC4FV7.js +0 -28
  124. package/dist/cli/tools-T5WIAD5Z.js +0 -40
  125. package/dist/cli/update-QY6RY3A6.js +0 -28
@@ -1,3 +1,5 @@
1
+ import type { BillingEntitlements } from '../../shared_libs/integration-contracts/billing-entitlements';
2
+ export type { BillingEntitlements } from '../../shared_libs/integration-contracts/billing-entitlements';
1
3
  import type {
2
4
  PlaySettingsResult,
3
5
  PlaySettingsPatch,
@@ -2495,6 +2497,8 @@ export type BillingUsageResult = {
2495
2497
  * @sdkReference client 030 client.billing
2496
2498
  */
2497
2499
  export type BillingNamespace = {
2500
+ /** Current workspace provider benefits; discovery does not authorize a call. */
2501
+ entitlements: () => Promise<BillingEntitlements>;
2498
2502
  /** Charge the saved payment method and add Deepline credits to the active workspace. */
2499
2503
  topUp: (options: {
2500
2504
  credits: number;
@@ -2914,6 +2918,7 @@ export class DeeplineClient {
2914
2918
  planQuery: (input) => planCustomerDbQuery(input),
2915
2919
  };
2916
2920
  this.billing = {
2921
+ entitlements: () => this.http.get('/api/v2/billing/entitlements'),
2917
2922
  topUp: (options) => this.topUpBillingBalance(options),
2918
2923
  topUpWithReceipt: (options) =>
2919
2924
  this.topUpBillingBalanceWithReceipt(options),
@@ -89,6 +89,12 @@ interface RequestOptions {
89
89
  /** Enables endpoint-specific structured tool failure mapping. */
90
90
  toolId?: string;
91
91
  onResponse?: (response: Response) => void;
92
+ /** Observation after the entire response body arrives, before error mapping. */
93
+ onResponseBody?: (observation: {
94
+ receivedAtMs: number;
95
+ httpStatus: number;
96
+ body: unknown;
97
+ }) => void;
92
98
  allowNotFound?: boolean;
93
99
  idempotencyKey?: string;
94
100
  }
@@ -524,8 +530,14 @@ export class HttpClient {
524
530
  // Receiving headers is not completion: a stalled response body must
525
531
  // remain inside the same request deadline and abort its connection.
526
532
  const body = await response.text();
533
+ const receivedAtMs = Date.now();
527
534
  clearTimeout(timeoutId);
528
535
  const parsed = parseResponseBody(body);
536
+ options?.onResponseBody?.({
537
+ receivedAtMs,
538
+ httpStatus: response.status,
539
+ body: parsed,
540
+ });
529
541
 
530
542
  const structuredToolError =
531
543
  options?.toolId && !response.ok
@@ -783,6 +795,7 @@ export class HttpClient {
783
795
  | 'exactUrlOnly'
784
796
  | 'toolId'
785
797
  | 'onResponse'
798
+ | 'onResponseBody'
786
799
  | 'allowNotFound'
787
800
  | 'idempotencyKey'
788
801
  | 'headers'
@@ -916,6 +929,7 @@ export class HttpClient {
916
929
  | 'exactUrlOnly'
917
930
  | 'toolId'
918
931
  | 'onResponse'
932
+ | 'onResponseBody'
919
933
  | 'allowNotFound'
920
934
  | 'idempotencyKey'
921
935
  >,
@@ -1,3 +1,4 @@
1
+ export type { BillingEntitlements } from '../../shared_libs/integration-contracts/billing-entitlements';
1
2
  export type {
2
3
  PlaySettings,
3
4
  PlayPath,
@@ -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.346',
203
+ version: '0.3.348',
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: {
@@ -135,6 +135,12 @@ export type ExecuteToolRawOptions = {
135
135
  searchRef?: string;
136
136
  /** Correlates one CLI command with its execute request and server telemetry. */
137
137
  cliInvocationId?: string;
138
+ /** Optional terminal API body-receipt observation; never a CLI exit clock. */
139
+ onResponseReceived?: (observation: {
140
+ receivedAtMs: number;
141
+ httpStatus: number;
142
+ state: 'completed' | 'failed' | 'cancelled';
143
+ }) => void;
138
144
  };
139
145
 
140
146
  /** Durable state returned for a keyed tool execution. */
@@ -398,23 +404,77 @@ export class ToolCalls {
398
404
  ? { 'x-deepline-cli-invocation-id': options.cliInvocationId }
399
405
  : {}),
400
406
  };
401
- const request = (requestTimeoutMs: number | undefined) =>
402
- this.http.post<ToolExecution<TData, TMeta>>(
403
- `/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
404
- {
405
- payload: inputSnapshot,
406
- ...(metadataSnapshot ? { metadata: metadataSnapshot } : {}),
407
- },
408
- headers,
409
- {
410
- timeout: requestTimeoutMs,
411
- maxRetries: idempotencyKey ? 0 : (options?.maxRetries ?? 0),
412
- retryApiErrors: options?.retryApiErrors === true,
413
- exactUrlOnly: true,
414
- toolId,
415
- idempotencyKey,
416
- },
417
- );
407
+ let lastResponse: {
408
+ receivedAtMs: number;
409
+ httpStatus: number;
410
+ body: unknown;
411
+ } | null = null;
412
+ const observeTerminal = (failure?: { error: unknown }) => {
413
+ if (!lastResponse) return;
414
+ // A final rejection is measurable only if it belongs to this complete
415
+ // HTTP body. Never reuse an earlier retry's body after a network failure.
416
+ if (failure) {
417
+ const { error } = failure;
418
+ if (
419
+ isRecoverableExecutionAttemptError(error) ||
420
+ !(error instanceof DeeplineError) ||
421
+ error.statusCode === undefined ||
422
+ error.statusCode !== lastResponse.httpStatus ||
423
+ error.code === 'EXECUTION_OUTCOME_UNKNOWN'
424
+ )
425
+ return;
426
+ }
427
+ const body = lastResponse.body;
428
+ const recovery = getExecutionRecoveryState(body);
429
+ if (recovery === 'running' || recovery === 'outcome_unknown') return;
430
+ const state = isRecord(body) ? body.status : null;
431
+ const terminal =
432
+ state === 'completed' || state === 'failed' || state === 'cancelled'
433
+ ? state
434
+ : state === 'canceled'
435
+ ? 'cancelled'
436
+ : failure
437
+ ? 'failed'
438
+ : null;
439
+ if (terminal)
440
+ options?.onResponseReceived?.({
441
+ receivedAtMs: lastResponse.receivedAtMs,
442
+ httpStatus: lastResponse.httpStatus,
443
+ state: terminal,
444
+ });
445
+ };
446
+ const request = async (requestTimeoutMs: number | undefined) => {
447
+ lastResponse = null;
448
+ try {
449
+ return await this.http.post<ToolExecution<TData, TMeta>>(
450
+ `/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
451
+ {
452
+ payload: inputSnapshot,
453
+ ...(metadataSnapshot ? { metadata: metadataSnapshot } : {}),
454
+ },
455
+ headers,
456
+ {
457
+ timeout: requestTimeoutMs,
458
+ maxRetries: idempotencyKey ? 0 : (options?.maxRetries ?? 0),
459
+ retryApiErrors: options?.retryApiErrors === true,
460
+ exactUrlOnly: true,
461
+ toolId,
462
+ idempotencyKey,
463
+ onResponse: () => {
464
+ lastResponse = null;
465
+ },
466
+ onResponseBody: (observation) => {
467
+ lastResponse = observation;
468
+ },
469
+ },
470
+ );
471
+ } catch (error) {
472
+ // Only the final HTTP rejection, not an intermediate retry or an
473
+ // ambiguous network/cancellation failure, proves a response endpoint.
474
+ observeTerminal({ error });
475
+ throw error;
476
+ }
477
+ };
418
478
  let response: ToolExecution<TData, TMeta>;
419
479
  let recoveryDeadline: number | null = null;
420
480
  const recoveryTimeoutMs =
@@ -518,6 +578,7 @@ export class ToolCalls {
518
578
  });
519
579
  }
520
580
  }
581
+ observeTerminal();
521
582
  const materialized = materializeToolExecutionResponse(response);
522
583
  return idempotencyKey ? { ...materialized, idempotencyKey } : materialized;
523
584
  }
@@ -0,0 +1,29 @@
1
+ /** Customer-visible discovery data; execution always rechecks admission. */
2
+ export type BillingEntitlements = {
3
+ org_id: string;
4
+ as_of: number;
5
+ /** The held commercial plan or existing legacy billing catalog plan. */
6
+ plan: {
7
+ sku: string;
8
+ name: string;
9
+ catalog_revision: string | null;
10
+ included_credits: number;
11
+ interval: 'month' | 'year' | null;
12
+ } | null;
13
+ benefits: {
14
+ quickenrichUnlimited?: {
15
+ status: 'active' | 'past_due';
16
+ value: { enabled: boolean; requestsPerMinute: number };
17
+ expiresAt?: number;
18
+ };
19
+ };
20
+ /** Configuration provenance is separate from the purchased promise. */
21
+ effective_limits: {
22
+ quickenrichUnlimited?: {
23
+ baseline: number;
24
+ effective: number;
25
+ source: 'plan' | 'override';
26
+ override_expires_at?: number;
27
+ };
28
+ };
29
+ };
@@ -9,7 +9,10 @@ import { stat } from 'node:fs/promises';
9
9
  import { Readable } from 'node:stream';
10
10
  import { pipeline } from 'node:stream/promises';
11
11
  import type { PlaySheetContract } from '../plays/static-pipeline';
12
- import type { AsyncPlayRunRef } from '../plays/authoring-contract';
12
+ import type {
13
+ AsyncPlayRunRef,
14
+ BillingEntitlements,
15
+ } from '../plays/authoring-contract';
13
16
  import type { PlayRowUpdate } from './/ctx-types';
14
17
  import type { PlayRunTimelineEntry } from './/live-events';
15
18
  import type { PlayDatasetBornFrom } from './/cell-provenance';
@@ -361,6 +364,7 @@ type RuntimeApiRequest =
361
364
  | ({
362
365
  action: 'governor_budget_charge';
363
366
  } & PlayRunnerBudgetChargeInput)
367
+ | { action: 'get_billing_entitlements' }
364
368
  | { action: 'get_runtime_traffic_policy' }
365
369
  | RuntimeReceiptAction;
366
370
 
@@ -2162,6 +2166,33 @@ export async function chargeGovernorBudgetViaAppRuntime(
2162
2166
  });
2163
2167
  }
2164
2168
 
2169
+ export async function getBillingEntitlementsViaAppRuntime(
2170
+ context: WorkerRuntimeApiContext,
2171
+ ): Promise<BillingEntitlements> {
2172
+ try {
2173
+ return await postAppRuntimeApi<BillingEntitlements>(context, {
2174
+ action: 'get_billing_entitlements',
2175
+ });
2176
+ } catch (error) {
2177
+ if (
2178
+ error instanceof AppRuntimeApiResponseError &&
2179
+ error.status === 403 &&
2180
+ error.code === null &&
2181
+ error.detail === 'Unsupported runtime action capability scope.'
2182
+ ) {
2183
+ throw new AppRuntimeApiResponseError({
2184
+ action: 'get_billing_entitlements',
2185
+ status: 503,
2186
+ code: 'BILLING_ENTITLEMENTS_UNAVAILABLE',
2187
+ retryable: false,
2188
+ detail:
2189
+ 'The app runtime receiver does not support billing entitlements.',
2190
+ });
2191
+ }
2192
+ throw error;
2193
+ }
2194
+ }
2195
+
2165
2196
  export async function getRuntimeTrafficPolicyViaAppRuntime(
2166
2197
  context: WorkerRuntimeApiContext,
2167
2198
  ): Promise<RuntimeTrafficPolicy> {
@@ -39,7 +39,10 @@ import {
39
39
  } from './batch-runtime';
40
40
  import type { CompiledRequestBatch } from './batch-runtime';
41
41
  import type { AnyBatchOperationStrategy } from './batching-types';
42
- import type { RuntimeApiResponseMeta } from './app-runtime-api';
42
+ import {
43
+ getBillingEntitlementsViaAppRuntime,
44
+ type RuntimeApiResponseMeta,
45
+ } from './app-runtime-api';
43
46
  import {
44
47
  parseExecuteServerTiming,
45
48
  type ExecuteServerTiming,
@@ -2694,6 +2697,7 @@ type ScalarPlayAuthoringRuntimeContext = Pick<
2694
2697
  PlayAuthoringRuntimeContext,
2695
2698
  | 'tools'
2696
2699
  | 'customerDb'
2700
+ | 'billing'
2697
2701
  | 'run'
2698
2702
  | 'tool'
2699
2703
  | 'step'
@@ -3275,6 +3279,18 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
3275
3279
  },
3276
3280
  };
3277
3281
 
3282
+ readonly billing = {
3283
+ entitlements: () => {
3284
+ this.assertNoPendingDurableSuspension();
3285
+ return getBillingEntitlementsViaAppRuntime({
3286
+ baseUrl: this.#options.baseUrl ?? '',
3287
+ executorToken: this.#options.executorToken ?? '',
3288
+ vercelProtectionBypassToken: this.#options.vercelProtectionBypassToken,
3289
+ signal: this.#options.executionSignal,
3290
+ });
3291
+ },
3292
+ };
3293
+
3278
3294
  readonly secrets = {
3279
3295
  get: (name: string): PlaySecretPromise => {
3280
3296
  if (typeof name !== 'string' || !name.trim()) {
@@ -4,6 +4,17 @@ import {
4
4
  } from './fixture-behavior';
5
5
  import { normalizeRuntimeSchedulerSchema } from './runtime-scheduler-topology';
6
6
 
7
+ /** An optional restriction, never a grant of runtime authority. */
8
+ export const MCP_EXECUTION_OPERATION_POLICY = 'mcp' as const;
9
+ export const EXECUTION_OPERATION_POLICY_HEADER = 'x-deepline-operation-policy';
10
+ export type ExecutionOperationPolicy = typeof MCP_EXECUTION_OPERATION_POLICY;
11
+
12
+ export function isExecutionOperationPolicy(
13
+ value: unknown,
14
+ ): value is ExecutionOperationPolicy {
15
+ return value === MCP_EXECUTION_OPERATION_POLICY;
16
+ }
17
+
7
18
  export const RUNTIME_EXECUTION_CAPABILITIES = [
8
19
  'artifact.read',
9
20
  'file.read',
@@ -36,6 +47,8 @@ const CAPABILITY_SET = new Set<string>(RUNTIME_EXECUTION_CAPABILITIES);
36
47
  * a bearer credential, so a scheduler can mint one short-lived token per leg.
37
48
  */
38
49
  export type RuntimeAuthorityDescriptor = {
50
+ /** Server-owned restriction inherited by every descendant and attempt. */
51
+ operationPolicy?: ExecutionOperationPolicy;
39
52
  orgId: string;
40
53
  workflowId: string;
41
54
  runId: string;
@@ -144,6 +157,8 @@ export function requireRuntimeAuthorityDescriptor(
144
157
  (entry) => typeof entry !== 'string' || entry.trim().length === 0,
145
158
  ) ||
146
159
  capabilities.length === 0 ||
160
+ (descriptor.operationPolicy !== undefined &&
161
+ !isExecutionOperationPolicy(descriptor.operationPolicy)) ||
147
162
  !fixtureBehavior.ok ||
148
163
  (fixtureBehavior.behavior !== null &&
149
164
  descriptor.integrationMode !== 'fixture')
@@ -153,6 +168,9 @@ export function requireRuntimeAuthorityDescriptor(
153
168
  );
154
169
  }
155
170
  return {
171
+ ...(descriptor.operationPolicy
172
+ ? { operationPolicy: descriptor.operationPolicy }
173
+ : {}),
156
174
  orgId: descriptor.orgId!,
157
175
  workflowId: descriptor.workflowId!,
158
176
  runId: descriptor.runId!,
@@ -1,5 +1,7 @@
1
1
  import { WORKFLOW_EXECUTOR_TOKEN_TTL_SECONDS } from './/runtime-constants';
2
2
  import {
3
+ isExecutionOperationPolicy,
4
+ type ExecutionOperationPolicy,
3
5
  DEFAULT_RUNTIME_EXECUTION_CAPABILITIES,
4
6
  isRuntimeExecutionCapability,
5
7
  normalizeRuntimeExecutionCapabilities,
@@ -303,6 +305,7 @@ type WorkflowInternalTokenBaseClaims = {
303
305
  export type WorkflowRunExecutionTokenClaims =
304
306
  WorkflowInternalTokenBaseClaims & {
305
307
  purpose: typeof INTERNAL_WORKFLOW_EXECUTION_PURPOSE;
308
+ operation_policy?: ExecutionOperationPolicy;
306
309
  workflow_id: string;
307
310
  run_id: string;
308
311
  // Billing owner for this execution. Defaults to run_id on older tokens and
@@ -642,6 +645,8 @@ function isValidWorkflowClaimsShape(
642
645
  (claims.fixture_behavior === undefined ||
643
646
  (claims.integration_mode === 'fixture' &&
644
647
  validateFixtureBehavior(claims.fixture_behavior).ok)) &&
648
+ (claims.operation_policy === undefined ||
649
+ isExecutionOperationPolicy(claims.operation_policy)) &&
645
650
  (claims.synthetic === undefined || claims.synthetic === true) &&
646
651
  (claims.actor_user_id === undefined ||
647
652
  typeof claims.actor_user_id === 'string') &&
@@ -737,6 +742,7 @@ export async function mintIngestionSubscriptionExecutionToken(input: {
737
742
  }
738
743
 
739
744
  export async function mintWorkflowRunExecutionToken(input: {
745
+ operationPolicy?: ExecutionOperationPolicy;
740
746
  orgId: string;
741
747
  workflowId: string;
742
748
  runId: string;
@@ -781,6 +787,9 @@ export async function mintWorkflowRunExecutionToken(input: {
781
787
  iss: INTERNAL_BOOTSTRAP_TOKEN_ISSUER,
782
788
  aud: INTERNAL_WORKFLOW_EXECUTION_AUDIENCE,
783
789
  purpose: INTERNAL_WORKFLOW_EXECUTION_PURPOSE,
790
+ ...(input.operationPolicy
791
+ ? { operation_policy: input.operationPolicy }
792
+ : {}),
784
793
  org_id: input.orgId,
785
794
  workflow_id: input.workflowId,
786
795
  run_id: input.runId,
@@ -2,6 +2,7 @@ import { mintWorkflowExecutorToken } from './/workflow-executor-auth';
2
2
  import {
3
3
  DEFAULT_RUNTIME_EXECUTION_CAPABILITIES,
4
4
  normalizeRuntimeExecutionCapabilities,
5
+ type ExecutionOperationPolicy,
5
6
  type RuntimeAuthorityDescriptor,
6
7
  type RuntimeExecutionCapability,
7
8
  } from './/execution-capabilities';
@@ -33,6 +34,9 @@ export function deriveAsyncChildRuntimeAuthority(input: {
33
34
  allowedSecrets: readonly string[];
34
35
  }): RuntimeAuthorityDescriptor {
35
36
  return {
37
+ ...(input.parent.operationPolicy
38
+ ? { operationPolicy: input.parent.operationPolicy }
39
+ : {}),
36
40
  orgId: input.parent.orgId,
37
41
  workflowId: input.workflowId,
38
42
  runId: input.runId,
@@ -85,6 +89,7 @@ export async function mintPlayRunRuntimeAuthorityDescriptor(input: {
85
89
  }
86
90
 
87
91
  export async function mintPlayRunRuntimeAuthority(input: {
92
+ operationPolicy?: ExecutionOperationPolicy;
88
93
  orgId: string;
89
94
  workflowId: string;
90
95
  runId: string;
@@ -104,6 +109,9 @@ export async function mintPlayRunRuntimeAuthority(input: {
104
109
  runLedgerIngressPrefixOrigin?: string | null;
105
110
  }): Promise<RuntimeAuthority> {
106
111
  const descriptor: RuntimeAuthorityDescriptor = {
112
+ ...(input.operationPolicy
113
+ ? { operationPolicy: input.operationPolicy }
114
+ : {}),
107
115
  orgId: input.orgId,
108
116
  workflowId: input.workflowId,
109
117
  runId: input.runId,
@@ -140,6 +148,9 @@ export function runtimeAuthorityMintInput(
140
148
  } = {},
141
149
  ) {
142
150
  return {
151
+ ...(descriptor.operationPolicy
152
+ ? { operationPolicy: descriptor.operationPolicy }
153
+ : {}),
143
154
  orgId: descriptor.orgId,
144
155
  workflowId: descriptor.workflowId,
145
156
  runId: descriptor.runId,
@@ -71,6 +71,8 @@ export const RUNTIME_OPERATION_CAPABILITIES = {
71
71
  get_runtime_traffic_policy: 'rate.acquire',
72
72
  governor_budget_charge: 'budget.charge',
73
73
  resolve_secret: 'secret.resolve',
74
+ // Provider prices and availability use the existing discovery authority.
75
+ get_billing_entitlements: 'tool.inspect',
74
76
  } as const satisfies Readonly<Record<string, RuntimeExecutionCapability>>;
75
77
 
76
78
  export const RUNTIME_OPERATION_CONTRACT: DeployedOperationContract =
@@ -78,6 +80,10 @@ export const RUNTIME_OPERATION_CONTRACT: DeployedOperationContract =
78
80
  id: 'runtime-api-actions',
79
81
  actions: RUNTIME_OPERATION_CAPABILITIES,
80
82
  olderReceiver: {
83
+ get_billing_entitlements: {
84
+ kind: 'feature-unavailable',
85
+ code: 'BILLING_ENTITLEMENTS_UNAVAILABLE',
86
+ },
81
87
  project_run_events: {
82
88
  kind: 'equivalent-fallback',
83
89
  action: 'append_run_events',
@@ -1,3 +1,4 @@
1
+ import type { ExecutionOperationPolicy } from './execution-capabilities';
1
2
  import { mintWorkflowRunExecutionToken } from './internal-bootstrap-token';
2
3
  import type { RuntimeExecutionCapability } from './/execution-capabilities';
3
4
  import type { FixtureBehavior } from './/fixture-behavior';
@@ -99,6 +100,7 @@ export async function decryptWorkflowExecutorApiKey(
99
100
  }
100
101
 
101
102
  export async function mintWorkflowExecutorToken(input: {
103
+ operationPolicy?: ExecutionOperationPolicy;
102
104
  orgId: string;
103
105
  workflowId: string;
104
106
  runId: string;
@@ -121,6 +123,7 @@ export async function mintWorkflowExecutorToken(input: {
121
123
  }) {
122
124
  const playName = input.playName?.trim() || input.workflowId;
123
125
  return mintWorkflowRunExecutionToken({
126
+ operationPolicy: input.operationPolicy,
124
127
  orgId: input.orgId,
125
128
  workflowId: input.workflowId,
126
129
  runId: input.runId,
@@ -1,3 +1,5 @@
1
+ import type { BillingEntitlements } from '../integration-contracts/billing-entitlements';
2
+ export type { BillingEntitlements } from '../integration-contracts/billing-entitlements';
1
3
  import { Type, type Static, type TSchema } from '@sinclair/typebox';
2
4
  import { Value } from '@sinclair/typebox/value';
3
5
  import type { PreviousCell } from './cell-staleness';
@@ -1481,6 +1483,15 @@ export const PLAY_AUTHORING_STATIC_FETCH_KEY_HINT =
1481
1483
  export interface PlayAuthoringRuntimeContext<
1482
1484
  TListGetter extends 'dataset' | 'array' = 'dataset',
1483
1485
  > {
1486
+ billing: {
1487
+ /**
1488
+ * Read current workspace plan benefits. Execution rechecks admission;
1489
+ * this read is fresh and is not a durable receipt.
1490
+ * @sdkReference runtime 179 ctx.billing.entitlements()
1491
+ */
1492
+ entitlements(): Promise<BillingEntitlements>;
1493
+ };
1494
+
1484
1495
  /**
1485
1496
  * Load a staged CSV file as a durable dataset handle.
1486
1497
  * @sdkReference runtime 040 ctx.csv(path, options)
@@ -3315,7 +3326,9 @@ export const PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
3315
3326
  ' run(options?: DatasetRunOptions<InputRow>): Promise<PlayDataset<OutputRow>>;',
3316
3327
  '};',
3317
3328
  'export type PlayReferenceLike<TInput extends Record<string, unknown> = Record<string, unknown>> = ({ readonly playName: string; readonly name?: string } | { readonly name: string; readonly playName?: string }) & { readonly __inputType?: TInput };',
3329
+ "export type BillingEntitlements = { org_id: string; as_of: number; plan: { sku: string; name: string; catalog_revision: string | null; included_credits: number; interval: 'month' | 'year' | null } | null; benefits: { quickenrichUnlimited?: { status: 'active' | 'past_due'; value: { enabled: boolean; requestsPerMinute: number }; expiresAt?: number } }; effective_limits: { quickenrichUnlimited?: { baseline: number; effective: number; source: 'plan' | 'override'; override_expires_at?: number } } };",
3318
3330
  'export interface DeeplinePlayRuntimeContext {',
3331
+ ' billing: { entitlements(): Promise<BillingEntitlements> };',
3319
3332
  ' csv<T = Record<string, unknown>>(path: string | CsvInput<T & object>, options?: CsvOptions): Promise<PlayDataset<T>>;',
3320
3333
  ' dataset<TSource extends PlayDatasetInput<object>>(key: string, items: TSource): DatasetBuilder<PlayDatasetRow<TSource> & object, PlayDatasetRow<TSource> & object>;',
3321
3334
  ' map<TSource extends PlayDatasetInput<object>>(key: string, items: TSource, options?: DatasetDefinitionOptions<PlayDatasetRow<TSource> & object>): never;',
@@ -9,11 +9,11 @@ import {
9
9
  registerAuthCommands,
10
10
  reportSetupCompleted,
11
11
  resolvePendingAuthClaimForResume
12
- } from "./chunk-XAM3XOUA.mjs";
13
- import "./chunk-2GRMXCLZ.mjs";
14
- import "./chunk-VC7M2QR7.mjs";
12
+ } from "./chunk-5UWZ52IW.mjs";
13
+ import "./chunk-5AZNXX2S.mjs";
14
+ import "./chunk-VWSEZMCR.mjs";
15
15
  import "./chunk-DLIRSHV6.mjs";
16
- import "./chunk-MOVEHSNM.mjs";
16
+ import "./chunk-2G7KMDDI.mjs";
17
17
  import "./chunk-NXGCO4JB.mjs";
18
18
  import "./chunk-WZYKRD7T.mjs";
19
19
  import "./chunk-KRD6H754.mjs";
@@ -0,0 +1,31 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+ var _chunk4JJN7BDIjs = require('./chunk-4JJN7BDI.js');
13
+ require('./chunk-EWYHXSV4.js');
14
+ require('./chunk-GVJPI7MB.js');
15
+ require('./chunk-XNYIZMNQ.js');
16
+ require('./chunk-PQZURAHR.js');
17
+ require('./chunk-7P5AA3SN.js');
18
+ require('./chunk-OG64RBAC.js');
19
+ require('./chunk-COGTRVWW.js');
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+ exports.EXIT_WORKSPACE_MISMATCH = _chunk4JJN7BDIjs.EXIT_WORKSPACE_MISMATCH; exports.clearPendingClaim = _chunk4JJN7BDIjs.clearPendingClaim; exports.clearSatisfiedPendingClaim = _chunk4JJN7BDIjs.clearSatisfiedPendingClaim; exports.handleRegister = _chunk4JJN7BDIjs.handleRegister; exports.handleStatus = _chunk4JJN7BDIjs.handleStatus; exports.handleWait = _chunk4JJN7BDIjs.handleWait; exports.readPendingAuthClaim = _chunk4JJN7BDIjs.readPendingAuthClaim; exports.registerAuthCommands = _chunk4JJN7BDIjs.registerAuthCommands; exports.reportSetupCompleted = _chunk4JJN7BDIjs.reportSetupCompleted; exports.resolvePendingAuthClaimForResume = _chunk4JJN7BDIjs.resolvePendingAuthClaimForResume;
@@ -2,7 +2,7 @@ import {
2
2
  DeeplineClient,
3
3
  iterateCursorPages,
4
4
  requireBillingIdempotencyKey
5
- } from "./chunk-KQCTQGUU.mjs";
5
+ } from "./chunk-35PLGSH6.mjs";
6
6
  import "./chunk-CBVIJSHF.mjs";
7
7
  import {
8
8
  createTimestampedName,
@@ -10,13 +10,13 @@ import {
10
10
  openInBrowser,
11
11
  printCommandEnvelope,
12
12
  shouldEmitJson
13
- } from "./chunk-2GRMXCLZ.mjs";
13
+ } from "./chunk-5AZNXX2S.mjs";
14
14
  import {
15
15
  AuthError,
16
16
  ConfigError
17
- } from "./chunk-VC7M2QR7.mjs";
17
+ } from "./chunk-VWSEZMCR.mjs";
18
18
  import "./chunk-DLIRSHV6.mjs";
19
- import "./chunk-MOVEHSNM.mjs";
19
+ import "./chunk-2G7KMDDI.mjs";
20
20
  import "./chunk-6IKARAYD.mjs";
21
21
  import {
22
22
  DeeplineError
@@ -1131,6 +1131,32 @@ async function handleTargetStatus(options) {
1131
1131
  { json: options.json }
1132
1132
  );
1133
1133
  }
1134
+ async function handleEntitlements(options) {
1135
+ const payload = await new DeeplineClient().billing.entitlements();
1136
+ printCommandEnvelope(
1137
+ {
1138
+ ok: true,
1139
+ ...payload,
1140
+ render: {
1141
+ sections: [
1142
+ {
1143
+ title: "billing entitlements",
1144
+ lines: [
1145
+ `Plan: ${payload.plan?.name ?? "Legacy billing"}`,
1146
+ ...Object.entries(payload.benefits).map(
1147
+ ([key, grant]) => `${key}: ${grant.status}, ${JSON.stringify(grant.value)}${grant.expiresAt === void 0 ? "" : `, expires ${new Date(grant.expiresAt).toISOString()}`}`
1148
+ ),
1149
+ ...Object.entries(payload.effective_limits).map(
1150
+ ([key, limit]) => `${key} rate: ${limit.effective}/minute (${limit.source}; plan baseline ${limit.baseline})`
1151
+ )
1152
+ ]
1153
+ }
1154
+ ]
1155
+ }
1156
+ },
1157
+ { json: options.json }
1158
+ );
1159
+ }
1134
1160
  async function handleAutoRechargeStatus(options) {
1135
1161
  const payload = await new DeeplineClient().billing.autoRecharge.get();
1136
1162
  const state = payload.available ? payload.enabled ? "on" : "off" : "unavailable";
@@ -1616,6 +1642,7 @@ Examples:
1616
1642
  billing.command("status").description(
1617
1643
  "Show plan, payment, and recharge state; use usage for charges."
1618
1644
  ).option("--json", "Emit JSON output").action(handleTargetStatus);
1645
+ billing.command("entitlements").description("Show current workspace benefits and effective rate limits.").option("--json", "Emit JSON output").action(handleEntitlements);
1619
1646
  billing.command("auto-recharge").description("Inspect and manage automatic Deepline credit recharge.").addHelpText(
1620
1647
  "after",
1621
1648
  `