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 CHANGED
@@ -1,5 +1,5 @@
1
1
  # llm-agent-runtime
2
2
 
3
- Reusable LangGraph agent runtime (intent routing, sticky flows, checkpointer, tool extractors).
3
+ Reusable LangGraph agent runtime: intent routing, sticky flows, checkpointer, tool outputs.
4
4
 
5
- See **llm-agent-runtime-usage-guide.pdf** in this folder for the usage guide.
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,CAsOvB"}
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"}
@@ -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
- (config.completeOn?.length
58
+ (completeOn?.length
57
59
  ? createCompleteOnFinalize({
58
- completeOn: config.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, type ToolOutputMap, } from "./services/simple-config.js";
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
@@ -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,EACxB,KAAK,aAAa,GACnB,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,GACd,MAAM,YAAY,CAAC"}
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;+CACV,MAAM;kDAsCT,OAAO,EAAE,KAAG,MAAM;gDAe3D,MAAM,KACf,OAAO,CAAC,MAAM,CAAC;EAUnB"}
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
- const content = String(message?.content ?? "").toLowerCase();
8
- return (!content.includes("tool failed") &&
9
- !content.includes("error") &&
10
- !content.includes("undefined"));
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(-8);
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
- return "System";
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(-6)
50
+ .slice(-INTENT_ROUTER_HISTORY_LIMIT)
39
51
  .map((message) => {
40
52
  const role = getMessageRole(message);
41
- const text = getMessageText(message).slice(0, 300);
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;+BA6JlB,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"}
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,MAAM,aAAa,CAAC;AAEpD;;;;;;;;;GASG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAChC,MAAM,EACJ,MAAM,GACN;IACE,6CAA6C;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CACJ,CAAC;AAEF,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"}
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
- import type { ToolOutputMap } from "./services/simple-config.js";
6
- export type { ToolOutputMap };
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;
@@ -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;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,2EAA2E;AAC3E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GAAG;IAC1B,sBAAsB,EAAE,OAAO,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,MAAM,CAAC;IACvC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,qBAAqB,EAAE,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAE3D,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,oBAAoB,GAAG;IACnD,MAAM,EAAE,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,oBAAoB,CAAC;IACpC,IAAI,EAAE,SAAS,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE9C,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,WAAW,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACzB,IAAI,CAAC;AAEV,mEAAmE;AACnE,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAE7D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE;QAAE,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,oDAAoD;IACpD,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,yCAAyC;IACzC,cAAc,EAAE,cAAc,CAAC;IAC/B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,mDAAmD;IACnD,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,kBAAkB,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,MAAM,CAAC,CAAC;IACxE,gFAAgF;IAChF,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,MAAM,CAAC;IACnD;;;OAGG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;OAEG;IACH,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,sEAAsE;IACtE,kBAAkB,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,iGAAiG;IACjG,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,qFAAqF;IACrF,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtE;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC9F,yEAAyE;IACzE,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC,KAAK,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,UAAU,CAAC,EAAE;QACX,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC9B,CAAC;IACF,mEAAmE;IACnE,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,aAAa,CAAC;QACrB,YAAY,CAAC,EAAE,aAAa,CAAC;QAC7B,UAAU,CAAC,EAAE,UAAU,CAAC;KACzB,CAAC;IACF,mEAAmE;IACnE,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,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.2",
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/**/*.test.ts",
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": {