deepline 0.3.459 → 0.3.461
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/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/monitors/billing/state.ts +28 -0
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-dead-letter.ts +24 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +11 -20
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +72 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +51 -3
- package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +5 -1
- package/dist/cli/{auth-2RM2ZC6E.mjs → auth-6HJXNWUG.mjs} +4 -4
- package/dist/cli/auth-IACERYQH.js +40 -0
- package/dist/cli/{billing-4BZABEOA.js → billing-6P5HO6QG.js} +73 -73
- package/dist/cli/{billing-FYF2GJ25.mjs → billing-MJ42N7YF.mjs} +4 -4
- package/dist/cli/{chunk-5WGW57KC.mjs → chunk-3BMLICF7.mjs} +3 -3
- package/dist/cli/{chunk-HUVI6EBF.js → chunk-5FDKJQZE.js} +1 -1
- package/dist/cli/{chunk-FBMVFOD7.js → chunk-5FY72YOV.js} +8 -8
- package/dist/cli/{chunk-KB4XJRQW.js → chunk-5IYOUBFZ.js} +8 -8
- package/dist/cli/{chunk-U3VAYRUL.js → chunk-5MDIZX7M.js} +6 -6
- package/dist/cli/{chunk-UIKSAVAE.js → chunk-ACCR7POB.js} +26 -26
- package/dist/cli/{chunk-MHMRLS7W.mjs → chunk-BGY2PLP7.mjs} +3 -3
- package/dist/cli/{chunk-ACCQ5OM7.js → chunk-CRYOUPEB.js} +16 -16
- package/dist/cli/{chunk-Z4YO4J4J.js → chunk-FCAZQ7WV.js} +50 -50
- package/dist/cli/{chunk-LSJYTDEK.mjs → chunk-FGLKOWSC.mjs} +1 -1
- package/dist/cli/{chunk-FFUQFRKZ.js → chunk-FGMX4HUZ.js} +20 -20
- package/dist/cli/{chunk-BIPMJKLI.mjs → chunk-FJZILBL7.mjs} +5 -5
- package/dist/cli/{chunk-SOUQUQQE.mjs → chunk-IHHLTHE7.mjs} +8 -8
- package/dist/cli/{chunk-PI65FBEA.js → chunk-KCCOQ5G5.js} +81 -81
- package/dist/cli/{chunk-OD236M42.mjs → chunk-KVJ5VHW5.mjs} +2 -2
- package/dist/cli/{chunk-LGOI2BRX.js → chunk-MDJPEGVN.js} +10 -10
- package/dist/cli/{chunk-ZAJAGMXA.mjs → chunk-MEAIOXJL.mjs} +2 -2
- package/dist/cli/{chunk-KDDB5S6E.mjs → chunk-MGXEUZHL.mjs} +3 -3
- package/dist/cli/{chunk-S5TTNBEZ.js → chunk-O6QOMHCH.js} +35 -35
- package/dist/cli/{chunk-FPPCTKV6.js → chunk-OZBWRICM.js} +2 -2
- package/dist/cli/{chunk-5KC7RLJO.js → chunk-PNATXKLP.js} +6 -6
- package/dist/cli/{chunk-Y35FCRLQ.mjs → chunk-QAJAJPKK.mjs} +1 -1
- package/dist/cli/{chunk-HU7JG4RL.mjs → chunk-QEYHTIV4.mjs} +1 -1
- package/dist/cli/{chunk-7DFM5YLL.mjs → chunk-QIW7TVV6.mjs} +4 -4
- package/dist/cli/{chunk-NLRKZJZF.mjs → chunk-R64BGGRQ.mjs} +2 -2
- package/dist/cli/{chunk-4EBJNT5C.mjs → chunk-RFONC4WJ.mjs} +2 -2
- package/dist/cli/{chunk-7AGGDRNR.mjs → chunk-RY4IVOU3.mjs} +1 -1
- package/dist/cli/{chunk-OY4JQBJG.js → chunk-SAZFZQRI.js} +2 -2
- package/dist/cli/{chunk-JOSOQJ5P.js → chunk-SCIR5JXW.js} +51 -51
- package/dist/cli/{chunk-OQW2YP3P.mjs → chunk-T3MVIPHG.mjs} +1 -1
- package/dist/cli/{chunk-2JSVKNLG.js → chunk-TNMBPMMC.js} +3 -3
- package/dist/cli/{chunk-RLQDDJZZ.mjs → chunk-V7REJRDZ.mjs} +1 -1
- package/dist/cli/{chunk-MNNMPS6J.mjs → chunk-VZBCEA5S.mjs} +1 -1
- package/dist/cli/{chunk-VLJXYDGZ.js → chunk-YQDUODZW.js} +4 -4
- package/dist/cli/{csv-SDVEU3O5.mjs → csv-DQ6GW5B5.mjs} +3 -3
- package/dist/cli/{csv-LRIV3RXE.js → csv-NX7NO3O6.js} +12 -12
- package/dist/cli/{db-NHYULZTM.mjs → db-2YP33M4K.mjs} +4 -4
- package/dist/cli/{db-JS4OEDNY.js → db-R72DFMP6.js} +25 -25
- package/dist/cli/{describe-ZFKCZHOJ.js → describe-2WQY7ZCY.js} +17 -17
- package/dist/cli/{describe-H5F72Q3S.mjs → describe-FRAVCY5F.mjs} +13 -13
- package/dist/cli/{executions-25YKX4K3.mjs → executions-WFBU7L2Q.mjs} +4 -4
- package/dist/cli/{executions-QPAKZTNQ.js → executions-ZLHD4QIT.js} +6 -6
- package/dist/cli/{feedback-Z3BES6L6.mjs → feedback-CN3HJFVF.mjs} +3 -3
- package/dist/cli/{feedback-O63Z5O2R.js → feedback-NDV6TPHG.js} +7 -7
- package/dist/cli/git-JVI36ZFV.js +24 -0
- package/dist/cli/{git-V7S3IBLO.mjs → git-QAD6E3HW.mjs} +4 -4
- package/dist/cli/index.js +132 -132
- package/dist/cli/index.mjs +37 -37
- package/dist/cli/{legacy-noops-ZLLYEGQ6.js → legacy-noops-KVC5QJ74.js} +7 -7
- package/dist/cli/{legacy-noops-VRT5WZ5I.mjs → legacy-noops-TPTKNBI2.mjs} +4 -4
- package/dist/cli/{monitors-T7FKIDDY.js → monitors-KCROV6PJ.js} +89 -89
- package/dist/cli/{monitors-44KSWY3M.mjs → monitors-SV57JFLO.mjs} +5 -5
- package/dist/cli/{org-BZE4CGIT.mjs → org-KX6QIR7A.mjs} +4 -4
- package/dist/cli/{org-KPPG2KY4.js → org-NJYX5743.js} +66 -66
- package/dist/cli/{play-M5P74N3E.js → play-32L7EQN4.js} +284 -284
- package/dist/cli/{play-CHTP4NKR.mjs → play-IQQ57L7Z.mjs} +11 -11
- package/dist/cli/{providers-CGLPOOXA.mjs → providers-4WEC2EQN.mjs} +4 -4
- package/dist/cli/{providers-L3PK7NHU.js → providers-ZQV6QLVQ.js} +7 -7
- package/dist/cli/{quickstart-LJ7HELWE.js → quickstart-HKUSFADF.js} +5 -5
- package/dist/cli/{quickstart-NWG35AKK.mjs → quickstart-RQ76RIUE.mjs} +3 -3
- package/dist/cli/search-75X5LTDE.js +30 -0
- package/dist/cli/{search-723TVSNC.mjs → search-ZRAVFBZC.mjs} +5 -5
- package/dist/cli/{secrets-ONN3Z5Y6.mjs → secrets-CMJOVNVH.mjs} +4 -4
- package/dist/cli/{secrets-SVSSLPWB.js → secrets-J3G5Y43U.js} +13 -13
- package/dist/cli/{sessions-3KAEYQ3U.mjs → sessions-MDQYY5CB.mjs} +4 -4
- package/dist/cli/{sessions-7LYPPYUY.js → sessions-WY7VN4AE.js} +5 -5
- package/dist/cli/{settings-2CBJI7FY.mjs → settings-4RWZPCT5.mjs} +9 -9
- package/dist/cli/{settings-JGJZO7EX.js → settings-HTNTFKCE.js} +76 -76
- package/dist/cli/{setup-BJCBDH34.mjs → setup-P3GYYZWG.mjs} +8 -8
- package/dist/cli/{setup-AIAOO7R4.js → setup-QGCAP62X.js} +43 -43
- package/dist/cli/{skills-7QSQPQXX.mjs → skills-7NAE4ICL.mjs} +6 -6
- package/dist/cli/skills-BKJ53JOQ.js +30 -0
- package/dist/cli/{tools-I7LYXHDR.mjs → tools-COWMIEJ6.mjs} +13 -13
- package/dist/cli/tools-TASOCE7I.js +45 -0
- package/dist/cli/{update-LKY5OJ56.mjs → update-GODLRKNB.mjs} +8 -8
- package/dist/cli/update-SJIKVME6.js +32 -0
- package/dist/cli/{workflow-DD32BU7Y.mjs → workflow-4BXOUVEO.mjs} +5 -5
- package/dist/cli/{workflow-Y4HGE7MB.js → workflow-AO3A6LXN.js} +15 -15
- package/dist/index.js +6 -6
- package/dist/index.mjs +3 -3
- package/dist/install-integrity.json +80 -80
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +2 -2
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
- package/dist/cli/auth-EAFWPDJG.js +0 -40
- package/dist/cli/git-KSRP3PNB.js +0 -24
- package/dist/cli/search-PESQULBG.js +0 -30
- package/dist/cli/skills-WECIGARR.js +0 -30
- package/dist/cli/tools-HTEMYXT2.js +0 -45
- package/dist/cli/update-J4LSPXHD.js +0 -32
|
@@ -205,7 +205,7 @@ export const SDK_RELEASE = {
|
|
|
205
205
|
// getters keep their established compatibility behavior.
|
|
206
206
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
207
207
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
208
|
-
version: '0.3.
|
|
208
|
+
version: '0.3.461',
|
|
209
209
|
updateSummary: {
|
|
210
210
|
introducedIn: '0.3.90',
|
|
211
211
|
summary:
|
|
@@ -285,6 +285,34 @@ export function monitorBillingStateWithProviderRenewal(input: {
|
|
|
285
285
|
};
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
+
/**
|
|
289
|
+
* An active, paid provider subscription that no renewal pass can ever select.
|
|
290
|
+
*
|
|
291
|
+
* Subscription renewal ranges only on the indexed `cancelBeforeAt` copy, and a
|
|
292
|
+
* periodic renewal only on `nextRenewalAt`. A paid monitor that carries a
|
|
293
|
+
* provider-subscription receipt (`provider_next_charge_at` or
|
|
294
|
+
* `cancel_before_at` in its billing JSON) but neither indexed anchor is never
|
|
295
|
+
* charged again while the provider keeps billing Deepline (KAR-103). Only a
|
|
296
|
+
* subscription can carry that receipt: an update-priced create refuses a
|
|
297
|
+
* provider `next_charge_at` outright, so the receipt is the discriminator and
|
|
298
|
+
* no billing-policy lookup is needed here.
|
|
299
|
+
*/
|
|
300
|
+
export function paidSubscriptionLacksRenewalAnchor(row: {
|
|
301
|
+
status: string;
|
|
302
|
+
cancelBeforeAt?: string | null;
|
|
303
|
+
nextRenewalAt?: string | null;
|
|
304
|
+
billingState: unknown;
|
|
305
|
+
}): boolean {
|
|
306
|
+
if (row.status !== 'active') return false;
|
|
307
|
+
if (row.cancelBeforeAt || row.nextRenewalAt) return false;
|
|
308
|
+
const state = parseStoredMonitorBillingState(row.billingState);
|
|
309
|
+
if (state.state !== 'active' && state.state !== 'billing_pending') {
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
if (state.lifecycle_charge_credits <= 0) return false;
|
|
313
|
+
return Boolean(state.provider_next_charge_at || state.cancel_before_at);
|
|
314
|
+
}
|
|
315
|
+
|
|
288
316
|
export function defaultMonitorBillingState(): StoredMonitorBillingState {
|
|
289
317
|
return {
|
|
290
318
|
state: 'billing_pending',
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { isRepairableTenantDataPlaneError } from '@deepline/ingestion-v2/tenant-data-plane-errors';
|
|
3
3
|
import type { SignalRadarInboundMessage } from '@deepline/monitors/signal-radars/inbound-message';
|
|
4
|
+
import {
|
|
5
|
+
hasMonitorSdkValidationIssues,
|
|
6
|
+
MONITOR_SDK_VALIDATION_ERROR_CODE,
|
|
7
|
+
} from '@deepline/monitors/validation';
|
|
4
8
|
|
|
5
9
|
// Minimal pg client seam shared with the ingestion stack: a `query(sql, args)`
|
|
6
10
|
// that returns `{ rows }`. Deliberately structural so PGlite (tests) and the
|
|
@@ -73,8 +77,28 @@ export function classifyInboundFailure(error: unknown): InboundFailureClass {
|
|
|
73
77
|
]);
|
|
74
78
|
if (code && transientCodes.has(code)) return 'transient';
|
|
75
79
|
|
|
80
|
+
// A lifecycle fence is temporary contention, including while recording a
|
|
81
|
+
// billing suspension. Preserve the callback until its owner finishes; do
|
|
82
|
+
// not classify unrelated validation failures as retryable.
|
|
83
|
+
if (
|
|
84
|
+
code === MONITOR_SDK_VALIDATION_ERROR_CODE &&
|
|
85
|
+
hasMonitorSdkValidationIssues(error) &&
|
|
86
|
+
error.issues.length > 0 &&
|
|
87
|
+
error.issues.every(
|
|
88
|
+
(issue) =>
|
|
89
|
+
issue?.code === 'provider_monitor_operation_in_progress' ||
|
|
90
|
+
issue?.code === 'provider_monitor_delete_in_progress',
|
|
91
|
+
)
|
|
92
|
+
) {
|
|
93
|
+
return 'transient';
|
|
94
|
+
}
|
|
95
|
+
|
|
76
96
|
const message = errorMessage(error);
|
|
77
97
|
const transientPatterns = [
|
|
98
|
+
// pg reports subsequent operations on a client whose connection failed
|
|
99
|
+
// without retaining the original socket error's code. A fresh delivery
|
|
100
|
+
// acquires a usable client; this is infrastructure failure, not poison.
|
|
101
|
+
/client has encountered a connection error and is not queryable/i,
|
|
78
102
|
/connection (?:terminated|refused|reset|closed|failure)/i,
|
|
79
103
|
/could not connect to server/i,
|
|
80
104
|
/connection to server .* failed/i,
|
|
@@ -250,6 +250,7 @@ import {
|
|
|
250
250
|
parseToolExecuteExactProviderRetryAtMs,
|
|
251
251
|
parseToolExecuteAuthScopeChangedError,
|
|
252
252
|
ToolExecuteAuthScopeChangedError,
|
|
253
|
+
toolExecuteBillingRetryIdentity,
|
|
253
254
|
type ToolExecuteHttpFailureOutcome,
|
|
254
255
|
} from './tool-execute-retry-policy';
|
|
255
256
|
import {
|
|
@@ -18917,11 +18918,9 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
18917
18918
|
? savedProviderRetryCursor?.legacyProviderOperationForceRefreshIdentities
|
|
18918
18919
|
: options?.providerOperationForceRefreshIdentities;
|
|
18919
18920
|
const executionRequestNonce = crypto.randomUUID();
|
|
18920
|
-
// Transport ambiguity must retain the billing identity.
|
|
18921
|
-
//
|
|
18922
|
-
//
|
|
18923
|
-
// renews fenced billing attribution, keeping its invocation and
|
|
18924
|
-
// provider-operation identities unchanged. Ambiguous deliveries retain it.
|
|
18921
|
+
// Transport ambiguity must retain the billing identity. Only a
|
|
18922
|
+
// definite release of the reservation renews it; see
|
|
18923
|
+
// toolExecuteBillingRetryIdentity.
|
|
18925
18924
|
let deeplineRequestId = `ctx-tool-${stableDigest(executionRequestNonce).slice(0, 32)}`;
|
|
18926
18925
|
// The provider operation has a semantic identity independent of
|
|
18927
18926
|
// the response receipt. Its key is supplied by the caller that owns
|
|
@@ -20786,21 +20785,13 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
20786
20785
|
remainingProviderWaitMs !== null,
|
|
20787
20786
|
);
|
|
20788
20787
|
logProvider429RetryPhase('retry_sleep_completed');
|
|
20789
|
-
|
|
20790
|
-
failure
|
|
20791
|
-
|
|
20792
|
-
|
|
20793
|
-
|
|
20794
|
-
|
|
20795
|
-
) {
|
|
20796
|
-
// These refusals release the prior reservation. App pacing
|
|
20797
|
-
// does not advance invocationAttempt, so use its own HTTP
|
|
20798
|
-
// failure count to avoid reusing a released retry reservation.
|
|
20799
|
-
// Durable result and provider-operation keys stay unchanged.
|
|
20800
|
-
const billingRetryIdentity =
|
|
20801
|
-
failure.reason === 'provider_pacing_wait'
|
|
20802
|
-
? `app-pacing-refusal:${httpFailureAttempt}`
|
|
20803
|
-
: `provider-rate-limit-retry:${invocationAttempt}`;
|
|
20788
|
+
const billingRetryIdentity = toolExecuteBillingRetryIdentity({
|
|
20789
|
+
failure,
|
|
20790
|
+
executionFenced: usesDurableInvocationFence,
|
|
20791
|
+
httpFailureAttempt,
|
|
20792
|
+
invocationAttempt,
|
|
20793
|
+
});
|
|
20794
|
+
if (billingRetryIdentity) {
|
|
20804
20795
|
deeplineRequestId = `ctx-tool-${stableDigest(`${executionRequestNonce}:${billingRetryIdentity}`).slice(0, 32)}`;
|
|
20805
20796
|
}
|
|
20806
20797
|
this.emitExecutionEvent({
|
package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts
CHANGED
|
@@ -204,6 +204,65 @@ export type RuntimeGatewayFailureContext = {
|
|
|
204
204
|
operation?: 'receipt' | 'runtime_sheet' | 'runtime_durability';
|
|
205
205
|
};
|
|
206
206
|
|
|
207
|
+
export type RuntimeSheetPersistenceDiagnostics = {
|
|
208
|
+
sqlState?: string;
|
|
209
|
+
transportCode?: string;
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const RUNTIME_SHEET_SQLSTATE_PATTERN = /^[0-9A-Z]{5}$/;
|
|
213
|
+
const RUNTIME_SHEET_TRANSPORT_CODES = new Set([
|
|
214
|
+
'ECONNABORTED',
|
|
215
|
+
'ECONNREFUSED',
|
|
216
|
+
'ECONNRESET',
|
|
217
|
+
'EHOSTDOWN',
|
|
218
|
+
'EHOSTUNREACH',
|
|
219
|
+
'EPIPE',
|
|
220
|
+
'ENETUNREACH',
|
|
221
|
+
'ENOTFOUND',
|
|
222
|
+
'ETIMEDOUT',
|
|
223
|
+
'EAI_AGAIN',
|
|
224
|
+
]);
|
|
225
|
+
|
|
226
|
+
export function isRuntimeSheetSqlState(value: unknown): value is string {
|
|
227
|
+
return (
|
|
228
|
+
typeof value === 'string' && RUNTIME_SHEET_SQLSTATE_PATTERN.test(value)
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export function isRuntimeSheetTransportCode(value: unknown): value is string {
|
|
233
|
+
return typeof value === 'string' && RUNTIME_SHEET_TRANSPORT_CODES.has(value);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export function runtimeSheetPersistenceDiagnostics(
|
|
237
|
+
error: unknown,
|
|
238
|
+
): RuntimeSheetPersistenceDiagnostics {
|
|
239
|
+
const diagnostics: RuntimeSheetPersistenceDiagnostics = {};
|
|
240
|
+
const seen = new Set<object>();
|
|
241
|
+
let current: unknown = error;
|
|
242
|
+
|
|
243
|
+
for (let depth = 0; depth < 8; depth += 1) {
|
|
244
|
+
if (current === null || typeof current !== 'object' || seen.has(current))
|
|
245
|
+
break;
|
|
246
|
+
seen.add(current);
|
|
247
|
+
let code: unknown;
|
|
248
|
+
let cause: unknown;
|
|
249
|
+
try {
|
|
250
|
+
const candidate = current as { code?: unknown; cause?: unknown };
|
|
251
|
+
code = candidate.code;
|
|
252
|
+
cause = candidate.cause;
|
|
253
|
+
} catch {
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
if (!diagnostics.sqlState && isRuntimeSheetSqlState(code))
|
|
257
|
+
diagnostics.sqlState = code;
|
|
258
|
+
if (!diagnostics.transportCode && isRuntimeSheetTransportCode(code))
|
|
259
|
+
diagnostics.transportCode = code;
|
|
260
|
+
current = cause;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return diagnostics;
|
|
264
|
+
}
|
|
265
|
+
|
|
207
266
|
export function receiptGatewayFailureResponse(
|
|
208
267
|
error: unknown,
|
|
209
268
|
context: RuntimeGatewayFailureContext = {},
|
|
@@ -296,6 +355,10 @@ export function receiptGatewayFailureResponse(
|
|
|
296
355
|
redactLedgerString(error instanceof Error ? error.message : error) ??
|
|
297
356
|
'Unknown runtime gateway failure.';
|
|
298
357
|
const headerDetail = detail.replace(/[\r\n]+/g, ' ').slice(0, 500);
|
|
358
|
+
const persistenceDiagnostics =
|
|
359
|
+
context.operation === 'runtime_sheet'
|
|
360
|
+
? runtimeSheetPersistenceDiagnostics(error)
|
|
361
|
+
: {};
|
|
299
362
|
const unavailableDetail = transientServiceUnavailableDetail(error);
|
|
300
363
|
if (unavailableDetail) {
|
|
301
364
|
return receiptGatewayJsonResponse(
|
|
@@ -349,6 +412,15 @@ export function receiptGatewayFailureResponse(
|
|
|
349
412
|
headers: {
|
|
350
413
|
'x-deepline-error-code': failure.code,
|
|
351
414
|
'x-deepline-error-detail': headerDetail,
|
|
415
|
+
...(persistenceDiagnostics.sqlState
|
|
416
|
+
? { 'x-deepline-error-sqlstate': persistenceDiagnostics.sqlState }
|
|
417
|
+
: {}),
|
|
418
|
+
...(persistenceDiagnostics.transportCode
|
|
419
|
+
? {
|
|
420
|
+
'x-deepline-error-transport-code':
|
|
421
|
+
persistenceDiagnostics.transportCode,
|
|
422
|
+
}
|
|
423
|
+
: {}),
|
|
352
424
|
},
|
|
353
425
|
},
|
|
354
426
|
);
|
|
@@ -278,8 +278,44 @@ export type ToolExecuteHttpFailureOutcome = ToolExecuteHttpRetryDecision & {
|
|
|
278
278
|
chargeRetryBudget: boolean;
|
|
279
279
|
/** The response proves the provider request was never dispatched. */
|
|
280
280
|
knownNotDispatched: boolean;
|
|
281
|
+
/** The response proves this attempt's billing reservation was released. */
|
|
282
|
+
billingReservationReleased: boolean;
|
|
281
283
|
};
|
|
282
284
|
|
|
285
|
+
/**
|
|
286
|
+
* The billing identity a retry must use instead of its current one, or null to
|
|
287
|
+
* keep it. Admission never reopens a released reservation, so each renewal
|
|
288
|
+
* follows a refusal that released one. Invocation and provider-operation
|
|
289
|
+
* identities never change here; ambiguous deliveries keep their identity.
|
|
290
|
+
*/
|
|
291
|
+
export function toolExecuteBillingRetryIdentity(input: {
|
|
292
|
+
failure: Pick<
|
|
293
|
+
ToolExecuteHttpFailureOutcome,
|
|
294
|
+
| 'reason'
|
|
295
|
+
| 'backpressureDelayMs'
|
|
296
|
+
| 'knownNotDispatched'
|
|
297
|
+
| 'billingReservationReleased'
|
|
298
|
+
>;
|
|
299
|
+
executionFenced: boolean;
|
|
300
|
+
httpFailureAttempt: number;
|
|
301
|
+
invocationAttempt: number;
|
|
302
|
+
}): string | null {
|
|
303
|
+
const { failure } = input;
|
|
304
|
+
// App pacing does not advance the invocation attempt, so it counts failures.
|
|
305
|
+
if (failure.reason === 'provider_pacing_wait') {
|
|
306
|
+
return `app-pacing-refusal:${input.httpFailureAttempt}`;
|
|
307
|
+
}
|
|
308
|
+
if (input.executionFenced) {
|
|
309
|
+
return failure.billingReservationReleased
|
|
310
|
+
? `transient-retry:${input.httpFailureAttempt}`
|
|
311
|
+
: null;
|
|
312
|
+
}
|
|
313
|
+
return failure.backpressureDelayMs !== null ||
|
|
314
|
+
(failure.reason === 'rate_limit' && failure.knownNotDispatched)
|
|
315
|
+
? `provider-rate-limit-retry:${input.invocationAttempt}`
|
|
316
|
+
: null;
|
|
317
|
+
}
|
|
318
|
+
|
|
283
319
|
export type ToolExecuteHttpFailureAttemptTracker = {
|
|
284
320
|
next(input: {
|
|
285
321
|
toolId: string;
|
|
@@ -804,11 +840,13 @@ export function classifyToolExecuteHttpFailure(input: {
|
|
|
804
840
|
// 429; ordinary pacing denials retain their established retry semantics.
|
|
805
841
|
const failureBody = parseJsonObject(input.bodyText);
|
|
806
842
|
const flatPublicDetails = failureBody?.details;
|
|
843
|
+
const providerOriginFailure =
|
|
844
|
+
error instanceof ToolExecutionError
|
|
845
|
+
? error.origin === 'provider'
|
|
846
|
+
: failureBody?.failure_origin === 'provider';
|
|
807
847
|
const acceptedOperationNeedsRecovery =
|
|
808
848
|
explicitRetryable === false &&
|
|
809
|
-
|
|
810
|
-
? error.origin === 'provider'
|
|
811
|
-
: failureBody?.failure_origin === 'provider') &&
|
|
849
|
+
providerOriginFailure &&
|
|
812
850
|
((error instanceof ToolExecutionError &&
|
|
813
851
|
error.publicDetails?.operationAccepted === true) ||
|
|
814
852
|
(flatPublicDetails !== null &&
|
|
@@ -910,6 +948,16 @@ export function classifyToolExecuteHttpFailure(input: {
|
|
|
910
948
|
retryDecision.reason !== 'concurrency_backpressure' &&
|
|
911
949
|
retryDecision.reason !== 'runtime_scheduler_capacity' &&
|
|
912
950
|
retryDecision.reason !== 'provider_pacing_wait',
|
|
951
|
+
// The app reported a provider failure and asked for a retry, so it has
|
|
952
|
+
// already released that attempt's reservation, and admission never reopens
|
|
953
|
+
// one. BILLING_UNAVAILABLE may follow an authorization whose response was
|
|
954
|
+
// lost, and an edge failure or unexplained 5xx proves nothing: all three
|
|
955
|
+
// keep their identity so a retry recovers the existing reservation.
|
|
956
|
+
billingReservationReleased:
|
|
957
|
+
shouldRetry &&
|
|
958
|
+
retryDecision.reason === 'retry_safe_transient_5xx' &&
|
|
959
|
+
explicitRetryable === true &&
|
|
960
|
+
providerOriginFailure,
|
|
913
961
|
// Only explicit pre-dispatch refusals permit automatic replay of an
|
|
914
962
|
// operation that does not declare ordinary transient retry safety.
|
|
915
963
|
knownNotDispatched:
|
|
@@ -323,7 +323,11 @@ function formatHardBillingFailureMessage(input: {
|
|
|
323
323
|
getStringField(input.billing, 'message') ??
|
|
324
324
|
getStringField(input.billing, 'error') ??
|
|
325
325
|
'Deepline billing cap exceeded.';
|
|
326
|
-
|
|
326
|
+
// A closed reservation is not a spending limit; the customer has nothing to raise.
|
|
327
|
+
const headline =
|
|
328
|
+
code === 'BILLING_RESERVATION_NOT_OPEN'
|
|
329
|
+
? 'Deepline billing reservation closed.'
|
|
330
|
+
: 'Deepline billing cap exceeded.';
|
|
327
331
|
return `tool ${input.toolId} ${input.status} attempt ${input.attempt}/${input.maxAttempts}: ${headline} Run halted before marking remaining rows processed. ${code ? `code=${code}. ` : ''}${message}`;
|
|
328
332
|
}
|
|
329
333
|
|
|
@@ -13,13 +13,13 @@ import {
|
|
|
13
13
|
reportSetupCompleted,
|
|
14
14
|
resolvePendingAuthClaimForResume,
|
|
15
15
|
statusBannerLine
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-MEAIOXJL.mjs";
|
|
17
|
+
import "./chunk-QAJAJPKK.mjs";
|
|
18
|
+
import "./chunk-RY4IVOU3.mjs";
|
|
19
19
|
import "./chunk-4QF2K7TM.mjs";
|
|
20
20
|
import "./chunk-DLIRSHV6.mjs";
|
|
21
21
|
import "./chunk-HBL4PM5Q.mjs";
|
|
22
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-T3MVIPHG.mjs";
|
|
23
23
|
import "./chunk-WZYKRD7T.mjs";
|
|
24
24
|
import "./chunk-KRD6H754.mjs";
|
|
25
25
|
export {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
var _chunkFCAZQ7WVjs = require('./chunk-FCAZQ7WV.js');
|
|
17
|
+
require('./chunk-5MDIZX7M.js');
|
|
18
|
+
require('./chunk-YQDUODZW.js');
|
|
19
|
+
require('./chunk-ALJJRZNJ.js');
|
|
20
|
+
require('./chunk-XNYIZMNQ.js');
|
|
21
|
+
require('./chunk-DIAWYWT5.js');
|
|
22
|
+
require('./chunk-5FDKJQZE.js');
|
|
23
|
+
require('./chunk-OG64RBAC.js');
|
|
24
|
+
require('./chunk-COGTRVWW.js');
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
exports.EXIT_WORKSPACE_MISMATCH = _chunkFCAZQ7WVjs.EXIT_WORKSPACE_MISMATCH; exports.authStatusLine = _chunkFCAZQ7WVjs.authStatusLine; exports.clearPendingClaim = _chunkFCAZQ7WVjs.clearPendingClaim; exports.clearSatisfiedPendingClaim = _chunkFCAZQ7WVjs.clearSatisfiedPendingClaim; exports.handleRegister = _chunkFCAZQ7WVjs.handleRegister; exports.handleStatus = _chunkFCAZQ7WVjs.handleStatus; exports.handleWait = _chunkFCAZQ7WVjs.handleWait; exports.httpJson = _chunkFCAZQ7WVjs.httpJson; exports.readPendingAuthClaim = _chunkFCAZQ7WVjs.readPendingAuthClaim; exports.readStatusBanner = _chunkFCAZQ7WVjs.readStatusBanner; exports.registerAuthCommands = _chunkFCAZQ7WVjs.registerAuthCommands; exports.reportSetupCompleted = _chunkFCAZQ7WVjs.reportSetupCompleted; exports.resolvePendingAuthClaimForResume = _chunkFCAZQ7WVjs.resolvePendingAuthClaimForResume; exports.statusBannerLine = _chunkFCAZQ7WVjs.statusBannerLine;
|