@hugex/ai 2.8.12 → 2.8.15
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 +132 -100
- package/dist/index.js +8 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
# @hugex/ai
|
|
2
2
|
|
|
3
|
-
HugeX Agent runtime
|
|
3
|
+
HugeX Agent runtime — a React client hook (`useAgent`) plus optional server handlers for hosting the agent backend on Cloudflare Workers.
|
|
4
4
|
|
|
5
|
-
Flows are **designed** in the [HugeX platform](https://hugex.co/) (**Agent Design**) and **saved** to HX Core.
|
|
5
|
+
Flows are **designed** in the [HugeX platform](https://hugex.co/) (**Agent Design**) and **saved** to HX Core. Most integrations only need the **client** half: install `@hugex/ai`, point `useAgent` at an already-deployed WebSocket endpoint, and render chat UI from the agent store.
|
|
6
|
+
|
|
7
|
+
## Two parts
|
|
8
|
+
|
|
9
|
+
| Part | Import | Runs in | When you need it |
|
|
10
|
+
|---|---|---|---|
|
|
11
|
+
| **Client** | `@hugex/ai/client` | Your React app (browser) | **Always** — connect UI to an agent session |
|
|
12
|
+
| **Server** | `@hugex/ai` | Cloudflare Worker | **Only if you host the agent runtime** (tenant Worker deployment) |
|
|
13
|
+
| **Shared types** | `@hugex/ai/common` | Either | Wire-protocol and flow types |
|
|
14
|
+
|
|
15
|
+
**You do not run `useAgent` on Cloudflare Workers.** The hook is frontend-only. It opens a WebSocket to a session endpoint; that endpoint is usually served by a HugeX tenant Worker you or HugeX already deployed. Your SPA can run anywhere — same origin, a separate frontend host, or a local dev server — as long as it can reach the WebSocket URL.
|
|
6
16
|
|
|
7
17
|
## Install
|
|
8
18
|
|
|
@@ -10,77 +20,43 @@ Flows are **designed** in the [HugeX platform](https://hugex.co/) (**Agent Desig
|
|
|
10
20
|
pnpm add @hugex/ai
|
|
11
21
|
```
|
|
12
22
|
|
|
13
|
-
Peer dependencies are declared in the package — align versions with your
|
|
23
|
+
Peer dependencies are declared in the package — align versions with your app.
|
|
14
24
|
|
|
15
|
-
##
|
|
25
|
+
## Integration paths
|
|
16
26
|
|
|
17
|
-
|
|
18
|
-
|---|---|
|
|
19
|
-
| `@hugex/ai` | Server: `handleAgentsRoutes`, `handleAuthRoutes`, `handleCommonRoutes`, `handleIntancesRoutes`, `AgentDO` |
|
|
20
|
-
| `@hugex/ai/client` | Client: `useAgent`, `useAgentStore`, `getAgentStore` |
|
|
21
|
-
| `@hugex/ai/common` | Shared types: `NodeType`, WS `messageTypes`, flow/message types |
|
|
27
|
+
### Frontend only (most common)
|
|
22
28
|
|
|
23
|
-
|
|
29
|
+
Use `@hugex/ai/client` in your React app. You need:
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
1. **flowId** — the agent graph id from Agent Design
|
|
32
|
+
2. **sessionId** — a stable id for this chat session (UUID recommended)
|
|
33
|
+
3. **WebSocket endpoint** — URL of a deployed agent server (see [WebSocket paths](#websocket-paths))
|
|
26
34
|
|
|
27
|
-
|
|
28
|
-
// workers/app.ts
|
|
29
|
-
import {
|
|
30
|
-
handleAgentsRoutes,
|
|
31
|
-
handleAuthRoutes,
|
|
32
|
-
handleCommonRoutes,
|
|
33
|
-
handleIntancesRoutes,
|
|
34
|
-
} from '@hugex/ai';
|
|
35
|
+
No Worker code, wrangler config, or server imports required in your frontend repo.
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const auth = await handleAuthRoutes(request, env, ctx);
|
|
42
|
-
if (auth instanceof Response) return auth;
|
|
43
|
-
|
|
44
|
-
const agent = await handleAgentsRoutes(request, env, ctx);
|
|
45
|
-
if (agent instanceof Response) return agent;
|
|
46
|
-
|
|
47
|
-
const instances = await handleIntancesRoutes(request, env, ctx);
|
|
48
|
-
if (instances instanceof Response) return instances;
|
|
49
|
-
|
|
50
|
-
// Then delegate to your app's SSR/router handler.
|
|
51
|
-
return yourAppHandler(request, { cloudflare: { env, ctx }, state: { ...auth } });
|
|
52
|
-
},
|
|
53
|
-
} satisfies ExportedHandler<Env>;
|
|
54
|
-
|
|
55
|
-
export { AgentDO } from '@hugex/ai';
|
|
56
|
-
```
|
|
37
|
+
| Scenario | `host` | Notes |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| App and agent server share a domain | omit | `basePath` is relative to the page origin |
|
|
40
|
+
| App on a different host (SPA, mobile web, local dev) | set to agent server host | e.g. `tenant.data.ora.socketServer` |
|
|
41
|
+
| Multiple agents on one screen | + `storeKey` | Isolates chat state per agent |
|
|
57
42
|
|
|
58
|
-
|
|
43
|
+
### Self-hosted runtime (tenant Worker)
|
|
59
44
|
|
|
60
|
-
|
|
61
|
-
{
|
|
62
|
-
"durable_objects": {
|
|
63
|
-
"bindings": [{ "class_name": "AgentDO", "name": "AGENT" }]
|
|
64
|
-
},
|
|
65
|
-
"migrations": [{ "tag": "v2", "new_sqlite_classes": ["AgentDO"] }]
|
|
66
|
-
}
|
|
67
|
-
```
|
|
45
|
+
Only needed when **your** Cloudflare Worker must serve agent WebSocket routes (`/api/agent/flow/...`, `/api/ora/connect/...`) and run `AgentDO` sessions. See [Cloudflare Workers (optional)](#cloudflare-workers-optional--host-the-runtime).
|
|
68
46
|
|
|
69
|
-
|
|
47
|
+
HugeX-managed tenant deployments already include this — frontend teams typically skip this section.
|
|
70
48
|
|
|
71
49
|
## Flow IDs and agent configuration
|
|
72
50
|
|
|
73
|
-
A **flow** is the graph you edit in
|
|
74
|
-
|
|
75
|
-
At runtime:
|
|
51
|
+
A **flow** is the graph you edit in **Agent Design** (`/ai/agents/:id`). The URL param `id` is the **flowId** (e.g. `1rShqGMrANRGmXTN1mjTJB`).
|
|
76
52
|
|
|
77
53
|
| Concept | Value | Notes |
|
|
78
54
|
|---|---|---|
|
|
79
|
-
| **flowId** | Agent Design `:id` | Identifies which flow graph to run
|
|
80
|
-
| **sessionId** | UUID (or stable string) | One chat session; maps to
|
|
81
|
-
| **
|
|
55
|
+
| **flowId** | Agent Design `:id` | Identifies which flow graph to run |
|
|
56
|
+
| **sessionId** | UUID (or stable string) | One chat session; server maps this to session state |
|
|
57
|
+
| **Session key** | `` `${flowId}::${sessionId}` `` | Server-side identifier (used when hosting the runtime) |
|
|
82
58
|
|
|
83
|
-
Flow metadata (tenant, visibility, status) lives in HX Core
|
|
59
|
+
Flow metadata (tenant, visibility, status) lives in HX Core. The runtime loads flow **state** (nodes/edges) from HX Core on WebSocket connect.
|
|
84
60
|
|
|
85
61
|
### Node types (flow graph)
|
|
86
62
|
|
|
@@ -97,9 +73,9 @@ Design-time node data (configured in Agent Design panels):
|
|
|
97
73
|
|
|
98
74
|
Rules: exactly one Start, at least one Answer, all paths connected.
|
|
99
75
|
|
|
100
|
-
## `useAgent` — client
|
|
76
|
+
## `useAgent` — client integration
|
|
101
77
|
|
|
102
|
-
`useAgent` opens a WebSocket to the session
|
|
78
|
+
`useAgent` opens a WebSocket to the agent session, decodes the `TYPE::CONTENT` wire protocol, and writes conversation state into the agent store. UI components subscribe to the store and call `send`, `clearHistory`, etc.
|
|
103
79
|
|
|
104
80
|
### Options
|
|
105
81
|
|
|
@@ -119,16 +95,16 @@ Returns `{ connection, store, send, clearHistory, sendAuth, setIdentity, approve
|
|
|
119
95
|
|
|
120
96
|
### WebSocket paths
|
|
121
97
|
|
|
122
|
-
|
|
98
|
+
These routes are served by the **agent backend** (typically a deployed tenant Worker). Your frontend connects to them; it does not implement them.
|
|
123
99
|
|
|
124
100
|
| Route | Auth | Typical use |
|
|
125
101
|
|---|---|---|
|
|
126
102
|
| `/api/agent/flow/{flowId}/{sessionId}` | JWT / `access_token` query | Tenant chat UIs, Run panel |
|
|
127
|
-
| `/api/ora/connect/{flowId}/{sessionId}` | Agent API key (`authorization` query/header) |
|
|
103
|
+
| `/api/ora/connect/{flowId}/{sessionId}` | Agent API key (`authorization` query/header) | Design assistant, tooling |
|
|
128
104
|
|
|
129
|
-
### Pattern 1 —
|
|
105
|
+
### Pattern 1 — same-origin chat
|
|
130
106
|
|
|
131
|
-
|
|
107
|
+
Frontend and agent server share a domain. No `host` needed. Uses the global store (`useAgentStore`).
|
|
132
108
|
|
|
133
109
|
```tsx
|
|
134
110
|
import { useAgent, useAgentStore } from '@hugex/ai/client';
|
|
@@ -146,19 +122,19 @@ function Chat({ flowId, sessionId }: { flowId: string; sessionId: string }) {
|
|
|
146
122
|
}
|
|
147
123
|
```
|
|
148
124
|
|
|
149
|
-
|
|
125
|
+
### Pattern 2 — cross-origin chat
|
|
150
126
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
Flow under design in Agent Design; `flowId` from route params; session from run store; JWT via `query`:
|
|
127
|
+
Frontend runs on a different host (SPA, local dev, separate deployment). Set `host` to the deployed agent server.
|
|
154
128
|
|
|
155
129
|
```tsx
|
|
130
|
+
import { useAgent, useAgentStore } from '@hugex/ai/client';
|
|
131
|
+
|
|
156
132
|
const flowId = '…'; // from your route or config
|
|
157
|
-
const sessionId = '…'; // from
|
|
158
|
-
const
|
|
133
|
+
const sessionId = '…'; // from session store
|
|
134
|
+
const socketHost = '…'; // deployed agent server host (no path)
|
|
159
135
|
|
|
160
136
|
const { send, sendAuth, clearHistory } = useAgent({
|
|
161
|
-
host:
|
|
137
|
+
host: socketHost,
|
|
162
138
|
basePath: `api/agent/flow/${flowId}/${sessionId}`,
|
|
163
139
|
agent: flowId,
|
|
164
140
|
name: sessionId,
|
|
@@ -168,38 +144,36 @@ const { send, sendAuth, clearHistory } = useAgent({
|
|
|
168
144
|
const messages = useAgentStore((s) => s.messages);
|
|
169
145
|
```
|
|
170
146
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
Start-node flags (`allow_images`, `allow_documents`, `memory_enabled`) are read from the canvas nodes to drive the Run UI.
|
|
147
|
+
Start-node flags (`allow_images`, `allow_documents`, `memory_enabled`) can be read from flow config (`flowConfig` in the store) or from your design metadata to drive the UI.
|
|
174
148
|
|
|
175
149
|
### Pattern 3 — multiple agents on one screen (`storeKey`)
|
|
176
150
|
|
|
177
|
-
When two agents mount together
|
|
151
|
+
When two agents mount together, pass a stable `storeKey` so their chat state does not collide:
|
|
178
152
|
|
|
179
153
|
```tsx
|
|
180
154
|
const { send, sendAuth, store } = useAgent({
|
|
181
|
-
host:
|
|
182
|
-
basePath: `api/ora/connect/${
|
|
183
|
-
agent:
|
|
155
|
+
host: AGENT_SERVER_HOST,
|
|
156
|
+
basePath: `api/ora/connect/${FLOW_ID}/${sessionId}`,
|
|
157
|
+
agent: FLOW_ID,
|
|
184
158
|
name: sessionId,
|
|
185
|
-
query: { authorization:
|
|
159
|
+
query: { authorization: AGENT_API_KEY },
|
|
186
160
|
user: email ?? undefined,
|
|
187
|
-
storeKey: '
|
|
161
|
+
storeKey: 'my-panel', // stable for this component's lifetime
|
|
188
162
|
});
|
|
189
163
|
|
|
190
164
|
const messages = store((s) => s.messages);
|
|
191
165
|
const status = store((s) => s.status);
|
|
192
166
|
```
|
|
193
167
|
|
|
194
|
-
|
|
168
|
+
Child components that need the same isolated state must use the **same** `storeKey` via `getAgentStore('my-panel')`.
|
|
195
169
|
|
|
196
170
|
**Rule:** `storeKey` must be constant for the component lifetime (do not derive from per-render state).
|
|
197
171
|
|
|
198
|
-
|
|
172
|
+
### Runtime credentials (`sendAuth`)
|
|
199
173
|
|
|
200
174
|
Tools may reference `{{ auth.NAME }}` placeholders. Push credentials with `sendAuth(name, value)` — they never appear in chat history.
|
|
201
175
|
|
|
202
|
-
**Important:** re-push credentials **before every `send`**, not once on connect.
|
|
176
|
+
**Important:** re-push credentials **before every `send`**, not once on connect. Server-side session hibernation can clear in-memory auth mid-connection without disconnecting the WebSocket.
|
|
203
177
|
|
|
204
178
|
```ts
|
|
205
179
|
const sendTurn = async (text: string) => {
|
|
@@ -211,13 +185,13 @@ const sendTurn = async (text: string) => {
|
|
|
211
185
|
|
|
212
186
|
`clearHistory()` wipes server auth too — re-push after clearing.
|
|
213
187
|
|
|
214
|
-
|
|
188
|
+
### Store fields (reactive UI)
|
|
215
189
|
|
|
216
190
|
Subscribe via `useAgentStore` (global) or `store` (isolated):
|
|
217
191
|
|
|
218
192
|
| Field | Use |
|
|
219
193
|
|---|---|
|
|
220
|
-
| `messages` | Chat history (replayed
|
|
194
|
+
| `messages` | Chat history (replayed on connect via `HIS::`) |
|
|
221
195
|
| `typingMessage` | Streaming assistant text (`TS` / `TSC`) |
|
|
222
196
|
| `reasoningMessage` | Streaming reasoning (`RS` / `RSC`) |
|
|
223
197
|
| `status` | `'connecting' \| 'connected' \| 'disconnected'` — gate input on `'connected'` |
|
|
@@ -226,7 +200,7 @@ Subscribe via `useAgentStore` (global) or `store` (isolated):
|
|
|
226
200
|
| `composioAuth` | OAuth redirect when a connected tool requires manual authorization |
|
|
227
201
|
| `approvals` | Human-in-the-loop tool approvals |
|
|
228
202
|
|
|
229
|
-
|
|
203
|
+
### Wire protocol (summary)
|
|
230
204
|
|
|
231
205
|
Inbound frames use `TYPE::CONTENT`:
|
|
232
206
|
|
|
@@ -241,7 +215,64 @@ Inbound frames use `TYPE::CONTENT`:
|
|
|
241
215
|
|
|
242
216
|
Outbound: `M:` user message, `CH:` clear history, `AUT:` runtime credential, `UID:` session identity.
|
|
243
217
|
|
|
244
|
-
|
|
218
|
+
## Cloudflare Workers (optional — host the runtime)
|
|
219
|
+
|
|
220
|
+
Use this section only when **you** deploy the agent backend on Cloudflare Workers (e.g. a tenant Worker). Frontend-only integrations can skip it entirely.
|
|
221
|
+
|
|
222
|
+
### Exports (server)
|
|
223
|
+
|
|
224
|
+
| Import | Purpose |
|
|
225
|
+
|---|---|
|
|
226
|
+
| `@hugex/ai` | `handleAgentsRoutes`, `handleAuthRoutes`, `handleCommonRoutes`, `handleIntancesRoutes`, `AgentDO` |
|
|
227
|
+
|
|
228
|
+
### Worker setup
|
|
229
|
+
|
|
230
|
+
Chain the route handlers and re-export the Durable Object:
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
// workers/app.ts
|
|
234
|
+
import {
|
|
235
|
+
handleAgentsRoutes,
|
|
236
|
+
handleAuthRoutes,
|
|
237
|
+
handleCommonRoutes,
|
|
238
|
+
handleIntancesRoutes,
|
|
239
|
+
} from '@hugex/ai';
|
|
240
|
+
|
|
241
|
+
export default {
|
|
242
|
+
async fetch(request, env, ctx) {
|
|
243
|
+
const common = await handleCommonRoutes(request, env, ctx);
|
|
244
|
+
if (common instanceof Response) return common;
|
|
245
|
+
|
|
246
|
+
const auth = await handleAuthRoutes(request, env, ctx);
|
|
247
|
+
if (auth instanceof Response) return auth;
|
|
248
|
+
|
|
249
|
+
const agent = await handleAgentsRoutes(request, env, ctx);
|
|
250
|
+
if (agent instanceof Response) return agent;
|
|
251
|
+
|
|
252
|
+
const instances = await handleIntancesRoutes(request, env, ctx);
|
|
253
|
+
if (instances instanceof Response) return instances;
|
|
254
|
+
|
|
255
|
+
return yourAppHandler(request, { cloudflare: { env, ctx }, state: { ...auth } });
|
|
256
|
+
},
|
|
257
|
+
} satisfies ExportedHandler<Env>;
|
|
258
|
+
|
|
259
|
+
export { AgentDO } from '@hugex/ai';
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
`wrangler.jsonc` must bind the Durable Object:
|
|
263
|
+
|
|
264
|
+
```jsonc
|
|
265
|
+
{
|
|
266
|
+
"durable_objects": {
|
|
267
|
+
"bindings": [{ "class_name": "AgentDO", "name": "AGENT" }]
|
|
268
|
+
},
|
|
269
|
+
"migrations": [{ "tag": "v2", "new_sqlite_classes": ["AgentDO"] }]
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Required env vars (typical): `HX_CORE_URL`, `HX_ORA_URL`, `HX_API_KEY`, tenant Vectorize binding `VDB_<tenant>_1024`, `AI` (Workers AI).
|
|
274
|
+
|
|
275
|
+
Session memory, secrets (`{{ secrets.NAME }}`), Vectorize memo, and tool execution run inside `AgentDO`; shared data is fetched from HX Core / hx-ora APIs.
|
|
245
276
|
|
|
246
277
|
## Bundler
|
|
247
278
|
|
|
@@ -253,6 +284,21 @@ optimizeDeps: {
|
|
|
253
284
|
},
|
|
254
285
|
```
|
|
255
286
|
|
|
287
|
+
## Architecture (high level)
|
|
288
|
+
|
|
289
|
+
```
|
|
290
|
+
Agent Design ──save──► HX Core (flow state + KV metadata)
|
|
291
|
+
▲
|
|
292
|
+
Agent backend (optional) ──fetch──┘
|
|
293
|
+
WebSocket routes → session runtime (per flowId::sessionId)
|
|
294
|
+
FlowEngine runs Start → … → Answer
|
|
295
|
+
|
|
296
|
+
React app (useAgent) ◄──WebSocket TYPE::CONTENT──► Agent backend
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
- **Frontend:** any React host — imports `@hugex/ai/client`, connects via WebSocket.
|
|
300
|
+
- **Backend:** Cloudflare Worker with `@hugex/ai` server exports — only when you host the runtime.
|
|
301
|
+
|
|
256
302
|
## Release (maintainers)
|
|
257
303
|
|
|
258
304
|
From the `ora/` source repo:
|
|
@@ -263,20 +309,6 @@ task publish:ai -- --dry-run # build + npm pack only
|
|
|
263
309
|
task build:ai # build to ../ai without publish
|
|
264
310
|
```
|
|
265
311
|
|
|
266
|
-
## Architecture (high level)
|
|
267
|
-
|
|
268
|
-
```
|
|
269
|
-
hx-ai Agent Design ──save──► HX Core (flow state + KV metadata)
|
|
270
|
-
▲
|
|
271
|
-
Tenant Worker (@hugex/ai) ──fetch──┘
|
|
272
|
-
├ handleAgentsRoutes → WebSocket → AgentDO (per flowId::sessionId)
|
|
273
|
-
└ FlowEngine runs Start → … → Answer
|
|
274
|
-
|
|
275
|
-
Client (useAgent) ◄──WebSocket TYPE::CONTENT──► AgentDO
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
Session memory, secrets (`{{ secrets.NAME }}`), Vectorize memo, and tool execution run inside the DO; shared data is fetched from HX Core / hx-ora APIs.
|
|
279
|
-
|
|
280
312
|
## License
|
|
281
313
|
|
|
282
314
|
Included with your HugeX deployment — install and use this package as documented in this README. Full terms are in the `LICENSE` file included in this npm package (also listed under **License** on this page).
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as it,b as Pt,c as Jt,d as Xt}from"./chunk-26SLPOG6.js";import{a as Wt}from"./chunk-GOWQA2OT.js";import{a as fo,b as at,c as uo,d as G,e as wt,f as Gt,g as Bt,h as
|
|
1
|
+
import{a as it,b as Pt,c as Jt,d as Xt}from"./chunk-26SLPOG6.js";import{a as Wt}from"./chunk-GOWQA2OT.js";import{a as fo,b as at,c as uo,d as G,e as wt,f as Gt,g as Bt,h as Et,i as Qt,j as rt,k as xt,l as Zt}from"./chunk-57TCP6J4.js";import{a as zt,b as Yt}from"./chunk-4FUIFBZO.js";import{a as b,b as et,c as Ge,d as ot,e as bt,f as qt,g as mo,h as yo}from"./chunk-HAYNUZZB.js";import{a as Y,b as Be,c as Ee,d as st,e as nt,f as Dt}from"./chunk-OYP6D5VN.js";import{a as Qe,b as Ze,c as Se,d as ve,e as to,f as eo,g as Ut,h as oo,i as Lt,j as so,k as no,l as io,m as ao,n as ro,o as lo,p as co,q as po,r as jt,s as Ht,t as Vt}from"./chunk-GRZ6ZRHM.js";import{a as qe}from"./chunk-43NDF544.js";import{a as Je}from"./chunk-2JN3IX2Y.js";import{a as We}from"./chunk-6HY7QUMP.js";import{a as Ke,b as Xe}from"./chunk-V6JSMX5A.js";import{a as z,b as tt,c as ze,d as Mt,e as Ye}from"./chunk-TUI5H3ZB.js";import{a as v}from"./chunk-U56YWPSI.js";import{a as Kt}from"./chunk-YHXUBVN2.js";import{a as S}from"./chunk-6BYZCJPP.js";import{Agent as Pe}from"agents";import{nanoid as Ue}from"nanoid";async function St(o,e){return o.length?!e||!e.HX_ORA_URL||!e.HX_API_KEY?(console.error("extractDocuments: missing HX_ORA_URL or HX_API_KEY"),o.map(t=>({name:t.name,text:""}))):await Promise.all(o.map(async t=>{try{let n=await fetch(`${e.HX_ORA_URL}/internal/files/extract`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:e.HX_API_KEY},body:JSON.stringify(t)});if(!n.ok)return console.error(`extractDocuments: ${t.name} failed ${n.status}`),{name:t.name,text:""};let l=await n.json();return{name:t.name,text:l.text||""}}catch(n){return console.error(`extractDocuments: ${t.name} threw`,n),{name:t.name,text:""}}})):[]}async function Rt(o,e,s,t,n,l,m){var c,d,f;t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"start"}});try{let r=await((c=o.getMessages)==null?void 0:c.call(o))??[],{flowId:p,chatId:a,tenant:u}=s.flowData,i=((d=r[r.length-1])==null?void 0:d.type)==="text"?r[r.length-1].content:"NO-TEXT";m==null||m({type:"answer_node",payload:{userMessage:(f=s==null?void 0:s.context)==null?void 0:f.user_input,answer:i}})}catch(r){console.error("answerNodeRunner: failed to emit answer telemetry:",r),t==null||t({type:"debug",content:"Warning: failed to emit answer telemetry"}),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"error",error:String(r)}})}n==null||n(e.id,{type:"answerNode",message:"Answer response for: "+e.data.response,saved:!0}),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"success"}})}function K(o,e,s,t,n){var c,d,f;let l=(n==null?void 0:n.callerTag)??"llmNodeRunner",m=(n==null?void 0:n.serializeNonStrings)??!1;try{return Dt(o,e,{context:s.context??{},results:s.results??{},nodes:((d=(c=s.flowData)==null?void 0:c.state)==null?void 0:d.nodes)??[],secrets:(f=n==null?void 0:n.sessionEnv)==null?void 0:f.secrets},{callerTag:l,serializeNonStrings:m,onError:r=>{t==null||t({type:`error:${l}`,content:r})}})}catch(r){return console.error(r),"error"}}var vt="[redacted]",Nt=(o,e,s,t,n)=>K(o,e,s,n,{callerTag:"apiNodeRunner",serializeNonStrings:!0,sessionEnv:t});async function Ct(o,e,s,t,n,l,m){var f,r,p,a,u,i;`${e.id}`,t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"start"}});let c=null,d=Date.now();try{console.log("[apiNodeRunner] context keys:",Object.keys(s.context||{})),console.log("[apiNodeRunner] results keys:",Object.keys(s.results||{}));let g=((f=e.data)==null?void 0:f.url)||"",h=Nt(g,e,s,o,t);if(console.log("[apiNodeRunner] resolved url:",it(g)?Pt(h):h),!h){t==null||t({type:"error:apiNodeRunner",content:"Missing url"}),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"error",error:"Missing url"}}),n==null||n(e.id,c);return}let w=(((r=e.data)==null?void 0:r.method)||"GET").toUpperCase();console.log("[apiNodeRunner] method:",w);let y=((p=e.data)==null?void 0:p.headers)||{},x={},C={};for(let M in y)if(Object.prototype.hasOwnProperty.call(y,M)){let q=String(y[M]??"");C[M]=it(q),x[M]=Nt(q,e,s,o,t)}let N,$=!1;if(w!=="GET"&&w!=="HEAD"&&((a=e.data)==null?void 0:a.body)!==void 0){let M=typeof e.data.body=="string"?e.data.body:JSON.stringify(e.data.body);$=it(M),N=Nt(M,e,s,o,t),!x["Content-Type"]&&!x["content-type"]&&(x["Content-Type"]="application/json")}let R={};for(let M in x)R[M]=C[M]?vt:x[M];console.log("[apiNodeRunner] headers:",JSON.stringify(R)),console.log("[apiNodeRunner] body:",$?vt:N),t==null||t({type:"info:apiNodeRunner",content:`${w} ${h}`});let k=Number((u=e.data)==null?void 0:u.timeoutMs),D=new AbortController,A=Number.isFinite(k)&&k>0?setTimeout(()=>D.abort(),k):null,F;try{console.log("[apiNodeRunner] fetching..."),F=await fetch(h,{method:w,headers:x,body:N,signal:D.signal}),console.log("[apiNodeRunner] fetch returned status:",F.status)}finally{A&&clearTimeout(A)}let j=F.headers.get("content-type")||"";console.log("[apiNodeRunner] content-type:",j);let T;j.includes("application/json")?T=await F.json():T=await F.text(),console.log("[apiNodeRunner] payload preview:",typeof T=="string"?T.slice(0,200):JSON.stringify(T).slice(0,200)),c={ok:F.ok,status:F.status,data:T};let U=Date.now()-d;m==null||m({type:"api_call",payload:{nodeId:e.id,url:h,method:w,status:F.status,latencyMs:U}}),t==null||t({type:"info:apiNodeRunner",content:`Response ${F.status} (${U}ms)`}),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"success"}})}catch(g){console.error("Error processing ApiNode:",g),t==null||t({type:"error:apiNodeRunner",content:`API node execution failed: ${g}`}),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"error",error:String(g)}})}finally{console.log("[apiNodeRunner] final result:",(i=JSON.stringify(c))==null?void 0:i.slice(0,300)),n==null||n(e.id,c)}}import{generateObject as he}from"ai";import{z as te}from"zod";async function Tt(o,e,s,t,n,l,m){var g,h,w;t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"start"}});let c=(s==null?void 0:s.context)??{},d=String(((g=e==null?void 0:e.data)==null?void 0:g.input_variable)||"user_input").trim(),f=(c==null?void 0:c[d])??"",r=Array.isArray((h=e==null?void 0:e.data)==null?void 0:h.items)?e.data.items:[];if(r.length===0){t==null||t({type:"error:classifier",content:"ClassifierNode has no items to classify."});return}let p=String((w=r[r.length-1])==null?void 0:w.id);if(!f||String(f).trim().length===0){t==null||t({type:"warning:classifier",content:"No input for classification \u2014 falling back to last item."}),n==null||n(e.id,{classification:p}),s.context=s.context||{},s.context.classified_id=p,l==null||l(s);return}let u=`You are a precise classifier. Given a short user message, identify the category that best matches from the provided list.
|
|
2
2
|
If the message is ambiguous or none clearly matches, choose the LAST category in the list.
|
|
3
3
|
|
|
4
4
|
Categories:
|
|
@@ -9,16 +9,16 @@ ${r.map(y=>{let x=y.keywords??y["keywords/topics"]??"",C=Array.isArray(x)?x.join
|
|
|
9
9
|
`,i=`User message:
|
|
10
10
|
"""${String(f).trim()}"""
|
|
11
11
|
|
|
12
|
-
Select the best matching category id.`;try{let y=Date.now(),x=r.map(F=>String(F.id)),C="gpt_4_1_mini",N=await at(C,o);if(!N)throw new Error(`Model '${C}' not found in registry`);let{modelHandle
|
|
12
|
+
Select the best matching category id.`;try{let y=Date.now(),x=r.map(F=>String(F.id)),C="gpt_4_1_mini",N=await at(C,o);if(!N)throw new Error(`Model '${C}' not found in registry`);let{modelHandle:$,effectiveParams:R}=N,k=await he({model:$,messages:[{role:"system",content:u},{role:"user",content:i}],schema:te.object({classification:te.enum(x).describe("The id of the best matching category")}),temperature:R.temperature??0}),D=Date.now()-y,A=k.object.classification;m==null||m({type:"class_telemetry",payload:{nodeId:e.id,totalLatency:D,model:k.response.modelId,usage:k.usage,options:x}}),m==null||m({type:"class_result",payload:{result:k}}),n==null||n(e.id,{classification:A}),s.context=s.context||{},s.context.classified_id=A,l==null||l(s),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"success"}})}catch(y){t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"error",error:String(y)}})}}import{stepCountIs as Re,streamText as Ne}from"ai";import{nanoid as Ce}from"nanoid";import"zod";var P=(o,e,s)=>{o.send(e+"::"+s)};function ee(o,e){var t,n,l,m,c,d;let s="";if((t=o.data)!=null&&t.varMapping&&Array.isArray(o.data.varMapping))for(let f of o.data.varMapping){let r=f.from;if(!r)continue;let p=!1;if(r==="files"||r==="file_content")p=!0;else{let a=r.indexOf(".");if(a!==-1){let u=r.substring(0,a),i=r.substring(a+1).split(".")[0],g=(m=(l=(n=e.flowData)==null?void 0:n.state)==null?void 0:l.nodes)==null?void 0:m.find(h=>h.id===u);if(g){let w=st(g).find(y=>y.name===i);(w==null?void 0:w.type)==="file"&&(p=!0)}}}if(p){let a=nt(r,{context:e.context||{},results:e.results||{},nodes:((d=(c=e.flowData)==null?void 0:c.state)==null?void 0:d.nodes)||[]});typeof a=="string"&&a.trim()&&(s+=(s?`
|
|
13
13
|
|
|
14
|
-
`:"")+a)}}return s}function oe(o,e){var t,n,l,m,c,d;let s=[];if((t=o.data)!=null&&t.varMapping&&Array.isArray(o.data.varMapping))for(let f of o.data.varMapping){let r=f.from;if(!r)continue;let p=!1;if(r==="images")p=!0;else{let a=r.indexOf(".");if(a!==-1){let u=r.substring(0,a),i=r.substring(a+1).split(".")[0],g=(m=(l=(n=e.flowData)==null?void 0:n.state)==null?void 0:l.nodes)==null?void 0:m.find(h=>h.id===u);if(g){let w=st(g).find(y=>y.name===i);(w==null?void 0:w.type)==="image"&&(p=!0)}}}if(p){let a=nt(r,{context:e.context||{},results:e.results||{},nodes:((d=(c=e.flowData)==null?void 0:c.state)==null?void 0:d.nodes)||[]});Array.isArray(a)&&s.push(...a)}}return s}var we=S({"../tools/composioTool.ts":()=>import("./composioTool-EXCSM6F4.js"),"../tools/convertTempMessure.ts":()=>import("./convertTempMessure-TT7DIP6C.js"),"../tools/httpTool.ts":()=>import("./httpTool-EU63HPF5.js"),"../tools/recall.ts":()=>import("./recall-SD6FENAS.js"),"../tools/skillTool.test.ts":()=>import("./skillTool.test-6UDHQARG.js"),"../tools/skillTool.ts":()=>import("./skillTool-Y5GZ4ZAR.js"),"../tools/tempTool.ts":()=>import("./tempTool-6Q6C4HEJ.js"),"../tools/twitter.ts":()=>import("./twitter-QNCTAE4E.js"),"../tools/vectorize.ts":()=>import("./vectorize-SQROWLSU.js")});var xe=S({});function It(o,e,s,t,n){var m;if(!((m=t.memoryConfig)!=null&&m.enabled)||!t.memoryConfig.toolCache||!s.cacheable||!e||typeof e.execute!="function")return e;let l=e.execute.bind(e);return e.execute=async(c,...d)=>{var a;if(!t.getContextIndex)return l(c,...d);let f=await wt(c),p=(await t.getContextIndex()).find(u=>{if(u.domain!=="tool")return!1;let i=xt(u.meta);return i.toolName===o&&i.paramsHash===f});if(p){let u=await((a=t.getContext)==null?void 0:a.call(t,p.ref));if((u==null?void 0:u.data)!=null&&xt(u.meta).truncated!==!0){n==null||n({type:"info:memory:cacheHit",content:{ref:u.ref,toolName:o}});try{return JSON.parse(u.data)}catch{return u.data}}}return l(c,...d)},e}async function Te(o,e,s,t){var r,p;if(!((r=s.memoryConfig)!=null&&r.enabled)||!s.setContext||s.cycle==null)return;let n=o.toolCalls??[],l=o.toolResults??[];if(!n.length||!l.length)return;let m=new Map;for(let a of l)a!=null&&a.toolCallId&&m.set(a.toolCallId,a);let c=Array.isArray((p=e==null?void 0:e.data)==null?void 0:p.tools)?e.data.tools:[],d=new Map;for(let a of c)a&&typeof a.id=="string"&&d.set(a.id,a);let f=new Map;for(let a of Object.values(s.toolDefs??{}))a&&a.name&&f.set(a.name,a);for(let a of n){let u=a.toolCallId,i=a.toolName,g=m.get(u);if(!i||!g||i==="readSkillRef")continue;let h=a.args??a.input,w=g.result??g.output,y=!1,x="",C="tool",N="",_=f.get(i);_&&_.kind==="skill"&&(y=!0,x=`skill:${i}`,C="skill",N=`Skill instructions for ${i}`),x||(x=await Bt(i,h),N=Gt(h,w));let R=d.get(i)??c.find(A=>A.id===i),k=await wt(h),b=typeof w=="string"?w:JSON.stringify(w??null);await s.setContext({ref:x,domain:C,description:N,data:b,cycle:s.cycle,meta:JSON.stringify({toolName:i,paramsHash:k,cacheable:(R==null?void 0:R.cacheable)===!0})}),t==null||t({type:"info:memory:updated",content:{ref:x}})}}async function Ie(o,e,s,t){var p;let n=Array.isArray((p=s==null?void 0:s.data)==null?void 0:p.tools)?s.data.tools:[];if(n.length===0)return{};let l={},m=a=>{var x,C;let u=typeof(a==null?void 0:a.description)=="string"?a.description:"",i=a==null?void 0:a.inputSchema,g;try{let N=(i==null?void 0:i.shape)??(typeof((x=i==null?void 0:i._def)==null?void 0:x.shape)=="function"?i._def.shape():(C=i==null?void 0:i._def)==null?void 0:C.shape);N&&typeof N=="object"&&(g=N)}catch{}let h=g?Object.keys(g):[],w=u?`description="${u.length>120?u.slice(0,120)+"\u2026":u}"`:"description=(none)",y=h.length?`inputSchema={${h.join(", ")}}`:"inputSchema=(none)";return`${w} ${y}`},c=(()=>{let a=[],u=[],i=[],g=[];for(let w=0;w<n.length;w++){let y=n[w];!y||typeof y!="object"||typeof y.id!="string"?g.push(w):y.kind==="builtin"?a.push(y.id):y.kind==="skill"?i.push(y.id):y.kind==="http"||y.kind==="mcp"||y.kind==="composio"?u.push(y.id):g.push(w)}let h=[];return a.length&&h.push(`builtin[${a.join(", ")}]`),u.length&&h.push(`custom[${u.join(", ")}]`),i.length&&h.push(`skill[${i.join(", ")}]`),g.length&&h.push(`invalid@[${g.join(", ")}]`),h.join(" ")||"(none)"})();console.log(`[tools] node ${s.id} requested (${n.length}): ${c}`);let d=!1,f=async()=>{if(d&&o.toolDefs)return o.toolDefs;if(!o.env)return o.toolDefs=o.toolDefs||{},d=!0,o.toolDefs;try{let a=await Kt(o.env),u={};for(let i of a)i&&i.id&&(u[i.id]=i);o.toolDefs=u}catch(a){t==null||t({type:"error:llmNodeRunner",content:`Failed to load custom tool defs: ${String(a)}`}),o.toolDefs=o.toolDefs||{}}return d=!0,o.toolDefs},r=[];for(let a=0;a<n.length;a++){let u=n[a];if(!u||typeof u!="object"||typeof u.id!="string"||u.kind!=="builtin"&&u.kind!=="http"&&u.kind!=="mcp"&&u.kind!=="composio"&&u.kind!=="skill"){t==null||t({type:"error:llmNodeRunner",content:`Invalid tool descriptor at index ${a}: expected { kind: 'http'|'mcp'|'composio'|'builtin'|'skill', id: string, params?: any }`});continue}let i=u;if(i.kind!=="builtin"){let h=(await f())[i.id];if(!h){console.error(`[tools] \u2717 custom '${i.id}': not found for tenant`),t==null||t({type:"error:llmNodeRunner",content:`custom tool '${i.id}' not found for this tenant`});continue}if(i.kind==="composio"){try{let y=await Wt(h,o,e,t),x=Object.keys(y);for(let[C,N]of Object.entries(y))l[C]=It(C,N,i,o,t);console.log(`[tools] \u2713 composio '${i.id}' \u2192 ${x.length} tool(s)`)}catch(y){console.error(`[tools] \u2717 composio '${i.id}': ${String(y)}`),t==null||t({type:"error:llmNodeRunner",content:`Error loading composio tool '${i.id}': ${String(y)}`})}continue}if(i.kind==="skill"){if(h.kind!=="skill"){console.error(`[tools] \u2717 skill '${i.id}': row is of kind '${h.kind}', not 'skill'`),t==null||t({type:"error:llmNodeRunner",content:`tool '${i.id}' is not a skill`});continue}let y=h.name;if(l[y]){t==null||t({type:"warn:llmNodeRunner",content:`tool name collision on '${y}' \u2014 builtin/other already registered, skipping skill '${i.id}'`});continue}try{l[y]=zt(h,o,e,t),r.push(h);let x=typeof h.execution=="string"?JSON.parse(h.execution):h.execution||{},C=Array.isArray(x.references)?x.references.map(N=>N==null?void 0:N.name):[];console.log(`[tools] \u2713 skill '${i.id}' \u2192 '${y}' (refs: ${C.join(", ")||"none"})`),t==null||t({type:"info:skill:registered",content:{skill:y,refCount:C.length,refs:C}})}catch(x){console.error(`[tools] \u2717 skill '${i.id}': ${String(x)}`),t==null||t({type:"error:llmNodeRunner",content:`Error loading skill tool '${i.id}': ${String(x)}`})}continue}let w=h.name;if(l[w]){t==null||t({type:"warn:llmNodeRunner",content:`tool name collision on '${w}' \u2014 builtin already registered, skipping custom tool '${i.id}'`});continue}try{let y=Xt(h,o,e,t);l[w]=It(w,y,i,o,t),console.log(`[tools] \u2713 custom '${i.id}' \u2192 '${w}'`),console.log(`[tools] ${m(l[w])}`)}catch(y){console.error(`[tools] \u2717 custom '${i.id}': ${String(y)}`),t==null||t({type:"error:llmNodeRunner",content:`Error loading custom tool '${i.id}': ${String(y)}`})}continue}if(!Vt[i.id]){console.error(`[tools] \u2717 builtin '${i.id}': not in registry`),t==null||t({type:"error:llmNodeRunner",content:`Tool '${i.id}' not found in registry`});continue}try{let g;try{g=await we(`../tools/${i.id}.ts`)}catch{g=await xe(`../tools/${i.id}.js`)}let h;if(g[i.id])h=g[i.id];else if(g.default)h=g.default;else if(g.create)h=g.create;else{let R=Object.values(g);R.length>0&&(h=R[0])}if(!h){t==null||t({type:"error:llmNodeRunner",content:`No factory export found for tool '${i.id}'`});continue}let w,y,x={};if(i.params&&typeof i.params=="object"){if(typeof i.params.description=="string"?w=i.params.description:i.params.description!==void 0&&(t==null||t({type:"error:llmNodeRunner",content:`Invalid description for tool '${i.id}' \u2014 must be a string`})),i.params.inputSchema!==void 0){let R=i.params.inputSchema;typeof R=="object"&&(typeof R.safeParse=="function"||R._def)?y=R:typeof R=="object"&&R!==null&&R.type==="object"&&R.properties?(y=Jt(R),y||t==null||t({type:"error:llmNodeRunner",content:`Invalid inputSchema for tool '${i.id}' \u2014 must be a Zod schema or JSON Schema object`})):t==null||t({type:"error:llmNodeRunner",content:`Invalid inputSchema for tool '${i.id}' \u2014 must be a Zod schema or JSON Schema object`})}i.params.defaults!==void 0?typeof i.params.defaults=="object"&&i.params.defaults!==null&&!Array.isArray(i.params.defaults)?x=i.params.defaults:(t==null||t({type:"error:llmNodeRunner",content:`Invalid defaults for tool '${i.id}' \u2014 must be an object`}),x={}):i.params.source!==void 0||i.params.target!==void 0?(t==null||t({type:"error:llmNodeRunner",content:`Invalid params for tool '${i.id}' \u2014 legacy top-level source/target not supported; use params.defaults instead`}),x={}):x={}}let C=h(o,e,x,t);w&&C&&typeof C=="object"&&(C.description=w),y&&C&&typeof C=="object"&&(C.inputSchema=y),l[i.id]=It(i.id,C,i,o,t);let N=[];w&&N.push("description"),y&&N.push("inputSchema"),Object.keys(x).length&&N.push(`defaults(${Object.keys(x).join(",")})`);let _=N.length?` [overrides: ${N.join(", ")}]`:"";console.log(`[tools] \u2713 builtin '${i.id}'${_}`),console.log(`[tools] ${m(C)}`)}catch(g){console.error(`[tools] \u2717 builtin '${i.id}': ${String(g)}`),t==null||t({type:"error:llmNodeRunner",content:`Error loading tool '${i.id}': ${String(g)}`});continue}}if(r.length>0)if(l.readSkillRef)t==null||t({type:"warn:llmNodeRunner",content:"tool name collision on 'readSkillRef' \u2014 builtin/other already registered, skipping readSkillRef tool"});else try{l.readSkillRef=Yt(o,r,e,t),console.log(`[tools] \u2713 registered readSkillRef tool for ${r.length} skill(s)`),t==null||t({type:"info:skill:readSkillRefRegistered",content:{skills:r.map(a=>a.name)}})}catch(a){console.error(`[tools] \u2717 failed to load readSkillRef tool: ${String(a)}`)}return l}async function Ot(o,e,s,t,n,l,m){var k,b,A,F,j;`${e.id}`,t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"start"}});let c=!1;try{let T=(k=s.flowData)==null?void 0:k.state;if(T&&T.edges&&T.nodes){let P=T.edges.filter(M=>M.source===e.id);if(P.length>0){let M=T.nodes.find(V=>V.id===P[0].target);M&&M.type==="answerNode"&&(c=!0)}}}catch(T){console.error("Error determining next node for streaming:",T)}let d=K(e.data.template,e,s,t,{sessionEnv:o});(!d||!d.trim())&&(d="Answer straight forward to the user, dont offer any other option to continue");let f=d,r="";if((b=o.memoryConfig)!=null&&b.enabled){let T=await((A=o.getContextIndex)==null?void 0:A.call(o))??[];r=Et(T),d+=r}let p=K(e.data.user_template||"",e,s,t,{sessionEnv:o}),a=T=>T&&Object.fromEntries(Object.keys(T).map(P=>[P,"[redacted]"])),u=o!=null&&o.secrets||o!=null&&o.userAuth?{...o,secrets:a(o.secrets),userAuth:a(o.userAuth)}:o,i=K(e.data.template,e,s,void 0,{sessionEnv:u})||f;i+=r;let g=K(e.data.user_template||"",e,s,void 0,{sessionEnv:u});t==null||t({type:`info:llmNodeRunner:${e.id}`,content:i}),t==null||t({type:`info:llmNodeRunner:${e.id}`,content:g});let h=(F=e==null?void 0:e.data)==null?void 0:F.window_size,w=Number(h);(!Number.isInteger(w)||w<=0)&&(w=5);let y=oe(e,s),x=ee(e,s),N=(await((j=o.getMessages)==null?void 0:j.call(o))??[]).slice(-w),_=N.filter(T=>T&&typeof T.role=="string"&&typeof T.content=="string");_.length!==N.length&&console.warn(`Filtered ${N.length-_.length} invalid messages from history`);let R=_e(_,p,y,x);await Oe(d,R,o.conn,t,e,c,n,s,l,o,m)}async function Oe(o,e,s,t,n,l,m,c,d,f,r){var a;let p=Date.now();if(!((a=f.env)!=null&&a.AI))throw new Error("AI binding is required for LLM node");return new Promise(async(u,i)=>{var j,T,P,M,V,B,Q;let g,h={},w,y="none",x=!1,C,N=!1,_=!1,R=0,k=0,b=(j=n==null?void 0:n.data)==null?void 0:j.sendReasoning,A=b!==!1;try{let L=(T=n==null?void 0:n.data)==null?void 0:T.model,W=Array.isArray(L)?L[0]:L||"gpt_5_nano",I=Ut(n==null?void 0:n.data),$=await at(W,f,I);if(!$)throw new Error(`Model '${W}' not found in registry`);g=$.modelHandle,h=$.effectiveParams||{},y=$.reasoning.kind;let O=Ht($.reasoning,(P=n==null?void 0:n.data)==null?void 0:P.reasoningEffort);x=A&&jt($.reasoning);let q=typeof((M=n==null?void 0:n.data)==null?void 0:M.reasoningMaxTokens)=="number"?n.data.reasoningMaxTokens:void 0;w=qt($.provider,{effort:O,exposeReasoning:x,maxTokens:q}),O&&(t==null||t({type:"info:llmNodeRunner:reasoningEffort",content:O})),console.log(`[reasoning] ${JSON.stringify({model:W,provider:$.provider,capability:$.reasoning,requestedEffort:((V=n==null?void 0:n.data)==null?void 0:V.reasoningEffort)??null,resolvedEffort:O??null,sendReasoning:A,exposeReasoning:x,providerOptions:w??null},null,2)}`);for(let H of $.paramAdjustments??[])t==null||t({type:"warn:llmNodeRunner",content:H});t==null||t({type:"info:llmNodeRunner:model",content:W}),t==null||t({type:"info:llmNodeRunner:generationParams",content:{...(B=n==null?void 0:n.data)!=null&&B.generationPreset?{preset:n.data.generationPreset}:{},...h,...y!=="none"?{reasoning:y,configuredSendReasoning:b,sendReasoning:A,exposeReasoning:x,...O?{effort:O}:{}}:{}}})}catch(L){throw t==null||t({type:"error:llmNodeRunner",content:`Model error: ${String(L)}`}),L}let F=await Ie(f,c,n,t);if((Q=f.memoryConfig)!=null&&Q.enabled){let{recall:L}=await import("./recall-SD6FENAS.js");F.recall=L(f,c,void 0,t)}console.log(`[tools] node ${n.id} loaded ${Object.keys(F).length}: ${Object.keys(F).join(", ")||"(none)"}`),t==null||t({type:"info:llmNodeRunner:toolsLoaded",content:{nodeId:n.id,tools:Object.keys(F)}});try{let L=Ne({model:g,system:o,messages:e,stopWhen:(()=>{var H;let $=!!F.readSkillRef?10:5,O=Number(((H=n.data)==null?void 0:H.max_steps)??$),q=Number.isFinite(O)?Math.max(1,Math.min(30,O)):$;return Re(q)})(),...Lt(h),...w?{providerOptions:w}:{},tools:F,onFinish:async I=>{var At,Ft;let $=I.text||"",O=I.reasoningText??((At=I.reasoning)==null?void 0:At.text)??"";if(console.log(`[reasoning] done: deltas=${R} chars=${k} result.reasoningText=${O.length} finishReason=${I.finishReason??"n/a"} reasoningTokens=${((Ft=I.usage)==null?void 0:Ft.reasoningTokens)??"n/a"}`),A&&x&&!N&&O&&s){N=!0;try{U(s,D.SERVER_REASONING_STREAM,O)}catch(ge){console.warn("Failed to send finished reasoning over connection",ge)}}let q={id:Ce(),role:"assistant",type:"text",content:$,ts:Date.now()};l&&(f.setMessages?await f.setMessages(q):t==null||t({type:"error:llmNodeRunner",content:"setMessages callback missing"})),s&&A&&N&&!_&&(_=!0,U(s,D.SERVER_REASONING_STREAM_COMPLETE,JSON.stringify({}))),l&&s&&U(s,D.SERVER_TEXT_STREAM_COMPLETE,JSON.stringify({})),m==null||m((n==null?void 0:n.id)||"llm_result",$),t==null||t({type:"info:llmNodeRunner:onFinish",content:JSON.stringify(I)});let H=Date.now()-p,ye=C?C-p:void 0;r==null||r({type:"llm_telemetry",payload:{nodeId:n.id,totalLatency:H,timeToFirstToken:ye,model:I.response.modelId,usage:I.usage}}),r==null||r({type:"llm_result",payload:{result:I}})},onStepFinish:async I=>{let $=(O,q=200)=>{let H=typeof O=="string"?O:JSON.stringify(O);return H?H.length>q?`${H.slice(0,q)}\u2026(+${H.length-q})`:H:""};if(I.toolCalls&&I.toolCalls.length>0){for(let O of I.toolCalls)console.log(`[tools] \u2192 ${O.toolName}(${$(O.args??O.input)})`);t==null||t({type:`info:llmNodeRunner:toolCalls:${n.id}`,content:JSON.stringify(I.toolCalls)})}if(I.toolResults&&I.toolResults.length>0){for(let O of I.toolResults)console.log(`[tools] \u2190 ${O.toolName} \u2192 ${$(O.result??O.output)}`);t==null||t({type:`info:llmNodeRunner:toolResults:${n.id}`,content:JSON.stringify(I.toolResults)})}await Te(I,n,f,t)},experimental_onToolCallStart:I=>{var $;t==null||t({type:"tool:execution",content:{nodeId:n.id,toolName:($=I==null?void 0:I.toolCall)==null?void 0:$.toolName,status:"start"}})},experimental_onToolCallFinish:I=>{var $;t==null||t({type:"tool:execution",content:{nodeId:n.id,toolName:($=I==null?void 0:I.toolCall)==null?void 0:$.toolName,status:I!=null&&I.success?"success":"error"}})},onError:I=>{t==null||t({type:"error:llmNodeRunner",content:"Execution error"}),i(I)},onChunk:I=>{if(I.chunk.type==="reasoning-delta"){let O=I.chunk.text??I.chunk.delta??"";if(O&&(N=!0,R+=1,k+=O.length,R===1&&console.log("[reasoning] \u2713 first reasoning-delta received")),A&&s&&O)try{U(s,D.SERVER_REASONING_STREAM,O)}catch(q){console.warn("Failed to send reasoning chunk over connection",q)}return}if(I.chunk.type==="text-delta"){if(C||(C=Date.now()),s&&A&&N&&!_){_=!0;try{U(s,D.SERVER_REASONING_STREAM_COMPLETE,JSON.stringify({}))}catch(O){console.warn("Failed to send reasoning complete over connection",O)}}return}r==null||r({type:I.chunk.type,payload:{nodeId:n.id,chunk:I.chunk}});let $=`llm_chunk:${I.chunk.type}`;t==null||t({type:$,content:{...I}})}}),W=async()=>{for await(let I of L.textStream)if(l&&s)try{U(s,D.SERVER_TEXT_STREAM,I)}catch($){console.warn("Failed to send chunk over connection",$)}};await Promise.all([L,W()]),u(),t==null||t({type:"node:execution",content:{nodeId:n.id,nodeType:n.type,status:"success"}})}catch(L){t==null||t({type:"node:execution",content:{nodeId:n.id,nodeType:n.type,status:"error",error:String(L)}}),i(L)}})}function _e(o,e,s,t){let n=!!(s&&s.length>0),l=!!t,m=n||l,d=o.length>0&&o[o.length-1].role==="user"?o[o.length-1]:void 0,f=r=>{let p=[],a="";if(l&&(a+=`[Attached files]
|
|
14
|
+
`:"")+a)}}return s}function oe(o,e){var t,n,l,m,c,d;let s=[];if((t=o.data)!=null&&t.varMapping&&Array.isArray(o.data.varMapping))for(let f of o.data.varMapping){let r=f.from;if(!r)continue;let p=!1;if(r==="images")p=!0;else{let a=r.indexOf(".");if(a!==-1){let u=r.substring(0,a),i=r.substring(a+1).split(".")[0],g=(m=(l=(n=e.flowData)==null?void 0:n.state)==null?void 0:l.nodes)==null?void 0:m.find(h=>h.id===u);if(g){let w=st(g).find(y=>y.name===i);(w==null?void 0:w.type)==="image"&&(p=!0)}}}if(p){let a=nt(r,{context:e.context||{},results:e.results||{},nodes:((d=(c=e.flowData)==null?void 0:c.state)==null?void 0:d.nodes)||[]});Array.isArray(a)&&s.push(...a)}}return s}var we=S({"../tools/composioTool.ts":()=>import("./composioTool-EXCSM6F4.js"),"../tools/convertTempMessure.ts":()=>import("./convertTempMessure-TT7DIP6C.js"),"../tools/httpTool.ts":()=>import("./httpTool-EU63HPF5.js"),"../tools/recall.ts":()=>import("./recall-SD6FENAS.js"),"../tools/skillTool.test.ts":()=>import("./skillTool.test-6UDHQARG.js"),"../tools/skillTool.ts":()=>import("./skillTool-Y5GZ4ZAR.js"),"../tools/tempTool.ts":()=>import("./tempTool-6Q6C4HEJ.js"),"../tools/twitter.ts":()=>import("./twitter-QNCTAE4E.js"),"../tools/vectorize.ts":()=>import("./vectorize-SQROWLSU.js")});var xe=S({});function It(o,e,s,t,n){var m;if(!((m=t.memoryConfig)!=null&&m.enabled)||!t.memoryConfig.toolCache||!s.cacheable||!e||typeof e.execute!="function")return e;let l=e.execute.bind(e);return e.execute=async(c,...d)=>{var a;if(!t.getContextIndex)return l(c,...d);let f=await wt(c),p=(await t.getContextIndex()).find(u=>{if(u.domain!=="tool")return!1;let i=xt(u.meta);return i.toolName===o&&i.paramsHash===f});if(p){let u=await((a=t.getContext)==null?void 0:a.call(t,p.ref));if((u==null?void 0:u.data)!=null&&xt(u.meta).truncated!==!0){n==null||n({type:"info:memory:cacheHit",content:{ref:u.ref,toolName:o}});try{return JSON.parse(u.data)}catch{return u.data}}}return l(c,...d)},e}async function Te(o,e,s,t){var r,p;if(!((r=s.memoryConfig)!=null&&r.enabled)||!s.setContext||s.cycle==null)return;let n=o.toolCalls??[],l=o.toolResults??[];if(!n.length||!l.length)return;let m=new Map;for(let a of l)a!=null&&a.toolCallId&&m.set(a.toolCallId,a);let c=Array.isArray((p=e==null?void 0:e.data)==null?void 0:p.tools)?e.data.tools:[],d=new Map;for(let a of c)a&&typeof a.id=="string"&&d.set(a.id,a);let f=new Map;for(let a of Object.values(s.toolDefs??{}))a&&a.name&&f.set(a.name,a);for(let a of n){let u=a.toolCallId,i=a.toolName,g=m.get(u);if(!i||!g||i==="readSkillRef")continue;let h=a.args??a.input,w=g.result??g.output,y=!1,x="",C="tool",N="",$=f.get(i);$&&$.kind==="skill"&&(y=!0,x=`skill:${i}`,C="skill",N=`Skill instructions for ${i}`),x||(x=await Bt(i,h),N=Gt(h,w));let R=d.get(i)??c.find(A=>A.id===i),k=await wt(h),D=typeof w=="string"?w:JSON.stringify(w??null);await s.setContext({ref:x,domain:C,description:N,data:D,cycle:s.cycle,meta:JSON.stringify({toolName:i,paramsHash:k,cacheable:(R==null?void 0:R.cacheable)===!0})}),t==null||t({type:"info:memory:updated",content:{ref:x}})}}async function Ie(o,e,s,t){var p;let n=Array.isArray((p=s==null?void 0:s.data)==null?void 0:p.tools)?s.data.tools:[];if(n.length===0)return{};let l={},m=a=>{var x,C;let u=typeof(a==null?void 0:a.description)=="string"?a.description:"",i=a==null?void 0:a.inputSchema,g;try{let N=(i==null?void 0:i.shape)??(typeof((x=i==null?void 0:i._def)==null?void 0:x.shape)=="function"?i._def.shape():(C=i==null?void 0:i._def)==null?void 0:C.shape);N&&typeof N=="object"&&(g=N)}catch{}let h=g?Object.keys(g):[],w=u?`description="${u.length>120?u.slice(0,120)+"\u2026":u}"`:"description=(none)",y=h.length?`inputSchema={${h.join(", ")}}`:"inputSchema=(none)";return`${w} ${y}`},c=(()=>{let a=[],u=[],i=[],g=[];for(let w=0;w<n.length;w++){let y=n[w];!y||typeof y!="object"||typeof y.id!="string"?g.push(w):y.kind==="builtin"?a.push(y.id):y.kind==="skill"?i.push(y.id):y.kind==="http"||y.kind==="mcp"||y.kind==="composio"?u.push(y.id):g.push(w)}let h=[];return a.length&&h.push(`builtin[${a.join(", ")}]`),u.length&&h.push(`custom[${u.join(", ")}]`),i.length&&h.push(`skill[${i.join(", ")}]`),g.length&&h.push(`invalid@[${g.join(", ")}]`),h.join(" ")||"(none)"})();console.log(`[tools] node ${s.id} requested (${n.length}): ${c}`);let d=!1,f=async()=>{if(d&&o.toolDefs)return o.toolDefs;if(!o.env)return o.toolDefs=o.toolDefs||{},d=!0,o.toolDefs;try{let a=await Kt(o.env),u={};for(let i of a)i&&i.id&&(u[i.id]=i);o.toolDefs=u}catch(a){t==null||t({type:"error:llmNodeRunner",content:`Failed to load custom tool defs: ${String(a)}`}),o.toolDefs=o.toolDefs||{}}return d=!0,o.toolDefs},r=[];for(let a=0;a<n.length;a++){let u=n[a];if(!u||typeof u!="object"||typeof u.id!="string"||u.kind!=="builtin"&&u.kind!=="http"&&u.kind!=="mcp"&&u.kind!=="composio"&&u.kind!=="skill"){t==null||t({type:"error:llmNodeRunner",content:`Invalid tool descriptor at index ${a}: expected { kind: 'http'|'mcp'|'composio'|'builtin'|'skill', id: string, params?: any }`});continue}let i=u;if(i.kind!=="builtin"){let h=(await f())[i.id];if(!h){console.error(`[tools] \u2717 custom '${i.id}': not found for tenant`),t==null||t({type:"error:llmNodeRunner",content:`custom tool '${i.id}' not found for this tenant`});continue}if(i.kind==="composio"){try{let y=await Wt(h,o,e,t),x=Object.keys(y);for(let[C,N]of Object.entries(y))l[C]=It(C,N,i,o,t);console.log(`[tools] \u2713 composio '${i.id}' \u2192 ${x.length} tool(s)`)}catch(y){console.error(`[tools] \u2717 composio '${i.id}': ${String(y)}`),t==null||t({type:"error:llmNodeRunner",content:`Error loading composio tool '${i.id}': ${String(y)}`})}continue}if(i.kind==="skill"){if(h.kind!=="skill"){console.error(`[tools] \u2717 skill '${i.id}': row is of kind '${h.kind}', not 'skill'`),t==null||t({type:"error:llmNodeRunner",content:`tool '${i.id}' is not a skill`});continue}let y=h.name;if(l[y]){t==null||t({type:"warn:llmNodeRunner",content:`tool name collision on '${y}' \u2014 builtin/other already registered, skipping skill '${i.id}'`});continue}try{l[y]=zt(h,o,e,t),r.push(h);let x=typeof h.execution=="string"?JSON.parse(h.execution):h.execution||{},C=Array.isArray(x.references)?x.references.map(N=>N==null?void 0:N.name):[];console.log(`[tools] \u2713 skill '${i.id}' \u2192 '${y}' (refs: ${C.join(", ")||"none"})`),t==null||t({type:"info:skill:registered",content:{skill:y,refCount:C.length,refs:C}})}catch(x){console.error(`[tools] \u2717 skill '${i.id}': ${String(x)}`),t==null||t({type:"error:llmNodeRunner",content:`Error loading skill tool '${i.id}': ${String(x)}`})}continue}let w=h.name;if(l[w]){t==null||t({type:"warn:llmNodeRunner",content:`tool name collision on '${w}' \u2014 builtin already registered, skipping custom tool '${i.id}'`});continue}try{let y=Xt(h,o,e,t);l[w]=It(w,y,i,o,t),console.log(`[tools] \u2713 custom '${i.id}' \u2192 '${w}'`),console.log(`[tools] ${m(l[w])}`)}catch(y){console.error(`[tools] \u2717 custom '${i.id}': ${String(y)}`),t==null||t({type:"error:llmNodeRunner",content:`Error loading custom tool '${i.id}': ${String(y)}`})}continue}if(!qt[i.id]){console.error(`[tools] \u2717 builtin '${i.id}': not in registry`),t==null||t({type:"error:llmNodeRunner",content:`Tool '${i.id}' not found in registry`});continue}try{let g;try{g=await we(`../tools/${i.id}.ts`)}catch{g=await xe(`../tools/${i.id}.js`)}let h;if(g[i.id])h=g[i.id];else if(g.default)h=g.default;else if(g.create)h=g.create;else{let R=Object.values(g);R.length>0&&(h=R[0])}if(!h){t==null||t({type:"error:llmNodeRunner",content:`No factory export found for tool '${i.id}'`});continue}let w,y,x={};if(i.params&&typeof i.params=="object"){if(typeof i.params.description=="string"?w=i.params.description:i.params.description!==void 0&&(t==null||t({type:"error:llmNodeRunner",content:`Invalid description for tool '${i.id}' \u2014 must be a string`})),i.params.inputSchema!==void 0){let R=i.params.inputSchema;typeof R=="object"&&(typeof R.safeParse=="function"||R._def)?y=R:typeof R=="object"&&R!==null&&R.type==="object"&&R.properties?(y=Jt(R),y||t==null||t({type:"error:llmNodeRunner",content:`Invalid inputSchema for tool '${i.id}' \u2014 must be a Zod schema or JSON Schema object`})):t==null||t({type:"error:llmNodeRunner",content:`Invalid inputSchema for tool '${i.id}' \u2014 must be a Zod schema or JSON Schema object`})}i.params.defaults!==void 0?typeof i.params.defaults=="object"&&i.params.defaults!==null&&!Array.isArray(i.params.defaults)?x=i.params.defaults:(t==null||t({type:"error:llmNodeRunner",content:`Invalid defaults for tool '${i.id}' \u2014 must be an object`}),x={}):i.params.source!==void 0||i.params.target!==void 0?(t==null||t({type:"error:llmNodeRunner",content:`Invalid params for tool '${i.id}' \u2014 legacy top-level source/target not supported; use params.defaults instead`}),x={}):x={}}let C=h(o,e,x,t);w&&C&&typeof C=="object"&&(C.description=w),y&&C&&typeof C=="object"&&(C.inputSchema=y),l[i.id]=It(i.id,C,i,o,t);let N=[];w&&N.push("description"),y&&N.push("inputSchema"),Object.keys(x).length&&N.push(`defaults(${Object.keys(x).join(",")})`);let $=N.length?` [overrides: ${N.join(", ")}]`:"";console.log(`[tools] \u2713 builtin '${i.id}'${$}`),console.log(`[tools] ${m(C)}`)}catch(g){console.error(`[tools] \u2717 builtin '${i.id}': ${String(g)}`),t==null||t({type:"error:llmNodeRunner",content:`Error loading tool '${i.id}': ${String(g)}`});continue}}if(r.length>0)if(l.readSkillRef)t==null||t({type:"warn:llmNodeRunner",content:"tool name collision on 'readSkillRef' \u2014 builtin/other already registered, skipping readSkillRef tool"});else try{l.readSkillRef=Yt(o,r,e,t),console.log(`[tools] \u2713 registered readSkillRef tool for ${r.length} skill(s)`),t==null||t({type:"info:skill:readSkillRefRegistered",content:{skills:r.map(a=>a.name)}})}catch(a){console.error(`[tools] \u2717 failed to load readSkillRef tool: ${String(a)}`)}return l}async function Ot(o,e,s,t,n,l,m){var k,D,A,F,j;`${e.id}`,t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"start"}});let c=!1;try{let T=(k=s.flowData)==null?void 0:k.state;if(T&&T.edges&&T.nodes){let U=T.edges.filter(M=>M.source===e.id);if(U.length>0){let M=T.nodes.find(q=>q.id===U[0].target);M&&M.type==="answerNode"&&(c=!0)}}}catch(T){console.error("Error determining next node for streaming:",T)}let d=K(e.data.template,e,s,t,{sessionEnv:o});(!d||!d.trim())&&(d="Answer straight forward to the user, dont offer any other option to continue");let f=d,r="";if((D=o.memoryConfig)!=null&&D.enabled){let T=await((A=o.getContextIndex)==null?void 0:A.call(o))??[];r=Qt(T),d+=r}let p=K(e.data.user_template||"",e,s,t,{sessionEnv:o}),a=T=>T&&Object.fromEntries(Object.keys(T).map(U=>[U,"[redacted]"])),u=o!=null&&o.secrets||o!=null&&o.userAuth?{...o,secrets:a(o.secrets),userAuth:a(o.userAuth)}:o,i=K(e.data.template,e,s,void 0,{sessionEnv:u})||f;i+=r;let g=K(e.data.user_template||"",e,s,void 0,{sessionEnv:u});t==null||t({type:`info:llmNodeRunner:${e.id}`,content:i}),t==null||t({type:`info:llmNodeRunner:${e.id}`,content:g});let h=(F=e==null?void 0:e.data)==null?void 0:F.window_size,w=Number(h);(!Number.isInteger(w)||w<=0)&&(w=5);let y=oe(e,s),x=ee(e,s),N=(await((j=o.getMessages)==null?void 0:j.call(o))??[]).slice(-w),$=N.filter(T=>T&&typeof T.role=="string"&&typeof T.content=="string");$.length!==N.length&&console.warn(`Filtered ${N.length-$.length} invalid messages from history`);let R=_e($,p,y,x);await Oe(d,R,o.conn,t,e,c,n,s,l,o,m)}async function Oe(o,e,s,t,n,l,m,c,d,f,r){var a;let p=Date.now();if(!((a=f.env)!=null&&a.AI))throw new Error("AI binding is required for LLM node");return new Promise(async(u,i)=>{var j,T,U,M,q,B,E;let g,h={},w,y="none",x=!1,C,N=!1,$=!1,R=0,k=0,D=(j=n==null?void 0:n.data)==null?void 0:j.sendReasoning,A=D!==!1;try{let L=(T=n==null?void 0:n.data)==null?void 0:T.model,W=Array.isArray(L)?L[0]:L||"gpt_5_nano",I=Ut(n==null?void 0:n.data),_=await at(W,f,I);if(!_)throw new Error(`Model '${W}' not found in registry`);g=_.modelHandle,h=_.effectiveParams||{},y=_.reasoning.kind;let O=Ht(_.reasoning,(U=n==null?void 0:n.data)==null?void 0:U.reasoningEffort);x=A&&jt(_.reasoning);let V=typeof((M=n==null?void 0:n.data)==null?void 0:M.reasoningMaxTokens)=="number"?n.data.reasoningMaxTokens:void 0;w=Vt(_.provider,{effort:O,exposeReasoning:x,maxTokens:V}),O&&(t==null||t({type:"info:llmNodeRunner:reasoningEffort",content:O})),console.log(`[reasoning] ${JSON.stringify({model:W,provider:_.provider,capability:_.reasoning,requestedEffort:((q=n==null?void 0:n.data)==null?void 0:q.reasoningEffort)??null,resolvedEffort:O??null,sendReasoning:A,exposeReasoning:x,providerOptions:w??null},null,2)}`);for(let H of _.paramAdjustments??[])t==null||t({type:"warn:llmNodeRunner",content:H});t==null||t({type:"info:llmNodeRunner:model",content:W}),t==null||t({type:"info:llmNodeRunner:generationParams",content:{...(B=n==null?void 0:n.data)!=null&&B.generationPreset?{preset:n.data.generationPreset}:{},...h,...y!=="none"?{reasoning:y,configuredSendReasoning:D,sendReasoning:A,exposeReasoning:x,...O?{effort:O}:{}}:{}}})}catch(L){throw t==null||t({type:"error:llmNodeRunner",content:`Model error: ${String(L)}`}),L}let F=await Ie(f,c,n,t);if((E=f.memoryConfig)!=null&&E.enabled){let{recall:L}=await import("./recall-SD6FENAS.js");F.recall=L(f,c,void 0,t)}console.log(`[tools] node ${n.id} loaded ${Object.keys(F).length}: ${Object.keys(F).join(", ")||"(none)"}`),t==null||t({type:"info:llmNodeRunner:toolsLoaded",content:{nodeId:n.id,tools:Object.keys(F)}});try{let L=Ne({model:g,system:o,messages:e,stopWhen:(()=>{var H;let _=!!F.readSkillRef?10:5,O=Number(((H=n.data)==null?void 0:H.max_steps)??_),V=Number.isFinite(O)?Math.max(1,Math.min(30,O)):_;return Re(V)})(),...Lt(h),...w?{providerOptions:w}:{},tools:F,onFinish:async I=>{var At,Ft;let _=I.text||"",O=I.reasoningText??((At=I.reasoning)==null?void 0:At.text)??"";if(console.log(`[reasoning] done: deltas=${R} chars=${k} result.reasoningText=${O.length} finishReason=${I.finishReason??"n/a"} reasoningTokens=${((Ft=I.usage)==null?void 0:Ft.reasoningTokens)??"n/a"}`),A&&x&&!N&&O&&s){N=!0;try{P(s,b.SERVER_REASONING_STREAM,O)}catch(ge){console.warn("Failed to send finished reasoning over connection",ge)}}let V={id:Ce(),role:"assistant",type:"text",content:_,ts:Date.now()};l&&(f.setMessages?await f.setMessages(V):t==null||t({type:"error:llmNodeRunner",content:"setMessages callback missing"})),s&&A&&N&&!$&&($=!0,P(s,b.SERVER_REASONING_STREAM_COMPLETE,JSON.stringify({}))),l&&s&&P(s,b.SERVER_TEXT_STREAM_COMPLETE,JSON.stringify({})),m==null||m((n==null?void 0:n.id)||"llm_result",_),t==null||t({type:"info:llmNodeRunner:onFinish",content:JSON.stringify(I)});let H=Date.now()-p,ye=C?C-p:void 0;r==null||r({type:"llm_telemetry",payload:{nodeId:n.id,totalLatency:H,timeToFirstToken:ye,model:I.response.modelId,usage:I.usage}}),r==null||r({type:"llm_result",payload:{result:I}})},onStepFinish:async I=>{let _=(O,V=200)=>{let H=typeof O=="string"?O:JSON.stringify(O);return H?H.length>V?`${H.slice(0,V)}\u2026(+${H.length-V})`:H:""};if(I.toolCalls&&I.toolCalls.length>0){for(let O of I.toolCalls)console.log(`[tools] \u2192 ${O.toolName}(${_(O.args??O.input)})`);t==null||t({type:`info:llmNodeRunner:toolCalls:${n.id}`,content:JSON.stringify(I.toolCalls)})}if(I.toolResults&&I.toolResults.length>0){for(let O of I.toolResults)console.log(`[tools] \u2190 ${O.toolName} \u2192 ${_(O.result??O.output)}`);t==null||t({type:`info:llmNodeRunner:toolResults:${n.id}`,content:JSON.stringify(I.toolResults)})}await Te(I,n,f,t)},experimental_onToolCallStart:I=>{var _;t==null||t({type:"tool:execution",content:{nodeId:n.id,toolName:(_=I==null?void 0:I.toolCall)==null?void 0:_.toolName,status:"start"}})},experimental_onToolCallFinish:I=>{var _;t==null||t({type:"tool:execution",content:{nodeId:n.id,toolName:(_=I==null?void 0:I.toolCall)==null?void 0:_.toolName,status:I!=null&&I.success?"success":"error"}})},onError:I=>{t==null||t({type:"error:llmNodeRunner",content:"Execution error"}),i(I)},onChunk:I=>{if(I.chunk.type==="reasoning-delta"){let O=I.chunk.text??I.chunk.delta??"";if(O&&(N=!0,R+=1,k+=O.length,R===1&&console.log("[reasoning] \u2713 first reasoning-delta received")),A&&s&&O)try{P(s,b.SERVER_REASONING_STREAM,O)}catch(V){console.warn("Failed to send reasoning chunk over connection",V)}return}if(I.chunk.type==="text-delta"){if(C||(C=Date.now()),s&&A&&N&&!$){$=!0;try{P(s,b.SERVER_REASONING_STREAM_COMPLETE,JSON.stringify({}))}catch(O){console.warn("Failed to send reasoning complete over connection",O)}}return}r==null||r({type:I.chunk.type,payload:{nodeId:n.id,chunk:I.chunk}});let _=`llm_chunk:${I.chunk.type}`;t==null||t({type:_,content:{...I}})}}),W=async()=>{let I="";for await(let _ of L.fullStream)if(_.type==="text-delta"){if(I+=_.text,l&&s)try{P(s,b.SERVER_TEXT_STREAM,_.text)}catch(O){console.warn("Failed to send chunk over connection",O)}}else if(_.type==="finish-step"&&_.finishReason==="tool-calls"){if(l&&s&&I.trim())try{P(s,b.SERVER_TEXT_STREAM_COMPLETE,JSON.stringify({}))}catch(O){console.warn("Failed to flush text segment over connection",O)}I=""}};await Promise.all([L,W()]),u(),t==null||t({type:"node:execution",content:{nodeId:n.id,nodeType:n.type,status:"success"}})}catch(L){t==null||t({type:"node:execution",content:{nodeId:n.id,nodeType:n.type,status:"error",error:String(L)}}),i(L)}})}function _e(o,e,s,t){let n=!!(s&&s.length>0),l=!!t,m=n||l,d=o.length>0&&o[o.length-1].role==="user"?o[o.length-1]:void 0,f=r=>{let p=[],a="";if(l&&(a+=`[Attached files]
|
|
15
15
|
${t}
|
|
16
16
|
[End of attached files]
|
|
17
17
|
|
|
18
18
|
`),r&&(a+=r),a&&p.push({type:"text",text:a}),n)for(let u of s)p.push({type:"image",image:u.data,mimeType:u.mimeType});return p};return e&&d&&d.content===e?[...o.slice(0,-1).map(p=>({role:p.role,content:p.content})),{role:"user",content:f(e)}]:e?[...o.map(r=>({role:r.role,content:r.content})),{role:"user",content:f(e)}]:m&&d?[...o.slice(0,-1).map(p=>({role:p.role,content:p.content})),{role:"user",content:f(d.content)}]:o.map(r=>({role:r.role,content:r.content}))}async function _t(o,e,s,t,n,l,m){var f,r,p,a;console.log(`**** MEMO Node id: ${e.id} ****`),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"start"}});let c="",d=Date.now();try{if(t==null||t({type:"info:memoNodeRunner",content:"Starting memo node execution"}),((f=s==null?void 0:s.context)==null?void 0:f[e.data.query_key])===void 0){t==null||t({type:"error:memoNodeRunner",content:`Query key ${e.data.query_key} not found in context`}),n==null||n(e.id,c);return}if(!o.env||!o.ctx){t==null||t({type:"error:memoNodeRunner",content:"Missing env or ctx"}),n==null||n(e.id,c);return}if(!e.data.rag_id){t==null||t({type:"error:memoNodeRunner",content:"Missing rag_id"}),n==null||n(e.id,c);return}let u=((r=s==null?void 0:s.context)==null?void 0:r[e.data.query_key])||"";t==null||t({type:"info:memoNodeRunner",content:`Query text: ${u}`}),t==null||t({type:"info:memoNodeRunner",content:"Generating embedding for query"});let i=await Mt(o,u,!0);t==null||t({type:"info:memoNodeRunner",content:`Embedding generated successfully, length: ${i.data[0].length}`});let g=Array.isArray(e.data.rag_id)?e.data.rag_id:[e.data.rag_id],h=[];for(let C of g){t==null||t({type:"info:memoNodeRunner",content:`Executing RAG query with namespace: ${C}`});let N=await o.env[`VDB_${(p=s.flowData)==null?void 0:p.tenant}_1024`].query(i.data[0],{namespace:C,topK:e.data.topk,returnMetadata:"all"});t==null||t({type:"info:memoNodeRunner",content:`RAG query completed for namespace ${C}, matches: ${((a=N.matches)==null?void 0:a.length)||0}`}),Array.isArray(N.matches)&&h.push(...N.matches)}let w=Date.now()-d;c=h.map(C=>{var N;return(N=C.metadata)==null?void 0:N.value}).filter(C=>typeof C=="string").join(`
|
|
19
19
|
|
|
20
|
-
`),m==null||m({type:"memo_search",payload:{nodeId:e.id,searchLatencyMs:w,retrievedContext:c}}),t==null||t({type:"info:memoNodeRunner",content:`Context retrieval complete, length: ${c.length}, preview: ${c.substring(0,200)}...`}),t==null||t({type:"info:memoNodeRunner",content:"Memo node execution completed successfully"})}catch(u){console.error("Error processing MemoNode:",u),t==null||t({type:"error:memoNodeRunner",content:`Memo node execution failed: ${u}`}),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"error",error:String(u)}})}finally{n==null||n(e.id,c),t==null||t({type:"info:memoNodeRunner",content:`onResult called with context length: ${c.length}`}),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"success"}})}}async function $t(o,e,s,t,n,l,m){var f,r,p,a,u,i;console.log(`**** START Node ${e.id} ****`),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"start"}}),t==null||t({type:"info:flow",content:s}),m==null||m({type:"start_node",payload:{userMessage:(f=s==null?void 0:s.context)==null?void 0:f.user_input}});let c=((r=e.data)==null?void 0:r.allow_images)!==!1,d=((p=e.data)==null?void 0:p.allow_documents)!==!1;!c&&(s!=null&&s.context)&&(s.context.user_images=[],l==null||l({...s})),!d&&(s!=null&&s.context)&&(s.context.files="",l==null||l({...s})),n==null||n(e.id,{user_input:(a=s==null?void 0:s.context)==null?void 0:a.user_input,images:c?(u=s==null?void 0:s.context)==null?void 0:u.user_images:[],files:d?(i=s==null?void 0:s.context)==null?void 0:i.files:""}),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"success"}})}function lt(o,e,s){let t=e;async function n(d){let f=d;for(t.executedNodes=t.executedNodes||[],t.context=t.context||{},t.results=t.results||{};f&&f.id;)await l(f),f=Ae(f,t.flowData,t)}async function l(d){var u;let f=c[d.type];if(!f){(u=s==null?void 0:s.onError)==null||u.call(s,`Unknown node type: ${d.type}`);return}let r=i=>{var g;return(g=s==null?void 0:s.onServerEvent)==null?void 0:g.call(s,{...i,ts:Date.now()})},p=i=>{var g,h;if((g=s==null?void 0:s.onTelemetry)==null||g.call(s,i),i.type==="llm_telemetry"||i.type==="class_telemetry"){let w=(h=i.payload)==null?void 0:h.usage;w&&(t.tokenUsage=t.tokenUsage||{promptTokens:0,completionTokens:0,totalTokens:0},t.tokenUsage.promptTokens+=w.promptTokens||0,t.tokenUsage.completionTokens+=w.completionTokens||0,t.tokenUsage.totalTokens+=w.totalTokens||0)}};return await f(o,d,t,r,(i,g)=>{t.results[i]=g},s==null?void 0:s.onChangeState,p)}let m=async d=>{var x,C,N;let f=Date.now(),r=typeof d=="string"?et(d):d,p=(r==null?void 0:r.text)||"",a=(r==null?void 0:r.images)||[],u=(r==null?void 0:r.documents)||[],i=await St(u,o.env),g=i.length>0?i.map(
|
|
21
|
-
${
|
|
20
|
+
`),m==null||m({type:"memo_search",payload:{nodeId:e.id,searchLatencyMs:w,retrievedContext:c}}),t==null||t({type:"info:memoNodeRunner",content:`Context retrieval complete, length: ${c.length}, preview: ${c.substring(0,200)}...`}),t==null||t({type:"info:memoNodeRunner",content:"Memo node execution completed successfully"})}catch(u){console.error("Error processing MemoNode:",u),t==null||t({type:"error:memoNodeRunner",content:`Memo node execution failed: ${u}`}),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"error",error:String(u)}})}finally{n==null||n(e.id,c),t==null||t({type:"info:memoNodeRunner",content:`onResult called with context length: ${c.length}`}),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"success"}})}}async function $t(o,e,s,t,n,l,m){var f,r,p,a,u,i;console.log(`**** START Node ${e.id} ****`),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"start"}}),t==null||t({type:"info:flow",content:s}),m==null||m({type:"start_node",payload:{userMessage:(f=s==null?void 0:s.context)==null?void 0:f.user_input}});let c=((r=e.data)==null?void 0:r.allow_images)!==!1,d=((p=e.data)==null?void 0:p.allow_documents)!==!1;!c&&(s!=null&&s.context)&&(s.context.user_images=[],l==null||l({...s})),!d&&(s!=null&&s.context)&&(s.context.files="",l==null||l({...s})),n==null||n(e.id,{user_input:(a=s==null?void 0:s.context)==null?void 0:a.user_input,images:c?(u=s==null?void 0:s.context)==null?void 0:u.user_images:[],files:d?(i=s==null?void 0:s.context)==null?void 0:i.files:""}),t==null||t({type:"node:execution",content:{nodeId:e.id,nodeType:e.type,status:"success"}})}function lt(o,e,s){let t=e;async function n(d){let f=d;for(t.executedNodes=t.executedNodes||[],t.context=t.context||{},t.results=t.results||{};f&&f.id;)await l(f),f=Ae(f,t.flowData,t)}async function l(d){var u;let f=c[d.type];if(!f){(u=s==null?void 0:s.onError)==null||u.call(s,`Unknown node type: ${d.type}`);return}let r=i=>{var g;return(g=s==null?void 0:s.onServerEvent)==null?void 0:g.call(s,{...i,ts:Date.now()})},p=i=>{var g,h;if((g=s==null?void 0:s.onTelemetry)==null||g.call(s,i),i.type==="llm_telemetry"||i.type==="class_telemetry"){let w=(h=i.payload)==null?void 0:h.usage;w&&(t.tokenUsage=t.tokenUsage||{promptTokens:0,completionTokens:0,totalTokens:0},t.tokenUsage.promptTokens+=w.promptTokens||0,t.tokenUsage.completionTokens+=w.completionTokens||0,t.tokenUsage.totalTokens+=w.totalTokens||0)}};return await f(o,d,t,r,(i,g)=>{t.results[i]=g},s==null?void 0:s.onChangeState,p)}let m=async d=>{var x,C,N;let f=Date.now(),r=typeof d=="string"?et(d):d,p=(r==null?void 0:r.text)||"",a=(r==null?void 0:r.images)||[],u=(r==null?void 0:r.documents)||[],i=await St(u,o.env),g=i.length>0?i.map($=>`--- file: ${$.name} ---
|
|
21
|
+
${$.text}`).join(`
|
|
22
22
|
|
|
23
23
|
`):"";t.context={user_input:p,user_images:a,files:g},t.tokenUsage={promptTokens:0,completionTokens:0,totalTokens:0},(x=s==null?void 0:s.onServerEvent)==null||x.call(s,{type:"agent:start",content:"Execution started",timestamp:Date.now()});let{startNode:h,error:w}=$e(t.flowData);if(!h){(C=s==null?void 0:s.onError)==null||C.call(s,w||"Flow Format Error");return}await n(h);let y=Date.now()-f;(N=s==null?void 0:s.onServerEvent)==null||N.call(s,{type:"agent:telemetry",content:{durationMs:y,tokenUsage:t.tokenUsage},timestamp:Date.now()})},c={startNode:$t,classifierNode:Tt,llmNode:Ot,memoNode:_t,answerNode:Rt,apiNode:Ct};return m}function $e(o){var r;let e=(o==null?void 0:o.state)??o;if(!e||!e.nodes||!e.edges||e.edges.length===0)return{error:"Flow is missing state, nodes, or edges."};let s=e.nodes.filter(p=>p.type==="startNode");if(s.length!==1)return{error:`Flow must include exactly one START node, found ${s.length}.`};let t=s[0],n=e.nodes.filter(p=>p.type==="answerNode");if(n.length===0)return{error:"Flow must include at least one ANSWER node."};let l=new Map;for(let p of e.edges)l.has(p.source)||l.set(p.source,[]),l.get(p.source).push(p.target);let m=new Map;for(let p of e.edges)m.has(p.target)||m.set(p.target,[]),m.get(p.target).push(p.source);let c=se(t.id,l),d=new Set;for(let p of n){let a=se(p.id,m);for(let u of a)d.add(u)}let f=[];for(let p of c)if(!d.has(p)){let a=e.nodes.find(u=>u.id===p);if(a){let u=((r=a.data)==null?void 0:r.label)||"";f.push(`${p}(${u},${a.type})`)}}return f.length>0?{error:`The following nodes reachable from START do not lead to any ANSWER node: ${f.join(", ")}`}:{startNode:t}}function se(o,e){let s=new Set,t=[o];for(s.add(o);t.length>0;){let n=t.shift(),l=e.get(n)||[];for(let m of l)s.has(m)||(s.add(m),t.push(m))}return s}function ke(o,e){var s;return((s=o.state)==null?void 0:s.nodes.find(t=>t.id===e))||null}function Ae(o,e,s){var c;let t=e==null?void 0:e.state;if(!t)return null;let n=t.edges.filter(d=>d.source===o.id);if(n.length===0)return null;let l=n[0].target;if(o.type==="classifierNode"&&((c=s==null?void 0:s.context)!=null&&c.classified_id)){let d=s.context.classified_id,f=n.find(r=>r.sourceHandle===`source-${d}`);f?l=f.target:console.log(`No matching edge, falling back to first: ${l}`)}return ke(e,l)}async function Fe(o){o.sql`CREATE TABLE IF NOT EXISTS messages (id TEXT PRIMARY KEY, role TEXT NOT NULL, type TEXT NOT NULL, content TEXT NOT NULL, ts INTEGER NOT NULL)`}async function ct(o,e){o.sql`INSERT INTO messages (id, role, type, content, ts) VALUES (${e.id}, ${e.role}, ${e.type}, ${e.content}, ${e.ts})`}async function X(o){return o.sql`SELECT id, role, type, content, ts FROM messages ORDER BY ts ASC`}async function dt(o){o.sql`DELETE FROM messages`}async function Me(o){o.sql`CREATE TABLE IF NOT EXISTS context (
|
|
24
24
|
ref TEXT PRIMARY KEY,
|
|
@@ -28,7 +28,7 @@ ${_.text}`).join(`
|
|
|
28
28
|
cycle INTEGER NOT NULL,
|
|
29
29
|
meta TEXT,
|
|
30
30
|
ts INTEGER NOT NULL
|
|
31
|
-
)`}async function ne(o,e){let s=e.data??null,t=s!=null?
|
|
31
|
+
)`}async function ne(o,e){let s=e.data??null,t=s!=null?Et(s):{data:null,truncated:!1},n=t.truncated?Zt(e.meta,{truncated:!0}):e.meta??null,l=e.ts??Date.now();o.sql`INSERT INTO context (ref, domain, description, data, cycle, meta, ts)
|
|
32
32
|
VALUES (${e.ref}, ${e.domain}, ${e.description}, ${t.data}, ${e.cycle}, ${n}, ${l})
|
|
33
33
|
ON CONFLICT(ref) DO UPDATE SET
|
|
34
34
|
domain = excluded.domain,
|
|
@@ -36,6 +36,6 @@ ${_.text}`).join(`
|
|
|
36
36
|
data = excluded.data,
|
|
37
37
|
cycle = excluded.cycle,
|
|
38
38
|
meta = excluded.meta,
|
|
39
|
-
ts = excluded.ts`}async function pt(o){return o.sql`SELECT ref, domain, description, cycle, meta, ts FROM context ORDER BY ts ASC`}async function ft(o,e){return o.sql`SELECT ref, domain, description, data, cycle, meta, ts FROM context WHERE ref = ${e} LIMIT 1`[0]??null}async function ie(o,e){var t;return((t=o.sql`SELECT data FROM context WHERE ref = ${e} LIMIT 1`[0])==null?void 0:t.data)??null}async function ae(o,e){let s=o.sql`SELECT ref, domain, description, data, cycle, meta, ts FROM context WHERE ref = ${e} LIMIT 1`;if(s[0])return s[0];let t=o.sql`SELECT ref, domain, description, data, cycle, meta, ts FROM context WHERE ref LIKE ${e+"%"} LIMIT 2`;return t.length===1?t[0]:null}async function re(o,e){o.sql`DELETE FROM context WHERE domain = 'tool' AND cycle <= ${e}`}async function le(o){var s;return((s=o.sql`SELECT COALESCE(MAX(cycle), 0) AS maxCycle FROM context`[0])==null?void 0:s.maxCycle)??0}async function ut(o){o.sql`DELETE FROM context`}async function ce(o){await Fe(o),await Me(o)}var kt=Object.freeze({});async function E(o,e){if(!e)return kt;if(o.HX_ORA_URL&&o.HX_API_KEY)try{let n=await fetch(`${o.HX_ORA_URL}/internal/secrets`,{headers:{Authorization:o.HX_API_KEY}});if(n.ok){let l=await n.json();if(l.secrets)return Object.freeze(l.secrets)}else console.warn(`[secrets] API failed with status ${n.status}, falling back to KV`)}catch(n){console.error("[secrets] API request failed, falling back to KV",n)}let s=o.ORA_SECRETS;if(!s)return kt;let t=`${e}:`;try{let n=await s.list({prefix:t,limit:1e3});n.list_complete===!1&&console.warn(`[secrets] tenant=${e} exceeded list page; truncating to first 1000 keys`);let l=await Promise.all(n.keys.map(async c=>{let d=await s.get(c.name);return d!==null?[c.name.slice(t.length),d]:null})),m={};for(let c of l){if(!c)continue;let[d,f]=c;d&&(m[d]=f)}return Object.freeze(m)}catch(n){return console.error("[secrets] failed to load tenant secrets from KV",{tenant:e,err:n}),kt}}import{nanoid as As}from"nanoid";function Z(o){var n,l;let e=(n=o==null?void 0:o.flowData)==null?void 0:n.state,t=((e==null?void 0:e.nodes)??((l=o==null?void 0:o.flowData)==null?void 0:l.nodes)??[]).find(m=>m.type==="startNode");return t==null?void 0:t.data}async function mt(o,e){return typeof e.cycle=="number"&&Number.isFinite(e.cycle)?e.cycle+1:await le(o)+1}function yt(o,e,s,t,n){let l=G(Z(s));return{...e,memoryConfig:l,cycle:t,setContext:async c=>{await ne(o,c),await(n==null?void 0:n(c.ref))},getContextIndex:async()=>pt(o),getContextData:async c=>ie(o,c),getContext:async c=>ft(o,c),resolveContext:async c=>ae(o,c),pruneContext:async c=>re(o,c)}}function gt(o,e){return!o||!o.HX_ORA_URL||!o.HX_API_KEY?Promise.resolve():fetch(`${o.HX_ORA_URL}/internal/sessions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:o.HX_API_KEY},body:JSON.stringify(e)}).catch(s=>{console.error("[sessionIndex] failed to index session",s)})}var ht=async(o,e)=>{fetch(`${e.DW_URL}/q/telemetry/event`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)}),`${JSON.stringify(o)}`};import{nanoid as be}from"nanoid";async function De(o,e){var l,m;let s=o.id||o.name||"",[t,n]=s.split("::");if(!t||!n)return null;try{let d=(l=(await z(t,e)).metadata)==null?void 0:l.tenant,f=await tt(t,e),r=(m=o.state)==null?void 0:m.user,p={flowData:{...f,tenant:d,flowId:t,chatId:n},executedNodes:[],context:r?{user:r}:{}};return o.setState({...o.state,engineState:p}),p}catch(c){return console.error("Failed to initialize engine state:",c),null}}async function de(o,e,s,t){var n,l,m;try{let c=await e.json(),d=c.message;if(!d||typeof d!="string")return new Response(JSON.stringify({error:"Invalid message"}),{status:400,headers:{"content-type":"application/json"}});let f=typeof c.userId=="string"?ot(c.userId):null;f&&!((n=o.state.user)!=null&&n.email)&&o.setState({...o.state,injectedUserId:f});let r=()=>{var T;return((T=o.state.user)==null?void 0:T.email)??f??o.state.injectedUserId??void 0},p=Date.now(),a=[],u=async()=>await X(o),i=async T=>{await ct(o,T)},g={id:be(),role:"user",type:"text",content:d,ts:Date.now()};await i(g);let h={onChangeState:T=>{o.setState({...o.state,engineState:T})},onServerEvent:async T=>{a.push(T)},onTelemetry:async T=>{var P,M,V,B,Q,L;await ht({...T,userId:r(),tenant:((M=(P=o.state.engineState)==null?void 0:P.flowData)==null?void 0:M.tenant)||"",flowId:((B=(V=o.state.engineState)==null?void 0:V.flowData)==null?void 0:B.flowId)||"",sessionId:((L=(Q=o.state.engineState)==null?void 0:Q.flowData)==null?void 0:L.chatId)||""},s)},onError:T=>{o.setState({...o.state,error:T})}},w=async T=>{if(o.state.modelsCache&&o.state.modelsCache[T])return o.state.modelsCache[T];try{let{fetchOraModel:P}=await import("./oraApi-3JWDQQUE.js"),M=await P(T,s);return o.setState({...o.state,modelsCache:{...o.state.modelsCache||{},[T]:M}}),M}catch(P){throw console.error(`Error fetching model ${T}:`,P),P}},y=o.state.engineState;if(!y&&(y=await De(o,s),!y))return new Response(JSON.stringify({error:"Failed to initialize agent"}),{status:500,headers:{"content-type":"application/json"}});let x=(l=y==null?void 0:y.flowData)==null?void 0:l.tenant,C=await E(s,x),N=G(Z(y)),_=typeof y.cycle=="number"?y.cycle:0;N.enabled&&(_=await mt(o,y),y={...y,cycle:_},o.setState({...o.state,engineState:y})),o.skillRefCache||(o.skillRefCache=new Map);let R=yt(o,{env:s,ctx:t,conn:void 0,getMessages:u,setMessages:i,getOraModel:w,secrets:C,skillRefCache:o.skillRefCache},y,_);await lt(R,y,h)(d);let{tenant:k,flowId:b,chatId:A}=y.flowData??{};k&&b&&A&&t.waitUntil(gt(s,{id:`${b}::${A}`,tenant:k,flowId:b,sessionId:A,userId:r(),title:d.slice(0,120),turnTs:p,events:a})),(m=R.memoryConfig)!=null&&m.enabled&&R.memoryConfig.mode==="summarize"&&t&&t.waitUntil(rt(o,R,_)),o.setState({...o.state,lastUpdated:new Date});let j=(await u()).reverse().find(T=>T.role==="assistant");return new Response(JSON.stringify({answer:(j==null?void 0:j.content)||""}),{headers:{"content-type":"application/json"}})}catch(c){return new Response(JSON.stringify({error:c.message}),{status:500,headers:{"content-type":"application/json"}})}}async function pe(o){try{return await dt(o),await ut(o),o.skillRefCache&&o.skillRefCache.clear(),o.setState({...o.state,error:"",engineState:void 0,lastUpdated:new Date}),new Response(JSON.stringify({success:!0,messages:[]}),{headers:{"content-type":"application/json"}})}catch(e){return new Response(JSON.stringify({error:e.message}),{status:500,headers:{"content-type":"application/json"}})}}var fe=class extends Pe{initialState={user:void 0,injectedUserId:null,sessionId:null,lastUpdated:null,modelsCache:{}};resolveSessionUserId(){var e;return((e=this.state.user)==null?void 0:e.email)??this.state.injectedUserId??void 0}secrets=Object.freeze({});userAuth={};composioSessions={};skillRefCache=new Map;publicOrigin;async onRequest(e){let s=new URL(e.url);if(s.pathname.endsWith("/state"))return new Response(JSON.stringify(this.state),{headers:{"content-type":"application/json"}});if(s.pathname.endsWith("/history")){let t=await X(this);return new Response(JSON.stringify(t),{headers:{"content-type":"application/json"}})}if(s.pathname.endsWith("/context")){let t={"content-type":"application/json","access-control-allow-origin":"*"};if(!e.headers.get("X-User-Payload"))return new Response(JSON.stringify({error:"Unauthorized"}),{status:401,headers:t});let n=s.searchParams.get("ref");if(n){let m=await ft(this,n);return m?new Response(JSON.stringify({entry:m}),{headers:t}):new Response(JSON.stringify({error:"Not found"}),{status:404,headers:t})}let l=await pt(this);return new Response(JSON.stringify({entries:l}),{headers:t})}return e.method==="POST"&&s.pathname.endsWith("/message")?de(this,e,this.env,this.ctx):e.method==="DELETE"&&s.pathname.endsWith("/clear")?pe(this):new Response("Ready to assist.")}async onConnect(e,s){var a,u,i,g,h;let[t,n]=e.server.split("::"),m=(a=(await z(t,this.env)).metadata)==null?void 0:a.tenant;this.secrets=await E(this.env,m),this.userAuth={},this.composioSessions={},this.publicOrigin=void 0;let c=null;if(s.request){try{this.publicOrigin=new URL(s.request.url).origin}catch{}let w=s.request.headers.get("X-User-Payload");if(w)try{c=JSON.parse(w)}catch(y){console.warn("Failed to parse X-User-Payload",y)}}let d=await tt(t,this.env);this.setState({...this.state,user:c||null,sessionId:n,engineState:{flowData:{...d,tenant:m,flowId:t,chatId:n},executedNodes:[],context:c?{user:c}:{}}}),c||console.warn("[AgentDO] WebSocket connected without authenticated user \u2014 Composio manual auth requires login (access_token on socket URL)");let f=await X(this);U(e,D.SERVER_HISTORY,JSON.stringify({messages:f}));let p=(((u=d==null?void 0:d.state)==null?void 0:u.nodes)??(d==null?void 0:d.nodes)??[]).find(w=>w.type==="startNode");if(p){let w={allow_images:((i=p.data)==null?void 0:i.allow_images)??!1,allow_documents:((g=p.data)==null?void 0:g.allow_documents)??!1,greeting:(h=p.data)==null?void 0:h.greeting};U(e,D.SERVER_CONFIG,JSON.stringify(w))}}async onMessage(e,s){if(typeof s!="string")return;let t=s.indexOf(":");if(t===-1)return;let n=s.substring(0,t),l=s.substring(t+1);if(!n||!l)return;let c={[D.USER_MESSAGE]:d=>this.onUserMessage(e,d),[D.USER_CLEAR_HISTORY]:()=>this.onClearHistory(e),[D.USER_AUTH]:d=>this.onUserAuth(e,d),[D.USER_IDENTITY]:d=>this.onUserIdentity(e,d)}[n];c&&await c(l)}async onUserMessage(e,s){var y,x,C,N,_;let t=Date.now(),n=[],l=async()=>await X(this),m=async R=>{await ct(this,R)},c=async R=>{if(this.state.modelsCache&&this.state.modelsCache[R])return this.state.modelsCache[R];try{let{fetchOraModel:k}=await import("./oraApi-3JWDQQUE.js"),b=await k(R,this.env);return this.setState({...this.state,modelsCache:{...this.state.modelsCache,[R]:b}}),b}catch(k){throw console.error(`Error fetching model ${R}:`,k),k}},d=et(s),f={id:Ue(),role:"user",type:"text",content:d.text,images:d.images,ts:Date.now()};await m(f);let r={onChangeState:R=>{this.setState({...this.state,engineState:R})},onServerEvent:async R=>{U(e,D.SERVER_EVENT,JSON.stringify(R)),n.push(R)},onTelemetry:async R=>{var k,b,A,F,j,T;await ht({...R,userId:this.resolveSessionUserId(),tenant:((b=(k=this.state.engineState)==null?void 0:k.flowData)==null?void 0:b.tenant)||"",flowId:((F=(A=this.state.engineState)==null?void 0:A.flowData)==null?void 0:F.flowId)||"",sessionId:((T=(j=this.state.engineState)==null?void 0:j.flowData)==null?void 0:T.chatId)||""},this.env)},onError:R=>{U(e,D.SERVER_ERROR,R),this.setState({...this.state,error:R})}};if(Object.keys(this.secrets).length===0){let R=(x=(y=this.state.engineState)==null?void 0:y.flowData)==null?void 0:x.tenant;R&&(this.secrets=await E(this.env,R))}let p={...this.state.engineState};this.state.user&&!((C=p.context)!=null&&C.user)&&(p.context={...p.context||{},user:this.state.user});let a=G(Z(p)),u=typeof p.cycle=="number"?p.cycle:0;a.enabled&&(u=await mt(this,p),p.cycle=u,this.setState({...this.state,engineState:p}));let i=yt(this,{env:this.env,ctx:this.ctx,conn:e,getMessages:l,setMessages:m,getOraModel:c,secrets:this.secrets,userAuth:this.userAuth,user:this.state.user,composioSessions:this.composioSessions,publicOrigin:this.publicOrigin,skillRefCache:this.skillRefCache},p,u,async R=>{U(e,D.SERVER_EVENT,JSON.stringify({type:"info:memory:updated",content:{ref:R}}))});await lt(i,p,r)(d);let{tenant:g,flowId:h,chatId:w}=p.flowData??{};g&&h&&w&&this.ctx.waitUntil(gt(this.env,{id:`${h}::${w}`,tenant:g,flowId:h,sessionId:w,userId:this.resolveSessionUserId(),title:(N=d.text)==null?void 0:N.slice(0,120),turnTs:t,events:n})),(_=i.memoryConfig)!=null&&_.enabled&&i.memoryConfig.mode==="summarize"&&this.ctx&&this.ctx.waitUntil(rt(this,i,u)),this.setState({...this.state,lastUpdated:new Date})}async onUserIdentity(e,s){let t=ot(s);if(!t){U(e,D.SERVER_ERROR,"Invalid identity payload");return}this.setState({...this.state,injectedUserId:t}),U(e,D.SERVER_EVENT,JSON.stringify({type:"info:identity",content:{set:!0}}))}async onUserAuth(e,s){let t=bt(s);if(!t){U(e,D.SERVER_ERROR,"Invalid auth payload");return}let n=t.value.trim();n===""?delete this.userAuth[t.name]:this.userAuth[t.name]=t.value,U(e,D.SERVER_EVENT,JSON.stringify({type:"info:auth",content:{name:t.name,set:n!==""}}))}async onClearHistory(e){await dt(this),await ut(this),this.userAuth={},this.composioSessions={},this.skillRefCache.clear();let s=this.state.engineState?{...this.state.engineState,cycle:void 0}:void 0;this.setState({...this.state,error:"",engineState:s,lastUpdated:new Date}),e&&U(e,D.SERVER_HISTORY,JSON.stringify({messages:[]}))}async onStart(){`${JSON.stringify(this.state)}`,await ce(this);let e=await X(this);`${JSON.stringify(e)}`}async onClose(e,s,t,n){console.log(`Session closed: ${this.state.sessionId} ${s} - ${t}`)}async onError(e){console.error("AgentDO encountered an error:",e)}};function mn(o){let e=o.state;if(!e)return null;let s=["startNode","answerNode"];for(let t of s)if(!e.nodes.some(l=>l.type===t))return!1;return e.nodes.find(t=>t.type==="startNode")}import{importSPKI as Le,jwtVerify as je}from"jose";function ue(o){let e={};if(!o)return e;let s=o.split(";");for(let t of s){let n=t.indexOf("=");if(n>-1){let l=t.slice(0,n).trim(),m=t.slice(n+1).trim();l&&(e[l]=decodeURIComponent(m))}}return e}async function J(o,e,s){let t=ue(o.headers.get("cookie")),n=new URL(o.url),l=t.access_token||n.searchParams.get("access_token"),m=await He(e,l);if(m.ok){let c=m.payload,d=typeof c.preferred_username=="string"?c.preferred_username.trim():"",f=typeof c.email=="string"?c.email.trim():"";return{id:c.sub,email:d||f,name:c.name,first_name:c.given_name,last_name:c.family_name,tenant:c.tenant,roles:c["ora-roles"],db_name:c.db_name||null,user_id:c.user_id||null}}return null}async function He(o,e){if(!e||typeof e!="string")return{ok:!1,payload:null,protectedHeader:null};if(!o.KC_RS256_PK)throw new Error("PK is not defined");let s=`-----BEGIN PUBLIC KEY-----
|
|
39
|
+
ts = excluded.ts`}async function pt(o){return o.sql`SELECT ref, domain, description, cycle, meta, ts FROM context ORDER BY ts ASC`}async function ft(o,e){return o.sql`SELECT ref, domain, description, data, cycle, meta, ts FROM context WHERE ref = ${e} LIMIT 1`[0]??null}async function ie(o,e){var t;return((t=o.sql`SELECT data FROM context WHERE ref = ${e} LIMIT 1`[0])==null?void 0:t.data)??null}async function ae(o,e){let s=o.sql`SELECT ref, domain, description, data, cycle, meta, ts FROM context WHERE ref = ${e} LIMIT 1`;if(s[0])return s[0];let t=o.sql`SELECT ref, domain, description, data, cycle, meta, ts FROM context WHERE ref LIKE ${e+"%"} LIMIT 2`;return t.length===1?t[0]:null}async function re(o,e){o.sql`DELETE FROM context WHERE domain = 'tool' AND cycle <= ${e}`}async function le(o){var s;return((s=o.sql`SELECT COALESCE(MAX(cycle), 0) AS maxCycle FROM context`[0])==null?void 0:s.maxCycle)??0}async function ut(o){o.sql`DELETE FROM context`}async function ce(o){await Fe(o),await Me(o)}var kt=Object.freeze({});async function Q(o,e){if(!e)return kt;if(o.HX_ORA_URL&&o.HX_API_KEY)try{let n=await fetch(`${o.HX_ORA_URL}/internal/secrets`,{headers:{Authorization:o.HX_API_KEY}});if(n.ok){let l=await n.json();if(l.secrets)return Object.freeze(l.secrets)}else console.warn(`[secrets] API failed with status ${n.status}, falling back to KV`)}catch(n){console.error("[secrets] API request failed, falling back to KV",n)}let s=o.ORA_SECRETS;if(!s)return kt;let t=`${e}:`;try{let n=await s.list({prefix:t,limit:1e3});n.list_complete===!1&&console.warn(`[secrets] tenant=${e} exceeded list page; truncating to first 1000 keys`);let l=await Promise.all(n.keys.map(async c=>{let d=await s.get(c.name);return d!==null?[c.name.slice(t.length),d]:null})),m={};for(let c of l){if(!c)continue;let[d,f]=c;d&&(m[d]=f)}return Object.freeze(m)}catch(n){return console.error("[secrets] failed to load tenant secrets from KV",{tenant:e,err:n}),kt}}import{nanoid as As}from"nanoid";function Z(o){var n,l;let e=(n=o==null?void 0:o.flowData)==null?void 0:n.state,t=((e==null?void 0:e.nodes)??((l=o==null?void 0:o.flowData)==null?void 0:l.nodes)??[]).find(m=>m.type==="startNode");return t==null?void 0:t.data}async function mt(o,e){return typeof e.cycle=="number"&&Number.isFinite(e.cycle)?e.cycle+1:await le(o)+1}function yt(o,e,s,t,n){let l=G(Z(s));return{...e,memoryConfig:l,cycle:t,setContext:async c=>{await ne(o,c),await(n==null?void 0:n(c.ref))},getContextIndex:async()=>pt(o),getContextData:async c=>ie(o,c),getContext:async c=>ft(o,c),resolveContext:async c=>ae(o,c),pruneContext:async c=>re(o,c)}}function gt(o,e){return!o||!o.HX_ORA_URL||!o.HX_API_KEY?Promise.resolve():fetch(`${o.HX_ORA_URL}/internal/sessions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:o.HX_API_KEY},body:JSON.stringify(e)}).catch(s=>{console.error("[sessionIndex] failed to index session",s)})}var ht=async(o,e)=>{fetch(`${e.DW_URL}/q/telemetry/event`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)}),`${JSON.stringify(o)}`};import{nanoid as be}from"nanoid";async function De(o,e){var l,m;let s=o.id||o.name||"",[t,n]=s.split("::");if(!t||!n)return null;try{let d=(l=(await z(t,e)).metadata)==null?void 0:l.tenant,f=await tt(t,e),r=(m=o.state)==null?void 0:m.user,p={flowData:{...f,tenant:d,flowId:t,chatId:n},executedNodes:[],context:r?{user:r}:{}};return o.setState({...o.state,engineState:p}),p}catch(c){return console.error("Failed to initialize engine state:",c),null}}async function de(o,e,s,t){var n,l,m;try{let c=await e.json(),d=c.message;if(!d||typeof d!="string")return new Response(JSON.stringify({error:"Invalid message"}),{status:400,headers:{"content-type":"application/json"}});let f=typeof c.userId=="string"?ot(c.userId):null;f&&!((n=o.state.user)!=null&&n.email)&&o.setState({...o.state,injectedUserId:f});let r=()=>{var T;return((T=o.state.user)==null?void 0:T.email)??f??o.state.injectedUserId??void 0},p=Date.now(),a=[],u=async()=>await X(o),i=async T=>{await ct(o,T)},g={id:be(),role:"user",type:"text",content:d,ts:Date.now()};await i(g);let h={onChangeState:T=>{o.setState({...o.state,engineState:T})},onServerEvent:async T=>{a.push(T)},onTelemetry:async T=>{var U,M,q,B,E,L;await ht({...T,userId:r(),tenant:((M=(U=o.state.engineState)==null?void 0:U.flowData)==null?void 0:M.tenant)||"",flowId:((B=(q=o.state.engineState)==null?void 0:q.flowData)==null?void 0:B.flowId)||"",sessionId:((L=(E=o.state.engineState)==null?void 0:E.flowData)==null?void 0:L.chatId)||""},s)},onError:T=>{o.setState({...o.state,error:T})}},w=async T=>{if(o.state.modelsCache&&o.state.modelsCache[T])return o.state.modelsCache[T];try{let{fetchOraModel:U}=await import("./oraApi-3JWDQQUE.js"),M=await U(T,s);return o.setState({...o.state,modelsCache:{...o.state.modelsCache||{},[T]:M}}),M}catch(U){throw console.error(`Error fetching model ${T}:`,U),U}},y=o.state.engineState;if(!y&&(y=await De(o,s),!y))return new Response(JSON.stringify({error:"Failed to initialize agent"}),{status:500,headers:{"content-type":"application/json"}});let x=(l=y==null?void 0:y.flowData)==null?void 0:l.tenant,C=await Q(s,x),N=G(Z(y)),$=typeof y.cycle=="number"?y.cycle:0;N.enabled&&($=await mt(o,y),y={...y,cycle:$},o.setState({...o.state,engineState:y})),o.skillRefCache||(o.skillRefCache=new Map);let R=yt(o,{env:s,ctx:t,conn:void 0,getMessages:u,setMessages:i,getOraModel:w,secrets:C,skillRefCache:o.skillRefCache},y,$);await lt(R,y,h)(d);let{tenant:k,flowId:D,chatId:A}=y.flowData??{};k&&D&&A&&t.waitUntil(gt(s,{id:`${D}::${A}`,tenant:k,flowId:D,sessionId:A,userId:r(),title:d.slice(0,120),turnTs:p,events:a})),(m=R.memoryConfig)!=null&&m.enabled&&R.memoryConfig.mode==="summarize"&&t&&t.waitUntil(rt(o,R,$)),o.setState({...o.state,lastUpdated:new Date});let j=(await u()).reverse().find(T=>T.role==="assistant");return new Response(JSON.stringify({answer:(j==null?void 0:j.content)||""}),{headers:{"content-type":"application/json"}})}catch(c){return new Response(JSON.stringify({error:c.message}),{status:500,headers:{"content-type":"application/json"}})}}async function pe(o){try{return await dt(o),await ut(o),o.skillRefCache&&o.skillRefCache.clear(),o.setState({...o.state,error:"",engineState:void 0,lastUpdated:new Date}),new Response(JSON.stringify({success:!0,messages:[]}),{headers:{"content-type":"application/json"}})}catch(e){return new Response(JSON.stringify({error:e.message}),{status:500,headers:{"content-type":"application/json"}})}}var fe=class extends Pe{initialState={user:void 0,injectedUserId:null,sessionId:null,lastUpdated:null,modelsCache:{}};resolveSessionUserId(){var e;return((e=this.state.user)==null?void 0:e.email)??this.state.injectedUserId??void 0}secrets=Object.freeze({});userAuth={};composioSessions={};skillRefCache=new Map;publicOrigin;async onRequest(e){let s=new URL(e.url);if(s.pathname.endsWith("/state"))return new Response(JSON.stringify(this.state),{headers:{"content-type":"application/json"}});if(s.pathname.endsWith("/history")){let t=await X(this);return new Response(JSON.stringify(t),{headers:{"content-type":"application/json"}})}if(s.pathname.endsWith("/context")){let t={"content-type":"application/json","access-control-allow-origin":"*"};if(!e.headers.get("X-User-Payload"))return new Response(JSON.stringify({error:"Unauthorized"}),{status:401,headers:t});let n=s.searchParams.get("ref");if(n){let m=await ft(this,n);return m?new Response(JSON.stringify({entry:m}),{headers:t}):new Response(JSON.stringify({error:"Not found"}),{status:404,headers:t})}let l=await pt(this);return new Response(JSON.stringify({entries:l}),{headers:t})}return e.method==="POST"&&s.pathname.endsWith("/message")?de(this,e,this.env,this.ctx):e.method==="DELETE"&&s.pathname.endsWith("/clear")?pe(this):new Response("Ready to assist.")}async onConnect(e,s){var a,u,i,g,h;let[t,n]=e.server.split("::"),m=(a=(await z(t,this.env)).metadata)==null?void 0:a.tenant;this.secrets=await Q(this.env,m),this.userAuth={},this.composioSessions={},this.publicOrigin=void 0;let c=null;if(s.request){try{this.publicOrigin=new URL(s.request.url).origin}catch{}let w=s.request.headers.get("X-User-Payload");if(w)try{c=JSON.parse(w)}catch(y){console.warn("Failed to parse X-User-Payload",y)}}let d=await tt(t,this.env);this.setState({...this.state,user:c||null,sessionId:n,engineState:{flowData:{...d,tenant:m,flowId:t,chatId:n},executedNodes:[],context:c?{user:c}:{}}}),c||console.warn("[AgentDO] WebSocket connected without authenticated user \u2014 Composio manual auth requires login (access_token on socket URL)");let f=await X(this);P(e,b.SERVER_HISTORY,JSON.stringify({messages:f}));let p=(((u=d==null?void 0:d.state)==null?void 0:u.nodes)??(d==null?void 0:d.nodes)??[]).find(w=>w.type==="startNode");if(p){let w={allow_images:((i=p.data)==null?void 0:i.allow_images)??!1,allow_documents:((g=p.data)==null?void 0:g.allow_documents)??!1,greeting:(h=p.data)==null?void 0:h.greeting};P(e,b.SERVER_CONFIG,JSON.stringify(w))}}async onMessage(e,s){if(typeof s!="string")return;let t=s.indexOf(":");if(t===-1)return;let n=s.substring(0,t),l=s.substring(t+1);if(!n||!l)return;let c={[b.USER_MESSAGE]:d=>this.onUserMessage(e,d),[b.USER_CLEAR_HISTORY]:()=>this.onClearHistory(e),[b.USER_AUTH]:d=>this.onUserAuth(e,d),[b.USER_IDENTITY]:d=>this.onUserIdentity(e,d)}[n];c&&await c(l)}async onUserMessage(e,s){var y,x,C,N,$;let t=Date.now(),n=[],l=async()=>await X(this),m=async R=>{await ct(this,R)},c=async R=>{if(this.state.modelsCache&&this.state.modelsCache[R])return this.state.modelsCache[R];try{let{fetchOraModel:k}=await import("./oraApi-3JWDQQUE.js"),D=await k(R,this.env);return this.setState({...this.state,modelsCache:{...this.state.modelsCache,[R]:D}}),D}catch(k){throw console.error(`Error fetching model ${R}:`,k),k}},d=et(s),f={id:Ue(),role:"user",type:"text",content:d.text,images:d.images,ts:Date.now()};await m(f);let r={onChangeState:R=>{this.setState({...this.state,engineState:R})},onServerEvent:async R=>{P(e,b.SERVER_EVENT,JSON.stringify(R)),n.push(R)},onTelemetry:async R=>{var k,D,A,F,j,T;await ht({...R,userId:this.resolveSessionUserId(),tenant:((D=(k=this.state.engineState)==null?void 0:k.flowData)==null?void 0:D.tenant)||"",flowId:((F=(A=this.state.engineState)==null?void 0:A.flowData)==null?void 0:F.flowId)||"",sessionId:((T=(j=this.state.engineState)==null?void 0:j.flowData)==null?void 0:T.chatId)||""},this.env)},onError:R=>{P(e,b.SERVER_ERROR,R),this.setState({...this.state,error:R})}};if(Object.keys(this.secrets).length===0){let R=(x=(y=this.state.engineState)==null?void 0:y.flowData)==null?void 0:x.tenant;R&&(this.secrets=await Q(this.env,R))}let p={...this.state.engineState};this.state.user&&!((C=p.context)!=null&&C.user)&&(p.context={...p.context||{},user:this.state.user});let a=G(Z(p)),u=typeof p.cycle=="number"?p.cycle:0;a.enabled&&(u=await mt(this,p),p.cycle=u,this.setState({...this.state,engineState:p}));let i=yt(this,{env:this.env,ctx:this.ctx,conn:e,getMessages:l,setMessages:m,getOraModel:c,secrets:this.secrets,userAuth:this.userAuth,user:this.state.user,composioSessions:this.composioSessions,publicOrigin:this.publicOrigin,skillRefCache:this.skillRefCache},p,u,async R=>{P(e,b.SERVER_EVENT,JSON.stringify({type:"info:memory:updated",content:{ref:R}}))});await lt(i,p,r)(d);let{tenant:g,flowId:h,chatId:w}=p.flowData??{};g&&h&&w&&this.ctx.waitUntil(gt(this.env,{id:`${h}::${w}`,tenant:g,flowId:h,sessionId:w,userId:this.resolveSessionUserId(),title:(N=d.text)==null?void 0:N.slice(0,120),turnTs:t,events:n})),($=i.memoryConfig)!=null&&$.enabled&&i.memoryConfig.mode==="summarize"&&this.ctx&&this.ctx.waitUntil(rt(this,i,u)),this.setState({...this.state,lastUpdated:new Date})}async onUserIdentity(e,s){let t=ot(s);if(!t){P(e,b.SERVER_ERROR,"Invalid identity payload");return}this.setState({...this.state,injectedUserId:t}),P(e,b.SERVER_EVENT,JSON.stringify({type:"info:identity",content:{set:!0}}))}async onUserAuth(e,s){let t=bt(s);if(!t){P(e,b.SERVER_ERROR,"Invalid auth payload");return}let n=t.value.trim();n===""?delete this.userAuth[t.name]:this.userAuth[t.name]=t.value,P(e,b.SERVER_EVENT,JSON.stringify({type:"info:auth",content:{name:t.name,set:n!==""}}))}async onClearHistory(e){await dt(this),await ut(this),this.userAuth={},this.composioSessions={},this.skillRefCache.clear();let s=this.state.engineState?{...this.state.engineState,cycle:void 0}:void 0;this.setState({...this.state,error:"",engineState:s,lastUpdated:new Date}),e&&P(e,b.SERVER_HISTORY,JSON.stringify({messages:[]}))}async onStart(){`${JSON.stringify(this.state)}`,await ce(this);let e=await X(this);`${JSON.stringify(e)}`}async onClose(e,s,t,n){console.log(`Session closed: ${this.state.sessionId} ${s} - ${t}`)}async onError(e){console.error("AgentDO encountered an error:",e)}};function mn(o){let e=o.state;if(!e)return null;let s=["startNode","answerNode"];for(let t of s)if(!e.nodes.some(l=>l.type===t))return!1;return e.nodes.find(t=>t.type==="startNode")}import{importSPKI as Le,jwtVerify as je}from"jose";function ue(o){let e={};if(!o)return e;let s=o.split(";");for(let t of s){let n=t.indexOf("=");if(n>-1){let l=t.slice(0,n).trim(),m=t.slice(n+1).trim();l&&(e[l]=decodeURIComponent(m))}}return e}async function J(o,e,s){let t=ue(o.headers.get("cookie")),n=new URL(o.url),l=t.access_token||n.searchParams.get("access_token"),m=await He(e,l);if(m.ok){let c=m.payload,d=typeof c.preferred_username=="string"?c.preferred_username.trim():"",f=typeof c.email=="string"?c.email.trim():"";return{id:c.sub,email:d||f,name:c.name,first_name:c.given_name,last_name:c.family_name,tenant:c.tenant,roles:c["ora-roles"],db_name:c.db_name||null,user_id:c.user_id||null}}return null}async function He(o,e){if(!e||typeof e!="string")return{ok:!1,payload:null,protectedHeader:null};if(!o.KC_RS256_PK)throw new Error("PK is not defined");let s=`-----BEGIN PUBLIC KEY-----
|
|
40
40
|
${o.KC_RS256_PK}
|
|
41
|
-
-----END PUBLIC KEY-----`,t=await Le(s,"RS256");try{let{payload:n,protectedHeader:l}=await je(e,t);return{ok:!0,payload:n,protectedHeader:l}}catch(n){return console.error("JWT verification failed:",n),{ok:!1,payload:null,protectedHeader:null}}}async function Rn(o,e,s){let t=new URL(o.url);if(t.pathname==="/favicon.ico")return new Response(null,{status:204});if(t.pathname.startsWith("/.well-known/appspecific"))return new Response(null,{status:204})}import{getAgentByName as me}from"agents";var
|
|
41
|
+
-----END PUBLIC KEY-----`,t=await Le(s,"RS256");try{let{payload:n,protectedHeader:l}=await je(e,t);return{ok:!0,payload:n,protectedHeader:l}}catch(n){return console.error("JWT verification failed:",n),{ok:!1,payload:null,protectedHeader:null}}}async function Rn(o,e,s){let t=new URL(o.url);if(t.pathname==="/favicon.ico")return new Response(null,{status:204});if(t.pathname.startsWith("/.well-known/appspecific"))return new Response(null,{status:204})}import{getAgentByName as me}from"agents";var Ve=/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;async function On(o,e,s){var n,l,m,c;let t=new URL(o.url);if(t.pathname.startsWith("/a/")){let d=t.pathname.split("/"),f=d[2],r=d[3];try{if(!f)return Response.redirect(new URL("/",t.origin).toString(),302);let p;try{p=await z(f,e)}catch{return new Response("Flow not found",{status:404})}if(!p.metadata||((n=p.metadata)==null?void 0:n.status)!=="active")return new Response("NO chat",{status:404});if(((l=p.metadata)==null?void 0:l.visibility)==="private"&&!await J(o,e,s)){let u=new URL("/login",t.origin);return u.searchParams.set("nextURL",`${t.pathname}${t.search}`),Response.redirect(u.toString(),302)}if(!r){let a=crypto.randomUUID(),u=new URL(`/a/${f}/${a}`,t.origin);return Response.redirect(u.toString(),302)}if(!Ve.test(r))return new Response("Id del chat no v\xE1lido",{status:400})}catch(p){return console.error("Error accessing flow KV:",p),new Response("Flow error",{status:500})}}if(t.pathname.startsWith("/api/agent/flow")){let d=t.pathname.split("/"),f=d[4],r=d[5],p=`${f}::${r}`;try{let a=await J(o,e,s);if(!a){let w=new URL(o.url).searchParams.has("access_token");console.warn(`[agents] Unauthenticated agent socket upgrade (access_token query=${w}) \u2014 Composio connections from tool editor will not apply`)}let u=new Headers(o.headers);a&&u.set("X-User-Payload",JSON.stringify(a));let i=new Request(o,{headers:u});return(await me(e.AGENT,p)).fetch(i)}catch(a){return console.error("Error accessing agent:",a),new Response("Agent error",{status:500})}}if(t.pathname.startsWith("/api/ora/connect")){let d=t.pathname.split("/"),f=d[4],r=d[5];if(!f||!r)return new Response("Missing flowId or sessionId",{status:400});let p=o.headers.get("Authorization")||t.searchParams.get("authorization");if(!p)return new Response("Missing Authorization header",{status:401});try{let a=`${e.HX_CORE_URL}/p/v1/validation/key/agent/${f}`,i=await(await fetch(a,{method:"GET",headers:{Authorization:p}})).json();if(((m=i.payload)==null?void 0:m.flowId)!==f)return console.error("FlowId mismatch:",(c=i.payload)==null?void 0:c.flowId,"!==",f),new Response("Validation error",{status:403});let g=`${f}::${r}`,h=await J(o,e,s);if(!h){let N=new URL(o.url).searchParams.has("access_token");console.warn(`[agents] Unauthenticated agent socket upgrade (access_token query=${N}) \u2014 Composio connections from tool editor will not apply`)}let w=new Headers(o.headers);h&&w.set("X-User-Payload",JSON.stringify(h));let y=new Request(o,{headers:w});return(await me(e.AGENT,g)).fetch(y)}catch(a){return console.error("Error in /api/ora/connect:",a),new Response("Internal error",{status:500})}}}async function kn(o,e,s){let t=new URL(o.url),n=o.method;if(!t.pathname.startsWith("/api/instances"))return;let l=await J(o,e,s);if(!l)return new Response("Unauthorized",{status:401});let m=e.HX_CORE_URL,c=e.HX_API_KEY;if(!m||!c)return console.error("Missing configuration: HX_CORE_URL or HX_API_KEY"),new Response("Internal Server Error",{status:500});let f=t.pathname.slice("/api/instances".length);f.startsWith("/")&&(f=f.slice(1)),f.endsWith("/")&&(f=f.slice(0,-1));let r="/ora/instances";f&&(r+=`/${f}`);let p=m.endsWith("/")?m.slice(0,-1):m,a=new URL(`${p}${r}`);t.searchParams.forEach((g,h)=>{a.searchParams.set(h,g)}),n==="GET"&&!f&&a.searchParams.set("filter_user_id",l.email);let u=new Headers;u.set("Authorization",c),u.set("Content-Type","application/json"),u.set("X-User-Payload",JSON.stringify(l));let i={method:n,headers:u};if(["POST","PATCH","PUT"].includes(n))try{i.body=await o.text()}catch(g){console.error("Error reading request body:",g)}try{let g=await fetch(a.toString(),i),h=await g.text();return new Response(h,{status:g.status,headers:{"Content-Type":"application/json"}})}catch(g){return console.error("Error proxying to flow instance backend:",g),new Response("Internal Server Error",{status:500})}}async function Mn(o,e,s){let t=new URL(o.url);if(o.method==="POST"&&t.pathname==="/auth/login")try{let n=await o.formData(),l=n.get("username"),m=n.get("password"),c=n.get("nextURL")||"/";if(!l||!m)return new Response("Missing username or password",{status:400});let d=new URLSearchParams;d.append("username",l),d.append("password",m),d.append("grant_type","password"),d.append("client_id",e.KC_CLIENT_ID),d.append("client_secret",e.KC_CLIENT_SECRET);let f=await fetch(`${e.KC_BASE_URL}/protocol/openid-connect/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Cookie:"hxsecure=1"},body:d});if(!f.ok)return new Response("Unauthorized",{status:401});let r=await f.json(),p=new Response(null,{status:302,headers:{Location:c}}),a=(u,i,g)=>{p.headers.append("Set-Cookie",`${u}=${i}; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=${g}`)};return r.access_token&&a("access_token",r.access_token,r.expires_in),r.refresh_token&&a("refresh_token",r.refresh_token,r.refresh_expires_in||3600*24*30),r.id_token&&a("id_token",r.id_token,r.expires_in),p}catch(n){return console.error("Auth error:",n),new Response("Internal Server Error",{status:500})}if(t.pathname==="/auth/logout"){let n=new Response(null,{status:302,headers:{Location:"/login"}}),l=m=>{n.headers.append("Set-Cookie",`${m}=; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=0`)};return l("access_token"),l("refresh_token"),l("id_token"),n}if(t.pathname.startsWith("/s/")){let n=await J(o,e,s);if(!n){let l=new URL("/login",t.origin);return l.searchParams.set("nextURL",`${t.pathname}${t.search}`),Response.redirect(l.toString(),302)}return{user:n}}}export{fe as AgentDO,Qe as GENERATION_PARAM_KEYS,Se as GENERATION_PRESETS,Ge as MAX_USER_IDENTITY_LENGTH,mo as MODEL_REGISTRY_SNAPSHOT,Y as NodeType,Ze as PRESET_PARAM_KEYS,lo as REASONING_EFFORT_LEVELS,qt as TOOL_REGISTRY_SNAPSHOT,eo as applyPresetToOverrides,Vt as buildReasoningProviderOptions,Xe as buildUrl,ut as clearAllContext,dt as clearAllMessages,qe as convertTempMessure,re as deleteContextToolsUpToCycle,ve as deriveParamSupport,Mt as embedText,ce as ensureAgentTables,Me as ensureContextTable,Fe as ensureMessagesTable,X as getAllMessages,ft as getContext,ie as getContextData,pt as getContextIndex,Ee as getDefaultOutVars,st as getEffectiveOutVars,le as getMaxContextCycle,yo as getModelEntry,On as handleAgentsRoutes,Mn as handleAuthRoutes,Rn as handleCommonRoutes,kn as handleIntancesRoutes,ze as hashText,Jt as jsonSchemaToZod,v as logc,b as messageTypes,oo as normalizeEffectiveParams,fo as normalizeModelEntry,co as normalizeReasoning,no as openAiReasoningParamSupport,so as openAiStandardParamSupport,ue as parseCookies,bt as parseUserAuth,et as parseUserMessage,Ut as pickNodeOverrides,po as reasoningEffortLevels,jt as reasoningExposable,uo as registerProvider,ae as resolveContextRef,at as resolveModelById,nt as resolveOutVarRef,to as resolvePreset,Ht as resolveReasoningEffort,Dt as resolveTemplate,Ke as safeParseJSON,ot as sanitizeUserIdentity,ht as sendEvent,P as serverSend,ne as setContext,ct as setMessage,lt as startEngine,ro as stripUnsupportedFromNodeData,Je as tempTool,Lt as toStreamTextSettings,We as twitter,mn as validateFlowStart,Ye as vectorize,He as verifyToken,J as verifyUser,Be as walkPath,ao as workersAiParamSupport,io as xaiParamSupport};
|