@xandreed/sdk 0.14.0 → 0.15.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.
Files changed (58) hide show
  1. package/README.md +1 -1
  2. package/dist/agent.adapter.d.ts +66 -34
  3. package/dist/agent.adapter.js +48 -37
  4. package/dist/conformance/index.d.ts +2 -0
  5. package/dist/conformance/index.js +1 -0
  6. package/dist/inbox-runner.adapter.d.ts +18 -0
  7. package/dist/inbox-runner.adapter.js +8 -0
  8. package/dist/index.d.ts +35 -2
  9. package/dist/index.js +59 -2
  10. package/dist/task-executor.adapter.d.ts +32 -0
  11. package/dist/task-executor.adapter.js +10 -0
  12. package/dist/task-inbox-runner.adapter.d.ts +11 -0
  13. package/dist/task-inbox-runner.adapter.js +22 -0
  14. package/dist/turn/memory-checkpoint.adapter.d.ts +17 -0
  15. package/dist/turn/memory-checkpoint.adapter.js +62 -0
  16. package/dist/turn/model-call-recorder.adapter.d.ts +9 -0
  17. package/dist/turn/model-call-recorder.adapter.js +93 -0
  18. package/dist/turn/model-call-recorder.entity.d.ts +145 -0
  19. package/dist/turn/model-call-recorder.entity.functions.d.ts +5 -0
  20. package/dist/turn/model-call-recorder.entity.functions.js +4 -0
  21. package/dist/turn/model-call-recorder.entity.js +8 -0
  22. package/dist/turn/tool-registry.conformance.d.ts +61 -0
  23. package/dist/turn/tool-registry.conformance.js +547 -0
  24. package/dist/turn/turn-after-reply.entity.functions.d.ts +9 -0
  25. package/dist/turn/turn-after-reply.entity.functions.js +4 -0
  26. package/dist/turn/turn-lifecycle.usecase.functions.d.ts +135 -0
  27. package/dist/turn/turn-lifecycle.usecase.functions.js +131 -0
  28. package/dist/turn/turn-observation.entity.d.ts +28 -0
  29. package/dist/turn/turn-observation.entity.functions.d.ts +15 -0
  30. package/dist/turn/turn-observation.entity.functions.js +17 -0
  31. package/dist/turn/turn-observation.entity.js +12 -0
  32. package/dist/turn/turn-overflow.entity.d.ts +7 -0
  33. package/dist/turn/turn-overflow.entity.functions.d.ts +11 -0
  34. package/dist/turn/turn-overflow.entity.functions.js +12 -0
  35. package/dist/turn/turn-overflow.entity.js +5 -0
  36. package/dist/turn/turn-phase.entity.d.ts +462 -0
  37. package/dist/turn/turn-phase.entity.functions.d.ts +44 -0
  38. package/dist/turn/turn-phase.entity.functions.js +49 -0
  39. package/dist/turn/turn-phase.entity.js +13 -0
  40. package/dist/turn/turn-run.usecase.functions.d.ts +72 -0
  41. package/dist/turn/turn-run.usecase.functions.js +329 -0
  42. package/dist/turn/turn.adapter.d.ts +26 -0
  43. package/dist/turn/turn.adapter.js +225 -0
  44. package/package.json +10 -4
  45. package/dist/activity.test.d.ts +0 -1
  46. package/dist/agent.adapter.test.d.ts +0 -1
  47. package/dist/agent.backends.test.d.ts +0 -1
  48. package/dist/agent.golden.test.d.ts +0 -231
  49. package/dist/agent.trace.test.d.ts +0 -1
  50. package/dist/events-guide.test.d.ts +0 -207
  51. package/dist/journal-compat.test.d.ts +0 -1
  52. package/dist/memory.conformance.test.d.ts +0 -1
  53. package/dist/models-plugin.test.d.ts +0 -1
  54. package/dist/plugin-stack.test.d.ts +0 -1
  55. package/dist/resume.journey.test.d.ts +0 -1
  56. package/dist/testing.port.d.ts +0 -16
  57. package/dist/testing.port.js +0 -7
  58. package/dist/turn-composition.test.d.ts +0 -1
