deepline 0.1.248 → 0.1.250
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundling-sources/sdk/src/client.ts +82 -1
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/types.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +3 -1
- package/dist/bundling-sources/shared_libs/play-runtime/coordinator-headers.ts +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-runtime-config.ts +10 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/types.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-environment.ts +44 -0
- package/dist/bundling-sources/shared_libs/play-runtime/secret-redaction.ts +18 -0
- package/dist/cli/index.js +123 -5
- package/dist/cli/index.mjs +123 -5
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +102 -2
- package/dist/index.mjs +102 -2
- package/package.json +1 -1
|
@@ -80,6 +80,13 @@ import type {
|
|
|
80
80
|
import type { PlayStagedFileRef } from './plays/local-file-discovery.js';
|
|
81
81
|
import type { PlayCompilerManifest } from '../../shared_libs/plays/compiler-manifest.js';
|
|
82
82
|
import type { EnrichCompiledConfig } from './cli/enrich-play-compiler.js';
|
|
83
|
+
import { RUNTIME_ENVIRONMENT_TOKEN_HEADER } from '../../shared_libs/play-runtime/coordinator-headers.js';
|
|
84
|
+
import {
|
|
85
|
+
normalizePlayRuntimeEnvironment,
|
|
86
|
+
normalizePlayRuntimeNamespace,
|
|
87
|
+
normalizePlayRuntimeSelection,
|
|
88
|
+
type PlayRuntimeSelection,
|
|
89
|
+
} from '../../shared_libs/play-runtime/runtime-environment.js';
|
|
83
90
|
|
|
84
91
|
const TERMINAL_PLAY_STATUSES = new Set(['completed', 'failed', 'cancelled']);
|
|
85
92
|
const INCLUDE_TOOL_METADATA_HEADER = 'x-deepline-include-tool-metadata';
|
|
@@ -109,6 +116,75 @@ function resolvePlayRunIntegrationMode(
|
|
|
109
116
|
);
|
|
110
117
|
}
|
|
111
118
|
|
|
119
|
+
function resolvePlayRunRuntimeSelection(
|
|
120
|
+
request: StartPlayRunRequest,
|
|
121
|
+
): PlayRuntimeSelection | undefined {
|
|
122
|
+
if (request.runtime !== undefined) {
|
|
123
|
+
const runtime = normalizePlayRuntimeSelection(request.runtime);
|
|
124
|
+
if (!runtime) {
|
|
125
|
+
throw new DeeplineError(
|
|
126
|
+
'runtime must be exactly { environment: "preview", namespace } with namespace matching ^[a-z][a-z0-9-]{0,30}$.',
|
|
127
|
+
undefined,
|
|
128
|
+
'INVALID_RUNTIME_SELECTION',
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
return runtime;
|
|
132
|
+
}
|
|
133
|
+
// These variables select where the app executes a run, not which app the
|
|
134
|
+
// SDK calls. DEEPLINE_API_BASE_URL still chooses the app host. Environment
|
|
135
|
+
// opts into remote preview routing, namespace names the isolated lane, and
|
|
136
|
+
// the token only authorizes that selection. Omitting all three leaves the
|
|
137
|
+
// app free to use its native runtime (local for a local app, prod for prod).
|
|
138
|
+
const configured = process.env.DEEPLINE_RUNTIME_ENVIRONMENT?.trim();
|
|
139
|
+
const configuredNamespace = process.env.DEEPLINE_RUNTIME_NAMESPACE?.trim();
|
|
140
|
+
const configuredToken =
|
|
141
|
+
process.env.DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN?.trim();
|
|
142
|
+
if (!configured) {
|
|
143
|
+
if (configuredNamespace || configuredToken) {
|
|
144
|
+
throw new DeeplineError(
|
|
145
|
+
'DEEPLINE_RUNTIME_ENVIRONMENT=preview and DEEPLINE_RUNTIME_NAMESPACE are required when runtime selection configuration is present.',
|
|
146
|
+
undefined,
|
|
147
|
+
'INVALID_RUNTIME_ENVIRONMENT',
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
const environment = normalizePlayRuntimeEnvironment(configured);
|
|
153
|
+
if (!environment) {
|
|
154
|
+
throw new DeeplineError(
|
|
155
|
+
`DEEPLINE_RUNTIME_ENVIRONMENT supports only explicit preview selection. Received "${configured}". Omit it to use the app-native runtime.`,
|
|
156
|
+
undefined,
|
|
157
|
+
'INVALID_RUNTIME_ENVIRONMENT',
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
const namespace = normalizePlayRuntimeNamespace(configuredNamespace);
|
|
161
|
+
if (!namespace) {
|
|
162
|
+
throw new DeeplineError(
|
|
163
|
+
'DEEPLINE_RUNTIME_NAMESPACE is required for preview and must match ^[a-z][a-z0-9-]{0,30}$.',
|
|
164
|
+
undefined,
|
|
165
|
+
'INVALID_RUNTIME_NAMESPACE',
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
return { environment, namespace };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function runtimeSelectionHeaders(
|
|
172
|
+
runtime: PlayRuntimeSelection | undefined,
|
|
173
|
+
): Record<string, string> | undefined {
|
|
174
|
+
if (!runtime) return undefined;
|
|
175
|
+
// Keep the credential out of the typed runtime payload. The app consumes it
|
|
176
|
+
// at the HTTP boundary and never forwards it to Fly, Absurd, or Daytona.
|
|
177
|
+
const token = process.env.DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN?.trim();
|
|
178
|
+
if (!token) {
|
|
179
|
+
throw new DeeplineError(
|
|
180
|
+
'DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN is required for explicit preview runtime selection.',
|
|
181
|
+
undefined,
|
|
182
|
+
'RUNTIME_ENVIRONMENT_TOKEN_REQUIRED',
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
return { [RUNTIME_ENVIRONMENT_TOKEN_HEADER]: token };
|
|
186
|
+
}
|
|
187
|
+
|
|
112
188
|
function normalizeTestPolicyOverrides(
|
|
113
189
|
value: unknown,
|
|
114
190
|
source: string,
|
|
@@ -1577,6 +1653,7 @@ export class DeeplineClient {
|
|
|
1577
1653
|
const testPolicyOverrides =
|
|
1578
1654
|
request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
|
|
1579
1655
|
const forceToolRefresh = request.forceToolRefresh === true;
|
|
1656
|
+
const runtime = resolvePlayRunRuntimeSelection(request);
|
|
1580
1657
|
const response = await this.http.post<Record<string, unknown>>(
|
|
1581
1658
|
'/api/v2/plays/run',
|
|
1582
1659
|
{
|
|
@@ -1619,9 +1696,10 @@ export class DeeplineClient {
|
|
|
1619
1696
|
// defaults to absurd; callers normally omit this field.
|
|
1620
1697
|
...(request.profile ? { profile: request.profile } : {}),
|
|
1621
1698
|
...(integrationMode ? { integrationMode } : {}),
|
|
1699
|
+
...(runtime ? { runtime } : {}),
|
|
1622
1700
|
...(testPolicyOverrides ? { testPolicyOverrides } : {}),
|
|
1623
1701
|
},
|
|
1624
|
-
|
|
1702
|
+
runtimeSelectionHeaders(runtime),
|
|
1625
1703
|
// A start can reach the server even when its response is lost or times
|
|
1626
1704
|
// out. Retrying this mutation without an idempotency key can create a
|
|
1627
1705
|
// second root run, so callers must resolve ambiguous failures explicitly.
|
|
@@ -1649,6 +1727,7 @@ export class DeeplineClient {
|
|
|
1649
1727
|
const testPolicyOverrides =
|
|
1650
1728
|
request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
|
|
1651
1729
|
const forceToolRefresh = request.forceToolRefresh === true;
|
|
1730
|
+
const runtime = resolvePlayRunRuntimeSelection(request);
|
|
1652
1731
|
const body = {
|
|
1653
1732
|
...(request.name ? { name: request.name } : {}),
|
|
1654
1733
|
...(request.revisionId ? { revisionId: request.revisionId } : {}),
|
|
@@ -1687,6 +1766,7 @@ export class DeeplineClient {
|
|
|
1687
1766
|
: {}),
|
|
1688
1767
|
...(request.profile ? { profile: request.profile } : {}),
|
|
1689
1768
|
...(integrationMode ? { integrationMode } : {}),
|
|
1769
|
+
...(runtime ? { runtime } : {}),
|
|
1690
1770
|
...(testPolicyOverrides ? { testPolicyOverrides } : {}),
|
|
1691
1771
|
};
|
|
1692
1772
|
for await (const event of this.http.streamSse<PlayLiveEvent>(
|
|
@@ -1694,6 +1774,7 @@ export class DeeplineClient {
|
|
|
1694
1774
|
{
|
|
1695
1775
|
method: 'POST',
|
|
1696
1776
|
body,
|
|
1777
|
+
headers: runtimeSelectionHeaders(runtime),
|
|
1697
1778
|
signal: options?.signal,
|
|
1698
1779
|
},
|
|
1699
1780
|
)) {
|
|
@@ -113,7 +113,7 @@ export const SDK_RELEASE = {
|
|
|
113
113
|
// runtime intentionally no longer compiles at publish or launch time.
|
|
114
114
|
// 0.1.242 removes the retired Workers/ESM compiler, generated bundles, and
|
|
115
115
|
// deploy-time artifact migration. Play authoring now has one CJS contract.
|
|
116
|
-
version: '0.1.
|
|
116
|
+
version: '0.1.250',
|
|
117
117
|
apiContract: '2026-07-cjs-absurd-only-play-runtime-hard-cutover',
|
|
118
118
|
supportPolicy: {
|
|
119
119
|
minimumSupported: '0.1.53',
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PlayCompilerManifest } from '../../shared_libs/plays/compiler-manifest';
|
|
2
|
+
import type { PlayRuntimeSelection } from '../../shared_libs/play-runtime/runtime-environment';
|
|
2
3
|
import type {
|
|
3
4
|
DeeplineToolCategory,
|
|
4
5
|
PlayBootstrapFinderKind,
|
|
@@ -1226,6 +1227,8 @@ export interface StartPlayRunRequest {
|
|
|
1226
1227
|
profile?: string;
|
|
1227
1228
|
/** Optional per-run provider execution mode for eval/smoke runs. */
|
|
1228
1229
|
integrationMode?: 'live' | 'eval_stub' | 'fixture';
|
|
1230
|
+
/** Internal runtime estate selection. The app host remains unchanged. */
|
|
1231
|
+
runtime?: PlayRuntimeSelection;
|
|
1229
1232
|
/** Internal/dev-only runtime policy overrides for black-box durability tests. */
|
|
1230
1233
|
testPolicyOverrides?: Record<string, unknown>;
|
|
1231
1234
|
}
|
|
@@ -6997,7 +6997,9 @@ export class PlayContextImpl {
|
|
|
6997
6997
|
Object.fromEntries(response.headers.entries()),
|
|
6998
6998
|
) as Record<string, string>,
|
|
6999
6999
|
bodyText: redactedBodyText,
|
|
7000
|
-
json: this.secretRedactor.
|
|
7000
|
+
json: this.secretRedactor.redactKnownSecrets(
|
|
7001
|
+
parseJsonOrNull(bodyText),
|
|
7002
|
+
),
|
|
7001
7003
|
};
|
|
7002
7004
|
|
|
7003
7005
|
this.checkpoint.resolvedBoundaries = {
|
|
@@ -28,6 +28,13 @@ export const WORKER_CALLBACK_URL_OVERRIDE_HEADER =
|
|
|
28
28
|
'x-deepline-worker-callback-url';
|
|
29
29
|
export const RUNTIME_SCHEDULER_SCHEMA_OVERRIDE_HEADER =
|
|
30
30
|
'x-deepline-runtime-scheduler-schema';
|
|
31
|
+
/**
|
|
32
|
+
* CLI-to-app credential used only to authorize a typed runtime-environment
|
|
33
|
+
* selection. It is deliberately separate from the coordinator credential:
|
|
34
|
+
* selecting an approved environment must not grant access to runtime callbacks.
|
|
35
|
+
*/
|
|
36
|
+
export const RUNTIME_ENVIRONMENT_TOKEN_HEADER =
|
|
37
|
+
'x-deepline-runtime-environment-token';
|
|
31
38
|
/**
|
|
32
39
|
* Internal top-level `profile=absurd` launches, including deploy canaries, use
|
|
33
40
|
* this header to pin an exact candidate release before activation. Public API
|
|
@@ -27,10 +27,17 @@ export function daytonaClientOptions(apiKey: string): DaytonaClientOptions {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export function loadDaytonaRequiredConfig(
|
|
31
|
-
|
|
30
|
+
export function loadDaytonaRequiredConfig(
|
|
31
|
+
options: {
|
|
32
|
+
environment?: 'preview' | 'production' | null;
|
|
33
|
+
} = {},
|
|
34
|
+
): DaytonaRequiredConfig {
|
|
35
|
+
const environment = options.environment ?? null;
|
|
36
|
+
const keyName =
|
|
37
|
+
environment === 'preview' ? 'DAYTONA_API_KEY_PREVIEW' : 'DAYTONA_API_KEY';
|
|
38
|
+
const apiKey = process.env[keyName]?.trim();
|
|
32
39
|
if (!apiKey) {
|
|
33
|
-
throw new Error(
|
|
40
|
+
throw new Error(`Missing required Daytona configuration: ${keyName}.`);
|
|
34
41
|
}
|
|
35
42
|
return {
|
|
36
43
|
apiKey,
|
|
@@ -624,6 +624,10 @@ export const daytonaPlayRunnerBackend: PlayRunnerBackend = {
|
|
|
624
624
|
await callbacks?.onRuntimeResourceAcquired?.({
|
|
625
625
|
kind: 'daytona_sandbox',
|
|
626
626
|
sandboxId: sandbox.id,
|
|
627
|
+
daytonaEnvironment:
|
|
628
|
+
process.env.DEEPLINE_RUNTIME_ENVIRONMENT === 'preview'
|
|
629
|
+
? 'preview'
|
|
630
|
+
: 'production',
|
|
627
631
|
billingStartedAt: acquired.billingStartedAt,
|
|
628
632
|
billingEndedAt,
|
|
629
633
|
cpu: typeof sandbox.cpu === 'number' ? sandbox.cpu : null,
|
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
export type PlayRunnerRuntimeResource = {
|
|
13
13
|
kind: 'daytona_sandbox';
|
|
14
14
|
sandboxId: string;
|
|
15
|
+
daytonaEnvironment?: 'preview' | 'production';
|
|
15
16
|
billingStartedAt: number;
|
|
16
17
|
billingEndedAt?: number | null;
|
|
17
18
|
terminalReason?: RuntimeResourceTerminalReason | null;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export const PLAY_RUNTIME_ENVIRONMENTS = ['preview'] as const;
|
|
2
|
+
|
|
3
|
+
export type PlayRuntimeEnvironment = (typeof PLAY_RUNTIME_ENVIRONMENTS)[number];
|
|
4
|
+
|
|
5
|
+
export type PlayRuntimeSelection = {
|
|
6
|
+
environment: 'preview';
|
|
7
|
+
/** Caller-named isolation scope inside a remote runtime environment. */
|
|
8
|
+
namespace: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const PLAY_RUNTIME_NAMESPACE_PATTERN = /^[a-z][a-z0-9-]{0,30}$/;
|
|
12
|
+
|
|
13
|
+
export function normalizePlayRuntimeNamespace(value: unknown): string | null {
|
|
14
|
+
if (typeof value !== 'string') return null;
|
|
15
|
+
const normalized = value.trim();
|
|
16
|
+
return PLAY_RUNTIME_NAMESPACE_PATTERN.test(normalized) ? normalized : null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Validate the selector as one value so the SDK and server cannot drift. */
|
|
20
|
+
export function normalizePlayRuntimeSelection(
|
|
21
|
+
value: unknown,
|
|
22
|
+
): PlayRuntimeSelection | null {
|
|
23
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
|
|
24
|
+
const record = value as Record<string, unknown>;
|
|
25
|
+
if (
|
|
26
|
+
Object.keys(record).some(
|
|
27
|
+
(key) => key !== 'environment' && key !== 'namespace',
|
|
28
|
+
) ||
|
|
29
|
+
record.environment !== 'preview'
|
|
30
|
+
) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const namespace = normalizePlayRuntimeNamespace(record.namespace);
|
|
34
|
+
return namespace ? { environment: 'preview', namespace } : null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function normalizePlayRuntimeEnvironment(
|
|
38
|
+
value: unknown,
|
|
39
|
+
): PlayRuntimeEnvironment | null {
|
|
40
|
+
return typeof value === 'string' &&
|
|
41
|
+
PLAY_RUNTIME_ENVIRONMENTS.includes(value as PlayRuntimeEnvironment)
|
|
42
|
+
? (value as PlayRuntimeEnvironment)
|
|
43
|
+
: null;
|
|
44
|
+
}
|
|
@@ -76,6 +76,7 @@ export function redactSecretLikeString(value: string): string {
|
|
|
76
76
|
export type SecretRedactionContext = {
|
|
77
77
|
register(value: string): void;
|
|
78
78
|
redactString(value: string): string;
|
|
79
|
+
redactKnownSecrets<T>(value: T): T;
|
|
79
80
|
redact<T>(value: T): T;
|
|
80
81
|
};
|
|
81
82
|
|
|
@@ -129,9 +130,26 @@ export function createSecretRedactionContext(
|
|
|
129
130
|
return value;
|
|
130
131
|
}
|
|
131
132
|
|
|
133
|
+
function redactKnownSecrets<T>(value: T): T {
|
|
134
|
+
if (typeof value === 'string') return redactString(value) as T;
|
|
135
|
+
if (Array.isArray(value)) {
|
|
136
|
+
return value.map((entry) => redactKnownSecrets(entry)) as T;
|
|
137
|
+
}
|
|
138
|
+
if (value && typeof value === 'object') {
|
|
139
|
+
return Object.fromEntries(
|
|
140
|
+
Object.entries(value).map(([key, entry]) => [
|
|
141
|
+
key,
|
|
142
|
+
redactKnownSecrets(entry),
|
|
143
|
+
]),
|
|
144
|
+
) as T;
|
|
145
|
+
}
|
|
146
|
+
return value;
|
|
147
|
+
}
|
|
148
|
+
|
|
132
149
|
return {
|
|
133
150
|
register,
|
|
134
151
|
redactString,
|
|
152
|
+
redactKnownSecrets,
|
|
135
153
|
redact,
|
|
136
154
|
};
|
|
137
155
|
}
|
package/dist/cli/index.js
CHANGED
|
@@ -632,7 +632,7 @@ var SDK_RELEASE = {
|
|
|
632
632
|
// runtime intentionally no longer compiles at publish or launch time.
|
|
633
633
|
// 0.1.242 removes the retired Workers/ESM compiler, generated bundles, and
|
|
634
634
|
// deploy-time artifact migration. Play authoring now has one CJS contract.
|
|
635
|
-
version: "0.1.
|
|
635
|
+
version: "0.1.250",
|
|
636
636
|
apiContract: "2026-07-cjs-absurd-only-play-runtime-hard-cutover",
|
|
637
637
|
supportPolicy: {
|
|
638
638
|
minimumSupported: "0.1.53",
|
|
@@ -790,6 +790,7 @@ var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
|
|
|
790
790
|
var COORDINATOR_URL_OVERRIDE_HEADER = "x-deepline-coordinator-url";
|
|
791
791
|
var WORKER_CALLBACK_URL_OVERRIDE_HEADER = "x-deepline-worker-callback-url";
|
|
792
792
|
var RUNTIME_SCHEDULER_SCHEMA_OVERRIDE_HEADER = "x-deepline-runtime-scheduler-schema";
|
|
793
|
+
var RUNTIME_ENVIRONMENT_TOKEN_HEADER = "x-deepline-runtime-environment-token";
|
|
793
794
|
var ABSURD_RELEASE_OVERRIDE_HEADER = "x-deepline-absurd-release";
|
|
794
795
|
var SYNTHETIC_RUN_HEADER = "x-deepline-synthetic-run";
|
|
795
796
|
|
|
@@ -1454,9 +1455,25 @@ function createSecretRedactionContext(initialValues = []) {
|
|
|
1454
1455
|
}
|
|
1455
1456
|
return value;
|
|
1456
1457
|
}
|
|
1458
|
+
function redactKnownSecrets(value) {
|
|
1459
|
+
if (typeof value === "string") return redactString(value);
|
|
1460
|
+
if (Array.isArray(value)) {
|
|
1461
|
+
return value.map((entry) => redactKnownSecrets(entry));
|
|
1462
|
+
}
|
|
1463
|
+
if (value && typeof value === "object") {
|
|
1464
|
+
return Object.fromEntries(
|
|
1465
|
+
Object.entries(value).map(([key, entry]) => [
|
|
1466
|
+
key,
|
|
1467
|
+
redactKnownSecrets(entry)
|
|
1468
|
+
])
|
|
1469
|
+
);
|
|
1470
|
+
}
|
|
1471
|
+
return value;
|
|
1472
|
+
}
|
|
1457
1473
|
return {
|
|
1458
1474
|
register,
|
|
1459
1475
|
redactString,
|
|
1476
|
+
redactKnownSecrets,
|
|
1460
1477
|
redact
|
|
1461
1478
|
};
|
|
1462
1479
|
}
|
|
@@ -2363,6 +2380,29 @@ async function* observeRunEvents(options) {
|
|
|
2363
2380
|
}
|
|
2364
2381
|
}
|
|
2365
2382
|
|
|
2383
|
+
// ../shared_libs/play-runtime/runtime-environment.ts
|
|
2384
|
+
var PLAY_RUNTIME_ENVIRONMENTS = ["preview"];
|
|
2385
|
+
var PLAY_RUNTIME_NAMESPACE_PATTERN = /^[a-z][a-z0-9-]{0,30}$/;
|
|
2386
|
+
function normalizePlayRuntimeNamespace(value) {
|
|
2387
|
+
if (typeof value !== "string") return null;
|
|
2388
|
+
const normalized = value.trim();
|
|
2389
|
+
return PLAY_RUNTIME_NAMESPACE_PATTERN.test(normalized) ? normalized : null;
|
|
2390
|
+
}
|
|
2391
|
+
function normalizePlayRuntimeSelection(value) {
|
|
2392
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
2393
|
+
const record = value;
|
|
2394
|
+
if (Object.keys(record).some(
|
|
2395
|
+
(key) => key !== "environment" && key !== "namespace"
|
|
2396
|
+
) || record.environment !== "preview") {
|
|
2397
|
+
return null;
|
|
2398
|
+
}
|
|
2399
|
+
const namespace = normalizePlayRuntimeNamespace(record.namespace);
|
|
2400
|
+
return namespace ? { environment: "preview", namespace } : null;
|
|
2401
|
+
}
|
|
2402
|
+
function normalizePlayRuntimeEnvironment(value) {
|
|
2403
|
+
return typeof value === "string" && PLAY_RUNTIME_ENVIRONMENTS.includes(value) ? value : null;
|
|
2404
|
+
}
|
|
2405
|
+
|
|
2366
2406
|
// src/client.ts
|
|
2367
2407
|
var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
2368
2408
|
var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
|
|
@@ -2385,6 +2425,61 @@ function resolvePlayRunIntegrationMode(request) {
|
|
|
2385
2425
|
request.integrationMode ?? process.env.DEEPLINE_EVAL_INTEGRATION_MODE
|
|
2386
2426
|
);
|
|
2387
2427
|
}
|
|
2428
|
+
function resolvePlayRunRuntimeSelection(request) {
|
|
2429
|
+
if (request.runtime !== void 0) {
|
|
2430
|
+
const runtime = normalizePlayRuntimeSelection(request.runtime);
|
|
2431
|
+
if (!runtime) {
|
|
2432
|
+
throw new DeeplineError(
|
|
2433
|
+
'runtime must be exactly { environment: "preview", namespace } with namespace matching ^[a-z][a-z0-9-]{0,30}$.',
|
|
2434
|
+
void 0,
|
|
2435
|
+
"INVALID_RUNTIME_SELECTION"
|
|
2436
|
+
);
|
|
2437
|
+
}
|
|
2438
|
+
return runtime;
|
|
2439
|
+
}
|
|
2440
|
+
const configured = process.env.DEEPLINE_RUNTIME_ENVIRONMENT?.trim();
|
|
2441
|
+
const configuredNamespace = process.env.DEEPLINE_RUNTIME_NAMESPACE?.trim();
|
|
2442
|
+
const configuredToken = process.env.DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN?.trim();
|
|
2443
|
+
if (!configured) {
|
|
2444
|
+
if (configuredNamespace || configuredToken) {
|
|
2445
|
+
throw new DeeplineError(
|
|
2446
|
+
"DEEPLINE_RUNTIME_ENVIRONMENT=preview and DEEPLINE_RUNTIME_NAMESPACE are required when runtime selection configuration is present.",
|
|
2447
|
+
void 0,
|
|
2448
|
+
"INVALID_RUNTIME_ENVIRONMENT"
|
|
2449
|
+
);
|
|
2450
|
+
}
|
|
2451
|
+
return void 0;
|
|
2452
|
+
}
|
|
2453
|
+
const environment = normalizePlayRuntimeEnvironment(configured);
|
|
2454
|
+
if (!environment) {
|
|
2455
|
+
throw new DeeplineError(
|
|
2456
|
+
`DEEPLINE_RUNTIME_ENVIRONMENT supports only explicit preview selection. Received "${configured}". Omit it to use the app-native runtime.`,
|
|
2457
|
+
void 0,
|
|
2458
|
+
"INVALID_RUNTIME_ENVIRONMENT"
|
|
2459
|
+
);
|
|
2460
|
+
}
|
|
2461
|
+
const namespace = normalizePlayRuntimeNamespace(configuredNamespace);
|
|
2462
|
+
if (!namespace) {
|
|
2463
|
+
throw new DeeplineError(
|
|
2464
|
+
"DEEPLINE_RUNTIME_NAMESPACE is required for preview and must match ^[a-z][a-z0-9-]{0,30}$.",
|
|
2465
|
+
void 0,
|
|
2466
|
+
"INVALID_RUNTIME_NAMESPACE"
|
|
2467
|
+
);
|
|
2468
|
+
}
|
|
2469
|
+
return { environment, namespace };
|
|
2470
|
+
}
|
|
2471
|
+
function runtimeSelectionHeaders(runtime) {
|
|
2472
|
+
if (!runtime) return void 0;
|
|
2473
|
+
const token = process.env.DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN?.trim();
|
|
2474
|
+
if (!token) {
|
|
2475
|
+
throw new DeeplineError(
|
|
2476
|
+
"DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN is required for explicit preview runtime selection.",
|
|
2477
|
+
void 0,
|
|
2478
|
+
"RUNTIME_ENVIRONMENT_TOKEN_REQUIRED"
|
|
2479
|
+
);
|
|
2480
|
+
}
|
|
2481
|
+
return { [RUNTIME_ENVIRONMENT_TOKEN_HEADER]: token };
|
|
2482
|
+
}
|
|
2388
2483
|
function normalizeTestPolicyOverrides(value, source) {
|
|
2389
2484
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
2390
2485
|
return value;
|
|
@@ -3083,6 +3178,7 @@ var DeeplineClient = class {
|
|
|
3083
3178
|
const integrationMode = resolvePlayRunIntegrationMode(request);
|
|
3084
3179
|
const testPolicyOverrides = request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
|
|
3085
3180
|
const forceToolRefresh = request.forceToolRefresh === true;
|
|
3181
|
+
const runtime = resolvePlayRunRuntimeSelection(request);
|
|
3086
3182
|
const response = await this.http.post(
|
|
3087
3183
|
"/api/v2/plays/run",
|
|
3088
3184
|
{
|
|
@@ -3109,9 +3205,10 @@ var DeeplineClient = class {
|
|
|
3109
3205
|
// defaults to absurd; callers normally omit this field.
|
|
3110
3206
|
...request.profile ? { profile: request.profile } : {},
|
|
3111
3207
|
...integrationMode ? { integrationMode } : {},
|
|
3208
|
+
...runtime ? { runtime } : {},
|
|
3112
3209
|
...testPolicyOverrides ? { testPolicyOverrides } : {}
|
|
3113
3210
|
},
|
|
3114
|
-
|
|
3211
|
+
runtimeSelectionHeaders(runtime),
|
|
3115
3212
|
// A start can reach the server even when its response is lost or times
|
|
3116
3213
|
// out. Retrying this mutation without an idempotency key can create a
|
|
3117
3214
|
// second root run, so callers must resolve ambiguous failures explicitly.
|
|
@@ -3134,6 +3231,7 @@ var DeeplineClient = class {
|
|
|
3134
3231
|
const integrationMode = resolvePlayRunIntegrationMode(request);
|
|
3135
3232
|
const testPolicyOverrides = request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
|
|
3136
3233
|
const forceToolRefresh = request.forceToolRefresh === true;
|
|
3234
|
+
const runtime = resolvePlayRunRuntimeSelection(request);
|
|
3137
3235
|
const body = {
|
|
3138
3236
|
...request.name ? { name: request.name } : {},
|
|
3139
3237
|
...request.revisionId ? { revisionId: request.revisionId } : {},
|
|
@@ -3156,6 +3254,7 @@ var DeeplineClient = class {
|
|
|
3156
3254
|
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
3157
3255
|
...request.profile ? { profile: request.profile } : {},
|
|
3158
3256
|
...integrationMode ? { integrationMode } : {},
|
|
3257
|
+
...runtime ? { runtime } : {},
|
|
3159
3258
|
...testPolicyOverrides ? { testPolicyOverrides } : {}
|
|
3160
3259
|
};
|
|
3161
3260
|
for await (const event of this.http.streamSse(
|
|
@@ -3163,6 +3262,7 @@ var DeeplineClient = class {
|
|
|
3163
3262
|
{
|
|
3164
3263
|
method: "POST",
|
|
3165
3264
|
body,
|
|
3265
|
+
headers: runtimeSelectionHeaders(runtime),
|
|
3166
3266
|
signal: options?.signal
|
|
3167
3267
|
}
|
|
3168
3268
|
)) {
|
|
@@ -24350,24 +24450,42 @@ function renderAvailableToolsText(payload) {
|
|
|
24350
24450
|
const returned = asFiniteNumber(payload.returned) ?? tools.length;
|
|
24351
24451
|
const total = asFiniteNumber(payload.total);
|
|
24352
24452
|
const lines = [
|
|
24353
|
-
total !== void 0 ? `
|
|
24453
|
+
total !== void 0 ? `Signal Radar types you can deploy (${returned} of ${total}):` : "Signal Radar types you can deploy:"
|
|
24354
24454
|
];
|
|
24455
|
+
let currentProvider;
|
|
24355
24456
|
for (const raw of tools) {
|
|
24356
24457
|
const entry = asRecord(raw);
|
|
24357
24458
|
const id = entry ? asString(entry.tool) : void 0;
|
|
24358
24459
|
if (!entry || !id) continue;
|
|
24359
24460
|
const name = asString(entry.name) ?? asString(entry.display_name);
|
|
24360
24461
|
const deployedCount = asFiniteNumber(entry.deployed_count);
|
|
24462
|
+
const description = asString(entry.description);
|
|
24463
|
+
const streams = Array.isArray(entry.streams) ? entry.streams.map((stream) => asString(stream)).filter((stream) => Boolean(stream)) : [];
|
|
24464
|
+
const provider = id.split(".")[0];
|
|
24465
|
+
if (provider && provider !== currentProvider) {
|
|
24466
|
+
currentProvider = provider;
|
|
24467
|
+
lines.push("", ` ${provider}:`);
|
|
24468
|
+
}
|
|
24361
24469
|
lines.push(
|
|
24362
|
-
`
|
|
24470
|
+
` ${id.split(".").slice(1).join(".") || id}${name ? ` \u2014 ${name}` : ""}${deployedCount !== void 0 ? ` (${deployedCount} deployed)` : ""}`
|
|
24363
24471
|
);
|
|
24472
|
+
if (description) lines.push(` ${description}`);
|
|
24473
|
+
if (streams.length > 0) {
|
|
24474
|
+
lines.push(` emits: ${streams.join(", ")}`);
|
|
24475
|
+
}
|
|
24364
24476
|
}
|
|
24365
24477
|
if (payload.is_truncated === true) {
|
|
24366
24478
|
lines.push("List truncated; raise --limit to see more.");
|
|
24367
24479
|
}
|
|
24368
24480
|
lines.push(
|
|
24369
24481
|
"",
|
|
24370
|
-
"
|
|
24482
|
+
"Next:",
|
|
24483
|
+
" Inspect payload fields, output columns, and a play binding:",
|
|
24484
|
+
" deepline monitors available <provider.tool> --json",
|
|
24485
|
+
" See monitors already deployed in this workspace:",
|
|
24486
|
+
" deepline monitors list",
|
|
24487
|
+
" Validate a monitor definition before deploying:",
|
|
24488
|
+
` deepline monitors check '{"key":"my-radar","tool":"<provider.tool>","payload":{...}}'`
|
|
24371
24489
|
);
|
|
24372
24490
|
return `${lines.join("\n")}
|
|
24373
24491
|
`;
|
package/dist/cli/index.mjs
CHANGED
|
@@ -617,7 +617,7 @@ var SDK_RELEASE = {
|
|
|
617
617
|
// runtime intentionally no longer compiles at publish or launch time.
|
|
618
618
|
// 0.1.242 removes the retired Workers/ESM compiler, generated bundles, and
|
|
619
619
|
// deploy-time artifact migration. Play authoring now has one CJS contract.
|
|
620
|
-
version: "0.1.
|
|
620
|
+
version: "0.1.250",
|
|
621
621
|
apiContract: "2026-07-cjs-absurd-only-play-runtime-hard-cutover",
|
|
622
622
|
supportPolicy: {
|
|
623
623
|
minimumSupported: "0.1.53",
|
|
@@ -775,6 +775,7 @@ var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
|
|
|
775
775
|
var COORDINATOR_URL_OVERRIDE_HEADER = "x-deepline-coordinator-url";
|
|
776
776
|
var WORKER_CALLBACK_URL_OVERRIDE_HEADER = "x-deepline-worker-callback-url";
|
|
777
777
|
var RUNTIME_SCHEDULER_SCHEMA_OVERRIDE_HEADER = "x-deepline-runtime-scheduler-schema";
|
|
778
|
+
var RUNTIME_ENVIRONMENT_TOKEN_HEADER = "x-deepline-runtime-environment-token";
|
|
778
779
|
var ABSURD_RELEASE_OVERRIDE_HEADER = "x-deepline-absurd-release";
|
|
779
780
|
var SYNTHETIC_RUN_HEADER = "x-deepline-synthetic-run";
|
|
780
781
|
|
|
@@ -1439,9 +1440,25 @@ function createSecretRedactionContext(initialValues = []) {
|
|
|
1439
1440
|
}
|
|
1440
1441
|
return value;
|
|
1441
1442
|
}
|
|
1443
|
+
function redactKnownSecrets(value) {
|
|
1444
|
+
if (typeof value === "string") return redactString(value);
|
|
1445
|
+
if (Array.isArray(value)) {
|
|
1446
|
+
return value.map((entry) => redactKnownSecrets(entry));
|
|
1447
|
+
}
|
|
1448
|
+
if (value && typeof value === "object") {
|
|
1449
|
+
return Object.fromEntries(
|
|
1450
|
+
Object.entries(value).map(([key, entry]) => [
|
|
1451
|
+
key,
|
|
1452
|
+
redactKnownSecrets(entry)
|
|
1453
|
+
])
|
|
1454
|
+
);
|
|
1455
|
+
}
|
|
1456
|
+
return value;
|
|
1457
|
+
}
|
|
1442
1458
|
return {
|
|
1443
1459
|
register,
|
|
1444
1460
|
redactString,
|
|
1461
|
+
redactKnownSecrets,
|
|
1445
1462
|
redact
|
|
1446
1463
|
};
|
|
1447
1464
|
}
|
|
@@ -2348,6 +2365,29 @@ async function* observeRunEvents(options) {
|
|
|
2348
2365
|
}
|
|
2349
2366
|
}
|
|
2350
2367
|
|
|
2368
|
+
// ../shared_libs/play-runtime/runtime-environment.ts
|
|
2369
|
+
var PLAY_RUNTIME_ENVIRONMENTS = ["preview"];
|
|
2370
|
+
var PLAY_RUNTIME_NAMESPACE_PATTERN = /^[a-z][a-z0-9-]{0,30}$/;
|
|
2371
|
+
function normalizePlayRuntimeNamespace(value) {
|
|
2372
|
+
if (typeof value !== "string") return null;
|
|
2373
|
+
const normalized = value.trim();
|
|
2374
|
+
return PLAY_RUNTIME_NAMESPACE_PATTERN.test(normalized) ? normalized : null;
|
|
2375
|
+
}
|
|
2376
|
+
function normalizePlayRuntimeSelection(value) {
|
|
2377
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
2378
|
+
const record = value;
|
|
2379
|
+
if (Object.keys(record).some(
|
|
2380
|
+
(key) => key !== "environment" && key !== "namespace"
|
|
2381
|
+
) || record.environment !== "preview") {
|
|
2382
|
+
return null;
|
|
2383
|
+
}
|
|
2384
|
+
const namespace = normalizePlayRuntimeNamespace(record.namespace);
|
|
2385
|
+
return namespace ? { environment: "preview", namespace } : null;
|
|
2386
|
+
}
|
|
2387
|
+
function normalizePlayRuntimeEnvironment(value) {
|
|
2388
|
+
return typeof value === "string" && PLAY_RUNTIME_ENVIRONMENTS.includes(value) ? value : null;
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2351
2391
|
// src/client.ts
|
|
2352
2392
|
var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
2353
2393
|
var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
|
|
@@ -2370,6 +2410,61 @@ function resolvePlayRunIntegrationMode(request) {
|
|
|
2370
2410
|
request.integrationMode ?? process.env.DEEPLINE_EVAL_INTEGRATION_MODE
|
|
2371
2411
|
);
|
|
2372
2412
|
}
|
|
2413
|
+
function resolvePlayRunRuntimeSelection(request) {
|
|
2414
|
+
if (request.runtime !== void 0) {
|
|
2415
|
+
const runtime = normalizePlayRuntimeSelection(request.runtime);
|
|
2416
|
+
if (!runtime) {
|
|
2417
|
+
throw new DeeplineError(
|
|
2418
|
+
'runtime must be exactly { environment: "preview", namespace } with namespace matching ^[a-z][a-z0-9-]{0,30}$.',
|
|
2419
|
+
void 0,
|
|
2420
|
+
"INVALID_RUNTIME_SELECTION"
|
|
2421
|
+
);
|
|
2422
|
+
}
|
|
2423
|
+
return runtime;
|
|
2424
|
+
}
|
|
2425
|
+
const configured = process.env.DEEPLINE_RUNTIME_ENVIRONMENT?.trim();
|
|
2426
|
+
const configuredNamespace = process.env.DEEPLINE_RUNTIME_NAMESPACE?.trim();
|
|
2427
|
+
const configuredToken = process.env.DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN?.trim();
|
|
2428
|
+
if (!configured) {
|
|
2429
|
+
if (configuredNamespace || configuredToken) {
|
|
2430
|
+
throw new DeeplineError(
|
|
2431
|
+
"DEEPLINE_RUNTIME_ENVIRONMENT=preview and DEEPLINE_RUNTIME_NAMESPACE are required when runtime selection configuration is present.",
|
|
2432
|
+
void 0,
|
|
2433
|
+
"INVALID_RUNTIME_ENVIRONMENT"
|
|
2434
|
+
);
|
|
2435
|
+
}
|
|
2436
|
+
return void 0;
|
|
2437
|
+
}
|
|
2438
|
+
const environment = normalizePlayRuntimeEnvironment(configured);
|
|
2439
|
+
if (!environment) {
|
|
2440
|
+
throw new DeeplineError(
|
|
2441
|
+
`DEEPLINE_RUNTIME_ENVIRONMENT supports only explicit preview selection. Received "${configured}". Omit it to use the app-native runtime.`,
|
|
2442
|
+
void 0,
|
|
2443
|
+
"INVALID_RUNTIME_ENVIRONMENT"
|
|
2444
|
+
);
|
|
2445
|
+
}
|
|
2446
|
+
const namespace = normalizePlayRuntimeNamespace(configuredNamespace);
|
|
2447
|
+
if (!namespace) {
|
|
2448
|
+
throw new DeeplineError(
|
|
2449
|
+
"DEEPLINE_RUNTIME_NAMESPACE is required for preview and must match ^[a-z][a-z0-9-]{0,30}$.",
|
|
2450
|
+
void 0,
|
|
2451
|
+
"INVALID_RUNTIME_NAMESPACE"
|
|
2452
|
+
);
|
|
2453
|
+
}
|
|
2454
|
+
return { environment, namespace };
|
|
2455
|
+
}
|
|
2456
|
+
function runtimeSelectionHeaders(runtime) {
|
|
2457
|
+
if (!runtime) return void 0;
|
|
2458
|
+
const token = process.env.DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN?.trim();
|
|
2459
|
+
if (!token) {
|
|
2460
|
+
throw new DeeplineError(
|
|
2461
|
+
"DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN is required for explicit preview runtime selection.",
|
|
2462
|
+
void 0,
|
|
2463
|
+
"RUNTIME_ENVIRONMENT_TOKEN_REQUIRED"
|
|
2464
|
+
);
|
|
2465
|
+
}
|
|
2466
|
+
return { [RUNTIME_ENVIRONMENT_TOKEN_HEADER]: token };
|
|
2467
|
+
}
|
|
2373
2468
|
function normalizeTestPolicyOverrides(value, source) {
|
|
2374
2469
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
2375
2470
|
return value;
|
|
@@ -3068,6 +3163,7 @@ var DeeplineClient = class {
|
|
|
3068
3163
|
const integrationMode = resolvePlayRunIntegrationMode(request);
|
|
3069
3164
|
const testPolicyOverrides = request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
|
|
3070
3165
|
const forceToolRefresh = request.forceToolRefresh === true;
|
|
3166
|
+
const runtime = resolvePlayRunRuntimeSelection(request);
|
|
3071
3167
|
const response = await this.http.post(
|
|
3072
3168
|
"/api/v2/plays/run",
|
|
3073
3169
|
{
|
|
@@ -3094,9 +3190,10 @@ var DeeplineClient = class {
|
|
|
3094
3190
|
// defaults to absurd; callers normally omit this field.
|
|
3095
3191
|
...request.profile ? { profile: request.profile } : {},
|
|
3096
3192
|
...integrationMode ? { integrationMode } : {},
|
|
3193
|
+
...runtime ? { runtime } : {},
|
|
3097
3194
|
...testPolicyOverrides ? { testPolicyOverrides } : {}
|
|
3098
3195
|
},
|
|
3099
|
-
|
|
3196
|
+
runtimeSelectionHeaders(runtime),
|
|
3100
3197
|
// A start can reach the server even when its response is lost or times
|
|
3101
3198
|
// out. Retrying this mutation without an idempotency key can create a
|
|
3102
3199
|
// second root run, so callers must resolve ambiguous failures explicitly.
|
|
@@ -3119,6 +3216,7 @@ var DeeplineClient = class {
|
|
|
3119
3216
|
const integrationMode = resolvePlayRunIntegrationMode(request);
|
|
3120
3217
|
const testPolicyOverrides = request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
|
|
3121
3218
|
const forceToolRefresh = request.forceToolRefresh === true;
|
|
3219
|
+
const runtime = resolvePlayRunRuntimeSelection(request);
|
|
3122
3220
|
const body = {
|
|
3123
3221
|
...request.name ? { name: request.name } : {},
|
|
3124
3222
|
...request.revisionId ? { revisionId: request.revisionId } : {},
|
|
@@ -3141,6 +3239,7 @@ var DeeplineClient = class {
|
|
|
3141
3239
|
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
3142
3240
|
...request.profile ? { profile: request.profile } : {},
|
|
3143
3241
|
...integrationMode ? { integrationMode } : {},
|
|
3242
|
+
...runtime ? { runtime } : {},
|
|
3144
3243
|
...testPolicyOverrides ? { testPolicyOverrides } : {}
|
|
3145
3244
|
};
|
|
3146
3245
|
for await (const event of this.http.streamSse(
|
|
@@ -3148,6 +3247,7 @@ var DeeplineClient = class {
|
|
|
3148
3247
|
{
|
|
3149
3248
|
method: "POST",
|
|
3150
3249
|
body,
|
|
3250
|
+
headers: runtimeSelectionHeaders(runtime),
|
|
3151
3251
|
signal: options?.signal
|
|
3152
3252
|
}
|
|
3153
3253
|
)) {
|
|
@@ -24386,24 +24486,42 @@ function renderAvailableToolsText(payload) {
|
|
|
24386
24486
|
const returned = asFiniteNumber(payload.returned) ?? tools.length;
|
|
24387
24487
|
const total = asFiniteNumber(payload.total);
|
|
24388
24488
|
const lines = [
|
|
24389
|
-
total !== void 0 ? `
|
|
24489
|
+
total !== void 0 ? `Signal Radar types you can deploy (${returned} of ${total}):` : "Signal Radar types you can deploy:"
|
|
24390
24490
|
];
|
|
24491
|
+
let currentProvider;
|
|
24391
24492
|
for (const raw of tools) {
|
|
24392
24493
|
const entry = asRecord(raw);
|
|
24393
24494
|
const id = entry ? asString(entry.tool) : void 0;
|
|
24394
24495
|
if (!entry || !id) continue;
|
|
24395
24496
|
const name = asString(entry.name) ?? asString(entry.display_name);
|
|
24396
24497
|
const deployedCount = asFiniteNumber(entry.deployed_count);
|
|
24498
|
+
const description = asString(entry.description);
|
|
24499
|
+
const streams = Array.isArray(entry.streams) ? entry.streams.map((stream) => asString(stream)).filter((stream) => Boolean(stream)) : [];
|
|
24500
|
+
const provider = id.split(".")[0];
|
|
24501
|
+
if (provider && provider !== currentProvider) {
|
|
24502
|
+
currentProvider = provider;
|
|
24503
|
+
lines.push("", ` ${provider}:`);
|
|
24504
|
+
}
|
|
24397
24505
|
lines.push(
|
|
24398
|
-
`
|
|
24506
|
+
` ${id.split(".").slice(1).join(".") || id}${name ? ` \u2014 ${name}` : ""}${deployedCount !== void 0 ? ` (${deployedCount} deployed)` : ""}`
|
|
24399
24507
|
);
|
|
24508
|
+
if (description) lines.push(` ${description}`);
|
|
24509
|
+
if (streams.length > 0) {
|
|
24510
|
+
lines.push(` emits: ${streams.join(", ")}`);
|
|
24511
|
+
}
|
|
24400
24512
|
}
|
|
24401
24513
|
if (payload.is_truncated === true) {
|
|
24402
24514
|
lines.push("List truncated; raise --limit to see more.");
|
|
24403
24515
|
}
|
|
24404
24516
|
lines.push(
|
|
24405
24517
|
"",
|
|
24406
|
-
"
|
|
24518
|
+
"Next:",
|
|
24519
|
+
" Inspect payload fields, output columns, and a play binding:",
|
|
24520
|
+
" deepline monitors available <provider.tool> --json",
|
|
24521
|
+
" See monitors already deployed in this workspace:",
|
|
24522
|
+
" deepline monitors list",
|
|
24523
|
+
" Validate a monitor definition before deploying:",
|
|
24524
|
+
` deepline monitors check '{"key":"my-radar","tool":"<provider.tool>","payload":{...}}'`
|
|
24407
24525
|
);
|
|
24408
24526
|
return `${lines.join("\n")}
|
|
24409
24527
|
`;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { a as PlayCompilerManifest } from './compiler-manifest-DlE7dnRm.mjs';
|
|
2
2
|
|
|
3
|
+
type PlayRuntimeSelection = {
|
|
4
|
+
environment: 'preview';
|
|
5
|
+
/** Caller-named isolation scope inside a remote runtime environment. */
|
|
6
|
+
namespace: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
3
9
|
declare const DEEPLINE_TOOL_CATEGORIES: readonly ["company_search", "people_search", "people_enrich", "email_finder", "email_verify", "phone_finder", "phone_verify", "identity_resolution", "reverse_lookup", "enrichment", "batch", "premium", "free"];
|
|
4
10
|
type DeeplineToolCategory = (typeof DEEPLINE_TOOL_CATEGORIES)[number] | (string & {});
|
|
5
11
|
declare const PLAY_BOOTSTRAP_TEMPLATES: readonly ["people-list", "company-list", "people-email", "people-phone", "company-people", "company-people-email", "company-people-phone"];
|
|
@@ -1194,6 +1200,8 @@ interface StartPlayRunRequest {
|
|
|
1194
1200
|
profile?: string;
|
|
1195
1201
|
/** Optional per-run provider execution mode for eval/smoke runs. */
|
|
1196
1202
|
integrationMode?: 'live' | 'eval_stub' | 'fixture';
|
|
1203
|
+
/** Internal runtime estate selection. The app host remains unchanged. */
|
|
1204
|
+
runtime?: PlayRuntimeSelection;
|
|
1197
1205
|
/** Internal/dev-only runtime policy overrides for black-box durability tests. */
|
|
1198
1206
|
testPolicyOverrides?: Record<string, unknown>;
|
|
1199
1207
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { a as PlayCompilerManifest } from './compiler-manifest-DlE7dnRm.js';
|
|
2
2
|
|
|
3
|
+
type PlayRuntimeSelection = {
|
|
4
|
+
environment: 'preview';
|
|
5
|
+
/** Caller-named isolation scope inside a remote runtime environment. */
|
|
6
|
+
namespace: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
3
9
|
declare const DEEPLINE_TOOL_CATEGORIES: readonly ["company_search", "people_search", "people_enrich", "email_finder", "email_verify", "phone_finder", "phone_verify", "identity_resolution", "reverse_lookup", "enrichment", "batch", "premium", "free"];
|
|
4
10
|
type DeeplineToolCategory = (typeof DEEPLINE_TOOL_CATEGORIES)[number] | (string & {});
|
|
5
11
|
declare const PLAY_BOOTSTRAP_TEMPLATES: readonly ["people-list", "company-list", "people-email", "people-phone", "company-people", "company-people-email", "company-people-phone"];
|
|
@@ -1194,6 +1200,8 @@ interface StartPlayRunRequest {
|
|
|
1194
1200
|
profile?: string;
|
|
1195
1201
|
/** Optional per-run provider execution mode for eval/smoke runs. */
|
|
1196
1202
|
integrationMode?: 'live' | 'eval_stub' | 'fixture';
|
|
1203
|
+
/** Internal runtime estate selection. The app host remains unchanged. */
|
|
1204
|
+
runtime?: PlayRuntimeSelection;
|
|
1197
1205
|
/** Internal/dev-only runtime policy overrides for black-box durability tests. */
|
|
1198
1206
|
testPolicyOverrides?: Record<string, unknown>;
|
|
1199
1207
|
}
|
package/dist/index.js
CHANGED
|
@@ -431,7 +431,7 @@ var SDK_RELEASE = {
|
|
|
431
431
|
// runtime intentionally no longer compiles at publish or launch time.
|
|
432
432
|
// 0.1.242 removes the retired Workers/ESM compiler, generated bundles, and
|
|
433
433
|
// deploy-time artifact migration. Play authoring now has one CJS contract.
|
|
434
|
-
version: "0.1.
|
|
434
|
+
version: "0.1.250",
|
|
435
435
|
apiContract: "2026-07-cjs-absurd-only-play-runtime-hard-cutover",
|
|
436
436
|
supportPolicy: {
|
|
437
437
|
minimumSupported: "0.1.53",
|
|
@@ -589,6 +589,7 @@ var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
|
|
|
589
589
|
var COORDINATOR_URL_OVERRIDE_HEADER = "x-deepline-coordinator-url";
|
|
590
590
|
var WORKER_CALLBACK_URL_OVERRIDE_HEADER = "x-deepline-worker-callback-url";
|
|
591
591
|
var RUNTIME_SCHEDULER_SCHEMA_OVERRIDE_HEADER = "x-deepline-runtime-scheduler-schema";
|
|
592
|
+
var RUNTIME_ENVIRONMENT_TOKEN_HEADER = "x-deepline-runtime-environment-token";
|
|
592
593
|
var ABSURD_RELEASE_OVERRIDE_HEADER = "x-deepline-absurd-release";
|
|
593
594
|
var SYNTHETIC_RUN_HEADER = "x-deepline-synthetic-run";
|
|
594
595
|
|
|
@@ -1253,9 +1254,25 @@ function createSecretRedactionContext(initialValues = []) {
|
|
|
1253
1254
|
}
|
|
1254
1255
|
return value;
|
|
1255
1256
|
}
|
|
1257
|
+
function redactKnownSecrets(value) {
|
|
1258
|
+
if (typeof value === "string") return redactString(value);
|
|
1259
|
+
if (Array.isArray(value)) {
|
|
1260
|
+
return value.map((entry) => redactKnownSecrets(entry));
|
|
1261
|
+
}
|
|
1262
|
+
if (value && typeof value === "object") {
|
|
1263
|
+
return Object.fromEntries(
|
|
1264
|
+
Object.entries(value).map(([key, entry]) => [
|
|
1265
|
+
key,
|
|
1266
|
+
redactKnownSecrets(entry)
|
|
1267
|
+
])
|
|
1268
|
+
);
|
|
1269
|
+
}
|
|
1270
|
+
return value;
|
|
1271
|
+
}
|
|
1256
1272
|
return {
|
|
1257
1273
|
register,
|
|
1258
1274
|
redactString,
|
|
1275
|
+
redactKnownSecrets,
|
|
1259
1276
|
redact
|
|
1260
1277
|
};
|
|
1261
1278
|
}
|
|
@@ -2162,6 +2179,29 @@ async function* observeRunEvents(options) {
|
|
|
2162
2179
|
}
|
|
2163
2180
|
}
|
|
2164
2181
|
|
|
2182
|
+
// ../shared_libs/play-runtime/runtime-environment.ts
|
|
2183
|
+
var PLAY_RUNTIME_ENVIRONMENTS = ["preview"];
|
|
2184
|
+
var PLAY_RUNTIME_NAMESPACE_PATTERN = /^[a-z][a-z0-9-]{0,30}$/;
|
|
2185
|
+
function normalizePlayRuntimeNamespace(value) {
|
|
2186
|
+
if (typeof value !== "string") return null;
|
|
2187
|
+
const normalized = value.trim();
|
|
2188
|
+
return PLAY_RUNTIME_NAMESPACE_PATTERN.test(normalized) ? normalized : null;
|
|
2189
|
+
}
|
|
2190
|
+
function normalizePlayRuntimeSelection(value) {
|
|
2191
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
2192
|
+
const record = value;
|
|
2193
|
+
if (Object.keys(record).some(
|
|
2194
|
+
(key) => key !== "environment" && key !== "namespace"
|
|
2195
|
+
) || record.environment !== "preview") {
|
|
2196
|
+
return null;
|
|
2197
|
+
}
|
|
2198
|
+
const namespace = normalizePlayRuntimeNamespace(record.namespace);
|
|
2199
|
+
return namespace ? { environment: "preview", namespace } : null;
|
|
2200
|
+
}
|
|
2201
|
+
function normalizePlayRuntimeEnvironment(value) {
|
|
2202
|
+
return typeof value === "string" && PLAY_RUNTIME_ENVIRONMENTS.includes(value) ? value : null;
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2165
2205
|
// src/client.ts
|
|
2166
2206
|
var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
2167
2207
|
var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
|
|
@@ -2184,6 +2224,61 @@ function resolvePlayRunIntegrationMode(request) {
|
|
|
2184
2224
|
request.integrationMode ?? process.env.DEEPLINE_EVAL_INTEGRATION_MODE
|
|
2185
2225
|
);
|
|
2186
2226
|
}
|
|
2227
|
+
function resolvePlayRunRuntimeSelection(request) {
|
|
2228
|
+
if (request.runtime !== void 0) {
|
|
2229
|
+
const runtime = normalizePlayRuntimeSelection(request.runtime);
|
|
2230
|
+
if (!runtime) {
|
|
2231
|
+
throw new DeeplineError(
|
|
2232
|
+
'runtime must be exactly { environment: "preview", namespace } with namespace matching ^[a-z][a-z0-9-]{0,30}$.',
|
|
2233
|
+
void 0,
|
|
2234
|
+
"INVALID_RUNTIME_SELECTION"
|
|
2235
|
+
);
|
|
2236
|
+
}
|
|
2237
|
+
return runtime;
|
|
2238
|
+
}
|
|
2239
|
+
const configured = process.env.DEEPLINE_RUNTIME_ENVIRONMENT?.trim();
|
|
2240
|
+
const configuredNamespace = process.env.DEEPLINE_RUNTIME_NAMESPACE?.trim();
|
|
2241
|
+
const configuredToken = process.env.DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN?.trim();
|
|
2242
|
+
if (!configured) {
|
|
2243
|
+
if (configuredNamespace || configuredToken) {
|
|
2244
|
+
throw new DeeplineError(
|
|
2245
|
+
"DEEPLINE_RUNTIME_ENVIRONMENT=preview and DEEPLINE_RUNTIME_NAMESPACE are required when runtime selection configuration is present.",
|
|
2246
|
+
void 0,
|
|
2247
|
+
"INVALID_RUNTIME_ENVIRONMENT"
|
|
2248
|
+
);
|
|
2249
|
+
}
|
|
2250
|
+
return void 0;
|
|
2251
|
+
}
|
|
2252
|
+
const environment = normalizePlayRuntimeEnvironment(configured);
|
|
2253
|
+
if (!environment) {
|
|
2254
|
+
throw new DeeplineError(
|
|
2255
|
+
`DEEPLINE_RUNTIME_ENVIRONMENT supports only explicit preview selection. Received "${configured}". Omit it to use the app-native runtime.`,
|
|
2256
|
+
void 0,
|
|
2257
|
+
"INVALID_RUNTIME_ENVIRONMENT"
|
|
2258
|
+
);
|
|
2259
|
+
}
|
|
2260
|
+
const namespace = normalizePlayRuntimeNamespace(configuredNamespace);
|
|
2261
|
+
if (!namespace) {
|
|
2262
|
+
throw new DeeplineError(
|
|
2263
|
+
"DEEPLINE_RUNTIME_NAMESPACE is required for preview and must match ^[a-z][a-z0-9-]{0,30}$.",
|
|
2264
|
+
void 0,
|
|
2265
|
+
"INVALID_RUNTIME_NAMESPACE"
|
|
2266
|
+
);
|
|
2267
|
+
}
|
|
2268
|
+
return { environment, namespace };
|
|
2269
|
+
}
|
|
2270
|
+
function runtimeSelectionHeaders(runtime) {
|
|
2271
|
+
if (!runtime) return void 0;
|
|
2272
|
+
const token = process.env.DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN?.trim();
|
|
2273
|
+
if (!token) {
|
|
2274
|
+
throw new DeeplineError(
|
|
2275
|
+
"DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN is required for explicit preview runtime selection.",
|
|
2276
|
+
void 0,
|
|
2277
|
+
"RUNTIME_ENVIRONMENT_TOKEN_REQUIRED"
|
|
2278
|
+
);
|
|
2279
|
+
}
|
|
2280
|
+
return { [RUNTIME_ENVIRONMENT_TOKEN_HEADER]: token };
|
|
2281
|
+
}
|
|
2187
2282
|
function normalizeTestPolicyOverrides(value, source) {
|
|
2188
2283
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
2189
2284
|
return value;
|
|
@@ -2882,6 +2977,7 @@ var DeeplineClient = class {
|
|
|
2882
2977
|
const integrationMode = resolvePlayRunIntegrationMode(request);
|
|
2883
2978
|
const testPolicyOverrides = request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
|
|
2884
2979
|
const forceToolRefresh = request.forceToolRefresh === true;
|
|
2980
|
+
const runtime = resolvePlayRunRuntimeSelection(request);
|
|
2885
2981
|
const response = await this.http.post(
|
|
2886
2982
|
"/api/v2/plays/run",
|
|
2887
2983
|
{
|
|
@@ -2908,9 +3004,10 @@ var DeeplineClient = class {
|
|
|
2908
3004
|
// defaults to absurd; callers normally omit this field.
|
|
2909
3005
|
...request.profile ? { profile: request.profile } : {},
|
|
2910
3006
|
...integrationMode ? { integrationMode } : {},
|
|
3007
|
+
...runtime ? { runtime } : {},
|
|
2911
3008
|
...testPolicyOverrides ? { testPolicyOverrides } : {}
|
|
2912
3009
|
},
|
|
2913
|
-
|
|
3010
|
+
runtimeSelectionHeaders(runtime),
|
|
2914
3011
|
// A start can reach the server even when its response is lost or times
|
|
2915
3012
|
// out. Retrying this mutation without an idempotency key can create a
|
|
2916
3013
|
// second root run, so callers must resolve ambiguous failures explicitly.
|
|
@@ -2933,6 +3030,7 @@ var DeeplineClient = class {
|
|
|
2933
3030
|
const integrationMode = resolvePlayRunIntegrationMode(request);
|
|
2934
3031
|
const testPolicyOverrides = request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
|
|
2935
3032
|
const forceToolRefresh = request.forceToolRefresh === true;
|
|
3033
|
+
const runtime = resolvePlayRunRuntimeSelection(request);
|
|
2936
3034
|
const body = {
|
|
2937
3035
|
...request.name ? { name: request.name } : {},
|
|
2938
3036
|
...request.revisionId ? { revisionId: request.revisionId } : {},
|
|
@@ -2955,6 +3053,7 @@ var DeeplineClient = class {
|
|
|
2955
3053
|
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
2956
3054
|
...request.profile ? { profile: request.profile } : {},
|
|
2957
3055
|
...integrationMode ? { integrationMode } : {},
|
|
3056
|
+
...runtime ? { runtime } : {},
|
|
2958
3057
|
...testPolicyOverrides ? { testPolicyOverrides } : {}
|
|
2959
3058
|
};
|
|
2960
3059
|
for await (const event of this.http.streamSse(
|
|
@@ -2962,6 +3061,7 @@ var DeeplineClient = class {
|
|
|
2962
3061
|
{
|
|
2963
3062
|
method: "POST",
|
|
2964
3063
|
body,
|
|
3064
|
+
headers: runtimeSelectionHeaders(runtime),
|
|
2965
3065
|
signal: options?.signal
|
|
2966
3066
|
}
|
|
2967
3067
|
)) {
|
package/dist/index.mjs
CHANGED
|
@@ -361,7 +361,7 @@ var SDK_RELEASE = {
|
|
|
361
361
|
// runtime intentionally no longer compiles at publish or launch time.
|
|
362
362
|
// 0.1.242 removes the retired Workers/ESM compiler, generated bundles, and
|
|
363
363
|
// deploy-time artifact migration. Play authoring now has one CJS contract.
|
|
364
|
-
version: "0.1.
|
|
364
|
+
version: "0.1.250",
|
|
365
365
|
apiContract: "2026-07-cjs-absurd-only-play-runtime-hard-cutover",
|
|
366
366
|
supportPolicy: {
|
|
367
367
|
minimumSupported: "0.1.53",
|
|
@@ -519,6 +519,7 @@ var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
|
|
|
519
519
|
var COORDINATOR_URL_OVERRIDE_HEADER = "x-deepline-coordinator-url";
|
|
520
520
|
var WORKER_CALLBACK_URL_OVERRIDE_HEADER = "x-deepline-worker-callback-url";
|
|
521
521
|
var RUNTIME_SCHEDULER_SCHEMA_OVERRIDE_HEADER = "x-deepline-runtime-scheduler-schema";
|
|
522
|
+
var RUNTIME_ENVIRONMENT_TOKEN_HEADER = "x-deepline-runtime-environment-token";
|
|
522
523
|
var ABSURD_RELEASE_OVERRIDE_HEADER = "x-deepline-absurd-release";
|
|
523
524
|
var SYNTHETIC_RUN_HEADER = "x-deepline-synthetic-run";
|
|
524
525
|
|
|
@@ -1183,9 +1184,25 @@ function createSecretRedactionContext(initialValues = []) {
|
|
|
1183
1184
|
}
|
|
1184
1185
|
return value;
|
|
1185
1186
|
}
|
|
1187
|
+
function redactKnownSecrets(value) {
|
|
1188
|
+
if (typeof value === "string") return redactString(value);
|
|
1189
|
+
if (Array.isArray(value)) {
|
|
1190
|
+
return value.map((entry) => redactKnownSecrets(entry));
|
|
1191
|
+
}
|
|
1192
|
+
if (value && typeof value === "object") {
|
|
1193
|
+
return Object.fromEntries(
|
|
1194
|
+
Object.entries(value).map(([key, entry]) => [
|
|
1195
|
+
key,
|
|
1196
|
+
redactKnownSecrets(entry)
|
|
1197
|
+
])
|
|
1198
|
+
);
|
|
1199
|
+
}
|
|
1200
|
+
return value;
|
|
1201
|
+
}
|
|
1186
1202
|
return {
|
|
1187
1203
|
register,
|
|
1188
1204
|
redactString,
|
|
1205
|
+
redactKnownSecrets,
|
|
1189
1206
|
redact
|
|
1190
1207
|
};
|
|
1191
1208
|
}
|
|
@@ -2092,6 +2109,29 @@ async function* observeRunEvents(options) {
|
|
|
2092
2109
|
}
|
|
2093
2110
|
}
|
|
2094
2111
|
|
|
2112
|
+
// ../shared_libs/play-runtime/runtime-environment.ts
|
|
2113
|
+
var PLAY_RUNTIME_ENVIRONMENTS = ["preview"];
|
|
2114
|
+
var PLAY_RUNTIME_NAMESPACE_PATTERN = /^[a-z][a-z0-9-]{0,30}$/;
|
|
2115
|
+
function normalizePlayRuntimeNamespace(value) {
|
|
2116
|
+
if (typeof value !== "string") return null;
|
|
2117
|
+
const normalized = value.trim();
|
|
2118
|
+
return PLAY_RUNTIME_NAMESPACE_PATTERN.test(normalized) ? normalized : null;
|
|
2119
|
+
}
|
|
2120
|
+
function normalizePlayRuntimeSelection(value) {
|
|
2121
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
2122
|
+
const record = value;
|
|
2123
|
+
if (Object.keys(record).some(
|
|
2124
|
+
(key) => key !== "environment" && key !== "namespace"
|
|
2125
|
+
) || record.environment !== "preview") {
|
|
2126
|
+
return null;
|
|
2127
|
+
}
|
|
2128
|
+
const namespace = normalizePlayRuntimeNamespace(record.namespace);
|
|
2129
|
+
return namespace ? { environment: "preview", namespace } : null;
|
|
2130
|
+
}
|
|
2131
|
+
function normalizePlayRuntimeEnvironment(value) {
|
|
2132
|
+
return typeof value === "string" && PLAY_RUNTIME_ENVIRONMENTS.includes(value) ? value : null;
|
|
2133
|
+
}
|
|
2134
|
+
|
|
2095
2135
|
// src/client.ts
|
|
2096
2136
|
var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
2097
2137
|
var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
|
|
@@ -2114,6 +2154,61 @@ function resolvePlayRunIntegrationMode(request) {
|
|
|
2114
2154
|
request.integrationMode ?? process.env.DEEPLINE_EVAL_INTEGRATION_MODE
|
|
2115
2155
|
);
|
|
2116
2156
|
}
|
|
2157
|
+
function resolvePlayRunRuntimeSelection(request) {
|
|
2158
|
+
if (request.runtime !== void 0) {
|
|
2159
|
+
const runtime = normalizePlayRuntimeSelection(request.runtime);
|
|
2160
|
+
if (!runtime) {
|
|
2161
|
+
throw new DeeplineError(
|
|
2162
|
+
'runtime must be exactly { environment: "preview", namespace } with namespace matching ^[a-z][a-z0-9-]{0,30}$.',
|
|
2163
|
+
void 0,
|
|
2164
|
+
"INVALID_RUNTIME_SELECTION"
|
|
2165
|
+
);
|
|
2166
|
+
}
|
|
2167
|
+
return runtime;
|
|
2168
|
+
}
|
|
2169
|
+
const configured = process.env.DEEPLINE_RUNTIME_ENVIRONMENT?.trim();
|
|
2170
|
+
const configuredNamespace = process.env.DEEPLINE_RUNTIME_NAMESPACE?.trim();
|
|
2171
|
+
const configuredToken = process.env.DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN?.trim();
|
|
2172
|
+
if (!configured) {
|
|
2173
|
+
if (configuredNamespace || configuredToken) {
|
|
2174
|
+
throw new DeeplineError(
|
|
2175
|
+
"DEEPLINE_RUNTIME_ENVIRONMENT=preview and DEEPLINE_RUNTIME_NAMESPACE are required when runtime selection configuration is present.",
|
|
2176
|
+
void 0,
|
|
2177
|
+
"INVALID_RUNTIME_ENVIRONMENT"
|
|
2178
|
+
);
|
|
2179
|
+
}
|
|
2180
|
+
return void 0;
|
|
2181
|
+
}
|
|
2182
|
+
const environment = normalizePlayRuntimeEnvironment(configured);
|
|
2183
|
+
if (!environment) {
|
|
2184
|
+
throw new DeeplineError(
|
|
2185
|
+
`DEEPLINE_RUNTIME_ENVIRONMENT supports only explicit preview selection. Received "${configured}". Omit it to use the app-native runtime.`,
|
|
2186
|
+
void 0,
|
|
2187
|
+
"INVALID_RUNTIME_ENVIRONMENT"
|
|
2188
|
+
);
|
|
2189
|
+
}
|
|
2190
|
+
const namespace = normalizePlayRuntimeNamespace(configuredNamespace);
|
|
2191
|
+
if (!namespace) {
|
|
2192
|
+
throw new DeeplineError(
|
|
2193
|
+
"DEEPLINE_RUNTIME_NAMESPACE is required for preview and must match ^[a-z][a-z0-9-]{0,30}$.",
|
|
2194
|
+
void 0,
|
|
2195
|
+
"INVALID_RUNTIME_NAMESPACE"
|
|
2196
|
+
);
|
|
2197
|
+
}
|
|
2198
|
+
return { environment, namespace };
|
|
2199
|
+
}
|
|
2200
|
+
function runtimeSelectionHeaders(runtime) {
|
|
2201
|
+
if (!runtime) return void 0;
|
|
2202
|
+
const token = process.env.DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN?.trim();
|
|
2203
|
+
if (!token) {
|
|
2204
|
+
throw new DeeplineError(
|
|
2205
|
+
"DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN is required for explicit preview runtime selection.",
|
|
2206
|
+
void 0,
|
|
2207
|
+
"RUNTIME_ENVIRONMENT_TOKEN_REQUIRED"
|
|
2208
|
+
);
|
|
2209
|
+
}
|
|
2210
|
+
return { [RUNTIME_ENVIRONMENT_TOKEN_HEADER]: token };
|
|
2211
|
+
}
|
|
2117
2212
|
function normalizeTestPolicyOverrides(value, source) {
|
|
2118
2213
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
2119
2214
|
return value;
|
|
@@ -2812,6 +2907,7 @@ var DeeplineClient = class {
|
|
|
2812
2907
|
const integrationMode = resolvePlayRunIntegrationMode(request);
|
|
2813
2908
|
const testPolicyOverrides = request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
|
|
2814
2909
|
const forceToolRefresh = request.forceToolRefresh === true;
|
|
2910
|
+
const runtime = resolvePlayRunRuntimeSelection(request);
|
|
2815
2911
|
const response = await this.http.post(
|
|
2816
2912
|
"/api/v2/plays/run",
|
|
2817
2913
|
{
|
|
@@ -2838,9 +2934,10 @@ var DeeplineClient = class {
|
|
|
2838
2934
|
// defaults to absurd; callers normally omit this field.
|
|
2839
2935
|
...request.profile ? { profile: request.profile } : {},
|
|
2840
2936
|
...integrationMode ? { integrationMode } : {},
|
|
2937
|
+
...runtime ? { runtime } : {},
|
|
2841
2938
|
...testPolicyOverrides ? { testPolicyOverrides } : {}
|
|
2842
2939
|
},
|
|
2843
|
-
|
|
2940
|
+
runtimeSelectionHeaders(runtime),
|
|
2844
2941
|
// A start can reach the server even when its response is lost or times
|
|
2845
2942
|
// out. Retrying this mutation without an idempotency key can create a
|
|
2846
2943
|
// second root run, so callers must resolve ambiguous failures explicitly.
|
|
@@ -2863,6 +2960,7 @@ var DeeplineClient = class {
|
|
|
2863
2960
|
const integrationMode = resolvePlayRunIntegrationMode(request);
|
|
2864
2961
|
const testPolicyOverrides = request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
|
|
2865
2962
|
const forceToolRefresh = request.forceToolRefresh === true;
|
|
2963
|
+
const runtime = resolvePlayRunRuntimeSelection(request);
|
|
2866
2964
|
const body = {
|
|
2867
2965
|
...request.name ? { name: request.name } : {},
|
|
2868
2966
|
...request.revisionId ? { revisionId: request.revisionId } : {},
|
|
@@ -2885,6 +2983,7 @@ var DeeplineClient = class {
|
|
|
2885
2983
|
...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
|
|
2886
2984
|
...request.profile ? { profile: request.profile } : {},
|
|
2887
2985
|
...integrationMode ? { integrationMode } : {},
|
|
2986
|
+
...runtime ? { runtime } : {},
|
|
2888
2987
|
...testPolicyOverrides ? { testPolicyOverrides } : {}
|
|
2889
2988
|
};
|
|
2890
2989
|
for await (const event of this.http.streamSse(
|
|
@@ -2892,6 +2991,7 @@ var DeeplineClient = class {
|
|
|
2892
2991
|
{
|
|
2893
2992
|
method: "POST",
|
|
2894
2993
|
body,
|
|
2994
|
+
headers: runtimeSelectionHeaders(runtime),
|
|
2895
2995
|
signal: options?.signal
|
|
2896
2996
|
}
|
|
2897
2997
|
)) {
|