@sequenceholdings/artifact-studio 0.7.1 → 0.8.1
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/README.md +87 -3
- package/dist/build.js +4 -2
- package/dist/gateway/authorization-cache.js +1 -1
- package/dist/gateway/control.d.ts +13 -1
- package/dist/gateway/control.js +3 -0
- package/dist/gateway/datadog-startup.d.ts +13 -0
- package/dist/gateway/datadog-startup.js +51 -0
- package/dist/gateway/hosted-proxy.d.ts +2 -0
- package/dist/gateway/hosted-proxy.js +9 -11
- package/dist/gateway/ingress-handler.js +2 -0
- package/dist/gateway/server.d.ts +1 -1
- package/dist/gateway/server.js +51 -20
- package/dist/gateway/session.d.ts +14 -0
- package/dist/gateway/session.js +31 -2
- package/dist/gateway-main.js +5 -3
- package/dist/manifest-next.d.ts +9 -0
- package/dist/manifest-next.js +5 -0
- package/dist/manifest.d.ts +3 -0
- package/dist/server/agent-responses.d.ts +425 -0
- package/dist/server/agent-responses.js +154 -0
- package/dist/server/broker-contract.d.ts +17 -0
- package/dist/server/broker-contract.js +17 -2
- package/dist/server/client.d.ts +5 -0
- package/dist/server/client.js +12 -2
- package/dist/server/groups.d.ts +32 -0
- package/dist/server/groups.js +28 -0
- package/dist/server/processes.d.ts +11 -0
- package/dist/server/request-authentication.d.ts +42 -0
- package/dist/server/request-authentication.js +93 -0
- package/dist/server/request-context.d.ts +1 -0
- package/dist/server/request-context.js +1 -0
- package/dist/server.d.ts +4 -3
- package/dist/server.js +2 -2
- package/dist/source-boundary.js +13 -5
- package/dist/templates/react-vite/package.json +1 -1
- package/dist/tunnel/broker.d.ts +14 -1
- package/dist/tunnel/broker.js +94 -10
- package/dist/tunnel/client.js +6 -0
- package/dist/tunnel/redis-types.d.ts +5 -1
- package/dist/tunnel/redis.d.ts +12 -0
- package/dist/tunnel/redis.js +102 -4
- package/dist/tunnel/transport.d.ts +3 -0
- package/package.json +2 -2
- package/templates/react-vite/package.json +1 -1
package/dist/gateway-main.js
CHANGED
|
@@ -10,6 +10,7 @@ import { RedisTunnelOwnership, RedisTunnelRelay } from './tunnel/redis.js';
|
|
|
10
10
|
import { ArtifactRequestAdmission } from './gateway/admission.js';
|
|
11
11
|
import { GatewayControlAdmission } from './gateway/control-admission.js';
|
|
12
12
|
import { createIngressRuntime, IngressSecretsError } from './gateway/ingress-runtime.js';
|
|
13
|
+
import { DatadogStartupError, waitForDatadogStartup } from './gateway/datadog-startup.js';
|
|
13
14
|
function required(name) {
|
|
14
15
|
const value = process.env[name];
|
|
15
16
|
if (!value)
|
|
@@ -20,6 +21,7 @@ function required(name) {
|
|
|
20
21
|
async function main() {
|
|
21
22
|
if (process.env.ARTIFACT_NEXT_ENABLED !== 'true')
|
|
22
23
|
throw new Error('Artifact Next gateway is disabled');
|
|
24
|
+
await waitForDatadogStartup({ env: process.env });
|
|
23
25
|
const redisUrl = required('ARTIFACT_NEXT_REDIS_URL');
|
|
24
26
|
if (new URL(redisUrl).protocol !== 'rediss:')
|
|
25
27
|
throw new Error('Artifact tunnel routing requires private Redis with TLS');
|
|
@@ -135,9 +137,9 @@ async function main() {
|
|
|
135
137
|
process.once('SIGINT', () => { void stop(); });
|
|
136
138
|
}
|
|
137
139
|
void main().catch((error) => {
|
|
138
|
-
//
|
|
139
|
-
//
|
|
140
|
-
const reason = error instanceof IngressSecretsError ? error.message : undefined;
|
|
140
|
+
// These startup refusals contain only fixed descriptions and configuration names.
|
|
141
|
+
// Other errors (Redis, URLs) may carry connection strings.
|
|
142
|
+
const reason = error instanceof IngressSecretsError || error instanceof DatadogStartupError ? error.message : undefined;
|
|
141
143
|
process.stderr.write(`${JSON.stringify({ event: 'artifact_gateway.start_failed', ...(reason ? { reason } : {}) })}\n`);
|
|
142
144
|
process.exit(1);
|
|
143
145
|
});
|
package/dist/manifest-next.d.ts
CHANGED
|
@@ -28,6 +28,9 @@ export declare const artifactNextServerCapabilitiesSchema: z.ZodPrefault<z.ZodOb
|
|
|
28
28
|
audit: z.ZodOptional<z.ZodObject<{
|
|
29
29
|
service: z.ZodString;
|
|
30
30
|
}, z.core.$strict>>;
|
|
31
|
+
groups: z.ZodOptional<z.ZodObject<{
|
|
32
|
+
read: z.ZodBoolean;
|
|
33
|
+
}, z.core.$strict>>;
|
|
31
34
|
storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
|
|
32
35
|
viewer: "viewer";
|
|
33
36
|
editor: "editor";
|
|
@@ -89,6 +92,9 @@ export declare const artifactNextServerSchema: z.ZodPrefault<z.ZodObject<{
|
|
|
89
92
|
audit: z.ZodOptional<z.ZodObject<{
|
|
90
93
|
service: z.ZodString;
|
|
91
94
|
}, z.core.$strict>>;
|
|
95
|
+
groups: z.ZodOptional<z.ZodObject<{
|
|
96
|
+
read: z.ZodBoolean;
|
|
97
|
+
}, z.core.$strict>>;
|
|
92
98
|
storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
|
|
93
99
|
viewer: "viewer";
|
|
94
100
|
editor: "editor";
|
|
@@ -280,6 +286,9 @@ export declare const artifactStudioNextManifestSchema: z.ZodObject<{
|
|
|
280
286
|
audit: z.ZodOptional<z.ZodObject<{
|
|
281
287
|
service: z.ZodString;
|
|
282
288
|
}, z.core.$strict>>;
|
|
289
|
+
groups: z.ZodOptional<z.ZodObject<{
|
|
290
|
+
read: z.ZodBoolean;
|
|
291
|
+
}, z.core.$strict>>;
|
|
283
292
|
storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
|
|
284
293
|
viewer: "viewer";
|
|
285
294
|
editor: "editor";
|
package/dist/manifest-next.js
CHANGED
|
@@ -15,9 +15,14 @@ export const ARTIFACT_NEXT_RESOURCE_DEFAULTS = {
|
|
|
15
15
|
};
|
|
16
16
|
export { artifactNextAuditCapabilitySchema };
|
|
17
17
|
export * from './manifest-next-ingress.js';
|
|
18
|
+
/** Caller-scoped group membership. A boolean, not a list of group ids: the directory decides which groups the signed-in user is in. */
|
|
19
|
+
const artifactNextGroupsCapabilitySchema = z.strictObject({
|
|
20
|
+
read: z.boolean(),
|
|
21
|
+
});
|
|
18
22
|
export const artifactNextServerCapabilitiesSchema = z.strictObject({
|
|
19
23
|
...reachShape,
|
|
20
24
|
audit: artifactNextAuditCapabilitySchema.optional(),
|
|
25
|
+
groups: artifactNextGroupsCapabilitySchema.optional(),
|
|
21
26
|
}).prefault({});
|
|
22
27
|
// Reuse role semantics and validation; only the new manifest rejects unknown keys.
|
|
23
28
|
const strictCustomRoles = customRolesBlockSchema.safeExtend({
|
package/dist/manifest.d.ts
CHANGED
|
@@ -167,6 +167,9 @@ export declare const artifactStudioManifestSchema: z.ZodUnion<readonly [z.ZodObj
|
|
|
167
167
|
audit: z.ZodOptional<z.ZodObject<{
|
|
168
168
|
service: z.ZodString;
|
|
169
169
|
}, z.core.$strict>>;
|
|
170
|
+
groups: z.ZodOptional<z.ZodObject<{
|
|
171
|
+
read: z.ZodBoolean;
|
|
172
|
+
}, z.core.$strict>>;
|
|
170
173
|
storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
|
|
171
174
|
viewer: "viewer";
|
|
172
175
|
editor: "editor";
|
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ArtifactServerMode, ArtifactServerRequest } from './broker-contract.js';
|
|
3
|
+
/** Mirrors the platform's completed response contract; cross-package fixtures protect this boundary. */
|
|
4
|
+
export declare const artifactCompletedAgentResponseSchema: z.ZodObject<{
|
|
5
|
+
runId: z.ZodString;
|
|
6
|
+
agent: z.ZodString;
|
|
7
|
+
threadId: z.ZodString;
|
|
8
|
+
status: z.ZodLiteral<"completed">;
|
|
9
|
+
output: z.ZodJSONSchema;
|
|
10
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
11
|
+
id: z.ZodString;
|
|
12
|
+
role: z.ZodLiteral<"assistant">;
|
|
13
|
+
parts: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
14
|
+
type: z.ZodLiteral<"text">;
|
|
15
|
+
text: z.ZodString;
|
|
16
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
17
|
+
type: z.ZodLiteral<"dynamic-tool">;
|
|
18
|
+
output: z.ZodObject<{
|
|
19
|
+
content: z.ZodArray<z.ZodObject<{
|
|
20
|
+
type: z.ZodLiteral<"resource">;
|
|
21
|
+
resource: z.ZodObject<{
|
|
22
|
+
uri: z.ZodString;
|
|
23
|
+
text: z.ZodString;
|
|
24
|
+
}, z.core.$strict>;
|
|
25
|
+
}, z.core.$strict>>;
|
|
26
|
+
}, z.core.$strict>;
|
|
27
|
+
}, z.core.$strict>]>>;
|
|
28
|
+
metadata: z.ZodOptional<z.ZodObject<{
|
|
29
|
+
citations: z.ZodArray<z.ZodJSONSchema>;
|
|
30
|
+
}, z.core.$strict>>;
|
|
31
|
+
}, z.core.$strict>>;
|
|
32
|
+
conversation: z.ZodOptional<z.ZodObject<{
|
|
33
|
+
messageCount: z.ZodNumber;
|
|
34
|
+
userMessageCount: z.ZodNumber;
|
|
35
|
+
assistantMessageCount: z.ZodNumber;
|
|
36
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
37
|
+
id: z.ZodString;
|
|
38
|
+
role: z.ZodEnum<{
|
|
39
|
+
user: "user";
|
|
40
|
+
assistant: "assistant";
|
|
41
|
+
}>;
|
|
42
|
+
textParts: z.ZodArray<z.ZodString>;
|
|
43
|
+
tools: z.ZodArray<z.ZodObject<{
|
|
44
|
+
partType: z.ZodString;
|
|
45
|
+
toolName: z.ZodNullable<z.ZodString>;
|
|
46
|
+
state: z.ZodNullable<z.ZodString>;
|
|
47
|
+
outputTruthy: z.ZodBoolean;
|
|
48
|
+
}, z.core.$strict>>;
|
|
49
|
+
}, z.core.$strict>>;
|
|
50
|
+
}, z.core.$strict>>;
|
|
51
|
+
}, z.core.$strict>;
|
|
52
|
+
export type ArtifactCompletedAgentRun = z.infer<typeof artifactCompletedAgentResponseSchema>;
|
|
53
|
+
export declare const artifactCompletedAgentConversationSchema: z.ZodObject<{
|
|
54
|
+
runId: z.ZodString;
|
|
55
|
+
agent: z.ZodString;
|
|
56
|
+
threadId: z.ZodString;
|
|
57
|
+
status: z.ZodLiteral<"completed">;
|
|
58
|
+
output: z.ZodJSONSchema;
|
|
59
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
60
|
+
id: z.ZodString;
|
|
61
|
+
role: z.ZodLiteral<"assistant">;
|
|
62
|
+
parts: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
63
|
+
type: z.ZodLiteral<"text">;
|
|
64
|
+
text: z.ZodString;
|
|
65
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
66
|
+
type: z.ZodLiteral<"dynamic-tool">;
|
|
67
|
+
output: z.ZodObject<{
|
|
68
|
+
content: z.ZodArray<z.ZodObject<{
|
|
69
|
+
type: z.ZodLiteral<"resource">;
|
|
70
|
+
resource: z.ZodObject<{
|
|
71
|
+
uri: z.ZodString;
|
|
72
|
+
text: z.ZodString;
|
|
73
|
+
}, z.core.$strict>;
|
|
74
|
+
}, z.core.$strict>>;
|
|
75
|
+
}, z.core.$strict>;
|
|
76
|
+
}, z.core.$strict>]>>;
|
|
77
|
+
metadata: z.ZodOptional<z.ZodObject<{
|
|
78
|
+
citations: z.ZodArray<z.ZodJSONSchema>;
|
|
79
|
+
}, z.core.$strict>>;
|
|
80
|
+
}, z.core.$strict>>;
|
|
81
|
+
conversation: z.ZodOptional<z.ZodObject<{
|
|
82
|
+
messageCount: z.ZodNumber;
|
|
83
|
+
userMessageCount: z.ZodNumber;
|
|
84
|
+
assistantMessageCount: z.ZodNumber;
|
|
85
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
86
|
+
id: z.ZodString;
|
|
87
|
+
role: z.ZodEnum<{
|
|
88
|
+
user: "user";
|
|
89
|
+
assistant: "assistant";
|
|
90
|
+
}>;
|
|
91
|
+
textParts: z.ZodArray<z.ZodString>;
|
|
92
|
+
tools: z.ZodArray<z.ZodObject<{
|
|
93
|
+
partType: z.ZodString;
|
|
94
|
+
toolName: z.ZodNullable<z.ZodString>;
|
|
95
|
+
state: z.ZodNullable<z.ZodString>;
|
|
96
|
+
outputTruthy: z.ZodBoolean;
|
|
97
|
+
}, z.core.$strict>>;
|
|
98
|
+
}, z.core.$strict>>;
|
|
99
|
+
}, z.core.$strict>>;
|
|
100
|
+
context: z.ZodObject<{
|
|
101
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
102
|
+
id: z.ZodString;
|
|
103
|
+
role: z.ZodEnum<{
|
|
104
|
+
user: "user";
|
|
105
|
+
assistant: "assistant";
|
|
106
|
+
}>;
|
|
107
|
+
parts: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
108
|
+
type: z.ZodLiteral<"text">;
|
|
109
|
+
text: z.ZodString;
|
|
110
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
111
|
+
type: z.ZodString;
|
|
112
|
+
toolName: z.ZodOptional<z.ZodString>;
|
|
113
|
+
name: z.ZodOptional<z.ZodString>;
|
|
114
|
+
toolCallId: z.ZodOptional<z.ZodString>;
|
|
115
|
+
state: z.ZodOptional<z.ZodString>;
|
|
116
|
+
input: z.ZodOptional<z.ZodJSONSchema>;
|
|
117
|
+
output: z.ZodOptional<z.ZodJSONSchema>;
|
|
118
|
+
}, z.core.$strict>]>>;
|
|
119
|
+
metadata: z.ZodOptional<z.ZodObject<{
|
|
120
|
+
citations: z.ZodArray<z.ZodJSONSchema>;
|
|
121
|
+
}, z.core.$strict>>;
|
|
122
|
+
}, z.core.$strict>>;
|
|
123
|
+
compactionSummary: z.ZodNullable<z.ZodString>;
|
|
124
|
+
}, z.core.$strict>;
|
|
125
|
+
}, z.core.$strict>;
|
|
126
|
+
export declare const artifactCompletedAgentSourceCaptureSchema: z.ZodObject<{
|
|
127
|
+
responseHash: z.ZodString;
|
|
128
|
+
sourceReceipt: z.ZodString;
|
|
129
|
+
response: z.ZodObject<{
|
|
130
|
+
runId: z.ZodString;
|
|
131
|
+
agent: z.ZodString;
|
|
132
|
+
threadId: z.ZodString;
|
|
133
|
+
status: z.ZodLiteral<"completed">;
|
|
134
|
+
output: z.ZodJSONSchema;
|
|
135
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
136
|
+
id: z.ZodString;
|
|
137
|
+
role: z.ZodLiteral<"assistant">;
|
|
138
|
+
parts: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
139
|
+
type: z.ZodLiteral<"text">;
|
|
140
|
+
text: z.ZodString;
|
|
141
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
142
|
+
type: z.ZodLiteral<"dynamic-tool">;
|
|
143
|
+
output: z.ZodObject<{
|
|
144
|
+
content: z.ZodArray<z.ZodObject<{
|
|
145
|
+
type: z.ZodLiteral<"resource">;
|
|
146
|
+
resource: z.ZodObject<{
|
|
147
|
+
uri: z.ZodString;
|
|
148
|
+
text: z.ZodString;
|
|
149
|
+
}, z.core.$strict>;
|
|
150
|
+
}, z.core.$strict>>;
|
|
151
|
+
}, z.core.$strict>;
|
|
152
|
+
}, z.core.$strict>]>>;
|
|
153
|
+
metadata: z.ZodOptional<z.ZodObject<{
|
|
154
|
+
citations: z.ZodArray<z.ZodJSONSchema>;
|
|
155
|
+
}, z.core.$strict>>;
|
|
156
|
+
}, z.core.$strict>>;
|
|
157
|
+
conversation: z.ZodOptional<z.ZodObject<{
|
|
158
|
+
messageCount: z.ZodNumber;
|
|
159
|
+
userMessageCount: z.ZodNumber;
|
|
160
|
+
assistantMessageCount: z.ZodNumber;
|
|
161
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
162
|
+
id: z.ZodString;
|
|
163
|
+
role: z.ZodEnum<{
|
|
164
|
+
user: "user";
|
|
165
|
+
assistant: "assistant";
|
|
166
|
+
}>;
|
|
167
|
+
textParts: z.ZodArray<z.ZodString>;
|
|
168
|
+
tools: z.ZodArray<z.ZodObject<{
|
|
169
|
+
partType: z.ZodString;
|
|
170
|
+
toolName: z.ZodNullable<z.ZodString>;
|
|
171
|
+
state: z.ZodNullable<z.ZodString>;
|
|
172
|
+
outputTruthy: z.ZodBoolean;
|
|
173
|
+
}, z.core.$strict>>;
|
|
174
|
+
}, z.core.$strict>>;
|
|
175
|
+
}, z.core.$strict>>;
|
|
176
|
+
}, z.core.$strict>;
|
|
177
|
+
}, z.core.$strict>;
|
|
178
|
+
export declare const artifactCompletedAgentConversationCaptureSchema: z.ZodObject<{
|
|
179
|
+
responseHash: z.ZodString;
|
|
180
|
+
sourceReceipt: z.ZodString;
|
|
181
|
+
response: z.ZodObject<{
|
|
182
|
+
runId: z.ZodString;
|
|
183
|
+
agent: z.ZodString;
|
|
184
|
+
threadId: z.ZodString;
|
|
185
|
+
status: z.ZodLiteral<"completed">;
|
|
186
|
+
output: z.ZodJSONSchema;
|
|
187
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
188
|
+
id: z.ZodString;
|
|
189
|
+
role: z.ZodLiteral<"assistant">;
|
|
190
|
+
parts: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
191
|
+
type: z.ZodLiteral<"text">;
|
|
192
|
+
text: z.ZodString;
|
|
193
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
194
|
+
type: z.ZodLiteral<"dynamic-tool">;
|
|
195
|
+
output: z.ZodObject<{
|
|
196
|
+
content: z.ZodArray<z.ZodObject<{
|
|
197
|
+
type: z.ZodLiteral<"resource">;
|
|
198
|
+
resource: z.ZodObject<{
|
|
199
|
+
uri: z.ZodString;
|
|
200
|
+
text: z.ZodString;
|
|
201
|
+
}, z.core.$strict>;
|
|
202
|
+
}, z.core.$strict>>;
|
|
203
|
+
}, z.core.$strict>;
|
|
204
|
+
}, z.core.$strict>]>>;
|
|
205
|
+
metadata: z.ZodOptional<z.ZodObject<{
|
|
206
|
+
citations: z.ZodArray<z.ZodJSONSchema>;
|
|
207
|
+
}, z.core.$strict>>;
|
|
208
|
+
}, z.core.$strict>>;
|
|
209
|
+
conversation: z.ZodOptional<z.ZodObject<{
|
|
210
|
+
messageCount: z.ZodNumber;
|
|
211
|
+
userMessageCount: z.ZodNumber;
|
|
212
|
+
assistantMessageCount: z.ZodNumber;
|
|
213
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
214
|
+
id: z.ZodString;
|
|
215
|
+
role: z.ZodEnum<{
|
|
216
|
+
user: "user";
|
|
217
|
+
assistant: "assistant";
|
|
218
|
+
}>;
|
|
219
|
+
textParts: z.ZodArray<z.ZodString>;
|
|
220
|
+
tools: z.ZodArray<z.ZodObject<{
|
|
221
|
+
partType: z.ZodString;
|
|
222
|
+
toolName: z.ZodNullable<z.ZodString>;
|
|
223
|
+
state: z.ZodNullable<z.ZodString>;
|
|
224
|
+
outputTruthy: z.ZodBoolean;
|
|
225
|
+
}, z.core.$strict>>;
|
|
226
|
+
}, z.core.$strict>>;
|
|
227
|
+
}, z.core.$strict>>;
|
|
228
|
+
context: z.ZodObject<{
|
|
229
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
230
|
+
id: z.ZodString;
|
|
231
|
+
role: z.ZodEnum<{
|
|
232
|
+
user: "user";
|
|
233
|
+
assistant: "assistant";
|
|
234
|
+
}>;
|
|
235
|
+
parts: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
236
|
+
type: z.ZodLiteral<"text">;
|
|
237
|
+
text: z.ZodString;
|
|
238
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
239
|
+
type: z.ZodString;
|
|
240
|
+
toolName: z.ZodOptional<z.ZodString>;
|
|
241
|
+
name: z.ZodOptional<z.ZodString>;
|
|
242
|
+
toolCallId: z.ZodOptional<z.ZodString>;
|
|
243
|
+
state: z.ZodOptional<z.ZodString>;
|
|
244
|
+
input: z.ZodOptional<z.ZodJSONSchema>;
|
|
245
|
+
output: z.ZodOptional<z.ZodJSONSchema>;
|
|
246
|
+
}, z.core.$strict>]>>;
|
|
247
|
+
metadata: z.ZodOptional<z.ZodObject<{
|
|
248
|
+
citations: z.ZodArray<z.ZodJSONSchema>;
|
|
249
|
+
}, z.core.$strict>>;
|
|
250
|
+
}, z.core.$strict>>;
|
|
251
|
+
compactionSummary: z.ZodNullable<z.ZodString>;
|
|
252
|
+
}, z.core.$strict>;
|
|
253
|
+
}, z.core.$strict>;
|
|
254
|
+
}, z.core.$strict>;
|
|
255
|
+
export declare const artifactAgentConversationSourceCaptureSchema: z.ZodObject<{
|
|
256
|
+
responseHash: z.ZodString;
|
|
257
|
+
sourceReceipt: z.ZodString;
|
|
258
|
+
response: z.ZodObject<{
|
|
259
|
+
agent: z.ZodString;
|
|
260
|
+
threadId: z.ZodString;
|
|
261
|
+
revision: z.ZodNumber;
|
|
262
|
+
cutoffAt: z.ZodISODateTime;
|
|
263
|
+
context: z.ZodObject<{
|
|
264
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
265
|
+
id: z.ZodString;
|
|
266
|
+
role: z.ZodEnum<{
|
|
267
|
+
user: "user";
|
|
268
|
+
assistant: "assistant";
|
|
269
|
+
}>;
|
|
270
|
+
parts: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
271
|
+
type: z.ZodLiteral<"text">;
|
|
272
|
+
text: z.ZodString;
|
|
273
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
274
|
+
type: z.ZodString;
|
|
275
|
+
toolName: z.ZodOptional<z.ZodString>;
|
|
276
|
+
name: z.ZodOptional<z.ZodString>;
|
|
277
|
+
toolCallId: z.ZodOptional<z.ZodString>;
|
|
278
|
+
state: z.ZodOptional<z.ZodString>;
|
|
279
|
+
input: z.ZodOptional<z.ZodJSONSchema>;
|
|
280
|
+
output: z.ZodOptional<z.ZodJSONSchema>;
|
|
281
|
+
}, z.core.$strict>]>>;
|
|
282
|
+
metadata: z.ZodOptional<z.ZodObject<{
|
|
283
|
+
citations: z.ZodArray<z.ZodJSONSchema>;
|
|
284
|
+
}, z.core.$strict>>;
|
|
285
|
+
}, z.core.$strict>>;
|
|
286
|
+
compactionSummary: z.ZodNull;
|
|
287
|
+
}, z.core.$strict>;
|
|
288
|
+
conversation: z.ZodObject<{
|
|
289
|
+
messageCount: z.ZodNumber;
|
|
290
|
+
userMessageCount: z.ZodNumber;
|
|
291
|
+
assistantMessageCount: z.ZodNumber;
|
|
292
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
293
|
+
id: z.ZodString;
|
|
294
|
+
role: z.ZodEnum<{
|
|
295
|
+
user: "user";
|
|
296
|
+
assistant: "assistant";
|
|
297
|
+
}>;
|
|
298
|
+
textParts: z.ZodArray<z.ZodString>;
|
|
299
|
+
tools: z.ZodArray<z.ZodObject<{
|
|
300
|
+
partType: z.ZodString;
|
|
301
|
+
toolName: z.ZodNullable<z.ZodString>;
|
|
302
|
+
state: z.ZodNullable<z.ZodString>;
|
|
303
|
+
outputTruthy: z.ZodBoolean;
|
|
304
|
+
}, z.core.$strict>>;
|
|
305
|
+
}, z.core.$strict>>;
|
|
306
|
+
}, z.core.$strict>;
|
|
307
|
+
}, z.core.$strict>;
|
|
308
|
+
}, z.core.$strict>;
|
|
309
|
+
export type ArtifactCompletedAgentSourceCapture = z.infer<typeof artifactCompletedAgentSourceCaptureSchema>;
|
|
310
|
+
export type ArtifactCompletedAgentConversationCapture = z.infer<typeof artifactCompletedAgentConversationCaptureSchema>;
|
|
311
|
+
export type ArtifactAgentConversationSourceCapture = z.infer<typeof artifactAgentConversationSourceCaptureSchema>;
|
|
312
|
+
export declare const artifactCompletedWorkflowSourceCaptureSchema: z.ZodObject<{
|
|
313
|
+
responseHash: z.ZodString;
|
|
314
|
+
sourceReceipt: z.ZodString;
|
|
315
|
+
response: z.ZodObject<{
|
|
316
|
+
workflow: z.ZodString;
|
|
317
|
+
runId: z.ZodString;
|
|
318
|
+
status: z.ZodLiteral<"completed">;
|
|
319
|
+
output: z.ZodJSONSchema;
|
|
320
|
+
}, z.core.$strict>;
|
|
321
|
+
}, z.core.$strict>;
|
|
322
|
+
export type ArtifactCompletedWorkflowSourceCapture = z.infer<typeof artifactCompletedWorkflowSourceCaptureSchema>;
|
|
323
|
+
export interface ArtifactServerAgents {
|
|
324
|
+
createJob(input: ArtifactCreateAgentJob): Promise<ArtifactCreatedAgentJob>;
|
|
325
|
+
createWorkflowJob(input: ArtifactCreateWorkflowJob): Promise<ArtifactCreatedWorkflowJob>;
|
|
326
|
+
getCurrentIdentity(query: {
|
|
327
|
+
kind: 'agent' | 'workflow';
|
|
328
|
+
id: string;
|
|
329
|
+
}): Promise<ArtifactExecutionIdentity>;
|
|
330
|
+
getCompletedRun(query: {
|
|
331
|
+
agent: string;
|
|
332
|
+
runId: string;
|
|
333
|
+
}): Promise<ArtifactCompletedAgentRun>;
|
|
334
|
+
captureCompletedRun(query: {
|
|
335
|
+
agent: string;
|
|
336
|
+
runId: string;
|
|
337
|
+
}): Promise<ArtifactCompletedAgentSourceCapture>;
|
|
338
|
+
captureCompletedConversation(query: {
|
|
339
|
+
agent: string;
|
|
340
|
+
runId: string;
|
|
341
|
+
}): Promise<ArtifactCompletedAgentConversationCapture>;
|
|
342
|
+
captureConversation(query: {
|
|
343
|
+
agent: string;
|
|
344
|
+
threadId: string;
|
|
345
|
+
}): Promise<ArtifactAgentConversationSourceCapture>;
|
|
346
|
+
captureCompletedWorkflow(query: {
|
|
347
|
+
workflow: string;
|
|
348
|
+
runId: string;
|
|
349
|
+
}): Promise<ArtifactCompletedWorkflowSourceCapture>;
|
|
350
|
+
}
|
|
351
|
+
export declare const artifactExecutionIdentitySchema: z.ZodObject<{
|
|
352
|
+
id: z.ZodString;
|
|
353
|
+
version: z.ZodString;
|
|
354
|
+
definitionSha256: z.ZodString;
|
|
355
|
+
}, z.core.$strict>;
|
|
356
|
+
export type ArtifactExecutionIdentity = z.infer<typeof artifactExecutionIdentitySchema>;
|
|
357
|
+
declare const createAgentJobSchema: z.ZodObject<{
|
|
358
|
+
agentId: z.ZodString;
|
|
359
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
360
|
+
id: z.ZodOptional<z.ZodString>;
|
|
361
|
+
role: z.ZodEnum<{
|
|
362
|
+
user: "user";
|
|
363
|
+
system: "system";
|
|
364
|
+
assistant: "assistant";
|
|
365
|
+
}>;
|
|
366
|
+
content: z.ZodOptional<z.ZodString>;
|
|
367
|
+
parts: z.ZodOptional<z.ZodArray<z.ZodJSONSchema>>;
|
|
368
|
+
fileIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
369
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
|
|
370
|
+
}, z.core.$strict>>;
|
|
371
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
|
|
372
|
+
expectedIdentity: z.ZodObject<{
|
|
373
|
+
id: z.ZodString;
|
|
374
|
+
version: z.ZodString;
|
|
375
|
+
definitionSha256: z.ZodString;
|
|
376
|
+
}, z.core.$strict>;
|
|
377
|
+
idempotencyKey: z.ZodString;
|
|
378
|
+
}, z.core.$strict>;
|
|
379
|
+
declare const createWorkflowJobSchema: z.ZodObject<{
|
|
380
|
+
workflowId: z.ZodString;
|
|
381
|
+
input: z.ZodJSONSchema;
|
|
382
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
|
|
383
|
+
expectedIdentity: z.ZodObject<{
|
|
384
|
+
id: z.ZodString;
|
|
385
|
+
version: z.ZodString;
|
|
386
|
+
definitionSha256: z.ZodString;
|
|
387
|
+
}, z.core.$strict>;
|
|
388
|
+
idempotencyKey: z.ZodString;
|
|
389
|
+
}, z.core.$strict>;
|
|
390
|
+
declare const createdAgentJobSchema: z.ZodObject<{
|
|
391
|
+
type: z.ZodLiteral<"agent">;
|
|
392
|
+
threadId: z.ZodString;
|
|
393
|
+
jobId: z.ZodString;
|
|
394
|
+
triggerId: z.ZodString;
|
|
395
|
+
status: z.ZodEnum<{
|
|
396
|
+
queued: "queued";
|
|
397
|
+
running: "running";
|
|
398
|
+
failed: "failed";
|
|
399
|
+
cancelled: "cancelled";
|
|
400
|
+
completed: "completed";
|
|
401
|
+
}>;
|
|
402
|
+
}, z.core.$strict>;
|
|
403
|
+
declare const createdWorkflowJobSchema: z.ZodObject<{
|
|
404
|
+
type: z.ZodLiteral<"workflow">;
|
|
405
|
+
workflowId: z.ZodString;
|
|
406
|
+
jobId: z.ZodString;
|
|
407
|
+
triggerId: z.ZodString;
|
|
408
|
+
status: z.ZodEnum<{
|
|
409
|
+
queued: "queued";
|
|
410
|
+
running: "running";
|
|
411
|
+
failed: "failed";
|
|
412
|
+
cancelled: "cancelled";
|
|
413
|
+
completed: "completed";
|
|
414
|
+
}>;
|
|
415
|
+
}, z.core.$strict>;
|
|
416
|
+
export type ArtifactCreateAgentJob = z.infer<typeof createAgentJobSchema>;
|
|
417
|
+
export type ArtifactCreateWorkflowJob = z.infer<typeof createWorkflowJobSchema>;
|
|
418
|
+
export type ArtifactCreatedAgentJob = z.infer<typeof createdAgentJobSchema>;
|
|
419
|
+
export type ArtifactCreatedWorkflowJob = z.infer<typeof createdWorkflowJobSchema>;
|
|
420
|
+
/** User mode only; the manifest declares each exact route and Atlas enforces its current source access floor. */
|
|
421
|
+
export declare function createArtifactAgentsClient({ mode, json }: {
|
|
422
|
+
mode: ArtifactServerMode;
|
|
423
|
+
json: (operation: ArtifactServerRequest) => Promise<unknown>;
|
|
424
|
+
}): ArtifactServerAgents;
|
|
425
|
+
export {};
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ArtifactServerError } from './errors.js';
|
|
3
|
+
const resourceId = z.string().min(1).max(255).regex(/^[A-Za-z0-9._-]+$/);
|
|
4
|
+
/** Mirrors the platform's completed response contract; cross-package fixtures protect this boundary. */
|
|
5
|
+
export const artifactCompletedAgentResponseSchema = z.strictObject({
|
|
6
|
+
runId: resourceId, agent: resourceId, threadId: resourceId, status: z.literal('completed'), output: z.json(),
|
|
7
|
+
messages: z.array(z.strictObject({
|
|
8
|
+
id: z.string().min(1).max(255), role: z.literal('assistant'),
|
|
9
|
+
parts: z.array(z.union([
|
|
10
|
+
z.strictObject({ type: z.literal('text'), text: z.string() }),
|
|
11
|
+
z.strictObject({ type: z.literal('dynamic-tool'), output: z.strictObject({ content: z.array(z.strictObject({ type: z.literal('resource'), resource: z.strictObject({ uri: z.string().startsWith('citation://'), text: z.string() }) })).max(1000) }) }),
|
|
12
|
+
])).max(1000),
|
|
13
|
+
metadata: z.strictObject({ citations: z.array(z.json()).max(1000) }).optional(),
|
|
14
|
+
})).max(1000),
|
|
15
|
+
conversation: z.strictObject({
|
|
16
|
+
messageCount: z.number().int().min(0).max(1000), userMessageCount: z.number().int().min(0).max(1000), assistantMessageCount: z.number().int().min(0).max(1000),
|
|
17
|
+
messages: z.array(z.strictObject({ id: z.string().min(1).max(255), role: z.enum(['user', 'assistant']), textParts: z.array(z.string()).max(1000), tools: z.array(z.strictObject({ partType: z.string().min(1).max(255), toolName: z.string().max(255).nullable(), state: z.string().max(255).nullable(), outputTruthy: z.boolean() })).max(1000) })).max(1000),
|
|
18
|
+
}).optional(),
|
|
19
|
+
});
|
|
20
|
+
const conversationToolPart = z.strictObject({
|
|
21
|
+
type: z.string().min(1).max(255).refine((type) => type !== 'tool-result' && (type === 'dynamic-tool' || type === 'tool-invocation' || type.startsWith('tool-')), 'Only tool parts are permitted'),
|
|
22
|
+
toolName: z.string().max(255).optional(), name: z.string().max(255).optional(), toolCallId: z.string().min(1).max(255).optional(), state: z.string().max(255).optional(),
|
|
23
|
+
input: z.json().optional(), output: z.json().optional(),
|
|
24
|
+
});
|
|
25
|
+
export const artifactCompletedAgentConversationSchema = artifactCompletedAgentResponseSchema.extend({
|
|
26
|
+
context: z.strictObject({
|
|
27
|
+
messages: z.array(z.strictObject({
|
|
28
|
+
id: z.string().min(1).max(255), role: z.enum(['user', 'assistant']),
|
|
29
|
+
parts: z.array(z.union([z.strictObject({ type: z.literal('text'), text: z.string() }), conversationToolPart])).max(1000),
|
|
30
|
+
metadata: z.strictObject({ citations: z.array(z.json()).max(1000) }).optional(),
|
|
31
|
+
})).max(1000),
|
|
32
|
+
compactionSummary: z.string().nullable(),
|
|
33
|
+
}),
|
|
34
|
+
});
|
|
35
|
+
const sourceFields = { responseHash: z.string().regex(/^[a-f0-9]{64}$/), sourceReceipt: z.string().min(1).max(16_384) };
|
|
36
|
+
export const artifactCompletedAgentSourceCaptureSchema = z.strictObject({ response: artifactCompletedAgentResponseSchema, ...sourceFields });
|
|
37
|
+
export const artifactCompletedAgentConversationCaptureSchema = z.strictObject({ response: artifactCompletedAgentConversationSchema, ...sourceFields });
|
|
38
|
+
export const artifactAgentConversationSourceCaptureSchema = z.strictObject({
|
|
39
|
+
response: z.strictObject({
|
|
40
|
+
agent: resourceId, threadId: resourceId, revision: z.number().int().min(1).max(Number.MAX_SAFE_INTEGER), cutoffAt: z.iso.datetime({ offset: true }),
|
|
41
|
+
context: artifactCompletedAgentConversationSchema.shape.context.extend({ compactionSummary: z.null() }),
|
|
42
|
+
conversation: artifactCompletedAgentResponseSchema.shape.conversation.unwrap(),
|
|
43
|
+
}),
|
|
44
|
+
...sourceFields,
|
|
45
|
+
});
|
|
46
|
+
export const artifactCompletedWorkflowSourceCaptureSchema = z.strictObject({ response: z.strictObject({ workflow: resourceId, runId: resourceId, status: z.literal('completed'), output: z.json() }), ...sourceFields });
|
|
47
|
+
export const artifactExecutionIdentitySchema = z.strictObject({
|
|
48
|
+
id: z.string().min(1).max(128).regex(/^[A-Za-z0-9_-]+$/), version: z.string().min(1).max(128),
|
|
49
|
+
definitionSha256: z.string().regex(/^[a-f0-9]{64}$/),
|
|
50
|
+
});
|
|
51
|
+
const idempotencyKeySchema = z.string().min(1).max(128).regex(/^[\x21-\x7e]+$/);
|
|
52
|
+
const jobMessageSchema = z.strictObject({
|
|
53
|
+
id: z.string().optional(), role: z.enum(['user', 'assistant', 'system']),
|
|
54
|
+
content: z.string().optional(), parts: z.array(z.json()).optional(),
|
|
55
|
+
fileIds: z.array(resourceId).optional(), metadata: z.record(z.string(), z.json()).optional(),
|
|
56
|
+
}).refine((message) => Boolean(message.content?.length || message.parts?.length), 'A job message requires content or parts');
|
|
57
|
+
const createAgentJobSchema = z.strictObject({
|
|
58
|
+
agentId: resourceId, messages: z.array(jobMessageSchema).min(1), metadata: z.record(z.string(), z.json()).optional(),
|
|
59
|
+
expectedIdentity: artifactExecutionIdentitySchema, idempotencyKey: idempotencyKeySchema,
|
|
60
|
+
});
|
|
61
|
+
const createWorkflowJobSchema = z.strictObject({
|
|
62
|
+
workflowId: resourceId, input: z.json(), metadata: z.record(z.string(), z.json()).optional(),
|
|
63
|
+
expectedIdentity: artifactExecutionIdentitySchema, idempotencyKey: idempotencyKeySchema,
|
|
64
|
+
});
|
|
65
|
+
const createdJobFields = { jobId: resourceId, triggerId: resourceId,
|
|
66
|
+
status: z.enum(['queued', 'running', 'completed', 'failed', 'cancelled']) };
|
|
67
|
+
const createdAgentJobSchema = z.strictObject({ ...createdJobFields, type: z.literal('agent'), threadId: resourceId });
|
|
68
|
+
const createdWorkflowJobSchema = z.strictObject({ ...createdJobFields, type: z.literal('workflow'), workflowId: resourceId });
|
|
69
|
+
/** User mode only; the manifest declares each exact route and Atlas enforces its current source access floor. */
|
|
70
|
+
export function createArtifactAgentsClient({ mode, json }) {
|
|
71
|
+
async function read(query, endpoint) {
|
|
72
|
+
if (mode !== 'user')
|
|
73
|
+
throw new ArtifactServerError(403, 'operation_not_allowed', 'Completed agent sources require user mode');
|
|
74
|
+
const { agent, runId } = z.strictObject({ agent: resourceId, runId: resourceId }).parse(query);
|
|
75
|
+
const path = `/api/agents/jobs/${encodeURIComponent(runId)}/${endpoint}?${new URLSearchParams({ agent })}`;
|
|
76
|
+
return json({ operation: 'api', mode, method: 'GET', path });
|
|
77
|
+
}
|
|
78
|
+
function matches(response, query) {
|
|
79
|
+
return response.runId === query.runId && response.agent === query.agent;
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
async createJob(input) {
|
|
83
|
+
if (mode !== 'user')
|
|
84
|
+
throw new ArtifactServerError(403, 'operation_not_allowed', 'Job admission requires user mode');
|
|
85
|
+
const body = createAgentJobSchema.parse(input);
|
|
86
|
+
if (body.expectedIdentity.id !== body.agentId)
|
|
87
|
+
throw new ArtifactServerError(400, 'invalid_request', 'The agent source identity does not match its job');
|
|
88
|
+
const parsed = createdAgentJobSchema.safeParse(await json({ operation: 'api', mode, method: 'POST', path: '/api/agents/jobs/create-idempotent', body }));
|
|
89
|
+
if (!parsed.success)
|
|
90
|
+
throw new ArtifactServerError(502, 'invalid_response', 'Atlas returned an invalid agent job admission');
|
|
91
|
+
return parsed.data;
|
|
92
|
+
},
|
|
93
|
+
async createWorkflowJob(input) {
|
|
94
|
+
if (mode !== 'user')
|
|
95
|
+
throw new ArtifactServerError(403, 'operation_not_allowed', 'Job admission requires user mode');
|
|
96
|
+
const { workflowId, ...body } = createWorkflowJobSchema.parse(input);
|
|
97
|
+
if (body.expectedIdentity.id !== workflowId)
|
|
98
|
+
throw new ArtifactServerError(400, 'invalid_request', 'The workflow source identity does not match its job');
|
|
99
|
+
const parsed = createdWorkflowJobSchema.safeParse(await json({ operation: 'api', mode, method: 'POST',
|
|
100
|
+
path: `/api/agents/workflows/${encodeURIComponent(workflowId)}/jobs`, body }));
|
|
101
|
+
if (!parsed.success || parsed.data.workflowId !== workflowId)
|
|
102
|
+
throw new ArtifactServerError(502, 'invalid_response', 'Atlas returned an invalid workflow job admission');
|
|
103
|
+
return parsed.data;
|
|
104
|
+
},
|
|
105
|
+
async getCurrentIdentity(query) {
|
|
106
|
+
if (mode !== 'user')
|
|
107
|
+
throw new ArtifactServerError(403, 'operation_not_allowed', 'Execution source identity requires user mode');
|
|
108
|
+
const { kind, id } = z.strictObject({ kind: z.enum(['agent', 'workflow']), id: resourceId }).parse(query);
|
|
109
|
+
const path = `/api/agents/${kind === 'agent' ? 'agents' : 'workflows'}/${encodeURIComponent(id)}/current-identity`;
|
|
110
|
+
const parsed = artifactExecutionIdentitySchema.safeParse(await json({ operation: 'api', mode, method: 'GET', path }));
|
|
111
|
+
if (!parsed.success || parsed.data.id !== id)
|
|
112
|
+
throw new ArtifactServerError(502, 'invalid_response', 'Atlas returned an invalid execution source identity');
|
|
113
|
+
return parsed.data;
|
|
114
|
+
},
|
|
115
|
+
async getCompletedRun(query) {
|
|
116
|
+
const parsed = artifactCompletedAgentResponseSchema.safeParse(await read(query, 'completed-response'));
|
|
117
|
+
if (!parsed.success || !matches(parsed.data, query))
|
|
118
|
+
throw new ArtifactServerError(502, 'invalid_response', 'Atlas returned an invalid completed agent response');
|
|
119
|
+
return parsed.data;
|
|
120
|
+
},
|
|
121
|
+
async captureCompletedRun(query) {
|
|
122
|
+
const parsed = artifactCompletedAgentSourceCaptureSchema.safeParse(await read(query, 'completed-source'));
|
|
123
|
+
if (!parsed.success || !matches(parsed.data.response, query))
|
|
124
|
+
throw new ArtifactServerError(502, 'invalid_response', 'Atlas returned an invalid completed source capture');
|
|
125
|
+
return parsed.data;
|
|
126
|
+
},
|
|
127
|
+
async captureCompletedConversation(query) {
|
|
128
|
+
const parsed = artifactCompletedAgentConversationCaptureSchema.safeParse(await read(query, 'completed-conversation'));
|
|
129
|
+
if (!parsed.success || !matches(parsed.data.response, query))
|
|
130
|
+
throw new ArtifactServerError(502, 'invalid_response', 'Atlas returned an invalid completed conversation capture');
|
|
131
|
+
return parsed.data;
|
|
132
|
+
},
|
|
133
|
+
async captureCompletedWorkflow(query) {
|
|
134
|
+
if (mode !== 'user')
|
|
135
|
+
throw new ArtifactServerError(403, 'operation_not_allowed', 'Workflow sources require user mode');
|
|
136
|
+
const { workflow, runId } = z.strictObject({ workflow: resourceId, runId: resourceId }).parse(query);
|
|
137
|
+
const path = `/api/agents/jobs/${encodeURIComponent(runId)}/completed-workflow-source?${new URLSearchParams({ workflow })}`;
|
|
138
|
+
const parsed = artifactCompletedWorkflowSourceCaptureSchema.safeParse(await json({ operation: 'api', mode, method: 'GET', path }));
|
|
139
|
+
if (!parsed.success || parsed.data.response.workflow !== workflow || parsed.data.response.runId !== runId)
|
|
140
|
+
throw new ArtifactServerError(502, 'invalid_response', 'Atlas returned an invalid completed workflow source');
|
|
141
|
+
return parsed.data;
|
|
142
|
+
},
|
|
143
|
+
async captureConversation(query) {
|
|
144
|
+
if (mode !== 'user')
|
|
145
|
+
throw new ArtifactServerError(403, 'operation_not_allowed', 'Conversation sources require user mode');
|
|
146
|
+
const { agent, threadId } = z.strictObject({ agent: resourceId, threadId: resourceId }).parse(query);
|
|
147
|
+
const path = `/api/agents/threads/${encodeURIComponent(threadId)}/conversation-source?${new URLSearchParams({ agent })}`;
|
|
148
|
+
const parsed = artifactAgentConversationSourceCaptureSchema.safeParse(await json({ operation: 'api', mode, method: 'GET', path }));
|
|
149
|
+
if (!parsed.success || parsed.data.response.agent !== agent || parsed.data.response.threadId !== threadId)
|
|
150
|
+
throw new ArtifactServerError(502, 'invalid_response', 'Atlas returned an invalid conversation source capture');
|
|
151
|
+
return parsed.data;
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|