@@ -0,0 +1,462 @@
1
+ import { Schema } from "effect";
2
+ import type { UserMessage } from "@xandreed/core";
3
+ /**
4
+ * Where one turn stands in `TurnLive`: its message not taken by memory yet
5
+ * (`Waiting`, with the context entries waiting for it), being taken
6
+ * (`Taking`: `persistMessage` is recording it, and context entries still
7
+ * wait), taken as turn `number` (`Taken`; `sectioned` once its turn-tier
8
+ * sections are due; `runs`, the ordinal its next run of the step loop
9
+ * takes), or replied (`Replied`, with the outcome recorded, and `held`, the
10
+ * memory entries held for the turn's closing commit: its reply, and what
11
+ * memory recorded after it, in order). Its transitions are the pure
12
+ * functions of `turn-phase.entity.functions.ts`.
13
+ */
14
+ export declare const TurnPhase: Schema.toTaggedUnion<"_tag", readonly [Schema.TaggedStruct<"Waiting", {
15
+ readonly early: Schema.$Array<Schema.TaggedStruct<"TurnContext", {
16
+ readonly sectionId: Schema.brand<Schema.String, "SectionId">;
17
+ readonly version: Schema.String;
18
+ readonly text: Schema.String;
19
+ }>>;
20
+ }>, Schema.TaggedStruct<"Taking", {
21
+ readonly early: Schema.$Array<Schema.TaggedStruct<"TurnContext", {
22
+ readonly sectionId: Schema.brand<Schema.String, "SectionId">;
23
+ readonly version: Schema.String;
24
+ readonly text: Schema.String;
25
+ }>>;
26
+ }>, Schema.TaggedStruct<"Taken", {
27
+ readonly number: Schema.Int;
28
+ readonly sectioned: Schema.Boolean;
29
+ readonly runs: Schema.brand<Schema.Int, "RunOrdinal">;
30
+ }>, Schema.TaggedStruct<"Replied", {
31
+ readonly number: Schema.Int;
32
+ readonly outcome: Schema.Literals<readonly ["completed", "partial", "failed", "waiting"]>;
33
+ readonly held: Schema.$Array<Schema.Struct<{
34
+ readonly id: Schema.brand<Schema.Trimmed, "EntryId">;
35
+ readonly runId: Schema.brand<Schema.String, "RunId">;
36
+ readonly turn: Schema.Int;
37
+ readonly step: Schema.Int;
38
+ readonly at: Schema.Number;
39
+ readonly body: Schema.toTaggedUnion<"_tag", readonly [Schema.TaggedStruct<"SystemPrepared", {
40
+ readonly fingerprint: Schema.String;
41
+ readonly text: Schema.String;
42
+ readonly sections: Schema.$Array<Schema.Struct<{
43
+ readonly id: Schema.brand<Schema.String, "SectionId">;
44
+ readonly version: Schema.String;
45
+ readonly fingerprint: Schema.String;
46
+ }>>;
47
+ }>, Schema.decodeTo<Schema.TaggedStruct<"TurnStarted", {
48
+ readonly userMessage: typeof UserMessage;
49
+ }>, Schema.Struct<{
50
+ readonly _tag: Schema.Literal<"TurnStarted">;
51
+ readonly prompt: Schema.String;
52
+ readonly attachments: Schema.optionalKey<Schema.$Array<Schema.toEncoded<Schema.Struct<{
53
+ readonly type: Schema.Literal<"media">;
54
+ readonly mediaType: Schema.Literals<readonly ["image/png", "image/jpeg", "image/gif", "image/webp"]>;
55
+ readonly data: Schema.String;
56
+ readonly fingerprint: Schema.brand<Schema.String, "MediaFingerprint">;
57
+ readonly bytes: Schema.Int;
58
+ readonly name: Schema.optionalKey<Schema.String>;
59
+ readonly alt: Schema.optionalKey<Schema.String>;
60
+ }>>>>;
61
+ }>, never, never>, Schema.TaggedStruct<"TurnContext", {
62
+ readonly sectionId: Schema.brand<Schema.String, "SectionId">;
63
+ readonly version: Schema.String;
64
+ readonly text: Schema.String;
65
+ }>, Schema.Struct<{
66
+ readonly _tag: Schema.tag<"Message">;
67
+ readonly message: Schema.Union<readonly [Schema.Struct<{
68
+ readonly role: Schema.Literal<"user">;
69
+ readonly content: Schema.Union<readonly [Schema.String, Schema.$Array<Schema.Union<readonly [Schema.Struct<{
70
+ readonly type: Schema.Literal<"text">;
71
+ readonly text: Schema.String;
72
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
73
+ }>, Schema.Struct<{
74
+ readonly type: Schema.Literal<"media">;
75
+ readonly mediaType: Schema.Literals<readonly ["image/png", "image/jpeg", "image/gif", "image/webp"]>;
76
+ readonly data: Schema.String;
77
+ readonly fingerprint: Schema.brand<Schema.String, "MediaFingerprint">;
78
+ readonly bytes: Schema.Int;
79
+ readonly name: Schema.optionalKey<Schema.String>;
80
+ readonly alt: Schema.optionalKey<Schema.String>;
81
+ }>]>>]>;
82
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
83
+ }>, Schema.Struct<{
84
+ readonly role: Schema.Literal<"assistant">;
85
+ readonly content: Schema.$Array<Schema.Union<readonly [Schema.Struct<{
86
+ readonly type: Schema.Literal<"text">;
87
+ readonly text: Schema.String;
88
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
89
+ }>, Schema.Struct<{
90
+ readonly type: Schema.Literal<"reasoning">;
91
+ readonly text: Schema.String;
92
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
93
+ }>, Schema.Struct<{
94
+ readonly type: Schema.Literal<"tool-call">;
95
+ readonly toolCallId: Schema.brand<Schema.String, "ToolCallId">;
96
+ readonly toolName: Schema.String;
97
+ readonly input: Schema.Unknown;
98
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
99
+ readonly providerExecuted: Schema.optional<Schema.Boolean>;
100
+ }>, Schema.Struct<{
101
+ readonly type: Schema.Literal<"tool-result">;
102
+ readonly toolCallId: Schema.brand<Schema.String, "ToolCallId">;
103
+ readonly toolName: Schema.String;
104
+ readonly output: Schema.Unknown;
105
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
106
+ readonly isError: Schema.optional<Schema.Boolean>;
107
+ readonly providerExecuted: Schema.optionalKey<Schema.Boolean>;
108
+ readonly media: Schema.optionalKey<Schema.$Array<Schema.Struct<{
109
+ readonly type: Schema.Literal<"media">;
110
+ readonly mediaType: Schema.Literals<readonly ["image/png", "image/jpeg", "image/gif", "image/webp"]>;
111
+ readonly data: Schema.String;
112
+ readonly fingerprint: Schema.brand<Schema.String, "MediaFingerprint">;
113
+ readonly bytes: Schema.Int;
114
+ readonly name: Schema.optionalKey<Schema.String>;
115
+ readonly alt: Schema.optionalKey<Schema.String>;
116
+ }>>>;
117
+ }>]>>;
118
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
119
+ }>, Schema.Struct<{
120
+ readonly role: Schema.Literal<"tool">;
121
+ readonly content: Schema.$Array<Schema.Struct<{
122
+ readonly type: Schema.Literal<"tool-result">;
123
+ readonly toolCallId: Schema.brand<Schema.String, "ToolCallId">;
124
+ readonly toolName: Schema.String;
125
+ readonly output: Schema.Unknown;
126
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
127
+ readonly isError: Schema.optional<Schema.Boolean>;
128
+ readonly providerExecuted: Schema.optionalKey<Schema.Boolean>;
129
+ readonly media: Schema.optionalKey<Schema.$Array<Schema.Struct<{
130
+ readonly type: Schema.Literal<"media">;
131
+ readonly mediaType: Schema.Literals<readonly ["image/png", "image/jpeg", "image/gif", "image/webp"]>;
132
+ readonly data: Schema.String;
133
+ readonly fingerprint: Schema.brand<Schema.String, "MediaFingerprint">;
134
+ readonly bytes: Schema.Int;
135
+ readonly name: Schema.optionalKey<Schema.String>;
136
+ readonly alt: Schema.optionalKey<Schema.String>;
137
+ }>>>;
138
+ }>>;
139
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
140
+ }>]>;
141
+ readonly run: Schema.optionalKey<Schema.brand<Schema.Int, "RunOrdinal">>;
142
+ readonly inbox: Schema.optionalKey<Schema.brand<Schema.Trimmed, "InboxItemId">>;
143
+ }>, Schema.TaggedStruct<"ToolResult", {
144
+ readonly toolCallId: Schema.brand<Schema.String, "ToolCallId">;
145
+ readonly run: Schema.optionalKey<Schema.brand<Schema.Int, "RunOrdinal">>;
146
+ readonly toolName: Schema.String;
147
+ readonly isError: Schema.Boolean;
148
+ readonly encoded: Schema.Unknown;
149
+ readonly interception: Schema.optionalKey<Schema.Struct<{
150
+ readonly invocationId: Schema.brand<Schema.String, "InvocationId">;
151
+ readonly effectiveInput: Schema.optionalKey<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
152
+ }>>;
153
+ readonly view: Schema.String;
154
+ readonly viewVersion: Schema.String;
155
+ readonly subjects: Schema.$Array<Schema.Struct<{
156
+ readonly kind: Schema.Trimmed;
157
+ readonly id: Schema.brand<Schema.Trimmed, "SubjectId">;
158
+ readonly label: Schema.OptionFromNullOr<Schema.String>;
159
+ readonly data: Schema.OptionFromNullOr<Schema.Unknown>;
160
+ }>>;
161
+ readonly artifacts: Schema.$Array<Schema.Struct<{
162
+ readonly id: Schema.brand<Schema.Trimmed, "ArtifactId">;
163
+ readonly kind: Schema.Literals<readonly ["image", "file"]>;
164
+ readonly mediaType: Schema.Trimmed;
165
+ readonly url: Schema.String;
166
+ readonly alt: Schema.OptionFromNullOr<Schema.String>;
167
+ }>>;
168
+ readonly pinned: Schema.Boolean;
169
+ readonly media: Schema.optionalKey<Schema.$Array<Schema.Struct<{
170
+ readonly path: Schema.$Array<Schema.Union<readonly [Schema.String, Schema.Int]>>;
171
+ readonly fingerprint: Schema.brand<Schema.String, "MediaFingerprint">;
172
+ readonly mediaType: Schema.Literals<readonly ["image/png", "image/jpeg", "image/gif", "image/webp"]>;
173
+ readonly bytes: Schema.Int;
174
+ }>>>;
175
+ readonly mediaNotes: Schema.optionalKey<Schema.$Array<Schema.String>>;
176
+ }>, Schema.TaggedStruct<"ToolDigest", {
177
+ readonly entry: Schema.brand<Schema.Trimmed, "EntryId">;
178
+ readonly version: Schema.String;
179
+ readonly mode: Schema.Literals<readonly ["select", "summarize"]>;
180
+ readonly keep: Schema.$Array<Schema.String>;
181
+ readonly text: Schema.String;
182
+ readonly digester: Schema.String;
183
+ readonly trigger: Schema.Literals<readonly ["write", "compaction"]>;
184
+ }>, Schema.TaggedStruct<"StepContext", {
185
+ readonly step: Schema.Int;
186
+ readonly run: Schema.withDecodingDefaultKey<Schema.brand<Schema.Int, "RunOrdinal">, never>;
187
+ readonly text: Schema.String;
188
+ }>, Schema.TaggedStruct<"ToolsActivated", {
189
+ readonly skills: Schema.$Array<Schema.String>;
190
+ readonly tools: Schema.$Array<Schema.String>;
191
+ readonly source: Schema.Literals<readonly ["always", "matcher", "load_skill", "host"]>;
192
+ readonly decision: Schema.OptionFromNullOr<Schema.brand<Schema.Trimmed, "DecisionId">>;
193
+ }>, Schema.TaggedStruct<"Compaction", {
194
+ readonly strategy: Schema.String;
195
+ readonly version: Schema.String;
196
+ readonly action: Schema.toTaggedUnion<"_tag", readonly [Schema.TaggedStruct<"CompactViews", {
197
+ readonly entries: Schema.$Array<Schema.brand<Schema.Trimmed, "EntryId">>;
198
+ readonly texts: Schema.$Array<Schema.String>;
199
+ }>, Schema.TaggedStruct<"Spill", {
200
+ readonly entry: Schema.brand<Schema.Trimmed, "EntryId">;
201
+ readonly preview: Schema.String;
202
+ }>, Schema.TaggedStruct<"DropTurns", {
203
+ readonly throughTurn: Schema.Int;
204
+ readonly ledger: Schema.String;
205
+ }>, Schema.TaggedStruct<"Summarize", {
206
+ readonly keepFromTurn: Schema.Int;
207
+ readonly summary: Schema.String;
208
+ }>, Schema.TaggedStruct<"OmitMedia", {
209
+ readonly entries: Schema.$Array<Schema.brand<Schema.Trimmed, "EntryId">>;
210
+ readonly reason: Schema.String;
211
+ }>]>;
212
+ }>, Schema.TaggedStruct<"TurnEnded", {
213
+ readonly outcome: Schema.Literals<readonly ["completed", "partial", "failed", "waiting"]>;
214
+ readonly reply: Schema.OptionFromNullOr<Schema.String>;
215
+ }>, Schema.TaggedStruct<"ToolPresentation", {
216
+ readonly entry: Schema.brand<Schema.Trimmed, "EntryId">;
217
+ readonly view: Schema.String;
218
+ readonly viewVersion: Schema.String;
219
+ readonly subjects: Schema.$Array<Schema.Struct<{
220
+ readonly kind: Schema.Trimmed;
221
+ readonly id: Schema.brand<Schema.Trimmed, "SubjectId">;
222
+ readonly label: Schema.OptionFromNullOr<Schema.String>;
223
+ readonly data: Schema.OptionFromNullOr<Schema.Unknown>;
224
+ }>>;
225
+ readonly artifacts: Schema.$Array<Schema.Struct<{
226
+ readonly id: Schema.brand<Schema.Trimmed, "ArtifactId">;
227
+ readonly kind: Schema.Literals<readonly ["image", "file"]>;
228
+ readonly mediaType: Schema.Trimmed;
229
+ readonly url: Schema.String;
230
+ readonly alt: Schema.OptionFromNullOr<Schema.String>;
231
+ }>>;
232
+ readonly pinned: Schema.Boolean;
233
+ readonly media: Schema.$Array<Schema.Struct<{
234
+ readonly path: Schema.$Array<Schema.Union<readonly [Schema.String, Schema.Int]>>;
235
+ readonly fingerprint: Schema.brand<Schema.String, "MediaFingerprint">;
236
+ readonly mediaType: Schema.Literals<readonly ["image/png", "image/jpeg", "image/gif", "image/webp"]>;
237
+ readonly bytes: Schema.Int;
238
+ }>>;
239
+ readonly mediaNotes: Schema.$Array<Schema.String>;
240
+ }>]>;
241
+ }>>;
242
+ }>]>;
243
+ export type TurnPhase = typeof TurnPhase.Type;
244
+ /**
245
+ * What a reply does (`reply`): `Record` the turn's reply (TurnEnded) as
246
+ * turn `number` and publish `turn.ended`; `Hold` these entries again for the
247
+ * closing commit, the reply among them downgraded to failed; or nothing.
248
+ */
249
+ export declare const ReplyStep: Schema.toTaggedUnion<"_tag", readonly [Schema.TaggedStruct<"Record", {
250
+ readonly number: Schema.Int;
251
+ }>, Schema.TaggedStruct<"Hold", {
252
+ readonly held: Schema.$Array<Schema.Struct<{
253
+ readonly id: Schema.brand<Schema.Trimmed, "EntryId">;
254
+ readonly runId: Schema.brand<Schema.String, "RunId">;
255
+ readonly turn: Schema.Int;
256
+ readonly step: Schema.Int;
257
+ readonly at: Schema.Number;
258
+ readonly body: Schema.toTaggedUnion<"_tag", readonly [Schema.TaggedStruct<"SystemPrepared", {
259
+ readonly fingerprint: Schema.String;
260
+ readonly text: Schema.String;
261
+ readonly sections: Schema.$Array<Schema.Struct<{
262
+ readonly id: Schema.brand<Schema.String, "SectionId">;
263
+ readonly version: Schema.String;
264
+ readonly fingerprint: Schema.String;
265
+ }>>;
266
+ }>, Schema.decodeTo<Schema.TaggedStruct<"TurnStarted", {
267
+ readonly userMessage: typeof UserMessage;
268
+ }>, Schema.Struct<{
269
+ readonly _tag: Schema.Literal<"TurnStarted">;
270
+ readonly prompt: Schema.String;
271
+ readonly attachments: Schema.optionalKey<Schema.$Array<Schema.toEncoded<Schema.Struct<{
272
+ readonly type: Schema.Literal<"media">;
273
+ readonly mediaType: Schema.Literals<readonly ["image/png", "image/jpeg", "image/gif", "image/webp"]>;
274
+ readonly data: Schema.String;
275
+ readonly fingerprint: Schema.brand<Schema.String, "MediaFingerprint">;
276
+ readonly bytes: Schema.Int;
277
+ readonly name: Schema.optionalKey<Schema.String>;
278
+ readonly alt: Schema.optionalKey<Schema.String>;
279
+ }>>>>;
280
+ }>, never, never>, Schema.TaggedStruct<"TurnContext", {
281
+ readonly sectionId: Schema.brand<Schema.String, "SectionId">;
282
+ readonly version: Schema.String;
283
+ readonly text: Schema.String;
284
+ }>, Schema.Struct<{
285
+ readonly _tag: Schema.tag<"Message">;
286
+ readonly message: Schema.Union<readonly [Schema.Struct<{
287
+ readonly role: Schema.Literal<"user">;
288
+ readonly content: Schema.Union<readonly [Schema.String, Schema.$Array<Schema.Union<readonly [Schema.Struct<{
289
+ readonly type: Schema.Literal<"text">;
290
+ readonly text: Schema.String;
291
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
292
+ }>, Schema.Struct<{
293
+ readonly type: Schema.Literal<"media">;
294
+ readonly mediaType: Schema.Literals<readonly ["image/png", "image/jpeg", "image/gif", "image/webp"]>;
295
+ readonly data: Schema.String;
296
+ readonly fingerprint: Schema.brand<Schema.String, "MediaFingerprint">;
297
+ readonly bytes: Schema.Int;
298
+ readonly name: Schema.optionalKey<Schema.String>;
299
+ readonly alt: Schema.optionalKey<Schema.String>;
300
+ }>]>>]>;
301
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
302
+ }>, Schema.Struct<{
303
+ readonly role: Schema.Literal<"assistant">;
304
+ readonly content: Schema.$Array<Schema.Union<readonly [Schema.Struct<{
305
+ readonly type: Schema.Literal<"text">;
306
+ readonly text: Schema.String;
307
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
308
+ }>, Schema.Struct<{
309
+ readonly type: Schema.Literal<"reasoning">;
310
+ readonly text: Schema.String;
311
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
312
+ }>, Schema.Struct<{
313
+ readonly type: Schema.Literal<"tool-call">;
314
+ readonly toolCallId: Schema.brand<Schema.String, "ToolCallId">;
315
+ readonly toolName: Schema.String;
316
+ readonly input: Schema.Unknown;
317
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
318
+ readonly providerExecuted: Schema.optional<Schema.Boolean>;
319
+ }>, Schema.Struct<{
320
+ readonly type: Schema.Literal<"tool-result">;
321
+ readonly toolCallId: Schema.brand<Schema.String, "ToolCallId">;
322
+ readonly toolName: Schema.String;
323
+ readonly output: Schema.Unknown;
324
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
325
+ readonly isError: Schema.optional<Schema.Boolean>;
326
+ readonly providerExecuted: Schema.optionalKey<Schema.Boolean>;
327
+ readonly media: Schema.optionalKey<Schema.$Array<Schema.Struct<{
328
+ readonly type: Schema.Literal<"media">;
329
+ readonly mediaType: Schema.Literals<readonly ["image/png", "image/jpeg", "image/gif", "image/webp"]>;
330
+ readonly data: Schema.String;
331
+ readonly fingerprint: Schema.brand<Schema.String, "MediaFingerprint">;
332
+ readonly bytes: Schema.Int;
333
+ readonly name: Schema.optionalKey<Schema.String>;
334
+ readonly alt: Schema.optionalKey<Schema.String>;
335
+ }>>>;
336
+ }>]>>;
337
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
338
+ }>, Schema.Struct<{
339
+ readonly role: Schema.Literal<"tool">;
340
+ readonly content: Schema.$Array<Schema.Struct<{
341
+ readonly type: Schema.Literal<"tool-result">;
342
+ readonly toolCallId: Schema.brand<Schema.String, "ToolCallId">;
343
+ readonly toolName: Schema.String;
344
+ readonly output: Schema.Unknown;
345
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
346
+ readonly isError: Schema.optional<Schema.Boolean>;
347
+ readonly providerExecuted: Schema.optionalKey<Schema.Boolean>;
348
+ readonly media: Schema.optionalKey<Schema.$Array<Schema.Struct<{
349
+ readonly type: Schema.Literal<"media">;
350
+ readonly mediaType: Schema.Literals<readonly ["image/png", "image/jpeg", "image/gif", "image/webp"]>;
351
+ readonly data: Schema.String;
352
+ readonly fingerprint: Schema.brand<Schema.String, "MediaFingerprint">;
353
+ readonly bytes: Schema.Int;
354
+ readonly name: Schema.optionalKey<Schema.String>;
355
+ readonly alt: Schema.optionalKey<Schema.String>;
356
+ }>>>;
357
+ }>>;
358
+ readonly providerOptions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>>;
359
+ }>]>;
360
+ readonly run: Schema.optionalKey<Schema.brand<Schema.Int, "RunOrdinal">>;
361
+ readonly inbox: Schema.optionalKey<Schema.brand<Schema.Trimmed, "InboxItemId">>;
362
+ }>, Schema.TaggedStruct<"ToolResult", {
363
+ readonly toolCallId: Schema.brand<Schema.String, "ToolCallId">;
364
+ readonly run: Schema.optionalKey<Schema.brand<Schema.Int, "RunOrdinal">>;
365
+ readonly toolName: Schema.String;
366
+ readonly isError: Schema.Boolean;
367
+ readonly encoded: Schema.Unknown;
368
+ readonly interception: Schema.optionalKey<Schema.Struct<{
369
+ readonly invocationId: Schema.brand<Schema.String, "InvocationId">;
370
+ readonly effectiveInput: Schema.optionalKey<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
371
+ }>>;
372
+ readonly view: Schema.String;
373
+ readonly viewVersion: Schema.String;
374
+ readonly subjects: Schema.$Array<Schema.Struct<{
375
+ readonly kind: Schema.Trimmed;
376
+ readonly id: Schema.brand<Schema.Trimmed, "SubjectId">;
377
+ readonly label: Schema.OptionFromNullOr<Schema.String>;
378
+ readonly data: Schema.OptionFromNullOr<Schema.Unknown>;
379
+ }>>;
380
+ readonly artifacts: Schema.$Array<Schema.Struct<{
381
+ readonly id: Schema.brand<Schema.Trimmed, "ArtifactId">;
382
+ readonly kind: Schema.Literals<readonly ["image", "file"]>;
383
+ readonly mediaType: Schema.Trimmed;
384
+ readonly url: Schema.String;
385
+ readonly alt: Schema.OptionFromNullOr<Schema.String>;
386
+ }>>;
387
+ readonly pinned: Schema.Boolean;
388
+ readonly media: Schema.optionalKey<Schema.$Array<Schema.Struct<{
389
+ readonly path: Schema.$Array<Schema.Union<readonly [Schema.String, Schema.Int]>>;
390
+ readonly fingerprint: Schema.brand<Schema.String, "MediaFingerprint">;
391
+ readonly mediaType: Schema.Literals<readonly ["image/png", "image/jpeg", "image/gif", "image/webp"]>;
392
+ readonly bytes: Schema.Int;
393
+ }>>>;
394
+ readonly mediaNotes: Schema.optionalKey<Schema.$Array<Schema.String>>;
395
+ }>, Schema.TaggedStruct<"ToolDigest", {
396
+ readonly entry: Schema.brand<Schema.Trimmed, "EntryId">;
397
+ readonly version: Schema.String;
398
+ readonly mode: Schema.Literals<readonly ["select", "summarize"]>;
399
+ readonly keep: Schema.$Array<Schema.String>;
400
+ readonly text: Schema.String;
401
+ readonly digester: Schema.String;
402
+ readonly trigger: Schema.Literals<readonly ["write", "compaction"]>;
403
+ }>, Schema.TaggedStruct<"StepContext", {
404
+ readonly step: Schema.Int;
405
+ readonly run: Schema.withDecodingDefaultKey<Schema.brand<Schema.Int, "RunOrdinal">, never>;
406
+ readonly text: Schema.String;
407
+ }>, Schema.TaggedStruct<"ToolsActivated", {
408
+ readonly skills: Schema.$Array<Schema.String>;
409
+ readonly tools: Schema.$Array<Schema.String>;
410
+ readonly source: Schema.Literals<readonly ["always", "matcher", "load_skill", "host"]>;
411
+ readonly decision: Schema.OptionFromNullOr<Schema.brand<Schema.Trimmed, "DecisionId">>;
412
+ }>, Schema.TaggedStruct<"Compaction", {
413
+ readonly strategy: Schema.String;
414
+ readonly version: Schema.String;
415
+ readonly action: Schema.toTaggedUnion<"_tag", readonly [Schema.TaggedStruct<"CompactViews", {
416
+ readonly entries: Schema.$Array<Schema.brand<Schema.Trimmed, "EntryId">>;
417
+ readonly texts: Schema.$Array<Schema.String>;
418
+ }>, Schema.TaggedStruct<"Spill", {
419
+ readonly entry: Schema.brand<Schema.Trimmed, "EntryId">;
420
+ readonly preview: Schema.String;
421
+ }>, Schema.TaggedStruct<"DropTurns", {
422
+ readonly throughTurn: Schema.Int;
423
+ readonly ledger: Schema.String;
424
+ }>, Schema.TaggedStruct<"Summarize", {
425
+ readonly keepFromTurn: Schema.Int;
426
+ readonly summary: Schema.String;
427
+ }>, Schema.TaggedStruct<"OmitMedia", {
428
+ readonly entries: Schema.$Array<Schema.brand<Schema.Trimmed, "EntryId">>;
429
+ readonly reason: Schema.String;
430
+ }>]>;
431
+ }>, Schema.TaggedStruct<"TurnEnded", {
432
+ readonly outcome: Schema.Literals<readonly ["completed", "partial", "failed", "waiting"]>;
433
+ readonly reply: Schema.OptionFromNullOr<Schema.String>;
434
+ }>, Schema.TaggedStruct<"ToolPresentation", {
435
+ readonly entry: Schema.brand<Schema.Trimmed, "EntryId">;
436
+ readonly view: Schema.String;
437
+ readonly viewVersion: Schema.String;
438
+ readonly subjects: Schema.$Array<Schema.Struct<{
439
+ readonly kind: Schema.Trimmed;
440
+ readonly id: Schema.brand<Schema.Trimmed, "SubjectId">;
441
+ readonly label: Schema.OptionFromNullOr<Schema.String>;
442
+ readonly data: Schema.OptionFromNullOr<Schema.Unknown>;
443
+ }>>;
444
+ readonly artifacts: Schema.$Array<Schema.Struct<{
445
+ readonly id: Schema.brand<Schema.Trimmed, "ArtifactId">;
446
+ readonly kind: Schema.Literals<readonly ["image", "file"]>;
447
+ readonly mediaType: Schema.Trimmed;
448
+ readonly url: Schema.String;
449
+ readonly alt: Schema.OptionFromNullOr<Schema.String>;
450
+ }>>;
451
+ readonly pinned: Schema.Boolean;
452
+ readonly media: Schema.$Array<Schema.Struct<{
453
+ readonly path: Schema.$Array<Schema.Union<readonly [Schema.String, Schema.Int]>>;
454
+ readonly fingerprint: Schema.brand<Schema.String, "MediaFingerprint">;
455
+ readonly mediaType: Schema.Literals<readonly ["image/png", "image/jpeg", "image/gif", "image/webp"]>;
456
+ readonly bytes: Schema.Int;
457
+ }>>;
458
+ readonly mediaNotes: Schema.$Array<Schema.String>;
459
+ }>]>;
460
+ }>>;
461
+ }>, Schema.TaggedStruct<"Nothing", {}>]>;
462
+ export type ReplyStep = typeof ReplyStep.Type;
@@ -0,0 +1,44 @@
1
+ import { Option, Result } from "effect";
2
+ import type { HarnessError, LogEntry, RunId, RunRef, TurnContextBody, TurnOutcomeKind } from "@xandreed/core";
3
+ import type { ReplyStep, TurnPhase } from "./turn-phase.entity.js";
4
+ /** What a transition returns, with the phase it moves to; or why the phase refuses it, which leaves the phase as it was. */
5
+ export type Transition<A> = Result.Result<readonly [A, TurnPhase], HarnessError>;
6
+ /** Start taking the message (`persistMessage`): only a waiting turn's, so once; `turn.persisted` otherwise. */
7
+ export declare const claim: (phase: TurnPhase) => Transition<void>;
8
+ /** The message was not recorded: it waits again, with its context entries, to be taken. */
9
+ export declare const release: (phase: TurnPhase) => TurnPhase;
10
+ /** The message is recorded as turn `number`: the turn is taken, and the context entries that waited for it are returned, to record next. */
11
+ export declare const take: (number: number) => (phase: TurnPhase) => Transition<ReadonlyArray<TurnContextBody>>;
12
+ /** A context entry: it waits for the message while the message is not taken, and is returned, to record now, once it is. */
13
+ export declare const addContext: (body: TurnContextBody) => (phase: TurnPhase) => Transition<ReadonlyArray<TurnContextBody>>;
14
+ /** Whether the turn-tier sections are due: once, after the message is taken and before the reply; `turn.unstarted` before. */
15
+ export declare const sectionsDue: (phase: TurnPhase) => Transition<boolean>;
16
+ /**
17
+ * A run of the step loop starts (`TurnMemory.startRun`): the turn's next
18
+ * run, under the turn's run id and number, its ordinal counting from 0.
19
+ * `turn.unstarted` before the message is taken; `turn.closed` once the
20
+ * reply is recorded, which ends the turn's runs.
21
+ */
22
+ export declare const startRun: (id: RunId) => (phase: TurnPhase) => Transition<RunRef>;
23
+ /**
24
+ * The reply, with its outcome: recorded once, after the message is taken
25
+ * (`Record`, the turn's number); nothing before. Once replied, a failed
26
+ * reply downgrades a completed or partial one (a finish that failed after
27
+ * it): the entries held for the closing commit are held again, the reply
28
+ * failed under its own id (`Hold`), or, when memory never held it, the reply
29
+ * is recorded again, failed. Anything else does nothing: a reply is never
30
+ * upgraded.
31
+ */
32
+ export declare const reply: (outcome: TurnOutcomeKind) => (phase: TurnPhase) => Transition<ReplyStep>;
33
+ /**
34
+ * Where entries memory records now go: once the turn replied, they are held
35
+ * for its closing commit after everything held before them (returned: the
36
+ * writer's `closing` takes them all, and `hold` keeps them once it did);
37
+ * before it, a reply (TurnEnded) recorded on its own is held alone, and
38
+ * anything else is stored as it is recorded (none).
39
+ */
40
+ export declare const heldWith: (entries: ReadonlyArray<LogEntry>) => (phase: TurnPhase) => Option.Option<ReadonlyArray<LogEntry>>;
41
+ /** The entries the writer now holds for the closing commit (`heldWith`'s), kept by a replied turn. */
42
+ export declare const hold: (held: ReadonlyArray<LogEntry>) => (phase: TurnPhase) => TurnPhase;
43
+ /** The turn's number, once the message is taken. */
44
+ export declare const numberOf: (phase: TurnPhase) => Option.Option<number>;
@@ -0,0 +1,49 @@
1
+ import { Match, Option, Result } from "effect";
2
+ import { harnessError, RunOrdinal } from "@xandreed/core";
3
+ const moved = (value, next) => Result.succeed([value, next]), persisted = Result.fail(harnessError("turn.persisted", "The user's message is already persisted")), unstarted = (what) => Result.fail(harnessError("turn.unstarted", what));
4
+ export const claim = (phase) => Match.valueTags(phase, {
5
+ Waiting: ({ early }) => moved(void 0, { _tag: "Taking", early }),
6
+ Taking: () => persisted,
7
+ Taken: () => persisted,
8
+ Replied: () => persisted
9
+ }), release = (phase) => phase._tag === "Taking" ? { _tag: "Waiting", early: phase.early } : phase, take = (number) => (phase) => Match.valueTags(phase, {
10
+ Waiting: () => unstarted("The user's message is not being persisted"),
11
+ Taking: ({ early }) => moved(early, { _tag: "Taken", number, sectioned: !1, runs: RunOrdinal.make(0) }),
12
+ Taken: () => persisted,
13
+ Replied: () => persisted
14
+ }), addContext = (body) => (phase) => Match.valueTags(phase, {
15
+ Waiting: ({ early }) => moved([], { _tag: "Waiting", early: [...early, body] }),
16
+ Taking: ({ early }) => moved([], { _tag: "Taking", early: [...early, body] }),
17
+ Taken: () => moved([body], phase),
18
+ Replied: () => moved([body], phase)
19
+ }), sectionsDue = (phase) => Match.valueTags(phase, {
20
+ Waiting: () => unstarted("The turn's sections are recorded after the user's message is persisted"),
21
+ Taking: () => unstarted("The turn's sections are recorded after the user's message is persisted"),
22
+ Taken: (taken) => moved(!taken.sectioned, { ...taken, sectioned: !0 }),
23
+ Replied: () => moved(!1, phase)
24
+ }), startRun = (id) => (phase) => Match.valueTags(phase, {
25
+ Waiting: () => unstarted("A run starts after the user's message is persisted"),
26
+ Taking: () => unstarted("A run starts after the user's message is persisted"),
27
+ Taken: (taken) => moved({ id, turn: taken.number, ordinal: taken.runs }, { ...taken, runs: RunOrdinal.make(taken.runs + 1) }),
28
+ Replied: () => Result.fail(harnessError("turn.closed", "The turn's reply is recorded: no run starts after it"))
29
+ });
30
+ const nothing = { _tag: "Nothing" }, isReply = (entry) => entry.body._tag === "TurnEnded", downgraded = (held) => held.map((entry) => entry.body._tag === "TurnEnded" ? { ...entry, body: { ...entry.body, outcome: "failed" } } : entry), downgrade = (replied) => replied.held.some(isReply) ? moved({ _tag: "Hold", held: downgraded(replied.held) }, { ...replied, outcome: "failed", held: downgraded(replied.held) }) : moved({ _tag: "Record", number: replied.number }, { ...replied, outcome: "failed" });
31
+ export const reply = (outcome) => (phase) => Match.valueTags(phase, {
32
+ Waiting: () => moved(nothing, phase),
33
+ Taking: () => moved(nothing, phase),
34
+ Taken: ({ number }) => moved({ _tag: "Record", number }, { _tag: "Replied", number, outcome, held: [] }),
35
+ Replied: (replied) => outcome === "failed" && replied.outcome !== "failed" ? downgrade(replied) : moved(nothing, phase)
36
+ }), heldWith = (entries) => (phase) => {
37
+ const alone = () => Option.liftPredicate(entries, (all) => all.some(isReply));
38
+ return Match.valueTags(phase, {
39
+ Waiting: alone,
40
+ Taking: alone,
41
+ Taken: alone,
42
+ Replied: ({ held }) => Option.some([...held, ...entries])
43
+ });
44
+ }, hold = (held) => (phase) => phase._tag === "Replied" ? { ...phase, held } : phase, numberOf = (phase) => Match.valueTags(phase, {
45
+ Waiting: () => Option.none(),
46
+ Taking: () => Option.none(),
47
+ Taken: ({ number }) => Option.some(number),
48
+ Replied: ({ number }) => Option.some(number)
49
+ });
@@ -0,0 +1,13 @@
1
+ import { Schema } from "effect";
2
+ import { LogEntry, RunOrdinal, TurnContextBody, TurnOutcomeKind } from "@xandreed/core";
3
+ const Early = Schema.Array(TurnContextBody);
4
+ export const TurnPhase = Schema.Union([
5
+ Schema.TaggedStruct("Waiting", { early: Early }),
6
+ Schema.TaggedStruct("Taking", { early: Early }),
7
+ Schema.TaggedStruct("Taken", { number: Schema.Int, sectioned: Schema.Boolean, runs: RunOrdinal }),
8
+ Schema.TaggedStruct("Replied", { number: Schema.Int, outcome: TurnOutcomeKind, held: Schema.Array(LogEntry) })
9
+ ]).pipe(Schema.toTaggedUnion("_tag")), ReplyStep = Schema.Union([
10
+ Schema.TaggedStruct("Record", { number: Schema.Int }),
11
+ Schema.TaggedStruct("Hold", { held: Schema.Array(LogEntry) }),
12
+ Schema.TaggedStruct("Nothing", {})
13
+ ]).pipe(Schema.toTaggedUnion("_tag"));
@@ -0,0 +1,72 @@
1
+ import { Effect, Option } from "effect";
2
+ import { StepLoop, TurnEvents, TurnMemory, TurnPrompt, TurnTasks, TurnToolbox } from "@xandreed/core";
3
+ import type { RunResult, RunTools, StepRequest, TurnError, TurnPolicy, TurnRunOptions } from "@xandreed/core";
4
+ /**
5
+ * The turn services one run reads.
6
+ *
7
+ * @public
8
+ */
9
+ export type TurnRunServices = TurnMemory | TurnToolbox | TurnPrompt | TurnEvents | TurnTasks;
10
+ /** The tokens the active tools' descriptions and parameter schemas take in a request. */
11
+ export declare const schemaTokens: (tools: RunTools, active: ReadonlyArray<string>) => number;
12
+ /**
13
+ * The prompt-cache key of a conversation: `<prefix>:<conversation>`, none without a prefix.
14
+ *
15
+ * @public
16
+ */
17
+ export declare const cacheKeyOf: (prefix: string, conversation: string) => Option.Option<string>;
18
+ /**
19
+ * Prepare one run of the step loop over the turn's services, in this
20
+ * order: the run is started (`TurnMemory.startRun`: its ordinal is on the
21
+ * run's step contexts, request headers and step events, and its dispatch
22
+ * check reads the header of its own run and step, so each run of a turn
23
+ * rebuilds its own requests), the run's budget is checked (`turn.budget`
24
+ * unless it is an integer of at least 1), the policy's planned skills are
25
+ * activated, the turn-tier sections are recorded, and memory is maintained
26
+ * for the turn's start with the whole budget. Each step gives memory what the system prompt and
27
+ * the active tools' schemas leave of the budget, and fails with
28
+ * `context.budget` when they leave nothing. Everything
29
+ * where this runs (the policy's services, the turn's, a host layer's) is
30
+ * captured: the policy callbacks, the prompt sections and the tool handlers
31
+ * run with it, without the span current here (`replayableContext`), so
32
+ * their spans nest under the step that calls them. Trace content is the
33
+ * policy's `captureTraceContent`, else the options', else
34
+ * `CurrentTraceContent` here. An optional `ModelRequestHook` runs after each
35
+ * fresh policy decision, before the single combined StepContext, reserves,
36
+ * maintenance and durable header. Its accepted patch is saved as `header.hook`;
37
+ * media replanning and same-step overflow reuse the frozen effective controls
38
+ * without invoking it again. When a provider refuses a step's request over
39
+ * an image, `onMediaRejected` records an `OmitMedia` of the images that
40
+ * build sent, and the step's next plan, that one only, rebuilds the context
41
+ * with the same model choice, system prompt, directive and resolved model
42
+ * (no second `policy.model` or `policy.step` call, no second
43
+ * `StepContext`). Any other plan of a step calls the policy again. The
44
+ * request's `cacheKey` is the turn's (`options.cacheKey`), its `callPolicy`
45
+ * the `CurrentModelCallPolicy` where this runs, read once; each request
46
+ * header records both, and the dispatch check compares them with what the
47
+ * model call will read, `CurrentPromptCacheKey` and `CurrentModelCallPolicy`
48
+ * where the loop dispatches, so a loop that does not provide the request's
49
+ * `cacheKey` and `callPolicy` (`StepLoopReferences`) fails with
50
+ * `request.diverged` before the provider is called. Each accepted response
51
+ * hands the run's memory maintenance to `TurnMemory.deferAfterReply`: the
52
+ * turn runs it once its reply is final and sealed (`TurnMemory.afterReply`,
53
+ * from `finishTurn`), on the run's last accepted input, so nothing it meets
54
+ * can cost the reply. The run's start (`turn-start`) is its safety net,
55
+ * calibrated by the last stored selected response (`acceptedBefore`): what
56
+ * a cut or never sealed maintenance left is maintained there. A step's
57
+ * ceiling is the run's input ceiling, lowered to the resolved model's
58
+ * catalog window less its output cap (the call policy's `maxOutputTokens`,
59
+ * else the catalog's) when a `ModelCatalog` knows that window.
60
+ *
61
+ * @public
62
+ */
63
+ export declare const stepRequestOf: <P = never>(policy: TurnPolicy<P>, options?: TurnRunOptions | undefined) => Effect.Effect<StepRequest, TurnError, TurnRunServices | P>;
64
+ /**
65
+ * One run of the turn: yield first when waiting; otherwise `stepRequestOf`,
66
+ * then the StepLoop. Nothing runs after the loop returns: its result goes
67
+ * straight back to the host, and the run's maintenance waits for the turn's
68
+ * sealed reply (`TurnMemory.afterReply`).
69
+ *
70
+ * @public
71
+ */
72
+ export declare const runTurnLoop: <P = never>(policy: TurnPolicy<P>, options?: TurnRunOptions) => Effect.Effect<RunResult, TurnError, P | TurnRunServices | StepLoop>;