deepline 0.2.9 → 0.2.11
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/dist/bundling-sources/sdk/src/client.ts +159 -3
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/activity-observation.ts +22 -5
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +23 -20
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +470 -258
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/db-session.ts +8 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +52 -22
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-writer.ts +38 -0
- package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +19 -6
- package/dist/cli/index.js +169 -6
- package/dist/cli/index.mjs +169 -6
- package/dist/index.d.mts +90 -3
- package/dist/index.d.ts +90 -3
- package/dist/index.js +75 -6
- package/dist/index.mjs +75 -6
- package/package.json +1 -1
|
@@ -902,6 +902,66 @@ export type BillingInvoicesResult = {
|
|
|
902
902
|
entries: BillingInvoiceEntry[];
|
|
903
903
|
};
|
|
904
904
|
|
|
905
|
+
export type TargetBillingOperation = {
|
|
906
|
+
id: string;
|
|
907
|
+
state: string;
|
|
908
|
+
version: number;
|
|
909
|
+
next_action?: string | null;
|
|
910
|
+
};
|
|
911
|
+
|
|
912
|
+
export type TargetBillingPlan = {
|
|
913
|
+
sku: 'payg-v1' | 'builder-v1' | 'team-v1';
|
|
914
|
+
name: string;
|
|
915
|
+
recurring_price_usd: number;
|
|
916
|
+
interval: 'month';
|
|
917
|
+
included_credits: number;
|
|
918
|
+
purchased_credit_price_usd: number;
|
|
919
|
+
};
|
|
920
|
+
|
|
921
|
+
export type TargetBillingPlansResult = {
|
|
922
|
+
org_id: string;
|
|
923
|
+
plans: TargetBillingPlan[];
|
|
924
|
+
current_plan_sku: string;
|
|
925
|
+
pending_plan_sku: string | null;
|
|
926
|
+
acquisition_enabled: boolean;
|
|
927
|
+
};
|
|
928
|
+
|
|
929
|
+
export type TargetBillingStatusResult = {
|
|
930
|
+
org_id: string;
|
|
931
|
+
plan: {
|
|
932
|
+
sku: string;
|
|
933
|
+
name: string;
|
|
934
|
+
recurring_price_usd: number | null;
|
|
935
|
+
interval: string | null;
|
|
936
|
+
included_credits: number | null;
|
|
937
|
+
};
|
|
938
|
+
state: string;
|
|
939
|
+
changes_allowed: boolean;
|
|
940
|
+
payment_state: string;
|
|
941
|
+
recharge_state: string;
|
|
942
|
+
next_action: string | null;
|
|
943
|
+
pending_plan_sku: string | null;
|
|
944
|
+
as_of: string | null;
|
|
945
|
+
};
|
|
946
|
+
|
|
947
|
+
export type TargetBillingMutationResult = {
|
|
948
|
+
data: Record<string, unknown>;
|
|
949
|
+
operation: TargetBillingOperation;
|
|
950
|
+
request_id?: string;
|
|
951
|
+
};
|
|
952
|
+
|
|
953
|
+
export type TargetBillingPlanTransitionOptions =
|
|
954
|
+
| {
|
|
955
|
+
action: 'start_or_change';
|
|
956
|
+
targetPlanSku: 'payg-v1' | 'builder-v1' | 'team-v1';
|
|
957
|
+
idempotencyKey: string;
|
|
958
|
+
}
|
|
959
|
+
| {
|
|
960
|
+
action: 'cancel' | 'undo_cancel';
|
|
961
|
+
targetPlanSku?: never;
|
|
962
|
+
idempotencyKey: string;
|
|
963
|
+
};
|
|
964
|
+
|
|
905
965
|
/** Saved payment method details returned by one-click billing top-up. */
|
|
906
966
|
export type BillingPaymentMethodSummary = {
|
|
907
967
|
brand?: string | null;
|
|
@@ -977,9 +1037,8 @@ export type BillingPlansResult = {
|
|
|
977
1037
|
/**
|
|
978
1038
|
* Public billing namespace exposed as `client.billing`.
|
|
979
1039
|
*
|
|
980
|
-
* Carries
|
|
981
|
-
*
|
|
982
|
-
* commands and programmatic callers share the same surface.
|
|
1040
|
+
* Carries plans, subscription state, cancellation, and invoice/receipt history
|
|
1041
|
+
* so CLI commands and programmatic callers share one surface.
|
|
983
1042
|
*
|
|
984
1043
|
* @sdkReference client 030 client.billing
|
|
985
1044
|
*/
|
|
@@ -1006,8 +1065,39 @@ export type BillingNamespace = {
|
|
|
1006
1065
|
/** Subscription invoices plus credit purchase receipts, newest first. */
|
|
1007
1066
|
list: (options?: { limit?: number }) => Promise<BillingInvoicesResult>;
|
|
1008
1067
|
};
|
|
1068
|
+
/** Metronome-authored target catalog and current Contract projection. */
|
|
1069
|
+
targetPlans: () => Promise<TargetBillingPlansResult>;
|
|
1070
|
+
/** Normalized target billing state. */
|
|
1071
|
+
targetStatus: () => Promise<TargetBillingStatusResult>;
|
|
1072
|
+
/** Buy Deepline credits through a payment-gated Metronome commit. */
|
|
1073
|
+
purchaseCredits: (options: {
|
|
1074
|
+
credits: number;
|
|
1075
|
+
idempotencyKey: string;
|
|
1076
|
+
}) => Promise<TargetBillingMutationResult>;
|
|
1077
|
+
/** Start, change, cancel, or undo a target plan transition. */
|
|
1078
|
+
transitionPlan: (
|
|
1079
|
+
options: TargetBillingPlanTransitionOptions,
|
|
1080
|
+
) => Promise<TargetBillingMutationResult>;
|
|
1081
|
+
/** Create a Stripe-hosted billing Portal session. */
|
|
1082
|
+
portalSession: () => Promise<{ url: string }>;
|
|
1009
1083
|
};
|
|
1010
1084
|
|
|
1085
|
+
function requireTargetBillingIdempotencyKey(value: string): string {
|
|
1086
|
+
const normalized = value.trim();
|
|
1087
|
+
if (
|
|
1088
|
+
normalized.length === 0 ||
|
|
1089
|
+
normalized.length > 200 ||
|
|
1090
|
+
normalized !== value
|
|
1091
|
+
) {
|
|
1092
|
+
throw new DeeplineError(
|
|
1093
|
+
'Billing idempotencyKey must contain 1–200 characters with no leading or trailing whitespace.',
|
|
1094
|
+
undefined,
|
|
1095
|
+
'INVALID_BILLING_IDEMPOTENCY_KEY',
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
return normalized;
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1011
1101
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
1012
1102
|
return Boolean(value && typeof value === 'object' && !Array.isArray(value));
|
|
1013
1103
|
}
|
|
@@ -1495,6 +1585,11 @@ export class DeeplineClient {
|
|
|
1495
1585
|
invoices: {
|
|
1496
1586
|
list: (options) => this.listBillingInvoices(options),
|
|
1497
1587
|
},
|
|
1588
|
+
targetPlans: () => this.getTargetBillingPlans(),
|
|
1589
|
+
targetStatus: () => this.getTargetBillingStatus(),
|
|
1590
|
+
purchaseCredits: (options) => this.purchaseTargetBillingCredits(options),
|
|
1591
|
+
transitionPlan: (options) => this.transitionTargetBillingPlan(options),
|
|
1592
|
+
portalSession: () => this.createTargetBillingPortalSession(),
|
|
1498
1593
|
};
|
|
1499
1594
|
this.monitors = {
|
|
1500
1595
|
status: () => this.getMonitorsAccess(),
|
|
@@ -4016,6 +4111,67 @@ export class DeeplineClient {
|
|
|
4016
4111
|
);
|
|
4017
4112
|
}
|
|
4018
4113
|
|
|
4114
|
+
/** List the reviewed target plans and whether new acquisition is enabled. */
|
|
4115
|
+
async getTargetBillingPlans(): Promise<TargetBillingPlansResult> {
|
|
4116
|
+
return this.http.get<TargetBillingPlansResult>('/api/v2/billing/plans');
|
|
4117
|
+
}
|
|
4118
|
+
|
|
4119
|
+
/** Read the workspace's normalized target plan, payment, and balance state. */
|
|
4120
|
+
async getTargetBillingStatus(): Promise<TargetBillingStatusResult> {
|
|
4121
|
+
return this.http.get<TargetBillingStatusResult>('/api/v2/billing/status');
|
|
4122
|
+
}
|
|
4123
|
+
|
|
4124
|
+
/**
|
|
4125
|
+
* Purchase target-billing credits through the durable commercial operation
|
|
4126
|
+
* flow. The caller supplies an idempotency key for safe retries.
|
|
4127
|
+
*/
|
|
4128
|
+
async purchaseTargetBillingCredits(options: {
|
|
4129
|
+
credits: number;
|
|
4130
|
+
idempotencyKey: string;
|
|
4131
|
+
}): Promise<TargetBillingMutationResult> {
|
|
4132
|
+
const idempotencyKey = requireTargetBillingIdempotencyKey(
|
|
4133
|
+
options.idempotencyKey,
|
|
4134
|
+
);
|
|
4135
|
+
return this.http.post<TargetBillingMutationResult>(
|
|
4136
|
+
'/api/v2/billing/credit-purchases',
|
|
4137
|
+
{ credits: options.credits },
|
|
4138
|
+
{ 'Idempotency-Key': idempotencyKey },
|
|
4139
|
+
{ maxRetries: 0, exactUrlOnly: true },
|
|
4140
|
+
);
|
|
4141
|
+
}
|
|
4142
|
+
|
|
4143
|
+
/**
|
|
4144
|
+
* Start, change, cancel, or restore a target plan through one idempotent
|
|
4145
|
+
* commercial operation.
|
|
4146
|
+
*/
|
|
4147
|
+
async transitionTargetBillingPlan(
|
|
4148
|
+
options: TargetBillingPlanTransitionOptions,
|
|
4149
|
+
): Promise<TargetBillingMutationResult> {
|
|
4150
|
+
const idempotencyKey = requireTargetBillingIdempotencyKey(
|
|
4151
|
+
options.idempotencyKey,
|
|
4152
|
+
);
|
|
4153
|
+
return this.http.post<TargetBillingMutationResult>(
|
|
4154
|
+
'/api/v2/billing/plan-transitions',
|
|
4155
|
+
{
|
|
4156
|
+
action: options.action,
|
|
4157
|
+
...(options.targetPlanSku
|
|
4158
|
+
? { target_plan_sku: options.targetPlanSku }
|
|
4159
|
+
: {}),
|
|
4160
|
+
},
|
|
4161
|
+
{ 'Idempotency-Key': idempotencyKey },
|
|
4162
|
+
{ maxRetries: 0, exactUrlOnly: true },
|
|
4163
|
+
);
|
|
4164
|
+
}
|
|
4165
|
+
|
|
4166
|
+
/** Create a Stripe-hosted portal session for payment recovery and invoices. */
|
|
4167
|
+
async createTargetBillingPortalSession(): Promise<{ url: string }> {
|
|
4168
|
+
const response = await this.http.post<{
|
|
4169
|
+
data: { url: string };
|
|
4170
|
+
request_id?: string;
|
|
4171
|
+
}>('/api/v2/billing/portal-sessions', {});
|
|
4172
|
+
return response.data;
|
|
4173
|
+
}
|
|
4174
|
+
|
|
4019
4175
|
// ——————————————————————————————————————————————————————————
|
|
4020
4176
|
// Monitors
|
|
4021
4177
|
// ——————————————————————————————————————————————————————————
|
|
@@ -160,7 +160,7 @@ export const SDK_RELEASE = {
|
|
|
160
160
|
// 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
|
|
161
161
|
// exposed storage-dependent synchronous access. This deliberate minor
|
|
162
162
|
// release keeps lazy paging semantics independent of row residency.
|
|
163
|
-
version: '0.2.
|
|
163
|
+
version: '0.2.11',
|
|
164
164
|
contracts: {
|
|
165
165
|
api: {
|
|
166
166
|
name: 'sdk-http-api',
|
|
@@ -328,6 +328,7 @@ type ProjectionStep = {
|
|
|
328
328
|
nodeId: string;
|
|
329
329
|
status?: string;
|
|
330
330
|
label?: string;
|
|
331
|
+
artifactTableNamespace?: string | null;
|
|
331
332
|
updatedAt?: number | null;
|
|
332
333
|
progress?: PlayActivityProgress | null;
|
|
333
334
|
};
|
|
@@ -490,6 +491,19 @@ export function projectPlayRunActivity(input: {
|
|
|
490
491
|
)
|
|
491
492
|
.sort((left, right) => (right.updatedAt ?? 0) - (left.updatedAt ?? 0))[0];
|
|
492
493
|
if (pendingDataset) {
|
|
494
|
+
const activeDatasetStep = input.nodeStates?.find(
|
|
495
|
+
(candidate) =>
|
|
496
|
+
candidate.nodeId === input.activeNodeId &&
|
|
497
|
+
candidate.status === 'running' &&
|
|
498
|
+
candidate.artifactTableNamespace === pendingDataset.tableNamespace,
|
|
499
|
+
);
|
|
500
|
+
const datasetStep =
|
|
501
|
+
activeDatasetStep ??
|
|
502
|
+
input.nodeStates?.find(
|
|
503
|
+
(candidate) =>
|
|
504
|
+
candidate.artifactTableNamespace === pendingDataset.tableNamespace,
|
|
505
|
+
);
|
|
506
|
+
const datasetProgress = datasetStep?.progress ?? null;
|
|
493
507
|
return projection(
|
|
494
508
|
{
|
|
495
509
|
schemaVersion: 1,
|
|
@@ -502,17 +516,20 @@ export function projectPlayRunActivity(input: {
|
|
|
502
516
|
state: {
|
|
503
517
|
kind: 'active',
|
|
504
518
|
progress: {
|
|
505
|
-
completed:
|
|
519
|
+
completed:
|
|
520
|
+
datasetProgress?.completed ?? pendingDataset.persistedRows,
|
|
506
521
|
total:
|
|
507
|
-
|
|
522
|
+
datasetProgress?.total ??
|
|
523
|
+
(typeof pendingDataset.succeededRows === 'number' ||
|
|
508
524
|
typeof pendingDataset.failedRows === 'number'
|
|
509
525
|
? (pendingDataset.succeededRows ?? 0) +
|
|
510
526
|
(pendingDataset.failedRows ?? 0)
|
|
511
|
-
: undefined,
|
|
512
|
-
failed: pendingDataset.failedRows,
|
|
527
|
+
: undefined),
|
|
528
|
+
failed: datasetProgress?.failed ?? pendingDataset.failedRows,
|
|
513
529
|
},
|
|
514
530
|
},
|
|
515
|
-
observedAt:
|
|
531
|
+
observedAt:
|
|
532
|
+
datasetStep?.updatedAt ?? pendingDataset.updatedAt ?? observedAt,
|
|
516
533
|
},
|
|
517
534
|
now,
|
|
518
535
|
);
|
|
@@ -367,17 +367,8 @@ function isRetryableAppRuntimeResponse(input: {
|
|
|
367
367
|
// The app runtime may explicitly classify an otherwise-client-error status
|
|
368
368
|
// as transient. Keep the structured delivery contract authoritative rather
|
|
369
369
|
// than reducing every 4xx to permanent at the worker boundary.
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
if (
|
|
373
|
-
parsed &&
|
|
374
|
-
typeof parsed === 'object' &&
|
|
375
|
-
!Array.isArray(parsed) &&
|
|
376
|
-
(parsed as { retryable?: unknown }).retryable === true
|
|
377
|
-
) {
|
|
378
|
-
return true;
|
|
379
|
-
}
|
|
380
|
-
} catch {}
|
|
370
|
+
const explicitRetryable = appRuntimeExplicitRetryable(input.body);
|
|
371
|
+
if (explicitRetryable !== null) return explicitRetryable;
|
|
381
372
|
if (
|
|
382
373
|
input.action === 'append_run_events' &&
|
|
383
374
|
input.status === 500 &&
|
|
@@ -391,6 +382,19 @@ function isRetryableAppRuntimeResponse(input: {
|
|
|
391
382
|
return isRetryableAppRuntimeResponseStatus(input.status);
|
|
392
383
|
}
|
|
393
384
|
|
|
385
|
+
function appRuntimeExplicitRetryable(body: string): boolean | null {
|
|
386
|
+
try {
|
|
387
|
+
const parsed = JSON.parse(body) as unknown;
|
|
388
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
const retryable = (parsed as { retryable?: unknown }).retryable;
|
|
392
|
+
return typeof retryable === 'boolean' ? retryable : null;
|
|
393
|
+
} catch {
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
394
398
|
function isRetryableAppRuntimeResponseStatus(status: number): boolean {
|
|
395
399
|
return (
|
|
396
400
|
status === 429 ||
|
|
@@ -1158,15 +1162,14 @@ async function postAppRuntimeApi<TResponse>(
|
|
|
1158
1162
|
status: response.status,
|
|
1159
1163
|
code,
|
|
1160
1164
|
requestId,
|
|
1161
|
-
//
|
|
1162
|
-
//
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
}),
|
|
1165
|
+
// The structured response is authoritative even for a 5xx. Retrying an
|
|
1166
|
+
// explicitly deterministic database failure here turns one rejected SQL
|
|
1167
|
+
// statement into an unbounded outer-writer loop.
|
|
1168
|
+
retryable: isRetryableAppRuntimeResponse({
|
|
1169
|
+
action: body.action,
|
|
1170
|
+
status: response.status,
|
|
1171
|
+
body: responseText,
|
|
1172
|
+
}),
|
|
1170
1173
|
detail: summarizeAppRuntimeErrorBody(responseText),
|
|
1171
1174
|
boundaryLabel,
|
|
1172
1175
|
});
|