deepline 0.3.59 → 0.3.61
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 +3 -0
- package/dist/bundling-sources/sdk/src/config.ts +90 -0
- package/dist/bundling-sources/sdk/src/play.ts +45 -12
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/types.ts +31 -11
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +40 -8
- package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +10 -54
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +116 -20
- package/dist/bundling-sources/shared_libs/plays/core.ts +46 -13
- package/dist/cli/index.js +464 -60
- package/dist/cli/index.mjs +458 -54
- package/dist/{compiler-manifest-B47AA7As.d.mts → compiler-manifest-IkyvsUO-.d.mts} +38 -10
- package/dist/{compiler-manifest-B47AA7As.d.ts → compiler-manifest-IkyvsUO-.d.ts} +38 -10
- package/dist/index.d.mts +41 -19
- package/dist/index.d.ts +41 -19
- package/dist/index.js +58 -5
- package/dist/index.mjs +58 -5
- package/dist/install-integrity.json +2 -2
- package/dist/plays/bundle-play-file.d.mts +2 -2
- package/dist/plays/bundle-play-file.d.ts +2 -2
- package/dist/plays/bundle-play-file.mjs +57 -5
- package/package.json +1 -1
|
@@ -2057,6 +2057,9 @@ export class DeeplineClient {
|
|
|
2057
2057
|
currentPublishedVersion:
|
|
2058
2058
|
play.currentPublishedVersion ?? play.liveRevision?.version ?? null,
|
|
2059
2059
|
latestRunId: play.latestRunId ?? detail.latestRuns[0]?.workflowId ?? null,
|
|
2060
|
+
...(play.triggerMetadata
|
|
2061
|
+
? { triggerMetadata: play.triggerMetadata }
|
|
2062
|
+
: {}),
|
|
2060
2063
|
...(play.runtimeLimit ? { runtimeLimit: play.runtimeLimit } : {}),
|
|
2061
2064
|
...(play.activeScheduledPlays
|
|
2062
2065
|
? { activeScheduledPlays: play.activeScheduledPlays }
|
|
@@ -94,6 +94,27 @@ export type ProjectPinTarget =
|
|
|
94
94
|
candidates: string[];
|
|
95
95
|
};
|
|
96
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Where the CLI obtained the credentials for the current invocation.
|
|
99
|
+
*
|
|
100
|
+
* This is provenance only. SDK consumers may intentionally use host-level
|
|
101
|
+
* credentials, so CLI-only safety policy must be enforced by the CLI command
|
|
102
|
+
* dispatcher rather than by {@link resolveConfig}.
|
|
103
|
+
*/
|
|
104
|
+
export type CliAuthProvenance = {
|
|
105
|
+
scope: 'env' | 'folder' | 'global';
|
|
106
|
+
project:
|
|
107
|
+
| {
|
|
108
|
+
state: 'project';
|
|
109
|
+
dir: string;
|
|
110
|
+
pinPath: string;
|
|
111
|
+
source: 'marker' | 'cowork' | 'folder';
|
|
112
|
+
}
|
|
113
|
+
| { state: 'not_project' }
|
|
114
|
+
| { state: 'ambiguous_cowork_project'; candidates: string[] };
|
|
115
|
+
folderAuthPath: string | null;
|
|
116
|
+
};
|
|
117
|
+
|
|
97
118
|
/**
|
|
98
119
|
* Convert a base URL to a filesystem-safe slug for per-host config storage.
|
|
99
120
|
*
|
|
@@ -676,6 +697,75 @@ export function getActiveProjectAuthSource(
|
|
|
676
697
|
return loadProjectEnvCandidates(startDir)[0] ?? null;
|
|
677
698
|
}
|
|
678
699
|
|
|
700
|
+
function findNearestProjectMarkerDir(startDir: string): string | null {
|
|
701
|
+
let current = resolve(startDir);
|
|
702
|
+
while (true) {
|
|
703
|
+
if (
|
|
704
|
+
COWORK_PROJECT_MARKERS.some((marker) => existsSync(join(current, marker)))
|
|
705
|
+
) {
|
|
706
|
+
return current;
|
|
707
|
+
}
|
|
708
|
+
const parent = dirname(current);
|
|
709
|
+
if (parent === current) return null;
|
|
710
|
+
current = parent;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
/**
|
|
715
|
+
* Resolve credential provenance and whether the command is being run from a
|
|
716
|
+
* project. A project is a marked checkout, a Cowork-mounted project, or a
|
|
717
|
+
* folder that already carries Deepline project auth.
|
|
718
|
+
*
|
|
719
|
+
* The result intentionally does not expose an API key. It lets the CLI reject
|
|
720
|
+
* cloud mutations which would otherwise inherit a different project's shared
|
|
721
|
+
* host-level organization selection.
|
|
722
|
+
*/
|
|
723
|
+
export function resolveCliAuthProvenance(
|
|
724
|
+
config: Pick<ResolvedConfig, 'baseUrl' | 'apiKey'>,
|
|
725
|
+
startDir: string = process.cwd(),
|
|
726
|
+
): CliAuthProvenance {
|
|
727
|
+
const envApiKey = process.env[API_KEY_ENV]?.trim();
|
|
728
|
+
const folderAuth = getResolvedProjectAuthSource(
|
|
729
|
+
config.baseUrl,
|
|
730
|
+
config.apiKey,
|
|
731
|
+
startDir,
|
|
732
|
+
);
|
|
733
|
+
const pinTarget = resolveProjectPinTarget(startDir);
|
|
734
|
+
const markerDir = findNearestProjectMarkerDir(startDir);
|
|
735
|
+
const project = !pinTarget.ok
|
|
736
|
+
? {
|
|
737
|
+
state: 'ambiguous_cowork_project' as const,
|
|
738
|
+
candidates: pinTarget.candidates,
|
|
739
|
+
}
|
|
740
|
+
: folderAuth
|
|
741
|
+
? {
|
|
742
|
+
state: 'project' as const,
|
|
743
|
+
dir: dirname(folderAuth.filePath),
|
|
744
|
+
pinPath: folderAuth.filePath,
|
|
745
|
+
source: 'folder' as const,
|
|
746
|
+
}
|
|
747
|
+
: pinTarget.source === 'cowork'
|
|
748
|
+
? {
|
|
749
|
+
state: 'project' as const,
|
|
750
|
+
dir: pinTarget.dir,
|
|
751
|
+
pinPath: join(pinTarget.dir, PROJECT_DEEPLINE_ENV_FILE),
|
|
752
|
+
source: 'cowork' as const,
|
|
753
|
+
}
|
|
754
|
+
: markerDir
|
|
755
|
+
? {
|
|
756
|
+
state: 'project' as const,
|
|
757
|
+
dir: markerDir,
|
|
758
|
+
pinPath: join(markerDir, PROJECT_DEEPLINE_ENV_FILE),
|
|
759
|
+
source: 'marker' as const,
|
|
760
|
+
}
|
|
761
|
+
: { state: 'not_project' as const };
|
|
762
|
+
return {
|
|
763
|
+
scope: envApiKey ? 'env' : folderAuth ? 'folder' : 'global',
|
|
764
|
+
project,
|
|
765
|
+
folderAuthPath: folderAuth?.filePath ?? null,
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
|
|
679
769
|
export {
|
|
680
770
|
baseUrlSlug,
|
|
681
771
|
loadCliEnv,
|
|
@@ -241,7 +241,8 @@ export type PlayFetchResponse = PlayAuthoringFetchResponse;
|
|
|
241
241
|
*
|
|
242
242
|
* @sdkReference runtime 030
|
|
243
243
|
*/
|
|
244
|
-
export type PlayBindings =
|
|
244
|
+
export type PlayBindings<TInput = Record<string, unknown>> =
|
|
245
|
+
PlayAuthoringBindings<TInput>;
|
|
245
246
|
export type SqlListenerOperation = PlaySqlListenerOperation;
|
|
246
247
|
export type SqlListenerFilterScalar = PlaySqlListenerFilterScalar;
|
|
247
248
|
export type SqlListenerFilterOperator = PlaySqlListenerFilterOperator;
|
|
@@ -873,14 +874,28 @@ export type DefinedPlay<
|
|
|
873
874
|
DeeplineNamedPlay<TInput, TOutput>
|
|
874
875
|
>;
|
|
875
876
|
|
|
876
|
-
type
|
|
877
|
+
type PlayHandlerInput<THandler> = THandler extends (
|
|
878
|
+
context: DeeplinePlayRuntimeContext,
|
|
879
|
+
input: infer TInput,
|
|
880
|
+
) => Promise<PlayReturnObject>
|
|
881
|
+
? TInput
|
|
882
|
+
: never;
|
|
883
|
+
|
|
884
|
+
type PlayHandlerOutput<THandler> = THandler extends (
|
|
885
|
+
context: DeeplinePlayRuntimeContext,
|
|
886
|
+
input: unknown,
|
|
887
|
+
) => Promise<infer TOutput extends PlayReturnObject>
|
|
888
|
+
? TOutput
|
|
889
|
+
: never;
|
|
890
|
+
|
|
891
|
+
type PlayMetadata<TInput = Record<string, unknown>> = {
|
|
877
892
|
name: string;
|
|
878
893
|
description?: string;
|
|
879
|
-
bindings?: PlayBindings
|
|
894
|
+
bindings?: PlayBindings<TInput>;
|
|
880
895
|
inputSchema?: Record<string, unknown>;
|
|
881
|
-
billing?: PlayBindings['billing'];
|
|
882
|
-
runtime?: PlayBindings['runtime'];
|
|
883
|
-
compatibility?: PlayBindings['compatibility'];
|
|
896
|
+
billing?: PlayBindings<TInput>['billing'];
|
|
897
|
+
runtime?: PlayBindings<TInput>['runtime'];
|
|
898
|
+
compatibility?: PlayBindings<TInput>['compatibility'];
|
|
884
899
|
};
|
|
885
900
|
|
|
886
901
|
const PLAY_METADATA_SYMBOL = Symbol.for('deepline.play.metadata');
|
|
@@ -1608,6 +1623,18 @@ export function defineInput<TInput>(
|
|
|
1608
1623
|
export function definePlay<TInput, TOutput extends PlayReturnObject>(
|
|
1609
1624
|
config: DefinePlayConfig<TInput, TOutput>,
|
|
1610
1625
|
): DefinedPlay<TInput, TOutput>;
|
|
1626
|
+
/** @internal Contextually type unannotated monitor-event handlers as unknown. */
|
|
1627
|
+
export function definePlay<TOutput extends PlayReturnObject>(
|
|
1628
|
+
name: string,
|
|
1629
|
+
fn: (
|
|
1630
|
+
context: DeeplinePlayRuntimeContext,
|
|
1631
|
+
input: unknown,
|
|
1632
|
+
) => Promise<TOutput>,
|
|
1633
|
+
bindings: PlayBindings<never> & {
|
|
1634
|
+
readonly sqlListeners: readonly SqlListenerDeclaration[];
|
|
1635
|
+
},
|
|
1636
|
+
): DefinedPlay<unknown, TOutput>;
|
|
1637
|
+
/* eslint-disable @typescript-eslint/no-explicit-any -- This constraint must infer a concrete contravariant handler input. */
|
|
1611
1638
|
/**
|
|
1612
1639
|
* Define a play with a name and function.
|
|
1613
1640
|
*
|
|
@@ -1616,11 +1643,17 @@ export function definePlay<TInput, TOutput extends PlayReturnObject>(
|
|
|
1616
1643
|
* @param bindings - Play configuration, including runtime limits and triggers.
|
|
1617
1644
|
* @returns Play handle.
|
|
1618
1645
|
*/
|
|
1619
|
-
export function definePlay<
|
|
1646
|
+
export function definePlay<
|
|
1647
|
+
THandler extends (
|
|
1648
|
+
context: DeeplinePlayRuntimeContext,
|
|
1649
|
+
input: any,
|
|
1650
|
+
) => Promise<PlayReturnObject>,
|
|
1651
|
+
>(
|
|
1620
1652
|
name: string,
|
|
1621
|
-
fn:
|
|
1622
|
-
bindings?: PlayBindings
|
|
1623
|
-
): DefinedPlay<
|
|
1653
|
+
fn: THandler,
|
|
1654
|
+
bindings?: PlayBindings<NoInfer<PlayHandlerInput<THandler>>>,
|
|
1655
|
+
): DefinedPlay<PlayHandlerInput<THandler>, PlayHandlerOutput<THandler>>;
|
|
1656
|
+
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
1624
1657
|
/**
|
|
1625
1658
|
* @sdkReference runtime 010
|
|
1626
1659
|
*/
|
|
@@ -1630,7 +1663,7 @@ export function definePlay<TInput, TOutput extends PlayReturnObject>(
|
|
|
1630
1663
|
ctx: DeeplinePlayRuntimeContext,
|
|
1631
1664
|
input: TInput,
|
|
1632
1665
|
) => Promise<TOutput>,
|
|
1633
|
-
maybeBindings?: PlayBindings
|
|
1666
|
+
maybeBindings?: PlayBindings<TInput>,
|
|
1634
1667
|
): DefinedPlay<TInput, TOutput> {
|
|
1635
1668
|
const config =
|
|
1636
1669
|
typeof nameOrConfig === 'string'
|
|
@@ -1690,7 +1723,7 @@ export function definePlay<TInput, TOutput extends PlayReturnObject>(
|
|
|
1690
1723
|
);
|
|
1691
1724
|
}
|
|
1692
1725
|
|
|
1693
|
-
const metadata: PlayMetadata = {
|
|
1726
|
+
const metadata: PlayMetadata<TInput> = {
|
|
1694
1727
|
name,
|
|
1695
1728
|
...(description ? { description } : {}),
|
|
1696
1729
|
...(bindings ? { bindings } : {}),
|
|
@@ -199,7 +199,7 @@ export const SDK_RELEASE = {
|
|
|
199
199
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
200
200
|
// getters keep their established compatibility behavior.
|
|
201
201
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
202
|
-
version: '0.3.
|
|
202
|
+
version: '0.3.61',
|
|
203
203
|
updateSummary:
|
|
204
204
|
'Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.',
|
|
205
205
|
packageCapabilities: {
|
|
@@ -1089,6 +1089,20 @@ export interface PlayDefinitionDetail {
|
|
|
1089
1089
|
liveRevision?: PlayRevisionSummary | null;
|
|
1090
1090
|
/** `true` if the working revision differs from the live revision. */
|
|
1091
1091
|
isDraftDirty?: boolean;
|
|
1092
|
+
/** Live trigger state. This is operational state, not a source declaration. */
|
|
1093
|
+
triggerStatus?: PlayTriggerStatus;
|
|
1094
|
+
/**
|
|
1095
|
+
* Additive scheduler metadata for human/UI rendering. Values are absent for
|
|
1096
|
+
* plays with no cron binding and must never be inferred from source alone.
|
|
1097
|
+
*/
|
|
1098
|
+
triggerMetadata?: {
|
|
1099
|
+
cronSchedule?: string | null;
|
|
1100
|
+
cronTimezone?: string | null;
|
|
1101
|
+
nextScheduledAt?: number | null;
|
|
1102
|
+
lastScheduledAt?: number | null;
|
|
1103
|
+
blockedReason?: string | null;
|
|
1104
|
+
[key: string]: unknown;
|
|
1105
|
+
} | null;
|
|
1092
1106
|
/** Effective sandbox limit from the live revision, or the working draft before first publish. */
|
|
1093
1107
|
runtimeLimit?: PlayRuntimeLimit | null;
|
|
1094
1108
|
/** Present for a Play with a cron trigger. Advisory only; publish remains authoritative. */
|
|
@@ -1125,11 +1139,14 @@ export interface PlayListItem {
|
|
|
1125
1139
|
currentRevision?: PlayRevisionSummary | null;
|
|
1126
1140
|
liveRevision?: PlayRevisionSummary | null;
|
|
1127
1141
|
aliases?: string[];
|
|
1128
|
-
triggerStatus?:
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1142
|
+
triggerStatus?: PlayTriggerStatus;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
/** Additive live trigger state shared by list, get, and describe. */
|
|
1146
|
+
export interface PlayTriggerStatus {
|
|
1147
|
+
cron: string | null;
|
|
1148
|
+
webhook: string | null;
|
|
1149
|
+
blockedReason: string | null;
|
|
1133
1150
|
}
|
|
1134
1151
|
|
|
1135
1152
|
export interface ProductNotificationEventDefinition {
|
|
@@ -1202,11 +1219,9 @@ export interface PlayDescription {
|
|
|
1202
1219
|
*/
|
|
1203
1220
|
liveVersion?: number | null;
|
|
1204
1221
|
/** Whether this play's cron and webhook triggers are armed. */
|
|
1205
|
-
triggerStatus?:
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
blockedReason: string | null;
|
|
1209
|
-
};
|
|
1222
|
+
triggerStatus?: PlayTriggerStatus;
|
|
1223
|
+
/** Additive cron timing metadata for an operational description. */
|
|
1224
|
+
triggerMetadata?: PlayDefinitionDetail['triggerMetadata'];
|
|
1210
1225
|
isDraftDirty?: boolean;
|
|
1211
1226
|
latestRunId?: string | null;
|
|
1212
1227
|
/** Effective sandbox limit from the revision named runs use. */
|
|
@@ -1512,7 +1527,12 @@ export interface PlayCheckSqlListenerEventSummary {
|
|
|
1512
1527
|
export interface PlayCheckTriggersSummary {
|
|
1513
1528
|
sqlListeners?: PlayCheckSqlListenerTrigger[];
|
|
1514
1529
|
sqlListenerEvent?: PlayCheckSqlListenerEventSummary;
|
|
1515
|
-
cron?: {
|
|
1530
|
+
cron?: {
|
|
1531
|
+
schedule: string;
|
|
1532
|
+
timezone?: string;
|
|
1533
|
+
/** Static input supplied to every run started by this cron binding. */
|
|
1534
|
+
input?: Record<string, unknown>;
|
|
1535
|
+
};
|
|
1516
1536
|
webhook?: true;
|
|
1517
1537
|
}
|
|
1518
1538
|
|
|
@@ -113,6 +113,7 @@ import {
|
|
|
113
113
|
import {
|
|
114
114
|
isProviderUnavailable,
|
|
115
115
|
serializeToolExecutionFailure,
|
|
116
|
+
ToolExecutionError,
|
|
116
117
|
TOOL_EXECUTION_ERROR_SCHEMA_VERSION,
|
|
117
118
|
TOOL_EXECUTION_ERROR_SCHEMA_HEADER,
|
|
118
119
|
type ToolExecutionErrorSchemaVersion,
|
|
@@ -2036,6 +2037,13 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
2036
2037
|
private readonly toolDispatchQueuedAtByLane = new Map<string, number>();
|
|
2037
2038
|
private readonly toolDispatcherWakeWaiters = new Set<() => void>();
|
|
2038
2039
|
private toolDispatcherFailure: unknown | null = null;
|
|
2040
|
+
/**
|
|
2041
|
+
* Deepline's own zero-credit denial is run-fatal. Keep it independently of
|
|
2042
|
+
* customer control flow so a broad `try/catch` cannot turn it into a
|
|
2043
|
+
* successful Play result. Provider account capacity remains a normal typed
|
|
2044
|
+
* waterfall miss.
|
|
2045
|
+
*/
|
|
2046
|
+
private deeplineInsufficientCreditsFailure: ToolExecutionError | null = null;
|
|
2039
2047
|
private toolCallResolvers = new Map<
|
|
2040
2048
|
string,
|
|
2041
2049
|
{ resolve: (value: unknown) => void; reject: (reason: unknown) => void }
|
|
@@ -2218,10 +2226,30 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
2218
2226
|
: {}),
|
|
2219
2227
|
}
|
|
2220
2228
|
: undefined,
|
|
2221
|
-
)
|
|
2229
|
+
).catch((error: unknown) => {
|
|
2230
|
+
this.recordDeeplineInsufficientCreditsFailure(error);
|
|
2231
|
+
throw error;
|
|
2232
|
+
}) as Promise<TOutput>;
|
|
2222
2233
|
},
|
|
2223
2234
|
};
|
|
2224
2235
|
|
|
2236
|
+
private recordDeeplineInsufficientCreditsFailure(error: unknown): void {
|
|
2237
|
+
if (
|
|
2238
|
+
error instanceof ToolExecutionError &&
|
|
2239
|
+
error.origin === 'deepline' &&
|
|
2240
|
+
error.code === 'INSUFFICIENT_CREDITS'
|
|
2241
|
+
) {
|
|
2242
|
+
this.deeplineInsufficientCreditsFailure ??= error;
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2246
|
+
/** Called by the runner after customer code returns, before a success settles. */
|
|
2247
|
+
assertNoDeeplineInsufficientCreditsFailure(): void {
|
|
2248
|
+
if (this.deeplineInsufficientCreditsFailure) {
|
|
2249
|
+
throw this.deeplineInsufficientCreditsFailure;
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2225
2253
|
async tool<TOutput = unknown>(
|
|
2226
2254
|
key: string,
|
|
2227
2255
|
toolId: string,
|
|
@@ -13258,14 +13286,12 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
13258
13286
|
...(requestsDurableInvocationFence
|
|
13259
13287
|
? { canonical_operation: canonicalOperation }
|
|
13260
13288
|
: {}),
|
|
13261
|
-
//
|
|
13262
|
-
//
|
|
13263
|
-
//
|
|
13264
|
-
|
|
13265
|
-
// representation.
|
|
13266
|
-
...(providerIdempotencyReceiptKey
|
|
13289
|
+
// The worker-owned receipt coordinates this physical durable
|
|
13290
|
+
// call. Provider idempotency is carried separately below so
|
|
13291
|
+
// exact-payload reuse never replaces batch receipt ownership.
|
|
13292
|
+
...(durableCallReceiptKey
|
|
13267
13293
|
? {
|
|
13268
|
-
durable_call_receipt_key:
|
|
13294
|
+
durable_call_receipt_key: durableCallReceiptKey,
|
|
13269
13295
|
...(executionAuthScopeDigest
|
|
13270
13296
|
? {
|
|
13271
13297
|
execution_auth_scope_digest:
|
|
@@ -13274,6 +13300,12 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
13274
13300
|
: {}),
|
|
13275
13301
|
}
|
|
13276
13302
|
: {}),
|
|
13303
|
+
...(providerIdempotencyReceiptKey
|
|
13304
|
+
? {
|
|
13305
|
+
provider_idempotency_receipt_key:
|
|
13306
|
+
providerIdempotencyReceiptKey,
|
|
13307
|
+
}
|
|
13308
|
+
: {}),
|
|
13277
13309
|
...(options?.customerDbDataset
|
|
13278
13310
|
? {
|
|
13279
13311
|
query_result_dataset: {
|
|
@@ -237,29 +237,6 @@ function isHardBillingFailurePayload(
|
|
|
237
237
|
);
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
/**
|
|
241
|
-
* A normalized provider 402 is fatal only when the integration boundary has
|
|
242
|
-
* declared it account-level capacity. A raw 402 never reaches this function as
|
|
243
|
-
* proof by itself: providers use that status inconsistently.
|
|
244
|
-
*/
|
|
245
|
-
function isProviderAccountCapacityFailurePayload(
|
|
246
|
-
payload: Record<string, unknown> | null,
|
|
247
|
-
): payload is Record<string, unknown> {
|
|
248
|
-
if (!payload) return false;
|
|
249
|
-
const code = String(payload.code ?? payload.error_code ?? '').toUpperCase();
|
|
250
|
-
const category = String(
|
|
251
|
-
payload.error_category ?? payload.errorCategory ?? '',
|
|
252
|
-
).toLowerCase();
|
|
253
|
-
const origin = String(
|
|
254
|
-
payload.failure_origin ?? payload.failureOrigin ?? '',
|
|
255
|
-
).toLowerCase();
|
|
256
|
-
return (
|
|
257
|
-
code === 'PROVIDER_ACCOUNT_CAPACITY' &&
|
|
258
|
-
category === 'provider_account' &&
|
|
259
|
-
(origin === 'provider' || origin === 'provider_account')
|
|
260
|
-
);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
240
|
function normalizeHardBillingPayload(
|
|
264
241
|
payload: Record<string, unknown>,
|
|
265
242
|
): Record<string, unknown> {
|
|
@@ -299,18 +276,11 @@ function formatHardBillingFailureMessage(input: {
|
|
|
299
276
|
maxAttempts: number;
|
|
300
277
|
}): string {
|
|
301
278
|
const code = getStringField(input.billing, 'code');
|
|
302
|
-
const providerCapacity = isProviderAccountCapacityFailurePayload(
|
|
303
|
-
input.billing,
|
|
304
|
-
);
|
|
305
279
|
const message =
|
|
306
280
|
getStringField(input.billing, 'message') ??
|
|
307
281
|
getStringField(input.billing, 'error') ??
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
: 'Deepline billing cap exceeded.');
|
|
311
|
-
const headline = providerCapacity
|
|
312
|
-
? 'Provider account capacity blocked execution.'
|
|
313
|
-
: 'Deepline billing cap exceeded.';
|
|
282
|
+
'Deepline billing cap exceeded.';
|
|
283
|
+
const headline = 'Deepline billing cap exceeded.';
|
|
314
284
|
return `tool ${input.toolId} ${input.status} attempt ${input.attempt}/${input.maxAttempts}: ${headline} Run halted before marking remaining rows processed. ${code ? `code=${code}. ` : ''}${message}`;
|
|
315
285
|
}
|
|
316
286
|
|
|
@@ -478,12 +448,8 @@ export function normalizeToolHttpErrorMessage(input: {
|
|
|
478
448
|
? normalizeHardBillingPayload(billing)
|
|
479
449
|
: isHardBillingFailurePayload(parsed)
|
|
480
450
|
? normalizeHardBillingPayload(parsed)
|
|
481
|
-
:
|
|
482
|
-
? parsed
|
|
483
|
-
: null;
|
|
451
|
+
: null;
|
|
484
452
|
if (hardBillingPayload) {
|
|
485
|
-
const providerCapacity =
|
|
486
|
-
isProviderAccountCapacityFailurePayload(hardBillingPayload);
|
|
487
453
|
return createToolHttpError(
|
|
488
454
|
schemaVersion,
|
|
489
455
|
formatHardBillingFailureMessage({
|
|
@@ -498,15 +464,9 @@ export function normalizeToolHttpErrorMessage(input: {
|
|
|
498
464
|
'terminal',
|
|
499
465
|
{
|
|
500
466
|
...publicOptions,
|
|
501
|
-
origin:
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
// provider-owned authentication; the code retains the precise
|
|
505
|
-
// account-capacity reason.
|
|
506
|
-
category: providerCapacity ? 'authentication' : 'billing',
|
|
507
|
-
code: providerCapacity
|
|
508
|
-
? 'PROVIDER_ACCOUNT_CAPACITY'
|
|
509
|
-
: publicOptions.code,
|
|
467
|
+
origin: 'deepline',
|
|
468
|
+
category: 'billing',
|
|
469
|
+
code: publicOptions.code,
|
|
510
470
|
retryable: false,
|
|
511
471
|
},
|
|
512
472
|
);
|
|
@@ -536,19 +496,15 @@ export function isHardBillingToolHttpError(error: unknown): boolean {
|
|
|
536
496
|
if (
|
|
537
497
|
error instanceof ToolHttpError &&
|
|
538
498
|
(isInsufficientCreditsBilling(error.billing) ||
|
|
539
|
-
isHardBillingFailurePayload(error.billing)
|
|
540
|
-
isProviderAccountCapacityFailurePayload(error.billing))
|
|
499
|
+
isHardBillingFailurePayload(error.billing))
|
|
541
500
|
) {
|
|
542
501
|
return true;
|
|
543
502
|
}
|
|
544
503
|
return (
|
|
545
504
|
error instanceof ToolExecutionError &&
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
(error.origin === 'provider' &&
|
|
550
|
-
error.category === 'authentication' &&
|
|
551
|
-
error.code === 'PROVIDER_ACCOUNT_CAPACITY'))
|
|
505
|
+
error.origin === 'deepline' &&
|
|
506
|
+
error.category === 'billing' &&
|
|
507
|
+
error.code !== 'BILLING_UNAVAILABLE'
|
|
552
508
|
);
|
|
553
509
|
}
|
|
554
510
|
|