deepline 0.2.73 → 0.3.0
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 +75 -4
- package/dist/bundling-sources/sdk/src/compat.ts +4 -0
- package/dist/bundling-sources/sdk/src/play.ts +9 -0
- package/dist/bundling-sources/sdk/src/release.ts +12 -1
- package/dist/bundling-sources/sdk/src/types.ts +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +159 -32
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/secret-capability.ts +32 -7
- package/dist/bundling-sources/shared_libs/play-runtime/tool-response-contract.ts +89 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result-types.ts +29 -3
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +203 -16
- package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +3 -0
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +6 -3
- package/dist/bundling-sources/shared_libs/plays/contracts.ts +14 -0
- package/dist/cli/index.js +83 -9
- package/dist/cli/index.mjs +83 -9
- package/dist/{compiler-manifest-DFBtSjB2.d.mts → compiler-manifest-BX85pKXW.d.mts} +11 -4
- package/dist/{compiler-manifest-DFBtSjB2.d.ts → compiler-manifest-BX85pKXW.d.ts} +11 -4
- package/dist/index.d.mts +14 -3
- package/dist/index.d.ts +14 -3
- package/dist/index.js +85 -4
- package/dist/index.mjs +85 -4
- package/dist/install-integrity.json +3 -2
- package/dist/plays/bundle-play-file.d.mts +12 -2
- package/dist/plays/bundle-play-file.d.ts +12 -2
- package/dist/plays/bundle-play-file.mjs +7 -2
- package/package.json +1 -1
|
@@ -30,8 +30,10 @@ export type SecretAuth = PlaySecretAuth &
|
|
|
30
30
|
}
|
|
31
31
|
);
|
|
32
32
|
|
|
33
|
+
export type SecretAuthInput = SecretAuth | readonly SecretAuth[];
|
|
34
|
+
|
|
33
35
|
export type SecretAwareRequestInit = PlaySecretAwareRequestInit & {
|
|
34
|
-
auth?:
|
|
36
|
+
auth?: SecretAuthInput;
|
|
35
37
|
};
|
|
36
38
|
|
|
37
39
|
function isRecord(value: unknown): value is Record<string | symbol, unknown> {
|
|
@@ -46,6 +48,22 @@ export function isSecretAuth(value: unknown): value is SecretAuth {
|
|
|
46
48
|
return isRecord(value) && value[SECRET_AUTH_BRAND] === true;
|
|
47
49
|
}
|
|
48
50
|
|
|
51
|
+
export function isSecretAuthInput(value: unknown): value is SecretAuthInput {
|
|
52
|
+
return (
|
|
53
|
+
isSecretAuth(value) ||
|
|
54
|
+
(Array.isArray(value) &&
|
|
55
|
+
value.length > 0 &&
|
|
56
|
+
value.every((entry) => isSecretAuth(entry)))
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function secretAuthEntries(
|
|
61
|
+
auth: SecretAuthInput | undefined,
|
|
62
|
+
): readonly SecretAuth[] {
|
|
63
|
+
if (!auth) return [];
|
|
64
|
+
return isSecretAuth(auth) ? [auth] : auth;
|
|
65
|
+
}
|
|
66
|
+
|
|
49
67
|
export function valueContainsSecret(value: unknown): boolean {
|
|
50
68
|
const pending: unknown[] = [value];
|
|
51
69
|
const seen = new WeakSet<object>();
|
|
@@ -107,17 +125,24 @@ export function createHeaderSecretAuth(
|
|
|
107
125
|
}
|
|
108
126
|
|
|
109
127
|
export function secretAuthHeaderMarkers(
|
|
110
|
-
auth:
|
|
128
|
+
auth: SecretAuthInput | undefined,
|
|
111
129
|
): Record<string, string> {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
130
|
+
const markers: Record<string, string> = {};
|
|
131
|
+
for (const entry of secretAuthEntries(auth)) {
|
|
132
|
+
const header =
|
|
133
|
+
entry.kind === 'bearer' ? 'authorization' : entry.header.toLowerCase();
|
|
134
|
+
if (markers[header] !== undefined) {
|
|
135
|
+
throw new Error(
|
|
136
|
+
`ctx.fetch cannot attach more than one secret to the ${header} header.`,
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
markers[header] = `[secret:${entry.secret.name}]`;
|
|
115
140
|
}
|
|
116
|
-
return
|
|
141
|
+
return markers;
|
|
117
142
|
}
|
|
118
143
|
|
|
119
144
|
export function assertSecretAuthUsesTls(
|
|
120
|
-
auth:
|
|
145
|
+
auth: SecretAuthInput | undefined,
|
|
121
146
|
input: string | URL,
|
|
122
147
|
sink: string,
|
|
123
148
|
): void {
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public tool-response contracts shared by the API, SDK, Play bundler, and
|
|
3
|
+
* runtime. A response contract is transport behavior, never Play authoring.
|
|
4
|
+
*/
|
|
5
|
+
export const V2_TOOL_RESPONSE_CONTRACT = 'v2-tool-response' as const;
|
|
6
|
+
export const RAW_V2_TOOL_RESPONSE_CONTRACT = 'raw-v2' as const;
|
|
7
|
+
|
|
8
|
+
export type ToolResponseContract =
|
|
9
|
+
| typeof V2_TOOL_RESPONSE_CONTRACT
|
|
10
|
+
| typeof RAW_V2_TOOL_RESPONSE_CONTRACT;
|
|
11
|
+
|
|
12
|
+
export type ToolResponseView = 'data' | 'rawV2';
|
|
13
|
+
|
|
14
|
+
export function isToolResponseContract(
|
|
15
|
+
value: unknown,
|
|
16
|
+
): value is ToolResponseContract {
|
|
17
|
+
return (
|
|
18
|
+
value === V2_TOOL_RESPONSE_CONTRACT ||
|
|
19
|
+
value === RAW_V2_TOOL_RESPONSE_CONTRACT
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class UnsupportedToolResponseContractError extends Error {
|
|
24
|
+
constructor(value: unknown) {
|
|
25
|
+
super(
|
|
26
|
+
`Unsupported tool response contract ${String(value)}. Supported contracts: ${V2_TOOL_RESPONSE_CONTRACT}, ${RAW_V2_TOOL_RESPONSE_CONTRACT}.`,
|
|
27
|
+
);
|
|
28
|
+
this.name = 'UnsupportedToolResponseContractError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Missing artifact compatibility predates canonical bodies and stays V2. */
|
|
33
|
+
export function normalizeToolResponseContract(
|
|
34
|
+
value: unknown,
|
|
35
|
+
): ToolResponseContract {
|
|
36
|
+
if (value == null) return V2_TOOL_RESPONSE_CONTRACT;
|
|
37
|
+
if (isToolResponseContract(value)) return value;
|
|
38
|
+
throw new UnsupportedToolResponseContractError(value);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function legacyRawFromToolResponseRawV2(
|
|
42
|
+
rawV2: unknown,
|
|
43
|
+
view: ToolResponseView,
|
|
44
|
+
responseMeta?: Record<string, unknown>,
|
|
45
|
+
): unknown {
|
|
46
|
+
const legacyRaw =
|
|
47
|
+
view === 'data' &&
|
|
48
|
+
rawV2 &&
|
|
49
|
+
typeof rawV2 === 'object' &&
|
|
50
|
+
!Array.isArray(rawV2)
|
|
51
|
+
? (rawV2 as Record<string, unknown>).data
|
|
52
|
+
: rawV2;
|
|
53
|
+
// Before raw-v2, an async launch without a data envelope exposed
|
|
54
|
+
// Deepline's billing summary at `toolResponse.raw.deepline_billing`.
|
|
55
|
+
// The canonical response keeps it separate from provider data, so reattach
|
|
56
|
+
// it only to this derived legacy view.
|
|
57
|
+
const deeplineBilling = responseMeta?.deepline_billing;
|
|
58
|
+
if (
|
|
59
|
+
view === 'rawV2' &&
|
|
60
|
+
deeplineBilling !== undefined &&
|
|
61
|
+
legacyRaw &&
|
|
62
|
+
typeof legacyRaw === 'object' &&
|
|
63
|
+
!Array.isArray(legacyRaw)
|
|
64
|
+
) {
|
|
65
|
+
return {
|
|
66
|
+
...(legacyRaw as Record<string, unknown>),
|
|
67
|
+
deepline_billing: deeplineBilling,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return legacyRaw;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function providerMetaFromToolResponseRawV2(
|
|
74
|
+
rawV2: unknown,
|
|
75
|
+
view: ToolResponseView,
|
|
76
|
+
): Record<string, unknown> | undefined {
|
|
77
|
+
if (
|
|
78
|
+
view !== 'data' ||
|
|
79
|
+
!rawV2 ||
|
|
80
|
+
typeof rawV2 !== 'object' ||
|
|
81
|
+
Array.isArray(rawV2)
|
|
82
|
+
) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
const meta = (rawV2 as Record<string, unknown>).meta;
|
|
86
|
+
return meta && typeof meta === 'object' && !Array.isArray(meta)
|
|
87
|
+
? (meta as Record<string, unknown>)
|
|
88
|
+
: undefined;
|
|
89
|
+
}
|
|
@@ -75,7 +75,7 @@ export type ToolResultEnvelope<
|
|
|
75
75
|
meta?: TMeta;
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
-
export type
|
|
78
|
+
export type SerializedToolExecuteResultV1 = {
|
|
79
79
|
__kind: 'deepline.tool_execute_result.v1';
|
|
80
80
|
status: string;
|
|
81
81
|
job_id?: string;
|
|
@@ -98,11 +98,36 @@ export type SerializedToolExecuteResult = {
|
|
|
98
98
|
execution: ToolResultExecutionMetadata;
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Canonical receipt form. Provider data is stored once as `rawV2`; the legacy
|
|
103
|
+
* raw/meta view is recreated from the payload-free projection descriptor.
|
|
104
|
+
*/
|
|
105
|
+
export type SerializedToolExecuteResultV2 = Omit<
|
|
106
|
+
SerializedToolExecuteResultV1,
|
|
107
|
+
'__kind' | 'toolResponse'
|
|
108
|
+
> & {
|
|
109
|
+
__kind: 'deepline.tool_execute_result.v2';
|
|
110
|
+
toolResponse: {
|
|
111
|
+
rawV2: unknown;
|
|
112
|
+
view: 'data' | 'rawV2';
|
|
113
|
+
/** Deepline-owned additions not already represented in `rawV2.meta`. */
|
|
114
|
+
responseMeta?: Record<string, unknown>;
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export type SerializedToolExecuteResult =
|
|
119
|
+
| SerializedToolExecuteResultV1
|
|
120
|
+
| SerializedToolExecuteResultV2;
|
|
121
|
+
|
|
101
122
|
export type ToolResponseEnvelope<
|
|
102
123
|
TData = unknown,
|
|
103
124
|
TMeta = Record<string, unknown>,
|
|
104
125
|
> = {
|
|
105
126
|
raw: TData;
|
|
127
|
+
/** Complete parsed and scrubbed provider response, materialized from raw-v2. */
|
|
128
|
+
rawV2?: unknown;
|
|
129
|
+
/** Durable descriptor for deriving the legacy raw view from `rawV2`. */
|
|
130
|
+
view?: 'data' | 'rawV2';
|
|
106
131
|
meta?: TMeta;
|
|
107
132
|
};
|
|
108
133
|
|
|
@@ -156,8 +181,9 @@ export type ToolExecuteResultAccessors<
|
|
|
156
181
|
* Canonical result returned by Deepline tool execution.
|
|
157
182
|
*
|
|
158
183
|
* The top-level object is Deepline-owned execution metadata and semantic
|
|
159
|
-
* extraction state.
|
|
160
|
-
*
|
|
184
|
+
* extraction state. The canonical provider response lives under
|
|
185
|
+
* `toolResponse.rawV2`; `toolResponse.raw` remains the legacy compatibility
|
|
186
|
+
* projection. Response metadata lives under `toolResponse.meta`. Semantic single-value
|
|
161
187
|
* getters live under `extractedValues.<name>.get()`, and list getters live
|
|
162
188
|
* under `extractedLists.<name>.get()`.
|
|
163
189
|
*
|
|
@@ -49,10 +49,18 @@ import {
|
|
|
49
49
|
} from '../plays/dataset';
|
|
50
50
|
import { normalizeTableNamespace, sha256Hex } from '../plays/row-identity';
|
|
51
51
|
import { listNameFromDeclaredPath } from './tool-result-paths';
|
|
52
|
+
import {
|
|
53
|
+
legacyRawFromToolResponseRawV2,
|
|
54
|
+
providerMetaFromToolResponseRawV2,
|
|
55
|
+
type ToolResponseView,
|
|
56
|
+
} from './tool-response-contract';
|
|
52
57
|
|
|
53
58
|
type PathSegment = string | number | '*';
|
|
54
59
|
|
|
55
|
-
const
|
|
60
|
+
const SERIALIZED_TOOL_EXECUTE_RESULT_V1_KIND =
|
|
61
|
+
'deepline.tool_execute_result.v1';
|
|
62
|
+
const SERIALIZED_TOOL_EXECUTE_RESULT_V2_KIND =
|
|
63
|
+
'deepline.tool_execute_result.v2';
|
|
56
64
|
const SERIALIZED_TOOL_RESULT_LIST_PREVIEW_LIMIT = 5;
|
|
57
65
|
const LIVE_TOOL_RESULT_LIST_DATASET_REGISTRY_LIMIT = 256;
|
|
58
66
|
const SERIALIZED_TOOL_LIST_ROWS = Symbol('deepline.serialized_tool_list_rows');
|
|
@@ -123,6 +131,8 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
123
131
|
|
|
124
132
|
type V2ToolExecuteOutput = {
|
|
125
133
|
raw: unknown;
|
|
134
|
+
rawV2?: unknown;
|
|
135
|
+
view?: ToolResponseView;
|
|
126
136
|
meta?: Record<string, unknown>;
|
|
127
137
|
};
|
|
128
138
|
|
|
@@ -131,12 +141,35 @@ function parseV2ToolExecuteOutput(
|
|
|
131
141
|
): V2ToolExecuteOutput | null {
|
|
132
142
|
const toolResponse = data.toolResponse;
|
|
133
143
|
if (isRecord(toolResponse)) {
|
|
134
|
-
const
|
|
144
|
+
const rawV2 = Object.prototype.hasOwnProperty.call(toolResponse, 'rawV2')
|
|
145
|
+
? toolResponse.rawV2
|
|
146
|
+
: undefined;
|
|
147
|
+
const view =
|
|
148
|
+
toolResponse.view === 'data' || toolResponse.view === 'rawV2'
|
|
149
|
+
? toolResponse.view
|
|
150
|
+
: undefined;
|
|
151
|
+
const providerMeta = providerMetaFromToolResponseRawV2(
|
|
152
|
+
rawV2,
|
|
153
|
+
view ?? 'rawV2',
|
|
154
|
+
);
|
|
155
|
+
const responseMeta = isRecord(toolResponse.responseMeta)
|
|
156
|
+
? toolResponse.responseMeta
|
|
157
|
+
: undefined;
|
|
158
|
+
const meta = {
|
|
159
|
+
...(isRecord(toolResponse.meta) ? toolResponse.meta : {}),
|
|
160
|
+
...(providerMeta ?? {}),
|
|
161
|
+
...(responseMeta ?? {}),
|
|
162
|
+
};
|
|
163
|
+
const raw = Object.prototype.hasOwnProperty.call(toolResponse, 'raw')
|
|
164
|
+
? toolResponse.raw
|
|
165
|
+
: rawV2 === undefined
|
|
166
|
+
? null
|
|
167
|
+
: legacyRawFromToolResponseRawV2(rawV2, view ?? 'rawV2', responseMeta);
|
|
135
168
|
return {
|
|
136
|
-
raw
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
...(meta ? { meta } : {}),
|
|
169
|
+
raw,
|
|
170
|
+
...(rawV2 !== undefined ? { rawV2 } : {}),
|
|
171
|
+
...(view ? { view } : {}),
|
|
172
|
+
...(Object.keys(meta).length > 0 ? { meta } : {}),
|
|
140
173
|
};
|
|
141
174
|
}
|
|
142
175
|
return null;
|
|
@@ -181,7 +214,10 @@ export type ParsedToolExecuteResponse = {
|
|
|
181
214
|
meta?: Record<string, unknown>;
|
|
182
215
|
toolResponse?: {
|
|
183
216
|
raw?: unknown;
|
|
217
|
+
rawV2?: unknown;
|
|
218
|
+
view?: 'data' | 'rawV2';
|
|
184
219
|
meta?: Record<string, unknown>;
|
|
220
|
+
responseMeta?: Record<string, unknown>;
|
|
185
221
|
};
|
|
186
222
|
/** Legacy `{ data, meta }` envelope consumed by createToolExecuteResult. */
|
|
187
223
|
result: unknown;
|
|
@@ -204,9 +240,17 @@ export function parseToolExecuteResponse(
|
|
|
204
240
|
status,
|
|
205
241
|
jobId: typeof body.job_id === 'string' ? body.job_id : undefined,
|
|
206
242
|
meta: isRecord(body.meta) ? body.meta : undefined,
|
|
207
|
-
toolResponse:
|
|
208
|
-
|
|
209
|
-
|
|
243
|
+
toolResponse: (() => {
|
|
244
|
+
const output = parseV2ToolExecuteOutput(body);
|
|
245
|
+
return output
|
|
246
|
+
? {
|
|
247
|
+
raw: output.raw,
|
|
248
|
+
...(output.rawV2 !== undefined ? { rawV2: output.rawV2 } : {}),
|
|
249
|
+
...(output.view ? { view: output.view } : {}),
|
|
250
|
+
...(output.meta ? { meta: output.meta } : {}),
|
|
251
|
+
}
|
|
252
|
+
: undefined;
|
|
253
|
+
})(),
|
|
210
254
|
result,
|
|
211
255
|
metadata: parseExecuteToolMetadata(toolId, body),
|
|
212
256
|
};
|
|
@@ -1135,11 +1179,20 @@ export function createToolExecuteResult<TResult = unknown>(input: {
|
|
|
1135
1179
|
metadata: ToolResultMetadataInput;
|
|
1136
1180
|
execution: ToolResultExecutionMetadata;
|
|
1137
1181
|
meta?: Record<string, unknown>;
|
|
1182
|
+
response?: {
|
|
1183
|
+
rawV2?: unknown;
|
|
1184
|
+
view?: 'data' | 'rawV2';
|
|
1185
|
+
meta?: Record<string, unknown>;
|
|
1186
|
+
};
|
|
1138
1187
|
}): ToolExecuteResult<TResult> {
|
|
1139
1188
|
const result = toResultEnvelope(input.result);
|
|
1140
1189
|
const resultRoot = {
|
|
1141
1190
|
toolResponse: {
|
|
1142
1191
|
raw: result.data,
|
|
1192
|
+
...(input.response && 'rawV2' in input.response
|
|
1193
|
+
? { rawV2: input.response.rawV2 }
|
|
1194
|
+
: {}),
|
|
1195
|
+
...(input.response?.view ? { view: input.response.view } : {}),
|
|
1143
1196
|
...(result.meta ? { meta: result.meta } : {}),
|
|
1144
1197
|
},
|
|
1145
1198
|
};
|
|
@@ -1165,6 +1218,10 @@ export function createToolExecuteResult<TResult = unknown>(input: {
|
|
|
1165
1218
|
};
|
|
1166
1219
|
const toolResponse = {
|
|
1167
1220
|
raw: result.data,
|
|
1221
|
+
...(input.response && 'rawV2' in input.response
|
|
1222
|
+
? { rawV2: input.response.rawV2 }
|
|
1223
|
+
: {}),
|
|
1224
|
+
...(input.response?.view ? { view: input.response.view } : {}),
|
|
1168
1225
|
...(result.meta ? { meta: result.meta } : {}),
|
|
1169
1226
|
};
|
|
1170
1227
|
const extractedValues = buildExtractedAccessors(targets);
|
|
@@ -1634,6 +1691,17 @@ function applySerializedListDatasets(
|
|
|
1634
1691
|
listDatasets,
|
|
1635
1692
|
listRows,
|
|
1636
1693
|
});
|
|
1694
|
+
if (Object.prototype.hasOwnProperty.call(result.toolResponse, 'rawV2')) {
|
|
1695
|
+
const view = result.toolResponse.view ?? 'rawV2';
|
|
1696
|
+
if (view === 'data' && isRecord(result.toolResponse.rawV2)) {
|
|
1697
|
+
result.toolResponse.rawV2 = {
|
|
1698
|
+
...result.toolResponse.rawV2,
|
|
1699
|
+
data: result.toolResponse.raw,
|
|
1700
|
+
};
|
|
1701
|
+
} else {
|
|
1702
|
+
result.toolResponse.rawV2 = result.toolResponse.raw;
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1637
1705
|
Object.defineProperty(result, SERIALIZED_TOOL_LIST_ROWS, {
|
|
1638
1706
|
value: listRows,
|
|
1639
1707
|
enumerable: false,
|
|
@@ -1695,6 +1763,47 @@ function metadataInputFromToolExecuteResult(
|
|
|
1695
1763
|
};
|
|
1696
1764
|
}
|
|
1697
1765
|
|
|
1766
|
+
function sameJsonValue(left: unknown, right: unknown): boolean {
|
|
1767
|
+
if (left === right) return true;
|
|
1768
|
+
try {
|
|
1769
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
1770
|
+
} catch {
|
|
1771
|
+
return false;
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
function responseMetaOutsideRawV2(input: {
|
|
1776
|
+
rawV2: unknown;
|
|
1777
|
+
view: 'data' | 'rawV2';
|
|
1778
|
+
meta: Record<string, unknown> | undefined;
|
|
1779
|
+
}): Record<string, unknown> | undefined {
|
|
1780
|
+
if (!input.meta) return undefined;
|
|
1781
|
+
const providerMeta =
|
|
1782
|
+
input.view === 'data' && isRecord(input.rawV2) && isRecord(input.rawV2.meta)
|
|
1783
|
+
? input.rawV2.meta
|
|
1784
|
+
: undefined;
|
|
1785
|
+
if (!providerMeta) return input.meta;
|
|
1786
|
+
const responseMeta = Object.fromEntries(
|
|
1787
|
+
Object.entries(input.meta).filter(
|
|
1788
|
+
([key, value]) =>
|
|
1789
|
+
!Object.prototype.hasOwnProperty.call(providerMeta, key) ||
|
|
1790
|
+
!sameJsonValue(providerMeta[key], value),
|
|
1791
|
+
),
|
|
1792
|
+
);
|
|
1793
|
+
return Object.keys(responseMeta).length > 0 ? responseMeta : undefined;
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
function rawV2WithSerializedRawPreview(input: {
|
|
1797
|
+
rawV2: unknown;
|
|
1798
|
+
view: 'data' | 'rawV2';
|
|
1799
|
+
raw: unknown;
|
|
1800
|
+
}): unknown {
|
|
1801
|
+
if (input.view === 'data' && isRecord(input.rawV2)) {
|
|
1802
|
+
return { ...input.rawV2, data: input.raw };
|
|
1803
|
+
}
|
|
1804
|
+
return input.raw;
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1698
1807
|
export function serializeToolExecuteResult(
|
|
1699
1808
|
value: ToolExecuteResult,
|
|
1700
1809
|
): SerializedToolExecuteResult {
|
|
@@ -1706,17 +1815,54 @@ export function serializeToolExecuteResult(
|
|
|
1706
1815
|
metadata,
|
|
1707
1816
|
});
|
|
1708
1817
|
const targetValues = serializedTargetValuesFromResult(value);
|
|
1818
|
+
const serializedRaw = serializedRawWithListPreviews({
|
|
1819
|
+
raw: value.toolResponse.raw,
|
|
1820
|
+
metadata,
|
|
1821
|
+
listDatasets,
|
|
1822
|
+
});
|
|
1823
|
+
if (Object.prototype.hasOwnProperty.call(value.toolResponse, 'rawV2')) {
|
|
1824
|
+
const view = value.toolResponse.view ?? 'rawV2';
|
|
1825
|
+
const rawV2 = rawV2WithSerializedRawPreview({
|
|
1826
|
+
rawV2: value.toolResponse.rawV2,
|
|
1827
|
+
view,
|
|
1828
|
+
raw:
|
|
1829
|
+
view === 'data'
|
|
1830
|
+
? serializedRaw
|
|
1831
|
+
: serializedRawWithListPreviews({
|
|
1832
|
+
raw: value.toolResponse.rawV2,
|
|
1833
|
+
metadata,
|
|
1834
|
+
listDatasets,
|
|
1835
|
+
}),
|
|
1836
|
+
});
|
|
1837
|
+
const responseMeta = responseMetaOutsideRawV2({
|
|
1838
|
+
rawV2: value.toolResponse.rawV2,
|
|
1839
|
+
view,
|
|
1840
|
+
meta: value.toolResponse.meta,
|
|
1841
|
+
});
|
|
1842
|
+
return {
|
|
1843
|
+
__kind: SERIALIZED_TOOL_EXECUTE_RESULT_V2_KIND,
|
|
1844
|
+
status: value.status,
|
|
1845
|
+
...(typeof value.job_id === 'string' ? { job_id: value.job_id } : {}),
|
|
1846
|
+
...(isRecord(value.meta) ? { meta: value.meta } : {}),
|
|
1847
|
+
toolResponse: {
|
|
1848
|
+
rawV2,
|
|
1849
|
+
view,
|
|
1850
|
+
...(responseMeta ? { responseMeta } : {}),
|
|
1851
|
+
},
|
|
1852
|
+
...(listDatasets ? { listDatasets } : {}),
|
|
1853
|
+
...(listRows ? { listRows } : {}),
|
|
1854
|
+
...(targetValues ? { targetValues } : {}),
|
|
1855
|
+
metadata,
|
|
1856
|
+
execution: value._metadata.execution,
|
|
1857
|
+
};
|
|
1858
|
+
}
|
|
1709
1859
|
return {
|
|
1710
|
-
__kind:
|
|
1860
|
+
__kind: SERIALIZED_TOOL_EXECUTE_RESULT_V1_KIND,
|
|
1711
1861
|
status: value.status,
|
|
1712
1862
|
...(typeof value.job_id === 'string' ? { job_id: value.job_id } : {}),
|
|
1713
1863
|
...(isRecord(value.meta) ? { meta: value.meta } : {}),
|
|
1714
1864
|
toolResponse: {
|
|
1715
|
-
raw:
|
|
1716
|
-
raw: value.toolResponse.raw,
|
|
1717
|
-
metadata,
|
|
1718
|
-
listDatasets,
|
|
1719
|
-
}),
|
|
1865
|
+
raw: serializedRaw,
|
|
1720
1866
|
...(value.toolResponse.meta ? { meta: value.toolResponse.meta } : {}),
|
|
1721
1867
|
},
|
|
1722
1868
|
...(listDatasets ? { listDatasets } : {}),
|
|
@@ -1732,7 +1878,8 @@ export function isSerializedToolExecuteResult(
|
|
|
1732
1878
|
): value is SerializedToolExecuteResult {
|
|
1733
1879
|
return (
|
|
1734
1880
|
isRecord(value) &&
|
|
1735
|
-
value.__kind ===
|
|
1881
|
+
(value.__kind === SERIALIZED_TOOL_EXECUTE_RESULT_V1_KIND ||
|
|
1882
|
+
value.__kind === SERIALIZED_TOOL_EXECUTE_RESULT_V2_KIND) &&
|
|
1736
1883
|
typeof value.status === 'string' &&
|
|
1737
1884
|
isRecord(value.toolResponse) &&
|
|
1738
1885
|
isRecord(value.metadata) &&
|
|
@@ -1743,6 +1890,46 @@ export function isSerializedToolExecuteResult(
|
|
|
1743
1890
|
export function deserializeToolExecuteResult(
|
|
1744
1891
|
value: SerializedToolExecuteResult,
|
|
1745
1892
|
): ToolExecuteResult {
|
|
1893
|
+
if (value.__kind === SERIALIZED_TOOL_EXECUTE_RESULT_V2_KIND) {
|
|
1894
|
+
const view = value.toolResponse.view;
|
|
1895
|
+
const rawV2 = value.toolResponse.rawV2;
|
|
1896
|
+
const providerMeta =
|
|
1897
|
+
view === 'data' && isRecord(rawV2) && isRecord(rawV2.meta)
|
|
1898
|
+
? rawV2.meta
|
|
1899
|
+
: undefined;
|
|
1900
|
+
const meta = {
|
|
1901
|
+
...(providerMeta ?? {}),
|
|
1902
|
+
...(value.toolResponse.responseMeta ?? {}),
|
|
1903
|
+
};
|
|
1904
|
+
const raw = legacyRawFromToolResponseRawV2(
|
|
1905
|
+
rawV2,
|
|
1906
|
+
view,
|
|
1907
|
+
value.toolResponse.responseMeta,
|
|
1908
|
+
);
|
|
1909
|
+
return applySerializedListDatasets(
|
|
1910
|
+
applySerializedTargetValues(
|
|
1911
|
+
createToolExecuteResult({
|
|
1912
|
+
status: value.status,
|
|
1913
|
+
jobId: value.job_id,
|
|
1914
|
+
result: {
|
|
1915
|
+
data: raw,
|
|
1916
|
+
...(Object.keys(meta).length > 0 ? { meta } : {}),
|
|
1917
|
+
},
|
|
1918
|
+
response: {
|
|
1919
|
+
rawV2,
|
|
1920
|
+
view,
|
|
1921
|
+
...(Object.keys(meta).length > 0 ? { meta } : {}),
|
|
1922
|
+
},
|
|
1923
|
+
metadata: value.metadata,
|
|
1924
|
+
execution: value.execution,
|
|
1925
|
+
meta: value.meta,
|
|
1926
|
+
}),
|
|
1927
|
+
value.targetValues,
|
|
1928
|
+
),
|
|
1929
|
+
value.listDatasets,
|
|
1930
|
+
value.listRows,
|
|
1931
|
+
);
|
|
1932
|
+
}
|
|
1746
1933
|
return applySerializedListDatasets(
|
|
1747
1934
|
applySerializedTargetValues(
|
|
1748
1935
|
createToolExecuteResult({
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ToolExecutionErrorSchemaVersion } from '../tool-execution-error';
|
|
2
|
+
import type { ToolResponseContract } from '../play-runtime/tool-response-contract';
|
|
2
3
|
import type { PlayAuthoringContractEdition } from './authoring-contract';
|
|
3
4
|
|
|
4
5
|
export type PlayPackageImport = {
|
|
@@ -28,6 +29,8 @@ export type PlayArtifactCompatibility = {
|
|
|
28
29
|
toolErrorSchemaVersion?: ToolExecutionErrorSchemaVersion;
|
|
29
30
|
/** Missing preserves edition 1 for artifacts created before authoring contracts were pinned. */
|
|
30
31
|
authoringContractEdition?: PlayAuthoringContractEdition;
|
|
32
|
+
/** Missing preserves the raw-only V2 execute response contract. */
|
|
33
|
+
toolResponseContract?: ToolResponseContract;
|
|
31
34
|
};
|
|
32
35
|
|
|
33
36
|
/** The only executable Play artifact contract. */
|
|
@@ -410,6 +410,8 @@ export type PlaySecretAuth = {
|
|
|
410
410
|
/** Header name, set only when `kind` is `header`. */
|
|
411
411
|
readonly header?: string;
|
|
412
412
|
};
|
|
413
|
+
/** One or more resolved authentication schemes for an outbound request. */
|
|
414
|
+
export type PlaySecretAuthInput = PlaySecretAuth | readonly PlaySecretAuth[];
|
|
413
415
|
/**
|
|
414
416
|
* The `init` accepted by `ctx.fetch`. Same shape as `RequestInit` plus `auth`.
|
|
415
417
|
*
|
|
@@ -419,9 +421,9 @@ export type PlaySecretAwareRequestInit = Omit<RequestInit, 'headers'> & {
|
|
|
419
421
|
/** Ordinary request headers, recorded in the durable receipt. Never interpolate a secret value here — use `auth`. */
|
|
420
422
|
headers?: HeadersInit;
|
|
421
423
|
/**
|
|
422
|
-
*
|
|
424
|
+
* One or more secret-backed authentication headers for this request. Pass a single `ctx.secrets` auth for the common case, or an array when an API requires multiple credentialed headers — for example, Supabase with both `apikey` and `Authorization`. Every secret is resolved only while the request is attached, never stored in the durable receipt. Each auth entry must target a distinct header.
|
|
423
425
|
*/
|
|
424
|
-
auth?:
|
|
426
|
+
auth?: PlaySecretAuthInput;
|
|
425
427
|
};
|
|
426
428
|
export type PlayLooseObject = { [key: string]: PlayLooseObject };
|
|
427
429
|
|
|
@@ -2464,6 +2466,7 @@ export const PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
|
|
|
2464
2466
|
'declare const SECRET_HANDLE_BRAND: unique symbol;',
|
|
2465
2467
|
'export type SecretHandle = { readonly [SECRET_HANDLE_BRAND]: never; readonly name: string; toString(): string; toJSON(): never };',
|
|
2466
2468
|
"export type SecretAuth = { readonly kind: 'bearer' | 'header'; readonly secret: SecretHandle; readonly header?: string };",
|
|
2469
|
+
'export type SecretAuthInput = SecretAuth | readonly SecretAuth[];',
|
|
2467
2470
|
'export type PlayInputContract<TInput> = { readonly schema: Record<string, unknown>; readonly __inputType?: TInput };',
|
|
2468
2471
|
'export type PlayReturnObject = Record<string, unknown> & { readonly _metadata?: never };',
|
|
2469
2472
|
'export type CsvRenameMap = Record<string, string | readonly string[]>;',
|
|
@@ -2512,7 +2515,7 @@ export const PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
|
|
|
2512
2515
|
` customerDb: { query<TRow extends Record<string, unknown> = Record<string, unknown>>(statement: SqlQuery, options?: { maxRows?: ${cloudReferenceType('ctx.customerDb.query.options.maxRows')}; timeoutMs?: ${cloudReferenceType('ctx.customerDb.query.options.timeoutMs')} }): Promise<TRow[]> };`,
|
|
2513
2516
|
` tool<K extends string>(key: ${cloudReferenceType('ctx.tool.key')}, toolId: K, input: ${cloudReferenceType('ctx.tool.input')}, options?: { description?: ${cloudReferenceType('ctx.tool.options.description')} }): Promise<ToolExecutionOutput<K>>;`,
|
|
2514
2517
|
' step<T>(id: string, run: () => T | Promise<T>, options?: RuntimeStepOptions): Promise<T>;',
|
|
2515
|
-
" fetch(key: string, url: string | URL, init?: RequestInit & { headers?: HeadersInit & { 'Idempotency-Key'?: string; 'X-Idempotency-Key'?: string }; auth?:
|
|
2518
|
+
" fetch(key: string, url: string | URL, init?: RequestInit & { headers?: HeadersInit & { 'Idempotency-Key'?: string; 'X-Idempotency-Key'?: string }; auth?: SecretAuthInput }, options?: FetchOptions): Promise<PlayFetchResponse>;",
|
|
2516
2519
|
' secrets: { get(name: string): SecretHandle; bearer(secret: SecretHandle): SecretAuth; header(header: string, secret: SecretHandle): SecretAuth };',
|
|
2517
2520
|
` runPlay<TOutput = unknown>(key: string, playRef: ${cloudReferenceType('ctx.runPlay.playRef')}, input: ${cloudReferenceType('ctx.runPlay.input')}, options: PlayCallOptions): Promise<TOutput>;`,
|
|
2518
2521
|
' log(message: string): void;',
|
|
@@ -10,6 +10,11 @@ import {
|
|
|
10
10
|
type PlayAuthoringContractEdition,
|
|
11
11
|
type AdmittedPlayAuthoringContract,
|
|
12
12
|
} from './authoring-contract';
|
|
13
|
+
import {
|
|
14
|
+
normalizeToolResponseContract,
|
|
15
|
+
RAW_V2_TOOL_RESPONSE_CONTRACT,
|
|
16
|
+
type ToolResponseContract,
|
|
17
|
+
} from '../play-runtime/tool-response-contract';
|
|
13
18
|
|
|
14
19
|
export type PlayContractSource = 'ad_hoc' | 'draft' | 'published';
|
|
15
20
|
|
|
@@ -39,12 +44,15 @@ export type PlayContractCompatibilitySnapshot = {
|
|
|
39
44
|
toolErrorSchemaVersion?: ToolExecutionErrorSchemaVersion;
|
|
40
45
|
/** Missing preserves edition 1 for artifacts stored before authoring contracts were pinned. */
|
|
41
46
|
authoringContractEdition?: PlayAuthoringContractEdition;
|
|
47
|
+
/** Immutable execute-result transport selected when the artifact is built. */
|
|
48
|
+
toolResponseContract?: ToolResponseContract;
|
|
42
49
|
};
|
|
43
50
|
|
|
44
51
|
export type NormalizedPlayContractCompatibilitySnapshot =
|
|
45
52
|
PlayContractCompatibilitySnapshot & {
|
|
46
53
|
toolErrorSchemaVersion: ToolExecutionErrorSchemaVersion;
|
|
47
54
|
authoringContractEdition: PlayAuthoringContractEdition;
|
|
55
|
+
toolResponseContract: ToolResponseContract;
|
|
48
56
|
};
|
|
49
57
|
|
|
50
58
|
export class UnsupportedPlayToolErrorSchemaVersionError extends Error {
|
|
@@ -94,6 +102,9 @@ export function normalizePlayContractCompatibility(
|
|
|
94
102
|
return {
|
|
95
103
|
...compatibility,
|
|
96
104
|
toolErrorSchemaVersion: TOOL_EXECUTION_ERROR_SCHEMA_VERSION,
|
|
105
|
+
toolResponseContract: normalizeToolResponseContract(
|
|
106
|
+
compatibility.toolResponseContract,
|
|
107
|
+
),
|
|
97
108
|
authoringContractEdition: normalizePlayAuthoringContractEdition(
|
|
98
109
|
compatibility.authoringContractEdition,
|
|
99
110
|
),
|
|
@@ -104,6 +115,7 @@ export function buildPlayContractCompatibility(input?: {
|
|
|
104
115
|
runtimeBackend?: string | null;
|
|
105
116
|
toolErrorSchemaVersion?: ToolExecutionErrorSchemaVersion;
|
|
106
117
|
authoringContractEdition?: PlayAuthoringContractEdition;
|
|
118
|
+
toolResponseContract?: ToolResponseContract;
|
|
107
119
|
}): PlayContractCompatibilitySnapshot {
|
|
108
120
|
return {
|
|
109
121
|
apiVersion: PLAY_PUBLIC_API_VERSION,
|
|
@@ -115,6 +127,8 @@ export function buildPlayContractCompatibility(input?: {
|
|
|
115
127
|
input?.toolErrorSchemaVersion ?? TOOL_EXECUTION_ERROR_SCHEMA_VERSION,
|
|
116
128
|
authoringContractEdition:
|
|
117
129
|
input?.authoringContractEdition ?? PLAY_AUTHORING_CONTRACT_EDITION,
|
|
130
|
+
toolResponseContract:
|
|
131
|
+
input?.toolResponseContract ?? RAW_V2_TOOL_RESPONSE_CONTRACT,
|
|
118
132
|
};
|
|
119
133
|
}
|
|
120
134
|
|