deepline 0.3.434 → 0.3.435
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 +32 -3
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-dead-letter.ts +7 -0
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +18 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +9 -119
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-tool-hooks.ts +155 -0
- package/dist/bundling-sources/shared_libs/product-notifications/slack-delivery.ts +32 -3
- package/dist/bundling-sources/shared_libs/product-notifications/slack-transport.ts +2 -0
- package/dist/cli/{auth-ZWASM3JJ.mjs → auth-EQ3MPGNF.mjs} +4 -4
- package/dist/cli/auth-N3273IA5.js +40 -0
- package/dist/cli/{billing-SQI72SQI.js → billing-23HTLBTU.js} +73 -73
- package/dist/cli/{billing-BICK6R5J.mjs → billing-AZXP6FQ6.mjs} +4 -4
- package/dist/cli/{chunk-E5HBBE7F.js → chunk-26X3B5SV.js} +16 -16
- package/dist/cli/{chunk-6AOEQVTN.js → chunk-2CM22MQI.js} +50 -50
- package/dist/cli/{chunk-NIRI3ILU.mjs → chunk-5WJ4K7ZJ.mjs} +1 -1
- package/dist/cli/{chunk-K324EUI2.mjs → chunk-6R6BUVOX.mjs} +8 -8
- package/dist/cli/{chunk-ISU67CJA.mjs → chunk-7JZD5E5E.mjs} +3 -3
- package/dist/cli/{chunk-KPPCM62O.js → chunk-B6ZCP3Z5.js} +6 -6
- package/dist/cli/{chunk-NP5HEQAW.mjs → chunk-BFYSJUB7.mjs} +2 -2
- package/dist/cli/{chunk-6ZGPHO5R.js → chunk-CF4T46L6.js} +1 -1
- package/dist/cli/{chunk-Q7IWP5UM.js → chunk-CTDN4FZR.js} +2 -2
- package/dist/cli/{chunk-KXB5UAFH.js → chunk-DCSRQRUL.js} +2 -2
- package/dist/cli/{chunk-ISUKMN5B.mjs → chunk-DOWK7NOY.mjs} +1 -1
- package/dist/cli/{chunk-QY2DYCUJ.mjs → chunk-EW5TD772.mjs} +2 -2
- package/dist/cli/{chunk-GDIZKSKB.mjs → chunk-HBZWT2US.mjs} +2 -2
- package/dist/cli/{chunk-KHR6V4CE.mjs → chunk-HHJYD3PC.mjs} +1 -1
- package/dist/cli/{chunk-GVMQS6G7.js → chunk-HN6WJC4Y.js} +10 -10
- package/dist/cli/{chunk-A4RM6SQK.mjs → chunk-HR7TOTM7.mjs} +1 -1
- package/dist/cli/{chunk-VFNLUKRT.mjs → chunk-IIW7JOKQ.mjs} +4 -4
- package/dist/cli/{chunk-EAZGVI2H.js → chunk-KDTYSHTE.js} +8 -8
- package/dist/cli/{chunk-NLD7TUJ6.js → chunk-KSXYGT6J.js} +8 -8
- package/dist/cli/{chunk-WB7HZOGR.mjs → chunk-LQTNFYOL.mjs} +2 -2
- package/dist/cli/{chunk-NBZGQRBQ.mjs → chunk-PBK2HVL5.mjs} +3 -3
- package/dist/cli/{chunk-FECJ5LBK.js → chunk-PKHERMMF.js} +52 -52
- package/dist/cli/{chunk-OLWNESMO.js → chunk-PSOCBKRK.js} +35 -35
- package/dist/cli/{chunk-EEQEQRTO.js → chunk-R2DKLSIE.js} +4 -4
- package/dist/cli/{chunk-6P3SCJZA.mjs → chunk-R4KGIU4P.mjs} +1 -1
- package/dist/cli/{chunk-S57PLAGM.mjs → chunk-TXG7K6OK.mjs} +1 -1
- package/dist/cli/{chunk-XVDYAJ4B.js → chunk-UDWRO43L.js} +79 -79
- package/dist/cli/{chunk-CYJJUUIT.mjs → chunk-UFXJB5VM.mjs} +5 -5
- package/dist/cli/{chunk-TFOUACKF.js → chunk-V5S5JGXE.js} +20 -20
- package/dist/cli/{chunk-SVRL42S7.js → chunk-VZOIX2SU.js} +26 -26
- package/dist/cli/{chunk-XZBBTLIL.js → chunk-X3GM2FO2.js} +6 -6
- package/dist/cli/{chunk-HMJS4EP4.mjs → chunk-X7L2ICG7.mjs} +3 -3
- package/dist/cli/{csv-JDI6IB23.js → csv-CHD4AORD.js} +12 -12
- package/dist/cli/{csv-4VNH4CNZ.mjs → csv-RBYDE2VF.mjs} +3 -3
- package/dist/cli/{db-RIXQ4WX5.js → db-G66I35IX.js} +25 -25
- package/dist/cli/{db-2BT7CMVU.mjs → db-PEAA46HL.mjs} +4 -4
- package/dist/cli/{describe-ODFGJI7Q.js → describe-N3WGB4RU.js} +16 -16
- package/dist/cli/{describe-SF4TKH2Y.mjs → describe-YAAQ22BK.mjs} +12 -12
- package/dist/cli/{executions-DNPJRBW2.mjs → executions-NFYYKOQ4.mjs} +4 -4
- package/dist/cli/{executions-HZTV7BRI.js → executions-XL3VMVUS.js} +6 -6
- package/dist/cli/{feedback-OBODUERI.js → feedback-KZ6SBLG6.js} +7 -7
- package/dist/cli/{feedback-SK5AKR7W.mjs → feedback-PUTCVMTD.mjs} +3 -3
- package/dist/cli/git-QTHF7KRA.js +24 -0
- package/dist/cli/{git-7IE5J53C.mjs → git-UU3XVCT4.mjs} +4 -4
- package/dist/cli/index.js +131 -131
- package/dist/cli/index.mjs +36 -36
- package/dist/cli/{legacy-noops-UIQWCOGF.mjs → legacy-noops-BOGHHXVF.mjs} +4 -4
- package/dist/cli/{legacy-noops-CVHQS2Z4.js → legacy-noops-FZSGPSPI.js} +7 -7
- package/dist/cli/{monitors-37W655H5.js → monitors-BDUIUKJJ.js} +84 -84
- package/dist/cli/{monitors-47U23SEH.mjs → monitors-XUSIJAQS.mjs} +4 -4
- package/dist/cli/{org-AS7BDCF2.js → org-4M4LF366.js} +64 -64
- package/dist/cli/{org-Z3WRCPPN.mjs → org-YKDMSVRT.mjs} +4 -4
- package/dist/cli/{play-CQNGRFJX.mjs → play-CLGVNXQW.mjs} +10 -10
- package/dist/cli/{play-IDRYO2XG.js → play-XYAA5UC5.js} +283 -283
- package/dist/cli/{providers-LXH4JT4W.js → providers-HS2JM5MQ.js} +7 -7
- package/dist/cli/{providers-XFGJTDA2.mjs → providers-MFI6MK72.mjs} +4 -4
- package/dist/cli/{quickstart-AFPLY6AL.js → quickstart-BHNM5TQN.js} +5 -5
- package/dist/cli/{quickstart-I34EZG6K.mjs → quickstart-CWUBSTJ2.mjs} +3 -3
- package/dist/cli/search-MN7DAPYR.js +30 -0
- package/dist/cli/{search-GV3H73R7.mjs → search-VK6EN3BR.mjs} +5 -5
- package/dist/cli/{secrets-Z2RLL7MD.mjs → secrets-GPRZ4XF5.mjs} +4 -4
- package/dist/cli/{secrets-ADPINHAV.js → secrets-HJ3HW5TQ.js} +13 -13
- package/dist/cli/{sessions-H7QVYCTY.mjs → sessions-NN4AJLGF.mjs} +4 -4
- package/dist/cli/{sessions-A635YVAT.js → sessions-XJYXZKFA.js} +5 -5
- package/dist/cli/{settings-G6FM442W.js → settings-3Y4FZRE6.js} +75 -75
- package/dist/cli/{settings-LUYTVWTR.mjs → settings-ADLQGWTJ.mjs} +8 -8
- package/dist/cli/{setup-7Y3JAMBT.js → setup-DR2F5EHD.js} +42 -42
- package/dist/cli/{setup-EPRBDJXZ.mjs → setup-PJUA2JPA.mjs} +7 -7
- package/dist/cli/skills-AF3OYN25.js +29 -0
- package/dist/cli/{skills-2SNUHQC7.mjs → skills-YYLZ6ZCQ.mjs} +5 -5
- package/dist/cli/tools-3XW4TJBV.js +44 -0
- package/dist/cli/{tools-PJPLF63I.mjs → tools-GIVNDAF4.mjs} +12 -12
- package/dist/cli/update-2WLAPOXT.js +31 -0
- package/dist/cli/{update-JP7BOOIZ.mjs → update-IZO6EDLX.mjs} +7 -7
- package/dist/cli/{workflow-42ISZKK5.mjs → workflow-FO67TXGC.mjs} +5 -5
- package/dist/cli/{workflow-L33RGJ4A.js → workflow-O4TG6Q3C.js} +15 -15
- package/dist/index.js +6 -6
- package/dist/index.mjs +3 -3
- package/dist/install-integrity.json +79 -78
- 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-KFYDF5TS.js +0 -40
- package/dist/cli/git-WMBBN7S7.js +0 -24
- package/dist/cli/search-HBEAM36R.js +0 -30
- package/dist/cli/skills-GV2L7QWT.js +0 -29
- package/dist/cli/tools-PXECTR3C.js +0 -44
- package/dist/cli/update-LKVWKWIV.js +0 -31
|
@@ -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.435',
|
|
209
209
|
updateSummary: {
|
|
210
210
|
introducedIn: '0.3.90',
|
|
211
211
|
summary:
|
|
@@ -457,6 +457,35 @@ export function monitorBillingStateForSuspension(input: {
|
|
|
457
457
|
};
|
|
458
458
|
}
|
|
459
459
|
|
|
460
|
+
/**
|
|
461
|
+
* Deepline's org-wide billing pause of a direct monitor whose slot-month was
|
|
462
|
+
* already paid (an exhausted wallet, a cap, an archive). Like
|
|
463
|
+
* `monitorBillingStateForDisabled`, the paid-through anchor survives: the
|
|
464
|
+
* revival re-create reads it through `readPreviousMonitorBillingState`, and
|
|
465
|
+
* without it the month was charged a second time. Renewals still stop,
|
|
466
|
+
* because they range on active rows and the caller clears the index fields.
|
|
467
|
+
* A renewal whose own charge failed collected nothing and keeps using
|
|
468
|
+
* `monitorBillingStateForSuspension`.
|
|
469
|
+
*/
|
|
470
|
+
export function monitorBillingStateForDirectBillingSuspension(input: {
|
|
471
|
+
previous?: StoredMonitorBillingState | null;
|
|
472
|
+
reason: string;
|
|
473
|
+
error?: string;
|
|
474
|
+
disablePending?: boolean;
|
|
475
|
+
}): StoredMonitorBillingState {
|
|
476
|
+
return {
|
|
477
|
+
...monitorBillingStateForSuspension(input),
|
|
478
|
+
next_renewal_at: input.previous?.next_renewal_at ?? null,
|
|
479
|
+
provider_next_charge_at: input.previous?.provider_next_charge_at ?? null,
|
|
480
|
+
cancel_before_at: input.previous?.cancel_before_at ?? null,
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Billing cleanup's upstream delete failed. The paid-through dates are the
|
|
486
|
+
* ones the suspension that started cleanup already chose: a direct billing
|
|
487
|
+
* pause keeps them, a failed renewal or settle has nulled them.
|
|
488
|
+
*/
|
|
460
489
|
export function monitorBillingStateForUpstreamDisableFailed(input: {
|
|
461
490
|
previous?: StoredMonitorBillingState | null;
|
|
462
491
|
error: string;
|
|
@@ -468,9 +497,9 @@ export function monitorBillingStateForUpstreamDisableFailed(input: {
|
|
|
468
497
|
reactivation_required: true,
|
|
469
498
|
suspension_reason: 'billing_failure_upstream_disable_failed',
|
|
470
499
|
last_billing_error: input.error,
|
|
471
|
-
next_renewal_at: null,
|
|
472
|
-
provider_next_charge_at: null,
|
|
473
|
-
cancel_before_at: null,
|
|
500
|
+
next_renewal_at: input.previous?.next_renewal_at ?? null,
|
|
501
|
+
provider_next_charge_at: input.previous?.provider_next_charge_at ?? null,
|
|
502
|
+
cancel_before_at: input.previous?.cancel_before_at ?? null,
|
|
474
503
|
};
|
|
475
504
|
}
|
|
476
505
|
|
|
@@ -64,6 +64,9 @@ export function classifyInboundFailure(error: unknown): InboundFailureClass {
|
|
|
64
64
|
'08003', // connection does not exist
|
|
65
65
|
'08006', // connection failure
|
|
66
66
|
'53300', // too many connections
|
|
67
|
+
'40001', // serialization failure
|
|
68
|
+
'40P01', // deadlock detected
|
|
69
|
+
'55P03', // lock not available (a lock_timeout expired)
|
|
67
70
|
]);
|
|
68
71
|
if (code && transientCodes.has(code)) return 'transient';
|
|
69
72
|
|
|
@@ -81,6 +84,10 @@ export function classifyInboundFailure(error: unknown): InboundFailureClass {
|
|
|
81
84
|
/convex.*(?:unavailable|timeout|network)/i,
|
|
82
85
|
/fetch failed/i,
|
|
83
86
|
/socket hang up/i,
|
|
87
|
+
// A concurrent catalog change on the tenant table (grant, column add,
|
|
88
|
+
// dynamic promotion). Raised as XX000, so it is matched by message, as in
|
|
89
|
+
// connection-uris.ts and runtime-sheet-data-plane-readiness.ts.
|
|
90
|
+
/tuple concurrently updated|could not serialize access|deadlock detected/i,
|
|
84
91
|
];
|
|
85
92
|
if (transientPatterns.some((pattern) => pattern.test(message))) {
|
|
86
93
|
return 'transient';
|
|
@@ -747,6 +747,24 @@
|
|
|
747
747
|
"failureAlert": "vercel_route_wrapper",
|
|
748
748
|
"domainReportRequired": true
|
|
749
749
|
},
|
|
750
|
+
{
|
|
751
|
+
"id": "vercel.monitor-delivery-canary",
|
|
752
|
+
"name": "TamRadar monitor delivery canary",
|
|
753
|
+
"scheduler": "vercel_cron",
|
|
754
|
+
"cadence": "*/30 * * * *",
|
|
755
|
+
"timezone": "UTC",
|
|
756
|
+
"source": "apps/deepline-api/vercel.json",
|
|
757
|
+
"locator": "/api/v2/cron/monitor-delivery-canary",
|
|
758
|
+
"owner": "monitors",
|
|
759
|
+
"criticality": "critical",
|
|
760
|
+
"purpose": "Send one synthetic TamRadar job-opening finding to the internal canary monitor's own callback route so the deepline-monitor-delivery-heartbeat Play can prove receiver, queue, typed write and Play dispatch end to end.",
|
|
761
|
+
"successDefinition": "The canary monitor's binding is read from Convex and its callback route acknowledges this slot's synthetic finding with a 2xx.",
|
|
762
|
+
"failureDefinition": "The canary monitor is missing, inactive or mis-bound, or its callback route returns a non-2xx response or times out.",
|
|
763
|
+
"startGraceMs": 300000,
|
|
764
|
+
"runTimeoutMs": 60000,
|
|
765
|
+
"failureAlert": "vercel_route_wrapper",
|
|
766
|
+
"domainReportRequired": true
|
|
767
|
+
},
|
|
750
768
|
{
|
|
751
769
|
"id": "vercel.public-tool-execution-blob-cleanup",
|
|
752
770
|
"name": "Public tool execution blob cleanup",
|
|
@@ -25,7 +25,6 @@ import {
|
|
|
25
25
|
iteratePlayDatasetInputPages,
|
|
26
26
|
type PlayDataset,
|
|
27
27
|
} from '../../plays/dataset';
|
|
28
|
-
import type { PlayQueueHint } from '../governor/rate-state-backend';
|
|
29
28
|
import { AppRuntimeRateStateBackend } from '../governor/app-runtime-rate-state-backend';
|
|
30
29
|
import { AppRuntimeBudgetStateBackend } from '../governor/app-runtime-budget-state-backend';
|
|
31
30
|
import {
|
|
@@ -90,8 +89,10 @@ import {
|
|
|
90
89
|
type PlayRunnerTerminalTransportEvent,
|
|
91
90
|
} from './runtime-terminal-push';
|
|
92
91
|
import { vercelProtectionBypassHeader } from '../vercel-protection';
|
|
93
|
-
import {
|
|
94
|
-
|
|
92
|
+
import {
|
|
93
|
+
createRuntimeToolHooks,
|
|
94
|
+
type RuntimeToolMetadata,
|
|
95
|
+
} from './runtime-tool-hooks';
|
|
95
96
|
import type {
|
|
96
97
|
ContextOptions,
|
|
97
98
|
RuntimeSheetDatasetPageReaderScope,
|
|
@@ -227,7 +228,6 @@ import {
|
|
|
227
228
|
sqlSafePlayColumnName,
|
|
228
229
|
type PlaySheetContract,
|
|
229
230
|
} from '../../plays/static-pipeline';
|
|
230
|
-
import { isIntegrationEventWaitToolId } from '../event-wait-tools';
|
|
231
231
|
import { type PlayBundleArtifact } from '../../plays/artifact-types';
|
|
232
232
|
import {
|
|
233
233
|
RuntimeReceiptStoreAdapter,
|
|
@@ -356,32 +356,6 @@ export function playRunnerReceiptStoreAdapterOptions() {
|
|
|
356
356
|
// co-located receipt gateway. There is no host-injected or app-runtime path.
|
|
357
357
|
type RuntimeStepReceiptHandlers = RuntimeReceiptStoreHandlers;
|
|
358
358
|
|
|
359
|
-
type RuntimeToolMetadata = {
|
|
360
|
-
reusableResult?: { supported: boolean; unavailableReason: string | null };
|
|
361
|
-
provider?: string | null;
|
|
362
|
-
operation?: string | null;
|
|
363
|
-
extractors?: ToolResultMetadataInput['extractors'];
|
|
364
|
-
actionCacheVersion: string;
|
|
365
|
-
actionCacheReadVersions?: string[];
|
|
366
|
-
queueHints?: unknown;
|
|
367
|
-
retry?: {
|
|
368
|
-
idempotencyScope?: 'invocation';
|
|
369
|
-
retrySafeTransientHttp?: boolean;
|
|
370
|
-
requiresExecutionFence?: boolean;
|
|
371
|
-
};
|
|
372
|
-
targetGetters?: Record<string, string[]>;
|
|
373
|
-
listExtractorPaths?: string[];
|
|
374
|
-
listExtractorAliases?: ToolResultMetadataInput['listExtractorAliases'];
|
|
375
|
-
listIdentityGetters?: Record<string, string[]>;
|
|
376
|
-
eventWait?: boolean;
|
|
377
|
-
asyncOperation?:
|
|
378
|
-
| import('../async-operation').AsyncOperationContractWire
|
|
379
|
-
| null;
|
|
380
|
-
asyncOperationPoll?:
|
|
381
|
-
| import('../async-operation').AsyncOperationPollExecution
|
|
382
|
-
| null;
|
|
383
|
-
};
|
|
384
|
-
|
|
385
359
|
type RuntimeToolAuthScope = {
|
|
386
360
|
digest?: unknown;
|
|
387
361
|
managedAsyncExecutionRecovery?: unknown;
|
|
@@ -2489,101 +2463,17 @@ async function run(
|
|
|
2489
2463
|
options,
|
|
2490
2464
|
);
|
|
2491
2465
|
},
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
},
|
|
2498
|
-
getToolProvider: async (toolId) => {
|
|
2499
|
-
const provider = (await getRuntimeToolMetadata(toolId)).provider;
|
|
2500
|
-
return typeof provider === 'string' && provider.trim()
|
|
2501
|
-
? provider.trim()
|
|
2502
|
-
: null;
|
|
2503
|
-
},
|
|
2504
|
-
getToolOperation: async (toolId) => {
|
|
2505
|
-
const operation = (await getRuntimeToolMetadata(toolId)).operation;
|
|
2506
|
-
return typeof operation === 'string' && operation.trim()
|
|
2507
|
-
? operation.trim()
|
|
2508
|
-
: null;
|
|
2509
|
-
},
|
|
2510
|
-
getToolIdempotencyScope: async (toolId) => {
|
|
2511
|
-
const metadata = await getRuntimeToolMetadata(toolId);
|
|
2512
|
-
return metadata.retry?.idempotencyScope === 'invocation'
|
|
2513
|
-
? 'invocation'
|
|
2514
|
-
: null;
|
|
2515
|
-
},
|
|
2516
|
-
getToolReusableResultSupport: async (toolId) => {
|
|
2517
|
-
const support = (await getRuntimeToolMetadata(toolId)).reusableResult;
|
|
2518
|
-
if (!support) {
|
|
2519
|
-
throw new Error(
|
|
2520
|
-
`Tool ${toolId} has no reusable-result capability metadata. Deploy the runtime metadata reader before admitting explicit-freshness artifacts.`,
|
|
2521
|
-
);
|
|
2522
|
-
}
|
|
2523
|
-
return support;
|
|
2524
|
-
},
|
|
2525
|
-
getToolRetryPolicy: async (toolId) => {
|
|
2526
|
-
const metadata = await getRuntimeToolMetadata(toolId);
|
|
2527
|
-
return {
|
|
2528
|
-
retrySafeTransientHttp: metadata.retry?.retrySafeTransientHttp === true,
|
|
2529
|
-
requiresExecutionFence: metadata.retry?.requiresExecutionFence === true,
|
|
2530
|
-
};
|
|
2531
|
-
},
|
|
2532
|
-
getToolActionCacheVersion: async (toolId) => {
|
|
2533
|
-
const metadata = await getRuntimeToolMetadata(toolId);
|
|
2534
|
-
const version = metadata.actionCacheVersion.trim();
|
|
2535
|
-
if (!version) {
|
|
2536
|
-
throw new Error(
|
|
2537
|
-
`Runtime metadata for ${toolId} is missing actionCacheVersion.`,
|
|
2538
|
-
);
|
|
2539
|
-
}
|
|
2540
|
-
return version;
|
|
2541
|
-
},
|
|
2542
|
-
getToolActionCacheReadVersions: async (toolId) => {
|
|
2543
|
-
const metadata = await getRuntimeToolMetadata(toolId);
|
|
2544
|
-
return [
|
|
2545
|
-
...new Set(
|
|
2546
|
-
(metadata.actionCacheReadVersions ?? [])
|
|
2547
|
-
.map((version) => String(version || '').trim())
|
|
2548
|
-
.filter(Boolean),
|
|
2549
|
-
),
|
|
2550
|
-
];
|
|
2551
|
-
},
|
|
2466
|
+
...createRuntimeToolHooks({
|
|
2467
|
+
getRuntimeToolMetadata,
|
|
2468
|
+
createEventWaitHandler: (toolId) =>
|
|
2469
|
+
createRuntimeEventWaitHandler(config, toolId),
|
|
2470
|
+
}),
|
|
2552
2471
|
getToolAuthScopeDigest: getRuntimeToolAuthScopeDigest,
|
|
2553
2472
|
getToolAsyncExecutionRecovery:
|
|
2554
2473
|
getRuntimeToolAuthScopeDigest.asyncExecutionRecovery,
|
|
2555
2474
|
getToolRateScope: getRuntimeToolAuthScopeDigest.rateScope,
|
|
2556
2475
|
invalidateToolAuthScopeDigest: (toolId) =>
|
|
2557
2476
|
getRuntimeToolAuthScopeDigest.invalidate?.(toolId),
|
|
2558
|
-
getToolTargetGetters: async (toolId, output) => {
|
|
2559
|
-
const metadata = await getRuntimeToolMetadata(toolId);
|
|
2560
|
-
return metadata.targetGetters?.[output] ?? [];
|
|
2561
|
-
},
|
|
2562
|
-
getToolResultMetadata: async (toolId) => {
|
|
2563
|
-
const metadata = await getRuntimeToolMetadata(toolId);
|
|
2564
|
-
return {
|
|
2565
|
-
toolId,
|
|
2566
|
-
extractors: metadata.extractors ?? {},
|
|
2567
|
-
targetGetters: metadata.targetGetters ?? {},
|
|
2568
|
-
listExtractorPaths: metadata.listExtractorPaths ?? [],
|
|
2569
|
-
listExtractorAliases: metadata.listExtractorAliases,
|
|
2570
|
-
listIdentityGetters: metadata.listIdentityGetters ?? {},
|
|
2571
|
-
};
|
|
2572
|
-
},
|
|
2573
|
-
getToolAsyncOperation: async (toolId) =>
|
|
2574
|
-
(await getRuntimeToolMetadata(toolId)).asyncOperation ?? null,
|
|
2575
|
-
getToolAsyncOperationPoll: async (toolId) =>
|
|
2576
|
-
(await getRuntimeToolMetadata(toolId)).asyncOperationPoll ?? null,
|
|
2577
|
-
getBatchOperationStrategy: (toolId) => getPlayRuntimeBatchStrategy(toolId),
|
|
2578
|
-
getIntegrationEventWaitHandler: async (toolId) => {
|
|
2579
|
-
if (isIntegrationEventWaitToolId(toolId)) {
|
|
2580
|
-
return createRuntimeEventWaitHandler(config, toolId);
|
|
2581
|
-
}
|
|
2582
|
-
const metadata = await getRuntimeToolMetadata(toolId);
|
|
2583
|
-
return metadata.eventWait
|
|
2584
|
-
? createRuntimeEventWaitHandler(config, toolId)
|
|
2585
|
-
: null;
|
|
2586
|
-
},
|
|
2587
2477
|
onRowUpdate: (() => {
|
|
2588
2478
|
let rowUpdateCount = 0;
|
|
2589
2479
|
let lastEmitAt = 0;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import type { ContextOptions, IntegrationEventWaitHandler } from '../ctx-types';
|
|
2
|
+
import { isIntegrationEventWaitToolId } from '../event-wait-tools';
|
|
3
|
+
import type { PlayQueueHint } from '../governor/rate-state-backend';
|
|
4
|
+
import { getPlayRuntimeBatchStrategy } from '../play-runtime-batching-registry';
|
|
5
|
+
import type { ToolResultMetadataInput } from '../tool-result';
|
|
6
|
+
|
|
7
|
+
/** The app's runtime tool metadata as the runner receives it over HTTP. */
|
|
8
|
+
export type RuntimeToolMetadata = {
|
|
9
|
+
reusableResult?: { supported: boolean; unavailableReason: string | null };
|
|
10
|
+
provider?: string | null;
|
|
11
|
+
operation?: string | null;
|
|
12
|
+
extractors?: ToolResultMetadataInput['extractors'];
|
|
13
|
+
actionCacheVersion: string;
|
|
14
|
+
actionCacheReadVersions?: string[];
|
|
15
|
+
queueHints?: unknown;
|
|
16
|
+
retry?: {
|
|
17
|
+
idempotencyScope?: 'invocation';
|
|
18
|
+
retrySafeTransientHttp?: boolean;
|
|
19
|
+
requiresExecutionFence?: boolean;
|
|
20
|
+
};
|
|
21
|
+
targetGetters?: Record<string, string[]>;
|
|
22
|
+
listExtractorPaths?: string[];
|
|
23
|
+
listExtractorAliases?: ToolResultMetadataInput['listExtractorAliases'];
|
|
24
|
+
listIdentityGetters?: Record<string, string[]>;
|
|
25
|
+
eventWait?: boolean;
|
|
26
|
+
asyncOperation?:
|
|
27
|
+
| import('../async-operation').AsyncOperationContractWire
|
|
28
|
+
| null;
|
|
29
|
+
asyncOperationPoll?:
|
|
30
|
+
| import('../async-operation').AsyncOperationPollExecution
|
|
31
|
+
| null;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type RuntimeToolHooks = Required<
|
|
35
|
+
Pick<
|
|
36
|
+
ContextOptions,
|
|
37
|
+
| 'getToolQueueHints'
|
|
38
|
+
| 'getToolProvider'
|
|
39
|
+
| 'getToolOperation'
|
|
40
|
+
| 'getToolIdempotencyScope'
|
|
41
|
+
| 'getToolReusableResultSupport'
|
|
42
|
+
| 'getToolRetryPolicy'
|
|
43
|
+
| 'getToolActionCacheVersion'
|
|
44
|
+
| 'getToolActionCacheReadVersions'
|
|
45
|
+
| 'getToolTargetGetters'
|
|
46
|
+
| 'getToolResultMetadata'
|
|
47
|
+
| 'getToolAsyncOperation'
|
|
48
|
+
| 'getToolAsyncOperationPoll'
|
|
49
|
+
| 'getBatchOperationStrategy'
|
|
50
|
+
| 'getIntegrationEventWaitHandler'
|
|
51
|
+
>
|
|
52
|
+
>;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Every tool-policy decision the Play runner makes from tool metadata. The
|
|
56
|
+
* runner and in-process tests both build their context from this, so a test
|
|
57
|
+
* swaps only where metadata and event-wait effects come from, never a policy.
|
|
58
|
+
*/
|
|
59
|
+
export function createRuntimeToolHooks(input: {
|
|
60
|
+
getRuntimeToolMetadata: (toolId: string) => Promise<RuntimeToolMetadata>;
|
|
61
|
+
createEventWaitHandler: (
|
|
62
|
+
toolId: string,
|
|
63
|
+
) => IntegrationEventWaitHandler | null;
|
|
64
|
+
}): RuntimeToolHooks {
|
|
65
|
+
const { getRuntimeToolMetadata, createEventWaitHandler } = input;
|
|
66
|
+
return {
|
|
67
|
+
getToolQueueHints: async (toolId) => {
|
|
68
|
+
const metadata = await getRuntimeToolMetadata(toolId);
|
|
69
|
+
return Array.isArray(metadata.queueHints)
|
|
70
|
+
? (metadata.queueHints as PlayQueueHint[])
|
|
71
|
+
: [];
|
|
72
|
+
},
|
|
73
|
+
getToolProvider: async (toolId) => {
|
|
74
|
+
const provider = (await getRuntimeToolMetadata(toolId)).provider;
|
|
75
|
+
return typeof provider === 'string' && provider.trim()
|
|
76
|
+
? provider.trim()
|
|
77
|
+
: null;
|
|
78
|
+
},
|
|
79
|
+
getToolOperation: async (toolId) => {
|
|
80
|
+
const operation = (await getRuntimeToolMetadata(toolId)).operation;
|
|
81
|
+
return typeof operation === 'string' && operation.trim()
|
|
82
|
+
? operation.trim()
|
|
83
|
+
: null;
|
|
84
|
+
},
|
|
85
|
+
getToolIdempotencyScope: async (toolId) => {
|
|
86
|
+
const metadata = await getRuntimeToolMetadata(toolId);
|
|
87
|
+
return metadata.retry?.idempotencyScope === 'invocation'
|
|
88
|
+
? 'invocation'
|
|
89
|
+
: null;
|
|
90
|
+
},
|
|
91
|
+
getToolReusableResultSupport: async (toolId) => {
|
|
92
|
+
const support = (await getRuntimeToolMetadata(toolId)).reusableResult;
|
|
93
|
+
if (!support) {
|
|
94
|
+
throw new Error(
|
|
95
|
+
`Tool ${toolId} has no reusable-result capability metadata. Deploy the runtime metadata reader before admitting explicit-freshness artifacts.`,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
return support;
|
|
99
|
+
},
|
|
100
|
+
getToolRetryPolicy: async (toolId) => {
|
|
101
|
+
const metadata = await getRuntimeToolMetadata(toolId);
|
|
102
|
+
return {
|
|
103
|
+
retrySafeTransientHttp: metadata.retry?.retrySafeTransientHttp === true,
|
|
104
|
+
requiresExecutionFence: metadata.retry?.requiresExecutionFence === true,
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
getToolActionCacheVersion: async (toolId) => {
|
|
108
|
+
const metadata = await getRuntimeToolMetadata(toolId);
|
|
109
|
+
const version = metadata.actionCacheVersion.trim();
|
|
110
|
+
if (!version) {
|
|
111
|
+
throw new Error(
|
|
112
|
+
`Runtime metadata for ${toolId} is missing actionCacheVersion.`,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
return version;
|
|
116
|
+
},
|
|
117
|
+
getToolActionCacheReadVersions: async (toolId) => {
|
|
118
|
+
const metadata = await getRuntimeToolMetadata(toolId);
|
|
119
|
+
return [
|
|
120
|
+
...new Set(
|
|
121
|
+
(metadata.actionCacheReadVersions ?? [])
|
|
122
|
+
.map((version) => String(version || '').trim())
|
|
123
|
+
.filter(Boolean),
|
|
124
|
+
),
|
|
125
|
+
];
|
|
126
|
+
},
|
|
127
|
+
getToolTargetGetters: async (toolId, output) => {
|
|
128
|
+
const metadata = await getRuntimeToolMetadata(toolId);
|
|
129
|
+
return metadata.targetGetters?.[output] ?? [];
|
|
130
|
+
},
|
|
131
|
+
getToolResultMetadata: async (toolId) => {
|
|
132
|
+
const metadata = await getRuntimeToolMetadata(toolId);
|
|
133
|
+
return {
|
|
134
|
+
toolId,
|
|
135
|
+
extractors: metadata.extractors ?? {},
|
|
136
|
+
targetGetters: metadata.targetGetters ?? {},
|
|
137
|
+
listExtractorPaths: metadata.listExtractorPaths ?? [],
|
|
138
|
+
listExtractorAliases: metadata.listExtractorAliases,
|
|
139
|
+
listIdentityGetters: metadata.listIdentityGetters ?? {},
|
|
140
|
+
};
|
|
141
|
+
},
|
|
142
|
+
getToolAsyncOperation: async (toolId) =>
|
|
143
|
+
(await getRuntimeToolMetadata(toolId)).asyncOperation ?? null,
|
|
144
|
+
getToolAsyncOperationPoll: async (toolId) =>
|
|
145
|
+
(await getRuntimeToolMetadata(toolId)).asyncOperationPoll ?? null,
|
|
146
|
+
getBatchOperationStrategy: (toolId) => getPlayRuntimeBatchStrategy(toolId),
|
|
147
|
+
getIntegrationEventWaitHandler: async (toolId) => {
|
|
148
|
+
if (isIntegrationEventWaitToolId(toolId)) {
|
|
149
|
+
return createEventWaitHandler(toolId);
|
|
150
|
+
}
|
|
151
|
+
const metadata = await getRuntimeToolMetadata(toolId);
|
|
152
|
+
return metadata.eventWait ? createEventWaitHandler(toolId) : null;
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
}
|
|
@@ -25,6 +25,7 @@ export type SlackChannelKey =
|
|
|
25
25
|
| 'python_cli_session'
|
|
26
26
|
| 'monitor_activity'
|
|
27
27
|
| 'monitor_error_activity'
|
|
28
|
+
| 'monitor_cron_failures'
|
|
28
29
|
| 'plain_thread_activity'
|
|
29
30
|
| 'inbound_leads';
|
|
30
31
|
|
|
@@ -85,7 +86,10 @@ const SLACK_MONITOR_ERROR_ACTIVITY_CHANNEL_ID_ENV =
|
|
|
85
86
|
const DEFAULT_PROVIDER_ALERTS_CHANNEL_ID = 'C0B4QRC8NEM';
|
|
86
87
|
const DEFAULT_USER_SIGNUP_CHANNEL_ID = 'C0AGWVD2TNK';
|
|
87
88
|
const DEFAULT_MONITOR_ACTIVITY_CHANNEL_ID = 'C0BDRFY7NE7';
|
|
88
|
-
|
|
89
|
+
// #deepline-monitor-error-activity. Replaces the archived C0BDGCEMLBZ (KAR-49).
|
|
90
|
+
const DEFAULT_MONITOR_ERROR_ACTIVITY_CHANNEL_ID = 'C0CD0JQTU20';
|
|
91
|
+
// #deepline-monitor-cron-failures: failures of scheduled jobs owned by monitors.
|
|
92
|
+
export const MONITOR_CRON_FAILURES_SLACK_CHANNEL_ID = 'C0CCZCKETEV';
|
|
89
93
|
|
|
90
94
|
export const SDK_CLI_ACTIVITY_SLACK_CHANNEL_ID = 'C0B7D7DB40Y';
|
|
91
95
|
export const SDK_CLI_ERRORS_SLACK_CHANNEL_ID = 'C0B6JUJ9QJW';
|
|
@@ -124,6 +128,7 @@ const CHANNEL_ALERT_LEVEL: Record<
|
|
|
124
128
|
python_cli_session: 'info',
|
|
125
129
|
monitor_activity: 'info',
|
|
126
130
|
monitor_error_activity: 'error',
|
|
131
|
+
monitor_cron_failures: 'error',
|
|
127
132
|
plain_thread_activity: 'info',
|
|
128
133
|
inbound_leads: 'info',
|
|
129
134
|
};
|
|
@@ -144,6 +149,8 @@ function getSlackChannelEnvironmentRequirement(
|
|
|
144
149
|
case 'user_signup':
|
|
145
150
|
case 'sdk_cli_activity':
|
|
146
151
|
case 'sdk_cli_errors':
|
|
152
|
+
// Vercel crons run only in production.
|
|
153
|
+
case 'monitor_cron_failures':
|
|
147
154
|
// Preview and local deploys must never page GTM with test submissions.
|
|
148
155
|
case 'inbound_leads':
|
|
149
156
|
return 'prod';
|
|
@@ -200,6 +207,7 @@ function isBotOnlySlackChannel(channel: SlackChannelKey): boolean {
|
|
|
200
207
|
channel === 'user_signup' ||
|
|
201
208
|
channel === 'sdk_cli_activity' ||
|
|
202
209
|
channel === 'sdk_cli_errors' ||
|
|
210
|
+
channel === 'monitor_cron_failures' ||
|
|
203
211
|
channel === 'sdk_cli_feedback' ||
|
|
204
212
|
channel === 'dashboard_feedback' ||
|
|
205
213
|
channel === 'python_cli_feedback' ||
|
|
@@ -264,6 +272,8 @@ function resolveBotChannel(
|
|
|
264
272
|
return { token, channelId: SDK_CLI_ACTIVITY_SLACK_CHANNEL_ID };
|
|
265
273
|
case 'sdk_cli_errors':
|
|
266
274
|
return { token, channelId: SDK_CLI_ERRORS_SLACK_CHANNEL_ID };
|
|
275
|
+
case 'monitor_cron_failures':
|
|
276
|
+
return { token, channelId: MONITOR_CRON_FAILURES_SLACK_CHANNEL_ID };
|
|
267
277
|
case 'sdk_cli_feedback':
|
|
268
278
|
return { token, channelId: SDK_CLI_FEEDBACK_SLACK_CHANNEL_ID };
|
|
269
279
|
case 'dashboard_feedback':
|
|
@@ -277,6 +287,14 @@ function resolveBotChannel(
|
|
|
277
287
|
}
|
|
278
288
|
}
|
|
279
289
|
|
|
290
|
+
/**
|
|
291
|
+
* The Axiom email alert counts failed posts to these channels, so their
|
|
292
|
+
* failures must always produce a `Slack event send failed.` line.
|
|
293
|
+
*/
|
|
294
|
+
function isMonitorSlackChannel(channel: SlackChannelKey): boolean {
|
|
295
|
+
return channel.startsWith('monitor_');
|
|
296
|
+
}
|
|
297
|
+
|
|
280
298
|
function isSlackChannelUnavailableError(error: unknown): boolean {
|
|
281
299
|
const message = error instanceof Error ? error.message : String(error);
|
|
282
300
|
return (
|
|
@@ -582,12 +600,20 @@ export async function sendSlackEvent(
|
|
|
582
600
|
|
|
583
601
|
const botChannel = resolveBotChannel(channel);
|
|
584
602
|
if (botChannel) {
|
|
603
|
+
// Monitor cron alerts await this post, so bound it like a webhook post.
|
|
604
|
+
const controller = isMonitorSlackChannel(channel)
|
|
605
|
+
? new AbortController()
|
|
606
|
+
: null;
|
|
607
|
+
const timeout = controller
|
|
608
|
+
? setTimeout(() => controller.abort(), resolveTimeoutMs())
|
|
609
|
+
: null;
|
|
585
610
|
try {
|
|
611
|
+
const botOptions = messageOptions(sanitizedNormalized);
|
|
586
612
|
await postMessage(
|
|
587
613
|
botChannel.token,
|
|
588
614
|
botChannel.channelId,
|
|
589
615
|
sanitizedNormalized.text,
|
|
590
|
-
|
|
616
|
+
controller ? { ...botOptions, signal: controller.signal } : botOptions,
|
|
591
617
|
);
|
|
592
618
|
logSlackEventDispatch(channel, sanitizedNormalized, 'bot');
|
|
593
619
|
return;
|
|
@@ -611,6 +637,8 @@ export async function sendSlackEvent(
|
|
|
611
637
|
await postSlackWebhook(webhookUrl, sanitizedNormalized);
|
|
612
638
|
logSlackEventDispatch(channel, sanitizedNormalized, 'webhook');
|
|
613
639
|
return;
|
|
640
|
+
} finally {
|
|
641
|
+
if (timeout) clearTimeout(timeout);
|
|
614
642
|
}
|
|
615
643
|
}
|
|
616
644
|
|
|
@@ -631,7 +659,8 @@ export async function sendSlackEventSafe(
|
|
|
631
659
|
return true;
|
|
632
660
|
} catch (error) {
|
|
633
661
|
const message = error instanceof Error ? error.message : String(error);
|
|
634
|
-
if (message.startsWith('Missing SLACK_')
|
|
662
|
+
if (message.startsWith('Missing SLACK_') && !isMonitorSlackChannel(channel))
|
|
663
|
+
return false;
|
|
635
664
|
console.warn('Slack event send failed.', {
|
|
636
665
|
channel,
|
|
637
666
|
source: payload.source,
|
|
@@ -13,6 +13,7 @@ export type SlackMessageOptions = {
|
|
|
13
13
|
unfurlLinks?: boolean;
|
|
14
14
|
unfurlMedia?: boolean;
|
|
15
15
|
username?: string;
|
|
16
|
+
signal?: AbortSignal;
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
async function postSlackMessage(
|
|
@@ -29,6 +30,7 @@ async function postSlackMessage(
|
|
|
29
30
|
: undefined;
|
|
30
31
|
const res = await fetch('https://slack.com/api/chat.postMessage', {
|
|
31
32
|
method: 'POST',
|
|
33
|
+
signal: options?.signal,
|
|
32
34
|
headers: {
|
|
33
35
|
Authorization: `Bearer ${token}`,
|
|
34
36
|
'Content-Type': 'application/json',
|
|
@@ -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-LQTNFYOL.mjs";
|
|
17
|
+
import "./chunk-HHJYD3PC.mjs";
|
|
18
|
+
import "./chunk-DOWK7NOY.mjs";
|
|
19
19
|
import "./chunk-MAMVGOSC.mjs";
|
|
20
20
|
import "./chunk-DLIRSHV6.mjs";
|
|
21
21
|
import "./chunk-E4IXDAZI.mjs";
|
|
22
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-R4KGIU4P.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 _chunk2CM22MQIjs = require('./chunk-2CM22MQI.js');
|
|
17
|
+
require('./chunk-X3GM2FO2.js');
|
|
18
|
+
require('./chunk-R2DKLSIE.js');
|
|
19
|
+
require('./chunk-NPBJI7RE.js');
|
|
20
|
+
require('./chunk-XNYIZMNQ.js');
|
|
21
|
+
require('./chunk-PPDBRJRW.js');
|
|
22
|
+
require('./chunk-CF4T46L6.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 = _chunk2CM22MQIjs.EXIT_WORKSPACE_MISMATCH; exports.authStatusLine = _chunk2CM22MQIjs.authStatusLine; exports.clearPendingClaim = _chunk2CM22MQIjs.clearPendingClaim; exports.clearSatisfiedPendingClaim = _chunk2CM22MQIjs.clearSatisfiedPendingClaim; exports.handleRegister = _chunk2CM22MQIjs.handleRegister; exports.handleStatus = _chunk2CM22MQIjs.handleStatus; exports.handleWait = _chunk2CM22MQIjs.handleWait; exports.httpJson = _chunk2CM22MQIjs.httpJson; exports.readPendingAuthClaim = _chunk2CM22MQIjs.readPendingAuthClaim; exports.readStatusBanner = _chunk2CM22MQIjs.readStatusBanner; exports.registerAuthCommands = _chunk2CM22MQIjs.registerAuthCommands; exports.reportSetupCompleted = _chunk2CM22MQIjs.reportSetupCompleted; exports.resolvePendingAuthClaimForResume = _chunk2CM22MQIjs.resolvePendingAuthClaimForResume; exports.statusBannerLine = _chunk2CM22MQIjs.statusBannerLine;
|