@picoflow/ezgraph 0.0.6 → 0.0.8

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.
Files changed (60) hide show
  1. package/README.md +247 -86
  2. package/dist/framework/base-graph.js +1 -1
  3. package/dist/framework/conversation-node.js +1 -1
  4. package/dist/framework/conversation-runner.js +1 -1
  5. package/dist/framework/decision/decision-node.js +1 -0
  6. package/dist/framework/decision/decision-provider.js +1 -0
  7. package/dist/framework/decision/decision-runner.js +1 -0
  8. package/dist/framework/decision/decision-types.js +1 -0
  9. package/dist/framework/decision/decision-validation.js +1 -0
  10. package/dist/framework/decision/typesafe-provider.js +1 -0
  11. package/dist/framework/graph-engine.js +1 -1
  12. package/dist/framework/graph-node.js +1 -1
  13. package/dist/framework/graph-state.js +1 -1
  14. package/dist/framework/langchain-llm-gateway.js +1 -1
  15. package/dist/framework/langchain-provider.adapter.js +1 -1
  16. package/dist/framework/node-invocation.js +1 -0
  17. package/dist/framework/node-outcome.js +1 -1
  18. package/dist/framework/node-state.js +1 -1
  19. package/dist/framework/persistence/session-manager.js +1 -1
  20. package/dist/framework/session-log.js +1 -1
  21. package/dist/framework/state-graph-ext.js +1 -1
  22. package/dist/framework/tool-response.js +1 -0
  23. package/dist/index.js +1 -1
  24. package/dist/testing/scripted-decisions.js +1 -0
  25. package/dist/testing/turn-harness.js +1 -1
  26. package/dist/testing.js +1 -1
  27. package/dist/types/npmlib/src/index.d.ts +11 -5
  28. package/dist/types/npmlib/src/testing.d.ts +1 -0
  29. package/dist/types/src/framework/base-graph.d.ts +28 -14
  30. package/dist/types/src/framework/conversation-node.d.ts +9 -15
  31. package/dist/types/src/framework/conversation-runner.d.ts +9 -9
  32. package/dist/types/src/framework/decision/decision-node.d.ts +17 -0
  33. package/dist/types/src/framework/decision/decision-provider.d.ts +14 -0
  34. package/dist/types/src/framework/decision/decision-runner.d.ts +18 -0
  35. package/dist/types/src/framework/decision/decision-types.d.ts +126 -0
  36. package/dist/types/src/framework/decision/decision-validation.d.ts +4 -0
  37. package/dist/types/src/framework/decision/typesafe-provider.d.ts +12 -0
  38. package/dist/types/src/framework/graph-engine.d.ts +4 -0
  39. package/dist/types/src/framework/graph-llm.config.d.ts +3 -3
  40. package/dist/types/src/framework/graph-node.d.ts +51 -36
  41. package/dist/types/src/framework/graph-registry.d.ts +10 -5
  42. package/dist/types/src/framework/graph-state-support.d.ts +1 -1
  43. package/dist/types/src/framework/graph-state.d.ts +6 -5
  44. package/dist/types/src/framework/langchain-provider.adapter.d.ts +2 -2
  45. package/dist/types/src/framework/llm-gateway.d.ts +4 -4
  46. package/dist/types/src/framework/model-stop-reason.d.ts +2 -2
  47. package/dist/types/src/framework/node-invocation.d.ts +12 -0
  48. package/dist/types/src/framework/node-outcome.d.ts +3 -32
  49. package/dist/types/src/framework/node-state.d.ts +3 -2
  50. package/dist/types/src/framework/openai-auth-provider.d.ts +1 -1
  51. package/dist/types/src/framework/persistence/session-manager.d.ts +4 -0
  52. package/dist/types/src/framework/session-log.d.ts +30 -0
  53. package/dist/types/src/framework/state-graph-ext.d.ts +4 -10
  54. package/dist/types/src/framework/token-usage.d.ts +2 -2
  55. package/dist/types/src/framework/tool-response.d.ts +29 -0
  56. package/dist/types/src/testing/scripted-decisions.d.ts +24 -0
  57. package/dist/types/src/testing/turn-harness.d.ts +2 -0
  58. package/package.json +11 -7
  59. package/dist/framework/conversation-tool-result.js +0 -1
  60. package/dist/types/src/framework/conversation-tool-result.d.ts +0 -19
package/README.md CHANGED
@@ -1,110 +1,268 @@
1
1
  # EZGraph
2
2
 
