@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.
Files changed (44) hide show
  1. package/README.md +87 -3
  2. package/dist/build.js +4 -2
  3. package/dist/gateway/authorization-cache.js +1 -1
  4. package/dist/gateway/control.d.ts +13 -1
  5. package/dist/gateway/control.js +3 -0
  6. package/dist/gateway/datadog-startup.d.ts +13 -0
  7. package/dist/gateway/datadog-startup.js +51 -0
  8. package/dist/gateway/hosted-proxy.d.ts +2 -0
  9. package/dist/gateway/hosted-proxy.js +9 -11
  10. package/dist/gateway/ingress-handler.js +2 -0
  11. package/dist/gateway/server.d.ts +1 -1
  12. package/dist/gateway/server.js +51 -20
  13. package/dist/gateway/session.d.ts +14 -0
  14. package/dist/gateway/session.js +31 -2
  15. package/dist/gateway-main.js +5 -3
  16. package/dist/manifest-next.d.ts +9 -0
  17. package/dist/manifest-next.js +5 -0
  18. package/dist/manifest.d.ts +3 -0
  19. package/dist/server/agent-responses.d.ts +425 -0
  20. package/dist/server/agent-responses.js +154 -0
  21. package/dist/server/broker-contract.d.ts +17 -0
  22. package/dist/server/broker-contract.js +17 -2
  23. package/dist/server/client.d.ts +5 -0
  24. package/dist/server/client.js +12 -2
  25. package/dist/server/groups.d.ts +32 -0
  26. package/dist/server/groups.js +28 -0
  27. package/dist/server/processes.d.ts +11 -0
  28. package/dist/server/request-authentication.d.ts +42 -0
  29. package/dist/server/request-authentication.js +93 -0
  30. package/dist/server/request-context.d.ts +1 -0
  31. package/dist/server/request-context.js +1 -0
  32. package/dist/server.d.ts +4 -3
  33. package/dist/server.js +2 -2
  34. package/dist/source-boundary.js +13 -5
  35. package/dist/templates/react-vite/package.json +1 -1
  36. package/dist/tunnel/broker.d.ts +14 -1
  37. package/dist/tunnel/broker.js +94 -10
  38. package/dist/tunnel/client.js +6 -0
  39. package/dist/tunnel/redis-types.d.ts +5 -1
  40. package/dist/tunnel/redis.d.ts +12 -0
  41. package/dist/tunnel/redis.js +102 -4
  42. package/dist/tunnel/transport.d.ts +3 -0
  43. package/package.json +2 -2
  44. package/templates/react-vite/package.json +1 -1
@@ -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
- // Only an ingress-secrets refusal is described: its message names variables, never values, by
139
- // construction. Other errors (Redis, URLs) may carry connection strings.
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
  });
@@ -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";
@@ -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({
@@ -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
+ }