effect-assistant 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +22 -2
- package/dist/AppEvent.d.ts +111 -0
- package/dist/AppEvent.d.ts.map +1 -0
- package/dist/AppEvent.js +71 -0
- package/dist/AppEvent.js.map +1 -0
- package/dist/Assistant.d.ts +403 -0
- package/dist/Assistant.d.ts.map +1 -0
- package/dist/Assistant.js +126 -0
- package/dist/Assistant.js.map +1 -0
- package/dist/AssistantActivity.d.ts +85 -0
- package/dist/AssistantActivity.d.ts.map +1 -0
- package/dist/AssistantActivity.js +105 -0
- package/dist/AssistantActivity.js.map +1 -0
- package/dist/AssistantEngine.d.ts +116 -0
- package/dist/AssistantEngine.d.ts.map +1 -0
- package/dist/AssistantEngine.js +255 -0
- package/dist/AssistantEngine.js.map +1 -0
- package/dist/AssistantEvent.d.ts +614 -0
- package/dist/AssistantEvent.d.ts.map +1 -0
- package/dist/AssistantEvent.js +523 -0
- package/dist/AssistantEvent.js.map +1 -0
- package/dist/AssistantLoop.d.ts +171 -0
- package/dist/AssistantLoop.d.ts.map +1 -0
- package/dist/AssistantLoop.js +108 -0
- package/dist/AssistantLoop.js.map +1 -0
- package/dist/AssistantToolCall.d.ts +32 -0
- package/dist/AssistantToolCall.d.ts.map +1 -0
- package/dist/AssistantToolCall.js +37 -0
- package/dist/AssistantToolCall.js.map +1 -0
- package/dist/Block.d.ts +69 -0
- package/dist/Block.d.ts.map +1 -0
- package/dist/Block.js +39 -0
- package/dist/Block.js.map +1 -0
- package/dist/BlockKit.d.ts +184 -0
- package/dist/BlockKit.d.ts.map +1 -0
- package/dist/BlockKit.js +151 -0
- package/dist/BlockKit.js.map +1 -0
- package/dist/ChatId.d.ts +31 -0
- package/dist/ChatId.d.ts.map +1 -0
- package/dist/ChatId.js +36 -0
- package/dist/ChatId.js.map +1 -0
- package/dist/ChatLog.d.ts +109 -0
- package/dist/ChatLog.d.ts.map +1 -0
- package/dist/ChatLog.js +177 -0
- package/dist/ChatLog.js.map +1 -0
- package/dist/ChatView.d.ts +459 -0
- package/dist/ChatView.d.ts.map +1 -0
- package/dist/ChatView.js +496 -0
- package/dist/ChatView.js.map +1 -0
- package/dist/Chats.d.ts +110 -0
- package/dist/Chats.d.ts.map +1 -0
- package/dist/Chats.js +98 -0
- package/dist/Chats.js.map +1 -0
- package/dist/Compaction.d.ts +105 -0
- package/dist/Compaction.d.ts.map +1 -0
- package/dist/Compaction.js +133 -0
- package/dist/Compaction.js.map +1 -0
- package/dist/CurrentChat.d.ts +40 -0
- package/dist/CurrentChat.d.ts.map +1 -0
- package/dist/CurrentChat.js +33 -0
- package/dist/CurrentChat.js.map +1 -0
- package/dist/Decision.d.ts +145 -0
- package/dist/Decision.d.ts.map +1 -0
- package/dist/Decision.js +178 -0
- package/dist/Decision.js.map +1 -0
- package/dist/DecisionId.d.ts +37 -0
- package/dist/DecisionId.d.ts.map +1 -0
- package/dist/DecisionId.js +44 -0
- package/dist/DecisionId.js.map +1 -0
- package/dist/InputId.d.ts +38 -0
- package/dist/InputId.d.ts.map +1 -0
- package/dist/InputId.js +43 -0
- package/dist/InputId.js.map +1 -0
- package/dist/Instructions.d.ts +56 -0
- package/dist/Instructions.d.ts.map +1 -0
- package/dist/Instructions.js +50 -0
- package/dist/Instructions.js.map +1 -0
- package/dist/Memory.d.ts +190 -0
- package/dist/Memory.d.ts.map +1 -0
- package/dist/Memory.js +216 -0
- package/dist/Memory.js.map +1 -0
- package/dist/RunId.d.ts +41 -0
- package/dist/RunId.d.ts.map +1 -0
- package/dist/RunId.js +46 -0
- package/dist/RunId.js.map +1 -0
- package/dist/Skill.d.ts +72 -0
- package/dist/Skill.d.ts.map +1 -0
- package/dist/Skill.js +58 -0
- package/dist/Skill.js.map +1 -0
- package/dist/Specialist.d.ts +267 -0
- package/dist/Specialist.d.ts.map +1 -0
- package/dist/Specialist.js +119 -0
- package/dist/Specialist.js.map +1 -0
- package/dist/ToolDiscovery.d.ts +108 -0
- package/dist/ToolDiscovery.d.ts.map +1 -0
- package/dist/ToolDiscovery.js +139 -0
- package/dist/ToolDiscovery.js.map +1 -0
- package/dist/ToolFailure.d.ts +66 -0
- package/dist/ToolFailure.d.ts.map +1 -0
- package/dist/ToolFailure.js +79 -0
- package/dist/ToolFailure.js.map +1 -0
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +26 -0
- package/dist/internal/chat.js +202 -0
- package/dist/internal/chat.js.map +1 -0
- package/dist/internal/decisions.js +66 -0
- package/dist/internal/decisions.js.map +1 -0
- package/dist/internal/events.d.ts +46 -0
- package/dist/internal/events.d.ts.map +1 -0
- package/dist/internal/events.js +65 -0
- package/dist/internal/events.js.map +1 -0
- package/dist/internal/history.js +185 -0
- package/dist/internal/history.js.map +1 -0
- package/dist/internal/instructions.js +11 -0
- package/dist/internal/instructions.js.map +1 -0
- package/dist/internal/loop.d.ts +73 -0
- package/dist/internal/loop.d.ts.map +1 -0
- package/dist/internal/loop.js +166 -0
- package/dist/internal/loop.js.map +1 -0
- package/dist/internal/schema.js +14 -0
- package/dist/internal/schema.js.map +1 -0
- package/dist/internal/skills.js +28 -0
- package/dist/internal/skills.js.map +1 -0
- package/dist/internal/specialists.js +273 -0
- package/dist/internal/specialists.js.map +1 -0
- package/dist/internal/telemetry.js +85 -0
- package/dist/internal/telemetry.js.map +1 -0
- package/dist/internal/toolkit.d.ts +76 -0
- package/dist/internal/toolkit.d.ts.map +1 -0
- package/dist/internal/toolkit.js +129 -0
- package/dist/internal/toolkit.js.map +1 -0
- package/dist/internal/tools.js +132 -0
- package/dist/internal/tools.js.map +1 -0
- package/dist/internal/turns.d.ts +64 -0
- package/dist/internal/turns.d.ts.map +1 -0
- package/dist/internal/turns.js +221 -0
- package/dist/internal/turns.js.map +1 -0
- package/dist/internal/uuid.js +45 -0
- package/dist/internal/uuid.js.map +1 -0
- package/dist/internal/writer.d.ts +12 -0
- package/dist/internal/writer.d.ts.map +1 -0
- package/package.json +51 -3
- package/src/AppEvent.ts +134 -0
- package/src/Assistant.ts +589 -0
- package/src/AssistantActivity.ts +150 -0
- package/src/AssistantEngine.ts +343 -0
- package/src/AssistantEvent.ts +635 -0
- package/src/AssistantLoop.ts +207 -0
- package/src/AssistantToolCall.ts +40 -0
- package/src/Block.ts +84 -0
- package/src/BlockKit.ts +311 -0
- package/src/ChatId.ts +36 -0
- package/src/ChatLog.ts +247 -0
- package/src/ChatView.ts +658 -0
- package/src/Chats.ts +122 -0
- package/src/Compaction.ts +224 -0
- package/src/CurrentChat.ts +47 -0
- package/src/Decision.ts +241 -0
- package/src/DecisionId.ts +46 -0
- package/src/InputId.ts +43 -0
- package/src/Instructions.ts +72 -0
- package/src/Memory.ts +276 -0
- package/src/RunId.ts +46 -0
- package/src/Skill.ts +91 -0
- package/src/Specialist.ts +355 -0
- package/src/ToolDiscovery.ts +187 -0
- package/src/ToolFailure.ts +74 -0
- package/src/index.ts +130 -0
- package/src/internal/chat.ts +372 -0
- package/src/internal/decisions.ts +131 -0
- package/src/internal/events.ts +100 -0
- package/src/internal/history.ts +366 -0
- package/src/internal/instructions.ts +9 -0
- package/src/internal/loop.ts +344 -0
- package/src/internal/schema.ts +25 -0
- package/src/internal/skills.ts +37 -0
- package/src/internal/specialists.ts +414 -0
- package/src/internal/telemetry.ts +125 -0
- package/src/internal/toolkit.ts +231 -0
- package/src/internal/tools.ts +210 -0
- package/src/internal/turns.ts +429 -0
- package/src/internal/uuid.ts +50 -0
- package/src/internal/writer.ts +12 -0
package/dist/Decision.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { fromCallId } from "./DecisionId.js";
|
|
3
|
+
import { DecisionOutcome, isLibraryEvent } from "./AssistantEvent.js";
|
|
4
|
+
import { make } from "./Block.js";
|
|
5
|
+
import * as Predicate from "effect/Predicate";
|
|
6
|
+
import * as Schema from "effect/Schema";
|
|
7
|
+
import * as Option from "effect/Option";
|
|
8
|
+
//#region src/Decision.ts
|
|
9
|
+
/**
|
|
10
|
+
* Lets the user approve or decline a tool call the assistant can't make on its own, such as
|
|
11
|
+
* placing an order or publishing a post.
|
|
12
|
+
*
|
|
13
|
+
* When the model calls a tool marked with Effect's `needsApproval`, the call is parked instead of
|
|
14
|
+
* run. The model asks the user with the decision {@link block}, and the user's answer to that
|
|
15
|
+
* block runs the call or declines it. {@link fromEntries} computes where every decision in a
|
|
16
|
+
* chat's log stands.
|
|
17
|
+
*
|
|
18
|
+
* @since 0.1.0
|
|
19
|
+
*/
|
|
20
|
+
var Decision_exports = /* @__PURE__ */ __exportAll({
|
|
21
|
+
Answer: () => Answer,
|
|
22
|
+
Props: () => Props,
|
|
23
|
+
answerAll: () => answerAll,
|
|
24
|
+
apply: () => apply,
|
|
25
|
+
block: () => block,
|
|
26
|
+
fromEntries: () => fromEntries,
|
|
27
|
+
kind: () => kind
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* The kind of the decision block.
|
|
31
|
+
*
|
|
32
|
+
* @category utils
|
|
33
|
+
* @since 0.1.0
|
|
34
|
+
*/
|
|
35
|
+
const kind = "decision";
|
|
36
|
+
/**
|
|
37
|
+
* Schema for the decision block's props, which list the decisions it asks for and, optionally,
|
|
38
|
+
* its buttons' labels.
|
|
39
|
+
*
|
|
40
|
+
* @category schemas
|
|
41
|
+
* @since 0.1.0
|
|
42
|
+
*/
|
|
43
|
+
const Props = Schema.Struct({
|
|
44
|
+
decisionIds: Schema.Array(Schema.String).check(Schema.isMinLength(1)).annotate({ description: "The decisions to ask for: each waiting call's decisionId. Several go in one block when the user decides them together." }),
|
|
45
|
+
approveLabel: Schema.optional(Schema.String).annotate({ description: "The approve button, like \"Place order\"." }),
|
|
46
|
+
declineLabel: Schema.optional(Schema.String).annotate({ description: "The decline button, like \"Cancel\"." })
|
|
47
|
+
});
|
|
48
|
+
/**
|
|
49
|
+
* Schema for the decision block's answer, which holds an outcome for every decision the block
|
|
50
|
+
* asks for, by id.
|
|
51
|
+
*
|
|
52
|
+
* @category schemas
|
|
53
|
+
* @since 0.1.0
|
|
54
|
+
*/
|
|
55
|
+
const Answer = Schema.Struct({ decisions: Schema.Record(Schema.String, DecisionOutcome) });
|
|
56
|
+
/**
|
|
57
|
+
* Block with approve and decline buttons for the decisions waiting for the user.
|
|
58
|
+
*
|
|
59
|
+
* **Details**
|
|
60
|
+
*
|
|
61
|
+
* Put it in the assistant's `BlockKit`. An assistant with a tool that needs a decision must have
|
|
62
|
+
* it. The client renders it like any other block, with the calls from {@link fromEntries} (their
|
|
63
|
+
* tool and params).
|
|
64
|
+
*
|
|
65
|
+
* **Example** (Asking the user before placing an order)
|
|
66
|
+
*
|
|
67
|
+
* ```ts
|
|
68
|
+
* import { Assistant, BlockKit, Decision } from "effect-assistant"
|
|
69
|
+
* import * as Tool from "effect/ai/Tool"
|
|
70
|
+
* import * as Toolkit from "effect/ai/Toolkit"
|
|
71
|
+
* import * as Effect from "effect/Effect"
|
|
72
|
+
* import * as Layer from "effect/Layer"
|
|
73
|
+
* import * as Schema from "effect/Schema"
|
|
74
|
+
*
|
|
75
|
+
* export const Shop = Assistant.make("shop", { blocks: BlockKit.make([Decision.block]) })
|
|
76
|
+
*
|
|
77
|
+
* const OrderTools = Toolkit.make(
|
|
78
|
+
* Tool.make("place_order", {
|
|
79
|
+
* description: "Places an order.",
|
|
80
|
+
* parameters: Schema.Struct({ sku: Schema.String, quantity: Schema.Int }),
|
|
81
|
+
* success: Schema.Struct({ reference: Schema.String }),
|
|
82
|
+
* needsApproval: true
|
|
83
|
+
* })
|
|
84
|
+
* )
|
|
85
|
+
*
|
|
86
|
+
* const OrderToolsLive = OrderTools.toLayer({
|
|
87
|
+
* place_order: () => Effect.succeed({ reference: "R-1042" })
|
|
88
|
+
* })
|
|
89
|
+
*
|
|
90
|
+
* // The call waits until the user answers the decision block.
|
|
91
|
+
* const ShopLive = Shop.toLayer((turn) =>
|
|
92
|
+
* turn.loop({ instructions: "You place orders for the team.", toolkit: OrderTools })
|
|
93
|
+
* ).pipe(Layer.provide(OrderToolsLive))
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
96
|
+
* @category constructors
|
|
97
|
+
* @since 0.1.0
|
|
98
|
+
*/
|
|
99
|
+
const block = make(kind, {
|
|
100
|
+
description: "Approve / decline buttons for decisions waiting for the user: a call of yours that waits for their decision. The only way such a decision is made: write what they decide on (the call's key facts), and put the decision ids in decisionIds.",
|
|
101
|
+
props: Props,
|
|
102
|
+
answer: Answer
|
|
103
|
+
});
|
|
104
|
+
/**
|
|
105
|
+
* Creates an answer that gives every decision the block asks for the same outcome.
|
|
106
|
+
*
|
|
107
|
+
* This is what an "Approve" or "Decline" button sends.
|
|
108
|
+
*
|
|
109
|
+
* @category constructors
|
|
110
|
+
* @since 0.1.0
|
|
111
|
+
*/
|
|
112
|
+
const answerAll = (props, outcome) => ({ decisions: Object.fromEntries(props.decisionIds.map((id) => [id, outcome])) });
|
|
113
|
+
const decodeAnswer = Schema.decodeUnknownOption(Answer);
|
|
114
|
+
/**
|
|
115
|
+
* Returns the decision states after one more event.
|
|
116
|
+
*
|
|
117
|
+
* @category utils
|
|
118
|
+
* @since 0.1.0
|
|
119
|
+
*/
|
|
120
|
+
const apply = (states, event) => {
|
|
121
|
+
if (!isLibraryEvent(event)) return states;
|
|
122
|
+
const update = (id, f) => {
|
|
123
|
+
const state = states.get(id);
|
|
124
|
+
return state === void 0 ? states : new Map(states).set(id, f(state));
|
|
125
|
+
};
|
|
126
|
+
if (Predicate.isTagged(event, "DecisionRequested")) return states.has(event.id) ? states : new Map(states).set(event.id, {
|
|
127
|
+
request: event,
|
|
128
|
+
outcome: void 0,
|
|
129
|
+
answer: void 0,
|
|
130
|
+
resolved: false,
|
|
131
|
+
result: void 0
|
|
132
|
+
});
|
|
133
|
+
if (Predicate.isTagged(event, "DecisionResolved")) return update(event.id, (state) => ({
|
|
134
|
+
...state,
|
|
135
|
+
outcome: event.outcome,
|
|
136
|
+
answer: event.answer,
|
|
137
|
+
resolved: true
|
|
138
|
+
}));
|
|
139
|
+
if (Predicate.isTagged(event, "BlockAnswer") && event.kind === "decision") return Option.match(decodeAnswer(event.value), {
|
|
140
|
+
onNone: () => states,
|
|
141
|
+
onSome: ({ decisions }) => {
|
|
142
|
+
const next = new Map(states);
|
|
143
|
+
for (const [id, outcome] of Object.entries(decisions)) {
|
|
144
|
+
const state = states.get(id);
|
|
145
|
+
if (state !== void 0 && state.outcome === void 0) next.set(id, {
|
|
146
|
+
...state,
|
|
147
|
+
outcome,
|
|
148
|
+
answer: event.id
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return next;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
if (Predicate.isTagged(event, "ToolResult")) {
|
|
155
|
+
const id = fromCallId(event.callId);
|
|
156
|
+
const state = states.get(id);
|
|
157
|
+
return state !== void 0 && Predicate.isTagged(state.request.origin, "Call") && state.outcome === "approved" ? update(id, (current) => ({
|
|
158
|
+
...current,
|
|
159
|
+
result: event
|
|
160
|
+
})) : states;
|
|
161
|
+
}
|
|
162
|
+
return states;
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Returns every decision in the log and where it stands, by id.
|
|
166
|
+
*
|
|
167
|
+
* @category utils
|
|
168
|
+
* @since 0.1.0
|
|
169
|
+
*/
|
|
170
|
+
const fromEntries = (entries) => {
|
|
171
|
+
let all = /* @__PURE__ */ new Map();
|
|
172
|
+
for (const entry of entries) all = apply(all, entry.event);
|
|
173
|
+
return all;
|
|
174
|
+
};
|
|
175
|
+
//#endregion
|
|
176
|
+
export { Answer, Decision_exports, Props, answerAll, apply, block, fromEntries, kind };
|
|
177
|
+
|
|
178
|
+
//# sourceMappingURL=Decision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Decision.js","names":["AssistantEvent.DecisionOutcome","Block.make","AssistantEvent.isLibraryEvent","DecisionId.fromCallId"],"sources":["../src/Decision.ts"],"sourcesContent":["/**\n * Lets the user approve or decline a tool call the assistant can't make on its own, such as\n * placing an order or publishing a post.\n *\n * When the model calls a tool marked with Effect's `needsApproval`, the call is parked instead of\n * run. The model asks the user with the decision {@link block}, and the user's answer to that\n * block runs the call or declines it. {@link fromEntries} computes where every decision in a\n * chat's log stands.\n *\n * @since 0.1.0\n */\nimport * as Option from \"effect/Option\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as Schema from \"effect/Schema\"\nimport * as AssistantEvent from \"./AssistantEvent.ts\"\nimport * as Block from \"./Block.ts\"\nimport * as DecisionId from \"./DecisionId.ts\"\nimport type { InputId } from \"./InputId.ts\"\n\n/**\n * The kind of the decision block.\n *\n * @category utils\n * @since 0.1.0\n */\nexport const kind = \"decision\"\n\n/**\n * Schema for the decision block's props, which list the decisions it asks for and, optionally,\n * its buttons' labels.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const Props = Schema.Struct({\n // Plain strings: a strict tool schema with the id's pattern is too much for some providers; the\n // ids are checked against the decisions waiting when the message is sent.\n decisionIds: Schema.Array(Schema.String).check(Schema.isMinLength(1)).annotate({\n description:\n \"The decisions to ask for: each waiting call's decisionId. Several go in one block when the user decides them together.\"\n }),\n approveLabel: Schema.optional(Schema.String).annotate({\n description: 'The approve button, like \"Place order\".'\n }),\n declineLabel: Schema.optional(Schema.String).annotate({\n description: 'The decline button, like \"Cancel\".'\n })\n})\n\n/**\n * Represents the decision block's props.\n *\n * @category models\n * @since 0.1.0\n */\nexport type Props = typeof Props.Type\n\n/**\n * Schema for the decision block's answer, which holds an outcome for every decision the block\n * asks for, by id.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const Answer = Schema.Struct({\n decisions: Schema.Record(Schema.String, AssistantEvent.DecisionOutcome)\n})\n\n/**\n * Represents the decision block's answer.\n *\n * @category models\n * @since 0.1.0\n */\nexport type Answer = typeof Answer.Type\n\n/**\n * Block with approve and decline buttons for the decisions waiting for the user.\n *\n * **Details**\n *\n * Put it in the assistant's `BlockKit`. An assistant with a tool that needs a decision must have\n * it. The client renders it like any other block, with the calls from {@link fromEntries} (their\n * tool and params).\n *\n * **Example** (Asking the user before placing an order)\n *\n * ```ts\n * import { Assistant, BlockKit, Decision } from \"effect-assistant\"\n * import * as Tool from \"effect/ai/Tool\"\n * import * as Toolkit from \"effect/ai/Toolkit\"\n * import * as Effect from \"effect/Effect\"\n * import * as Layer from \"effect/Layer\"\n * import * as Schema from \"effect/Schema\"\n *\n * export const Shop = Assistant.make(\"shop\", { blocks: BlockKit.make([Decision.block]) })\n *\n * const OrderTools = Toolkit.make(\n * Tool.make(\"place_order\", {\n * description: \"Places an order.\",\n * parameters: Schema.Struct({ sku: Schema.String, quantity: Schema.Int }),\n * success: Schema.Struct({ reference: Schema.String }),\n * needsApproval: true\n * })\n * )\n *\n * const OrderToolsLive = OrderTools.toLayer({\n * place_order: () => Effect.succeed({ reference: \"R-1042\" })\n * })\n *\n * // The call waits until the user answers the decision block.\n * const ShopLive = Shop.toLayer((turn) =>\n * turn.loop({ instructions: \"You place orders for the team.\", toolkit: OrderTools })\n * ).pipe(Layer.provide(OrderToolsLive))\n * ```\n *\n * @category constructors\n * @since 0.1.0\n */\nexport const block = Block.make(kind, {\n description:\n \"Approve / decline buttons for decisions waiting for the user: a call of yours that waits for their decision. The only way such a decision is made: write what they decide on (the call's key facts), and put the decision ids in decisionIds.\",\n props: Props,\n answer: Answer\n})\n\n/**\n * Creates an answer that gives every decision the block asks for the same outcome.\n *\n * This is what an \"Approve\" or \"Decline\" button sends.\n *\n * @category constructors\n * @since 0.1.0\n */\nexport const answerAll = (props: Props, outcome: AssistantEvent.DecisionOutcome): Answer => ({\n decisions: Object.fromEntries(props.decisionIds.map((id) => [id, outcome]))\n})\n\n/**\n * Represents the state of a decision.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface State {\n readonly request: AssistantEvent.DecisionRequested\n /** How the user decided, or `undefined` while the decision waits. */\n readonly outcome: AssistantEvent.DecisionOutcome | undefined\n /** The id of the answer that decided it. */\n readonly answer: InputId | undefined\n /** Whether its `DecisionResolved` is stored. A workflow's decision has been passed on by then. */\n readonly resolved: boolean\n /** The approved call's result, once the call has run. */\n readonly result: AssistantEvent.ToolResult | undefined\n}\n\nconst decodeAnswer = Schema.decodeUnknownOption(Answer)\n\n/**\n * Returns the decision states after one more event.\n *\n * @category utils\n * @since 0.1.0\n */\nexport const apply = (\n states: ReadonlyMap<string, State>,\n event: { readonly _tag: string }\n): ReadonlyMap<string, State> => {\n if (!AssistantEvent.isLibraryEvent(event)) return states\n\n const update = (id: string, f: (state: State) => State) => {\n const state = states.get(id)\n\n return state === undefined ? states : new Map(states).set(id, f(state))\n }\n\n if (Predicate.isTagged(event, \"DecisionRequested\")) {\n return states.has(event.id)\n ? states\n : new Map(states).set(event.id, {\n request: event,\n outcome: undefined,\n answer: undefined,\n resolved: false,\n result: undefined\n })\n }\n\n if (Predicate.isTagged(event, \"DecisionResolved\")) {\n return update(event.id, (state) => ({\n ...state,\n outcome: event.outcome,\n answer: event.answer,\n resolved: true\n }))\n }\n\n // A stored decision answer was checked against its block when it was submitted: the first one\n // for a decision decides it.\n if (Predicate.isTagged(event, \"BlockAnswer\") && event.kind === kind) {\n return Option.match(decodeAnswer(event.value), {\n onNone: () => states,\n onSome: ({ decisions }) => {\n const next = new Map(states)\n\n for (const [id, outcome] of Object.entries(decisions)) {\n const state = states.get(id)\n\n if (state !== undefined && state.outcome === undefined) next.set(id, { ...state, outcome, answer: event.id })\n }\n\n return next\n }\n })\n }\n\n if (Predicate.isTagged(event, \"ToolResult\")) {\n const id = DecisionId.fromCallId(event.callId)\n const state = states.get(id)\n\n return state !== undefined && Predicate.isTagged(state.request.origin, \"Call\") && state.outcome === \"approved\"\n ? update(id, (current) => ({ ...current, result: event }))\n : states\n }\n\n return states\n}\n\n/**\n * Returns every decision in the log and where it stands, by id.\n *\n * @category utils\n * @since 0.1.0\n */\nexport const fromEntries = (entries: ReadonlyArray<AssistantEvent.AnyEntry>): ReadonlyMap<string, State> => {\n let all: ReadonlyMap<string, State> = new Map()\n\n for (const entry of entries) all = apply(all, entry.event)\n\n return all\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAa,OAAO;;;;;;;;AASpB,MAAa,QAAQ,OAAO,OAAO;CAGjC,aAAa,OAAO,MAAM,OAAO,MAAM,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,EAC7E,aACE,yHACJ,CAAC;CACD,cAAc,OAAO,SAAS,OAAO,MAAM,CAAC,CAAC,SAAS,EACpD,aAAa,4CACf,CAAC;CACD,cAAc,OAAO,SAAS,OAAO,MAAM,CAAC,CAAC,SAAS,EACpD,aAAa,uCACf,CAAC;AACH,CAAC;;;;;;;;AAiBD,MAAa,SAAS,OAAO,OAAO,EAClC,WAAW,OAAO,OAAO,OAAO,QAAQA,eAA8B,EACxE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDD,MAAa,QAAQC,KAAW,MAAM;CACpC,aACE;CACF,OAAO;CACP,QAAQ;AACV,CAAC;;;;;;;;;AAUD,MAAa,aAAa,OAAc,aAAqD,EAC3F,WAAW,OAAO,YAAY,MAAM,YAAY,KAAK,OAAO,CAAC,IAAI,OAAO,CAAC,CAAC,EAC5E;AAoBA,MAAM,eAAe,OAAO,oBAAoB,MAAM;;;;;;;AAQtD,MAAa,SACX,QACA,UAC+B;CAC/B,IAAI,CAACC,eAA8B,KAAK,GAAG,OAAO;CAElD,MAAM,UAAU,IAAY,MAA+B;EACzD,MAAM,QAAQ,OAAO,IAAI,EAAE;EAE3B,OAAO,UAAU,KAAA,IAAY,SAAS,IAAI,IAAI,MAAM,CAAC,CAAC,IAAI,IAAI,EAAE,KAAK,CAAC;CACxE;CAEA,IAAI,UAAU,SAAS,OAAO,mBAAmB,GAC/C,OAAO,OAAO,IAAI,MAAM,EAAE,IACtB,SACA,IAAI,IAAI,MAAM,CAAC,CAAC,IAAI,MAAM,IAAI;EAC5B,SAAS;EACT,SAAS,KAAA;EACT,QAAQ,KAAA;EACR,UAAU;EACV,QAAQ,KAAA;CACV,CAAC;CAGP,IAAI,UAAU,SAAS,OAAO,kBAAkB,GAC9C,OAAO,OAAO,MAAM,KAAK,WAAW;EAClC,GAAG;EACH,SAAS,MAAM;EACf,QAAQ,MAAM;EACd,UAAU;CACZ,EAAE;CAKJ,IAAI,UAAU,SAAS,OAAO,aAAa,KAAK,MAAM,SAAA,YACpD,OAAO,OAAO,MAAM,aAAa,MAAM,KAAK,GAAG;EAC7C,cAAc;EACd,SAAS,EAAE,gBAAgB;GACzB,MAAM,OAAO,IAAI,IAAI,MAAM;GAE3B,KAAK,MAAM,CAAC,IAAI,YAAY,OAAO,QAAQ,SAAS,GAAG;IACrD,MAAM,QAAQ,OAAO,IAAI,EAAE;IAE3B,IAAI,UAAU,KAAA,KAAa,MAAM,YAAY,KAAA,GAAW,KAAK,IAAI,IAAI;KAAE,GAAG;KAAO;KAAS,QAAQ,MAAM;IAAG,CAAC;GAC9G;GAEA,OAAO;EACT;CACF,CAAC;CAGH,IAAI,UAAU,SAAS,OAAO,YAAY,GAAG;EAC3C,MAAM,KAAKC,WAAsB,MAAM,MAAM;EAC7C,MAAM,QAAQ,OAAO,IAAI,EAAE;EAE3B,OAAO,UAAU,KAAA,KAAa,UAAU,SAAS,MAAM,QAAQ,QAAQ,MAAM,KAAK,MAAM,YAAY,aAChG,OAAO,KAAK,aAAa;GAAE,GAAG;GAAS,QAAQ;EAAM,EAAE,IACvD;CACN;CAEA,OAAO;AACT;;;;;;;AAQA,MAAa,eAAe,YAAgF;CAC1G,IAAI,sBAAkC,IAAI,IAAI;CAE9C,KAAK,MAAM,SAAS,SAAS,MAAM,MAAM,KAAK,MAAM,KAAK;CAEzD,OAAO;AACT"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
declare namespace DecisionId_d_exports {
|
|
3
|
+
export { DecisionId, fromCallId, fromKey };
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Schema for decision ids of the form `` `decision:${uuid}` ``, branded.
|
|
7
|
+
*
|
|
8
|
+
* @category schemas
|
|
9
|
+
* @since 0.1.0
|
|
10
|
+
*/
|
|
11
|
+
export declare const DecisionId: Schema.brand<Schema.TemplateLiteral<readonly ["decision:", Schema.String]>, "~effect-assistant/DecisionId">;
|
|
12
|
+
/**
|
|
13
|
+
* Represents a decision id.
|
|
14
|
+
*
|
|
15
|
+
* @category models
|
|
16
|
+
* @since 0.1.0
|
|
17
|
+
*/
|
|
18
|
+
export type DecisionId = typeof DecisionId.Type;
|
|
19
|
+
/**
|
|
20
|
+
* Creates the decision id for a key. The same key always gives the same id, so a decision that is
|
|
21
|
+
* requested again is stored only once.
|
|
22
|
+
*
|
|
23
|
+
* @category constructors
|
|
24
|
+
* @since 0.1.0
|
|
25
|
+
*/
|
|
26
|
+
export declare const fromKey: (key: string) => DecisionId;
|
|
27
|
+
/**
|
|
28
|
+
* Returns the decision id for a tool call that waits for the user's decision, derived from the
|
|
29
|
+
* call's id.
|
|
30
|
+
*
|
|
31
|
+
* @category constructors
|
|
32
|
+
* @since 0.1.0
|
|
33
|
+
*/
|
|
34
|
+
export declare const fromCallId: (callId: string) => DecisionId;
|
|
35
|
+
//#endregion
|
|
36
|
+
export { DecisionId_d_exports };
|
|
37
|
+
//# sourceMappingURL=DecisionId.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DecisionId.d.ts","names":[],"sources":["../src/DecisionId.ts"],"mappings":";;;;;;;;;;qBAiBa,YAAU,OAAA,MAAA,OAAA,uCAAA,OAAA;;;;;;;YAUX,oBAAoB,WAAW;;;;;;;;qBAS9B,UAAO,gBAAkB;;;;;;;;qBASzB,aAAU,mBAAqB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { Uuid, fromKey as fromKey$1 } from "./internal/uuid.js";
|
|
3
|
+
import * as Schema from "effect/Schema";
|
|
4
|
+
//#region src/DecisionId.ts
|
|
5
|
+
/**
|
|
6
|
+
* This module provides the id of a decision the user is asked to make, which is `decision:`
|
|
7
|
+
* followed by a UUID.
|
|
8
|
+
*
|
|
9
|
+
* The model passes the id to a decision block, and the user's answer refers to it.
|
|
10
|
+
*
|
|
11
|
+
* @since 0.1.0
|
|
12
|
+
*/
|
|
13
|
+
var DecisionId_exports = /* @__PURE__ */ __exportAll({
|
|
14
|
+
DecisionId: () => DecisionId,
|
|
15
|
+
fromCallId: () => fromCallId,
|
|
16
|
+
fromKey: () => fromKey
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* Schema for decision ids of the form `` `decision:${uuid}` ``, branded.
|
|
20
|
+
*
|
|
21
|
+
* @category schemas
|
|
22
|
+
* @since 0.1.0
|
|
23
|
+
*/
|
|
24
|
+
const DecisionId = Schema.TemplateLiteral(["decision:", Uuid]).pipe(Schema.brand("~effect-assistant/DecisionId"));
|
|
25
|
+
/**
|
|
26
|
+
* Creates the decision id for a key. The same key always gives the same id, so a decision that is
|
|
27
|
+
* requested again is stored only once.
|
|
28
|
+
*
|
|
29
|
+
* @category constructors
|
|
30
|
+
* @since 0.1.0
|
|
31
|
+
*/
|
|
32
|
+
const fromKey = (key) => DecisionId.make(`decision:${fromKey$1(key)}`);
|
|
33
|
+
/**
|
|
34
|
+
* Returns the decision id for a tool call that waits for the user's decision, derived from the
|
|
35
|
+
* call's id.
|
|
36
|
+
*
|
|
37
|
+
* @category constructors
|
|
38
|
+
* @since 0.1.0
|
|
39
|
+
*/
|
|
40
|
+
const fromCallId = (callId) => fromKey(`tool-call:${callId}`);
|
|
41
|
+
//#endregion
|
|
42
|
+
export { DecisionId, DecisionId_exports, fromCallId, fromKey };
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=DecisionId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DecisionId.js","names":["Uuid.Uuid","Uuid.fromKey"],"sources":["../src/DecisionId.ts"],"sourcesContent":["/**\n * This module provides the id of a decision the user is asked to make, which is `decision:`\n * followed by a UUID.\n *\n * The model passes the id to a decision block, and the user's answer refers to it.\n *\n * @since 0.1.0\n */\nimport * as Schema from \"effect/Schema\"\nimport * as Uuid from \"./internal/uuid.ts\"\n\n/**\n * Schema for decision ids of the form `` `decision:${uuid}` ``, branded.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const DecisionId = Schema.TemplateLiteral([\"decision:\", Uuid.Uuid]).pipe(\n Schema.brand(\"~effect-assistant/DecisionId\")\n)\n\n/**\n * Represents a decision id.\n *\n * @category models\n * @since 0.1.0\n */\nexport type DecisionId = typeof DecisionId.Type\n\n/**\n * Creates the decision id for a key. The same key always gives the same id, so a decision that is\n * requested again is stored only once.\n *\n * @category constructors\n * @since 0.1.0\n */\nexport const fromKey = (key: string): DecisionId => DecisionId.make(`decision:${Uuid.fromKey(key)}`)\n\n/**\n * Returns the decision id for a tool call that waits for the user's decision, derived from the\n * call's id.\n *\n * @category constructors\n * @since 0.1.0\n */\nexport const fromCallId = (callId: string): DecisionId => fromKey(`tool-call:${callId}`)\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAiBA,MAAa,aAAa,OAAO,gBAAgB,CAAC,aAAaA,IAAS,CAAC,CAAC,CAAC,KACzE,OAAO,MAAM,8BAA8B,CAC7C;;;;;;;;AAiBA,MAAa,WAAW,QAA4B,WAAW,KAAK,YAAYC,UAAa,GAAG,GAAG;;;;;;;;AASnG,MAAa,cAAc,WAA+B,QAAQ,aAAa,QAAQ"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
declare namespace InputId_d_exports {
|
|
4
|
+
export { InputId, fromKey, make };
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Schema for input ids. Any string is a valid input id, and the schema brands it.
|
|
8
|
+
*
|
|
9
|
+
* @category schemas
|
|
10
|
+
* @since 0.1.0
|
|
11
|
+
*/
|
|
12
|
+
export declare const InputId: Schema.brand<Schema.String, "~effect-assistant/InputId">;
|
|
13
|
+
/**
|
|
14
|
+
* Represents an input id.
|
|
15
|
+
*
|
|
16
|
+
* @category models
|
|
17
|
+
* @since 0.1.0
|
|
18
|
+
*/
|
|
19
|
+
export type InputId = typeof InputId.Type;
|
|
20
|
+
/**
|
|
21
|
+
* Creates a new random input id using Effect's `Random`. Seed `Random` in tests to get the same ids
|
|
22
|
+
* on every run.
|
|
23
|
+
*
|
|
24
|
+
* @category constructors
|
|
25
|
+
* @since 0.1.0
|
|
26
|
+
*/
|
|
27
|
+
export declare const make: () => Effect.Effect<InputId>;
|
|
28
|
+
/**
|
|
29
|
+
* Creates the input id for a key, such as `${runId}:order_placed`. The same key always gives the
|
|
30
|
+
* same id, so an input that is sent again is stored only once.
|
|
31
|
+
*
|
|
32
|
+
* @category constructors
|
|
33
|
+
* @since 0.1.0
|
|
34
|
+
*/
|
|
35
|
+
export declare const fromKey: (key: string) => InputId;
|
|
36
|
+
//#endregion
|
|
37
|
+
export { InputId_d_exports };
|
|
38
|
+
//# sourceMappingURL=InputId.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputId.d.ts","names":[],"sources":["../src/InputId.ts"],"mappings":";;;;;;;;;;;qBAgBa,SAAO,OAAA,MAAA,OAAA;;;;;;;YAQR,iBAAiB,QAAQ;;;;;;;;qBASxB,YAAW,OAAO,OAAO;;;;;;;;qBASzB,UAAO,gBAAkB"}
|
package/dist/InputId.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { make as make$1 } from "./internal/uuid.js";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Schema from "effect/Schema";
|
|
5
|
+
//#region src/InputId.ts
|
|
6
|
+
/**
|
|
7
|
+
* This module provides the id of an input to an assistant. An input is a user message, a block
|
|
8
|
+
* answer, or one of the app's events, and the id is stored in its `id` field.
|
|
9
|
+
*
|
|
10
|
+
* @since 0.1.0
|
|
11
|
+
*/
|
|
12
|
+
var InputId_exports = /* @__PURE__ */ __exportAll({
|
|
13
|
+
InputId: () => InputId,
|
|
14
|
+
fromKey: () => fromKey,
|
|
15
|
+
make: () => make
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* Schema for input ids. Any string is a valid input id, and the schema brands it.
|
|
19
|
+
*
|
|
20
|
+
* @category schemas
|
|
21
|
+
* @since 0.1.0
|
|
22
|
+
*/
|
|
23
|
+
const InputId = Schema.String.pipe(Schema.brand("~effect-assistant/InputId"));
|
|
24
|
+
/**
|
|
25
|
+
* Creates a new random input id using Effect's `Random`. Seed `Random` in tests to get the same ids
|
|
26
|
+
* on every run.
|
|
27
|
+
*
|
|
28
|
+
* @category constructors
|
|
29
|
+
* @since 0.1.0
|
|
30
|
+
*/
|
|
31
|
+
const make = () => Effect.map(make$1, (uuid) => InputId.make(uuid));
|
|
32
|
+
/**
|
|
33
|
+
* Creates the input id for a key, such as `${runId}:order_placed`. The same key always gives the
|
|
34
|
+
* same id, so an input that is sent again is stored only once.
|
|
35
|
+
*
|
|
36
|
+
* @category constructors
|
|
37
|
+
* @since 0.1.0
|
|
38
|
+
*/
|
|
39
|
+
const fromKey = (key) => InputId.make(key);
|
|
40
|
+
//#endregion
|
|
41
|
+
export { InputId, InputId_exports, fromKey, make };
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=InputId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputId.js","names":["Uuid.make"],"sources":["../src/InputId.ts"],"sourcesContent":["/**\n * This module provides the id of an input to an assistant. An input is a user message, a block\n * answer, or one of the app's events, and the id is stored in its `id` field.\n *\n * @since 0.1.0\n */\nimport * as Effect from \"effect/Effect\"\nimport * as Schema from \"effect/Schema\"\nimport * as Uuid from \"./internal/uuid.ts\"\n\n/**\n * Schema for input ids. Any string is a valid input id, and the schema brands it.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const InputId = Schema.String.pipe(Schema.brand(\"~effect-assistant/InputId\"))\n\n/**\n * Represents an input id.\n *\n * @category models\n * @since 0.1.0\n */\nexport type InputId = typeof InputId.Type\n\n/**\n * Creates a new random input id using Effect's `Random`. Seed `Random` in tests to get the same ids\n * on every run.\n *\n * @category constructors\n * @since 0.1.0\n */\nexport const make = (): Effect.Effect<InputId> => Effect.map(Uuid.make, (uuid) => InputId.make(uuid))\n\n/**\n * Creates the input id for a key, such as `${runId}:order_placed`. The same key always gives the\n * same id, so an input that is sent again is stored only once.\n *\n * @category constructors\n * @since 0.1.0\n */\nexport const fromKey = (key: string): InputId => InputId.make(key)\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAgBA,MAAa,UAAU,OAAO,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;;;;;;;;AAiBnF,MAAa,aAAqC,OAAO,IAAIA,SAAY,SAAS,QAAQ,KAAK,IAAI,CAAC;;;;;;;;AASpG,MAAa,WAAW,QAAyB,QAAQ,KAAK,GAAG"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
declare namespace Instructions_d_exports {
|
|
3
|
+
export { Instructions, Resolved, SpanAttributes, protocol, resolve };
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* The text the model has to know for a turn's loop to work.
|
|
7
|
+
*
|
|
8
|
+
* **Details**
|
|
9
|
+
*
|
|
10
|
+
* It tells the model that every step is a tool call, that `wait` (or a last message with
|
|
11
|
+
* `wait: true`) ends the turn, that the user sees only what it sends with `send_user_message`, and
|
|
12
|
+
* that messages can arrive mid-turn. The rest, such as what a `<specialist>` block or an app's
|
|
13
|
+
* event is, is in the tools' descriptions and in the history itself.
|
|
14
|
+
*
|
|
15
|
+
* `turn.instructions(text)` puts it before the text, and a custom loop on `AssistantLoop.run` can
|
|
16
|
+
* use it too.
|
|
17
|
+
*
|
|
18
|
+
* @category utils
|
|
19
|
+
* @since 0.1.0
|
|
20
|
+
*/
|
|
21
|
+
export declare const protocol = "Every step is a tool call. When you have nothing more to do right now, end your turn: set wait to true on your last send_user_message, or call wait if you have nothing to say.\nThe user sees only the text of what you send with send_user_message: anything else you write is never shown, so put the whole answer in the message, not next to it.\nMessages and updates can arrive while you work: handle the newest one, and don't repeat what you already told the user.";
|
|
22
|
+
/**
|
|
23
|
+
* Represents the span attributes added to every model call made with a prompt.
|
|
24
|
+
*
|
|
25
|
+
* @category models
|
|
26
|
+
* @since 0.1.0
|
|
27
|
+
*/
|
|
28
|
+
export type SpanAttributes = Readonly<Record<string, string | number | boolean>>;
|
|
29
|
+
/**
|
|
30
|
+
* Represents instructions resolved to text, with the span attributes to record them under.
|
|
31
|
+
*
|
|
32
|
+
* @category models
|
|
33
|
+
* @since 0.1.0
|
|
34
|
+
*/
|
|
35
|
+
export interface Resolved {
|
|
36
|
+
readonly text: string;
|
|
37
|
+
readonly attributes?: SpanAttributes | undefined;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Represents instructions as text, or as an Effect that produces the text (optionally with span
|
|
41
|
+
* attributes).
|
|
42
|
+
*
|
|
43
|
+
* @category models
|
|
44
|
+
* @since 0.1.0
|
|
45
|
+
*/
|
|
46
|
+
export type Instructions<R = never> = string | Effect.Effect<string | Resolved, never, R>;
|
|
47
|
+
/**
|
|
48
|
+
* Resolves instructions to their text and span attributes.
|
|
49
|
+
*
|
|
50
|
+
* @category utils
|
|
51
|
+
* @since 0.1.0
|
|
52
|
+
*/
|
|
53
|
+
export declare const resolve: <R = never>(instructions: Instructions<R>) => Effect.Effect<Resolved, never, R>;
|
|
54
|
+
//#endregion
|
|
55
|
+
export { Instructions_d_exports };
|
|
56
|
+
//# sourceMappingURL=Instructions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Instructions.d.ts","names":[],"sources":["../src/Instructions.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;qBA4Ba;;;;;;;YAUD,iBAAiB,SAAS;;;;;;;iBAQrB;WACN;WACA,aAAa;;;;;;;;;YAUZ,aAAa,sBAAsB,OAAO,gBAAgB,iBAAiB;;;;;;;qBAQ1E,UAAuD,WAAC,cAAA,aAAA,OAAA,OAAA,OAAA,iBAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
import * as Predicate from "effect/Predicate";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
//#region src/Instructions.ts
|
|
5
|
+
/**
|
|
6
|
+
* Defines the instructions that tell an assistant, specialist, or skill what to do.
|
|
7
|
+
*
|
|
8
|
+
* Instructions are text, or an Effect that produces text, optionally with span attributes
|
|
9
|
+
* (a {@link Resolved}). {@link resolve} turns them into a `Resolved`, and {@link protocol} is the
|
|
10
|
+
* text a turn's loop needs the model to know.
|
|
11
|
+
*
|
|
12
|
+
* @since 0.1.0
|
|
13
|
+
*/
|
|
14
|
+
var Instructions_exports = /* @__PURE__ */ __exportAll({
|
|
15
|
+
protocol: () => protocol,
|
|
16
|
+
resolve: () => resolve
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* The text the model has to know for a turn's loop to work.
|
|
20
|
+
*
|
|
21
|
+
* **Details**
|
|
22
|
+
*
|
|
23
|
+
* It tells the model that every step is a tool call, that `wait` (or a last message with
|
|
24
|
+
* `wait: true`) ends the turn, that the user sees only what it sends with `send_user_message`, and
|
|
25
|
+
* that messages can arrive mid-turn. The rest, such as what a `<specialist>` block or an app's
|
|
26
|
+
* event is, is in the tools' descriptions and in the history itself.
|
|
27
|
+
*
|
|
28
|
+
* `turn.instructions(text)` puts it before the text, and a custom loop on `AssistantLoop.run` can
|
|
29
|
+
* use it too.
|
|
30
|
+
*
|
|
31
|
+
* @category utils
|
|
32
|
+
* @since 0.1.0
|
|
33
|
+
*/
|
|
34
|
+
const protocol = `Every step is a tool call. When you have nothing more to do right now, end your turn: set wait to true on your last send_user_message, or call wait if you have nothing to say.
|
|
35
|
+
The user sees only the text of what you send with send_user_message: anything else you write is never shown, so put the whole answer in the message, not next to it.
|
|
36
|
+
Messages and updates can arrive while you work: handle the newest one, and don't repeat what you already told the user.`;
|
|
37
|
+
/**
|
|
38
|
+
* Resolves instructions to their text and span attributes.
|
|
39
|
+
*
|
|
40
|
+
* @category utils
|
|
41
|
+
* @since 0.1.0
|
|
42
|
+
*/
|
|
43
|
+
const resolve = Effect.fn("Instructions.resolve")(function* (instructions) {
|
|
44
|
+
return Predicate.isString(instructions) ? { text: instructions } : toResolved(yield* instructions);
|
|
45
|
+
});
|
|
46
|
+
const toResolved = (resolved) => Predicate.isString(resolved) ? { text: resolved } : resolved;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { Instructions_exports, protocol, resolve };
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=Instructions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Instructions.js","names":[],"sources":["../src/Instructions.ts"],"sourcesContent":["/**\n * Defines the instructions that tell an assistant, specialist, or skill what to do.\n *\n * Instructions are text, or an Effect that produces text, optionally with span attributes\n * (a {@link Resolved}). {@link resolve} turns them into a `Resolved`, and {@link protocol} is the\n * text a turn's loop needs the model to know.\n *\n * @since 0.1.0\n */\nimport * as Effect from \"effect/Effect\"\nimport * as Predicate from \"effect/Predicate\"\n\n/**\n * The text the model has to know for a turn's loop to work.\n *\n * **Details**\n *\n * It tells the model that every step is a tool call, that `wait` (or a last message with\n * `wait: true`) ends the turn, that the user sees only what it sends with `send_user_message`, and\n * that messages can arrive mid-turn. The rest, such as what a `<specialist>` block or an app's\n * event is, is in the tools' descriptions and in the history itself.\n *\n * `turn.instructions(text)` puts it before the text, and a custom loop on `AssistantLoop.run` can\n * use it too.\n *\n * @category utils\n * @since 0.1.0\n */\nexport const protocol = `Every step is a tool call. When you have nothing more to do right now, end your turn: set wait to true on your last send_user_message, or call wait if you have nothing to say.\nThe user sees only the text of what you send with send_user_message: anything else you write is never shown, so put the whole answer in the message, not next to it.\nMessages and updates can arrive while you work: handle the newest one, and don't repeat what you already told the user.`\n\n/**\n * Represents the span attributes added to every model call made with a prompt.\n *\n * @category models\n * @since 0.1.0\n */\nexport type SpanAttributes = Readonly<Record<string, string | number | boolean>>\n\n/**\n * Represents instructions resolved to text, with the span attributes to record them under.\n *\n * @category models\n * @since 0.1.0\n */\nexport interface Resolved {\n readonly text: string\n readonly attributes?: SpanAttributes | undefined\n}\n\n/**\n * Represents instructions as text, or as an Effect that produces the text (optionally with span\n * attributes).\n *\n * @category models\n * @since 0.1.0\n */\nexport type Instructions<R = never> = string | Effect.Effect<string | Resolved, never, R>\n\n/**\n * Resolves instructions to their text and span attributes.\n *\n * @category utils\n * @since 0.1.0\n */\nexport const resolve = Effect.fn(\"Instructions.resolve\")(function* <R = never>(instructions: Instructions<R>) {\n return Predicate.isString(instructions) ? { text: instructions } : toResolved(yield* instructions)\n})\n\nconst toResolved = (resolved: string | Resolved): Resolved =>\n Predicate.isString(resolved) ? { text: resolved } : resolved\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,MAAa,WAAW;;;;;;;;;AAsCxB,MAAa,UAAU,OAAO,GAAG,sBAAsB,CAAC,CAAC,WAAsB,cAA+B;CAC5G,OAAO,UAAU,SAAS,YAAY,IAAI,EAAE,MAAM,aAAa,IAAI,WAAW,OAAO,YAAY;AACnG,CAAC;AAED,MAAM,cAAc,aAClB,UAAU,SAAS,QAAQ,IAAI,EAAE,MAAM,SAAS,IAAI"}
|