@meistrari/agent-core 0.0.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/README.md +26 -0
- package/package.json +69 -0
- package/scripts/write-provenance.ts +74 -0
- package/src/errors/app-error.ts +66 -0
- package/src/errors/application-error.ts +55 -0
- package/src/errors/index.ts +16 -0
- package/src/errors/infrastructure-error.ts +13 -0
- package/src/errors/provider-error.ts +13 -0
- package/src/errors/validation-error.ts +19 -0
- package/src/logger/index.ts +75 -0
- package/src/protocol/agent-command.ts +65 -0
- package/src/protocol/agent-content.ts +73 -0
- package/src/protocol/agent-error.ts +81 -0
- package/src/protocol/agent-event.ts +391 -0
- package/src/protocol/agent-json.ts +30 -0
- package/src/protocol/agent-metadata.ts +30 -0
- package/src/protocol/agent-model.ts +68 -0
- package/src/protocol/agent-overflow.ts +18 -0
- package/src/protocol/agent-presentation.ts +98 -0
- package/src/protocol/agent-provider.ts +4 -0
- package/src/protocol/agent-tool-name.ts +48 -0
- package/src/protocol/agent-tool.ts +40 -0
- package/src/protocol/agent-usage.ts +14 -0
- package/src/protocol/agent-user-input.ts +38 -0
- package/src/protocol/agent-work.ts +100 -0
- package/src/protocol/index.ts +13 -0
- package/src/provenance.gen.ts +6 -0
- package/src/provenance.ts +27 -0
- package/src/supervisor-protocol/agent-event-wrapper.ts +179 -0
- package/src/supervisor-protocol/bootstrap-rejection-receipt.ts +3 -0
- package/src/supervisor-protocol/bootstrap.ts +126 -0
- package/src/supervisor-protocol/command-body.ts +82 -0
- package/src/supervisor-protocol/context-file-content.ts +90 -0
- package/src/supervisor-protocol/control-authority.ts +88 -0
- package/src/supervisor-protocol/durability.ts +33 -0
- package/src/supervisor-protocol/envelope.ts +58 -0
- package/src/supervisor-protocol/envelopes/common.ts +7 -0
- package/src/supervisor-protocol/envelopes/control-plane-to-supervisor.ts +38 -0
- package/src/supervisor-protocol/envelopes/supervisor-to-control-plane.ts +89 -0
- package/src/supervisor-protocol/event-body.ts +13 -0
- package/src/supervisor-protocol/input-attachment-content.ts +3 -0
- package/src/supervisor-protocol/payload-overflow.ts +15 -0
- package/src/supervisor-protocol/product-event.ts +27 -0
- package/src/supervisor-protocol/profile.ts +22 -0
- package/src/supervisor-protocol/rpc.ts +77 -0
- package/src/supervisor-protocol/supervisor-agent-run-snapshot.ts +12 -0
- package/src/supervisor-protocol/supervisor-event.ts +361 -0
- package/src/supervisor-protocol/tela-page-content.ts +6 -0
- package/src/supervisor-protocol/wire-codec.ts +71 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import type { AgentError } from '../protocol'
|
|
2
|
+
import z from 'zod'
|
|
3
|
+
import { agentErrorSchema } from '../protocol'
|
|
4
|
+
import { timestampSchema } from './envelopes/common'
|
|
5
|
+
import { supervisorAgentRunSnapshotSchema } from './supervisor-agent-run-snapshot'
|
|
6
|
+
|
|
7
|
+
export const inputAttachmentDeliveryFailureReasonSchema = z.enum([
|
|
8
|
+
'authorization',
|
|
9
|
+
'not_found',
|
|
10
|
+
'network',
|
|
11
|
+
'timeout',
|
|
12
|
+
'invalid_response',
|
|
13
|
+
'size_mismatch',
|
|
14
|
+
'sha256_mismatch',
|
|
15
|
+
'filesystem',
|
|
16
|
+
])
|
|
17
|
+
|
|
18
|
+
export type InputAttachmentDeliveryFailureReason = z.infer<typeof inputAttachmentDeliveryFailureReasonSchema>
|
|
19
|
+
|
|
20
|
+
type SupervisorCommandFailure
|
|
21
|
+
= | {
|
|
22
|
+
type: 'command'
|
|
23
|
+
detail: string
|
|
24
|
+
error?: AgentError
|
|
25
|
+
}
|
|
26
|
+
| {
|
|
27
|
+
type: 'input_attachment'
|
|
28
|
+
attachmentId: string
|
|
29
|
+
reason: InputAttachmentDeliveryFailureReason
|
|
30
|
+
detail: string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type SupervisorCommandFailedEvent
|
|
34
|
+
= | {
|
|
35
|
+
type: 'supervisor.command.failed'
|
|
36
|
+
payload: {
|
|
37
|
+
commandId: string
|
|
38
|
+
commandSeq: number
|
|
39
|
+
bodyType: 'agent.send-prompt'
|
|
40
|
+
failure: Extract<SupervisorCommandFailure, { type: 'input_attachment' }>
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
| {
|
|
44
|
+
type: 'supervisor.command.failed'
|
|
45
|
+
payload: {
|
|
46
|
+
commandId: string
|
|
47
|
+
commandSeq: number
|
|
48
|
+
bodyType: string
|
|
49
|
+
failure: Extract<SupervisorCommandFailure, { type: 'command' }>
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const supervisorShutdownReasonSchema = z.enum([
|
|
54
|
+
'sigterm',
|
|
55
|
+
'sigint',
|
|
56
|
+
'fatal_error',
|
|
57
|
+
])
|
|
58
|
+
|
|
59
|
+
const supervisorGitTriggerSchema = z.enum(['turn-ended', 'boot-reconcile'])
|
|
60
|
+
|
|
61
|
+
const supervisorGitCommitFailureReasonSchema = z.literal('unknown')
|
|
62
|
+
|
|
63
|
+
const supervisorGitPushFailureReasonSchema = z.enum([
|
|
64
|
+
'non-fast-forward',
|
|
65
|
+
'auth',
|
|
66
|
+
'network',
|
|
67
|
+
'rejected',
|
|
68
|
+
'unknown',
|
|
69
|
+
])
|
|
70
|
+
|
|
71
|
+
const supervisorGitRecoveryPromptFailureReasonSchema = z.enum(['dispatch-failed'])
|
|
72
|
+
|
|
73
|
+
const supervisorGitEventCommonPayloadFields = {
|
|
74
|
+
turnId: z.string(),
|
|
75
|
+
repository: z.string(),
|
|
76
|
+
branch: z.string(),
|
|
77
|
+
trigger: supervisorGitTriggerSchema,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const sessionWorkspaceGitRepositorySchema = z.object({
|
|
81
|
+
id: z.string().min(1),
|
|
82
|
+
fullName: z.string().max(256).regex(/^[^/\s]+\/[^/\s]+$/),
|
|
83
|
+
}).strict()
|
|
84
|
+
|
|
85
|
+
const sessionWorkspaceGitRevisionPayloadFields = {
|
|
86
|
+
repository: sessionWorkspaceGitRepositorySchema,
|
|
87
|
+
branch: z.string().min(1),
|
|
88
|
+
sha: z.string().regex(/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/),
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const sessionWorkspaceGitPayloadSchema = z.object({
|
|
92
|
+
...sessionWorkspaceGitRevisionPayloadFields,
|
|
93
|
+
turnId: z.string().min(1),
|
|
94
|
+
trigger: supervisorGitTriggerSchema,
|
|
95
|
+
}).strict()
|
|
96
|
+
|
|
97
|
+
const supervisorInterruptionRecoveryCommonPayloadFields = {
|
|
98
|
+
sourceCommandId: z.string().min(1),
|
|
99
|
+
recoveryCommandId: z.string().min(1),
|
|
100
|
+
attempt: z.number().int().positive(),
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const supervisorInterruptionRecoveryAcceptanceSchema = z.discriminatedUnion('kind', [
|
|
104
|
+
z.object({
|
|
105
|
+
kind: z.literal('submitted'),
|
|
106
|
+
}).strict(),
|
|
107
|
+
z.object({
|
|
108
|
+
kind: z.literal('turn'),
|
|
109
|
+
resultingTurnId: z.string().min(1),
|
|
110
|
+
}).strict(),
|
|
111
|
+
])
|
|
112
|
+
|
|
113
|
+
const supervisorInterruptionRecoveryOperationSchema = z.enum([
|
|
114
|
+
'resume',
|
|
115
|
+
'dispatch',
|
|
116
|
+
])
|
|
117
|
+
|
|
118
|
+
const supervisorInterruptionRecoveryWaitSchema = z.discriminatedUnion('kind', [
|
|
119
|
+
z.object({
|
|
120
|
+
kind: z.literal('retry'),
|
|
121
|
+
reason: z.string().min(1),
|
|
122
|
+
nextAttemptAt: timestampSchema,
|
|
123
|
+
}).strict(),
|
|
124
|
+
z.object({
|
|
125
|
+
kind: z.literal('external_action'),
|
|
126
|
+
reason: z.string().min(1),
|
|
127
|
+
nextAttemptAt: timestampSchema,
|
|
128
|
+
}).strict(),
|
|
129
|
+
])
|
|
130
|
+
|
|
131
|
+
const supervisorInterruptionRecoveryFailureSchema = z.discriminatedUnion('kind', [
|
|
132
|
+
z.object({
|
|
133
|
+
kind: z.literal('provider_rejected'),
|
|
134
|
+
operation: supervisorInterruptionRecoveryOperationSchema,
|
|
135
|
+
reason: z.string().min(1),
|
|
136
|
+
}).strict(),
|
|
137
|
+
z.object({
|
|
138
|
+
kind: z.literal('turn'),
|
|
139
|
+
resultingTurnId: z.string().min(1),
|
|
140
|
+
status: z.enum(['failed', 'interrupted', 'cancelled']),
|
|
141
|
+
}).strict(),
|
|
142
|
+
])
|
|
143
|
+
|
|
144
|
+
const supervisorInterruptionRecoveryRequestedEventSchema = z.object({
|
|
145
|
+
type: z.literal('supervisor.interruption_recovery.requested'),
|
|
146
|
+
payload: z.object({
|
|
147
|
+
...supervisorInterruptionRecoveryCommonPayloadFields,
|
|
148
|
+
}).strict(),
|
|
149
|
+
}).strict()
|
|
150
|
+
|
|
151
|
+
const supervisorInterruptionRecoveryAcceptedEventSchema = z.object({
|
|
152
|
+
type: z.literal('supervisor.interruption_recovery.accepted'),
|
|
153
|
+
payload: z.object({
|
|
154
|
+
...supervisorInterruptionRecoveryCommonPayloadFields,
|
|
155
|
+
acceptance: supervisorInterruptionRecoveryAcceptanceSchema,
|
|
156
|
+
}).strict(),
|
|
157
|
+
}).strict()
|
|
158
|
+
|
|
159
|
+
const supervisorInterruptionRecoveryWaitingEventSchema = z.object({
|
|
160
|
+
type: z.literal('supervisor.interruption_recovery.waiting'),
|
|
161
|
+
payload: z.object({
|
|
162
|
+
...supervisorInterruptionRecoveryCommonPayloadFields,
|
|
163
|
+
operation: supervisorInterruptionRecoveryOperationSchema,
|
|
164
|
+
wait: supervisorInterruptionRecoveryWaitSchema,
|
|
165
|
+
}).strict(),
|
|
166
|
+
}).strict()
|
|
167
|
+
|
|
168
|
+
const supervisorInterruptionRecoveryTurnCorrelatedEventSchema = z.object({
|
|
169
|
+
type: z.literal('supervisor.interruption_recovery.turn_correlated'),
|
|
170
|
+
payload: z.object({
|
|
171
|
+
...supervisorInterruptionRecoveryCommonPayloadFields,
|
|
172
|
+
resultingTurnId: z.string().min(1),
|
|
173
|
+
}).strict(),
|
|
174
|
+
}).strict()
|
|
175
|
+
|
|
176
|
+
const supervisorInterruptionRecoveryFailedEventSchema = z.object({
|
|
177
|
+
type: z.literal('supervisor.interruption_recovery.failed'),
|
|
178
|
+
payload: z.object({
|
|
179
|
+
...supervisorInterruptionRecoveryCommonPayloadFields,
|
|
180
|
+
failure: supervisorInterruptionRecoveryFailureSchema,
|
|
181
|
+
}).strict(),
|
|
182
|
+
}).strict()
|
|
183
|
+
|
|
184
|
+
const supervisorStartedEventSchema = z.object({
|
|
185
|
+
type: z.literal('supervisor.started'),
|
|
186
|
+
payload: z.object({}).strict(),
|
|
187
|
+
}).strict()
|
|
188
|
+
|
|
189
|
+
const supervisorAgentRunChangedEventSchema = z.object({
|
|
190
|
+
type: z.literal('supervisor.agent_run.changed'),
|
|
191
|
+
payload: z.object({
|
|
192
|
+
agentRun: supervisorAgentRunSnapshotSchema,
|
|
193
|
+
}).strict(),
|
|
194
|
+
}).strict()
|
|
195
|
+
|
|
196
|
+
const supervisorHeartbeatEventSchema = z.object({
|
|
197
|
+
type: z.literal('supervisor.heartbeat'),
|
|
198
|
+
payload: z.object({
|
|
199
|
+
unackedEventCount: z.number().int().nonnegative(),
|
|
200
|
+
}).strict(),
|
|
201
|
+
}).strict()
|
|
202
|
+
|
|
203
|
+
const supervisorShuttingDownEventSchema = z.object({
|
|
204
|
+
type: z.literal('supervisor.shutting_down'),
|
|
205
|
+
payload: z.object({
|
|
206
|
+
reason: supervisorShutdownReasonSchema,
|
|
207
|
+
detail: z.string().min(1).optional(),
|
|
208
|
+
}).strict(),
|
|
209
|
+
}).strict()
|
|
210
|
+
|
|
211
|
+
const supervisorSessionResumedEventSchema = z.object({
|
|
212
|
+
type: z.literal('supervisor.session_resumed'),
|
|
213
|
+
payload: z.object({
|
|
214
|
+
gapDuration: z.number().nonnegative(),
|
|
215
|
+
}).strict(),
|
|
216
|
+
}).strict()
|
|
217
|
+
|
|
218
|
+
const commandOutcomePayloadSchema = z.object({
|
|
219
|
+
commandId: z.string().min(1),
|
|
220
|
+
commandSeq: z.number().int().positive(),
|
|
221
|
+
bodyType: z.string().min(1),
|
|
222
|
+
}).strict()
|
|
223
|
+
|
|
224
|
+
const supervisorCommandAppliedEventSchema = z.object({
|
|
225
|
+
type: z.literal('supervisor.command.applied'),
|
|
226
|
+
payload: commandOutcomePayloadSchema,
|
|
227
|
+
}).strict()
|
|
228
|
+
|
|
229
|
+
const supervisorCommandTurnCorrelatedEventSchema = z.object({
|
|
230
|
+
type: z.literal('supervisor.command.turn_correlated'),
|
|
231
|
+
payload: commandOutcomePayloadSchema.extend({
|
|
232
|
+
bodyType: z.literal('agent.send-prompt'),
|
|
233
|
+
turnId: z.string().min(1),
|
|
234
|
+
}).strict(),
|
|
235
|
+
}).strict()
|
|
236
|
+
|
|
237
|
+
const supervisorCommandFailureSchema = z.object({
|
|
238
|
+
type: z.literal('command'),
|
|
239
|
+
detail: z.string().min(1),
|
|
240
|
+
error: agentErrorSchema.optional(),
|
|
241
|
+
}).strict()
|
|
242
|
+
|
|
243
|
+
const supervisorInputAttachmentFailureSchema = z.object({
|
|
244
|
+
type: z.literal('input_attachment'),
|
|
245
|
+
attachmentId: z.string().min(1),
|
|
246
|
+
reason: inputAttachmentDeliveryFailureReasonSchema,
|
|
247
|
+
detail: z.string().min(1),
|
|
248
|
+
}).strict()
|
|
249
|
+
|
|
250
|
+
const supervisorInputAttachmentCommandFailedPayloadSchema = commandOutcomePayloadSchema.extend({
|
|
251
|
+
bodyType: z.literal('agent.send-prompt'),
|
|
252
|
+
failure: supervisorInputAttachmentFailureSchema,
|
|
253
|
+
}).strict() satisfies z.ZodType<SupervisorCommandFailedEvent['payload']>
|
|
254
|
+
|
|
255
|
+
const supervisorOrdinaryCommandFailedPayloadSchema = commandOutcomePayloadSchema.extend({
|
|
256
|
+
failure: supervisorCommandFailureSchema,
|
|
257
|
+
}).strict() satisfies z.ZodType<SupervisorCommandFailedEvent['payload']>
|
|
258
|
+
|
|
259
|
+
const supervisorCommandFailedEventSchema = z.object({
|
|
260
|
+
type: z.literal('supervisor.command.failed'),
|
|
261
|
+
payload: z.union([
|
|
262
|
+
supervisorInputAttachmentCommandFailedPayloadSchema,
|
|
263
|
+
supervisorOrdinaryCommandFailedPayloadSchema,
|
|
264
|
+
]),
|
|
265
|
+
}).strict()
|
|
266
|
+
|
|
267
|
+
// Deployed immutable supervisors retain these durable v1 event bodies for their sandbox lifetime.
|
|
268
|
+
const legacySupervisorGitCommitCompletedEventSchema = z.object({
|
|
269
|
+
type: z.literal('supervisor.git.commit.completed'),
|
|
270
|
+
payload: z.object({
|
|
271
|
+
...supervisorGitEventCommonPayloadFields,
|
|
272
|
+
commitSha: z.string(),
|
|
273
|
+
}).strict(),
|
|
274
|
+
}).strict()
|
|
275
|
+
|
|
276
|
+
const sessionWorkspaceGitInitializedEventSchema = z.object({
|
|
277
|
+
type: z.literal('session.workspace.git.initialized'),
|
|
278
|
+
payload: z.object(sessionWorkspaceGitRevisionPayloadFields).strict(),
|
|
279
|
+
}).strict()
|
|
280
|
+
|
|
281
|
+
const sessionWorkspaceReadyEventSchema = z.object({
|
|
282
|
+
type: z.literal('session.workspace.ready'),
|
|
283
|
+
payload: z.object({
|
|
284
|
+
repositories: z.array(z.object(sessionWorkspaceGitRevisionPayloadFields).strict()),
|
|
285
|
+
}).strict(),
|
|
286
|
+
}).strict()
|
|
287
|
+
|
|
288
|
+
const sessionWorkspaceGitCommittedEventSchema = z.object({
|
|
289
|
+
type: z.literal('session.workspace.git.committed'),
|
|
290
|
+
payload: sessionWorkspaceGitPayloadSchema,
|
|
291
|
+
}).strict()
|
|
292
|
+
|
|
293
|
+
const supervisorGitCommitFailedEventSchema = z.object({
|
|
294
|
+
type: z.literal('supervisor.git.commit.failed'),
|
|
295
|
+
payload: z.object({
|
|
296
|
+
...supervisorGitEventCommonPayloadFields,
|
|
297
|
+
reason: supervisorGitCommitFailureReasonSchema,
|
|
298
|
+
detail: z.string(),
|
|
299
|
+
}).strict(),
|
|
300
|
+
}).strict()
|
|
301
|
+
|
|
302
|
+
const legacySupervisorGitPushCompletedEventSchema = z.object({
|
|
303
|
+
type: z.literal('supervisor.git.push.completed'),
|
|
304
|
+
payload: z.object({
|
|
305
|
+
...supervisorGitEventCommonPayloadFields,
|
|
306
|
+
remoteHeadSha: z.string(),
|
|
307
|
+
}).strict(),
|
|
308
|
+
}).strict()
|
|
309
|
+
|
|
310
|
+
const sessionWorkspaceGitPushedEventSchema = z.object({
|
|
311
|
+
type: z.literal('session.workspace.git.pushed'),
|
|
312
|
+
payload: sessionWorkspaceGitPayloadSchema,
|
|
313
|
+
}).strict()
|
|
314
|
+
|
|
315
|
+
const supervisorGitPushFailedEventSchema = z.object({
|
|
316
|
+
type: z.literal('supervisor.git.push.failed'),
|
|
317
|
+
payload: z.object({
|
|
318
|
+
...supervisorGitEventCommonPayloadFields,
|
|
319
|
+
reason: supervisorGitPushFailureReasonSchema,
|
|
320
|
+
detail: z.string(),
|
|
321
|
+
}).strict(),
|
|
322
|
+
}).strict()
|
|
323
|
+
|
|
324
|
+
const supervisorGitRecoveryPromptFailedEventSchema = z.object({
|
|
325
|
+
type: z.literal('supervisor.git.recovery_prompt.failed'),
|
|
326
|
+
payload: z.object({
|
|
327
|
+
turnId: z.string(),
|
|
328
|
+
branch: z.string(),
|
|
329
|
+
trigger: supervisorGitTriggerSchema,
|
|
330
|
+
commandId: z.string().min(1),
|
|
331
|
+
reason: supervisorGitRecoveryPromptFailureReasonSchema,
|
|
332
|
+
detail: z.string(),
|
|
333
|
+
}).strict(),
|
|
334
|
+
}).strict()
|
|
335
|
+
|
|
336
|
+
export const supervisorEventSchema = z.discriminatedUnion('type', [
|
|
337
|
+
supervisorStartedEventSchema,
|
|
338
|
+
supervisorAgentRunChangedEventSchema,
|
|
339
|
+
supervisorHeartbeatEventSchema,
|
|
340
|
+
supervisorShuttingDownEventSchema,
|
|
341
|
+
supervisorSessionResumedEventSchema,
|
|
342
|
+
supervisorCommandAppliedEventSchema,
|
|
343
|
+
supervisorCommandTurnCorrelatedEventSchema,
|
|
344
|
+
supervisorCommandFailedEventSchema,
|
|
345
|
+
supervisorInterruptionRecoveryRequestedEventSchema,
|
|
346
|
+
supervisorInterruptionRecoveryAcceptedEventSchema,
|
|
347
|
+
supervisorInterruptionRecoveryWaitingEventSchema,
|
|
348
|
+
supervisorInterruptionRecoveryTurnCorrelatedEventSchema,
|
|
349
|
+
supervisorInterruptionRecoveryFailedEventSchema,
|
|
350
|
+
legacySupervisorGitCommitCompletedEventSchema,
|
|
351
|
+
sessionWorkspaceGitInitializedEventSchema,
|
|
352
|
+
sessionWorkspaceReadyEventSchema,
|
|
353
|
+
sessionWorkspaceGitCommittedEventSchema,
|
|
354
|
+
supervisorGitCommitFailedEventSchema,
|
|
355
|
+
legacySupervisorGitPushCompletedEventSchema,
|
|
356
|
+
sessionWorkspaceGitPushedEventSchema,
|
|
357
|
+
supervisorGitPushFailedEventSchema,
|
|
358
|
+
supervisorGitRecoveryPromptFailedEventSchema,
|
|
359
|
+
])
|
|
360
|
+
|
|
361
|
+
export type SupervisorShutdownReason = z.infer<typeof supervisorShutdownReasonSchema>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const telaPageCacheControlHeader = 'cache-control' as const
|
|
2
|
+
export const telaPageCacheControlValue = 'private, no-store' as const
|
|
3
|
+
export const telaPageContentTypeHeader = 'content-type' as const
|
|
4
|
+
export const telaPageDeclaredSizeHeader = 'content-length' as const
|
|
5
|
+
// Task-context materialization stays bounded independently of Pages Gateway storage limits.
|
|
6
|
+
export const telaPageMaxBytes = 100 * 1024 * 1024
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ControlPlaneToSupervisorEnvelope,
|
|
3
|
+
SupervisorToControlPlaneEnvelope,
|
|
4
|
+
WireEnvelope,
|
|
5
|
+
} from './envelope'
|
|
6
|
+
import z from 'zod'
|
|
7
|
+
import {
|
|
8
|
+
controlPlaneToSupervisorEnvelopeKinds,
|
|
9
|
+
controlPlaneToSupervisorEnvelopeSchema,
|
|
10
|
+
supervisorToControlPlaneEnvelopeKinds,
|
|
11
|
+
supervisorToControlPlaneEnvelopeSchema,
|
|
12
|
+
wireEnvelopeSchema,
|
|
13
|
+
} from './envelope'
|
|
14
|
+
|
|
15
|
+
const knownEnvelopeKinds = ['session.bootstrap', 'command', 'event.ack', 'rpc.response', 'runtime.state', 'event', 'command.ack', 'rpc.request', 'rpc.cancel'] as const
|
|
16
|
+
const envelopeProbeSchema = z.object({ kind: z.string() }).passthrough()
|
|
17
|
+
|
|
18
|
+
export type DecodedFrame<TFrame>
|
|
19
|
+
= | { kind: 'ok', frame: TFrame }
|
|
20
|
+
| { kind: 'unknown', detail: string }
|
|
21
|
+
| { kind: 'invalid', detail: string }
|
|
22
|
+
|
|
23
|
+
export type DecodedWireFrame = DecodedFrame<WireEnvelope>
|
|
24
|
+
export type DecodedControlPlaneFrame = DecodedFrame<ControlPlaneToSupervisorEnvelope>
|
|
25
|
+
export type DecodedSupervisorFrame = DecodedFrame<SupervisorToControlPlaneEnvelope>
|
|
26
|
+
|
|
27
|
+
export function decodeWireFrame(text: string): DecodedWireFrame {
|
|
28
|
+
return decodeWithSchema({ text, schema: wireEnvelopeSchema, knownKinds: knownEnvelopeKinds, direction: 'wire' })
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function decodeControlPlaneFrame(text: string): DecodedControlPlaneFrame {
|
|
32
|
+
return decodeWithSchema({
|
|
33
|
+
text,
|
|
34
|
+
schema: controlPlaneToSupervisorEnvelopeSchema,
|
|
35
|
+
knownKinds: controlPlaneToSupervisorEnvelopeKinds,
|
|
36
|
+
direction: 'control-plane',
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function decodeSupervisorFrame(text: string): DecodedSupervisorFrame {
|
|
41
|
+
return decodeWithSchema({
|
|
42
|
+
text,
|
|
43
|
+
schema: supervisorToControlPlaneEnvelopeSchema,
|
|
44
|
+
knownKinds: supervisorToControlPlaneEnvelopeKinds,
|
|
45
|
+
direction: 'supervisor',
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function encodeWireFrame(frame: WireEnvelope): string {
|
|
50
|
+
return JSON.stringify(frame)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function decodeWithSchema<TFrame>({ text, schema, knownKinds, direction }: { text: string, schema: z.ZodType<TFrame>, knownKinds: readonly string[], direction: string }): DecodedFrame<TFrame> {
|
|
54
|
+
let value: unknown
|
|
55
|
+
try {
|
|
56
|
+
value = JSON.parse(text)
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return { kind: 'invalid', detail: 'Frame is not valid JSON.' }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const probe = envelopeProbeSchema.safeParse(value)
|
|
63
|
+
if (probe.success && !knownKinds.includes(probe.data.kind))
|
|
64
|
+
return { kind: 'unknown', detail: `Unknown ${direction} envelope kind: ${probe.data.kind}` }
|
|
65
|
+
|
|
66
|
+
const parsed = schema.safeParse(value)
|
|
67
|
+
if (!parsed.success)
|
|
68
|
+
return { kind: 'invalid', detail: `Frame does not match ${direction} envelope schema.` }
|
|
69
|
+
|
|
70
|
+
return { kind: 'ok', frame: parsed.data }
|
|
71
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2024"],
|
|
5
|
+
"moduleDetection": "force",
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"moduleResolution": "bundler",
|
|
8
|
+
"types": ["bun"],
|
|
9
|
+
"strict": true,
|
|
10
|
+
"allowUnreachableCode": false,
|
|
11
|
+
"allowUnusedLabels": false,
|
|
12
|
+
"noFallthroughCasesInSwitch": true,
|
|
13
|
+
"noImplicitOverride": true,
|
|
14
|
+
"noImplicitReturns": true,
|
|
15
|
+
"noUncheckedIndexedAccess": true,
|
|
16
|
+
"noUnusedLocals": true,
|
|
17
|
+
"noUnusedParameters": true,
|
|
18
|
+
"noEmit": true,
|
|
19
|
+
"isolatedModules": true,
|
|
20
|
+
"verbatimModuleSyntax": true,
|
|
21
|
+
"skipLibCheck": true
|
|
22
|
+
},
|
|
23
|
+
"include": ["src", "bin", "scripts", "e2e"]
|
|
24
|
+
}
|