@pattern-js/mod-buddy 0.4.0-main.c8eb671
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 +24 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge.d.ts +44 -0
- package/dist/knowledge.d.ts.map +1 -0
- package/dist/knowledge.js +227 -0
- package/dist/knowledge.js.map +1 -0
- package/dist/mod.d.ts +25 -0
- package/dist/mod.d.ts.map +1 -0
- package/dist/mod.js +70 -0
- package/dist/mod.js.map +1 -0
- package/dist/prompts.d.ts +17 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +59 -0
- package/dist/prompts.js.map +1 -0
- package/dist/threads.d.ts +26 -0
- package/dist/threads.d.ts.map +1 -0
- package/dist/threads.js +67 -0
- package/dist/threads.js.map +1 -0
- package/dist/tools.d.ts +24 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +251 -0
- package/dist/tools.js.map +1 -0
- package/dist/turn.d.ts +22 -0
- package/dist/turn.d.ts.map +1 -0
- package/dist/turn.js +276 -0
- package/dist/turn.js.map +1 -0
- package/docs/index.md +76 -0
- package/docs/ops/buddy.knowledge.search.md +13 -0
- package/docs/ops/buddy.status.md +6 -0
- package/docs/ops/buddy.thread.clear.md +4 -0
- package/docs/ops/buddy.thread.get.md +5 -0
- package/docs/ops/buddy.turn.abort.md +6 -0
- package/docs/ops/buddy.turn.begin.md +7 -0
- package/docs/ops/buddy.turn.save.md +4 -0
- package/package.json +58 -0
package/dist/turn.js
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @pattern-js/mod-buddy — the turn pipeline (Buddy's backend half).
|
|
3
|
+
*
|
|
4
|
+
* POST /buddy/api/turn → buddy.turn.begin (thread + instructions + model) →
|
|
5
|
+
* agents.agent + the ten pattern_* tools → agents.run → SSE out, while
|
|
6
|
+
* buddy.turn.save persists the updated history back to the thread. The
|
|
7
|
+
* pipeline is an ordinary editable workflow — Buddy is built from Pattern
|
|
8
|
+
* workflows, all the way down.
|
|
9
|
+
*
|
|
10
|
+
* The dock reads tool calls (incl. proposed docs) straight from the SSE
|
|
11
|
+
* turn events: `tool.activity` carries the tool's name and args.
|
|
12
|
+
*/
|
|
13
|
+
import { fromBody, fromParams, fromQuery, httpEndpoint, value, z } from "@pattern-js/core";
|
|
14
|
+
import { AGENTS_SERVICE } from "@pattern-js/mod-agents";
|
|
15
|
+
import { BUDDY_INSTRUCTIONS, contextBlock } from "./prompts.js";
|
|
16
|
+
import { clearThread, hasThreadStore, loadThread, saveThread } from "./threads.js";
|
|
17
|
+
import { CONTROL_PLANE_TOOLS } from "./tools.js";
|
|
18
|
+
const AI_CONFIG_SERVICE = "aiConfig";
|
|
19
|
+
/** The language alias Buddy runs on: "buddy" when configured, else the agent default. */
|
|
20
|
+
function buddyModelRef(services) {
|
|
21
|
+
const config = services[AI_CONFIG_SERVICE];
|
|
22
|
+
if (!config || typeof config.aliases !== "function")
|
|
23
|
+
return undefined;
|
|
24
|
+
const buddy = config.aliases().find((a) => a.name === "buddy" && (a.modality ?? "language") === "language");
|
|
25
|
+
return buddy ? { alias: "buddy" } : undefined;
|
|
26
|
+
}
|
|
27
|
+
const GLOBAL_SLUG = "~app";
|
|
28
|
+
/* ── ops ─────────────────────────────────────────────────────────────────── */
|
|
29
|
+
const turnBegin = {
|
|
30
|
+
type: "buddy.turn.begin",
|
|
31
|
+
title: "buddy.turn.begin",
|
|
32
|
+
description: "Start a Buddy turn: load the caller's thread for this workflow, assemble instructions (system prompt + canvas/run " +
|
|
33
|
+
"context), resolve the model (alias \"buddy\" → agent default). Outputs feed agents.agent/agents.run.",
|
|
34
|
+
reusable: false,
|
|
35
|
+
sensitivity: "privileged",
|
|
36
|
+
inputs: {
|
|
37
|
+
message: value(z.string()),
|
|
38
|
+
slug: value(z.string().optional()),
|
|
39
|
+
doc: value(z.record(z.string(), z.unknown()).optional()),
|
|
40
|
+
runId: value(z.string().optional()),
|
|
41
|
+
turnId: value(z.string().optional()),
|
|
42
|
+
},
|
|
43
|
+
outputs: {
|
|
44
|
+
input: value(z.string()),
|
|
45
|
+
history: value(),
|
|
46
|
+
instructions: value(z.string()),
|
|
47
|
+
model: value(),
|
|
48
|
+
turnId: value(z.string()),
|
|
49
|
+
slug: value(z.string()),
|
|
50
|
+
},
|
|
51
|
+
execute: async (ctx) => {
|
|
52
|
+
const [message, slug, doc, runId, turnId] = await Promise.all([
|
|
53
|
+
ctx.input.value("message"),
|
|
54
|
+
ctx.input.has("slug") ? ctx.input.value("slug") : undefined,
|
|
55
|
+
ctx.input.has("doc") ? ctx.input.value("doc") : undefined,
|
|
56
|
+
ctx.input.has("runId") ? ctx.input.value("runId") : undefined,
|
|
57
|
+
ctx.input.has("turnId") ? ctx.input.value("turnId") : undefined,
|
|
58
|
+
]);
|
|
59
|
+
if (!message?.trim())
|
|
60
|
+
throw new Error("buddy: an empty message is not a turn");
|
|
61
|
+
const threadSlug = slug?.trim() || GLOBAL_SLUG;
|
|
62
|
+
return {
|
|
63
|
+
input: message,
|
|
64
|
+
history: await loadThread(ctx, threadSlug),
|
|
65
|
+
instructions: BUDDY_INSTRUCTIONS + contextBlock({ slug: slug ?? undefined, doc, runId: runId ?? undefined }),
|
|
66
|
+
model: buddyModelRef(ctx.services),
|
|
67
|
+
turnId: turnId?.trim() || crypto.randomUUID(),
|
|
68
|
+
slug: threadSlug,
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
const turnSave = {
|
|
73
|
+
type: "buddy.turn.save",
|
|
74
|
+
title: "buddy.turn.save",
|
|
75
|
+
description: "Persist a finished turn: agents.run's updated history replaces the thread's messages (CAS-retried). " +
|
|
76
|
+
"Without mod-store this is a graceful no-op — Buddy just stays stateless.",
|
|
77
|
+
reusable: false,
|
|
78
|
+
inputs: { history: value(), slug: value(z.string()) },
|
|
79
|
+
outputs: { saved: value(z.boolean()) },
|
|
80
|
+
execute: async (ctx) => {
|
|
81
|
+
const [history, slug] = await Promise.all([ctx.input.value("history"), ctx.input.value("slug")]);
|
|
82
|
+
if (!Array.isArray(history))
|
|
83
|
+
return { saved: false };
|
|
84
|
+
return { saved: await saveThread(ctx, slug, history) };
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
const turnAbort = {
|
|
88
|
+
type: "buddy.turn.abort",
|
|
89
|
+
title: "buddy.turn.abort",
|
|
90
|
+
description: "Stop an in-flight Buddy turn by turnId (the dock's Stop button). Idempotent.",
|
|
91
|
+
reusable: false,
|
|
92
|
+
sensitivity: "privileged",
|
|
93
|
+
inputs: { turnId: value(z.string()) },
|
|
94
|
+
outputs: { result: value() },
|
|
95
|
+
execute: async (ctx) => {
|
|
96
|
+
const turnId = await ctx.input.value("turnId");
|
|
97
|
+
const agents = ctx.services[AGENTS_SERVICE];
|
|
98
|
+
const aborted = agents?.abortTurn(turnId) ?? false;
|
|
99
|
+
return { result: { ok: true, aborted } };
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
const threadGet = {
|
|
103
|
+
type: "buddy.thread.get",
|
|
104
|
+
title: "buddy.thread.get",
|
|
105
|
+
description: "The caller's Buddy thread for a workflow slug: { messages } (empty without mod-store).",
|
|
106
|
+
reusable: false,
|
|
107
|
+
sensitivity: "privileged",
|
|
108
|
+
inputs: { slug: value(z.string().optional()) },
|
|
109
|
+
outputs: { thread: value() },
|
|
110
|
+
execute: async (ctx) => {
|
|
111
|
+
const slug = ctx.input.has("slug") ? await ctx.input.value("slug") : undefined;
|
|
112
|
+
const messages = await loadThread(ctx, slug?.trim() || GLOBAL_SLUG);
|
|
113
|
+
return { thread: { slug: slug?.trim() || GLOBAL_SLUG, messages, persistent: hasThreadStore(ctx.services) } };
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
const threadClear = {
|
|
117
|
+
type: "buddy.thread.clear",
|
|
118
|
+
title: "buddy.thread.clear",
|
|
119
|
+
description: "Forget the caller's Buddy thread for a workflow slug (the dock's New conversation).",
|
|
120
|
+
reusable: false,
|
|
121
|
+
sensitivity: "privileged",
|
|
122
|
+
inputs: { slug: value(z.string().optional()) },
|
|
123
|
+
outputs: { result: value() },
|
|
124
|
+
execute: async (ctx) => {
|
|
125
|
+
const slug = ctx.input.has("slug") ? await ctx.input.value("slug") : undefined;
|
|
126
|
+
return { result: { ok: true, cleared: await clearThread(ctx, slug?.trim() || GLOBAL_SLUG) } };
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
/** The dock's boot probe: what Buddy can do in THIS app. */
|
|
130
|
+
export function statusOp(knowledge) {
|
|
131
|
+
return {
|
|
132
|
+
type: "buddy.status",
|
|
133
|
+
title: "buddy.status",
|
|
134
|
+
description: "Buddy's capabilities in this app: tool count, model alias in use, semantic-vs-lexical knowledge, thread persistence.",
|
|
135
|
+
reusable: false,
|
|
136
|
+
sensitivity: "privileged",
|
|
137
|
+
inputs: {},
|
|
138
|
+
outputs: { status: value() },
|
|
139
|
+
execute: async (ctx) => ({
|
|
140
|
+
status: {
|
|
141
|
+
ok: true,
|
|
142
|
+
tools: CONTROL_PLANE_TOOLS.length,
|
|
143
|
+
model: buddyModelRef(ctx.services)?.alias ?? "default",
|
|
144
|
+
knowledge: knowledge().isSemantic() ? "semantic" : "lexical",
|
|
145
|
+
threads: hasThreadStore(ctx.services),
|
|
146
|
+
},
|
|
147
|
+
}),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
export function turnOps(knowledge) {
|
|
151
|
+
return [turnBegin, turnSave, turnAbort, threadGet, threadClear, statusOp(knowledge)];
|
|
152
|
+
}
|
|
153
|
+
/* ── the pipeline + routes ───────────────────────────────────────────────── */
|
|
154
|
+
const admin = { scopes: ["admin"] };
|
|
155
|
+
/** POST /buddy/api/turn → SSE turn events (the dock's one streaming call). */
|
|
156
|
+
export function turnPipelineWorkflow() {
|
|
157
|
+
return {
|
|
158
|
+
id: "buddy.turn",
|
|
159
|
+
name: "Buddy · turn pipeline",
|
|
160
|
+
description: "A Buddy turn: message + editor context in → thread + instructions assembled → the agent runs with the ten " +
|
|
161
|
+
"pattern_* control-plane tools → turn events stream out (SSE) while the thread persists. Edit me to reshape " +
|
|
162
|
+
"Buddy — it is a workflow like any other.",
|
|
163
|
+
source: "code",
|
|
164
|
+
nodes: [
|
|
165
|
+
{
|
|
166
|
+
id: "in",
|
|
167
|
+
op: "boundary.http.request",
|
|
168
|
+
config: { method: "POST", path: "/buddy/api/turn", requireAuth: admin },
|
|
169
|
+
ui: { x: 40, y: 200, pair: "ok" },
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
id: "ex_body",
|
|
173
|
+
op: "core.object.extract",
|
|
174
|
+
config: { keys: ["message", "slug", "doc", "runId", "turnId"] },
|
|
175
|
+
ui: { x: 280, y: 200 },
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: "begin",
|
|
179
|
+
op: "buddy.turn.begin",
|
|
180
|
+
comment: "Thread + system prompt + canvas/run context + model resolution.",
|
|
181
|
+
ui: { x: 540, y: 200 },
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
id: "tools",
|
|
185
|
+
op: "agents.tools.workflows",
|
|
186
|
+
config: { tools: CONTROL_PLANE_TOOLS },
|
|
187
|
+
comment: "The ten restricted pattern_* tools, by explicit name.",
|
|
188
|
+
ui: { x: 800, y: 40 },
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
id: "agent",
|
|
192
|
+
op: "agents.agent",
|
|
193
|
+
config: { name: "Buddy", instructions: "(overridden per turn by buddy.turn.begin)" },
|
|
194
|
+
ui: { x: 1060, y: 120 },
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
id: "run",
|
|
198
|
+
op: "agents.run",
|
|
199
|
+
config: { maxTurns: 16 },
|
|
200
|
+
comment: "Streams turn events; tool calls are linked sub-runs.",
|
|
201
|
+
ui: { x: 1320, y: 200 },
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
id: "save",
|
|
205
|
+
op: "buddy.turn.save",
|
|
206
|
+
comment: "The updated history replaces the thread (CAS).",
|
|
207
|
+
ui: { x: 1580, y: 60 },
|
|
208
|
+
},
|
|
209
|
+
{ id: "ok", op: "boundary.http.response", config: { mode: "sse" }, ui: { x: 1580, y: 280, pair: "in" } },
|
|
210
|
+
],
|
|
211
|
+
edges: [
|
|
212
|
+
{ from: { node: "in", port: "body" }, to: { node: "ex_body", port: "object" } },
|
|
213
|
+
{ from: { node: "ex_body", port: "message" }, to: { node: "begin", port: "message" } },
|
|
214
|
+
{ from: { node: "ex_body", port: "slug" }, to: { node: "begin", port: "slug" } },
|
|
215
|
+
{ from: { node: "ex_body", port: "doc" }, to: { node: "begin", port: "doc" } },
|
|
216
|
+
{ from: { node: "ex_body", port: "runId" }, to: { node: "begin", port: "runId" } },
|
|
217
|
+
{ from: { node: "ex_body", port: "turnId" }, to: { node: "begin", port: "turnId" } },
|
|
218
|
+
// Control-thread the collector + the SSE gate onto the begin path (an
|
|
219
|
+
// out-gate with only a stream input would otherwise capture instantly).
|
|
220
|
+
{ from: { node: "begin", port: "out" }, to: { node: "tools", port: "in" } },
|
|
221
|
+
{ from: { node: "begin", port: "out" }, to: { node: "ok", port: "in" } },
|
|
222
|
+
{ from: { node: "tools", port: "toolset" }, to: { node: "agent", port: "tools" } },
|
|
223
|
+
{ from: { node: "begin", port: "instructions" }, to: { node: "agent", port: "instructions" } },
|
|
224
|
+
{ from: { node: "begin", port: "model" }, to: { node: "agent", port: "model" } },
|
|
225
|
+
{ from: { node: "agent", port: "agent" }, to: { node: "run", port: "agent" } },
|
|
226
|
+
{ from: { node: "begin", port: "input" }, to: { node: "run", port: "input" } },
|
|
227
|
+
{ from: { node: "begin", port: "history" }, to: { node: "run", port: "history" } },
|
|
228
|
+
{ from: { node: "begin", port: "turnId" }, to: { node: "run", port: "turnId" } },
|
|
229
|
+
{ from: { node: "run", port: "events" }, to: { node: "ok", port: "stream" } },
|
|
230
|
+
{ from: { node: "run", port: "history" }, to: { node: "save", port: "history" } },
|
|
231
|
+
{ from: { node: "begin", port: "slug" }, to: { node: "save", port: "slug" } },
|
|
232
|
+
],
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
/** The dock's plumbing routes (thread load/clear, stop, status). */
|
|
236
|
+
export function buddyRoutes() {
|
|
237
|
+
return [
|
|
238
|
+
httpEndpoint({
|
|
239
|
+
id: "buddy.route.thread.get",
|
|
240
|
+
name: "Buddy · GET /buddy/api/thread",
|
|
241
|
+
method: "GET",
|
|
242
|
+
path: "/buddy/api/thread",
|
|
243
|
+
op: "buddy.thread.get",
|
|
244
|
+
io: { in: { slug: fromQuery() }, out: "thread" },
|
|
245
|
+
auth: admin,
|
|
246
|
+
}),
|
|
247
|
+
httpEndpoint({
|
|
248
|
+
id: "buddy.route.thread.clear",
|
|
249
|
+
name: "Buddy · POST /buddy/api/thread/clear",
|
|
250
|
+
method: "POST",
|
|
251
|
+
path: "/buddy/api/thread/clear",
|
|
252
|
+
op: "buddy.thread.clear",
|
|
253
|
+
io: { in: { slug: fromBody() }, out: "result" },
|
|
254
|
+
auth: admin,
|
|
255
|
+
}),
|
|
256
|
+
httpEndpoint({
|
|
257
|
+
id: "buddy.route.turn.abort",
|
|
258
|
+
name: "Buddy · POST /buddy/api/turn/:turnId/abort",
|
|
259
|
+
method: "POST",
|
|
260
|
+
path: "/buddy/api/turn/:turnId/abort",
|
|
261
|
+
op: "buddy.turn.abort",
|
|
262
|
+
io: { in: { turnId: fromParams() }, out: "result" },
|
|
263
|
+
auth: admin,
|
|
264
|
+
}),
|
|
265
|
+
httpEndpoint({
|
|
266
|
+
id: "buddy.route.status",
|
|
267
|
+
name: "Buddy · GET /buddy/api/status",
|
|
268
|
+
method: "GET",
|
|
269
|
+
path: "/buddy/api/status",
|
|
270
|
+
op: "buddy.status",
|
|
271
|
+
io: { out: "status" },
|
|
272
|
+
auth: admin,
|
|
273
|
+
}),
|
|
274
|
+
];
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=turn.js.map
|
package/dist/turn.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn.js","sourceRoot":"","sources":["../src/turn.ts"],"names":[],"mappings":"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"}
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Buddy
|
|
2
|
+
|
|
3
|
+
`@pattern-js/mod-buddy` puts an assistant **inside the editor**: describe what
|
|
4
|
+
you want, and Buddy drafts the workflow — grounding itself in this app's
|
|
5
|
+
handbook and op catalog, repairing its own mistakes against the validator,
|
|
6
|
+
and applying proposals to your open canvas as ordinary, undoable edits. You
|
|
7
|
+
keep the Save and Deploy buttons. And because Buddy's own pipeline is a
|
|
8
|
+
Pattern workflow, you can open it on the canvas and reshape it.
|
|
9
|
+
|
|
10
|
+
```jsonc
|
|
11
|
+
{
|
|
12
|
+
"mods": [
|
|
13
|
+
"@pattern-js/mod-ai", "@pattern-js/mod-agents", "@pattern-js/mod-docs",
|
|
14
|
+
"@pattern-js/mod-admin", "@pattern-js/mod-identity",
|
|
15
|
+
"@pattern-js/mod-buddy"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`@pattern-js/mod-docs` is a **hard requirement**, not a nicety: the
|
|
21
|
+
`pattern_list_ops` / `pattern_get_op` / `pattern_search_docs` tools wire its
|
|
22
|
+
`docs.*` ops, and the knowledge engine retrieves over its handbook. Load
|
|
23
|
+
order in `mods` doesn't matter — seeded workflows register once every mod's
|
|
24
|
+
ops are in.
|
|
25
|
+
|
|
26
|
+
Optional but recommended: `@pattern-js/mod-store` (threads survive reloads)
|
|
27
|
+
and `@pattern-js/mod-vectors` (semantic knowledge — see below).
|
|
28
|
+
|
|
29
|
+
## The control-plane tools
|
|
30
|
+
|
|
31
|
+
Buddy's hands are ten **restricted** `boundary.tool` workflows — the
|
|
32
|
+
`pattern_*` control plane:
|
|
33
|
+
|
|
34
|
+
| Tool | What it does | Scope its ops demand |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| `pattern_list_ops` / `pattern_get_op` | the op catalog, schemas + prose | `workflows:read` |
|
|
37
|
+
| `pattern_search_docs` | handbook + catalog retrieval | `workflows:read` |
|
|
38
|
+
| `pattern_get_workflow` | meta, versions, live/latest docs | `workflows:read` |
|
|
39
|
+
| `pattern_validate_workflow` | located errors, nothing saved | `workflows:read` |
|
|
40
|
+
| `pattern_propose_workflow` | validate + surface an Apply card | `workflows:read` |
|
|
41
|
+
| `pattern_save_workflow_draft` | mint an immutable draft version | `workflows:write` |
|
|
42
|
+
| `pattern_deploy_workflow` | activate a version (needs approval) | `deploy` |
|
|
43
|
+
| `pattern_list_runs` / `pattern_get_run` | traces, spans, masked I/O | `runs:read` |
|
|
44
|
+
|
|
45
|
+
`restricted: true` keeps them out of every `["*"]` toolset and MCP wildcard —
|
|
46
|
+
they are offered only by explicit name, and every call is a traced sub-run on
|
|
47
|
+
the Runs page.
|
|
48
|
+
|
|
49
|
+
## The same tools, outside: the Pattern MCP server
|
|
50
|
+
|
|
51
|
+
`POST /mcp/pattern` exposes exactly these ten tools to external MCP clients
|
|
52
|
+
(Claude Code, Cursor, …), gated by **API tokens** (admin → Access → API
|
|
53
|
+
tokens). A token's scopes decide what succeeds: `workflows:read` +
|
|
54
|
+
`workflows:write` makes an authoring token that can draft but never ship;
|
|
55
|
+
`deploy` is its own decision. For local dev, `pattern mcp` serves the same
|
|
56
|
+
tools over stdio with no token — your shell already owns the box.
|
|
57
|
+
|
|
58
|
+
## Knowledge: lexical first, semantic when present
|
|
59
|
+
|
|
60
|
+
`buddy.knowledge.search` answers from the live handbook and op catalog. The
|
|
61
|
+
baseline is lexical — genuinely strong on structured docs and exact op names.
|
|
62
|
+
When `@pattern-js/mod-vectors` **and an embedding alias** are installed, a
|
|
63
|
+
boot indexer chunks the handbook into the `buddy.docs` collection
|
|
64
|
+
(content-hashed — upgrades re-embed only the diff) and the same op silently
|
|
65
|
+
upgrades to hybrid semantic retrieval. Name an embedding alias `buddy` to
|
|
66
|
+
pin which model indexes; otherwise the first embedding alias wins.
|
|
67
|
+
|
|
68
|
+
## Threads, model, and the pipeline
|
|
69
|
+
|
|
70
|
+
- Conversations persist per (workflow, user) in mod-store's `buddy.threads`
|
|
71
|
+
— reload the editor and the conversation is still there.
|
|
72
|
+
- Buddy runs on the `buddy` **language alias** when you define one (Settings →
|
|
73
|
+
AI Providers), else the app's default alias.
|
|
74
|
+
- The whole turn is the `buddy.turn` workflow: request → `buddy.turn.begin`
|
|
75
|
+
(thread + context + model) → agent + tools → SSE out, history saved back.
|
|
76
|
+
Fork it, add a guardrail, swap the toolset — it's yours.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Buddy's retrieval op: search the live handbook (every mod's docs chapter) and
|
|
2
|
+
the op catalog in one query. Returns `{ results: [{ title, path, snippet,
|
|
3
|
+
score }] }` — `path` is `guide/<chapter>/<file>` for handbook pages and
|
|
4
|
+
`op/<type>` for catalog hits.
|
|
5
|
+
|
|
6
|
+
Two engines, one shape: the baseline is lexical (token overlap over titles,
|
|
7
|
+
headings, op types and descriptions — genuinely strong on this corpus of
|
|
8
|
+
structured docs and exact op names). When `@pattern-js/mod-vectors` and an
|
|
9
|
+
embedding alias (`buddy`, falling back to `default`) are installed, the same
|
|
10
|
+
op silently upgrades to semantic retrieval. Nothing downstream changes.
|
|
11
|
+
|
|
12
|
+
This is the body of the `pattern_search_docs` tool; wire it directly anywhere
|
|
13
|
+
you want docs-grounded answers.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Buddy's capability probe — what the dock reads on mount: `{ ok, tools,
|
|
2
|
+
model, knowledge, threads }`. `model` is the alias Buddy runs on (`buddy`
|
|
3
|
+
when defined, else `default`), `knowledge` reports `semantic` once the boot
|
|
4
|
+
indexer has the handbook in mod-vectors (else `lexical`), and `threads` says
|
|
5
|
+
whether conversations persist (mod-store present). Privileged: gate the
|
|
6
|
+
trigger with the `admin` scope.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
The caller's Buddy thread for a workflow slug: `{ slug, messages,
|
|
2
|
+
persistent }` — the dock loads this on mount so conversations survive
|
|
3
|
+
reloads. `persistent: false` means mod-store is absent and threads are
|
|
4
|
+
per-session only. Threads are scoped per (workflow, user); no slug means the
|
|
5
|
+
app-wide thread. Privileged: gate the trigger with the `admin` scope.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Stop an in-flight Buddy turn by its `turnId` (the dock's Stop button). A
|
|
2
|
+
streaming agent turn settles for the engine as soon as its out-gates capture,
|
|
3
|
+
so run-cancel can't reach it — this goes through the agents service's
|
|
4
|
+
per-turn AbortController instead. Idempotent: aborting a finished or unknown
|
|
5
|
+
turn answers `{ ok: true, aborted: false }`. Privileged: gate the trigger
|
|
6
|
+
with the `admin` scope.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
The head of the `buddy.turn` pipeline: takes the dock's `{ message, slug?,
|
|
2
|
+
doc?, runId?, turnId? }`, loads the caller's thread for that workflow (empty
|
|
3
|
+
without mod-store), assembles the instructions (Buddy's system prompt + the
|
|
4
|
+
open canvas document + the run under debug), and resolves the model — the
|
|
5
|
+
`buddy` language alias when you've defined one, else the agent default.
|
|
6
|
+
Outputs wire straight into `agents.agent`/`agents.run`. Privileged: gate the
|
|
7
|
+
trigger with the `admin` scope.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
The tail of the `buddy.turn` pipeline: waits for `agents.run`'s updated
|
|
2
|
+
`history` and replaces the thread's messages with it (compare-and-swap,
|
|
3
|
+
retried). Without mod-store it is a graceful no-op — Buddy just stays
|
|
4
|
+
stateless. Wire `history` from agents.run and `slug` from buddy.turn.begin.
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pattern-js/mod-buddy",
|
|
3
|
+
"version": "0.4.0-main.c8eb671",
|
|
4
|
+
"description": "Buddy — the in-admin workflow assistant for Pattern. A chat dock in the editor that drafts workflows, self-repairs against the validator, debugs failed runs from traces, and applies proposals to your open canvas. Its control-plane toolset (the pattern_* tools) doubles as the Pattern MCP server surface.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"pattern",
|
|
7
|
+
"mod",
|
|
8
|
+
"buddy",
|
|
9
|
+
"assistant",
|
|
10
|
+
"agent",
|
|
11
|
+
"mcp",
|
|
12
|
+
"control-plane"
|
|
13
|
+
],
|
|
14
|
+
"type": "module",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"main": "./dist/index.js",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"docs",
|
|
27
|
+
"README.md"
|
|
28
|
+
],
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"zod": "^4.0.0",
|
|
31
|
+
"@pattern-js/core": "0.4.0-main.c8eb671",
|
|
32
|
+
"@pattern-js/mod-ai": "0.4.0-main.c8eb671",
|
|
33
|
+
"@pattern-js/mod-agents": "0.4.0-main.c8eb671",
|
|
34
|
+
"@pattern-js/runtime-node": "0.4.0-main.c8eb671",
|
|
35
|
+
"@pattern-js/mod-docs": "0.4.0-main.c8eb671"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^22.0.0",
|
|
39
|
+
"typescript": "^5.6.0",
|
|
40
|
+
"@pattern-js/mod-admin": "0.4.0-main.c8eb671",
|
|
41
|
+
"@pattern-js/mod-identity": "0.4.0-main.c8eb671"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=22.5"
|
|
45
|
+
},
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "git+https://github.com/makkr-studio/pattern.git",
|
|
49
|
+
"directory": "packages/mod-buddy"
|
|
50
|
+
},
|
|
51
|
+
"homepage": "https://github.com/makkr-studio/pattern#readme",
|
|
52
|
+
"bugs": "https://github.com/makkr-studio/pattern/issues",
|
|
53
|
+
"author": "Makkr Studio (https://github.com/makkr-studio)",
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsc -p tsconfig.json",
|
|
56
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
57
|
+
}
|
|
58
|
+
}
|