effect-assistant 0.2.0 → 0.4.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/dist/Assistant.d.ts +77 -37
- 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 +104 -11
- package/dist/AssistantEvent.d.ts.map +1 -1
- package/dist/AssistantEvent.js +88 -13
- package/dist/AssistantEvent.js.map +1 -1
- package/dist/AssistantLoop.d.ts +4 -2
- package/dist/AssistantLoop.d.ts.map +1 -1
- package/dist/AssistantLoop.js +4 -2
- package/dist/AssistantLoop.js.map +1 -1
- package/dist/BlockKit.d.ts +4 -4
- package/dist/BlockKit.js +1 -1
- package/dist/BlockKit.js.map +1 -1
- package/dist/ChatLog.js +1 -1
- package/dist/Compaction.d.ts +7 -3
- package/dist/Compaction.d.ts.map +1 -1
- package/dist/Compaction.js +19 -8
- 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 +86 -11
- package/dist/Skill.d.ts.map +1 -1
- package/dist/Skill.js +93 -18
- package/dist/Skill.js.map +1 -1
- package/dist/Specialist.d.ts +7 -7
- package/dist/Specialist.d.ts.map +1 -1
- package/dist/Specialist.js.map +1 -1
- package/dist/Timeline.d.ts +516 -0
- package/dist/Timeline.d.ts.map +1 -0
- package/dist/Timeline.js +631 -0
- package/dist/Timeline.js.map +1 -0
- package/dist/ToolApproval.d.ts +146 -0
- package/dist/ToolApproval.d.ts.map +1 -0
- package/dist/ToolApproval.js +201 -0
- package/dist/ToolApproval.js.map +1 -0
- package/dist/ToolDiscovery.d.ts +6 -4
- package/dist/ToolDiscovery.d.ts.map +1 -1
- package/dist/ToolDiscovery.js +5 -4
- package/dist/ToolDiscovery.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/internal/chat.js +9 -7
- 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 +53 -22
- 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 +10 -5
- package/dist/internal/loop.d.ts.map +1 -1
- package/dist/internal/loop.js +55 -22
- package/dist/internal/loop.js.map +1 -1
- package/dist/internal/specialists.js +10 -16
- package/dist/internal/specialists.js.map +1 -1
- package/dist/internal/toolkit.d.ts +5 -7
- package/dist/internal/toolkit.d.ts.map +1 -1
- package/dist/internal/toolkit.js +28 -18
- package/dist/internal/toolkit.js.map +1 -1
- package/dist/internal/tools.js +1 -1
- package/dist/internal/turns.d.ts.map +1 -1
- package/dist/internal/turns.js +35 -42
- package/dist/internal/turns.js.map +1 -1
- package/package.json +1 -1
- package/src/Assistant.ts +80 -40
- package/src/AssistantActivity.ts +11 -18
- package/src/AssistantEngine.ts +110 -43
- package/src/AssistantEvent.ts +106 -14
- package/src/AssistantLoop.ts +4 -2
- package/src/BlockKit.ts +6 -6
- package/src/Compaction.ts +25 -4
- package/src/CurrentChat.ts +2 -1
- package/src/Skill.ts +133 -23
- package/src/Specialist.ts +9 -9
- package/src/Timeline.ts +947 -0
- package/src/ToolApproval.ts +249 -0
- package/src/ToolDiscovery.ts +8 -3
- package/src/index.ts +10 -10
- package/src/internal/chat.ts +15 -5
- package/src/internal/events.ts +43 -43
- package/src/internal/history.ts +94 -32
- package/src/internal/input.ts +3 -0
- package/src/internal/loop.ts +120 -34
- package/src/internal/specialists.ts +7 -12
- package/src/internal/toolkit.ts +47 -30
- package/src/internal/turns.ts +52 -58
- 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 -408
- package/dist/ChatView.d.ts.map +0 -1
- package/dist/ChatView.js +0 -443
- package/dist/ChatView.js.map +0 -1
- package/dist/internal/skills.js +0 -28
- package/dist/internal/skills.js.map +0 -1
- package/src/AppEvent.ts +0 -134
- package/src/ChatView.ts +0 -587
- package/src/internal/skills.ts +0 -37
package/src/internal/turns.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type * as LanguageModel from "effect/ai/LanguageModel"
|
|
2
|
+
import * as Response from "effect/ai/Response"
|
|
2
3
|
import type * as Tool from "effect/ai/Tool"
|
|
3
|
-
import type * as Prompt from "effect/ai/Prompt"
|
|
4
4
|
import * as Cause from "effect/Cause"
|
|
5
5
|
import * as Context from "effect/Context"
|
|
6
6
|
import * as Effect from "effect/Effect"
|
|
@@ -8,6 +8,7 @@ import * as Exit from "effect/Exit"
|
|
|
8
8
|
import { identity } from "effect/Function"
|
|
9
9
|
import * as Option from "effect/Option"
|
|
10
10
|
import * as Predicate from "effect/Predicate"
|
|
11
|
+
import * as Ref from "effect/Ref"
|
|
11
12
|
import * as Schema from "effect/Schema"
|
|
12
13
|
import type * as Scope from "effect/Scope"
|
|
13
14
|
import * as Stream from "effect/Stream"
|
|
@@ -19,8 +20,7 @@ import * as Loop from "./loop.ts"
|
|
|
19
20
|
import type * as BlockKit from "../BlockKit.ts"
|
|
20
21
|
import type { CurrentChat } from "../CurrentChat.ts"
|
|
21
22
|
import * as Instructions from "../Instructions.ts"
|
|
22
|
-
import * as
|
|
23
|
-
import * as Skills from "./skills.ts"
|
|
23
|
+
import * as ToolApproval from "../ToolApproval.ts"
|
|
24
24
|
import type * as Specialist from "../Specialist.ts"
|
|
25
25
|
import * as AppEvents from "./events.ts"
|
|
26
26
|
import * as History from "./history.ts"
|
|
@@ -125,35 +125,22 @@ const failureMessage = (cause: Cause.Cause<unknown>): string =>
|
|
|
125
125
|
onSome: ({ _tag, raw }) => `${_tag ?? "Error"}: ${Predicate.isString(raw) ? raw : toJsonText(raw)}`
|
|
126
126
|
})
|
|
127
127
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
for (const item of viewed) {
|
|
143
|
-
if (isEntry(item)) run.push(item)
|
|
144
|
-
else {
|
|
145
|
-
flush()
|
|
146
|
-
out.push(item)
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
flush()
|
|
151
|
-
|
|
152
|
-
return out
|
|
153
|
-
}
|
|
128
|
+
// Approved, and not run yet: also one a crash cut off while it ran, which runs again with the same id.
|
|
129
|
+
const approvedCalls = (entries: ReadonlyArray<AssistantEvent.AnyEntry>): ReadonlyArray<AssistantEvent.ToolCallPart> =>
|
|
130
|
+
[...ToolApproval.fromEntries(entries).values()].flatMap(({ request, status, outcome }) =>
|
|
131
|
+
status === "approved" && outcome === undefined
|
|
132
|
+
? [
|
|
133
|
+
Response.makePart("tool-call", {
|
|
134
|
+
id: request.callId,
|
|
135
|
+
name: request.tool,
|
|
136
|
+
params: request.params,
|
|
137
|
+
providerExecuted: false
|
|
138
|
+
})
|
|
139
|
+
]
|
|
140
|
+
: []
|
|
141
|
+
)
|
|
154
142
|
|
|
155
|
-
const
|
|
156
|
-
Predicate.hasProperty(item, "seq")
|
|
143
|
+
const lastSeq = (entries: ReadonlyArray<AssistantEvent.AnyEntry>, otherwise: number) => entries.at(-1)?.seq ?? otherwise
|
|
157
144
|
|
|
158
145
|
// The handler's stream can end between a step's output and its tools, or while they run. An interrupted turn (a
|
|
159
146
|
// shutdown) leaves its calls open instead: the next turn runs them again.
|
|
@@ -164,7 +151,7 @@ const closeOpenCalls = Effect.fnUntraced(function* (chat: Writer, startSeq: numb
|
|
|
164
151
|
entries.flatMap(({ event }) => (Predicate.isTagged(event, "ToolStarted") ? [event.callId] : []))
|
|
165
152
|
)
|
|
166
153
|
|
|
167
|
-
const open = History.unansweredCalls(History.fromEntries(entries
|
|
154
|
+
const open = History.unansweredCalls(History.fromEntries(entries))
|
|
168
155
|
|
|
169
156
|
if (open.length === 0) return
|
|
170
157
|
|
|
@@ -196,13 +183,13 @@ const handledThrough = (entries: ReadonlyArray<AssistantEvent.AnyEntry>, startSe
|
|
|
196
183
|
startSeq
|
|
197
184
|
)
|
|
198
185
|
|
|
199
|
-
//
|
|
200
|
-
// next turn, which replies.
|
|
201
|
-
const finishTurn = Effect.fnUntraced(function* (chat: Writer, read: number,
|
|
186
|
+
// A turn that ran the loop fails visibly when the user's latest input got no reply; an input that arrived after what
|
|
187
|
+
// its model read gets the next turn, which replies. A handler that ended without the loop decided that itself.
|
|
188
|
+
const finishTurn = Effect.fnUntraced(function* (chat: Writer, read: number, ranLoop: boolean) {
|
|
202
189
|
const entries = yield* chat.entries
|
|
203
190
|
|
|
204
191
|
const end =
|
|
205
|
-
History.owesReply(entries, read) && !History.unreadAfter(entries, read
|
|
192
|
+
ranLoop && History.owesReply(entries, read) && !History.unreadAfter(entries, read)
|
|
206
193
|
? AssistantEvent.TurnFailed.make({ throughSeq: read, message: silentTurnMessage })
|
|
207
194
|
: AssistantEvent.TurnCompleted.make({ throughSeq: read })
|
|
208
195
|
|
|
@@ -222,11 +209,15 @@ const makeTurnApi = (
|
|
|
222
209
|
registration: Registration,
|
|
223
210
|
chat: Writer,
|
|
224
211
|
startSeq: number,
|
|
225
|
-
checkOpen: Effect.Effect<void
|
|
212
|
+
checkOpen: Effect.Effect<void>,
|
|
213
|
+
ranLoop: Ref.Ref<boolean>
|
|
226
214
|
): Assistant.Turn<any> => {
|
|
227
215
|
const { definition, builtins } = registration
|
|
228
216
|
const { app } = definition
|
|
229
217
|
|
|
218
|
+
const running = <A, E, R>(stream: Stream.Stream<A, E, R>) =>
|
|
219
|
+
Stream.unwrap(Ref.set(ranLoop, true).pipe(Effect.as(stream)))
|
|
220
|
+
|
|
230
221
|
// With how far into the chat it goes: the step records it on the model's output.
|
|
231
222
|
// Read before every model call: a chat the app deleted meanwhile stops here.
|
|
232
223
|
const history = Effect.fnUntraced(function* (view: Assistant.HistoryView<any> = identity) {
|
|
@@ -235,7 +226,7 @@ const makeTurnApi = (
|
|
|
235
226
|
const all = yield* chat.entries
|
|
236
227
|
|
|
237
228
|
const read: AssistantLoop.ChatHistory = {
|
|
238
|
-
messages:
|
|
229
|
+
messages: History.fromEntries(view(AppEvents.decodeEntries(app, all))),
|
|
239
230
|
throughSeq: lastSeq(all, startSeq)
|
|
240
231
|
}
|
|
241
232
|
|
|
@@ -258,7 +249,7 @@ const makeTurnApi = (
|
|
|
258
249
|
const through = handledThrough(all, startSeq)
|
|
259
250
|
|
|
260
251
|
// Something arrived after what the loop's model read: the next turn reads it with the full loop, and replies.
|
|
261
|
-
if (History.unreadAfter(all, through
|
|
252
|
+
if (History.unreadAfter(all, through)) return Stream.empty
|
|
262
253
|
|
|
263
254
|
const owed = History.owesReply(all, through)
|
|
264
255
|
const undelivered = !owed && History.owesDelivery(all, through)
|
|
@@ -282,7 +273,7 @@ const makeTurnApi = (
|
|
|
282
273
|
|
|
283
274
|
return {
|
|
284
275
|
messages: [
|
|
285
|
-
...
|
|
276
|
+
...History.fromEntries(options.view(AppEvents.decodeEntries(app, entries))),
|
|
286
277
|
History.userText(nudge)
|
|
287
278
|
],
|
|
288
279
|
throughSeq: lastSeq(entries, startSeq)
|
|
@@ -290,27 +281,27 @@ const makeTurnApi = (
|
|
|
290
281
|
}),
|
|
291
282
|
// A second step, for a reply after a call it was refused.
|
|
292
283
|
maxSteps: 2
|
|
293
|
-
|
|
284
|
+
// The loop ran the approved calls; a pass that can only reply runs none.
|
|
285
|
+
}).pipe(Stream.provideService(Loop.TurnApprovals, Option.none()))
|
|
294
286
|
})
|
|
295
287
|
)
|
|
296
288
|
|
|
297
289
|
const replyIfOwed = (options: Assistant.ReplyOptions) =>
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
290
|
+
running(
|
|
291
|
+
replyPass({
|
|
292
|
+
instructions: instructions(options.instructions),
|
|
293
|
+
toolkit: builtins,
|
|
294
|
+
view: identity,
|
|
295
|
+
nudge: options.nudge
|
|
296
|
+
})
|
|
297
|
+
)
|
|
304
298
|
|
|
305
|
-
const prepare = <T extends Record<string, Tool.Any
|
|
306
|
-
const
|
|
299
|
+
const prepare = <T extends Record<string, Tool.Any>>(options: Assistant.LoopOptions<T, any>) => {
|
|
300
|
+
const own = Toolkits.fromToolkitOrEmpty(options.toolkit)
|
|
307
301
|
|
|
308
302
|
return {
|
|
309
|
-
system:
|
|
310
|
-
toolkit: Toolkits.merge(
|
|
311
|
-
Toolkits.merge(builtins, Skills.toTools(skills)),
|
|
312
|
-
Toolkits.fromToolkitOrEmpty(options.toolkit)
|
|
313
|
-
),
|
|
303
|
+
system: instructions(options.instructions),
|
|
304
|
+
toolkit: Toolkits.merge(builtins, own),
|
|
314
305
|
view: options.history ?? identity
|
|
315
306
|
}
|
|
316
307
|
}
|
|
@@ -334,7 +325,7 @@ const makeTurnApi = (
|
|
|
334
325
|
maxSteps: options.maxSteps ?? 16
|
|
335
326
|
})
|
|
336
327
|
|
|
337
|
-
return Stream.concat(loop, replyPass({ instructions: system, toolkit, view, nudge: options.replyNudge }))
|
|
328
|
+
return running(Stream.concat(loop, replyPass({ instructions: system, toolkit, view, nudge: options.replyNudge })))
|
|
338
329
|
}
|
|
339
330
|
}
|
|
340
331
|
}
|
|
@@ -353,7 +344,7 @@ export const run = Effect.fnUntraced(
|
|
|
353
344
|
const { chat } = options
|
|
354
345
|
const before = yield* chat.entries
|
|
355
346
|
|
|
356
|
-
yield* Telemetry.agentInput(History.unhandledInputs(before
|
|
347
|
+
yield* Telemetry.agentInput(History.unhandledInputs(before))
|
|
357
348
|
|
|
358
349
|
const assistant = options.registration.definition.name
|
|
359
350
|
const traceId = yield* Telemetry.currentTraceId
|
|
@@ -368,7 +359,8 @@ export const run = Effect.fnUntraced(
|
|
|
368
359
|
])
|
|
369
360
|
|
|
370
361
|
const startSeq = lastSeq(started, 0)
|
|
371
|
-
const
|
|
362
|
+
const ranLoop = yield* Ref.make(false)
|
|
363
|
+
const turn = makeTurnApi(options.registration, chat, startSeq, options.checkOpen, ranLoop)
|
|
372
364
|
|
|
373
365
|
const record = (event: AssistantLoop.Event) => chat.append([event])
|
|
374
366
|
|
|
@@ -380,12 +372,14 @@ export const run = Effect.fnUntraced(
|
|
|
380
372
|
Loop.TurnTools,
|
|
381
373
|
Option.some(Toolkits.provide(options.registration.builtins, options.services))
|
|
382
374
|
),
|
|
375
|
+
// A turn's loop waits for the user's approval, and runs the calls they approved.
|
|
376
|
+
Effect.provideService(Loop.TurnApprovals, Option.some({ approved: Effect.map(chat.entries, approvedCalls) })),
|
|
383
377
|
Effect.provideContext(options.services),
|
|
384
378
|
Effect.matchCauseEffect({
|
|
385
379
|
onSuccess: Effect.fnUntraced(function* () {
|
|
386
380
|
const all = yield* chat.entries
|
|
387
381
|
|
|
388
|
-
yield* finishTurn(chat, handledThrough(all, startSeq),
|
|
382
|
+
yield* finishTurn(chat, handledThrough(all, startSeq), yield* Ref.get(ranLoop))
|
|
389
383
|
}),
|
|
390
384
|
onFailure: (cause) => failTurn(chat, cause)
|
|
391
385
|
})
|
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"}
|