effect-assistant 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/Assistant.d.ts +74 -28
- package/dist/Assistant.d.ts.map +1 -1
- package/dist/Assistant.js +11 -4
- package/dist/Assistant.js.map +1 -1
- package/dist/AssistantActivity.d.ts +10 -16
- package/dist/AssistantActivity.d.ts.map +1 -1
- package/dist/AssistantActivity.js +11 -4
- package/dist/AssistantActivity.js.map +1 -1
- package/dist/AssistantEngine.d.ts +39 -1
- package/dist/AssistantEngine.d.ts.map +1 -1
- package/dist/AssistantEngine.js +81 -28
- package/dist/AssistantEngine.js.map +1 -1
- package/dist/AssistantEvent.d.ts +52 -70
- package/dist/AssistantEvent.d.ts.map +1 -1
- package/dist/AssistantEvent.js +28 -57
- package/dist/AssistantEvent.js.map +1 -1
- package/dist/AssistantLoop.d.ts +7 -5
- package/dist/AssistantLoop.d.ts.map +1 -1
- package/dist/AssistantLoop.js +6 -3
- package/dist/AssistantLoop.js.map +1 -1
- package/dist/Block.js.map +1 -1
- package/dist/BlockKit.d.ts +14 -18
- package/dist/BlockKit.d.ts.map +1 -1
- package/dist/BlockKit.js +4 -7
- package/dist/BlockKit.js.map +1 -1
- package/dist/ChatLog.js +1 -1
- package/dist/Compaction.d.ts +8 -4
- package/dist/Compaction.d.ts.map +1 -1
- package/dist/Compaction.js +12 -15
- package/dist/Compaction.js.map +1 -1
- package/dist/CurrentChat.d.ts +2 -1
- package/dist/CurrentChat.d.ts.map +1 -1
- package/dist/CurrentChat.js.map +1 -1
- package/dist/Instructions.js +1 -1
- package/dist/Skill.d.ts +33 -0
- package/dist/Skill.d.ts.map +1 -1
- package/dist/Skill.js +27 -1
- package/dist/Skill.js.map +1 -1
- package/dist/Specialist.d.ts +4 -1
- package/dist/Specialist.d.ts.map +1 -1
- package/dist/Specialist.js.map +1 -1
- package/dist/Timeline.d.ts +482 -0
- package/dist/Timeline.d.ts.map +1 -0
- package/dist/Timeline.js +572 -0
- package/dist/Timeline.js.map +1 -0
- package/dist/ToolDiscovery.d.ts +4 -5
- package/dist/ToolDiscovery.d.ts.map +1 -1
- package/dist/ToolDiscovery.js +5 -4
- package/dist/ToolDiscovery.js.map +1 -1
- package/dist/ToolFailure.d.ts +1 -1
- package/dist/ToolFailure.js +1 -1
- package/dist/ToolFailure.js.map +1 -1
- package/dist/index.d.ts +2 -5
- package/dist/index.js +4 -7
- package/dist/internal/chat.js +11 -37
- package/dist/internal/chat.js.map +1 -1
- package/dist/internal/events.d.ts +15 -16
- package/dist/internal/events.d.ts.map +1 -1
- package/dist/internal/events.js +29 -28
- package/dist/internal/events.js.map +1 -1
- package/dist/internal/history.js +26 -58
- package/dist/internal/history.js.map +1 -1
- package/dist/internal/input.js +7 -0
- package/dist/internal/input.js.map +1 -0
- package/dist/internal/loop.d.ts +2 -2
- package/dist/internal/loop.d.ts.map +1 -1
- package/dist/internal/loop.js +21 -56
- package/dist/internal/loop.js.map +1 -1
- package/dist/internal/skills.js +6 -1
- package/dist/internal/skills.js.map +1 -1
- package/dist/internal/specialists.js +7 -7
- package/dist/internal/specialists.js.map +1 -1
- package/dist/internal/toolkit.d.ts +6 -20
- package/dist/internal/toolkit.d.ts.map +1 -1
- package/dist/internal/toolkit.js +10 -31
- package/dist/internal/toolkit.js.map +1 -1
- package/dist/internal/tools.js +2 -21
- package/dist/internal/tools.js.map +1 -1
- package/dist/internal/turns.d.ts.map +1 -1
- package/dist/internal/turns.js +24 -43
- package/dist/internal/turns.js.map +1 -1
- package/package.json +3 -2
- package/src/Assistant.ts +75 -29
- package/src/AssistantActivity.ts +11 -18
- package/src/AssistantEngine.ts +110 -43
- package/src/AssistantEvent.ts +46 -74
- package/src/AssistantLoop.ts +7 -5
- package/src/Block.ts +1 -1
- package/src/BlockKit.ts +18 -31
- package/src/Compaction.ts +8 -21
- package/src/CurrentChat.ts +2 -1
- package/src/Skill.ts +34 -1
- package/src/Specialist.ts +4 -1
- package/src/Timeline.ts +861 -0
- package/src/ToolDiscovery.ts +5 -13
- package/src/ToolFailure.ts +1 -1
- package/src/index.ts +5 -20
- package/src/internal/chat.ts +8 -57
- package/src/internal/events.ts +43 -43
- package/src/internal/history.ts +36 -101
- package/src/internal/input.ts +3 -0
- package/src/internal/loop.ts +31 -101
- package/src/internal/skills.ts +11 -0
- package/src/internal/specialists.ts +6 -9
- package/src/internal/toolkit.ts +17 -60
- package/src/internal/tools.ts +2 -53
- package/src/internal/turns.ts +37 -79
- package/dist/AppEvent.d.ts +0 -111
- package/dist/AppEvent.d.ts.map +0 -1
- package/dist/AppEvent.js +0 -71
- package/dist/AppEvent.js.map +0 -1
- package/dist/ChatView.d.ts +0 -459
- package/dist/ChatView.d.ts.map +0 -1
- package/dist/ChatView.js +0 -496
- package/dist/ChatView.js.map +0 -1
- package/dist/Decision.d.ts +0 -145
- package/dist/Decision.d.ts.map +0 -1
- package/dist/Decision.js +0 -178
- package/dist/Decision.js.map +0 -1
- package/dist/DecisionId.d.ts +0 -37
- package/dist/DecisionId.d.ts.map +0 -1
- package/dist/DecisionId.js +0 -44
- package/dist/DecisionId.js.map +0 -1
- package/dist/internal/decisions.js +0 -66
- package/dist/internal/decisions.js.map +0 -1
- package/src/AppEvent.ts +0 -134
- package/src/ChatView.ts +0 -658
- package/src/Decision.ts +0 -241
- package/src/DecisionId.ts +0 -46
- package/src/internal/decisions.ts +0 -131
package/src/internal/turns.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type * as LanguageModel from "effect/ai/LanguageModel"
|
|
2
2
|
import type * as Tool from "effect/ai/Tool"
|
|
3
|
-
import type * as Prompt from "effect/ai/Prompt"
|
|
4
3
|
import * as Cause from "effect/Cause"
|
|
5
4
|
import * as Context from "effect/Context"
|
|
6
5
|
import * as Effect from "effect/Effect"
|
|
@@ -8,6 +7,7 @@ import * as Exit from "effect/Exit"
|
|
|
8
7
|
import { identity } from "effect/Function"
|
|
9
8
|
import * as Option from "effect/Option"
|
|
10
9
|
import * as Predicate from "effect/Predicate"
|
|
10
|
+
import * as Ref from "effect/Ref"
|
|
11
11
|
import * as Schema from "effect/Schema"
|
|
12
12
|
import type * as Scope from "effect/Scope"
|
|
13
13
|
import * as Stream from "effect/Stream"
|
|
@@ -18,12 +18,10 @@ import type * as AssistantLoop from "../AssistantLoop.ts"
|
|
|
18
18
|
import * as Loop from "./loop.ts"
|
|
19
19
|
import type * as BlockKit from "../BlockKit.ts"
|
|
20
20
|
import type { CurrentChat } from "../CurrentChat.ts"
|
|
21
|
-
import * as Decision from "../Decision.ts"
|
|
22
21
|
import * as Instructions from "../Instructions.ts"
|
|
23
22
|
import * as Skill from "../Skill.ts"
|
|
24
23
|
import * as Skills from "./skills.ts"
|
|
25
24
|
import type * as Specialist from "../Specialist.ts"
|
|
26
|
-
import * as Decisions from "./decisions.ts"
|
|
27
25
|
import * as AppEvents from "./events.ts"
|
|
28
26
|
import * as History from "./history.ts"
|
|
29
27
|
import { mapText } from "./instructions.ts"
|
|
@@ -87,12 +85,6 @@ export const register = Effect.fnUntraced(function* (
|
|
|
87
85
|
) {
|
|
88
86
|
const model = yield* Effect.context<LanguageModel.LanguageModel>()
|
|
89
87
|
|
|
90
|
-
const decisionBlock = definition.blocks?.byKind.get(Decision.kind)
|
|
91
|
-
|
|
92
|
-
if (decisionBlock !== undefined && decisionBlock !== Decision.block) {
|
|
93
|
-
return yield* Effect.die(`The ${Decision.kind} block kind is the library's: use Decision.block.`)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
88
|
const specialists = yield* Effect.forEach(
|
|
97
89
|
definition.specialists,
|
|
98
90
|
Effect.fnUntraced(function* (specialist) {
|
|
@@ -135,34 +127,6 @@ const failureMessage = (cause: Cause.Cause<unknown>): string =>
|
|
|
135
127
|
|
|
136
128
|
const lastSeq = (entries: ReadonlyArray<AssistantEvent.AnyEntry>, otherwise: number) => entries.at(-1)?.seq ?? otherwise
|
|
137
129
|
|
|
138
|
-
const toHistory = (
|
|
139
|
-
viewed: ReadonlyArray<Assistant.Entry<any> | Prompt.Message>,
|
|
140
|
-
app: AppEvents.AppEvents
|
|
141
|
-
): ReadonlyArray<Prompt.Message> => {
|
|
142
|
-
const out: Array<Prompt.Message> = []
|
|
143
|
-
let run: Array<AssistantEvent.AnyEntry> = []
|
|
144
|
-
|
|
145
|
-
const flush = () => {
|
|
146
|
-
out.push(...History.fromEntries(run, (event) => AppEvents.read(app, event)))
|
|
147
|
-
run = []
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
for (const item of viewed) {
|
|
151
|
-
if (isEntry(item)) run.push(item)
|
|
152
|
-
else {
|
|
153
|
-
flush()
|
|
154
|
-
out.push(item)
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
flush()
|
|
159
|
-
|
|
160
|
-
return out
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const isEntry = (item: Assistant.Entry<any> | Prompt.Message): item is Assistant.Entry<any> =>
|
|
164
|
-
Predicate.hasProperty(item, "seq")
|
|
165
|
-
|
|
166
130
|
// The handler's stream can end between a step's output and its tools, or while they run. An interrupted turn (a
|
|
167
131
|
// shutdown) leaves its calls open instead: the next turn runs them again.
|
|
168
132
|
const closeOpenCalls = Effect.fnUntraced(function* (chat: Writer, startSeq: number) {
|
|
@@ -172,10 +136,7 @@ const closeOpenCalls = Effect.fnUntraced(function* (chat: Writer, startSeq: numb
|
|
|
172
136
|
entries.flatMap(({ event }) => (Predicate.isTagged(event, "ToolStarted") ? [event.callId] : []))
|
|
173
137
|
)
|
|
174
138
|
|
|
175
|
-
|
|
176
|
-
const all = yield* chat.entries
|
|
177
|
-
const approved = Decisions.approvedCalls(all).filter((call) => started.has(call.id))
|
|
178
|
-
const open = [...History.unansweredCalls(History.fromEntries(entries, () => undefined)), ...approved]
|
|
139
|
+
const open = History.unansweredCalls(History.fromEntries(entries))
|
|
179
140
|
|
|
180
141
|
if (open.length === 0) return
|
|
181
142
|
|
|
@@ -207,13 +168,13 @@ const handledThrough = (entries: ReadonlyArray<AssistantEvent.AnyEntry>, startSe
|
|
|
207
168
|
startSeq
|
|
208
169
|
)
|
|
209
170
|
|
|
210
|
-
//
|
|
211
|
-
// next turn, which replies.
|
|
212
|
-
const finishTurn = Effect.fnUntraced(function* (chat: Writer, read: number,
|
|
171
|
+
// A turn that ran the loop fails visibly when the user's latest input got no reply; an input that arrived after what
|
|
172
|
+
// its model read gets the next turn, which replies. A handler that ended without the loop decided that itself.
|
|
173
|
+
const finishTurn = Effect.fnUntraced(function* (chat: Writer, read: number, ranLoop: boolean) {
|
|
213
174
|
const entries = yield* chat.entries
|
|
214
175
|
|
|
215
176
|
const end =
|
|
216
|
-
History.owesReply(entries, read) && !History.unreadAfter(entries, read
|
|
177
|
+
ranLoop && History.owesReply(entries, read) && !History.unreadAfter(entries, read)
|
|
217
178
|
? AssistantEvent.TurnFailed.make({ throughSeq: read, message: silentTurnMessage })
|
|
218
179
|
: AssistantEvent.TurnCompleted.make({ throughSeq: read })
|
|
219
180
|
|
|
@@ -233,11 +194,15 @@ const makeTurnApi = (
|
|
|
233
194
|
registration: Registration,
|
|
234
195
|
chat: Writer,
|
|
235
196
|
startSeq: number,
|
|
236
|
-
checkOpen: Effect.Effect<void
|
|
197
|
+
checkOpen: Effect.Effect<void>,
|
|
198
|
+
ranLoop: Ref.Ref<boolean>
|
|
237
199
|
): Assistant.Turn<any> => {
|
|
238
200
|
const { definition, builtins } = registration
|
|
239
201
|
const { app } = definition
|
|
240
202
|
|
|
203
|
+
const running = <A, E, R>(stream: Stream.Stream<A, E, R>) =>
|
|
204
|
+
Stream.unwrap(Ref.set(ranLoop, true).pipe(Effect.as(stream)))
|
|
205
|
+
|
|
241
206
|
// With how far into the chat it goes: the step records it on the model's output.
|
|
242
207
|
// Read before every model call: a chat the app deleted meanwhile stops here.
|
|
243
208
|
const history = Effect.fnUntraced(function* (view: Assistant.HistoryView<any> = identity) {
|
|
@@ -246,7 +211,7 @@ const makeTurnApi = (
|
|
|
246
211
|
const all = yield* chat.entries
|
|
247
212
|
|
|
248
213
|
const read: AssistantLoop.ChatHistory = {
|
|
249
|
-
messages:
|
|
214
|
+
messages: History.fromEntries(view(AppEvents.decodeEntries(app, all))),
|
|
250
215
|
throughSeq: lastSeq(all, startSeq)
|
|
251
216
|
}
|
|
252
217
|
|
|
@@ -269,7 +234,7 @@ const makeTurnApi = (
|
|
|
269
234
|
const through = handledThrough(all, startSeq)
|
|
270
235
|
|
|
271
236
|
// Something arrived after what the loop's model read: the next turn reads it with the full loop, and replies.
|
|
272
|
-
if (History.unreadAfter(all, through
|
|
237
|
+
if (History.unreadAfter(all, through)) return Stream.empty
|
|
273
238
|
|
|
274
239
|
const owed = History.owesReply(all, through)
|
|
275
240
|
const undelivered = !owed && History.owesDelivery(all, through)
|
|
@@ -293,7 +258,7 @@ const makeTurnApi = (
|
|
|
293
258
|
|
|
294
259
|
return {
|
|
295
260
|
messages: [
|
|
296
|
-
...
|
|
261
|
+
...History.fromEntries(options.view(AppEvents.decodeEntries(app, entries))),
|
|
297
262
|
History.userText(nudge)
|
|
298
263
|
],
|
|
299
264
|
throughSeq: lastSeq(entries, startSeq)
|
|
@@ -306,22 +271,22 @@ const makeTurnApi = (
|
|
|
306
271
|
)
|
|
307
272
|
|
|
308
273
|
const replyIfOwed = (options: Assistant.ReplyOptions) =>
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
274
|
+
running(
|
|
275
|
+
replyPass({
|
|
276
|
+
instructions: instructions(options.instructions),
|
|
277
|
+
toolkit: builtins,
|
|
278
|
+
view: identity,
|
|
279
|
+
nudge: options.nudge
|
|
280
|
+
})
|
|
281
|
+
)
|
|
315
282
|
|
|
316
283
|
const prepare = <T extends Record<string, Tool.Any>, RS>(options: Assistant.LoopOptions<T, RS, any>) => {
|
|
317
|
-
const
|
|
284
|
+
const own = Toolkits.fromToolkitOrEmpty(options.toolkit)
|
|
285
|
+
const skills = Skills.available(options.skills ?? [], [...builtins.definitions, ...own.definitions])
|
|
318
286
|
|
|
319
287
|
return {
|
|
320
288
|
system: mapText(instructions(options.instructions), (text) => Skill.withCatalog(text, skills)),
|
|
321
|
-
toolkit: Toolkits.merge(
|
|
322
|
-
Toolkits.merge(builtins, Skills.toTools(skills)),
|
|
323
|
-
Toolkits.fromToolkitOrEmpty(options.toolkit)
|
|
324
|
-
),
|
|
289
|
+
toolkit: Toolkits.merge(Toolkits.merge(builtins, Skills.toTools(skills)), own),
|
|
325
290
|
view: options.history ?? identity
|
|
326
291
|
}
|
|
327
292
|
}
|
|
@@ -335,25 +300,17 @@ const makeTurnApi = (
|
|
|
335
300
|
const { system, toolkit, view } = prepare(options)
|
|
336
301
|
const twice = Toolkits.duplicateNames(toolkit)
|
|
337
302
|
|
|
338
|
-
const deciding = toolkit.definitions.filter(
|
|
339
|
-
(tool) => tool.needsApproval !== undefined && tool.needsApproval !== false
|
|
340
|
-
)
|
|
341
|
-
|
|
342
303
|
const loop =
|
|
343
304
|
twice.length > 0
|
|
344
305
|
? Stream.die(`Tool names used twice, like one named after a built-in: ${twice.join(", ")}`)
|
|
345
|
-
:
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
)
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
maxSteps: options.maxSteps ?? 16
|
|
354
|
-
})
|
|
355
|
-
|
|
356
|
-
return Stream.concat(loop, replyPass({ instructions: system, toolkit, view, nudge: options.replyNudge }))
|
|
306
|
+
: Loop.run({
|
|
307
|
+
instructions: system,
|
|
308
|
+
toolkit,
|
|
309
|
+
history: history(view),
|
|
310
|
+
maxSteps: options.maxSteps ?? 16
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
return running(Stream.concat(loop, replyPass({ instructions: system, toolkit, view, nudge: options.replyNudge })))
|
|
357
314
|
}
|
|
358
315
|
}
|
|
359
316
|
}
|
|
@@ -372,7 +329,7 @@ export const run = Effect.fnUntraced(
|
|
|
372
329
|
const { chat } = options
|
|
373
330
|
const before = yield* chat.entries
|
|
374
331
|
|
|
375
|
-
yield* Telemetry.agentInput(History.unhandledInputs(before
|
|
332
|
+
yield* Telemetry.agentInput(History.unhandledInputs(before))
|
|
376
333
|
|
|
377
334
|
const assistant = options.registration.definition.name
|
|
378
335
|
const traceId = yield* Telemetry.currentTraceId
|
|
@@ -387,7 +344,8 @@ export const run = Effect.fnUntraced(
|
|
|
387
344
|
])
|
|
388
345
|
|
|
389
346
|
const startSeq = lastSeq(started, 0)
|
|
390
|
-
const
|
|
347
|
+
const ranLoop = yield* Ref.make(false)
|
|
348
|
+
const turn = makeTurnApi(options.registration, chat, startSeq, options.checkOpen, ranLoop)
|
|
391
349
|
|
|
392
350
|
const record = (event: AssistantLoop.Event) => chat.append([event])
|
|
393
351
|
|
|
@@ -404,7 +362,7 @@ export const run = Effect.fnUntraced(
|
|
|
404
362
|
onSuccess: Effect.fnUntraced(function* () {
|
|
405
363
|
const all = yield* chat.entries
|
|
406
364
|
|
|
407
|
-
yield* finishTurn(chat, handledThrough(all, startSeq),
|
|
365
|
+
yield* finishTurn(chat, handledThrough(all, startSeq), yield* Ref.get(ranLoop))
|
|
408
366
|
}),
|
|
409
367
|
onFailure: (cause) => failTurn(chat, cause)
|
|
410
368
|
})
|
package/dist/AppEvent.d.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import * as SchemaAST from "effect/SchemaAST";
|
|
2
|
-
import * as Schema from "effect/Schema";
|
|
3
|
-
declare namespace AppEvent_d_exports {
|
|
4
|
-
export { Any, AppEvent, EventSchema, Render, Type, make };
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Schema for one of the application's own events.
|
|
8
|
-
*
|
|
9
|
-
* It is a tagged struct or class (`Schema.TaggedStruct`, `Schema.TaggedClass`) that needs no
|
|
10
|
-
* services.
|
|
11
|
-
*
|
|
12
|
-
* @category models
|
|
13
|
-
* @since 0.1.0
|
|
14
|
-
*/
|
|
15
|
-
export type EventSchema = Schema.Codec<{
|
|
16
|
-
readonly _tag: string;
|
|
17
|
-
}, {
|
|
18
|
-
readonly _tag: string;
|
|
19
|
-
}> & {
|
|
20
|
-
readonly fields: {
|
|
21
|
-
readonly _tag: {
|
|
22
|
-
readonly ast: SchemaAST.AST;
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* Describes how the model reads an event.
|
|
28
|
-
*
|
|
29
|
-
* `"json"` shows the event's tag and fields as JSON. A function shows the text it returns for the
|
|
30
|
-
* event.
|
|
31
|
-
*
|
|
32
|
-
* @category models
|
|
33
|
-
* @since 0.1.0
|
|
34
|
-
*/
|
|
35
|
-
export type Render<A> = "json" | ((event: A) => string);
|
|
36
|
-
/**
|
|
37
|
-
* Represents one of the application's events, registered with an assistant.
|
|
38
|
-
*
|
|
39
|
-
* It holds the event's schema and tag, whether storing it wakes a turn, and how the model reads
|
|
40
|
-
* it. A `render` of `undefined` means the model doesn't read it.
|
|
41
|
-
*
|
|
42
|
-
* @category models
|
|
43
|
-
* @since 0.1.0
|
|
44
|
-
*/
|
|
45
|
-
export interface AppEvent<S extends EventSchema = EventSchema> {
|
|
46
|
-
readonly schema: S;
|
|
47
|
-
readonly tag: string;
|
|
48
|
-
readonly wakes: boolean;
|
|
49
|
-
readonly render: Render<S["Type"]> | undefined;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Represents any registered event, for generic constraints.
|
|
53
|
-
*
|
|
54
|
-
* @category utility types
|
|
55
|
-
* @since 0.1.0
|
|
56
|
-
*/
|
|
57
|
-
export type Any = AppEvent<any>;
|
|
58
|
-
/**
|
|
59
|
-
* Extracts the type of a registered event's values.
|
|
60
|
-
*
|
|
61
|
-
* @category utility types
|
|
62
|
-
* @since 0.1.0
|
|
63
|
-
*/
|
|
64
|
-
export type Type<E extends Any> = E["schema"]["Type"];
|
|
65
|
-
/**
|
|
66
|
-
* Registers one of the application's events with an assistant.
|
|
67
|
-
*
|
|
68
|
-
* **Details**
|
|
69
|
-
*
|
|
70
|
-
* Storing the event wakes a turn only when `wakes` is `true`; it defaults to `false`. `render`
|
|
71
|
-
* defaults to `"json"` for an event that wakes a turn. An event that doesn't wake a turn and has
|
|
72
|
-
* no `render` isn't read by the model.
|
|
73
|
-
*
|
|
74
|
-
* The schema must be a tagged struct or class whose `_tag` is a string literal; `make` throws
|
|
75
|
-
* otherwise.
|
|
76
|
-
*
|
|
77
|
-
* **Example** (Registering an event that wakes a turn)
|
|
78
|
-
*
|
|
79
|
-
* ```ts
|
|
80
|
-
* import { AppEvent, Assistant, InputId } from "effect-assistant"
|
|
81
|
-
* import * as Schema from "effect/Schema"
|
|
82
|
-
*
|
|
83
|
-
* class OrderShipped extends Schema.TaggedClass<OrderShipped>()("OrderShipped", {
|
|
84
|
-
* id: InputId.InputId,
|
|
85
|
-
* orderId: Schema.String,
|
|
86
|
-
* carrier: Schema.String
|
|
87
|
-
* }) {}
|
|
88
|
-
*
|
|
89
|
-
* export const MyAssistant = Assistant.make("my-assistant", {
|
|
90
|
-
* events: [
|
|
91
|
-
* AppEvent.make(OrderShipped, {
|
|
92
|
-
* wakes: true,
|
|
93
|
-
* render: (shipped) =>
|
|
94
|
-
* `Order ${shipped.orderId} shipped with ${shipped.carrier}. Tell the user if it matters.`
|
|
95
|
-
* })
|
|
96
|
-
* ]
|
|
97
|
-
* })
|
|
98
|
-
* ```
|
|
99
|
-
*
|
|
100
|
-
* @category constructors
|
|
101
|
-
* @since 0.1.0
|
|
102
|
-
*/
|
|
103
|
-
export declare const make: <S extends EventSchema>(schema: S, options?: {
|
|
104
|
-
/** Whether storing it starts a turn, like a user's message. Default false. */
|
|
105
|
-
readonly wakes?: boolean | undefined;
|
|
106
|
-
/** How the model reads it in its history. */
|
|
107
|
-
readonly render?: Render<S["Type"]> | undefined;
|
|
108
|
-
}) => AppEvent<S>;
|
|
109
|
-
//#endregion
|
|
110
|
-
export { AppEvent_d_exports };
|
|
111
|
-
//# sourceMappingURL=AppEvent.d.ts.map
|
package/dist/AppEvent.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AppEvent.d.ts","names":[],"sources":["../src/AppEvent.ts"],"mappings":";;;;;;;;;;;;;;YAuBY,cAAc,OAAO;WAAiB;;WAA2B;;WAClE;aAAmB;eAAiB,KAAK,UAAU;;;;;;;;;;;;;YAYlD,OAAO,gBAAgB,OAAO;;;;;;;;;;iBAWzB,SAAS,UAAU,cAAc;WACvC,QAAQ;WACR;WACA;WACA,QAAQ,OAAO;;;;;;;;YASd,MAAM;;;;;;;YAQN,KAAK,UAAU,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAgDrB,OAAQ,UAAU,aAAW,QAChC,GAAC;;WAGE;;WAEA,SAAS,OAAO;MAE1B,SAAS"}
|
package/dist/AppEvent.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
-
import * as Predicate from "effect/Predicate";
|
|
3
|
-
import * as SchemaAST from "effect/SchemaAST";
|
|
4
|
-
//#region src/AppEvent.ts
|
|
5
|
-
/**
|
|
6
|
-
* Registers an application's own events with an assistant.
|
|
7
|
-
*
|
|
8
|
-
* An app event is a tagged schema for something the application reports into a chat, such as a
|
|
9
|
-
* workflow's progress, a webhook, a summary for compaction, or the draft the user opened.
|
|
10
|
-
* {@link make} registers one with two choices: whether storing it wakes a turn (`wakes`), and
|
|
11
|
-
* how the model reads it (`render`).
|
|
12
|
-
*
|
|
13
|
-
* @since 0.1.0
|
|
14
|
-
*/
|
|
15
|
-
var AppEvent_exports = /* @__PURE__ */ __exportAll({ make: () => make });
|
|
16
|
-
const tagOf = (schema) => {
|
|
17
|
-
const ast = schema.fields._tag.ast;
|
|
18
|
-
if (SchemaAST.isLiteral(ast) && Predicate.isString(ast.literal)) return ast.literal;
|
|
19
|
-
throw new Error("An app event is a tagged struct or class.");
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Registers one of the application's events with an assistant.
|
|
23
|
-
*
|
|
24
|
-
* **Details**
|
|
25
|
-
*
|
|
26
|
-
* Storing the event wakes a turn only when `wakes` is `true`; it defaults to `false`. `render`
|
|
27
|
-
* defaults to `"json"` for an event that wakes a turn. An event that doesn't wake a turn and has
|
|
28
|
-
* no `render` isn't read by the model.
|
|
29
|
-
*
|
|
30
|
-
* The schema must be a tagged struct or class whose `_tag` is a string literal; `make` throws
|
|
31
|
-
* otherwise.
|
|
32
|
-
*
|
|
33
|
-
* **Example** (Registering an event that wakes a turn)
|
|
34
|
-
*
|
|
35
|
-
* ```ts
|
|
36
|
-
* import { AppEvent, Assistant, InputId } from "effect-assistant"
|
|
37
|
-
* import * as Schema from "effect/Schema"
|
|
38
|
-
*
|
|
39
|
-
* class OrderShipped extends Schema.TaggedClass<OrderShipped>()("OrderShipped", {
|
|
40
|
-
* id: InputId.InputId,
|
|
41
|
-
* orderId: Schema.String,
|
|
42
|
-
* carrier: Schema.String
|
|
43
|
-
* }) {}
|
|
44
|
-
*
|
|
45
|
-
* export const MyAssistant = Assistant.make("my-assistant", {
|
|
46
|
-
* events: [
|
|
47
|
-
* AppEvent.make(OrderShipped, {
|
|
48
|
-
* wakes: true,
|
|
49
|
-
* render: (shipped) =>
|
|
50
|
-
* `Order ${shipped.orderId} shipped with ${shipped.carrier}. Tell the user if it matters.`
|
|
51
|
-
* })
|
|
52
|
-
* ]
|
|
53
|
-
* })
|
|
54
|
-
* ```
|
|
55
|
-
*
|
|
56
|
-
* @category constructors
|
|
57
|
-
* @since 0.1.0
|
|
58
|
-
*/
|
|
59
|
-
const make = (schema, options) => {
|
|
60
|
-
const wakes = options?.wakes ?? false;
|
|
61
|
-
return {
|
|
62
|
-
schema,
|
|
63
|
-
tag: tagOf(schema),
|
|
64
|
-
wakes,
|
|
65
|
-
render: options?.render ?? (wakes ? "json" : void 0)
|
|
66
|
-
};
|
|
67
|
-
};
|
|
68
|
-
//#endregion
|
|
69
|
-
export { AppEvent_exports, make };
|
|
70
|
-
|
|
71
|
-
//# sourceMappingURL=AppEvent.js.map
|
package/dist/AppEvent.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AppEvent.js","names":[],"sources":["../src/AppEvent.ts"],"sourcesContent":["/**\n * Registers an application's own events with an assistant.\n *\n * An app event is a tagged schema for something the application reports into a chat, such as a\n * workflow's progress, a webhook, a summary for compaction, or the draft the user opened.\n * {@link make} registers one with two choices: whether storing it wakes a turn (`wakes`), and\n * how the model reads it (`render`).\n *\n * @since 0.1.0\n */\nimport * as Predicate from \"effect/Predicate\"\nimport type * as Schema from \"effect/Schema\"\nimport * as SchemaAST from \"effect/SchemaAST\"\n\n/**\n * Schema for one of the application's own events.\n *\n * It is a tagged struct or class (`Schema.TaggedStruct`, `Schema.TaggedClass`) that needs no\n * services.\n *\n * @category models\n * @since 0.1.0\n */\nexport type EventSchema = Schema.Codec<{ readonly _tag: string }, { readonly _tag: string }> & {\n readonly fields: { readonly _tag: { readonly ast: SchemaAST.AST } }\n}\n\n/**\n * Describes how the model reads an event.\n *\n * `\"json\"` shows the event's tag and fields as JSON. A function shows the text it returns for the\n * event.\n *\n * @category models\n * @since 0.1.0\n */\nexport type Render<A> = \"json\" | ((event: A) => string)\n\n/**\n * Represents one of the application's events, registered with an assistant.\n *\n * It holds the event's schema and tag, whether storing it wakes a turn, and how the model reads\n * it. A `render` of `undefined` means the model doesn't read it.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface AppEvent<S extends EventSchema = EventSchema> {\n readonly schema: S\n readonly tag: string\n readonly wakes: boolean\n readonly render: Render<S[\"Type\"]> | undefined\n}\n\n/**\n * Represents any registered event, for generic constraints.\n *\n * @category utility types\n * @since 0.1.0\n */\nexport type Any = AppEvent<any>\n\n/**\n * Extracts the type of a registered event's values.\n *\n * @category utility types\n * @since 0.1.0\n */\nexport type Type<E extends Any> = E[\"schema\"][\"Type\"]\n\nconst tagOf = (schema: EventSchema): string => {\n const ast = schema.fields._tag.ast\n\n if (SchemaAST.isLiteral(ast) && Predicate.isString(ast.literal)) return ast.literal\n\n throw new Error(\"An app event is a tagged struct or class.\")\n}\n\n/**\n * Registers one of the application's events with an assistant.\n *\n * **Details**\n *\n * Storing the event wakes a turn only when `wakes` is `true`; it defaults to `false`. `render`\n * defaults to `\"json\"` for an event that wakes a turn. An event that doesn't wake a turn and has\n * no `render` isn't read by the model.\n *\n * The schema must be a tagged struct or class whose `_tag` is a string literal; `make` throws\n * otherwise.\n *\n * **Example** (Registering an event that wakes a turn)\n *\n * ```ts\n * import { AppEvent, Assistant, InputId } from \"effect-assistant\"\n * import * as Schema from \"effect/Schema\"\n *\n * class OrderShipped extends Schema.TaggedClass<OrderShipped>()(\"OrderShipped\", {\n * id: InputId.InputId,\n * orderId: Schema.String,\n * carrier: Schema.String\n * }) {}\n *\n * export const MyAssistant = Assistant.make(\"my-assistant\", {\n * events: [\n * AppEvent.make(OrderShipped, {\n * wakes: true,\n * render: (shipped) =>\n * `Order ${shipped.orderId} shipped with ${shipped.carrier}. Tell the user if it matters.`\n * })\n * ]\n * })\n * ```\n *\n * @category constructors\n * @since 0.1.0\n */\nexport const make = <S extends EventSchema>(\n schema: S,\n options?: {\n /** Whether storing it starts a turn, like a user's message. Default false. */\n readonly wakes?: boolean | undefined\n /** How the model reads it in its history. */\n readonly render?: Render<S[\"Type\"]> | undefined\n }\n): AppEvent<S> => {\n const wakes = options?.wakes ?? false\n\n return {\n schema,\n tag: tagOf(schema),\n wakes,\n render: options?.render ?? (wakes ? \"json\" : undefined)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAsEA,MAAM,SAAS,WAAgC;CAC7C,MAAM,MAAM,OAAO,OAAO,KAAK;CAE/B,IAAI,UAAU,UAAU,GAAG,KAAK,UAAU,SAAS,IAAI,OAAO,GAAG,OAAO,IAAI;CAE5E,MAAM,IAAI,MAAM,2CAA2C;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,MAAa,QACX,QACA,YAMgB;CAChB,MAAM,QAAQ,SAAS,SAAS;CAEhC,OAAO;EACL;EACA,KAAK,MAAM,MAAM;EACjB;EACA,QAAQ,SAAS,WAAW,QAAQ,SAAS,KAAA;CAC/C;AACF"}
|