llm-agent-runtime 0.1.2 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/USAGE.md +391 -0
- package/dist/create-runtime.d.ts.map +1 -1
- package/dist/create-runtime.js +4 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/services/conversation.d.ts.map +1 -1
- package/dist/services/conversation.js +20 -8
- package/dist/services/flow-router.d.ts.map +1 -1
- package/dist/services/flow-router.js +12 -0
- package/dist/services/simple-config.d.ts +2 -19
- package/dist/services/simple-config.d.ts.map +1 -1
- package/dist/types.d.ts +18 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# llm-agent-runtime
|
|
2
2
|
|
|
3
|
-
Reusable LangGraph agent runtime
|
|
3
|
+
Reusable LangGraph agent runtime: intent routing, sticky flows, checkpointer, tool outputs.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Docs:** [USAGE.md](./USAGE.md)
|
package/USAGE.md
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
# llm-agent-runtime
|
|
2
|
+
|
|
3
|
+
Reusable LangGraph agent engine. Your app supplies **intents, prompts, and tools**. The package runs:
|
|
4
|
+
|
|
5
|
+
`resolveFlow → runAgent → extract tool outputs → finalize`
|
|
6
|
+
|
|
7
|
+
Same shape as Xel-agent, but flexible for any product.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install llm-agent-runtime
|
|
15
|
+
# or
|
|
16
|
+
pnpm add llm-agent-runtime
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Peer dependencies** (usually already in a LangChain app):
|
|
20
|
+
|
|
21
|
+
- `@langchain/core`
|
|
22
|
+
- `@langchain/langgraph`
|
|
23
|
+
- `@langchain/langgraph-checkpoint`
|
|
24
|
+
- `zod`
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Quick start
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { createAgentRuntime } from "llm-agent-runtime";
|
|
32
|
+
import { tool } from "@langchain/core/tools";
|
|
33
|
+
import { z } from "zod";
|
|
34
|
+
|
|
35
|
+
const greet = tool(async () => "ok", {
|
|
36
|
+
name: "noop",
|
|
37
|
+
description: "No-op",
|
|
38
|
+
schema: z.object({}),
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const runtime = await createAgentRuntime({
|
|
42
|
+
redisUrl: process.env.REDIS_URL, // omit → in-memory checkpointer
|
|
43
|
+
// llm omitted → reads process.env (see Env vars below)
|
|
44
|
+
|
|
45
|
+
intents: [
|
|
46
|
+
{
|
|
47
|
+
name: "greetings",
|
|
48
|
+
examples: ["hi", "hello", "good morning"],
|
|
49
|
+
description: "hello or small talk",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: "create_campaign",
|
|
53
|
+
examples: ["create a campaign", "start fundraising"],
|
|
54
|
+
sticky: true,
|
|
55
|
+
description: "new campaign wizard",
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
|
|
59
|
+
intentRegistry: {
|
|
60
|
+
greetings: {
|
|
61
|
+
prompt: (ctx) =>
|
|
62
|
+
`Greet the user. Name: ${ctx.context?.contactName ?? "friend"}.`,
|
|
63
|
+
tools: () => [greet],
|
|
64
|
+
},
|
|
65
|
+
create_campaign: {
|
|
66
|
+
prompt: () => "Help create a campaign step by step. Call create_campaign when ready.",
|
|
67
|
+
tools: (phoneKey) => [/* your tools scoped by phoneKey */],
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
toolOutputMap: {
|
|
72
|
+
create_campaign: "campaign",
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
await runtime.connect();
|
|
77
|
+
|
|
78
|
+
const result = await runtime.invoke({
|
|
79
|
+
message: "hi",
|
|
80
|
+
threadId: "user-123",
|
|
81
|
+
context: { contactName: "Ada" },
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
console.log(result.answer, result.intent, result.flow, result.toolOutputs);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## What you pass vs what the library does
|
|
90
|
+
|
|
91
|
+
| You configure | Library handles |
|
|
92
|
+
| --- | --- |
|
|
93
|
+
| `intents` (examples + `sticky`) | Hybrid LLM + embedding router |
|
|
94
|
+
| `intentRegistry` (prompt + tools) | LangGraph agent + Redis/memory checkpointer |
|
|
95
|
+
| `toolOutputMap` | Parse tool calls into structured outputs |
|
|
96
|
+
| `completeOn` | Sticky-flow completion + Redis flow state |
|
|
97
|
+
| `menuMap` (optional) | Digit → intent after a numbered menu |
|
|
98
|
+
| Prompts, API tools, webhooks | — stay in your app |
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Config reference
|
|
103
|
+
|
|
104
|
+
### `createAgentRuntime(config)`
|
|
105
|
+
|
|
106
|
+
#### Required
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
intents: IntentDefinition[]
|
|
110
|
+
intentRegistry: Record<string, { prompt: (ctx) => string; tools: (phoneKey) => Tool[] }>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### Common optional
|
|
114
|
+
|
|
115
|
+
| Option | Default | Purpose |
|
|
116
|
+
| --- | --- | --- |
|
|
117
|
+
| `redisUrl` | none (MemorySaver) | Checkpointer + flow state + optional answer cache |
|
|
118
|
+
| `llm` | `llmConfigFromEnv()` | Provider / models |
|
|
119
|
+
| `cache.enabled` | `false` | Exact-match answer cache (needs Redis) |
|
|
120
|
+
| `toolOutputMap` | raw tool args | Map tool name → output key |
|
|
121
|
+
| `completeOn` | keys of `toolOutputMap` | Tool names that finish a sticky flow |
|
|
122
|
+
| `menuMap` | `{}` | `{ "1": "create_campaign" }` for digit menus |
|
|
123
|
+
| `intentAliases` | `{}` | Legacy name → catalog name |
|
|
124
|
+
| `defaultIntent` | first intent | Fallback intent |
|
|
125
|
+
| `buildSystemPrompt` | registry `prompt` | One builder for all intents |
|
|
126
|
+
| `resolvePhoneKey` | `phoneKey ?? threadId` | Key passed to `tools(phoneKey)` |
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Intents
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
intents: [
|
|
134
|
+
{
|
|
135
|
+
name: "greetings",
|
|
136
|
+
examples: ["hi", "hello"],
|
|
137
|
+
description: "Shown to the LLM router",
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: "create_campaign",
|
|
141
|
+
examples: ["create a campaign"],
|
|
142
|
+
sticky: true, // keep this flow across turns until completeOn fires
|
|
143
|
+
},
|
|
144
|
+
]
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- **examples** — embedding routing
|
|
148
|
+
- **sticky** — multi-step wizards
|
|
149
|
+
- **description** — LLM intent router
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Prompts & tools (`intentRegistry`)
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
intentRegistry: {
|
|
157
|
+
greetings: {
|
|
158
|
+
prompt: (ctx) => string,
|
|
159
|
+
tools: (phoneKey) => DynamicStructuredTool[],
|
|
160
|
+
},
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
`prompt` receives:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
{
|
|
168
|
+
hasConversationHistory: boolean
|
|
169
|
+
intent: string
|
|
170
|
+
intentScore?: number
|
|
171
|
+
message?: string
|
|
172
|
+
context?: Record<string, unknown> // whatever you passed to invoke()
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Or use one builder for everything:
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
buildSystemPrompt: (ctx) => combineGeneralAndIntent(ctx)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Tool outputs (`toolOutputMap`)
|
|
185
|
+
|
|
186
|
+
Replaces hand-written extractors:
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
toolOutputMap: {
|
|
190
|
+
create_campaign: "campaign",
|
|
191
|
+
buy_airtime: "buyAirtime",
|
|
192
|
+
// Nested field on args + seed:
|
|
193
|
+
propose_tickets: { as: "tickets", from: "tickets", initial: [] },
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Result lands on `result.toolOutputs` and completed keys on `result.extras`.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Flow completion (`completeOn`)
|
|
202
|
+
|
|
203
|
+
Pass tool **names**. When any of them produces output, the sticky flow ends:
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
completeOn: ["create_campaign", "buy_airtime", "add_airtime"]
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
If you omit `completeOn`, the library defaults `completeOn` to the keys of `toolOutputMap`.
|
|
210
|
+
|
|
211
|
+
This is tuned to Xel-style wizards: when a sticky flow is already active and the user message looks like wizard input (digits / yes-no), the router LLM call is skipped for that turn to reduce tokens.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Menu digits (`menuMap`)
|
|
216
|
+
|
|
217
|
+
Optional. Needed only if users pick a numbered menu (`1`, `2`, …).
|
|
218
|
+
|
|
219
|
+
The **prompt** shows the menu text. **`menuMap`** tells the **router** that `"1"` means `create_campaign`. Without it, a bare `"1"` is not reliably routed.
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
menuMap: {
|
|
223
|
+
"1": "create_campaign",
|
|
224
|
+
"2": "support_campaign",
|
|
225
|
+
"3": "buy_airtime_and_data",
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Invoke
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
const result = await runtime.invoke({
|
|
235
|
+
message: "hi",
|
|
236
|
+
threadId: "whatsapp:234...", // conversation / checkpoint id
|
|
237
|
+
phoneKey: "234...", // optional; passed to tools()
|
|
238
|
+
explicitIntent: "greetings", // optional; skips hybrid router
|
|
239
|
+
context: {
|
|
240
|
+
contactName: "Ada",
|
|
241
|
+
userInfo: { email: "ada@example.com" },
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Result**
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
{
|
|
250
|
+
messages: unknown[]
|
|
251
|
+
answer?: string
|
|
252
|
+
intent: { intent: string, score: number }
|
|
253
|
+
flow: { active: boolean, intent: string | null }
|
|
254
|
+
toolOutputs: Record<string, unknown>
|
|
255
|
+
flowCompleted: boolean
|
|
256
|
+
extras?: Record<string, unknown>
|
|
257
|
+
router?: { action: "continue" | "switch" | "cancel", reason?: string }
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## Lifecycle
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
await runtime.connect() // Redis (if redisUrl set)
|
|
267
|
+
await runtime.invoke(...)
|
|
268
|
+
await runtime.clearFlow(id) // drop sticky flow state
|
|
269
|
+
await runtime.disconnect()
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Env vars (when `llm` is omitted)
|
|
275
|
+
|
|
276
|
+
| Variable | Notes |
|
|
277
|
+
| --- | --- |
|
|
278
|
+
| `LLM_PROVIDER` | `ollama` (default) or `openai` |
|
|
279
|
+
| `EMBEDDINGS_PROVIDER` | defaults to `LLM_PROVIDER` |
|
|
280
|
+
| `OLLAMA_MODEL` | default `qwen2.5:7b` |
|
|
281
|
+
| `OLLAMA_BASE_URL` | e.g. `http://localhost:11434` |
|
|
282
|
+
| `INTENT_ROUTER_MODEL` | optional smaller router model |
|
|
283
|
+
| `OLLAMA_EMBEDDINGS_MODEL` | default `mxbai-embed-large:latest` |
|
|
284
|
+
| `OPENAI_API_KEY` | required for openai |
|
|
285
|
+
| `OPENAI_MODEL` | default `gpt-4o-mini` |
|
|
286
|
+
| `OPENAI_EMBEDDINGS_MODEL` | default `text-embedding-3-small` |
|
|
287
|
+
| `REDIS_URL` | your app usually passes this as `redisUrl` |
|
|
288
|
+
| `ANSWER_CACHE` | app convention: `"1"` to enable cache |
|
|
289
|
+
|
|
290
|
+
Or pass LLM explicitly:
|
|
291
|
+
|
|
292
|
+
```ts
|
|
293
|
+
import { llmConfigFromEnv } from "llm-agent-runtime";
|
|
294
|
+
|
|
295
|
+
createAgentRuntime({
|
|
296
|
+
llm: llmConfigFromEnv(),
|
|
297
|
+
// or
|
|
298
|
+
llm: { provider: "openai", model: "gpt-4o-mini", apiKey: "..." },
|
|
299
|
+
})
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Minimal app shape (recommended)
|
|
305
|
+
|
|
306
|
+
```
|
|
307
|
+
your-app/
|
|
308
|
+
agent/
|
|
309
|
+
runtime.ts # createAgentRuntime({ ... })
|
|
310
|
+
intents.ts # intents + menuMap + aliases
|
|
311
|
+
prompts/ # prompt strings
|
|
312
|
+
tools/ # LangChain tools / API clients
|
|
313
|
+
controllers/ # HTTP / WhatsApp — call runtime.invoke()
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Keep channel adapters and product APIs **out** of this package.
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## Full example (Xel-like)
|
|
321
|
+
|
|
322
|
+
```ts
|
|
323
|
+
import { createAgentRuntime } from "llm-agent-runtime";
|
|
324
|
+
|
|
325
|
+
const runtime = await createAgentRuntime({
|
|
326
|
+
redisUrl: process.env.REDIS_URL ?? "redis://localhost:6379",
|
|
327
|
+
cache: { enabled: process.env.ANSWER_CACHE === "1" },
|
|
328
|
+
|
|
329
|
+
intents: [
|
|
330
|
+
{ name: "greetings", examples: ["hi", "hello"] },
|
|
331
|
+
{
|
|
332
|
+
name: "create_campaign",
|
|
333
|
+
examples: ["create a campaign"],
|
|
334
|
+
sticky: true,
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
name: "buy_airtime_and_data",
|
|
338
|
+
examples: ["buy airtime", "vend airtime"],
|
|
339
|
+
sticky: true,
|
|
340
|
+
},
|
|
341
|
+
],
|
|
342
|
+
|
|
343
|
+
menuMap: {
|
|
344
|
+
"1": "create_campaign",
|
|
345
|
+
"4": "buy_airtime_and_data",
|
|
346
|
+
},
|
|
347
|
+
|
|
348
|
+
intentAliases: {
|
|
349
|
+
buy_airtime: "buy_airtime_and_data",
|
|
350
|
+
},
|
|
351
|
+
|
|
352
|
+
intentRegistry: {
|
|
353
|
+
greetings: {
|
|
354
|
+
prompt: (ctx) => `Greet ${ctx.context?.contactName ?? "there"}. Show menu 1–7.`,
|
|
355
|
+
tools: () => [],
|
|
356
|
+
},
|
|
357
|
+
create_campaign: {
|
|
358
|
+
prompt: () => "Walk through campaign creation.",
|
|
359
|
+
tools: (phoneKey) => createCampaignTools(phoneKey),
|
|
360
|
+
},
|
|
361
|
+
buy_airtime_and_data: {
|
|
362
|
+
prompt: () => "Help buy airtime/data.",
|
|
363
|
+
tools: (phoneKey) => airtimeTools(phoneKey),
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
|
|
367
|
+
toolOutputMap: {
|
|
368
|
+
create_campaign: "campaign",
|
|
369
|
+
buy_airtime: "buyAirtime",
|
|
370
|
+
add_airtime: "addAirtime",
|
|
371
|
+
},
|
|
372
|
+
completeOn: ["create_campaign", "buy_airtime", "add_airtime"],
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
await runtime.connect();
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## Exports
|
|
381
|
+
|
|
382
|
+
```ts
|
|
383
|
+
import {
|
|
384
|
+
createAgentRuntime,
|
|
385
|
+
llmConfigFromEnv,
|
|
386
|
+
getLastMessageContent,
|
|
387
|
+
// advanced (usually not needed)
|
|
388
|
+
createToolOutputExtractor,
|
|
389
|
+
toolOutputMapToExtractors,
|
|
390
|
+
} from "llm-agent-runtime";
|
|
391
|
+
```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-runtime.d.ts","sourceRoot":"","sources":["../src/create-runtime.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,kBAAkB,EAClB,WAAW,EACX,YAAY,EAEb,MAAM,YAAY,CAAC;AAepB,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IACtD,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,gEAAgE;IAChE,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClE,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,4EAA4E;IAC5E,0BAA0B,EAAE,MAAM,IAAI,CAAC;CACxC,CAAC;AAEF;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"create-runtime.d.ts","sourceRoot":"","sources":["../src/create-runtime.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,kBAAkB,EAClB,WAAW,EACX,YAAY,EAEb,MAAM,YAAY,CAAC;AAepB,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IACtD,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,gEAAgE;IAChE,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClE,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,4EAA4E;IAC5E,0BAA0B,EAAE,MAAM,IAAI,CAAC;CACxC,CAAC;AAEF;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,YAAY,CAAC,CA0OvB"}
|
package/dist/create-runtime.js
CHANGED
|
@@ -52,10 +52,12 @@ export async function createAgentRuntime(config) {
|
|
|
52
52
|
: null;
|
|
53
53
|
const toolExtractors = config.toolExtractors ?? fromMap?.toolExtractors;
|
|
54
54
|
const initialToolOutputs = config.initialToolOutputs ?? fromMap?.initialToolOutputs;
|
|
55
|
+
const completeOn = config.completeOn ??
|
|
56
|
+
(config.toolOutputMap ? Object.keys(config.toolOutputMap) : undefined);
|
|
55
57
|
const finalizeFlow = config.finalizeFlow ??
|
|
56
|
-
(
|
|
58
|
+
(completeOn?.length
|
|
57
59
|
? createCompleteOnFinalize({
|
|
58
|
-
completeOn
|
|
60
|
+
completeOn,
|
|
59
61
|
toolOutputMap: config.toolOutputMap,
|
|
60
62
|
})
|
|
61
63
|
: undefined);
|
package/dist/index.d.ts
CHANGED
|
@@ -3,9 +3,9 @@ export { createModels } from "./llm.js";
|
|
|
3
3
|
export { llmConfigFromEnv } from "./env-llm.js";
|
|
4
4
|
export { createRedis } from "./redis.js";
|
|
5
5
|
export { extractRawToolOutputs, extractToolCallArgs, getToolCallsFromMessages, createToolOutputExtractor, } from "./services/extract.js";
|
|
6
|
-
export { toolOutputMapToExtractors, createCompleteOnFinalize,
|
|
6
|
+
export { toolOutputMapToExtractors, createCompleteOnFinalize, } from "./services/simple-config.js";
|
|
7
7
|
export { isWizardInput } from "./services/flow-router.js";
|
|
8
8
|
export { getLastMessageContent } from "./utils/message.js";
|
|
9
9
|
export { normalize } from "./utils/normalize.js";
|
|
10
|
-
export type { AgentRuntimeConfig, CacheConfig, ChatFlowState, DetectedIntentResult, FinalizeFlowInput, FinalizeFlowResult, FlowResolution, FlowState, IntentBinding, IntentDefinition, IntentRegistry, InvokeInput, InvokeResult, LlmConfig, LlmIntentResult, LlmProvider, PromptContext, ToolCall, ToolExtractor, ToolExtractorMap, TracingConfig, } from "./types.js";
|
|
10
|
+
export type { AgentRuntimeConfig, CacheConfig, ChatFlowState, DetectedIntentResult, FinalizeFlowInput, FinalizeFlowResult, FlowResolution, FlowState, IntentBinding, IntentDefinition, IntentRegistry, InvokeInput, InvokeResult, LlmConfig, LlmIntentResult, LlmProvider, PromptContext, ToolCall, ToolExtractor, ToolExtractorMap, ToolOutputMap, TracingConfig, } from "./types.js";
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,yBAAyB,EACzB,wBAAwB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,YAAY,EACV,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,YAAY,EACZ,SAAS,EACT,eAAe,EACf,WAAW,EACX,aAAa,EACb,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/services/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,YAAY;+
|
|
1
|
+
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/services/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,YAAY;+CAWV,MAAM;kDAwCT,OAAO,EAAE,KAAG,MAAM;gDAkB3D,MAAM,KACf,OAAO,CAAC,MAAM,CAAC;EAUnB"}
|
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
export function createConversationService(agentFactory) {
|
|
2
|
+
// Keep intent-router prompts small (matches Xel-agent defaults).
|
|
3
|
+
const AGENT_HISTORY_LIMIT = 4;
|
|
4
|
+
const INTENT_ROUTER_HISTORY_LIMIT = 3;
|
|
5
|
+
const INTENT_ROUTER_MESSAGE_CHAR_LIMIT = 200;
|
|
6
|
+
const isHumanOrAiMessage = (message) => {
|
|
7
|
+
const type = message._getType?.() ?? message.type ?? "";
|
|
8
|
+
return type === "human" || type === "ai";
|
|
9
|
+
};
|
|
2
10
|
const getManagedConversationMessages = async (threadId) => {
|
|
3
11
|
const state = await agentFactory.getAgentState(threadId);
|
|
4
12
|
const messages = state.values.messages ?? [];
|
|
5
13
|
return messages
|
|
6
14
|
.filter((message) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
15
|
+
if (!isHumanOrAiMessage(message))
|
|
16
|
+
return false;
|
|
17
|
+
const content = String(message?.content ?? "")
|
|
18
|
+
.toLowerCase();
|
|
19
|
+
return !(content.includes("tool failed") ||
|
|
20
|
+
content.includes("error") ||
|
|
21
|
+
content.includes("undefined"));
|
|
11
22
|
})
|
|
12
|
-
.slice(-
|
|
23
|
+
.slice(-AGENT_HISTORY_LIMIT);
|
|
13
24
|
};
|
|
14
25
|
const getMessageRole = (message) => {
|
|
15
26
|
const type = message._getType?.() ?? message.type ?? "";
|
|
@@ -17,7 +28,8 @@ export function createConversationService(agentFactory) {
|
|
|
17
28
|
return "User";
|
|
18
29
|
if (type === "ai")
|
|
19
30
|
return "Assistant";
|
|
20
|
-
|
|
31
|
+
// Should not happen due to isHumanOrAiMessage filter.
|
|
32
|
+
return "User";
|
|
21
33
|
};
|
|
22
34
|
const getMessageText = (message) => {
|
|
23
35
|
const content = message.content;
|
|
@@ -35,10 +47,10 @@ export function createConversationService(agentFactory) {
|
|
|
35
47
|
if (messages.length === 0)
|
|
36
48
|
return "(no prior messages)";
|
|
37
49
|
return messages
|
|
38
|
-
.slice(-
|
|
50
|
+
.slice(-INTENT_ROUTER_HISTORY_LIMIT)
|
|
39
51
|
.map((message) => {
|
|
40
52
|
const role = getMessageRole(message);
|
|
41
|
-
const text = getMessageText(message).slice(0,
|
|
53
|
+
const text = getMessageText(message).slice(0, INTENT_ROUTER_MESSAGE_CHAR_LIMIT);
|
|
42
54
|
return text ? `${role}: ${text}` : null;
|
|
43
55
|
})
|
|
44
56
|
.filter(Boolean)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow-router.d.ts","sourceRoot":"","sources":["../../src/services/flow-router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,eAAe,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAOjD,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,KAAG,OAI/C,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACxC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,kBAAkB,EAAE,MAAM,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC,CAAC;IAC3E,sBAAsB,EAAE,CACtB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,KAC9C,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACrC,qBAAqB,EAAE,CAAC,KAAK,EAAE;QAC7B,OAAO,EAAE,MAAM,CAAC;QAChB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAClC,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IAC/B,kBAAkB,EAAE,CAClB,YAAY,EAAE,oBAAoB,EAClC,SAAS,EAAE,eAAe,KACvB,oBAAoB,GAAG;QAAE,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAC;IAClE,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,CACb,KAAK,EAAE,iBAAiB,KACrB,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACtD,UAAU,CAAC,EAAE;QACX,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;sFAoBI;QACD,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,aAAa,GAAG,IAAI,CAAC;QACtC,mBAAmB,EAAE,MAAM,CAAC;KAC7B,KAAG,OAAO,CAAC,cAAc,CAAC;+
|
|
1
|
+
{"version":3,"file":"flow-router.d.ts","sourceRoot":"","sources":["../../src/services/flow-router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,eAAe,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAOjD,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,KAAG,OAI/C,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACxC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,kBAAkB,EAAE,MAAM,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC,CAAC;IAC3E,sBAAsB,EAAE,CACtB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,KAC9C,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACrC,qBAAqB,EAAE,CAAC,KAAK,EAAE;QAC7B,OAAO,EAAE,MAAM,CAAC;QAChB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAClC,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IAC/B,kBAAkB,EAAE,CAClB,YAAY,EAAE,oBAAoB,EAClC,SAAS,EAAE,eAAe,KACvB,oBAAoB,GAAG;QAAE,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAC;IAClE,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,CACb,KAAK,EAAE,iBAAiB,KACrB,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACtD,UAAU,CAAC,EAAE;QACX,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;sFAoBI;QACD,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,aAAa,GAAG,IAAI,CAAC;QACtC,mBAAmB,EAAE,MAAM,CAAC;KAC7B,KAAG,OAAO,CAAC,cAAc,CAAC;+BA4KlB,iBAAiB,KACvB,OAAO,CAAC,kBAAkB,CAAC;EAkB/B;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAE7E;AAED,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -31,6 +31,18 @@ export function createFlowRouter(options) {
|
|
|
31
31
|
const cachedIntent = cachedFlowState?.intent
|
|
32
32
|
? options.normalizeIntent(cachedFlowState.intent)
|
|
33
33
|
: null;
|
|
34
|
+
// Token reduction: when we already know a sticky wizard intent,
|
|
35
|
+
// and the user replies with wizard-like input, skip router LLM.
|
|
36
|
+
// (Xel-agent equivalent: shouldSkipIntentClassification()).
|
|
37
|
+
if (cachedIntent !== null &&
|
|
38
|
+
options.stickyFlows.has(cachedIntent) &&
|
|
39
|
+
isWizardInput(message)) {
|
|
40
|
+
return {
|
|
41
|
+
messageIntent: { intent: cachedIntent, score: 1 },
|
|
42
|
+
flow: { active: true, intent: cachedIntent },
|
|
43
|
+
promptIntent: cachedIntent,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
34
46
|
const menuIntent = resolveGreetingMenuSelection(message, cachedIntent);
|
|
35
47
|
if (menuIntent) {
|
|
36
48
|
const sticky = options.stickyFlows.has(menuIntent);
|
|
@@ -1,22 +1,5 @@
|
|
|
1
|
-
import type { ToolExtractorMap } from "../types.js";
|
|
2
|
-
|
|
3
|
-
* Simple tool → output key map.
|
|
4
|
-
*
|
|
5
|
-
* @example
|
|
6
|
-
* {
|
|
7
|
-
* create_campaign: "campaign",
|
|
8
|
-
* buy_airtime: "buyAirtime",
|
|
9
|
-
* propose_tickets: { as: "tickets", from: "tickets", initial: [] },
|
|
10
|
-
* }
|
|
11
|
-
*/
|
|
12
|
-
export type ToolOutputMap = Record<string, string | {
|
|
13
|
-
/** Key written onto toolOutputs / extras. */
|
|
14
|
-
as: string;
|
|
15
|
-
/** Nested field on tool args (e.g. args.tickets). */
|
|
16
|
-
from?: string;
|
|
17
|
-
/** Seed value when nothing extracted yet. */
|
|
18
|
-
initial?: unknown;
|
|
19
|
-
}>;
|
|
1
|
+
import type { ToolExtractorMap, ToolOutputMap } from "../types.js";
|
|
2
|
+
export type { ToolOutputMap };
|
|
20
3
|
export declare function resolveToolOutputKey(toolName: string, map: ToolOutputMap): string;
|
|
21
4
|
/** Build first-wins extractors + initial seed from a simple map. */
|
|
22
5
|
export declare function toolOutputMapToExtractors(map: ToolOutputMap): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-config.d.ts","sourceRoot":"","sources":["../../src/services/simple-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"simple-config.d.ts","sourceRoot":"","sources":["../../src/services/simple-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEnE,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,aAAa,GACjB,MAAM,CAIR;AAED,oEAAoE;AACpE,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,aAAa,GAAG;IAC7D,cAAc,EAAE,gBAAgB,CAAC;IACjC,kBAAkB,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnD,CAkCA;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,IAGS,wBAGL;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACjD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;;;;;;;EA0BF"}
|
package/dist/types.d.ts
CHANGED
|
@@ -2,8 +2,24 @@ import type { BaseChatModel } from "@langchain/core/language_models/chat_models"
|
|
|
2
2
|
import type { Embeddings } from "@langchain/core/embeddings";
|
|
3
3
|
import type { DynamicStructuredTool } from "@langchain/core/tools";
|
|
4
4
|
import type { BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Simple tool → output key map.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* {
|
|
10
|
+
* create_campaign: "campaign",
|
|
11
|
+
* buy_airtime: "buyAirtime",
|
|
12
|
+
* propose_tickets: { as: "tickets", from: "tickets", initial: [] },
|
|
13
|
+
* }
|
|
14
|
+
*/
|
|
15
|
+
export type ToolOutputMap = Record<string, string | {
|
|
16
|
+
/** Key written onto toolOutputs / extras. */
|
|
17
|
+
as: string;
|
|
18
|
+
/** Nested field on tool args (e.g. args.tickets). */
|
|
19
|
+
from?: string;
|
|
20
|
+
/** Seed value when nothing extracted yet. */
|
|
21
|
+
initial?: unknown;
|
|
22
|
+
}>;
|
|
7
23
|
/** Intent catalog entry used for embedding routing + sticky-flow rules. */
|
|
8
24
|
export type IntentDefinition = {
|
|
9
25
|
name: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llm-agent-runtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Reusable LangGraph agent runtime: intent routing, sticky flows, Redis checkpointer, optional answer cache",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"type": "module",
|
|
@@ -13,13 +13,15 @@
|
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
|
-
"dist"
|
|
16
|
+
"dist",
|
|
17
|
+
"USAGE.md",
|
|
18
|
+
"README.md"
|
|
17
19
|
],
|
|
18
20
|
"scripts": {
|
|
19
21
|
"build": "tsc -p tsconfig.json",
|
|
20
22
|
"dev": "tsc -p tsconfig.json --watch",
|
|
21
23
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
22
|
-
"test": "tsx --test src
|
|
24
|
+
"test": "tsx --test src/services/extract.test.ts && tsx --test src/services/simple-config.test.ts",
|
|
23
25
|
"prepublishOnly": "pnpm build && pnpm test"
|
|
24
26
|
},
|
|
25
27
|
"publishConfig": {
|