3
- EZGraph is a pre-release TypeScript application layer for durable,
4
- multi-turn conversational workflows. It is built on LangGraph and LangChain,
5
- but gives each conversation an explicit graph, typed node state, durable session
6
- handling, and code-owned outcomes for validation, confirmation, and routing.
3
+ EZGraph is a TypeScript application layer for durable, guided conversations on
4
+ [LangGraph](https://langchain-ai.github.io/langgraphjs/). It gives customer-facing
5
+ chat applications an explicit contract for node-owned state, decorated tools,
6
+ durable sessions, and deterministic transitions—without requiring an EZGraph
7
+ account, cloud service, or dependency-injection framework.
7
8
 
8
- It is provider-neutral and framework-neutral: use it with the model provider
9
- and Node.js HTTP framework you already run.
9
+ Use it when a conversation is an application: it gathers validated facts,
10
+ applies business policy, presents exact reviews or decisions, and resumes safely
11
+ across requests.
10
12
 
11
- ## What it provides
13
+ > **Upgrading:** Version 0.0.7 contains breaking changes from 0.0.6; see the [EZGraph documentation](https://www.picoflow.io/ezgraph) before upgrading.
12
14
 
13
- - Graph and node primitives for staged conversations, rather than one large
14
- prompt or an implicit agent loop.
15
- - Per-node state, named history spaces, and typed outcomes such as `stay()`,
16
- `advance()`, `finish()`, and `quit()`.
17
- - One versioned session document per conversation, backed by memory, SQLite,
18
- MongoDB, or Azure Cosmos DB.
19
- - A model and tool loop that is bounded and owned by the graph, while business
20
- validation and routing remain ordinary application code.
21
- - Provider adapters and a typed model catalog, with support for OpenAI,
22
- Anthropic, Google, Azure OpenAI, and custom compatible endpoints.
15
+ ## Install
23
16
 
24
- For the product overview, tutorial, and full developer guide, visit
25
- [picoflow.io/ezgraph](https://www.picoflow.io/ezgraph/).
17
+ ```bash
18
+ npm install @picoflow/ezgraph zod
26
19
 
27
- ## Requirements
20
+ # Install only the LangChain provider adapter your application uses.
21
+ npm install @langchain/openai
22
+ # or: npm install @langchain/anthropic
23
+ # or: npm install @langchain/google
24
+ ```
25
+
26
+ Requirements:
28
27
 
29
28
  - Node.js 22.5 or later
30
29
  - TypeScript 5.x
31
- - A model-provider package and credentials for the provider you choose
30
+ - `experimentalDecorators` and `emitDecoratorMetadata` enabled in `tsconfig.json`
31
+ - `import "reflect-metadata"` once, before any module that declares `@Tool`
32
32
 
33
- Tool handlers use method decorators. Enable `experimentalDecorators` and
34
- `emitDecoratorMetadata` in `tsconfig.json`, and import `reflect-metadata` once
35
- at the very top of your application entry point.
33
+ EZGraph is ESM. TypeScript applications should use `module` and
34
+ `moduleResolution` set to `NodeNext`.
36
35
 
37
- ## Install
36
+ ## The conversation contract
38
37
 
39
- ```bash
40
- npm install @picoflow/ezgraph
38
+ Each node owns the facts it validates. A tool handler saves valid state, then
39
+ returns exactly one response:
41
40
 
42
- # Install only the provider adapter you use.
43
- npm install @langchain/openai
44
- # or: npm install @langchain/anthropic
45
- # or: npm install @langchain/google
46
- ```
41
+ | Return | Use it for |
42
+ | --- | --- |
43
+ | `stay(feedback)` | Validation failed; continue collecting in the current node. |
44
+ | `go(TargetNode)` | Enter another registered conversational node now. |
45
+ | `direct(content)` | Return exact code-owned content, such as a policy decision, price table, or ticket ID. |
46
+ | `directTo(TargetNode, content)` | Return exact content and make the target the next user-turn node. |
47
+ | `finish(content)` | Return exact final content and complete the conversation. |
47
48
 
48
- The provider adapters are optional peer dependencies. The published package is
49
- ESM; TypeScript applications should use `module` and `moduleResolution` set to
50
- `NodeNext`.
49
+ There is no per-turn context object, post-tool transition hook, synthetic tool
50
+ result, or automatic outcome router to maintain.
51
51
 
52
- ## Start an application graph
52
+ ## Define durable state
53
53
 
54
- Define your graph and nodes in application code, then register the graph with a
55
- `GraphEngine`. The engine creates or resumes a session using the supplied
56
- `sessionId`.
54
+ Keep the node registry next to the graph. It is converted into the annotated
55
+ LangGraph state; each node channel is replaced when that node saves state.
57
56
 
58
57
  ```ts
59
- import "reflect-metadata";
60
- import { GraphEngine } from "@picoflow/ezgraph";
61
- import { WeatherGraph } from "./weather-graph.js";
58
+ import { createGraphStateAnnotation, type NodeStateValue } from "@picoflow/ezgraph";
59
+ import { CityNode } from "./nodes/city.node.js";
62
60
 
63
- const engine = await GraphEngine.create({ graphs: [WeatherGraph] });
61
+ export type WeatherGraphNodes = {
62
+ CityNode?: NodeStateValue<{ city?: string }>;
63
+ WeatherNode?: NodeStateValue<{ forecast?: string }>;
64
+ };
64
65
 
65
- const result = await engine.run({
66
- graphName: "WeatherGraph",
67
- sessionId: "customer-123",
68
- userMessage: "I need the weather in Seattle",
69
- });
66
+ export const WeatherGraphState = createGraphStateAnnotation(
67
+ CityNode.name,
68
+ () => ({} as WeatherGraphNodes),
69
+ );
70
+
71
+ export type WeatherGraphStateType = typeof WeatherGraphState.State;
72
+ ```
70
73
 
71
- // { status, body, session }
74
+ ## Write a conversational node
75
+
76
+ `ConversationNode` normally needs only the graph-state type. The handler below
77
+ validates model input in code, saves the owned state channel, and uses
78
+ `direct()` for an exact result.
79
+
80
+ ```ts
81
+ import { z } from "zod";
82
+ import {
83
+ ConversationNode,
84
+ Tool,
85
+ direct,
86
+ stay,
87
+ type ToolDefinition,
88
+ type ToolResponse,
89
+ } from "@picoflow/ezgraph";
90
+ import type { WeatherGraphStateType } from "../weather-graph.state.js";
91
+
92
+ type CityInput = { city: string };
93
+
94
+ export class CityNode extends ConversationNode<WeatherGraphStateType> {
95
+ getPrompt(): string {
96
+ return "Collect a city, then call capture_city.";
97
+ }
98
+
99
+ defineTool(): readonly ToolDefinition<CityInput>[] {
100
+ return [{
101
+ name: "capture_city",
102
+ description: "Save a city for the forecast.",
103
+ schema: z.object({ city: z.string().min(2) }),
104
+ }];
105
+ }
106
+
107
+ @Tool("capture_city")
108
+ async captureCity({ city }: CityInput): Promise<ToolResponse> {
109
+ const value = city.trim();
110
+ if (!value) return stay("Ask for a non-empty city.");
111
+
112
+ this.saveState({ city: value });
113
+ return direct(`Saved ${value}.`);
114
+ }
115
+ }
72
116
  ```
73
117
 
74
- `GraphEngine.create()` reads `.env` and process environment values. Model
75
- credentials stay with the provider you configure; EZGraph does not require an
76
- EZGraph account or runtime key.
118
+ Use `go(TargetNode).withState({ ... })` when a transition also initializes the
119
+ target node's state. Use `withMessages()` for real model-visible messages or
120
+ attachments, and `withCleanup()` for cleanup tied to that tool result.
121
+ When a custom `GraphNode.run()` makes its own model call, attach that call's
122
+ token delta with `.withUsage(conversation.usage)` so a `go()` or response
123
+ builder preserves the session's LLM accounting.
124
+ Use `directTo(TargetNode, content)` when the current handler should answer now
125
+ and defer the target until the next user turn.
77
126
 
78
- ### Experimental local OpenAI auth
127
+ For deterministic policy that needs state owned by another node, read
128
+ `this.graph.graphState()`. To write another node's channel, use
129
+ `this.graph.saveNodeState(TargetNode, patch)`.
79
130
 
80
- For local development, `openai-auth` uses the OAuth session owned by an
81
- already signed-in Codex client. The graph only selects the built-in model; no
82
- provider adapter or `OPENAI_API_KEY` is required:
131
+ ## Add typed decisions with Jev
132
+
133
+ EZGraph supports [Jev](https://typesafe.ai/) through LangChain's optional
134
+ `@langchain/typesafe` package. Use a provider-neutral `DecisionNode` when a
135
+ workflow needs a bounded classification or review rather than generated text.
136
+ Jev returns typed Choice, Score, and Noul answers; your application keeps
137
+ thresholds, routing, authorization, and side effects in code.
138
+
139
+ ```bash
140
+ npm install @langchain/typesafe
141
+ ```
83
142
 
84
143
  ```ts
85
- ModelCatalog.model("openai-auth:gpt-5.4", {
86
- retries: 3,
87
- reasoningEffort: "low",
144
+ import {
145
+ DecisionNode,
146
+ DecisionProvider,
147
+ GraphEngine,
148
+ go,
149
+ type DecisionAnswers,
150
+ type DecisionQuestionMap,
151
+ } from "@picoflow/ezgraph";
152
+
153
+ const TRIAGE = {
154
+ route: {
155
+ type: "choice",
156
+ criteria: {
157
+ billing: "Invoice or refund question",
158
+ technical: "Failure requiring diagnosis",
159
+ unclear: "Missing indispensable detail",
160
+ },
161
+ },
162
+ urgent: {
163
+ type: "noul",
164
+ instructions: "Is a production operation currently blocked?",
165
+ },
166
+ } as const satisfies DecisionQuestionMap;
167
+
168
+ class TriageNode extends DecisionNode<SupportGraphStateType, typeof TRIAGE> {
169
+ defineQuestions() {
170
+ return TRIAGE;
171
+ }
172
+
173
+ override getPrompt() {
174
+ return "Classify the latest support request.";
175
+ }
176
+
177
+ onDecision(answers: DecisionAnswers<typeof TRIAGE>) {
178
+ if (answers.route.confidence < 0.75) return go(ClarifyNode);
179
+ if (answers.urgent.noul >= 0.9) return go(SpecialistNode);
180
+ return answers.route.choice === "billing"
181
+ ? go(BillingPolicyNode)
182
+ : go(QuickAnswerNode);
183
+ }
184
+ }
185
+
186
+ const decisionProviders = DecisionProvider.create({
187
+ typesafe: { apiKey: process.env.TYPESAFE_API_KEY },
188
+ });
189
+
190
+ const engine = await GraphEngine.create({
191
+ graphs: [SupportGraph],
192
+ decisionProviders,
88
193
  });
89
194
  ```
90
195
 
91
- The provider reads `~/.codex/auth.json` for each request and never writes the
92
- shared credential or refresh token. Run `codex` when the access token expires.
93
- `EZGRAPH_OPENAI_AUTH_FILE` and `EZGRAPH_OPENAI_AUTH_BASE_URL` override the
94
- local defaults for testing.
196
+ The default decision configuration uses provider `typesafe` and model
197
+ `jev-latest`; graphs or individual nodes can override the model, timeout, and
198
+ bounded retry count. Provider registration is explicit, and a missing Jev
199
+ provider, package, or credential fails clearly instead of falling back to a
200
+ chat model. Decision usage is persisted separately from chat-model tokens.
95
201
 
96
- This provider targets a private ChatGPT Codex backend. It is experimental,
97
- intended for local use, and may change independently of the supported OpenAI
98
- API-key provider.
202
+ ## Build and register the graph
99
203
 
100
- For a complete two-stage graph, including state, a tool handler, explicit
101
- outcomes, and graph registration, follow the
102
- [Get started tutorial](https://www.picoflow.io/ezgraph/tutorial/).
204
+ Register conversational nodes explicitly. Tool-returned `go()` responses choose
205
+ ordinary conversational handoffs; fixed worker edges remain ordinary LangGraph
206
+ edges. Register `TerminateSessionNode` and connect it to `END` when a graph
207
+ contains conversational nodes.
103
208
 
104
- ## Persistence and configuration
209
+ ```ts
210
+ import "reflect-metadata";
211
+ import { END } from "@langchain/langgraph";
212
+ import {
213
+ BaseGraph,
214
+ GRAPH_END_NODE,
215
+ GraphEngine,
216
+ ModelCatalog,
217
+ TerminateSessionNode,
218
+ type GraphDefinition,
219
+ type LlmGateway,
220
+ } from "@picoflow/ezgraph";
221
+ import { WeatherGraphState, type WeatherGraphStateType } from "./weather-graph.state.js";
222
+ import { CityNode } from "./nodes/city.node.js";
223
+ import { WeatherNode } from "./nodes/weather.node.js";
224
+
225
+ export class WeatherGraph extends BaseGraph<WeatherGraphStateType> {
226
+ static getGraphDefinition(): GraphDefinition {
227
+ return {
228
+ llmConfig: ModelCatalog.model("openai:gpt-5.4", { retries: 2 }),
229
+ endNode: GRAPH_END_NODE,
230
+ initialHistorySpace: "weather",
231
+ historySpaces: [
232
+ [CityNode, "weather"],
233
+ [WeatherNode, "weather"],
234
+ [TerminateSessionNode, "weather-terminal"],
235
+ ],
236
+ };
237
+ }
238
+
239
+ constructor(llmGateway: LlmGateway) {
240
+ super(llmGateway, WeatherGraph.getGraphDefinition());
241
+ }
242
+
243
+ protected buildGraph() {
244
+ const graph = this.createStateGraph(WeatherGraphState);
245
+ graph.registerTurnNodes(CityNode, WeatherNode, TerminateSessionNode);
246
+ graph.addEdge(TerminateSessionNode, END);
247
+ return graph.compile();
248
+ }
249
+ }
105
250
 
106
- The default `SESSION_STORE=memory` is useful for local development. Select a
107
- durable store when conversations must resume across process restarts or
251
+ const engine = await GraphEngine.create({ graphs: [WeatherGraph] });
252
+ const result = await engine.run({
253
+ graphName: "WeatherGraph",
254
+ userMessage: "I need the weather in Seattle",
255
+ });
256
+ ```
257
+
258
+ `GraphEngine.create()` loads the selected session store from environment
259
+ configuration. The result contains an HTTP-ready status/body envelope and a
260
+ session ID for the next customer turn.
261
+
262
+ ## Persistence and providers
263
+
264
+ The default `SESSION_STORE=memory` is suitable for local development. Use a
265
+ durable store for sessions that must survive process restarts or run across
108
266
  instances:
109
267
 
110
268
  ```dotenv
@@ -112,33 +270,36 @@ instances:
112
270
  SESSION_STORE=sqlite
113
271
  SQLITE_DB_PATH=./data/sessions.sqlite
114
272
 
115
- # Set the credential for the model provider you use.
273
+ # Example provider credential
116
274
  OPENAI_API_KEY=...
117
275
  ```
118
276
 
119
277
  For MongoDB, configure `MONGODB_URL`, `MONGODB_NAME`, and
120
- `MONGODB_COLLECTION`. For Cosmos DB, use the Cosmos settings described in the
121
- [developer guide](https://www.picoflow.io/ezgraph/docs/developer-guide/).
278
+ `MONGODB_COLLECTION`. See the developer guide for Cosmos DB and model-provider
279
+ configuration.
280
+
281
+ ## Testing
122
282
 
123
- The [EZGraph demo application](https://github.com/picoflowio/ezgraph-demo)
124
- shows a NestJS + Fastify service with QuoteGraph, a LangGraph comparison, and a
125
- copyable [`.env.example`](https://github.com/picoflowio/ezgraph-demo/blob/main/.env.example).
283
+ Keep deterministic state, transition, and policy tests separate from live
284
+ provider evaluations. The accompanying demo uses `USE_ENV=1` as its opt-in
285
+ live-provider switch and `KEEP_SESSION=1` to retain a session for inspection.
126
286
 
127
287
  ## Learn more
128
288
 
129
- - [Get started tutorial](https://www.picoflow.io/ezgraph/tutorial/)
289
+ - [Tutorial](https://www.picoflow.io/ezgraph/tutorial/)
130
290
  - [Developer guide](https://www.picoflow.io/ezgraph/docs/developer-guide/)
131
291
  - [QuoteGraph walkthrough](https://www.picoflow.io/ezgraph/quote-graph/)
132
- - [EZGraph compared with direct LangGraph](https://www.picoflow.io/ezgraph/compare/langgraph/)
292
+ - [Comparison with direct LangGraph](https://www.picoflow.io/ezgraph/compare/langgraph/)
293
+ - [Runnable demo application](https://github.com/picoflowio/ezgraph-demo)
133
294
 
134
295
  ## License
135
296
 
136
297
  EZGraph is proprietary software distributed under the
137
298
  [EZGraph Commercial Runtime License](https://www.picoflow.io/ezgraph/license/).
138
- Personal use, commercial SaaS, internal enterprise production, client work,
139
- and closed-source applications are permitted with no EZGraph runtime fee or
140
- license key. Optional support is separate; an active support subscription
141
- includes the private source and debug package.
299
+ The license permits personal use, commercial SaaS, internal enterprise
300
+ production, client work, and closed-source applications. You may not repackage,
301
+ re-license, or redistribute EZGraph as a competing SDK, developer library,
302
+ plugin framework, or hosted service.
142
303
 
143
- See the [license page](https://www.picoflow.io/ezgraph/license/) for the
144
- applicable production-use terms.
304
+ See [LICENSE.md](LICENSE.md) and the [license page](https://www.picoflow.io/ezgraph/license/)
305
+ for the applicable terms.
@@ -1 +1 @@
1
- var d=Object.defineProperty;var a=(t,r)=>d(t,"name",{value:r,configurable:!0});import{GraphLlm as c}from"./graph-llm.config.js";import{GraphNodeRuntime as g}from"./graph-node.js";import{StateGraphExt as u}from"./state-graph-ext.js";import{assertEmptyResponseRetries as l,assertMaxAgentRounds as y,DEFAULT_CONVERSATION_POLICY as h,DEFAULT_MAX_AGENT_ROUNDS as w}from"./conversation-runner.js";import{assertLlmTimeoutMs as f}from"./llm-gateway.js";import{assertGraphSchemaVersion as m,assertStableId as M,stableClassId as n}from"./stable-id.js";class p{static{a(this,"BaseGraph")}llmGateway;static id(){return this.name}static assertName(r){return p.assertId(r)}static assertId(r){return M(r,"graph")}name;id;schemaVersion;llmConfig;requiresUserMessage;responseMode;maxAgentRounds;conversationPolicy;compiledGraph;runtime;nodeMap=new Map;endNode;migrations;constructor(r,e){this.llmGateway=r;const s=new.target;this.name=s.name,this.id=n(s,"graph"),this.schemaVersion=m(e.schemaVersion??1),this.migrations=S(e.migrations,this.schemaVersion),this.llmConfig=c.resolveConfig(e.llmConfig),this.requiresUserMessage=e.requiresUserMessage??!0,this.responseMode=e.responseMode??"chat",this.maxAgentRounds=y(e.maxAgentRounds??w),this.conversationPolicy=v(e),this.endNode=e.endNode,this.runtime=new g(e.endNode,this.llmConfig,R(e.historySpaces),e.initialHistorySpace,this.responseMode,this.maxAgentRounds,this.conversationPolicy)}get graph(){return this.compiledGraph??=this.buildGraph()}prepareInput(r,e){const s=this.runtime.historySpace(r?.currentNode);return{...r??{},histories:{...r?.histories??{},[s]:[...r?.histories[s]??[],e]}}}async restoreSessionDoc(r){if(r.graph.id!==this.id)throw new Error(`Session '${r.id}' belongs to graph '${r.graph.id}', not '${this.id}'. Start a new session to run a different graph.`);if(r.graph.schemaVersion>this.schemaVersion)throw new Error(`Session '${r.id}' uses graph '${this.id}' schema version ${r.graph.schemaVersion}, but this runtime supports version ${this.schemaVersion}.`);let e=r;for(;e.graph.schemaVersion<this.schemaVersion;){const s=e.graph.schemaVersion,i=this.migrations.get(s);if(!i)throw new Error(`Graph '${this.id}' has no migration from schema version ${s} to ${s+1}.`);const o=await i.migrate(e);if(o.graph.id!==this.id)throw new Error(`Graph '${this.id}' migration from schema version ${s} changed the persisted graph ID.`);e={...o,graph:{...o.graph,schemaVersion:s+1}}}return await this.onRestoreSessionDoc(e)}async onRestoreSessionDoc(r){return r}idleMs(r){const e=Date.parse(r.modifiedAt);return Number.isFinite(e)?Date.now()-e:0}createStateGraph(r){return new u(r,(e=>this.createNode(e)),this.endNode)}createNode(r){const e=new r(this.llmGateway,this.runtime),s=n(r,"graph node");if(e.id!==s)throw new Error(`Graph node factory for '${s}' constructs '${e.id}'.`);if(this.nodeMap.has(e.id))throw new Error(`Graph node '${e.id}' is already registered.`);return this.nodeMap.set(e.id,e),this.runtime.registerTools(e.id,e.defineTool()),Object.freeze(e),e}}function v(t){const r=t.emptyResponseRecovery===void 0?h.emptyResponseRecovery:t.emptyResponseRecovery;return r&&l(r.retries),{...t.llmTimeoutMs===void 0?{}:{llmTimeoutMs:f(t.llmTimeoutMs)},emptyHistorySeed:t.emptyHistorySeed===void 0?h.emptyHistorySeed:t.emptyHistorySeed,emptyResponseRecovery:r}}a(v,"resolveConversationPolicy");function R(t){return Object.fromEntries((t??[]).map(([r,e])=>[n(r,"graph node"),e]))}a(R,"historySpaceMap");function S(t,r){const e=new Map;let s;for(const i of t??[]){const o=m(i.from);if(o>=r)throw new Error(`A graph migration from version ${o} cannot target schema version ${r}.`);if(e.has(o))throw new Error(`More than one graph migration starts at version ${o}.`);if(s!==void 0&&o!==s+1)throw new Error(`Graph migrations must be ordered and contiguous; version ${s} must be followed by ${s+1}.`);e.set(o,i),s=o}return e}a(S,"migrationMap");export{p as BaseGraph};
1
+ var d=Object.defineProperty;var a=(t,r)=>d(t,"name",{value:r,configurable:!0});import{GraphLlm as c}from"./graph-llm.config.js";import{GraphNodeRuntime as u}from"./graph-node.js";import{StateGraphExt as g}from"./state-graph-ext.js";import{assertEmptyResponseRetries as l,assertMaxAgentRounds as y,DEFAULT_CONVERSATION_POLICY as h,DEFAULT_MAX_AGENT_ROUNDS as w}from"./conversation-runner.js";import{assertLlmTimeoutMs as f}from"./llm-gateway.js";import{assertGraphSchemaVersion as m,assertStableId as v,stableClassId as n}from"./stable-id.js";class p{static{a(this,"BaseGraph")}llmGateway;static id(){return this.name}static assertName(r){return p.assertId(r)}static assertId(r){return v(r,"graph")}name;id;schemaVersion;llmConfig;requiresUserMessage;responseMode;maxAgentRounds;conversationPolicy;compiledGraph;runtime;nodeMap=new Map;endNode;migrations;constructor(r,e){this.llmGateway=r;const s=new.target;this.name=s.name,this.id=n(s,"graph"),this.schemaVersion=m(e.schemaVersion??1),this.migrations=S(e.migrations,this.schemaVersion),this.llmConfig=c.resolveConfig(e.llmConfig),this.requiresUserMessage=e.requiresUserMessage??!0,this.responseMode=e.responseMode??"chat",this.maxAgentRounds=y(e.maxAgentRounds??w),this.conversationPolicy=M(e),this.endNode=e.endNode,this.runtime=new u(e.endNode,this.llmConfig,R(e.historySpaces),e.initialHistorySpace,this.responseMode,this.maxAgentRounds,this.conversationPolicy,e.decisionConfig,i=>this.onDecisionError(i))}onDecisionError(r){return null}attachDecisionProviderResolver(r){this.runtime.attachDecisionProviderResolver(r)}get graph(){return this.compiledGraph??=this.buildGraph()}prepareInput(r,e){const s=this.runtime.historySpace(r?.currentNode);return{...r??{},histories:{...r?.histories??{},[s]:[...r?.histories[s]??[],e]}}}saveNodeState(r,e){this.runtime.saveNode(n(r,"graph node"),e)}async restoreSessionDoc(r){if(r.graph.id!==this.id)throw new Error(`Session '${r.id}' belongs to graph '${r.graph.id}', not '${this.id}'. Start a new session to run a different graph.`);if(r.graph.schemaVersion>this.schemaVersion)throw new Error(`Session '${r.id}' uses graph '${this.id}' schema version ${r.graph.schemaVersion}, but this runtime supports version ${this.schemaVersion}.`);let e=r;for(;e.graph.schemaVersion<this.schemaVersion;){const s=e.graph.schemaVersion,i=this.migrations.get(s);if(!i)throw new Error(`Graph '${this.id}' has no migration from schema version ${s} to ${s+1}.`);const o=await i.migrate(e);if(o.graph.id!==this.id)throw new Error(`Graph '${this.id}' migration from schema version ${s} changed the persisted graph ID.`);e={...o,graph:{...o.graph,schemaVersion:s+1}}}return await this.onRestoreSessionDoc(e)}async onRestoreSessionDoc(r){return r}idleMs(r){const e=Date.parse(r.modifiedAt);return Number.isFinite(e)?Date.now()-e:0}createStateGraph(r){return new g(r,(e=>this.createNode(e)),this.endNode)}createNode(r){const e=new r(this.llmGateway,this.runtime),s=n(r,"graph node");if(e.id!==s)throw new Error(`Graph node factory for '${s}' constructs '${e.id}'.`);if(this.nodeMap.has(e.id))throw new Error(`Graph node '${e.id}' is already registered.`);return this.nodeMap.set(e.id,e),this.runtime.registerTools(e.id,e.defineTool()),Object.freeze(e),e}}function M(t){const r=t.emptyResponseRecovery===void 0?h.emptyResponseRecovery:t.emptyResponseRecovery;return r&&l(r.retries),{...t.llmTimeoutMs===void 0?{}:{llmTimeoutMs:f(t.llmTimeoutMs)},emptyHistorySeed:t.emptyHistorySeed===void 0?h.emptyHistorySeed:t.emptyHistorySeed,emptyResponseRecovery:r}}a(M,"resolveConversationPolicy");function R(t){return Object.fromEntries((t??[]).map(([r,e])=>[n(r,"graph node"),e]))}a(R,"historySpaceMap");function S(t,r){const e=new Map;let s;for(const i of t??[]){const o=m(i.from);if(o>=r)throw new Error(`A graph migration from version ${o} cannot target schema version ${r}.`);if(e.has(o))throw new Error(`More than one graph migration starts at version ${o}.`);if(s!==void 0&&o!==s+1)throw new Error(`Graph migrations must be ordered and contiguous; version ${s} must be followed by ${s+1}.`);e.set(o,i),s=o}return e}a(S,"migrationMap");export{p as BaseGraph};
@@ -1 +1 @@
1
- var f=Object.defineProperty;var c=(n,e)=>f(n,"name",{value:e,configurable:!0});var p=function(n,e,t,r){var o=arguments.length,s=o<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,i;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(n,e,t,r);else for(var a=n.length-1;a>=0;a--)(i=n[a])&&(s=(o<3?i(s):o>3?i(e,t,s):i(e,t))||s);return o>3&&s&&Object.defineProperty(e,t,s),s},u=function(n,e){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(n,e)};import{GraphNode as l,Tool as h}from"./graph-node.js";import{TerminateSessionNode as d}from"./terminate-session.node.js";class m extends l{static{c(this,"ConversationNode")}quitRequests=new WeakSet;supportsAutomaticOutcomeRouting=!0;async endChat(e,t){return this.quitRequests.add(t),{output:{message:e.message?.trim()||"Of course. This conversation is now complete."},stopAfterBatch:!0}}quit(e){return this.transition(d,e,!1)}async run(e){const t=this.createContext(e),r=await this.runConversation(e,t);return this.nextStep(e,t,r)}async runConversation(e,t){this.quitRequests.delete(t);try{return{...await super.runConversation(e,t),quitRequested:this.quitRequests.has(t)}}finally{this.quitRequests.delete(t)}}}p([h("terminate_session"),u("design:type",Function),u("design:paramtypes",[Object,Object]),u("design:returntype",Promise)],m.prototype,"endChat",null);export{m as ConversationNode};
1
+ var m=Object.defineProperty;var h=(s,t)=>m(s,"name",{value:t,configurable:!0});var u=function(s,t,e,n){var r=arguments.length,o=r<3?t:n===null?n=Object.getOwnPropertyDescriptor(t,e):n,i;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")o=Reflect.decorate(s,t,e,n);else for(var a=s.length-1;a>=0;a--)(i=s[a])&&(o=(r<3?i(o):r>3?i(t,e,o):i(t,e))||o);return r>3&&o&&Object.defineProperty(t,e,o),o},c=function(s,t){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(s,t)};import{AIMessage as w,HumanMessage as y}from"@langchain/core/messages";import{Command as d,END as p}from"@langchain/langgraph";import{GraphNode as l,Tool as v}from"./graph-node.js";import{stableClassId as f}from"./stable-id.js";import{TerminateSessionNode as C}from"./terminate-session.node.js";import{go as R}from"./tool-response.js";import{addTokenUsage as N}from"./token-usage.js";class _ extends l{static{h(this,"ConversationNode")}async endChat(t){return R(C).withMessage(new y({content:t.message?.trim()||"The user asked to end the conversation.",additional_kwargs:{ezgraphInternal:!0}}))}async run(t){const e=await this.runConversation(t,{});if(e.toolResponse)return this.resolveToolResponse(e,e.toolResponse);const n=e.response;if(!n?.trim())throw new Error(`Conversation node '${this.id}' stopped without a response or tool transition.`);return new d({update:{currentNode:this.id,response:n,inputConsumed:!0,completed:!1,...this.historyUpdate(e.messages),tokens:e.usage},goto:p})}resolveToolResponse(t,e){const n=this.historyUpdate(t.messages),r=N(t.usage,e.usage);if(e.kind==="go"){if(!e.target)throw new Error(`Conversation node '${this.id}' selected go() without a target.`);const o=f(e.target,"graph node");return e.state&&this.graph.saveNodeState(e.target,e.state),e.message&&this.graph.appendHistory(this.graph.historySpace(o),[e.message]),new d({update:{currentNode:o,inputConsumed:!0,response:"",completed:!1,...n,tokens:r},goto:o})}if(e.kind==="directTo"){if(!e.target)throw new Error(`Conversation node '${this.id}' selected directTo() without a target.`);const o=f(e.target,"graph node"),i=this.graph.historySpace(o);e.state&&this.graph.saveNodeState(e.target,e.state),e.message&&this.graph.appendHistory(i,[e.message]);const a=g(this.id,e);return i!==this.historySpace()&&this.graph.appendHistory(i,[new w(a)]),new d({update:{currentNode:o,response:a,inputConsumed:!0,completed:!1,...n,tokens:r},goto:p})}if(e.kind==="direct")return new d({update:{currentNode:this.id,response:g(this.id,e),inputConsumed:!0,completed:!1,...n,tokens:r},goto:p});if(e.kind==="finish")return new d({update:{...this.graph.complete(g(this.id,e)),...n,tokens:r},goto:p});throw new Error(`Conversation node '${this.id}' returned stay() after the agent loop stopped.`)}}u([v("terminate_session"),c("design:type",Function),c("design:paramtypes",[Object]),c("design:returntype",Promise)],_.prototype,"endChat",null);function g(s,t){if(!t.response?.trim())throw new Error(`Conversation node '${s}' selected ${t.kind}() without a response.`);return t.response}h(g,"requireResponse");export{_ as ConversationNode};
@@ -1 +1 @@
1
- const GN=e;(function(Y,R){const Go={Y:0x1df,R:0x1f1,Z:0x20f,m:0x209},Ga=e,Z=Y();while(!![]){try{const m=-parseInt(Ga(0x1f2))/0x1*(parseInt(Ga(Go.Y))/0x2)+-parseInt(Ga(0x1de))/0x3*(-parseInt(Ga(0x1e5))/0x4)+parseInt(Ga(0x20a))/0x5+parseInt(Ga(0x1ed))/0x6*(parseInt(Ga(Go.R))/0x7)+-parseInt(Ga(0x1dc))/0x8*(-parseInt(Ga(0x1f7))/0x9)+-parseInt(Ga(Go.Z))/0xa*(-parseInt(Ga(0x204))/0xb)+-parseInt(Ga(Go.m))/0xc;if(m===R)break;else Z['push'](Z['shift']());}catch(J){Z['push'](Z['shift']());}}}(G,0x8250d));var v=Object[GN(0x1ef)],p=(Y,R)=>v(Y,GN(0x207),{'value':R,'configurable':!0x0});import{HumanMessage as j,ToolMessage as g}from'@langchain/core/messages';import{addTokenUsage as E,emptyTokenUsage as X}from'./token-usage.js';import{describeStopReason as a,isRetryableStopReason as w,modelStopReason as i}from'./model-stop-reason.js';import{SessionLogWarning as c}from'./session-log.js';import{isOpenAIAuthConfig as f,openAIAuthMessageText as o}from'./openai-auth-provider.js';class V extends Error{static{p(this,GN(0x1ea));}[GN(0x200)];constructor(Y){const GY={Y:0x1db},GF=GN;super(GF(GY.Y)+a(Y)+').'),this[GF(0x200)]=Y,this[GF(0x207)]=GF(0x1ea);}}const D=0x8;function L(Y){const GU=GN;if(!Number[GU(0x20c)](Y)||Y<0x1)throw new Error('maxAgentRounds\x20must\x20be\x20a\x20positive\x20integer;\x20received\x20'+String(Y)+'.');return Y;}p(L,GN(0x20d));const S=GN(0x1f3),T={'retries':0x2,'nudge':GN(0x1e8)};function e(j,S){j=j-0x1da;const C=G();let g=C[j];if(e['zpVeGM']===undefined){var E=function(F){const U='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let w='',i='';for(let c=0x0,q,f,o=0x0;f=F['charAt'](o++);~f&&(q=c%0x4?q*0x40+f:f,c++%0x4)?w+=String['fromCharCode'](0xff&q>>(-0x2*c&0x6)):0x0){f=U['indexOf'](f);}for(let Y=0x0,R=w['length'];Y<R;Y++){i+='%'+('00'+w['charCodeAt'](Y)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(i);};e['BHXLBH']=E,e['kNhkym']={},e['zpVeGM']=!![];}const X=C[0x0],a=j+X,N=e['kNhkym'][a];return!N?(g=e['BHXLBH'](g),e['kNhkym'][a]=g):g=N,g;}function $(Y){const Gw=GN;if(!Number[Gw(0x20c)](Y)||Y<0x0)throw new Error(Gw(0x20b)+String(Y)+'.');return Y;}p($,GN(0x20e));const q={'emptyHistorySeed':S,'emptyResponseRecovery':T};class W{static{p(this,'ConversationRunner');}[GN(0x1fd)];constructor(Y){const Gi=GN;this[Gi(0x1fd)]=Y;}async[GN(0x1da)](Y){const GJ={Y:0x1ee,R:0x205,Z:0x208,m:0x202,J:0x203,Q:0x1eb,s:0x1fd,K:0x1fb,n:0x1e2,H:0x1e9,u:0x1f9,t:0x1f0,B:0x1e0,r:0x1fe,z:0x201,h:0x1dd,d:0x206,l:0x201,y:0x1e1,k:0x201},Gc=GN,Z=Y['emptyHistorySeed']===void 0x0?S:Y[Gc(GJ.Y)],J=Y[Gc(GJ.R)][Gc(GJ.Z)]===0x0&&Z!==null,Q=J?[new j(Z)]:[...Y[Gc(0x205)]],K=J?[...Q]:[];let H=[],t=X();const B=L(Y[Gc(GJ.m)]??D),z=Y[Gc(GJ.J)]===void 0x0?T:Y['emptyResponseRecovery'],k=z?$(z[Gc(GJ.Q)]):0x0;let G0=0x0;for(let G2=0x0;G2<B;G2+=0x1){let G3;try{G3=await this[Gc(GJ.s)]['agent'](Y[Gc(0x1ec)],Q,Y[Gc(GJ.K)],Y[Gc(0x1ff)],Y[Gc(GJ.n)]);}catch(G6){const G7=H;throw H=[],await Promise[Gc(0x1e6)](G7[Gc(GJ.H)](G8=>G8())),G6;}t=E(t,G3[Gc(GJ.u)]),K['push'](G3[Gc(GJ.t)]),Q['push'](G3['value']);const G4=G3[Gc(0x1f0)][Gc(GJ.B)]??[];if(G4[Gc(0x208)]===0x0){const G8=f(Y['llmConfig'])?o(G3[Gc(GJ.t)][Gc(0x1f8)]):F(G3[Gc(0x1f0)]);if(G8[Gc(GJ.r)]())return await G1(),{'messages':K,'usage':t,'response':G8,'stoppedAfterTool':!0x1};const G9=i(G3[Gc(0x1f0)]),GG=w(G9)&&z!==null&&G0<k;if(c({'empty_model_response':a(G9),'retried':GG}),GG&&z){G0+=0x1,K[Gc(0x1f4)](),Q[Gc(0x1f4)](),Q[Gc(GJ.z)](new j(z[Gc(GJ.h)]));continue;}return await G1(),{'messages':K,'usage':t,'response':G8,'stoppedAfterTool':!0x1,'stopReason':G9};}await G1();let G5=!0x1;try{for(const [Ge,Gj]of G4[Gc(0x1fa)]()){const GS=await Y[Gc(0x1e7)](Gj),GC=new g({'content':JSON[Gc(0x1e4)](GS[Gc(GJ.d)]),'tool_call_id':Gj['id']??'tool-call-'+G2+'-'+Ge,'name':Gj[Gc(0x207)]});K['push'](GC),Q['push'](GC),GS['messages']&&(K[Gc(GJ.l)](...GS[Gc(0x1f5)]),Q[Gc(0x201)](...GS['messages'])),GS[Gc(GJ.y)]&&H[Gc(GJ.k)](GS[Gc(0x1e1)]),G5||=GS['stopAfterBatch']===!0x0;}}catch(Gg){throw await G1(),Gg;}if(G5)return await G1(),{'messages':K,'usage':t,'stoppedAfterTool':!0x0};}throw await G1(),new Error('Conversation\x20exceeded\x20'+B+Gc(0x1f6));async function G1(){const Gq=Gc,GE=H;H=[],await Promise[Gq(0x1e6)](GE['map'](GX=>GX()));}p(G1,Gc(0x1e3));}}function G(){const Gs=['nZi0mZrXsNnKC2m','u3rHCNq','Cg9W','BwvZC2fNzxm','igfNzw50ihjVDw5KCY4','mti3mde5n2DZt0vbEa','y29UDgvUDa','DxnHz2u','zw50CMLLCW','Dg9VBhm','BwvZC2fNzvrLEhq','BgXTr2f0zxDHEq','DhjPBq','BgXTq29UzMLN','CMvHC29U','ChvZAa','Bwf4qwDLBNrsB3vUzhm','zw1WDhLszxnWB25ZzvjLy292zxj5','mJCXn2j5zwDkvG','AgLZDg9YEq','B3v0Chv0','BMfTzq','BgvUz3rO','odu3nZK5nK9WwfvKDq','mJq2nZG1y0DxthrP','zw1WDhLszxnWB25ZzvjLy292zxj5lNjLDhjPzxmGBxvZDcbIzsbHig5VBI1UzwDHDgL2zsbPBNrLz2vYoYbYzwnLAxzLzca','AxnjBNrLz2vY','yxnZzxj0twf4qwDLBNrsB3vUzhm','yxnZzxj0rw1WDhLszxnWB25ZzvjLDhjPzxm','mtK0mdbpCxbXqKy','C3rYAw5N','CNvU','vgHLig1VzgvSihjLDhvYBMvKigfUigvTChr5ihjLC3bVBNnLicG','mtzdt0nMEfC','BNvKz2u','mJGZmJe3n09rDenQCa','mtHYwhzsA0u','Dg9VBf9JywXSCW','y2XLyw51Ca','y2fSBe9WDgLVBNm','y2XLyw51Cef0DgfJAg1LBNrZ','C3rYAw5NAwz5','nerSAxv6Aa','ywXSu2v0DgXLza','zxHLy3v0zvrVB2W','rM9SBg93ihrOzsbZExn0zw0GChjVBxb0igfUzcbYzxnWB25KihbYB3bLCMX5lIbvC2uGDgHLihjLCxvPCMvKihrVB2WGD2HLBIbPBNn0CNvJDgvKlG','BwfW','rw1WDhLnB2rLBfjLC3bVBNnLrxjYB3i','CMv0CMLLCW','C3LZDgvTuhjVBxb0','mte2ntjowgLQshK','zw1WDhLiAxn0B3j5u2vLza','zgvMAw5LuhjVCgvYDhK','DMfSDwu','nti1uNnkyuTi'];G=function(){return Gs;};return G();}function F(Y){const GQ={Y:0x1f8,R:0x1e4,Z:0x1f8},Gf=GN;return typeof Y['content']==Gf(0x210)?Y[Gf(GQ.Y)]:JSON[Gf(GQ.R)](Y[Gf(GQ.Z)]);}p(F,GN(0x1fc));export{W as ConversationRunner,q as DEFAULT_CONVERSATION_POLICY,S as DEFAULT_EMPTY_HISTORY_SEED,T as DEFAULT_EMPTY_RESPONSE_RECOVERY,D as DEFAULT_MAX_AGENT_ROUNDS,V as EmptyModelResponseError,$ as assertEmptyResponseRetries,L as assertMaxAgentRounds};
1
+ function K(){const KN=['DgfYz2v0','AgLZDg9YEq','C3rHEq','Bwf4qwDLBNrsB3vUzhmGBxvZDcbIzsbHihbVC2L0AxzLigLUDgvNzxi7ihjLy2vPDMvKia','u3rHCNq','ChvZAa','mZq2mZG3oenpBuLvqW','zxHLy3v0zvrVB2W','BwvZC2fNzvrLEhq','CMvHC29U','C3LZDgvTuhjVBxb0','BMfTzq','CNvU','Axntyw1LqMfYzvrYyw5ZAxrPB24','y2fSBe9WDgLVBNm','zw50CMLLCW','ywXSu2v0DgXLza','y29UDgvUDa','Cg9W','zw1WDhLiAxn0B3j5u2vLza','Dg9VBhm','Dg9VBc1JywXSlq','mtK3mta4uwjct0vt','C3rHDgu','Bwf4qwDLBNrsB3vUzhm','ntKWodi4menwv01ctq','q29UDMvYC2f0Aw9Uigv4y2vLzgvKia','yxnZzxj0rw1WDhLszxnWB25ZzvjLDhjPzxm','zw1WDhLszxnWB25ZzvjLy292zxj5','BNvKz2u','rw1WDhLnB2rLBfjLC3bVBNnLrxjYB3i','BwvZC2fNzq','ywDLBNq','ndj3D0rzsvO','DhjPBq','Aw50zxjUywXiDw1HBK1LC3nHz2u','zMvLzgjHy2S','otG3mZbgvgnkvNu','DxnHz2u','yxnZzxj0twf4qwDLBNrsB3vUzhm','AxnjBNrLz2vY','nJy2mdi4rvLxsvbk','CMvZCg9UC2u','BgvUz3rO','zgvMAw5LuhjVCgvYDhK','q29UDMvYC2f0Aw9UuNvUBMvY','BwfW','ndq0nZa2nvnJAMv6sa','ndKZnteYEuDVywHq','BgXTr2f0zxDHEq','BwvZC2fNzxm','zw1WDhLszxnWB25ZzvjLy292zxj5lNjLDhjPzxmGBxvZDcbIzsbHig5VBI1UzwDHDgL2zsbPBNrLz2vYoYbYzwnLAxzLzca','DMfSDwu','ovP3Aw1srW','y2XLyw51Ca','BgXTq29UzMLN','A2LUza'];K=function(){return KN;};return K();}const Kq=e;(function(M,u){const KA={M:0x197,u:0x193,A:0x19d,r:0x187},Kk=e,A=M();while(!![]){try{const r=-parseInt(Kk(KA.M))/0x1+parseInt(Kk(KA.u))/0x2+parseInt(Kk(0x18f))/0x3*(parseInt(Kk(0x184))/0x4)+-parseInt(Kk(KA.A))/0x5+parseInt(Kk(0x174))/0x6+parseInt(Kk(KA.r))/0x7+parseInt(Kk(0x19e))/0x8*(-parseInt(Kk(0x16a))/0x9);if(r===u)break;else A['push'](A['shift']());}catch(f){A['push'](A['shift']());}}}(K,0x84aea));var v=Object[Kq(0x19a)],i=(M,u)=>v(M,'name',{'value':u,'configurable':!0x0});import{AIMessage as J,HumanMessage as V,ToolMessage as m}from'@langchain/core/messages';import{addTokenUsage as h,emptyTokenUsage as c}from'./token-usage.js';import{isToolResponse as s}from'./tool-response.js';import{describeStopReason as n,isRetryableStopReason as o,modelStopReason as z}from'./model-stop-reason.js';import{SessionLogWarning as t}from'./session-log.js';import{isOpenAIAuthConfig as E,openAIAuthMessageText as q}from'./openai-auth-provider.js';class j extends Error{static{i(this,Kq(0x18c));}[Kq(0x177)];constructor(M){const Kx={M:0x179},KD=Kq;super('The\x20model\x20returned\x20an\x20empty\x20response\x20('+n(M)+').'),this['reason']=M,this[KD(Kx.M)]='EmptyModelResponseError';}}const $=0x8;function F(M){const Kr={M:0x196,u:0x171},KM=Kq;if(!Number[KM(Kr.M)](M)||M<0x1)throw new Error(KM(Kr.u)+String(M)+'.');return M;}function e(j,C){j=j-0x168;const I=K();let J=I[j];if(e['ZMOyaa']===undefined){var F=function(c){const s='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let P='',n='';for(let o=0x0,z,H,t=0x0;H=c['charAt'](t++);~H&&(z=o%0x4?z*0x40+H:H,o++%0x4)?P+=String['fromCharCode'](0xff&z>>(-0x2*o&0x6)):0x0){H=s['indexOf'](H);}for(let E=0x0,q=P['length'];E<q;E++){n+='%'+('00'+P['charCodeAt'](E)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(n);};e['MLcmJN']=F,e['BemBlG']={},e['ZMOyaa']=!![];}const V=I[0x0],m=j+V,h=e['BemBlG'][m];return!h?(J=e['MLcmJN'](J),e['BemBlG'][m]=J):J=h,J;}i(F,Kq(0x195));const x=Kq(0x172),S={'retries':0x2,'nudge':'Follow\x20the\x20system\x20prompt\x20and\x20respond\x20properly.\x20Use\x20the\x20required\x20tool\x20when\x20instructed.'};function Y(M){const KS={M:0x168},KQ=Kq;if(!Number['isInteger'](M)||M<0x0)throw new Error(KQ(KS.M)+String(M)+'.');return M;}i(Y,Kq(0x189));const Q={'emptyHistorySeed':x,'emptyResponseRecovery':S};class Z{static{i(this,Kq(0x19b));}[Kq(0x19f)];constructor(M){const KZ=Kq;this[KZ(0x19f)]=M;}async[Kq(0x17a)](X){const Kd={M:0x181,u:0x16f,A:0x16f,r:0x186,f:0x182,d:0x173,y:0x169,X:0x17f,w:0x190,R:0x18b,g:0x17d,p:0x16d,a:0x16d,W:0x170,l:0x192,K0:0x1a0,K1:0x16b,K2:0x170,K3:0x173,K4:0x173},Kv={M:0x19c},KO=Kq,W=X[KO(0x181)]===void 0x0?x:X[KO(Kd.M)],K0=X[KO(Kd.u)][KO(0x199)]===0x0&&W!==null,K1=K0?[_(W)]:[...X[KO(Kd.A)]],K2=K0?[...K1]:[];let K3=[],K4=c();const K5=F(X[KO(Kd.r)]??$),K6=X['emptyResponseRecovery']===void 0x0?S:X[KO(0x18a)],K7=K6?Y(K6['retries']):0x0;let K8=0x0;for(let KK=0x0;KK<K5;KK+=0x1){let Ke;try{Ke=await this['llmGateway'][KO(0x18e)](X[KO(0x178)],K1,X[KO(Kd.f)],X['llmConfig'],X[KO(0x17c)]);}catch(KJ){const KF=K3;throw K3=[],await Promise[KO(0x17e)](KF['map'](KV=>KV())),KJ;}K4=h(K4,Ke['usage']),K2[KO(0x173)](Ke[KO(0x169)]),K1[KO(Kd.d)](Ke[KO(Kd.y)]);const Kj=Ke['value']['tool_calls']??[];if(Kj[KO(0x199)]===0x0){const KV=E(X[KO(0x16c)])?q(Ke[KO(0x169)][KO(Kd.X)]):B(Ke[KO(0x169)]);if(KV[KO(Kd.w)]())return await K9(),{'messages':K2,'usage':K4,'response':KV,'stoppedAfterTool':!0x1};const Km=z(Ke[KO(0x169)]),Kh=o(Km)&&K6!==null&&K8<K7;if(t({'empty_model_response':n(Km),'retried':Kh}),Kh&&K6){K8+=0x1,K2[KO(0x180)](),K1['pop'](),K1['push'](_(K6[KO(Kd.R)]));continue;}return await K9(),{'messages':K2,'usage':K4,'response':KV,'stoppedAfterTool':!0x1,'stopReason':Km};}await K9();let KC=!0x1,KI;try{for(const [Kc,Ks]of Kj[KO(Kd.g)]()){const KP=await X[KO(0x175)](Ks);if(s(KP)){if(KP[KO(Kd.p)]!=='stay'){if(KI&&KI[KO(Kd.a)]!==KO(Kd.W)&&!G(KI,KP))throw new Error('A\x20tool\x20batch\x20selected\x20more\x20than\x20one\x20terminal\x20response\x20or\x20transition.');KI=KP;}else KI||(KI=KP);const Kn=new m({'content':KP[KO(Kd.l)]??'OK','tool_call_id':Ks['id']??KO(0x183)+KK+'-'+Kc,'name':Ks[KO(0x179)]});K2[KO(0x173)](Kn),K1['push'](Kn),KP['messages']&&(K2['push'](...KP[KO(Kd.K0)]),K1['push'](...KP[KO(0x1a0)])),KP[KO(0x16b)]&&K3[KO(0x173)](KP[KO(Kd.K1)]),KC||=KP['kind']!==KO(Kd.K2);continue;}}}catch(Ko){throw await K9(),Ko;}if(KC){const Kz=KI?.['response'];if(Kz){const KH=new J(Kz);K2[KO(Kd.K3)](KH),K1[KO(Kd.K4)](KH);}return await K9(),{'messages':K2,'usage':K4,'stoppedAfterTool':!0x0,...Kz?{'response':Kz}:{},...KI?{'toolResponse':KI}:{}};}}throw await K9(),new Error(KO(0x188)+K5+'\x20agent\x20rounds.');async function K9(){const Kb=KO,Kt=K3;K3=[],await Promise[Kb(0x17e)](Kt[Kb(Kv.M)](KE=>KE()));}i(K9,'cleanupAttachments');}}function G(M,u){const Ky={M:0x16d,u:0x1a0,A:0x198,r:0x194},Ku=Kq;return M[Ku(0x16d)]==='go'&&u[Ku(Ky.M)]==='go'&&M['target']===u[Ku(0x16e)]&&M[Ku(0x185)]===void 0x0&&u[Ku(0x185)]===void 0x0&&M[Ku(0x18d)]===void 0x0&&u[Ku(0x18d)]===void 0x0&&M[Ku(Ky.u)]===void 0x0&&u['messages']===void 0x0&&M[Ku(0x16b)]===void 0x0&&u[Ku(0x16b)]===void 0x0&&M[Ku(0x198)]===void 0x0&&u[Ku(Ky.A)]===void 0x0&&M[Ku(Ky.r)]===void 0x0&&u['usage']===void 0x0;}i(G,Kq(0x17b));function _(M){return new V({'content':M,'additional_kwargs':{'ezgraphInternal':!0x0}});}i(_,Kq(0x191));function B(M){const Kw={M:0x17f},KU=Kq;return typeof M[KU(Kw.M)]=='string'?M[KU(0x17f)]:JSON['stringify'](M[KU(0x17f)]);}i(B,Kq(0x176));export{Z as ConversationRunner,Q as DEFAULT_CONVERSATION_POLICY,x as DEFAULT_EMPTY_HISTORY_SEED,S as DEFAULT_EMPTY_RESPONSE_RECOVERY,$ as DEFAULT_MAX_AGENT_ROUNDS,j as EmptyModelResponseError,Y as assertEmptyResponseRetries,F as assertMaxAgentRounds};
@@ -0,0 +1 @@
1
+ var D=Object.defineProperty;var n=(a,o)=>D(a,"name",{value:o,configurable:!0});import{GraphNode as v}from"../graph-node.js";import{currentTurnSignal as m}from"../turn-context.js";import{DecisionRunner as C}from"./decision-runner.js";import{assertJsonCompatible as w,validateDecisionQuestions as g}from"./decision-validation.js";class y extends v{static{n(this,"DecisionNode")}getPrompt(o){return""}getDecisionEvidence(o){return{}}getDecisionConfig(){return{}}onDecisionError(o){return null}async run(o){this.assertNoChatConfiguration();const t=m();t?.throwIfAborted();const h=this.graph.resolveDecisionOptions(this.getDecisionConfig()),f=this.graph.resolveDecisionProvider(h.provider),l=structuredClone(this.defineQuestions(o));g(l);const u=this.getPrompt(o).trim(),d=Object.fromEntries(Object.entries(l).map(([e,i])=>[e,{...i,...u?{instructions:[u,...i.instructions===void 0?[]:[i.instructions]]}:{}}]));g(d);const s=this.graph.getConversation(this.historySpace()),c=structuredClone(this.getDecisionEvidence(o));if("request"in c||"priorRequests"in c)throw new Error("getDecisionEvidence() cannot replace framework-owned request or priorRequests.");const p={...c,request:s.request,priorRequests:[...s.priorRequests]};return w(p,"Decision input"),C.run({nodeId:this.id,state:o,conversation:s,providerState:p,questions:d,provider:f,options:h,callerSignal:t,onDecision:n(async(e,i,r)=>this.resolveNodeResponse(await this.onDecision(e,i,r)),"onDecision"),onError:n(async e=>{const r=await this.onDecisionError(e)??await this.graph.handleDecisionError(e);if(r===null)throw e.error;return this.resolveNodeResponse(r)},"onError")})}validateTools(){this.assertNoChatConfiguration();const o=this.graph.resolveDecisionOptions(this.getDecisionConfig());this.graph.resolveDecisionProvider(o.provider)}assertNoChatConfiguration(){const o=this.defineTool(),t=this.obtainTools();if(o.length>0||t.length>0)throw new Error("DecisionNode cannot configure chat tools.");if(Object.keys(this.getLlmConfig()).length>0)throw new Error("DecisionNode uses getDecisionConfig(), not a chat model configuration.")}usesChatModel(){return!1}async runConversation(o,t){throw new Error("DecisionNode does not run the conversational model loop.")}}export{y as DecisionNode};
@@ -0,0 +1 @@
1
+ var n=Object.defineProperty;var t=(s,e)=>n(s,"name",{value:e,configurable:!0});import{DecisionConfigurationError as o}from"./decision-types.js";import{TypeSafeClassifierAdapter as p}from"./typesafe-provider.js";class v{static{t(this,"DecisionProvider")}constructor(){}static create(e){const r=[];return Object.hasOwn(e,"typesafe")&&r.push(new p(e.typesafe)),r}}class f{static{t(this,"DecisionProviderRegistry")}providers=new Map;constructor(e=[]){for(const r of e){const i=r.id.trim();if(!i)throw new o("Decision provider IDs must be non-empty.");if(i!==r.id)throw new o(`Decision provider ID '${r.id}' cannot have leading or trailing whitespace.`);if(this.providers.has(i))throw new o(`Decision provider '${i}' is already registered.`);this.providers.set(i,r)}}resolve(e){const r=this.providers.get(e);if(!r)throw new o(`Decision provider '${e}' is not registered.`);return r}}export{v as DecisionProvider,f as DecisionProviderRegistry};
@@ -0,0 +1 @@
1
+ var k=Object.defineProperty;var n=(o,e)=>k(o,"name",{value:e,configurable:!0});import{Command as M,isCommand as v}from"@langchain/langgraph";import{SessionLogDecision as _,SessionLogWarning as m}from"../session-log.js";import{DecisionConfigurationError as L,DecisionTimeoutError as P,DecisionValidationError as h,addDecisionUsage as I,decisionUsage as U,emptyDecisionUsage as C}from"./decision-types.js";import{validateDecisionResult as R}from"./decision-validation.js";class G{static{n(this,"DecisionRunner")}static async run(e){e.callerSignal?.throwIfAborted();const i=performance.now();let t=0,a=C(),r,d,c;try{for(;;){t+=1;try{r=await x(e),d=r.model,c=r.requestId,a=I(a,U(N(r))),R(r,e.questions);break}catch(l){const s=D(l);if(e.callerSignal?.throwIfAborted(),A(s)||!(!(s instanceof h)&&(s.name==="TimeoutError"||e.provider.shouldRetry?.(s)===!0))||t>e.options.maxRetries)throw s;m({decision_retry:!0,node:e.nodeId,provider:e.provider.id,attempt:t+1}),await F(250,e.callerSignal)}}}catch(l){const s=D(l);if(e.callerSignal?.throwIfAborted(),A(s))throw s;const u=j(s);m({decision_fallback:u,node:e.nodeId,provider:e.provider.id});const w=y(e,{outcome:"fallback",failure:u,attempts:t,durationMs:performance.now()-i,usage:a,...d?{actualModel:d}:{},...c?{requestId:c}:{}});let g;try{g=await q(e.onError({nodeId:e.nodeId,provider:e.provider.id,model:e.options.model,failure:u,attempts:t,error:s,state:e.state}),e.callerSignal,"Decision fallback handler aborted.")}catch(T){throw w&&(w.outcome="fallback_handler_failed"),S(e,"fallback",t,a),T}return e.callerSignal?.throwIfAborted(),E(g,a)}e.callerSignal?.throwIfAborted();const f={provider:e.provider.id,model:r.model,durationMs:performance.now()-i,attempts:t,usage:r.usage??{},...r.requestId?{requestId:r.requestId}:{},request:e.conversation.request,priorRequests:[...e.conversation.priorRequests]},p=y(e,{outcome:"success",attempts:t,durationMs:f.durationMs,usage:a,actualModel:r.model,...r.requestId?{requestId:r.requestId}:{}});let b;try{b=await q(e.onDecision(r.answers,f,e.state),e.callerSignal,"Decision handler aborted.")}catch(l){throw p&&(p.outcome="decision_handler_failed"),S(e,"decision",t,a),l}return e.callerSignal?.throwIfAborted(),E(b,a)}}function y(o,e){return _({node:o.nodeId,provider:o.provider.id,configuredModel:o.options.model,...e})}n(y,"recordDecision");async function x(o){const e=new AbortController,i=setTimeout(()=>e.abort(new P),o.options.timeoutMs),t=o.callerSignal?AbortSignal.any([o.callerSignal,e.signal]):e.signal;let a=n(()=>{},"onAbort");try{t.throwIfAborted();const r=new Promise((c,f)=>{a=n(()=>f(t.reason??new Error("Decision call aborted.")),"onAbort"),t.addEventListener("abort",a,{once:!0})}),d=await Promise.race([o.provider.decide({model:o.options.model,state:o.providerState,questions:o.questions},{signal:t,timeoutMs:o.options.timeoutMs}),r]);return t.throwIfAborted(),d}finally{clearTimeout(i),t.removeEventListener("abort",a)}}n(x,"callProvider");function E(o,e){const i=v(o)?o.update??{}:o,t={...i,decisionUsage:I(i.decisionUsage,e)};return v(o)?new M({update:t,...o.goto===void 0?{}:{goto:o.goto},...o.graph===void 0?{}:{graph:o.graph},...o.resume===void 0?{}:{resume:o.resume}}):t}n(E,"withUsage");function F(o,e){return e?(e.throwIfAborted(),new Promise((i,t)=>{const a=setTimeout(()=>{e.removeEventListener("abort",r),i()},o),r=n(()=>{clearTimeout(a),t(e.reason??new Error("Decision retry aborted."))},"onAbort");e.addEventListener("abort",r,{once:!0})})):new Promise(i=>setTimeout(i,o))}n(F,"retryDelay");async function q(o,e,i){if(!e)return o;e.throwIfAborted();let t=n(()=>{},"onAbort");try{const a=new Promise((d,c)=>{t=n(()=>c(e.reason??new Error(i)),"onAbort"),e.addEventListener("abort",t,{once:!0})}),r=await Promise.race([Promise.resolve(o),a]);return e.throwIfAborted(),r}finally{e.removeEventListener("abort",t)}}n(q,"withCallerCancellation");function j(o){return o instanceof h?"validation":o.name==="TimeoutError"?"timeout":"provider"}n(j,"classifyFailure");function A(o){if(o instanceof L)return!0;const e=o.status;return e===401||e===403}n(A,"isConfigurationFailure");function D(o){return o instanceof Error?o:new Error(String(o))}n(D,"asError");function N(o){if(!o||typeof o!="object")return{};const e=o.usage;if(!e||typeof e!="object")return{};const i=e.inputTokens,t=e.outputTokens;return{...Number.isInteger(i)&&i>=0?{inputTokens:i}:{},...Number.isInteger(t)&&t>=0?{outputTokens:t}:{}}}n(N,"observedUsage");function S(o,e,i,t){m({decision_handler_failed:e,node:o.nodeId,provider:o.provider.id,model:o.options.model,attempts:i,observedDecisionUsage:t})}n(S,"logHandlerFailure");export{G as DecisionRunner};
@@ -0,0 +1 @@
1
+ var c=Object.defineProperty;var n=(o,t)=>c(o,"name",{value:t,configurable:!0});function l(){return{calls:0,inputTokens:0,outputTokens:0,totalTokens:0}}n(l,"emptyDecisionUsage");function u(o){const t=o??{},e=i(t.inputTokens),r=i(t.outputTokens);return{calls:i(t.calls),inputTokens:e,outputTokens:r,totalTokens:e+r}}n(u,"normalizeDecisionUsage");function m(o,t){const e=u(o),r=u(t);return{calls:e.calls+r.calls,inputTokens:e.inputTokens+r.inputTokens,outputTokens:e.outputTokens+r.outputTokens,totalTokens:e.totalTokens+r.totalTokens}}n(m,"addDecisionUsage");function T(o={}){const t=i(o.inputTokens),e=i(o.outputTokens);return{calls:1,inputTokens:t,outputTokens:e,totalTokens:t+e}}n(T,"decisionUsage");function i(o){return Number.isInteger(o)&&(o??-1)>=0?o??0:0}n(i,"nonnegativeInteger");const a={provider:"typesafe",model:"jev-latest",timeoutMs:3e4,maxRetries:0};function d(o={},t={}){const e={...a,...o,...t};if(typeof e.provider!="string"||typeof e.model!="string"||!e.provider.trim()||!e.model.trim())throw new s("Decision provider and model must be non-empty.");if(!Number.isInteger(e.timeoutMs)||e.timeoutMs<1)throw new s(`Decision timeoutMs must be a positive integer; received ${String(e.timeoutMs)}.`);if(!Number.isInteger(e.maxRetries)||e.maxRetries<0)throw new s(`Decision maxRetries must be a non-negative integer; received ${String(e.maxRetries)}.`);return{...e,provider:e.provider.trim(),model:e.model.trim()}}n(d,"resolveDecisionOptions");class k extends Error{static{n(this,"DecisionValidationError")}constructor(t){super(t),this.name="DecisionValidationError"}}class s extends Error{static{n(this,"DecisionConfigurationError")}constructor(t){super(t),this.name="DecisionConfigurationError"}}class g extends Error{static{n(this,"DecisionTimeoutError")}constructor(t="Decision call timed out."){super(t),this.name="TimeoutError"}}export{a as DEFAULT_DECISION_OPTIONS,s as DecisionConfigurationError,g as DecisionTimeoutError,k as DecisionValidationError,m as addDecisionUsage,T as decisionUsage,l as emptyDecisionUsage,u as normalizeDecisionUsage,d as resolveDecisionOptions};
@@ -0,0 +1 @@
1
+ var y=Object.defineProperty;var a=(t,i)=>y(t,"name",{value:i,configurable:!0});import{z as e}from"zod";import{DecisionValidationError as c}from"./decision-types.js";const o=e.lazy(()=>e.union([e.string(),e.number(),e.boolean(),e.null(),e.array(o),e.record(e.string(),o)])),u=e.union([e.string(),e.record(e.string(),o),e.array(o)]),g=e.discriminatedUnion("type",[e.object({type:e.literal("choice"),criteria:e.record(e.string(),o).refine(t=>Object.keys(t).length>0&&Object.keys(t).every(i=>i.trim().length>0)),instructions:u.optional()}).strict(),e.object({type:e.literal("score"),criteria:e.array(o).min(2),instructions:u.optional()}).strict(),e.object({type:e.literal("noul"),criteria:e.object({true:o.optional(),false:o.optional()}).strict().optional(),instructions:u.optional()}).strict().refine(t=>t.instructions!==void 0||t.criteria!==void 0)]),l=e.number().min(0).max(1),h=e.discriminatedUnion("type",[e.object({type:e.literal("choice"),choice:e.string(),probabilities:e.record(e.string(),l),confidence:l}).strict(),e.object({type:e.literal("score"),score:e.number().nonnegative(),legend:e.record(e.string(),o),probabilities:e.record(e.string(),l),confidence:l}).strict(),e.object({type:e.literal("noul"),noul:l}).strict()]),m=e.object({model:e.string().min(1),answers:e.record(e.string(),h),usage:e.object({inputTokens:e.number().int().nonnegative().optional(),outputTokens:e.number().int().nonnegative().optional()}).strict().optional(),requestId:e.string().optional()}).strict();function w(t,i){if(!o.safeParse(t).success)throw new c(`${i} must contain only JSON values.`)}a(w,"assertJsonCompatible");function k(t){if(w(t,"Decision questions"),!t||Object.keys(t).length===0)throw new c("At least one decision question is required.");for(const[i,s]of Object.entries(t))if(!i.trim()||!g.safeParse(s).success)throw new c(`Invalid decision question '${i}'.`)}a(k,"validateDecisionQuestions");function $(t,i){if(!m.safeParse(t).success||!p(t.answers,Object.keys(i)))throw new c("Decision response does not match the registered questions.");for(const[s,r]of Object.entries(i)){const n=t.answers[s];if(!n||n.type!==r.type)throw new c(`Wrong decision answer type for '${s}'.`);if(n.type==="choice"&&r.type==="choice"&&(!Object.hasOwn(r.criteria,n.choice)||!p(n.probabilities,Object.keys(r.criteria))))throw new c(`Unknown or missing choice for '${s}'.`);if(n.type==="score"&&r.type==="score"){const b=r.criteria.map((d,f)=>String(f));if(n.score>r.criteria.length-1||!p(n.probabilities,b)||!p(n.legend,b))throw new c(`Invalid score range or legend for '${s}'.`)}if(n.type!=="noul"&&Math.abs(Object.values(n.probabilities).reduce((b,d)=>b+d,0)-1)>.02)throw new c(`Invalid probability distribution for '${s}'.`)}}a($,"validateDecisionResult");function p(t,i){return Object.keys(t).length===i.length&&i.every(r=>Object.hasOwn(t,r))}a(p,"sameKeys");export{w as assertJsonCompatible,k as validateDecisionQuestions,$ as validateDecisionResult};
@@ -0,0 +1 @@
1
+ var c=Object.defineProperty;var i=(o,e)=>c(o,"name",{value:e,configurable:!0});import{DecisionConfigurationError as u}from"./decision-types.js";class T{static{i(this,"TypeSafeClassifierAdapter")}options;id="typesafe";constructor(e={}){this.options=e}async decide(e,t){const n=this.options.apiKey??process.env.TYPESAFE_API_KEY;if(!n)throw new u("TypeSafe decision provider requires TYPESAFE_API_KEY or an explicit apiKey.");let r;try{({TypeSafeClassifier:r}=await import("@langchain/typesafe"))}catch(a){throw d(a)?new u("TypeSafe decision provider requires the optional '@langchain/typesafe' package."):a}const s=await new r({apiKey:n,...this.options.fetch===void 0?{}:{fetch:this.options.fetch},model:e.model,questions:structuredClone(e.questions),maxRetries:0,timeout:t.timeoutMs,dangerouslyAllowBrowser:!1}).invoke(structuredClone(e.state),{signal:t.signal});return{model:s.model,answers:s.answers,usage:{...s.usage.inputTokens===void 0?{}:{inputTokens:s.usage.inputTokens},...s.usage.outputTokens===void 0?{}:{outputTokens:s.usage.outputTokens}},...s.requestId?{requestId:s.requestId}:{}}}shouldRetry(e){const t=e.status;return t===408||t===429||t!==void 0&&t>=500||["TypeSafeAPIConnectionError","TypeSafeAPITimeoutError","TimeoutError"].includes(e.name)}}function d(o){return o instanceof Error?o.code==="ERR_MODULE_NOT_FOUND"&&o.message.includes("@langchain/typesafe"):!1}i(d,"isMissingTypeSafePackage");export{T as TypeSafeClassifierAdapter};