deepline 0.3.409 → 0.3.411
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/agent-runtime.ts +18 -1
- package/dist/bundling-sources/sdk/src/client.ts +206 -333
- package/dist/bundling-sources/sdk/src/compat.ts +45 -2
- package/dist/bundling-sources/sdk/src/db/query.ts +9 -10
- package/dist/bundling-sources/sdk/src/http.ts +38 -20
- package/dist/bundling-sources/sdk/src/index.ts +4 -5
- package/dist/bundling-sources/sdk/src/play.ts +10 -10
- package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +6 -4
- package/dist/bundling-sources/sdk/src/plays/check-local-play-graph.ts +114 -0
- package/dist/bundling-sources/sdk/src/plays/client.ts +431 -0
- package/dist/bundling-sources/sdk/src/plays/local-play-execution.ts +2 -2
- package/dist/bundling-sources/sdk/src/plays/run-request.ts +106 -16
- package/dist/bundling-sources/sdk/src/release.ts +13 -7
- package/dist/bundling-sources/sdk/src/runs/read-errors.ts +8 -0
- package/dist/bundling-sources/sdk/src/runs/watch-polling.ts +124 -13
- package/dist/bundling-sources/sdk/src/tool-calls.ts +108 -19
- package/dist/bundling-sources/sdk/src/types.ts +18 -0
- package/dist/bundling-sources/shared_libs/integration-contracts/execute-retry-contract.ts +37 -0
- package/dist/bundling-sources/shared_libs/integration-contracts/package.json +3 -0
- package/dist/bundling-sources/shared_libs/monitors/package.json +1 -1
- package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +3 -1
- package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +277 -76
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/dataset-row-input.ts +124 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +6 -62
- package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durable-tool-identity.ts +67 -0
- package/dist/bundling-sources/shared_libs/play-runtime/execute-server-timing.ts +64 -6
- package/dist/bundling-sources/shared_libs/play-runtime/freshness-receipt-execution.ts +1 -5
- package/dist/bundling-sources/shared_libs/play-runtime/ledger-safe-payload.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/play-artifact-runtime-contract.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-http-request.ts +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/query-result-dataset.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/egress-probe.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +26 -16
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-heartbeat.ts +36 -11
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-terminal-push.ts +35 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-launch-transport.ts +21 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +21 -6
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +11 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +85 -20
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +71 -13
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-execution-queries.ts +100 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-pool.ts +9 -5
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +337 -146
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +26 -12
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +3 -1
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +425 -102
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-dispatch-authority.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +9 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +181 -124
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-worker-wake.ts +152 -0
- package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +5 -3
- package/dist/bundling-sources/shared_libs/play-runtime/tool-cache-policy.ts +31 -0
- package/dist/bundling-sources/shared_libs/play-runtime/transient-service-error.ts +10 -0
- package/dist/bundling-sources/shared_libs/plays/ambiguous-write-error.ts +25 -0
- package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +4 -0
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +63 -68
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +129 -63
- package/dist/bundling-sources/shared_libs/plays/contracts.ts +14 -0
- package/dist/bundling-sources/shared_libs/plays/enrich-play-compiler.ts +58 -16
- package/dist/bundling-sources/shared_libs/plays/fetch-http-error.ts +50 -0
- package/dist/bundling-sources/shared_libs/plays/source-authoring-edition.ts +351 -0
- package/dist/bundling-sources/shared_libs/plays/tool-list-getter-mode.ts +9 -0
- package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +1 -1
- package/dist/cli/auth-M7TBLW55.js +40 -0
- package/dist/cli/{auth-5HIIACF7.mjs → auth-YD6ZTMB2.mjs} +6 -6
- package/dist/cli/{billing-4275N7FL.js → billing-2L3MOB42.js} +84 -84
- package/dist/cli/{billing-EVZ3ZWKC.mjs → billing-ZT46GV4C.mjs} +8 -8
- package/dist/cli/{chunk-ZAAKSJAS.js → chunk-27GJKC5Q.js} +17 -10
- package/dist/cli/{chunk-UHNDVD3P.js → chunk-2H4EY7KH.js} +100 -41
- package/dist/cli/{chunk-GAICVLKL.js → chunk-2NI6DHN7.js} +2 -2
- package/dist/cli/{chunk-JGHG4NBA.js → chunk-2WUY3VNK.js} +19 -4
- package/dist/cli/{chunk-FHPCKULR.mjs → chunk-4BA6ATHA.mjs} +2 -2
- package/dist/cli/{chunk-RTCDW2GU.js → chunk-4O4WNFFC.js} +170 -49
- package/dist/cli/{chunk-OSDXE27V.mjs → chunk-4PG4ARL2.mjs} +17 -10
- package/dist/cli/{chunk-AU4OFDFX.js → chunk-5IGDNBG7.js} +26 -26
- package/dist/cli/{chunk-WYQO2CBS.mjs → chunk-5LRWWMRV.mjs} +149 -28
- package/dist/cli/{chunk-PMVFAYL7.mjs → chunk-63ILLN5H.mjs} +2 -2
- package/dist/cli/chunk-6AUE6JXY.js +35 -0
- package/dist/cli/chunk-7DSMMCXP.js +501 -0
- package/dist/cli/{chunk-6BJK4EJ3.mjs → chunk-AARWVK4C.mjs} +2132 -65
- package/dist/cli/{chunk-FERRDNMO.js → chunk-AD47BXN2.js} +5 -5
- package/dist/cli/{chunk-J6DCKJNM.mjs → chunk-BJV3VSKE.mjs} +16 -1
- package/dist/cli/{chunk-S6R3OX7B.js → chunk-E4CABWXL.js} +25 -2
- package/dist/cli/{chunk-NXGCO4JB.mjs → chunk-E4IXDAZI.mjs} +5 -0
- package/dist/cli/{chunk-BEVLCKXG.mjs → chunk-E4KBNNNB.mjs} +1 -1
- package/dist/cli/{chunk-2PRO2JTX.mjs → chunk-E52TKKVI.mjs} +36 -284
- package/dist/cli/chunk-FR2ILQ4G.mjs +8 -0
- package/dist/cli/{chunk-2GI3QD3L.js → chunk-FRVPOXGB.js} +644 -330
- package/dist/cli/chunk-G43JLBDE.mjs +501 -0
- package/dist/cli/{chunk-BZAMOCPA.mjs → chunk-IMZ56EOH.mjs} +3 -3
- package/dist/cli/chunk-IPGV6VFA.mjs +6084 -0
- package/dist/cli/{chunk-IT3XBJQR.mjs → chunk-IR3AKJAY.mjs} +330 -625
- package/dist/cli/chunk-J33TSWO5.js +8 -0
- package/dist/cli/chunk-JQMZUWNM.mjs +35 -0
- package/dist/cli/chunk-JYHSEGRM.js +6084 -0
- package/dist/cli/{chunk-JI2B4RZP.mjs → chunk-KCC3FKIW.mjs} +71 -12
- package/dist/cli/{chunk-6IKARAYD.mjs → chunk-L2VKAASU.mjs} +23 -0
- package/dist/cli/{chunk-O3VSXP2F.js → chunk-LWBM5FFL.js} +50 -50
- package/dist/cli/{chunk-VWBTTJYQ.mjs → chunk-M6OASCVL.mjs} +6 -3
- package/dist/cli/{chunk-YHPYUZZX.mjs → chunk-MAMVGOSC.mjs} +1 -1
- package/dist/cli/{chunk-Q2E4E4FJ.js → chunk-NPBJI7RE.js} +8 -8
- package/dist/cli/chunk-NQWIZ5PZ.js +313 -0
- package/dist/cli/{chunk-HQXL5526.mjs → chunk-NUX2QHNC.mjs} +1 -1
- package/dist/cli/{chunk-TQNHMWUR.mjs → chunk-OGSXENOF.mjs} +5 -2
- package/dist/cli/{chunk-SEFMGO3Z.js → chunk-OQQOXSYA.js} +2184 -117
- package/dist/cli/{chunk-FJCIUF34.js → chunk-OZSC6CEW.js} +128 -376
- package/dist/cli/{chunk-NZSF57UO.mjs → chunk-PO2VU6WV.mjs} +2 -2
- package/dist/cli/{chunk-7P5AA3SN.js → chunk-PPDBRJRW.js} +6 -1
- package/dist/cli/{chunk-ILHRA7AD.js → chunk-QADCFSGH.js} +7 -7
- package/dist/cli/{chunk-N44JHMKY.mjs → chunk-RFES6Q2J.mjs} +452 -138
- package/dist/cli/{chunk-DEC3JECC.js → chunk-RMINBDYY.js} +5 -2
- package/dist/cli/{chunk-WLOCMJWV.js → chunk-TPFD4F5S.js} +426 -721
- package/dist/cli/{chunk-V76R6HMV.js → chunk-U5AQKE3T.js} +1029 -806
- package/dist/cli/{chunk-PBZYY7VZ.mjs → chunk-UAEVKAUR.mjs} +734 -511
- package/dist/cli/{chunk-WHG43Z67.js → chunk-VGHWJL4W.js} +11 -8
- package/dist/cli/chunk-VKKVSFRD.js +62 -0
- package/dist/cli/{chunk-GSK6NHVM.js → chunk-WU4U6VSB.js} +5 -5
- package/dist/cli/chunk-XAB47ZRV.mjs +313 -0
- package/dist/cli/{chunk-JRAVVJ3T.mjs → chunk-XJD6LZCO.mjs} +2 -2
- package/dist/cli/chunk-ZCALLYF6.mjs +62 -0
- package/dist/cli/{chunk-YD7B53RW.js → chunk-ZHWBU36H.js} +12 -12
- package/dist/cli/{csv-A2MP6EFV.mjs → csv-BKNRRW7D.mjs} +5 -5
- package/dist/cli/{csv-BBOTCGQY.js → csv-SVDP2EU7.js} +14 -14
- package/dist/cli/{db-3W5DMTUX.mjs → db-LU4KLRM6.mjs} +15 -20
- package/dist/cli/{db-G4CODDCA.js → db-OQ6S7TTZ.js} +42 -47
- package/dist/cli/{describe-PQTQ5B6F.js → describe-45TGETKR.js} +27 -22
- package/dist/cli/{describe-XYJ2ZT4M.mjs → describe-U4KOGDRA.mjs} +20 -15
- package/dist/cli/describe-core.d.mts +2 -2
- package/dist/cli/describe-core.d.ts +2 -2
- package/dist/cli/describe-core.js +6 -6
- package/dist/cli/describe-core.mjs +5 -5
- package/dist/cli/{executions-UR67CA5H.mjs → executions-2GAAUXLA.mjs} +8 -8
- package/dist/cli/{executions-TLANVR7Y.js → executions-VZN56VRC.js} +10 -10
- package/dist/cli/{feedback-6C2YTRJL.js → feedback-NS76B5GU.js} +13 -9
- package/dist/cli/{feedback-WHCMGEIL.mjs → feedback-XW5IWA5R.mjs} +11 -7
- package/dist/cli/{git-GWLB6VSA.mjs → git-CLI66XP6.mjs} +6 -6
- package/dist/cli/git-VGYRGFEN.js +24 -0
- package/dist/cli/index.js +236 -348
- package/dist/cli/index.mjs +162 -274
- package/dist/cli/{legacy-noops-ZUFA7RWI.js → legacy-noops-HCFB3ZOV.js} +9 -9
- package/dist/cli/{legacy-noops-KF4XIFEF.mjs → legacy-noops-ODDOMLBL.mjs} +6 -6
- package/dist/cli/{monitors-TB3K2IVE.js → monitors-7WXQ7JFT.js} +94 -94
- package/dist/cli/{monitors-6UOIDIMB.mjs → monitors-ZXX456TE.mjs} +8 -8
- package/dist/cli/{org-CKWMBPIR.js → org-YLX5PHBQ.js} +68 -68
- package/dist/cli/{org-WGHHMVDZ.mjs → org-YUN3TLNP.mjs} +8 -8
- package/dist/cli/{play-LYPAXCLD.mjs → play-LL73A7EP.mjs} +533 -98
- package/dist/cli/{play-N2B3KAVS.js → play-YGOXL52D.js} +1067 -632
- package/dist/cli/{providers-6DI5BVZJ.mjs → providers-35QSAUHL.mjs} +8 -8
- package/dist/cli/{providers-UR42MD6Z.js → providers-RHCIU2PX.js} +11 -11
- package/dist/cli/{quickstart-MNA2S6PO.mjs → quickstart-6BN3LCZH.mjs} +5 -5
- package/dist/cli/{quickstart-FCJG4XGB.js → quickstart-ORMM4NRK.js} +7 -7
- package/dist/cli/search-EWDMUPHR.js +30 -0
- package/dist/cli/{search-VPPYUJ2M.mjs → search-GAERWLSE.mjs} +9 -9
- package/dist/cli/{secrets-QOSMVO36.js → secrets-3AFCTGT7.js} +17 -17
- package/dist/cli/{secrets-DRI4W7Z5.mjs → secrets-FCL5PALY.mjs} +8 -8
- package/dist/cli/sessions-3OEHEQG7.js +16 -0
- package/dist/cli/{sessions-DQNUKP43.mjs → sessions-RSSL7I7O.mjs} +6 -6
- package/dist/cli/{settings-DWDK3Y2R.mjs → settings-GE4NRE7Y.mjs} +12 -12
- package/dist/cli/{settings-JUGGCOPS.js → settings-RX5K4I7H.js} +79 -79
- package/dist/cli/{setup-AWBHNYXK.js → setup-N3ZNAEL5.js} +45 -44
- package/dist/cli/{setup-D5DWVNY4.mjs → setup-X3RXGG4F.mjs} +11 -10
- package/dist/cli/{skills-YV2XR35J.mjs → skills-5JEAJBDE.mjs} +7 -7
- package/dist/cli/skills-VAAQVEQC.js +29 -0
- package/dist/cli/tools-BYYOT2DU.js +44 -0
- package/dist/cli/{tools-VFJYHNV2.mjs → tools-JOKUWEBZ.mjs} +19 -14
- package/dist/cli/update-36G4ZD7B.js +31 -0
- package/dist/cli/{update-IM6VOTGL.mjs → update-UBHEVFR3.mjs} +11 -9
- package/dist/cli/{workflow-26URBWPV.mjs → workflow-FR6EXAXF.mjs} +44 -20
- package/dist/cli/{workflow-3BS6U6SL.js → workflow-SZAVOHN6.js} +54 -30
- package/dist/{client-BfInrZPB.d.mts → client-74k4IPh6.d.mts} +135 -54
- package/dist/{client-BMjJFpan.d.ts → client-C1IK1f8c.d.ts} +135 -54
- package/dist/{compiler-manifest-Ycx-hoAr.d.mts → compiler-manifest-lzWpbV3w.d.mts} +83 -66
- package/dist/{compiler-manifest-Ycx-hoAr.d.ts → compiler-manifest-lzWpbV3w.d.ts} +83 -66
- package/dist/{index-CZXgiN3E.d.mts → index-C8Cy-YTm.d.ts} +5 -1
- package/dist/{index-NPG5pqxQ.d.ts → index-CtNK-0nI.d.mts} +5 -1
- package/dist/index.d.mts +47 -9
- package/dist/index.d.ts +47 -9
- package/dist/index.js +17 -14
- package/dist/index.mjs +13 -10
- package/dist/install-integrity.json +118 -102
- package/dist/plays/bundle-play-file.d.mts +3 -3
- package/dist/plays/bundle-play-file.d.ts +3 -3
- package/dist/plays/bundle-play-file.mjs +5 -4
- package/dist/plays/csv-data-input.js +3 -3
- package/dist/plays/csv-data-input.mjs +2 -2
- package/dist/plays/play-description.d.mts +2 -2
- package/dist/plays/play-description.d.ts +2 -2
- package/dist/plays/run-request.d.mts +2 -2
- package/dist/plays/run-request.d.ts +2 -2
- package/dist/plays/run-request.js +11 -3
- package/dist/plays/run-request.mjs +10 -2
- package/dist/release.d.mts +15 -6
- package/dist/release.d.ts +15 -6
- package/dist/release.js +2 -2
- package/dist/release.mjs +1 -1
- package/package.json +2 -2
- package/dist/cli/auth-F6BX32XZ.js +0 -40
- package/dist/cli/chunk-264PC2RN.mjs +0 -83
- package/dist/cli/chunk-44ZTYHMQ.mjs +0 -155
- package/dist/cli/chunk-53HN7WZN.js +0 -392
- package/dist/cli/chunk-7AALNGTA.mjs +0 -392
- package/dist/cli/chunk-ALD4COBH.js +0 -155
- package/dist/cli/chunk-CLJGSOVM.mjs +0 -1716
- package/dist/cli/chunk-WNUR6VP5.js +0 -83
- package/dist/cli/chunk-Z4VNJOF7.js +0 -1716
- package/dist/cli/git-VQFF6D7C.js +0 -24
- package/dist/cli/search-NCEEONMQ.js +0 -30
- package/dist/cli/sessions-3WYKQABW.js +0 -16
- package/dist/cli/skills-AKPAJVSO.js +0 -29
- package/dist/cli/tools-RBKEK6PM.js +0 -39
- package/dist/cli/update-VFNUBLDA.js +0 -29
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote Play operations shared by the full SDK client and imported Play handles.
|
|
3
|
+
* Handles resolve configuration lazily; a submitted job keeps its original client.
|
|
4
|
+
*/
|
|
5
|
+
import { resolveConfig } from '../config';
|
|
6
|
+
import { DeeplineError } from '../errors';
|
|
7
|
+
import { HttpClient } from '../http';
|
|
8
|
+
import { SDK_API_MAJOR } from '../version';
|
|
9
|
+
import type {
|
|
10
|
+
DeeplineClientOptions,
|
|
11
|
+
ClearPlayHistoryRequest,
|
|
12
|
+
ClearPlayHistoryResult,
|
|
13
|
+
PlayDetail,
|
|
14
|
+
PlayRevisionSummary,
|
|
15
|
+
PlayRunListItem,
|
|
16
|
+
PlayRunStart,
|
|
17
|
+
PlayStatus,
|
|
18
|
+
PublishPlayVersionRequest,
|
|
19
|
+
PublishPlayVersionResult,
|
|
20
|
+
StartPlayRunRequest,
|
|
21
|
+
StopPlayRunResult,
|
|
22
|
+
} from '../types';
|
|
23
|
+
import {
|
|
24
|
+
isPlayRunPackage,
|
|
25
|
+
startPlayRun,
|
|
26
|
+
type ResolvedStartPlayRunRequest,
|
|
27
|
+
type PlayRunStartOptions,
|
|
28
|
+
} from './run-request';
|
|
29
|
+
import {
|
|
30
|
+
RUNTIME_ENVIRONMENT_TOKEN_HEADER,
|
|
31
|
+
RETAINED_PIPELINE_RECEIVERS_HEADER,
|
|
32
|
+
} from '../../../shared_libs/play-runtime/coordinator-headers.js';
|
|
33
|
+
import {
|
|
34
|
+
normalizePlayRuntimeEnvironment,
|
|
35
|
+
normalizePlayRuntimeNamespace,
|
|
36
|
+
normalizePlayRuntimeSandboxPlacementPolicy,
|
|
37
|
+
normalizePlayRuntimeSelection,
|
|
38
|
+
type PlayRuntimeSelection,
|
|
39
|
+
} from '../../../shared_libs/play-runtime/runtime-environment.js';
|
|
40
|
+
import { decodePlayRunPublicStatus } from '../../../shared_libs/play-runtime/run-lifecycle-policy.js';
|
|
41
|
+
|
|
42
|
+
export function normalizePlayRunIntegrationMode(
|
|
43
|
+
value: unknown,
|
|
44
|
+
): 'live' | 'eval_stub' | 'fixture' | undefined {
|
|
45
|
+
if (value === 'live' || value === 'eval_stub' || value === 'fixture') {
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type ClientEnvironment = Readonly<Record<string, string | undefined>>;
|
|
52
|
+
|
|
53
|
+
function resolvePlayRunIntegrationMode(
|
|
54
|
+
request: StartPlayRunRequest,
|
|
55
|
+
env: ClientEnvironment,
|
|
56
|
+
): 'live' | 'eval_stub' | 'fixture' | undefined {
|
|
57
|
+
return normalizePlayRunIntegrationMode(
|
|
58
|
+
request.integrationMode ?? env.DEEPLINE_EVAL_INTEGRATION_MODE,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function resolvePlayRunRuntimeSelection(
|
|
63
|
+
request: StartPlayRunRequest,
|
|
64
|
+
env: ClientEnvironment,
|
|
65
|
+
): PlayRuntimeSelection | undefined {
|
|
66
|
+
if (request.runtime !== undefined) {
|
|
67
|
+
const runtime = normalizePlayRuntimeSelection(request.runtime);
|
|
68
|
+
if (!runtime) {
|
|
69
|
+
throw new DeeplineError(
|
|
70
|
+
'runtime must be { environment: "preview", namespace, backend?: "daytona" | "modal", sandboxPlacementPolicy?: "policy_name@1" } with namespace matching ^[a-z][a-z0-9-]{0,30}$.',
|
|
71
|
+
undefined,
|
|
72
|
+
'INVALID_RUNTIME_SELECTION',
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
return runtime;
|
|
76
|
+
}
|
|
77
|
+
// These variables select where the app executes a run, not which app the
|
|
78
|
+
// SDK calls. DEEPLINE_API_BASE_URL still chooses the app host. Environment
|
|
79
|
+
// opts into remote preview routing, namespace names the isolated lane, and
|
|
80
|
+
// the token only authorizes that selection. Omitting all three leaves the
|
|
81
|
+
// app free to use its native runtime (local for a local app, prod for prod).
|
|
82
|
+
const configured = env.DEEPLINE_RUNTIME_ENVIRONMENT?.trim();
|
|
83
|
+
const configuredNamespace = env.DEEPLINE_RUNTIME_NAMESPACE?.trim();
|
|
84
|
+
const configuredToken = env.DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN?.trim();
|
|
85
|
+
const configuredPlacementPolicy =
|
|
86
|
+
env.DEEPLINE_RUNTIME_SANDBOX_PLACEMENT_POLICY?.trim();
|
|
87
|
+
if (!configured) {
|
|
88
|
+
if (configuredNamespace || configuredToken || configuredPlacementPolicy) {
|
|
89
|
+
// Name the variables that are actually set. This branch is almost always
|
|
90
|
+
// hit by a stale value auto-loaded from a .env/.env.local rather than by
|
|
91
|
+
// a deliberate export, so the message has to say where to look and how
|
|
92
|
+
// to run the command anyway.
|
|
93
|
+
const present: string[] = [];
|
|
94
|
+
if (configuredNamespace) present.push('DEEPLINE_RUNTIME_NAMESPACE');
|
|
95
|
+
if (configuredToken) present.push('DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN');
|
|
96
|
+
if (configuredPlacementPolicy) {
|
|
97
|
+
present.push('DEEPLINE_RUNTIME_SANDBOX_PLACEMENT_POLICY');
|
|
98
|
+
}
|
|
99
|
+
const isPlural = present.length > 1;
|
|
100
|
+
throw new DeeplineError(
|
|
101
|
+
[
|
|
102
|
+
`Incomplete play runtime selection: ${present.join(' and ')} ${isPlural ? 'are' : 'is'} set but DEEPLINE_RUNTIME_ENVIRONMENT is not.`,
|
|
103
|
+
'Preview routing requires DEEPLINE_RUNTIME_ENVIRONMENT=preview together with DEEPLINE_RUNTIME_NAMESPACE; the token alone authorizes nothing.',
|
|
104
|
+
`If you did not export ${isPlural ? 'these' : 'this'} yourself, ${isPlural ? 'they were' : 'it was'} most likely auto-loaded from a .env or .env.local in the current directory (bun loads those automatically, and in a git worktree .env.local is usually a symlink to the main checkout).`,
|
|
105
|
+
`To run against the app-native runtime, clear ${isPlural ? 'them' : 'it'} for this command: ${present.map((name) => `${name}=`).join(' ')} <your deepline command>`,
|
|
106
|
+
].join('\n'),
|
|
107
|
+
undefined,
|
|
108
|
+
'INVALID_RUNTIME_ENVIRONMENT',
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
const environment = normalizePlayRuntimeEnvironment(configured);
|
|
114
|
+
if (!environment) {
|
|
115
|
+
throw new DeeplineError(
|
|
116
|
+
`DEEPLINE_RUNTIME_ENVIRONMENT supports only explicit preview selection. Received "${configured}". Omit it to use the app-native runtime.`,
|
|
117
|
+
undefined,
|
|
118
|
+
'INVALID_RUNTIME_ENVIRONMENT',
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
const namespace = normalizePlayRuntimeNamespace(configuredNamespace);
|
|
122
|
+
if (!namespace) {
|
|
123
|
+
throw new DeeplineError(
|
|
124
|
+
'DEEPLINE_RUNTIME_NAMESPACE is required for preview and must match ^[a-z][a-z0-9-]{0,30}$.',
|
|
125
|
+
undefined,
|
|
126
|
+
'INVALID_RUNTIME_NAMESPACE',
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
const configuredBackendValue = env.DEEPLINE_PLAY_RUNNER_BACKEND?.trim();
|
|
130
|
+
const configuredBackend =
|
|
131
|
+
configuredBackendValue === 'daytona' || configuredBackendValue === 'modal'
|
|
132
|
+
? configuredBackendValue
|
|
133
|
+
: undefined;
|
|
134
|
+
if (configuredBackendValue && !configuredBackend) {
|
|
135
|
+
throw new DeeplineError(
|
|
136
|
+
`DEEPLINE_PLAY_RUNNER_BACKEND must be daytona or modal for preview runtime selection. Received "${configuredBackendValue}".`,
|
|
137
|
+
undefined,
|
|
138
|
+
'INVALID_RUNTIME_BACKEND',
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
if (
|
|
142
|
+
configuredPlacementPolicy &&
|
|
143
|
+
!normalizePlayRuntimeSandboxPlacementPolicy(configuredPlacementPolicy)
|
|
144
|
+
) {
|
|
145
|
+
throw new DeeplineError(
|
|
146
|
+
`DEEPLINE_RUNTIME_SANDBOX_PLACEMENT_POLICY must be a versioned placement policy id such as daytona_only@1. Received "${configuredPlacementPolicy}".`,
|
|
147
|
+
undefined,
|
|
148
|
+
'INVALID_RUNTIME_SANDBOX_PLACEMENT_POLICY',
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
environment,
|
|
153
|
+
namespace,
|
|
154
|
+
...(configuredBackend ? { backend: configuredBackend } : {}),
|
|
155
|
+
...(configuredPlacementPolicy
|
|
156
|
+
? { sandboxPlacementPolicy: configuredPlacementPolicy }
|
|
157
|
+
: {}),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Resolve the environment-derived run-start fields (eval integration mode,
|
|
163
|
+
* test policy overrides, preview runtime) into explicit request fields, in the
|
|
164
|
+
* order the SDK has always validated them. The shared body builder in
|
|
165
|
+
* `plays/run-request` never reads the environment.
|
|
166
|
+
*/
|
|
167
|
+
export function resolveStartPlayRunRequest(
|
|
168
|
+
request: StartPlayRunRequest,
|
|
169
|
+
env: ClientEnvironment,
|
|
170
|
+
): {
|
|
171
|
+
request: ResolvedStartPlayRunRequest;
|
|
172
|
+
runtime: PlayRuntimeSelection | undefined;
|
|
173
|
+
} {
|
|
174
|
+
const integrationMode = resolvePlayRunIntegrationMode(request, env);
|
|
175
|
+
const testPolicyOverrides =
|
|
176
|
+
request.testPolicyOverrides ?? parseEnvTestPolicyOverrides(env);
|
|
177
|
+
const runtime = resolvePlayRunRuntimeSelection(request, env);
|
|
178
|
+
const resolved: ResolvedStartPlayRunRequest = { ...request };
|
|
179
|
+
delete resolved.integrationMode;
|
|
180
|
+
delete resolved.runtime;
|
|
181
|
+
delete resolved.testPolicyOverrides;
|
|
182
|
+
if (integrationMode) resolved.integrationMode = integrationMode;
|
|
183
|
+
if (runtime) resolved.runtime = runtime;
|
|
184
|
+
if (testPolicyOverrides) resolved.testPolicyOverrides = testPolicyOverrides;
|
|
185
|
+
return { request: resolved, runtime };
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function runtimeSelectionHeaders(
|
|
189
|
+
runtime: PlayRuntimeSelection | undefined,
|
|
190
|
+
env: ClientEnvironment,
|
|
191
|
+
): Record<string, string> | undefined {
|
|
192
|
+
if (!runtime) return undefined;
|
|
193
|
+
// Keep the credential out of the typed runtime payload. The app consumes it
|
|
194
|
+
// at the HTTP boundary and never forwards it to Fly, Absurd, or Daytona.
|
|
195
|
+
const token = env.DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN?.trim();
|
|
196
|
+
if (!token) {
|
|
197
|
+
throw new DeeplineError(
|
|
198
|
+
'DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN is required for explicit preview runtime selection.',
|
|
199
|
+
undefined,
|
|
200
|
+
'RUNTIME_ENVIRONMENT_TOKEN_REQUIRED',
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
const receivers = env.DEEPLINE_RUNTIME_RETAINED_PIPELINE_RECEIVERS?.trim();
|
|
204
|
+
return {
|
|
205
|
+
[RUNTIME_ENVIRONMENT_TOKEN_HEADER]: token,
|
|
206
|
+
...(receivers ? { [RETAINED_PIPELINE_RECEIVERS_HEADER]: receivers } : {}),
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function normalizeTestPolicyOverrides(
|
|
211
|
+
value: unknown,
|
|
212
|
+
source: string,
|
|
213
|
+
): Record<string, unknown> {
|
|
214
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
215
|
+
return value as Record<string, unknown>;
|
|
216
|
+
}
|
|
217
|
+
throw new DeeplineError(
|
|
218
|
+
`${source} must be a JSON object.`,
|
|
219
|
+
undefined,
|
|
220
|
+
'INVALID_TEST_POLICY_OVERRIDES',
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function parseEnvTestPolicyOverrides(
|
|
225
|
+
env: ClientEnvironment,
|
|
226
|
+
): Record<string, unknown> | undefined {
|
|
227
|
+
const raw = env.DEEPLINE_TEST_POLICY_OVERRIDES;
|
|
228
|
+
const trimmed = raw?.trim();
|
|
229
|
+
if (!trimmed) return undefined;
|
|
230
|
+
let parsed: unknown;
|
|
231
|
+
try {
|
|
232
|
+
parsed = JSON.parse(trimmed);
|
|
233
|
+
} catch (error) {
|
|
234
|
+
const detail = error instanceof Error ? ` ${error.message}` : '';
|
|
235
|
+
throw new DeeplineError(
|
|
236
|
+
`DEEPLINE_TEST_POLICY_OVERRIDES must be valid JSON.${detail}`,
|
|
237
|
+
undefined,
|
|
238
|
+
'INVALID_TEST_POLICY_OVERRIDES',
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
return normalizeTestPolicyOverrides(parsed, 'DEEPLINE_TEST_POLICY_OVERRIDES');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
245
|
+
return Boolean(value && typeof value === 'object' && !Array.isArray(value));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export function normalizePlayStatus(raw: Record<string, unknown>): PlayStatus {
|
|
249
|
+
const runPackage = isPlayRunPackage(raw)
|
|
250
|
+
? raw
|
|
251
|
+
: isPlayRunPackage(raw.package)
|
|
252
|
+
? raw.package
|
|
253
|
+
: null;
|
|
254
|
+
const packageRun = runPackage?.run;
|
|
255
|
+
const rawStatus =
|
|
256
|
+
typeof raw.status === 'string'
|
|
257
|
+
? raw.status
|
|
258
|
+
: typeof packageRun?.status === 'string'
|
|
259
|
+
? packageRun.status
|
|
260
|
+
: null;
|
|
261
|
+
const status = decodePlayRunPublicStatus(rawStatus);
|
|
262
|
+
if (!status) {
|
|
263
|
+
throw new Error(
|
|
264
|
+
`Invalid play run lifecycle status in API response: ${JSON.stringify(rawStatus)}.`,
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
const runId =
|
|
268
|
+
typeof raw.runId === 'string'
|
|
269
|
+
? raw.runId
|
|
270
|
+
: typeof raw.workflowId === 'string'
|
|
271
|
+
? raw.workflowId
|
|
272
|
+
: (packageRun?.id ?? '');
|
|
273
|
+
const legacyOverview = runPackage?.overview ?? raw.overview;
|
|
274
|
+
const runStatus = runPackage?.runStatus ?? raw.runStatus;
|
|
275
|
+
return {
|
|
276
|
+
...(raw as unknown as Omit<PlayStatus, 'runId' | 'status'>),
|
|
277
|
+
runId,
|
|
278
|
+
...(isRecord(legacyOverview)
|
|
279
|
+
? {
|
|
280
|
+
overview: legacyOverview as unknown as PlayStatus['overview'],
|
|
281
|
+
}
|
|
282
|
+
: {}),
|
|
283
|
+
...(isRecord(runStatus)
|
|
284
|
+
? { runStatus: runStatus as unknown as PlayStatus['runStatus'] }
|
|
285
|
+
: {}),
|
|
286
|
+
...(runPackage
|
|
287
|
+
? {
|
|
288
|
+
package: runPackage,
|
|
289
|
+
outputs: runPackage.outputs,
|
|
290
|
+
}
|
|
291
|
+
: {}),
|
|
292
|
+
status,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export class PlayClient {
|
|
297
|
+
constructor(
|
|
298
|
+
private readonly http: HttpClient,
|
|
299
|
+
private readonly environment: ClientEnvironment = process.env,
|
|
300
|
+
) {}
|
|
301
|
+
|
|
302
|
+
async startPlayRun(
|
|
303
|
+
request: StartPlayRunRequest,
|
|
304
|
+
options?: PlayRunStartOptions,
|
|
305
|
+
): Promise<PlayRunStart> {
|
|
306
|
+
const resolved = resolveStartPlayRunRequest(request, this.environment);
|
|
307
|
+
const headers = runtimeSelectionHeaders(resolved.runtime, this.environment);
|
|
308
|
+
return startPlayRun(
|
|
309
|
+
this.http,
|
|
310
|
+
resolved.request,
|
|
311
|
+
options?.cliAdmission
|
|
312
|
+
? { ...headers, 'X-Deepline-API-Major': String(SDK_API_MAJOR) }
|
|
313
|
+
: headers,
|
|
314
|
+
options,
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
async getPlayStatus(
|
|
319
|
+
workflowId: string,
|
|
320
|
+
options?: { billing?: boolean; full?: boolean },
|
|
321
|
+
): Promise<PlayStatus> {
|
|
322
|
+
const params = new URLSearchParams();
|
|
323
|
+
if (options?.billing === false) {
|
|
324
|
+
params.set('billing', 'false');
|
|
325
|
+
}
|
|
326
|
+
if (options?.full === true) {
|
|
327
|
+
params.set('full', 'true');
|
|
328
|
+
}
|
|
329
|
+
const query = params.size > 0 ? `?${params.toString()}` : '';
|
|
330
|
+
const response = await this.http.get<Record<string, unknown>>(
|
|
331
|
+
`/api/v2/runs/${encodeURIComponent(workflowId)}${query}`,
|
|
332
|
+
);
|
|
333
|
+
return normalizePlayStatus(response);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
async cancelPlay(workflowId: string): Promise<void> {
|
|
337
|
+
await this.http.request(
|
|
338
|
+
`/api/v2/runs/${encodeURIComponent(workflowId)}/stop`,
|
|
339
|
+
{ method: 'POST' },
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
async stopPlay(
|
|
344
|
+
workflowId: string,
|
|
345
|
+
options?: { reason?: string },
|
|
346
|
+
): Promise<StopPlayRunResult> {
|
|
347
|
+
return this.http.post<StopPlayRunResult>(
|
|
348
|
+
`/api/v2/runs/${encodeURIComponent(workflowId)}/stop`,
|
|
349
|
+
options?.reason ? { reason: options.reason } : {},
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
async listPlayRuns(playName: string): Promise<PlayRunListItem[]> {
|
|
354
|
+
const encodedName = encodeURIComponent(playName);
|
|
355
|
+
const response = await this.http.get<{ runs: PlayRunListItem[] }>(
|
|
356
|
+
`/api/v2/plays/${encodedName}/runs`,
|
|
357
|
+
);
|
|
358
|
+
return response.runs ?? [];
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
async getPlay(
|
|
362
|
+
name: string,
|
|
363
|
+
options?: {
|
|
364
|
+
source?: 'working' | 'live' | `version:${number}`;
|
|
365
|
+
guidance?: boolean;
|
|
366
|
+
},
|
|
367
|
+
): Promise<PlayDetail> {
|
|
368
|
+
const encodedName = encodeURIComponent(name);
|
|
369
|
+
const query = options?.source
|
|
370
|
+
? `?include=source&revision=${encodeURIComponent(options.source)}`
|
|
371
|
+
: options?.guidance
|
|
372
|
+
? '?include=guidance'
|
|
373
|
+
: '';
|
|
374
|
+
return this.http.get<PlayDetail>(`/api/v2/plays/${encodedName}${query}`);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
async clearPlayHistory(
|
|
378
|
+
name: string,
|
|
379
|
+
request: ClearPlayHistoryRequest = {},
|
|
380
|
+
): Promise<ClearPlayHistoryResult> {
|
|
381
|
+
const encodedName = encodeURIComponent(name);
|
|
382
|
+
return this.http.post<ClearPlayHistoryResult>(
|
|
383
|
+
`/api/v2/plays/${encodedName}/history/clear`,
|
|
384
|
+
request,
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
async listPlayVersions(
|
|
389
|
+
name: string,
|
|
390
|
+
options?: { full?: boolean },
|
|
391
|
+
): Promise<PlayRevisionSummary[]> {
|
|
392
|
+
const encodedName = encodeURIComponent(name);
|
|
393
|
+
const suffix = options?.full ? '?full=true' : '';
|
|
394
|
+
const response = await this.http.get<{ versions: PlayRevisionSummary[] }>(
|
|
395
|
+
`/api/v2/plays/${encodedName}/versions${suffix}`,
|
|
396
|
+
);
|
|
397
|
+
return response.versions ?? [];
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
async publishPlayVersion(
|
|
401
|
+
name: string,
|
|
402
|
+
request: PublishPlayVersionRequest = {},
|
|
403
|
+
): Promise<PublishPlayVersionResult> {
|
|
404
|
+
const encodedName = encodeURIComponent(name);
|
|
405
|
+
return this.http.post<PublishPlayVersionResult>(
|
|
406
|
+
`/api/v2/plays/${encodedName}/live`,
|
|
407
|
+
request,
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
export type PlayClientOperations = Pick<
|
|
413
|
+
PlayClient,
|
|
414
|
+
| 'getPlay'
|
|
415
|
+
| 'listPlayRuns'
|
|
416
|
+
| 'listPlayVersions'
|
|
417
|
+
| 'publishPlayVersion'
|
|
418
|
+
| 'clearPlayHistory'
|
|
419
|
+
| 'startPlayRun'
|
|
420
|
+
| 'getPlayStatus'
|
|
421
|
+
| 'cancelPlay'
|
|
422
|
+
| 'stopPlay'
|
|
423
|
+
>;
|
|
424
|
+
|
|
425
|
+
export function createPlayClient(options?: DeeplineClientOptions): PlayClient {
|
|
426
|
+
const config = resolveConfig(options);
|
|
427
|
+
return new PlayClient(
|
|
428
|
+
new HttpClient(config),
|
|
429
|
+
config.environment ?? process.env,
|
|
430
|
+
);
|
|
431
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { DeeplineClient } from '../client';
|
|
2
|
-
import type { BundledPlayFileSuccess } from './bundle-play-file';
|
|
1
|
+
import type { DeeplineClient } from '../client.js';
|
|
2
|
+
import type { BundledPlayFileSuccess } from './bundle-play-file.js';
|
|
3
3
|
|
|
4
4
|
export type LocalPlayGraph = {
|
|
5
5
|
root: BundledPlayFileSuccess;
|
|
@@ -31,9 +31,12 @@ import type { PlayStagedFileRef } from './local-file-discovery';
|
|
|
31
31
|
|
|
32
32
|
export { DeeplineError };
|
|
33
33
|
|
|
34
|
-
/**
|
|
34
|
+
/** Canonical admission; the CLI adapter adds compatibility before this handler. */
|
|
35
35
|
export const PLAY_RUN_START_PATH = '/api/v2/plays/run';
|
|
36
|
+
export const CLI_PLAY_RUN_START_PATH = `${PLAY_RUN_START_PATH}/cli`;
|
|
37
|
+
export const CLI_PLAY_RUN_SUPPORTED_HEADER = 'x-deepline-cli-play-admission';
|
|
36
38
|
export const PLAY_RUN_START_STREAM_PATH = `${PLAY_RUN_START_PATH}?stream=true`;
|
|
39
|
+
export const CLI_PLAY_RUN_START_STREAM_PATH = `${CLI_PLAY_RUN_START_PATH}?stream=true`;
|
|
37
40
|
export const PLAY_FILES_STAGE_PATH = '/api/v2/plays/files/stage';
|
|
38
41
|
export const PLAY_FILES_STAGE_MINT_PATH = `${PLAY_FILES_STAGE_PATH}/mint`;
|
|
39
42
|
|
|
@@ -44,12 +47,20 @@ export const PLAY_FILES_STAGE_MINT_PATH = `${PLAY_FILES_STAGE_PATH}/mint`;
|
|
|
44
47
|
* responses so the staging fallbacks below classify failures identically.
|
|
45
48
|
*/
|
|
46
49
|
export interface PlayRunHttp {
|
|
47
|
-
get?<T = unknown>(
|
|
50
|
+
get?<T = unknown>(
|
|
51
|
+
path: string,
|
|
52
|
+
options?: { signal?: AbortSignal },
|
|
53
|
+
): Promise<T>;
|
|
48
54
|
post<T = unknown>(
|
|
49
55
|
path: string,
|
|
50
56
|
body: unknown,
|
|
51
57
|
headers?: Record<string, string>,
|
|
52
|
-
options?: {
|
|
58
|
+
options?: {
|
|
59
|
+
maxRetries?: number;
|
|
60
|
+
exactUrlOnly?: boolean;
|
|
61
|
+
signal?: AbortSignal;
|
|
62
|
+
onResponse?: (response: Response) => void;
|
|
63
|
+
},
|
|
53
64
|
): Promise<T>;
|
|
54
65
|
postFormData<T = unknown>(
|
|
55
66
|
path: string,
|
|
@@ -66,6 +77,28 @@ export interface PlayRunHttp {
|
|
|
66
77
|
*/
|
|
67
78
|
export type ResolvedStartPlayRunRequest = StartPlayRunRequest;
|
|
68
79
|
|
|
80
|
+
export type PlayRunStartOptions = {
|
|
81
|
+
signal?: AbortSignal;
|
|
82
|
+
onSubmission?: (intent: {
|
|
83
|
+
workflowId: string;
|
|
84
|
+
orgId: string;
|
|
85
|
+
request: Record<string, unknown>;
|
|
86
|
+
}) => void | Promise<void>;
|
|
87
|
+
/** @internal CLI JSON admission checks compatibility in the same request. */
|
|
88
|
+
cliAdmission?: boolean;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/** Only the transport can prove that the named action never dispatched. */
|
|
92
|
+
export class CliPlayAdmissionUnsupportedError extends DeeplineError {
|
|
93
|
+
constructor(status: number) {
|
|
94
|
+
super(
|
|
95
|
+
'This server does not support CLI Play admission.',
|
|
96
|
+
status,
|
|
97
|
+
'CLI_PLAY_ADMISSION_UNSUPPORTED',
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
69
102
|
/** The exact JSON body `POST /api/v2/plays/run` receives. Key order is part of the contract. */
|
|
70
103
|
export function buildPlayRunStartBody(
|
|
71
104
|
request: ResolvedStartPlayRunRequest,
|
|
@@ -122,6 +155,7 @@ export function buildPlayRunStartBody(
|
|
|
122
155
|
...(typeof request.waitForCompletionMs === 'number'
|
|
123
156
|
? { waitForCompletionMs: request.waitForCompletionMs }
|
|
124
157
|
: {}),
|
|
158
|
+
...(request.terminalStatus === 'full' ? { terminalStatus: 'full' } : {}),
|
|
125
159
|
// Profile selection is the API's job, not the caller's. The server
|
|
126
160
|
// defaults to absurd; callers normally omit this field.
|
|
127
161
|
...(request.profile ? { profile: request.profile } : {}),
|
|
@@ -154,6 +188,7 @@ export async function preparePlayRunAdmission(
|
|
|
154
188
|
orgId: string;
|
|
155
189
|
request: Record<string, unknown>;
|
|
156
190
|
}) => void | Promise<void>,
|
|
191
|
+
options?: { signal?: AbortSignal },
|
|
157
192
|
): Promise<{
|
|
158
193
|
body: Record<string, unknown>;
|
|
159
194
|
workflowId?: string;
|
|
@@ -168,7 +203,7 @@ export async function preparePlayRunAdmission(
|
|
|
168
203
|
} | null = null;
|
|
169
204
|
if (http.get) {
|
|
170
205
|
try {
|
|
171
|
-
capability = await http.get(PLAY_RUN_START_PATH);
|
|
206
|
+
capability = await http.get(PLAY_RUN_START_PATH, options);
|
|
172
207
|
} catch (error) {
|
|
173
208
|
if (
|
|
174
209
|
!(error instanceof DeeplineError) ||
|
|
@@ -193,6 +228,7 @@ export async function preparePlayRunAdmission(
|
|
|
193
228
|
}
|
|
194
229
|
const supportsCallerIntent =
|
|
195
230
|
capability?.admissionContract === 'caller-intent-v1';
|
|
231
|
+
options?.signal?.throwIfAborted();
|
|
196
232
|
if (
|
|
197
233
|
supportsCallerIntent &&
|
|
198
234
|
(!capability?.orgId ||
|
|
@@ -211,6 +247,23 @@ export async function preparePlayRunAdmission(
|
|
|
211
247
|
'PLAY_RUN_ADMISSION_RECOVERY_UNSUPPORTED',
|
|
212
248
|
);
|
|
213
249
|
}
|
|
250
|
+
if (
|
|
251
|
+
request.maxTotalCredits !== undefined &&
|
|
252
|
+
capability?.strictTotalBudget === 'unbounded-v1'
|
|
253
|
+
) {
|
|
254
|
+
if (request.maxTotalCredits === 0) {
|
|
255
|
+
throw new DeeplineError(
|
|
256
|
+
'A zero-credit total budget cannot admit a Play: sandbox compute is billed even when provider tools are free.',
|
|
257
|
+
422,
|
|
258
|
+
'PLAY_TOTAL_BUDGET_COMPUTE_REQUIRED',
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
throw new DeeplineError(
|
|
262
|
+
'A strict total Play budget cannot currently be admitted: provider operations, Customer DB compute, and additional sandbox sessions do not have a finite admitted upper bound.',
|
|
263
|
+
422,
|
|
264
|
+
'PLAY_TOTAL_BUDGET_UNBOUNDED',
|
|
265
|
+
);
|
|
266
|
+
}
|
|
214
267
|
if (
|
|
215
268
|
request.maxTotalCredits !== undefined &&
|
|
216
269
|
capability?.strictTotalBudget !== 'fail-closed-v1'
|
|
@@ -267,26 +320,49 @@ export async function startPlayRun(
|
|
|
267
320
|
http: PlayRunHttp,
|
|
268
321
|
request: ResolvedStartPlayRunRequest,
|
|
269
322
|
headers?: Record<string, string>,
|
|
270
|
-
|
|
271
|
-
workflowId: string;
|
|
272
|
-
orgId: string;
|
|
273
|
-
request: Record<string, unknown>;
|
|
274
|
-
}) => void | Promise<void>,
|
|
323
|
+
options?: PlayRunStartOptions,
|
|
275
324
|
): Promise<PlayRunStart> {
|
|
276
325
|
const {
|
|
277
326
|
body: submittedBody,
|
|
278
327
|
workflowId,
|
|
279
328
|
supportsCallerIntent,
|
|
280
|
-
} = await preparePlayRunAdmission(
|
|
329
|
+
} = await preparePlayRunAdmission(
|
|
330
|
+
http,
|
|
331
|
+
request,
|
|
332
|
+
options?.onSubmission,
|
|
333
|
+
options,
|
|
334
|
+
);
|
|
335
|
+
let cliAdmissionSupported = false;
|
|
281
336
|
let response: Record<string, unknown>;
|
|
282
337
|
try {
|
|
283
338
|
response = await http.post<Record<string, unknown>>(
|
|
284
|
-
PLAY_RUN_START_PATH,
|
|
339
|
+
options?.cliAdmission ? CLI_PLAY_RUN_START_PATH : PLAY_RUN_START_PATH,
|
|
285
340
|
submittedBody,
|
|
286
341
|
headers,
|
|
287
|
-
{
|
|
342
|
+
{
|
|
343
|
+
maxRetries: 0,
|
|
344
|
+
exactUrlOnly: true,
|
|
345
|
+
...(options?.signal ? { signal: options.signal } : {}),
|
|
346
|
+
...(options?.cliAdmission
|
|
347
|
+
? {
|
|
348
|
+
onResponse: (response: Response) => {
|
|
349
|
+
cliAdmissionSupported =
|
|
350
|
+
response.headers.get(CLI_PLAY_RUN_SUPPORTED_HEADER) ===
|
|
351
|
+
'true';
|
|
352
|
+
},
|
|
353
|
+
}
|
|
354
|
+
: {}),
|
|
355
|
+
},
|
|
288
356
|
);
|
|
289
357
|
} catch (error) {
|
|
358
|
+
if (
|
|
359
|
+
options?.cliAdmission &&
|
|
360
|
+
!cliAdmissionSupported &&
|
|
361
|
+
error instanceof DeeplineError &&
|
|
362
|
+
(error.statusCode === 404 || error.statusCode === 405)
|
|
363
|
+
) {
|
|
364
|
+
throw new CliPlayAdmissionUnsupportedError(error.statusCode);
|
|
365
|
+
}
|
|
290
366
|
if (
|
|
291
367
|
(error instanceof DeeplineError &&
|
|
292
368
|
['NETWORK_TIMEOUT', 'NETWORK_ERROR', 'FETCH_FAILED'].includes(
|
|
@@ -320,7 +396,18 @@ export async function startPlayRun(
|
|
|
320
396
|
}
|
|
321
397
|
throw error;
|
|
322
398
|
}
|
|
323
|
-
|
|
399
|
+
const started = normalizePlayRunStart(response);
|
|
400
|
+
if (
|
|
401
|
+
options?.cliAdmission &&
|
|
402
|
+
(!started.workflowId || started.workflowId === 'pending')
|
|
403
|
+
) {
|
|
404
|
+
throw new DeeplineError(
|
|
405
|
+
'Play admission returned no run id. Check recent runs before submitting again.',
|
|
406
|
+
undefined,
|
|
407
|
+
'PLAY_START_MISSING_RUN_ID',
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
return started;
|
|
324
411
|
}
|
|
325
412
|
|
|
326
413
|
export function isPlayRunPackage(value: unknown): value is PlayRunPackage {
|
|
@@ -367,7 +454,9 @@ export function normalizePlayRunStart(
|
|
|
367
454
|
? { dashboardUrl: runPackage.run.dashboardUrl }
|
|
368
455
|
: {}),
|
|
369
456
|
...(isTerminalPlayRunLifecycleStatus(status)
|
|
370
|
-
?
|
|
457
|
+
? raw.finalStatusView === 'full' && raw.runId === runPackage.run.id
|
|
458
|
+
? { finalStatus: raw, finalStatusView: 'full' as const }
|
|
459
|
+
: { finalStatus: runPackage }
|
|
371
460
|
: {}),
|
|
372
461
|
package: runPackage,
|
|
373
462
|
};
|
|
@@ -1018,12 +1107,13 @@ export function createSessionPlayRunHttp(
|
|
|
1018
1107
|
return parsed as T;
|
|
1019
1108
|
};
|
|
1020
1109
|
return {
|
|
1021
|
-
get: (path) => send(path, { method: 'GET' }),
|
|
1022
|
-
post: (path, body, headers) =>
|
|
1110
|
+
get: (path, options) => send(path, { method: 'GET', ...options }),
|
|
1111
|
+
post: (path, body, headers, options) =>
|
|
1023
1112
|
send(path, {
|
|
1024
1113
|
method: 'POST',
|
|
1025
1114
|
headers: { 'content-type': 'application/json', ...headers },
|
|
1026
1115
|
body: JSON.stringify(body),
|
|
1116
|
+
...(options?.signal ? { signal: options.signal } : {}),
|
|
1027
1117
|
}),
|
|
1028
1118
|
postFormData: (path, formData) =>
|
|
1029
1119
|
send(path, {
|
|
@@ -139,11 +139,14 @@ export type SdkRelease = {
|
|
|
139
139
|
*/
|
|
140
140
|
version: string;
|
|
141
141
|
/**
|
|
142
|
-
* One concise, agent-readable explanation
|
|
143
|
-
*
|
|
144
|
-
*
|
|
142
|
+
* One concise, agent-readable explanation of what a named release changed.
|
|
143
|
+
* The compatibility route shows it only to clients older than
|
|
144
|
+
* `introducedIn`, labelled with that version. `version` above is bumped on
|
|
145
|
+
* every publish while this text is written by hand, so labelling it with the
|
|
146
|
+
* latest version would repeat the same line for releases it does not
|
|
147
|
+
* describe. Keep it actionable; older installed CLIs print it too.
|
|
145
148
|
*/
|
|
146
|
-
updateSummary?: string;
|
|
149
|
+
updateSummary?: { introducedIn: string; summary: string };
|
|
147
150
|
/** Capabilities stamped into the published package's `deepline` metadata. */
|
|
148
151
|
packageCapabilities: {
|
|
149
152
|
updatePreferences: 1;
|
|
@@ -202,9 +205,12 @@ export const SDK_RELEASE = {
|
|
|
202
205
|
// getters keep their established compatibility behavior.
|
|
203
206
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
204
207
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
205
|
-
version: '0.3.
|
|
206
|
-
updateSummary:
|
|
207
|
-
'
|
|
208
|
+
version: '0.3.411',
|
|
209
|
+
updateSummary: {
|
|
210
|
+
introducedIn: '0.3.90',
|
|
211
|
+
summary:
|
|
212
|
+
'Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.',
|
|
213
|
+
},
|
|
208
214
|
packageCapabilities: {
|
|
209
215
|
updatePreferences: 1,
|
|
210
216
|
skillsGuidance: 1,
|