deepline 0.3.325 → 0.3.326
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 +23 -25
- package/dist/bundling-sources/sdk/src/compat.ts +11 -6
- package/dist/bundling-sources/sdk/src/db/query.ts +172 -0
- package/dist/bundling-sources/sdk/src/errors.ts +35 -0
- package/dist/bundling-sources/sdk/src/index.ts +13 -0
- package/dist/bundling-sources/sdk/src/play.ts +34 -31
- package/dist/bundling-sources/sdk/src/plays/authoring-graph-path.ts +13 -0
- package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +2 -1
- package/dist/bundling-sources/sdk/src/plays/local-play-execution.ts +189 -0
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/tool-calls.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +84 -10
- package/dist/cli/auth-6STWK6UK.js +31 -0
- package/dist/cli/{auth-PIZESRPC.mjs → auth-VON5FFUK.mjs} +4 -4
- package/dist/cli/{billing-HSL6VTCM.mjs → billing-X6JUEFRE.mjs} +4 -4
- package/dist/cli/{billing-DQKFCQV5.js → billing-YI4RZI2O.js} +70 -70
- package/dist/cli/{chunk-UYFWTIKF.js → chunk-3NGWGFVL.js} +26 -26
- package/dist/cli/{chunk-PWV2M4LW.mjs → chunk-4AB4Y6FF.mjs} +1 -1
- package/dist/cli/{chunk-DLW7X2UK.js → chunk-4LNBSQM4.js} +5928 -5730
- package/dist/cli/{chunk-OOPSX57I.js → chunk-5NXHSRRE.js} +6 -6
- package/dist/cli/{chunk-XNL3SEMC.js → chunk-AFNEQ43J.js} +8 -3
- package/dist/cli/{chunk-XSEMQ4II.js → chunk-AGH6YP2T.js} +2 -1
- package/dist/cli/chunk-AID3OYVJ.js +8 -0
- package/dist/cli/{chunk-NWBARG3F.mjs → chunk-BQJVMKWL.mjs} +1 -1
- package/dist/cli/{chunk-YE3O2UHM.mjs → chunk-BR7GGTAE.mjs} +24 -1
- package/dist/cli/{chunk-K7FC5IUU.js → chunk-BUYZEUY4.js} +1 -1
- package/dist/cli/{chunk-QQ2FG5W3.js → chunk-CUUHQ3AO.js} +6 -6
- package/dist/cli/{chunk-H5TJBRSC.mjs → chunk-DFDXKOLR.mjs} +98 -113
- package/dist/cli/{chunk-HPTQEWCF.js → chunk-EMZ7Y5SW.js} +70 -67
- package/dist/cli/chunk-GVESPYSY.mjs +234 -0
- package/dist/cli/{chunk-MNKDSR2J.js → chunk-GVYKY6T6.js} +344 -254
- package/dist/cli/{chunk-6RMKHN7S.mjs → chunk-IQCCGOQH.mjs} +4 -20
- package/dist/cli/{chunk-76VKBPOC.mjs → chunk-JOA6IKDE.mjs} +7 -2
- package/dist/cli/{chunk-XIVUB36F.mjs → chunk-KLWBAQ5A.mjs} +104 -14
- package/dist/cli/{chunk-CV5GDCKN.js → chunk-KZ4PCK4O.js} +29 -45
- package/dist/cli/chunk-LVEDPCLJ.js +234 -0
- package/dist/cli/{chunk-AQUNQJ5Y.mjs → chunk-M7CPVMDB.mjs} +1 -1
- package/dist/cli/{chunk-HUKWYHBG.js → chunk-MDQZQ3NY.js} +2 -2
- package/dist/cli/{chunk-PBNZXZCW.js → chunk-MKHSZA2X.js} +48 -48
- package/dist/cli/{chunk-5TYU3UIS.mjs → chunk-MOBZS4F3.mjs} +1 -1
- package/dist/cli/chunk-OVDNJAJN.mjs +8 -0
- package/dist/cli/{chunk-KZNFYOHX.js → chunk-T33W6JUJ.js} +6 -6
- package/dist/cli/{chunk-6VZDSBK6.mjs → chunk-TDSNAC3C.mjs} +2 -2
- package/dist/cli/{chunk-PVDQ55PS.js → chunk-TXVOB5J2.js} +29 -6
- package/dist/cli/{chunk-YXRPWMGN.js → chunk-TZQMFWLF.js} +147 -162
- package/dist/cli/{chunk-OPERWJR6.mjs → chunk-VGKVLADU.mjs} +3 -3
- package/dist/cli/{chunk-7MD453WV.mjs → chunk-VKXGOQG5.mjs} +5674 -5476
- package/dist/cli/{chunk-WW4XZIVM.mjs → chunk-W74E5ETE.mjs} +12 -9
- package/dist/cli/{chunk-7PZFGB7L.mjs → chunk-YIY74KUF.mjs} +2 -1
- package/dist/cli/{chunk-5FHU7TV4.mjs → chunk-ZRN6YOF2.mjs} +2 -2
- package/dist/cli/client-TEBW2P24.js +20 -0
- package/dist/cli/{client-57SR4KVM.mjs → client-ZMOKUNL2.mjs} +3 -3
- package/dist/cli/{csv-5DJSC6BD.js → csv-HZRKEI7J.js} +12 -12
- package/dist/cli/{csv-G2FRMOXL.mjs → csv-IICJHJZ4.mjs} +3 -3
- package/dist/cli/{db-NVO7P4VO.js → db-TM5NZF73.js} +226 -149
- package/dist/cli/{db-WWZEXM3N.mjs → db-X4B7YFNY.mjs} +214 -137
- package/dist/cli/{describe-M26LHDBQ.js → describe-BDBARWZJ.js} +28 -27
- package/dist/cli/{describe-26OMF3A4.mjs → describe-GMVS3LFC.mjs} +12 -11
- package/dist/cli/{executions-2LLHY3IL.mjs → executions-447ZJMN4.mjs} +4 -4
- package/dist/cli/{executions-KI47LPKE.js → executions-QX25UOQM.js} +6 -6
- package/dist/cli/{feedback-2Y26C2BZ.js → feedback-4IXUTBX7.js} +6 -6
- package/dist/cli/{feedback-O26VL2OF.mjs → feedback-JB7HHIC6.mjs} +3 -3
- package/dist/cli/git-C7C7DTEH.js +23 -0
- package/dist/cli/{git-UVPGZN3K.mjs → git-VID6KGAA.mjs} +4 -4
- package/dist/cli/index.js +105 -87
- package/dist/cli/index.mjs +65 -47
- package/dist/cli/{legacy-noops-H6Y3SEVB.js → legacy-noops-3FYTCOZO.js} +7 -7
- package/dist/cli/{legacy-noops-IK5CH72U.mjs → legacy-noops-SGR3G5WS.mjs} +4 -4
- package/dist/cli/{monitors-SFVVMAJT.mjs → monitors-SH4FOMBM.mjs} +4 -4
- package/dist/cli/{monitors-JL6TTQCI.js → monitors-SP52UHS4.js} +85 -85
- package/dist/cli/{org-SSDONL57.mjs → org-B32MMIQT.mjs} +4 -4
- package/dist/cli/{org-OVMAZCQS.js → org-UQMX7JOR.js} +60 -60
- package/dist/cli/play-UCIWBN7U.js +153 -0
- package/dist/cli/{play-X6NPACUO.mjs → play-XTE4LUP7.mjs} +11 -10
- package/dist/cli/{providers-E24JDWSR.js → providers-JNMJJ2OH.js} +7 -7
- package/dist/cli/{providers-ONUBYYY4.mjs → providers-RWLN6FUR.mjs} +4 -4
- package/dist/cli/{quickstart-TB7C3DLG.js → quickstart-HK6WZ342.js} +5 -5
- package/dist/cli/{quickstart-B7NIXACV.mjs → quickstart-IDB3Y375.mjs} +3 -3
- package/dist/cli/{search-N3QUIATW.mjs → search-6D3IFNPT.mjs} +5 -5
- package/dist/cli/search-LUZ2S7DH.js +26 -0
- package/dist/cli/{secrets-CPCVFDYB.js → secrets-JOQB57IE.js} +13 -13
- package/dist/cli/{secrets-V7Z4M67T.mjs → secrets-TZ53CQ3D.mjs} +4 -4
- package/dist/cli/{sessions-PDOBKAKO.mjs → sessions-4MBDC4EK.mjs} +4 -4
- package/dist/cli/{sessions-E4FIZLQP.js → sessions-QSAICDXX.js} +5 -5
- package/dist/cli/{settings-UVM2WDE4.js → settings-OTOCW7L7.js} +74 -74
- package/dist/cli/{settings-QYHYHZDI.mjs → settings-RKQFMLDU.mjs} +7 -7
- package/dist/cli/{setup-4RLAETDW.mjs → setup-2S5TNTUB.mjs} +6 -6
- package/dist/cli/{setup-3JFAXQLJ.js → setup-AKZUDVYY.js} +41 -41
- package/dist/cli/skills-26LASHZF.js +28 -0
- package/dist/cli/{skills-ZX2JSWOZ.mjs → skills-AGZXDLSA.mjs} +4 -4
- package/dist/cli/{tools-EGXCVIPJ.mjs → tools-7Y6RD6FY.mjs} +8 -7
- package/dist/cli/tools-L5VIJQWX.js +39 -0
- package/dist/cli/{update-7FEKRQFE.mjs → update-M7YGF67I.mjs} +6 -6
- package/dist/cli/update-MNHF6M2F.js +28 -0
- package/dist/cli/{workflow-7V7TTTKK.mjs → workflow-CTVE7S7W.mjs} +5 -5
- package/dist/cli/{workflow-54VCKIG2.js → workflow-NGMY425T.js} +15 -15
- package/dist/{client-Bb4Jjzmj.d.ts → client-DHq8dJ56.d.ts} +39 -11
- package/dist/{client-COa-3GHK.d.mts → client-wiWPZhnI.d.mts} +39 -11
- package/dist/{compiler-manifest-CsnWj-AK.d.mts → compiler-manifest-9TkZ_ykI.d.mts} +711 -711
- package/dist/{compiler-manifest-CsnWj-AK.d.ts → compiler-manifest-9TkZ_ykI.d.ts} +711 -711
- package/dist/index-B-5_Xhud.d.mts +75 -0
- package/dist/index-ykksoEyR.d.ts +75 -0
- package/dist/index.d.mts +52 -13
- package/dist/index.d.ts +52 -13
- package/dist/index.js +92 -28
- package/dist/index.mjs +91 -27
- package/dist/install-integrity.json +91 -84
- package/dist/plays/bundle-play-file.d.mts +7 -75
- package/dist/plays/bundle-play-file.d.ts +7 -75
- package/dist/plays/bundle-play-file.mjs +1 -1
- package/dist/plays/run-request.d.mts +2 -2
- package/dist/plays/run-request.d.ts +2 -2
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +2 -2
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
- package/dist/cli/auth-RXCD4GOV.js +0 -31
- package/dist/cli/chunk-OWJZUE3Y.mjs +0 -103
- package/dist/cli/chunk-SDK3ZA2C.js +0 -103
- package/dist/cli/client-562MULXK.js +0 -20
- package/dist/cli/git-KGPX5YPD.js +0 -23
- package/dist/cli/play-3DB4MSHN.js +0 -152
- package/dist/cli/search-NJ637YGQ.js +0 -26
- package/dist/cli/skills-BYRYG64R.js +0 -28
- package/dist/cli/tools-TAWOAY5X.js +0 -38
- package/dist/cli/update-H24GEBXM.js +0 -28
|
@@ -51,6 +51,12 @@ import { playInputExampleArgs } from './plays/input-example.js';
|
|
|
51
51
|
*/
|
|
52
52
|
import { resolveConfig } from './config.js';
|
|
53
53
|
import { DeeplineError } from './errors.js';
|
|
54
|
+
import {
|
|
55
|
+
planCustomerDbQuery,
|
|
56
|
+
queryCustomerDatabase,
|
|
57
|
+
type CustomerDbQueryOptions,
|
|
58
|
+
type CustomerDbQueryPlan,
|
|
59
|
+
} from './db/query.js';
|
|
54
60
|
import {
|
|
55
61
|
ToolCalls,
|
|
56
62
|
type ExecuteToolRawOptions,
|
|
@@ -1256,11 +1262,10 @@ export type StopAllRunsOptions = {
|
|
|
1256
1262
|
|
|
1257
1263
|
/** Current mutable customer database namespace exposed as `client.db`. */
|
|
1258
1264
|
export type DbNamespace = {
|
|
1259
|
-
/** Run a bounded SQL query
|
|
1260
|
-
query: (input:
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
}) => Promise<CustomerDbQueryResult>;
|
|
1265
|
+
/** Run a bounded SQL query; every request is attempted once. */
|
|
1266
|
+
query: (input: CustomerDbQueryOptions) => Promise<CustomerDbQueryResult>;
|
|
1267
|
+
/** Describe the request, effects and recovery policy without executing SQL. */
|
|
1268
|
+
planQuery: (input: CustomerDbQueryOptions) => CustomerDbQueryPlan;
|
|
1264
1269
|
};
|
|
1265
1270
|
|
|
1266
1271
|
/**
|
|
@@ -2921,6 +2926,7 @@ export class DeeplineClient {
|
|
|
2921
2926
|
};
|
|
2922
2927
|
this.db = {
|
|
2923
2928
|
query: (input) => this.queryDb(input),
|
|
2929
|
+
planQuery: (input) => planCustomerDbQuery(input),
|
|
2924
2930
|
};
|
|
2925
2931
|
this.billing = {
|
|
2926
2932
|
topUp: (options) => this.topUpBillingBalance(options),
|
|
@@ -3485,21 +3491,10 @@ export class DeeplineClient {
|
|
|
3485
3491
|
return this.executeTool<TData, TMeta>(toolId, input, options);
|
|
3486
3492
|
}
|
|
3487
3493
|
|
|
3488
|
-
private async queryDb(
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
const result = await this.http.post<CustomerDbQueryResult>(
|
|
3493
|
-
'/api/v2/db/query',
|
|
3494
|
-
{
|
|
3495
|
-
sql: input.sql,
|
|
3496
|
-
...(input.maxRows ? { max_rows: input.maxRows } : {}),
|
|
3497
|
-
},
|
|
3498
|
-
);
|
|
3499
|
-
return {
|
|
3500
|
-
...result,
|
|
3501
|
-
scope: { kind: 'database', mutability: 'current' },
|
|
3502
|
-
};
|
|
3494
|
+
private async queryDb(
|
|
3495
|
+
input: CustomerDbQueryOptions,
|
|
3496
|
+
): Promise<CustomerDbQueryResult> {
|
|
3497
|
+
return queryCustomerDatabase(this.http, input);
|
|
3503
3498
|
}
|
|
3504
3499
|
|
|
3505
3500
|
/**
|
|
@@ -3510,10 +3505,9 @@ export class DeeplineClient {
|
|
|
3510
3505
|
*
|
|
3511
3506
|
* @deprecated Use {@link DeeplineClient.db} `.query(...)`.
|
|
3512
3507
|
*/
|
|
3513
|
-
async queryCustomerDb(
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
}): Promise<CustomerDbQueryResult> {
|
|
3508
|
+
async queryCustomerDb(
|
|
3509
|
+
input: CustomerDbQueryOptions,
|
|
3510
|
+
): Promise<CustomerDbQueryResult> {
|
|
3517
3511
|
return this.db.query(input);
|
|
3518
3512
|
}
|
|
3519
3513
|
|
|
@@ -3627,6 +3621,8 @@ export class DeeplineClient {
|
|
|
3627
3621
|
artifact: Record<string, unknown>;
|
|
3628
3622
|
compilerManifest?: PlayCompilerManifest;
|
|
3629
3623
|
publish?: boolean;
|
|
3624
|
+
/** Store execution content without changing a draft or live revision. */
|
|
3625
|
+
artifactOnly?: boolean;
|
|
3630
3626
|
ownerType?: 'org' | 'deepline';
|
|
3631
3627
|
scope?: 'org' | 'system';
|
|
3632
3628
|
userId?: string;
|
|
@@ -3652,7 +3648,9 @@ export class DeeplineClient {
|
|
|
3652
3648
|
artifact: input.artifact,
|
|
3653
3649
|
}));
|
|
3654
3650
|
return this.http.post(
|
|
3655
|
-
|
|
3651
|
+
input.artifactOnly === true
|
|
3652
|
+
? '/api/v2/plays/artifacts/immutable'
|
|
3653
|
+
: '/api/v2/plays/artifacts',
|
|
3656
3654
|
{
|
|
3657
3655
|
...input,
|
|
3658
3656
|
compilerManifest,
|
|
@@ -338,6 +338,8 @@ export async function checkSdkCompatibility(
|
|
|
338
338
|
skillsVersion?: string | null;
|
|
339
339
|
/** Blocking budget for the live request; defaults to the full timeout. */
|
|
340
340
|
timeoutMs?: number;
|
|
341
|
+
/** Disable cache writes and invalidation for commands that permit no local maintenance. */
|
|
342
|
+
persistCache?: boolean;
|
|
341
343
|
/** Optional read-only catalog result carried by the same live check. */
|
|
342
344
|
catalog?: {
|
|
343
345
|
toolId: string;
|
|
@@ -396,12 +398,14 @@ export async function checkSdkCompatibility(
|
|
|
396
398
|
}
|
|
397
399
|
// Catalog results belong to this command only, never the policy cache.
|
|
398
400
|
const { catalog_metadata: catalogMetadata, ...data } = raw;
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
401
|
+
if (options.persistCache !== false) {
|
|
402
|
+
writeCachedCompatibility(
|
|
403
|
+
baseUrl,
|
|
404
|
+
options.command,
|
|
405
|
+
options.skillsVersion,
|
|
406
|
+
data,
|
|
407
|
+
);
|
|
408
|
+
}
|
|
405
409
|
if (
|
|
406
410
|
options.catalog &&
|
|
407
411
|
catalogMetadata &&
|
|
@@ -423,6 +427,7 @@ export async function checkSdkCompatibility(
|
|
|
423
427
|
);
|
|
424
428
|
if (cached) {
|
|
425
429
|
if (
|
|
430
|
+
options.persistCache !== false &&
|
|
426
431
|
options.timeoutMs !== undefined &&
|
|
427
432
|
options.timeoutMs < CHECK_TIMEOUT_MS
|
|
428
433
|
) {
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CustomerDbQueryOutcomeUnknownError,
|
|
3
|
+
DeeplineError,
|
|
4
|
+
} from '../errors.js';
|
|
5
|
+
import type { HttpClient } from '../http.js';
|
|
6
|
+
import type { CustomerDbQueryResult } from '../types.js';
|
|
7
|
+
|
|
8
|
+
export type CustomerDbQueryOptions = {
|
|
9
|
+
sql: string;
|
|
10
|
+
maxRows?: number;
|
|
11
|
+
/** Reuse only to recover the original statement and options. */
|
|
12
|
+
operationKey?: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type CustomerDbQueryPlan = {
|
|
16
|
+
request: {
|
|
17
|
+
method: 'POST';
|
|
18
|
+
path: '/api/v2/db/query';
|
|
19
|
+
body: { sql: string; max_rows?: number; operation_key?: string };
|
|
20
|
+
};
|
|
21
|
+
effects: {
|
|
22
|
+
cloudMutations: 'statement_dependent';
|
|
23
|
+
localWrites: 'none';
|
|
24
|
+
creditSpending: 'none';
|
|
25
|
+
recovery: 'original_operation_key' | 'unkeyed_unknown_outcome';
|
|
26
|
+
};
|
|
27
|
+
transport: { maxRetries: 0; urlFailover: 'disabled' };
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/** Validate and describe SQL execution without sending it. */
|
|
31
|
+
export function planCustomerDbQuery(
|
|
32
|
+
input: CustomerDbQueryOptions,
|
|
33
|
+
): CustomerDbQueryPlan {
|
|
34
|
+
if (typeof input.sql !== 'string' || !input.sql.trim())
|
|
35
|
+
throw new DeeplineError('sql must not be empty.', 400, 'INVALID_SQL');
|
|
36
|
+
if (
|
|
37
|
+
input.operationKey !== undefined &&
|
|
38
|
+
typeof input.operationKey !== 'string'
|
|
39
|
+
)
|
|
40
|
+
throw new DeeplineError(
|
|
41
|
+
'operationKey must be a string containing 1–512 characters.',
|
|
42
|
+
400,
|
|
43
|
+
'INVALID_OPERATION_KEY',
|
|
44
|
+
);
|
|
45
|
+
// An operation key is an opaque identity shared with REST and tool callers.
|
|
46
|
+
// Trim only to reject blank input; changing a valid key creates new intent.
|
|
47
|
+
const operationKey = input.operationKey;
|
|
48
|
+
if (
|
|
49
|
+
operationKey !== undefined &&
|
|
50
|
+
(!operationKey.trim() || operationKey.length > 512)
|
|
51
|
+
) {
|
|
52
|
+
throw new DeeplineError(
|
|
53
|
+
'operationKey must contain 1–512 characters.',
|
|
54
|
+
400,
|
|
55
|
+
'INVALID_OPERATION_KEY',
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
if (
|
|
59
|
+
input.maxRows !== undefined &&
|
|
60
|
+
(!Number.isSafeInteger(input.maxRows) ||
|
|
61
|
+
input.maxRows < 1 ||
|
|
62
|
+
input.maxRows > 1000)
|
|
63
|
+
) {
|
|
64
|
+
throw new DeeplineError(
|
|
65
|
+
'maxRows must be a whole number from 1 to 1000.',
|
|
66
|
+
400,
|
|
67
|
+
'INVALID_MAX_ROWS',
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
request: {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
path: '/api/v2/db/query',
|
|
74
|
+
body: {
|
|
75
|
+
sql: input.sql,
|
|
76
|
+
...(input.maxRows !== undefined ? { max_rows: input.maxRows } : {}),
|
|
77
|
+
...(operationKey !== undefined ? { operation_key: operationKey } : {}),
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
effects: {
|
|
81
|
+
cloudMutations: 'statement_dependent',
|
|
82
|
+
localWrites: 'none',
|
|
83
|
+
creditSpending: 'none',
|
|
84
|
+
recovery:
|
|
85
|
+
operationKey === undefined
|
|
86
|
+
? 'unkeyed_unknown_outcome'
|
|
87
|
+
: 'original_operation_key',
|
|
88
|
+
},
|
|
89
|
+
transport: {
|
|
90
|
+
maxRetries: 0,
|
|
91
|
+
urlFailover: 'disabled',
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export async function queryCustomerDatabase(
|
|
97
|
+
http: HttpClient,
|
|
98
|
+
input: CustomerDbQueryOptions,
|
|
99
|
+
): Promise<CustomerDbQueryResult> {
|
|
100
|
+
const plan = planCustomerDbQuery(input);
|
|
101
|
+
let result: CustomerDbQueryResult;
|
|
102
|
+
try {
|
|
103
|
+
result = await http.post<CustomerDbQueryResult>(
|
|
104
|
+
plan.request.path,
|
|
105
|
+
plan.request.body,
|
|
106
|
+
undefined,
|
|
107
|
+
{
|
|
108
|
+
maxRetries: plan.transport.maxRetries,
|
|
109
|
+
exactUrlOnly: plan.transport.urlFailover === 'disabled',
|
|
110
|
+
},
|
|
111
|
+
);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
if (
|
|
114
|
+
error instanceof DeeplineError &&
|
|
115
|
+
(error.code?.startsWith('NETWORK_') ||
|
|
116
|
+
// Older API readers return PostgreSQL errors as HTTP 400, including
|
|
117
|
+
// lost connections and explicitly unknown transaction resolution.
|
|
118
|
+
/^08[A-Z0-9]{3}$/.test(error.code ?? '') ||
|
|
119
|
+
['57P01', '57P02', '57P03'].includes(error.code ?? '') ||
|
|
120
|
+
error.statusCode === 408 ||
|
|
121
|
+
(error.statusCode ?? 0) >= 500)
|
|
122
|
+
) {
|
|
123
|
+
throw new CustomerDbQueryOutcomeUnknownError(
|
|
124
|
+
error,
|
|
125
|
+
plan.request.body.operation_key,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
if (
|
|
131
|
+
!result ||
|
|
132
|
+
typeof result !== 'object' ||
|
|
133
|
+
Array.isArray(result) ||
|
|
134
|
+
typeof result.command !== 'string' ||
|
|
135
|
+
!Array.isArray(result.columns) ||
|
|
136
|
+
!Array.isArray(result.rows) ||
|
|
137
|
+
typeof result.truncated !== 'boolean' ||
|
|
138
|
+
(result.row_count !== null &&
|
|
139
|
+
(!Number.isSafeInteger(result.row_count) || result.row_count < 0)) ||
|
|
140
|
+
!Number.isSafeInteger(result.row_count_returned) ||
|
|
141
|
+
result.row_count_returned < 0
|
|
142
|
+
) {
|
|
143
|
+
throw new CustomerDbQueryOutcomeUnknownError(
|
|
144
|
+
new DeeplineError(
|
|
145
|
+
'The SQL response did not contain a valid result.',
|
|
146
|
+
200,
|
|
147
|
+
'CUSTOMER_DB_QUERY_RESPONSE_INVALID',
|
|
148
|
+
),
|
|
149
|
+
plan.request.body.operation_key,
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
const operation = result.operation;
|
|
153
|
+
if (
|
|
154
|
+
input.operationKey !== undefined &&
|
|
155
|
+
(!operation ||
|
|
156
|
+
operation.operation_key !== input.operationKey ||
|
|
157
|
+
!Number.isSafeInteger(operation.completed_at_ms) ||
|
|
158
|
+
operation.completed_at_ms < 0 ||
|
|
159
|
+
!['executed', 'operation_recovery'].includes(operation.source))
|
|
160
|
+
) {
|
|
161
|
+
throw new CustomerDbQueryOutcomeUnknownError(
|
|
162
|
+
new DeeplineError(
|
|
163
|
+
'The server did not confirm the original atomic SQL operation.',
|
|
164
|
+
200,
|
|
165
|
+
'CUSTOMER_DB_OPERATION_ACK_INVALID',
|
|
166
|
+
),
|
|
167
|
+
input.operationKey,
|
|
168
|
+
{ recoveryAvailable: false },
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
return { ...result, scope: { kind: 'database', mutability: 'current' } };
|
|
172
|
+
}
|
|
@@ -18,6 +18,41 @@ import {
|
|
|
18
18
|
type ToolExecutionPublicDetails,
|
|
19
19
|
} from '../../shared_libs/plays/tool-execution-error';
|
|
20
20
|
|
|
21
|
+
/** SQL may have committed, but its response was not confirmed. */
|
|
22
|
+
export class CustomerDbQueryOutcomeUnknownError extends DeeplineError {
|
|
23
|
+
declare readonly cause: DeeplineError;
|
|
24
|
+
readonly outcome = 'unknown' as const;
|
|
25
|
+
readonly operationKey?: string;
|
|
26
|
+
readonly retryable: boolean;
|
|
27
|
+
|
|
28
|
+
constructor(
|
|
29
|
+
cause: DeeplineError,
|
|
30
|
+
operationKey?: string,
|
|
31
|
+
options: { recoveryAvailable?: boolean } = {},
|
|
32
|
+
) {
|
|
33
|
+
const recoveryAvailable =
|
|
34
|
+
operationKey !== undefined && options.recoveryAvailable !== false;
|
|
35
|
+
super(
|
|
36
|
+
operationKey === undefined
|
|
37
|
+
? 'SQL outcome is unknown. The unkeyed request was attempted once; inspect the database before issuing another write. An operation key added afterwards cannot recover this request.'
|
|
38
|
+
: recoveryAvailable
|
|
39
|
+
? 'SQL outcome is unknown. Recover by submitting the same SQL and options with the original operation key; do not use a new key.'
|
|
40
|
+
: 'SQL outcome is unknown. The server did not confirm atomic recovery support. Do not resubmit this write; inspect the database and confirm reader support before recovering with the original operation key.',
|
|
41
|
+
cause.statusCode,
|
|
42
|
+
'CUSTOMER_DB_QUERY_OUTCOME_UNKNOWN',
|
|
43
|
+
{
|
|
44
|
+
outcome: 'unknown',
|
|
45
|
+
recovery: recoveryAvailable ? 'original_operation_key' : 'unavailable',
|
|
46
|
+
causeCode: cause.code,
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
this.name = 'CustomerDbQueryOutcomeUnknownError';
|
|
50
|
+
this.operationKey = operationKey;
|
|
51
|
+
this.retryable = recoveryAvailable;
|
|
52
|
+
Object.defineProperty(this, 'cause', { value: cause, configurable: true });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
21
56
|
export {
|
|
22
57
|
DeeplineError,
|
|
23
58
|
ProviderTransientError,
|
|
@@ -41,6 +41,7 @@ export type {
|
|
|
41
41
|
* export default definePlay('my-play', async (ctx, input: { domain: string }) => {
|
|
42
42
|
* ctx.log(`Looking up ${input.domain}`);
|
|
43
43
|
* const company = await ctx.tools.execute({
|
|
44
|
+
* staleAfterSeconds: 0,
|
|
44
45
|
* id: 'company_search',
|
|
45
46
|
* tool: 'test_company_search',
|
|
46
47
|
* input: { domain: input.domain },
|
|
@@ -76,6 +77,17 @@ export {
|
|
|
76
77
|
MONITOR_JOB_RECONCILIATION_STATES,
|
|
77
78
|
MONITOR_JOB_STATES,
|
|
78
79
|
} from './client.js';
|
|
80
|
+
export type {
|
|
81
|
+
CustomerDbQueryOptions,
|
|
82
|
+
CustomerDbQueryPlan,
|
|
83
|
+
} from './db/query.js';
|
|
84
|
+
export { planCustomerDbQuery } from './db/query.js';
|
|
85
|
+
export type { DeeplineToolCallOptions } from './play.js';
|
|
86
|
+
export {
|
|
87
|
+
planLocalPlayExecution,
|
|
88
|
+
pinLocalPlayImports,
|
|
89
|
+
} from './plays/local-play-execution.js';
|
|
90
|
+
export type { LocalPlayGraph } from './plays/local-play-execution.js';
|
|
79
91
|
export { CtxFetchHttpError } from './play.js';
|
|
80
92
|
export { RunObserveTransportUnavailableError } from './runs/observe-transport.js';
|
|
81
93
|
export { RunEventQueryInputError } from '../../shared_libs/play-runtime/run-event-query';
|
|
@@ -258,6 +270,7 @@ export {
|
|
|
258
270
|
// ——— Errors ———
|
|
259
271
|
export {
|
|
260
272
|
DeeplineError,
|
|
273
|
+
CustomerDbQueryOutcomeUnknownError,
|
|
261
274
|
ProviderTransientError,
|
|
262
275
|
ToolExecutionError,
|
|
263
276
|
getProviderUnavailableReason,
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
* export default definePlay('my-play', async (ctx, input: { domain: string }) => {
|
|
30
30
|
* ctx.log(`Looking up ${input.domain}`);
|
|
31
31
|
* const company = await ctx.tools.execute({
|
|
32
|
+
* staleAfterSeconds: 0,
|
|
32
33
|
* id: 'company_search',
|
|
33
34
|
* tool: 'test_company_search',
|
|
34
35
|
* input: { domain: input.domain },
|
|
@@ -59,6 +60,7 @@
|
|
|
59
60
|
*
|
|
60
61
|
* export default definePlay('daily-sync', async (ctx) => {
|
|
61
62
|
* const data = await ctx.tools.execute({
|
|
63
|
+
* staleAfterSeconds: 0,
|
|
62
64
|
* id: 'crm_export',
|
|
63
65
|
* tool: 'crm_export',
|
|
64
66
|
* input: {},
|
|
@@ -115,6 +117,7 @@ import type {
|
|
|
115
117
|
ExecutionRecovery,
|
|
116
118
|
ToolExecution,
|
|
117
119
|
} from './client.js';
|
|
120
|
+
import type { ExecuteToolRawOptions } from './tool-calls.js';
|
|
118
121
|
import type {
|
|
119
122
|
DurableCallStaleAfterSeconds,
|
|
120
123
|
PlayAuthoringBindings,
|
|
@@ -638,6 +641,12 @@ export interface DeeplineNamedPlay<
|
|
|
638
641
|
): Promise<TOutput>;
|
|
639
642
|
}
|
|
640
643
|
|
|
644
|
+
/** Per-call HTTP deadline and recovery identity for a direct tool operation. */
|
|
645
|
+
export type DeeplineToolCallOptions = Pick<
|
|
646
|
+
ExecuteToolRawOptions,
|
|
647
|
+
'timeout' | 'idempotencyKey' | 'recover' | 'onExecution' | 'recoveryTimeoutMs'
|
|
648
|
+
>;
|
|
649
|
+
|
|
641
650
|
/**
|
|
642
651
|
* Tool/provider operations available from a connected {@link DeeplineContext}.
|
|
643
652
|
*
|
|
@@ -652,6 +661,12 @@ export type DeeplineToolsNamespace = {
|
|
|
652
661
|
list(): Promise<ToolDefinition[]>;
|
|
653
662
|
/** Get detailed metadata for one provider-backed tool. */
|
|
654
663
|
get(toolId: string): Promise<ToolMetadata>;
|
|
664
|
+
/** Call one tool. A key or recover enables same-execution recovery after a lost response. */
|
|
665
|
+
call(
|
|
666
|
+
toolId: string,
|
|
667
|
+
input: Record<string, unknown>,
|
|
668
|
+
options?: DeeplineToolCallOptions,
|
|
669
|
+
): Promise<DeeplineToolExecuteResult>;
|
|
655
670
|
/**
|
|
656
671
|
* Execute a provider-backed tool from a regular SDK process.
|
|
657
672
|
*
|
|
@@ -661,14 +676,7 @@ export type DeeplineToolsNamespace = {
|
|
|
661
676
|
execute(
|
|
662
677
|
toolId: string,
|
|
663
678
|
input: Record<string, unknown>,
|
|
664
|
-
options?:
|
|
665
|
-
idempotencyKey?: string;
|
|
666
|
-
recover?: boolean;
|
|
667
|
-
onExecution?: (execution: {
|
|
668
|
-
idempotencyKey: string;
|
|
669
|
-
}) => void | Promise<void>;
|
|
670
|
-
recoveryTimeoutMs?: number;
|
|
671
|
-
},
|
|
679
|
+
options?: DeeplineToolCallOptions,
|
|
672
680
|
): Promise<DeeplineToolExecuteResult>;
|
|
673
681
|
};
|
|
674
682
|
|
|
@@ -1100,35 +1108,30 @@ export class DeeplineContext {
|
|
|
1100
1108
|
* ```
|
|
1101
1109
|
*/
|
|
1102
1110
|
get tools(): DeeplineToolsNamespace {
|
|
1111
|
+
const call: DeeplineToolsNamespace['call'] = async (
|
|
1112
|
+
toolId,
|
|
1113
|
+
input,
|
|
1114
|
+
options,
|
|
1115
|
+
) => {
|
|
1116
|
+
const response = await this.client.executeTool(toolId, input, {
|
|
1117
|
+
includeToolMetadata: true,
|
|
1118
|
+
responseIntent: 'dataset',
|
|
1119
|
+
...options,
|
|
1120
|
+
});
|
|
1121
|
+
return toolExecutionEnvelopeToResult(toolId, response, {
|
|
1122
|
+
client: this.client,
|
|
1123
|
+
input,
|
|
1124
|
+
});
|
|
1125
|
+
};
|
|
1103
1126
|
return {
|
|
1104
1127
|
/** List all available tools. */
|
|
1105
1128
|
list: (): Promise<ToolDefinition[]> => this.client.listTools(),
|
|
1106
1129
|
/** Get detailed metadata for a tool. */
|
|
1107
1130
|
get: (toolId: string): Promise<ToolMetadata> =>
|
|
1108
1131
|
this.client.getTool(toolId),
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
input: Record<string, unknown>,
|
|
1113
|
-
options?: {
|
|
1114
|
-
idempotencyKey?: string;
|
|
1115
|
-
recover?: boolean;
|
|
1116
|
-
onExecution?: (execution: {
|
|
1117
|
-
idempotencyKey: string;
|
|
1118
|
-
}) => void | Promise<void>;
|
|
1119
|
-
recoveryTimeoutMs?: number;
|
|
1120
|
-
},
|
|
1121
|
-
): Promise<DeeplineToolExecuteResult> => {
|
|
1122
|
-
const response = await this.client.executeTool(toolId, input, {
|
|
1123
|
-
includeToolMetadata: true,
|
|
1124
|
-
responseIntent: 'dataset',
|
|
1125
|
-
...options,
|
|
1126
|
-
});
|
|
1127
|
-
return toolExecutionEnvelopeToResult(toolId, response, {
|
|
1128
|
-
client: this.client,
|
|
1129
|
-
input,
|
|
1130
|
-
});
|
|
1131
|
-
},
|
|
1132
|
+
call,
|
|
1133
|
+
/** Compatibility spelling for the same tool operation. */
|
|
1134
|
+
execute: call,
|
|
1132
1135
|
};
|
|
1133
1136
|
}
|
|
1134
1137
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { dirname, isAbsolute, join, relative } from 'node:path';
|
|
2
|
+
|
|
3
|
+
/** Transport a child path in its importing artifact's source identity frame. */
|
|
4
|
+
export function playAuthoringGraphPath(
|
|
5
|
+
parent: { filePath: string; artifact: { entryFile: string } },
|
|
6
|
+
filePath: string,
|
|
7
|
+
): string {
|
|
8
|
+
if (isAbsolute(parent.artifact.entryFile)) return filePath;
|
|
9
|
+
return join(
|
|
10
|
+
dirname(parent.artifact.entryFile),
|
|
11
|
+
relative(dirname(parent.filePath), filePath),
|
|
12
|
+
).replaceAll('\\', '/');
|
|
13
|
+
}
|
|
@@ -141,7 +141,7 @@ export function createSdkPlayBundlingAdapter(): PlayBundlingAdapter {
|
|
|
141
141
|
|
|
142
142
|
export async function bundlePlayFile(
|
|
143
143
|
filePath: string,
|
|
144
|
-
options: BundlePlayFileOptions = {},
|
|
144
|
+
options: BundlePlayFileOptions & { cache?: boolean } = {},
|
|
145
145
|
): Promise<BundledPlayFileResult> {
|
|
146
146
|
// The SDK sends this graph to a remote checker/runtime. Its file identities
|
|
147
147
|
// therefore must describe the authoring workspace, rather than the local
|
|
@@ -159,6 +159,7 @@ export async function bundlePlayFile(
|
|
|
159
159
|
adapter: {
|
|
160
160
|
...createSdkPlayBundlingAdapter(),
|
|
161
161
|
sourceIdentityRoot,
|
|
162
|
+
...(options.cache === false ? { cacheDir: null } : {}),
|
|
162
163
|
},
|
|
163
164
|
});
|
|
164
165
|
if (result.success)
|