@arcgis/ai-orchestrator 5.1.0-next.84 → 5.1.0-next.86
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/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import R from "@arcgis/core/identity/IdentityManager.js";
|
|
2
2
|
import I from "@arcgis/core/portal/Portal.js";
|
|
3
|
-
import { Annotation as
|
|
4
|
-
import { HumanMessage as W, AIMessage as
|
|
5
|
-
import { dispatchCustomEvent as
|
|
6
|
-
import
|
|
3
|
+
import { Annotation as x, isGraphInterrupt as ne, StateGraph as re, START as se, END as ie, MemorySaver as ae } from "@langchain/langgraph/web";
|
|
4
|
+
import { HumanMessage as W, AIMessage as k, isAIMessage as oe, isToolMessage as ce } from "@langchain/core/messages";
|
|
5
|
+
import { dispatchCustomEvent as j } from "@langchain/core/callbacks/dispatch/web";
|
|
6
|
+
import h, { z as l } from "zod";
|
|
7
7
|
import { ChatPromptTemplate as N, SystemMessagePromptTemplate as de } from "@langchain/core/prompts";
|
|
8
|
-
import { createAgent as le, summarizationMiddleware as
|
|
9
|
-
import { ChatOpenAI as
|
|
8
|
+
import { createAgent as le, summarizationMiddleware as ue, modelCallLimitMiddleware as me } from "langchain";
|
|
9
|
+
import { ChatOpenAI as ge, OpenAIEmbeddings as pe } from "@langchain/openai";
|
|
10
10
|
import * as H from "@arcgis/core/core/reactiveUtils.js";
|
|
11
11
|
import O from "@arcgis/core/layers/FeatureLayer.js";
|
|
12
12
|
import he from "@arcgis/core/request.js";
|
|
@@ -14,20 +14,20 @@ const V = {
|
|
|
14
14
|
advanced: "gpt-5.2",
|
|
15
15
|
default: "gpt-5-mini",
|
|
16
16
|
fast: "gpt-5.4-nano"
|
|
17
|
-
},
|
|
17
|
+
}, T = {
|
|
18
18
|
default: "text-embedding-ada-002"
|
|
19
19
|
}, M = /* @__PURE__ */ new Map();
|
|
20
20
|
let E = null;
|
|
21
21
|
const fe = () => {
|
|
22
|
-
const
|
|
23
|
-
if (!
|
|
22
|
+
const t = I.getDefault().helperServices;
|
|
23
|
+
if (!t?.aiModels?.url)
|
|
24
24
|
throw new Error("AI Models Service URL is not defined in the portal's helper services.");
|
|
25
|
-
return
|
|
26
|
-
}, z = async (
|
|
27
|
-
const
|
|
25
|
+
return t.aiModels.url;
|
|
26
|
+
}, z = async (e) => {
|
|
27
|
+
const t = fe();
|
|
28
28
|
M.size === 0 && (E || (E = (async () => {
|
|
29
29
|
try {
|
|
30
|
-
const n = await fetch(`${
|
|
30
|
+
const n = await fetch(`${t}/models`);
|
|
31
31
|
if (!n.ok)
|
|
32
32
|
throw new Error("Failed to fetch AI service discovery data.");
|
|
33
33
|
(await n.json()).models.forEach((a) => M.set(a.name, a));
|
|
@@ -35,88 +35,97 @@ const fe = () => {
|
|
|
35
35
|
throw E = null, n;
|
|
36
36
|
}
|
|
37
37
|
})()), await E);
|
|
38
|
-
const r = M.get(
|
|
38
|
+
const r = M.get(e);
|
|
39
39
|
if (!r)
|
|
40
|
-
throw new Error(`Model '${
|
|
40
|
+
throw new Error(`Model '${e}' is not available in the discovery service.`);
|
|
41
41
|
return r.endpoint;
|
|
42
|
-
}, ye = async (
|
|
43
|
-
const
|
|
42
|
+
}, ye = async (e = "default") => await z(V[e]), G = async (e = "default") => await z(T[e]), we = async (e) => {
|
|
43
|
+
const t = await ve(), r = await G("default"), n = I.getDefault(), a = (await R.getCredential(`${n.url}/sharing`)).token, i = {
|
|
44
44
|
type: "generateEmbeddings",
|
|
45
|
-
webmapEmbeddings:
|
|
45
|
+
webmapEmbeddings: e,
|
|
46
46
|
auth: { apiUrl: r, token: a }
|
|
47
47
|
};
|
|
48
|
-
return
|
|
49
|
-
const d = (
|
|
50
|
-
|
|
51
|
-
},
|
|
52
|
-
|
|
48
|
+
return t.postMessage(i), await new Promise((c, o) => {
|
|
49
|
+
const d = (m) => {
|
|
50
|
+
m.data === "completed" && (t.removeEventListener("message", d), c());
|
|
51
|
+
}, u = (m) => {
|
|
52
|
+
t.removeEventListener("message", d), o(m instanceof Error ? m : new Error("Embeddings worker error"));
|
|
53
53
|
};
|
|
54
|
-
|
|
55
|
-
}),
|
|
54
|
+
t.addEventListener("message", d), t.addEventListener("error", u, { once: !0 });
|
|
55
|
+
}), t;
|
|
56
56
|
}, ve = async () => {
|
|
57
57
|
{
|
|
58
|
-
const
|
|
59
|
-
return new
|
|
58
|
+
const e = (await import("./embeddings.worker-GH7zdYqF.js")).default;
|
|
59
|
+
return new e();
|
|
60
60
|
}
|
|
61
|
-
},
|
|
62
|
-
...
|
|
63
|
-
...
|
|
64
|
-
}),
|
|
65
|
-
agentExecutionContext:
|
|
61
|
+
}, L = (e, t) => t, xe = (e, t) => ({
|
|
62
|
+
...e,
|
|
63
|
+
...t
|
|
64
|
+
}), be = x.Root({
|
|
65
|
+
agentExecutionContext: x({
|
|
66
66
|
default: () => ({
|
|
67
67
|
userRequest: "",
|
|
68
68
|
assignedTask: "",
|
|
69
69
|
priorSteps: [],
|
|
70
70
|
messages: []
|
|
71
71
|
}),
|
|
72
|
-
reducer:
|
|
72
|
+
reducer: xe
|
|
73
73
|
}),
|
|
74
|
-
currentIntent:
|
|
74
|
+
currentIntent: x({
|
|
75
75
|
default: () => "none",
|
|
76
|
-
reducer:
|
|
76
|
+
reducer: L
|
|
77
77
|
}),
|
|
78
|
-
requiresFollowUp:
|
|
78
|
+
requiresFollowUp: x({
|
|
79
79
|
default: () => !0,
|
|
80
|
-
reducer:
|
|
80
|
+
reducer: L
|
|
81
81
|
}),
|
|
82
|
-
stepCount:
|
|
82
|
+
stepCount: x({
|
|
83
83
|
default: () => 0,
|
|
84
|
-
reducer: (
|
|
84
|
+
reducer: (e, t) => t ?? e + 1
|
|
85
85
|
})
|
|
86
|
-
}),
|
|
87
|
-
await
|
|
88
|
-
},
|
|
89
|
-
await
|
|
90
|
-
}, Ee = (
|
|
91
|
-
|
|
92
|
-
}, Ie = async (
|
|
93
|
-
if (
|
|
94
|
-
const n = new W(
|
|
95
|
-
|
|
86
|
+
}), f = async (e, t) => {
|
|
87
|
+
await j("trace_message", e, t);
|
|
88
|
+
}, gt = async (e, t) => {
|
|
89
|
+
await j("graph_ux_suggestion", e, t);
|
|
90
|
+
}, Ee = (e) => {
|
|
91
|
+
e.currentIntent = "none";
|
|
92
|
+
}, Ie = async (e, t) => {
|
|
93
|
+
if (e.agentExecutionContext.userRequest) {
|
|
94
|
+
const n = new W(e.agentExecutionContext.userRequest.trim());
|
|
95
|
+
e.agentExecutionContext.messages = [...e.agentExecutionContext.messages, n], Ee(e);
|
|
96
96
|
}
|
|
97
|
-
const r =
|
|
98
|
-
return await
|
|
99
|
-
}, Se = async (
|
|
100
|
-
if (typeof
|
|
97
|
+
const r = t?.configurable?.services.agentRegistry.list().map((n) => n.agent.id) ?? [];
|
|
98
|
+
return await f({ text: `Available agents: ${[...r].join(", ")}` }, t), await f({ text: "Analyzing user input" }, t), e;
|
|
99
|
+
}, Se = async (e, t) => (await f({ text: "Exiting..." }, t), e), $ = 4e3, q = (e) => {
|
|
100
|
+
if (typeof e != "string")
|
|
101
101
|
return;
|
|
102
|
-
const
|
|
103
|
-
return
|
|
104
|
-
}, Me = (
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
const t = e.trim();
|
|
103
|
+
return t || void 0;
|
|
104
|
+
}, Me = (e) => {
|
|
105
|
+
switch (e) {
|
|
106
|
+
case "failed":
|
|
107
|
+
return "Agent failed without a summary.";
|
|
108
|
+
case "unknown":
|
|
109
|
+
return "Agent returned with unknown status.";
|
|
110
|
+
case "success":
|
|
111
|
+
return "Agent completed without a summary.";
|
|
112
|
+
default:
|
|
113
|
+
return "Agent completed without a summary.";
|
|
114
|
+
}
|
|
115
|
+
}, Re = (e, t) => {
|
|
116
|
+
const r = q(t?.outputMessage), n = q(t?.summary), s = t?.status ?? "unknown";
|
|
117
|
+
return s === "unknown" && console.warn(`Registered agent "${e}" returned an invalid or missing status.`), {
|
|
109
118
|
outputMessage: r,
|
|
110
|
-
summary: n ?? r ??
|
|
119
|
+
summary: n ?? r ?? Me(s),
|
|
111
120
|
status: s
|
|
112
121
|
};
|
|
113
|
-
},
|
|
114
|
-
const r =
|
|
122
|
+
}, ke = async (e, t) => {
|
|
123
|
+
const r = t?.configurable, { agentRegistry: n } = r.services, s = n?.get(e.currentIntent);
|
|
115
124
|
if (!s)
|
|
116
|
-
return console.warn(`No agent found for intent: ${
|
|
117
|
-
await
|
|
125
|
+
return console.warn(`No agent found for intent: ${e.currentIntent}`), e;
|
|
126
|
+
await f({ text: `Executing registered agent: ${s.agent.name}` }, t);
|
|
118
127
|
const a = {
|
|
119
|
-
...
|
|
128
|
+
...t ?? {},
|
|
120
129
|
configurable: {
|
|
121
130
|
...r ?? {},
|
|
122
131
|
agentId: s.agent.id,
|
|
@@ -128,80 +137,81 @@ const fe = () => {
|
|
|
128
137
|
const d = await s.agent.createGraph().compile().invoke(
|
|
129
138
|
{
|
|
130
139
|
agentExecutionContext: {
|
|
131
|
-
...
|
|
132
|
-
messages: [...
|
|
133
|
-
priorSteps: [...
|
|
140
|
+
...e.agentExecutionContext,
|
|
141
|
+
messages: [...e.agentExecutionContext.messages],
|
|
142
|
+
priorSteps: [...e.agentExecutionContext.priorSteps ?? []]
|
|
134
143
|
}
|
|
135
144
|
},
|
|
136
145
|
a
|
|
137
146
|
);
|
|
138
|
-
i =
|
|
147
|
+
i = Re(s.agent.name, d), await f({ text: `Finished executing registered agent: ${s.agent.name}` }, t);
|
|
139
148
|
} catch (d) {
|
|
140
149
|
if (ne(d))
|
|
141
150
|
throw d;
|
|
142
|
-
const
|
|
143
|
-
console.error(`Agent "${s.agent.name}" failed:`, d), await
|
|
151
|
+
const u = d instanceof Error ? d.message : String(d);
|
|
152
|
+
console.error(`Agent "${s.agent.name}" failed:`, d), await f({ text: `Registered agent failed: ${s.agent.name}. ${u}` }, t), i = {
|
|
144
153
|
status: "failed",
|
|
145
|
-
outputMessage: `Agent execution failed: ${
|
|
146
|
-
summary: `Agent execution failed: ${
|
|
154
|
+
outputMessage: `Agent execution failed: ${u}`,
|
|
155
|
+
summary: `Agent execution failed: ${u}`
|
|
147
156
|
};
|
|
148
157
|
}
|
|
149
|
-
const c = i.outputMessage, o = [...
|
|
158
|
+
const c = i.outputMessage, o = [...e.agentExecutionContext.messages];
|
|
150
159
|
if (c) {
|
|
151
|
-
const d = c.length >
|
|
160
|
+
const d = c.length > $ ? `${c.slice(0, $ - 14)}
|
|
152
161
|
[truncated]` : c;
|
|
153
|
-
o.push(new
|
|
162
|
+
o.push(new k(d));
|
|
154
163
|
}
|
|
155
164
|
return {
|
|
156
|
-
...
|
|
157
|
-
stepCount:
|
|
165
|
+
...e,
|
|
166
|
+
stepCount: e.stepCount + 1,
|
|
167
|
+
requiresFollowUp: i.status === "failed" ? !0 : e.requiresFollowUp,
|
|
158
168
|
agentExecutionContext: {
|
|
159
|
-
...
|
|
169
|
+
...e.agentExecutionContext,
|
|
160
170
|
messages: o,
|
|
161
171
|
priorSteps: [
|
|
162
|
-
...
|
|
172
|
+
...e.agentExecutionContext.priorSteps ?? [],
|
|
163
173
|
{
|
|
164
174
|
agentId: s.agent.id,
|
|
165
|
-
assignedTask:
|
|
166
|
-
summary: i.
|
|
175
|
+
assignedTask: e.agentExecutionContext.assignedTask,
|
|
176
|
+
summary: i?.summary || "No summary provided.",
|
|
167
177
|
status: i.status
|
|
168
178
|
}
|
|
169
179
|
]
|
|
170
180
|
}
|
|
171
181
|
};
|
|
172
|
-
},
|
|
173
|
-
const n = t
|
|
182
|
+
}, Te = (e, t, r) => {
|
|
183
|
+
const n = e[t];
|
|
174
184
|
return n ? typeof n == "function" ? n() : Promise.resolve(n) : new Promise((s, a) => {
|
|
175
|
-
(typeof queueMicrotask == "function" ? queueMicrotask : setTimeout)(a.bind(null, /* @__PURE__ */ new Error("Unknown variable dynamic import: " +
|
|
185
|
+
(typeof queueMicrotask == "function" ? queueMicrotask : setTimeout)(a.bind(null, /* @__PURE__ */ new Error("Unknown variable dynamic import: " + t + (t.split("/").length !== r ? ". Note that variables only represent file names one level deep." : ""))));
|
|
176
186
|
});
|
|
177
|
-
},
|
|
178
|
-
const { agent:
|
|
179
|
-
return { structuredResponse: (await
|
|
187
|
+
}, C = async (e) => (await Te(/* @__PURE__ */ Object.assign({ "./field_descriptions_prompt.md": () => import("./field_descriptions_prompt-haMV_aoG.js"), "./intent_prompt.md": () => import("./intent_prompt-BSRo2YLj.js"), "./layer_descriptions_prompt.md": () => import("./layer_descriptions_prompt-NAaKWdJi.js") }), `./${e}.md`, 2)).default, Ce = async (e) => {
|
|
188
|
+
const { agent: t, messages: r, config: n } = e;
|
|
189
|
+
return { structuredResponse: (await t.invoke(
|
|
180
190
|
{
|
|
181
191
|
messages: r
|
|
182
192
|
},
|
|
183
193
|
n
|
|
184
194
|
)).structuredResponse };
|
|
185
|
-
}, K = (
|
|
195
|
+
}, K = (e) => async (t, r) => {
|
|
186
196
|
const n = new Headers(r?.headers);
|
|
187
|
-
return n.delete("Authorization"), n.delete("api-key"),
|
|
197
|
+
return n.delete("Authorization"), n.delete("api-key"), e && e.length > 0 && (n.set("X-Esri-Authorization", `Bearer ${e}`), n.set("X-Esri-Request-Source", "MapsSDK")), await fetch(t, {
|
|
188
198
|
...r,
|
|
189
199
|
headers: n
|
|
190
200
|
});
|
|
191
|
-
},
|
|
192
|
-
const r = I.getDefault(), n = await R.getCredential(`${r.url}/sharing`), s = V[
|
|
193
|
-
return new
|
|
201
|
+
}, b = async (e = "default", t = 0) => {
|
|
202
|
+
const r = I.getDefault(), n = await R.getCredential(`${r.url}/sharing`), s = V[e], a = await ye(e);
|
|
203
|
+
return new ge({
|
|
194
204
|
modelName: s,
|
|
195
205
|
apiKey: "dummy-key",
|
|
196
206
|
// 5-mini does not support temperature parameter
|
|
197
|
-
...
|
|
207
|
+
...e !== "default" && { temperature: t },
|
|
198
208
|
configuration: {
|
|
199
209
|
baseURL: a,
|
|
200
210
|
fetch: K(n.token)
|
|
201
211
|
}
|
|
202
212
|
});
|
|
203
|
-
},
|
|
204
|
-
const
|
|
213
|
+
}, Ae = async (e = "default") => {
|
|
214
|
+
const t = I.getDefault(), r = await R.getCredential(`${t.url}/sharing`), n = T[e], s = await G(e);
|
|
205
215
|
return new pe({
|
|
206
216
|
modelName: n,
|
|
207
217
|
apiKey: "dummy-key",
|
|
@@ -218,116 +228,138 @@ const fe = () => {
|
|
|
218
228
|
description: l.string().min(1)
|
|
219
229
|
});
|
|
220
230
|
l.array(Fe);
|
|
221
|
-
const
|
|
222
|
-
const
|
|
231
|
+
const U = (e) => JSON.stringify(e, null, 2), De = (e) => {
|
|
232
|
+
const t = e.map((n) => n.id), r = l.enum(t);
|
|
223
233
|
return l.object({
|
|
224
234
|
intent: r.nullable(),
|
|
225
235
|
assignedTask: l.string().nullable(),
|
|
226
236
|
requiresFollowUp: l.boolean()
|
|
227
237
|
});
|
|
228
|
-
},
|
|
238
|
+
}, Le = async (e, t) => {
|
|
229
239
|
try {
|
|
230
|
-
await
|
|
231
|
-
const s = (
|
|
240
|
+
await f({ text: "Asking LLM to route to an agent" }, t);
|
|
241
|
+
const s = (t?.configurable?.services.agentRegistry?.list() ?? []).map(({ agent: v }) => ({
|
|
232
242
|
id: v.id,
|
|
233
243
|
name: v.name,
|
|
234
244
|
description: v.description
|
|
235
245
|
}));
|
|
236
246
|
if (!s.length)
|
|
237
|
-
return await
|
|
238
|
-
const a = await
|
|
239
|
-
`), c = Le(s), o = {
|
|
247
|
+
return await f({ text: "No agents registered; skipping intent detection" }, t), { ...e, currentIntent: "none" };
|
|
248
|
+
const a = await C("intent_prompt"), i = U(s), c = De(s), o = {
|
|
240
249
|
registeredAgents: i,
|
|
241
|
-
priorSteps:
|
|
242
|
-
userRequest:
|
|
243
|
-
},
|
|
244
|
-
model: await
|
|
250
|
+
priorSteps: U(e.agentExecutionContext.priorSteps),
|
|
251
|
+
userRequest: e.agentExecutionContext.userRequest
|
|
252
|
+
}, u = await N.fromTemplate(a).format(o), m = le({
|
|
253
|
+
model: await b("fast"),
|
|
245
254
|
tools: [],
|
|
246
|
-
systemPrompt:
|
|
255
|
+
systemPrompt: u,
|
|
247
256
|
checkpointer: !0,
|
|
248
257
|
responseFormat: c,
|
|
249
258
|
middleware: [
|
|
250
259
|
// Preserve recent conversation context while summarizing older messages
|
|
251
260
|
// to control token usage without losing important intent signals.
|
|
252
261
|
// The trigger and keep parameters can be tuned based on token limits and behavior.
|
|
253
|
-
|
|
254
|
-
model: await
|
|
262
|
+
ue({
|
|
263
|
+
model: await b("fast"),
|
|
255
264
|
trigger: { tokens: 4e3 },
|
|
256
265
|
keep: { messages: 6 }
|
|
257
266
|
}),
|
|
258
267
|
// Enforce no loop/retry.
|
|
259
268
|
// 1 usual LLM call and 1 optional summarization call.
|
|
260
|
-
|
|
269
|
+
me({ runLimit: 2 })
|
|
261
270
|
]
|
|
262
271
|
}), { structuredResponse: y } = await Ce({
|
|
263
|
-
agent:
|
|
264
|
-
messages:
|
|
265
|
-
config:
|
|
266
|
-
}),
|
|
272
|
+
agent: m,
|
|
273
|
+
messages: e.agentExecutionContext.messages,
|
|
274
|
+
config: t
|
|
275
|
+
}), p = c.parse(
|
|
267
276
|
y ?? { intent: null, assignedTask: null, requiresFollowUp: !1 }
|
|
268
|
-
),
|
|
269
|
-
...
|
|
270
|
-
currentIntent:
|
|
271
|
-
requiresFollowUp:
|
|
277
|
+
), g = p.intent ?? "none", S = {
|
|
278
|
+
...e,
|
|
279
|
+
currentIntent: g,
|
|
280
|
+
requiresFollowUp: p.requiresFollowUp,
|
|
272
281
|
agentExecutionContext: {
|
|
273
|
-
...
|
|
274
|
-
assignedTask:
|
|
282
|
+
...e.agentExecutionContext,
|
|
283
|
+
assignedTask: p.assignedTask ?? ""
|
|
275
284
|
}
|
|
276
285
|
};
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
286
|
+
if (g === "none") {
|
|
287
|
+
const v = "I could not find a matching agent for that request. Please rephrase your question with more detail.";
|
|
288
|
+
return await f({ text: "LLM did not identify a clear intent." }, t), {
|
|
289
|
+
...e,
|
|
290
|
+
currentIntent: g,
|
|
291
|
+
requiresFollowUp: !1,
|
|
292
|
+
agentExecutionContext: {
|
|
293
|
+
...e.agentExecutionContext,
|
|
294
|
+
assignedTask: "",
|
|
295
|
+
messages: [...e.agentExecutionContext.messages, new k(v)],
|
|
296
|
+
priorSteps: [
|
|
297
|
+
...e.agentExecutionContext.priorSteps ?? [],
|
|
298
|
+
{
|
|
299
|
+
agentId: "no-intent-router",
|
|
300
|
+
assignedTask: e.agentExecutionContext.userRequest,
|
|
301
|
+
summary: "No matching agent found; asked user to rephrase.",
|
|
302
|
+
status: "success"
|
|
303
|
+
}
|
|
304
|
+
]
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
return await f(
|
|
309
|
+
{
|
|
310
|
+
text: `Agent picked: ${g}
|
|
311
|
+
Task Assigned: ${p.assignedTask ?? ""}
|
|
312
|
+
Requires Follow-Up: ${p.requiresFollowUp}`
|
|
313
|
+
},
|
|
314
|
+
t
|
|
281
315
|
), S;
|
|
282
316
|
} catch (r) {
|
|
283
|
-
throw await
|
|
317
|
+
throw await f({ text: "Error during intent detection" }, t), new Error(`Error during intent detection: ${r instanceof Error ? r.message : String(r)}`);
|
|
284
318
|
}
|
|
285
|
-
},
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}), !e.requiresFollowUp || e.stepCount >= _ ? "exit" : "intentLLM")).addEdge("exit", ie);
|
|
291
|
-
class je {
|
|
319
|
+
}, $e = 3, qe = () => new re(be).addNode("ingestInput", Ie).addNode("intentLLM", Le).addNode("executeRegisteredAgent", ke).addNode("exit", Se).addEdge(se, "ingestInput").addEdge("ingestInput", "intentLLM").addConditionalEdges("intentLLM", (t) => t.currentIntent === "none" ? "exit" : "executeRegisteredAgent").addConditionalEdges(
|
|
320
|
+
"executeRegisteredAgent",
|
|
321
|
+
(t) => t.stepCount >= $e || !t.requiresFollowUp ? "exit" : "intentLLM"
|
|
322
|
+
).addEdge("exit", ie);
|
|
323
|
+
class Ue {
|
|
292
324
|
constructor() {
|
|
293
325
|
this.agentRegistry = /* @__PURE__ */ new Map();
|
|
294
326
|
}
|
|
295
|
-
register(
|
|
296
|
-
const { agent: r } =
|
|
327
|
+
register(t) {
|
|
328
|
+
const { agent: r } = t;
|
|
297
329
|
if (this.agentRegistry.has(r.id))
|
|
298
330
|
throw new Error(`Duplicate agent id: ${r.id}`);
|
|
299
|
-
this.agentRegistry.set(r.id,
|
|
331
|
+
this.agentRegistry.set(r.id, t);
|
|
300
332
|
}
|
|
301
|
-
get(
|
|
302
|
-
return this.agentRegistry.get(
|
|
333
|
+
get(t) {
|
|
334
|
+
return this.agentRegistry.get(t);
|
|
303
335
|
}
|
|
304
336
|
list() {
|
|
305
337
|
return [...this.agentRegistry.values()];
|
|
306
338
|
}
|
|
307
339
|
}
|
|
308
|
-
class
|
|
340
|
+
class _e {
|
|
309
341
|
/**
|
|
310
342
|
* Create a new InterruptHandler tied to a specific compiled graph and config.
|
|
311
343
|
*/
|
|
312
|
-
constructor(
|
|
313
|
-
this.graph =
|
|
344
|
+
constructor(t, r) {
|
|
345
|
+
this.graph = t, this.config = { ...r };
|
|
314
346
|
}
|
|
315
347
|
/**
|
|
316
348
|
* Returns a promise that resolves when the user provides a HITL response.
|
|
317
349
|
*/
|
|
318
350
|
async waitForUser() {
|
|
319
|
-
return await new Promise((
|
|
320
|
-
this.resolveWait =
|
|
351
|
+
return await new Promise((t, r) => {
|
|
352
|
+
this.resolveWait = t, this.rejectWait = r;
|
|
321
353
|
});
|
|
322
354
|
}
|
|
323
355
|
/**
|
|
324
356
|
* Resume graph execution after the UI responds to an interrupt.
|
|
325
357
|
*/
|
|
326
|
-
handle(
|
|
358
|
+
handle(t, r) {
|
|
327
359
|
try {
|
|
328
360
|
const n = {
|
|
329
|
-
agentId:
|
|
330
|
-
id:
|
|
361
|
+
agentId: t.agentId,
|
|
362
|
+
id: t.id,
|
|
331
363
|
payload: r
|
|
332
364
|
}, s = this.graph.streamEvents(null, {
|
|
333
365
|
...this.config,
|
|
@@ -352,32 +384,32 @@ class Ue {
|
|
|
352
384
|
this.rejectWait && (this.rejectWait(new Error("Request cancelled by user.")), this.resolveWait = void 0, this.rejectWait = void 0);
|
|
353
385
|
}
|
|
354
386
|
}
|
|
355
|
-
const
|
|
356
|
-
let
|
|
357
|
-
for (let r =
|
|
358
|
-
if (
|
|
359
|
-
|
|
387
|
+
const Pe = (e) => {
|
|
388
|
+
let t = -1;
|
|
389
|
+
for (let r = e.length - 1; r >= 0; r--)
|
|
390
|
+
if (e[r] instanceof W) {
|
|
391
|
+
t = r;
|
|
360
392
|
break;
|
|
361
393
|
}
|
|
362
|
-
return
|
|
394
|
+
return t === -1 ? "" : e.slice(t + 1).filter((r) => r instanceof k).map((r) => r.content).join(`
|
|
363
395
|
`);
|
|
364
|
-
}, B = async (
|
|
396
|
+
}, B = async (e) => {
|
|
365
397
|
try {
|
|
366
|
-
return await (await
|
|
367
|
-
} catch (
|
|
368
|
-
throw console.error("Failed to generate embeddings:",
|
|
398
|
+
return await (await Ae()).embedDocuments(e);
|
|
399
|
+
} catch (t) {
|
|
400
|
+
throw console.error("Failed to generate embeddings:", t), t;
|
|
369
401
|
}
|
|
370
|
-
}, J = async (
|
|
371
|
-
const r =
|
|
402
|
+
}, J = async (e, t) => {
|
|
403
|
+
const r = t.get(e);
|
|
372
404
|
if (r)
|
|
373
405
|
return r;
|
|
374
|
-
const n = await B([
|
|
375
|
-
return
|
|
406
|
+
const n = await B([e]);
|
|
407
|
+
return t.set(e, n[0]), n[0];
|
|
376
408
|
};
|
|
377
|
-
async function
|
|
409
|
+
async function We(e, t, r, n) {
|
|
378
410
|
const s = `req-${Date.now()}`, i = {
|
|
379
411
|
type: "layerSearch",
|
|
380
|
-
precomputedEmbedding: n ? await J(
|
|
412
|
+
precomputedEmbedding: n ? await J(e, n) : void 0,
|
|
381
413
|
requestId: s,
|
|
382
414
|
minScore: r
|
|
383
415
|
};
|
|
@@ -385,58 +417,58 @@ async function Pe(t, e, r, n) {
|
|
|
385
417
|
const o = (d) => {
|
|
386
418
|
d.data.requestId === s && c(d.data.results);
|
|
387
419
|
};
|
|
388
|
-
|
|
420
|
+
t.addEventListener("message", o, { once: !0 }), t.postMessage(i);
|
|
389
421
|
});
|
|
390
422
|
}
|
|
391
|
-
function
|
|
392
|
-
const { worker:
|
|
423
|
+
function je(e) {
|
|
424
|
+
const { worker: t } = e;
|
|
393
425
|
return {
|
|
394
426
|
async searchLayers({
|
|
395
427
|
text: r,
|
|
396
428
|
minScore: n,
|
|
397
429
|
embeddingCache: s
|
|
398
430
|
}) {
|
|
399
|
-
return await
|
|
431
|
+
return await We(r, t, n, s);
|
|
400
432
|
}
|
|
401
433
|
};
|
|
402
434
|
}
|
|
403
435
|
const Ne = async ({
|
|
404
|
-
combinedQuery:
|
|
405
|
-
layerIds:
|
|
436
|
+
combinedQuery: e,
|
|
437
|
+
layerIds: t,
|
|
406
438
|
embeddingsWorker: r,
|
|
407
439
|
minScore: n,
|
|
408
440
|
topResults: s,
|
|
409
441
|
embeddingCache: a
|
|
410
442
|
}) => {
|
|
411
|
-
const i = `req-${Date.now()}`, c = a ? await J(
|
|
443
|
+
const i = `req-${Date.now()}`, c = a ? await J(e, a) : void 0, o = {
|
|
412
444
|
type: "fieldSearch",
|
|
413
|
-
layerIdForFieldsSearch:
|
|
445
|
+
layerIdForFieldsSearch: t,
|
|
414
446
|
precomputedEmbedding: c,
|
|
415
447
|
requestId: i,
|
|
416
448
|
minScore: n,
|
|
417
449
|
topResults: s
|
|
418
450
|
};
|
|
419
451
|
return await new Promise((d) => {
|
|
420
|
-
const
|
|
421
|
-
if (
|
|
452
|
+
const u = (m) => {
|
|
453
|
+
if (m.data.requestId !== i)
|
|
422
454
|
return;
|
|
423
|
-
const y =
|
|
424
|
-
layerId:
|
|
425
|
-
results:
|
|
455
|
+
const y = m.data.results.map(({ layerId: p, results: g }) => ({
|
|
456
|
+
layerId: p,
|
|
457
|
+
results: g
|
|
426
458
|
}));
|
|
427
459
|
d(y);
|
|
428
460
|
};
|
|
429
|
-
r.addEventListener("message",
|
|
461
|
+
r.addEventListener("message", u, { once: !0 }), r.postMessage(o);
|
|
430
462
|
});
|
|
431
463
|
};
|
|
432
|
-
function He(
|
|
433
|
-
const { worker:
|
|
464
|
+
function He(e) {
|
|
465
|
+
const { worker: t } = e;
|
|
434
466
|
return {
|
|
435
467
|
async searchFields({ text: r, layerIds: n, minScore: s, topResults: a, embeddingCache: i }) {
|
|
436
468
|
return await Ne({
|
|
437
469
|
combinedQuery: r,
|
|
438
470
|
layerIds: n,
|
|
439
|
-
embeddingsWorker:
|
|
471
|
+
embeddingsWorker: t,
|
|
440
472
|
minScore: s,
|
|
441
473
|
topResults: a,
|
|
442
474
|
embeddingCache: i
|
|
@@ -444,9 +476,9 @@ function He(t) {
|
|
|
444
476
|
}
|
|
445
477
|
};
|
|
446
478
|
}
|
|
447
|
-
const X = "0.1", w = 1536, Q = "openai", Y =
|
|
479
|
+
const X = "0.1", w = 1536, Q = "openai", Y = T.default, A = `Name: {name}
|
|
448
480
|
Title: {title}
|
|
449
|
-
Description: {description}`,
|
|
481
|
+
Description: {description}`, F = `Name: {name}
|
|
450
482
|
Alias: {alias}
|
|
451
483
|
Description: {description}`, Z = l.object({
|
|
452
484
|
schemaVersion: l.literal(X),
|
|
@@ -457,7 +489,7 @@ Description: {description}`, Z = l.object({
|
|
|
457
489
|
dimensions: l.literal(w),
|
|
458
490
|
templates: l.object({
|
|
459
491
|
layer: l.string().default(A),
|
|
460
|
-
field: l.string().default(
|
|
492
|
+
field: l.string().default(F)
|
|
461
493
|
})
|
|
462
494
|
}),
|
|
463
495
|
layers: l.array(
|
|
@@ -481,18 +513,18 @@ Description: {description}`, Z = l.object({
|
|
|
481
513
|
)
|
|
482
514
|
})
|
|
483
515
|
).default([])
|
|
484
|
-
}), Oe = (
|
|
485
|
-
const
|
|
486
|
-
if (!
|
|
516
|
+
}), Oe = (e) => {
|
|
517
|
+
const t = Z.safeParse(e);
|
|
518
|
+
if (!t.success)
|
|
487
519
|
throw new Error("Embeddings response validation failed. Regenerate embeddings.");
|
|
488
|
-
return
|
|
489
|
-
}, Ve = (
|
|
520
|
+
return t.data;
|
|
521
|
+
}, Ve = (e, t) => {
|
|
490
522
|
const r = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
|
|
491
|
-
if (
|
|
523
|
+
if (t.allLayers.forEach((s) => {
|
|
492
524
|
s instanceof O && n.set(s.id, s);
|
|
493
|
-
}),
|
|
525
|
+
}), e.length !== n.size)
|
|
494
526
|
throw new Error("Layer count mismatch during registry restoration. Regenerate embeddings.");
|
|
495
|
-
for (const s of
|
|
527
|
+
for (const s of e) {
|
|
496
528
|
const a = n.get(s.id);
|
|
497
529
|
if (!a)
|
|
498
530
|
throw new Error(
|
|
@@ -528,19 +560,19 @@ Description: {description}`, Z = l.object({
|
|
|
528
560
|
});
|
|
529
561
|
}
|
|
530
562
|
return r;
|
|
531
|
-
}, ze = async (
|
|
563
|
+
}, ze = async (e) => {
|
|
532
564
|
try {
|
|
533
|
-
return (await he(
|
|
565
|
+
return (await he(e, {
|
|
534
566
|
responseType: "json"
|
|
535
567
|
})).data;
|
|
536
|
-
} catch (
|
|
537
|
-
throw new Error(`Failed to fetch data from ${
|
|
568
|
+
} catch (t) {
|
|
569
|
+
throw new Error(`Failed to fetch data from ${e}: ${String(t)}`);
|
|
538
570
|
}
|
|
539
|
-
}, Ge = async (
|
|
540
|
-
const
|
|
541
|
-
if (!
|
|
571
|
+
}, Ge = async (e) => {
|
|
572
|
+
const t = e.map;
|
|
573
|
+
if (!t?.portalItem)
|
|
542
574
|
throw new Error("WebMap portal item is missing.");
|
|
543
|
-
const { resources: r } = await
|
|
575
|
+
const { resources: r } = await t.portalItem.fetchResources(), n = r.find((i) => i.resource.path === "embeddings-v01.json");
|
|
544
576
|
if (!n?.resource.url)
|
|
545
577
|
throw new Error("Embeddings resource 'embeddings-v01.json' not found in the webmap portal item.");
|
|
546
578
|
const s = await ze(n.resource.url);
|
|
@@ -548,25 +580,25 @@ Description: {description}`, Z = l.object({
|
|
|
548
580
|
};
|
|
549
581
|
class ee {
|
|
550
582
|
constructor() {
|
|
551
|
-
this.orchestratorReady = !1, this.chatHistory = [], this.priorSteps = [], this.threadId = "", this.agentRegistry = new
|
|
583
|
+
this.orchestratorReady = !1, this.chatHistory = [], this.priorSteps = [], this.threadId = "", this.agentRegistry = new Ue(), this.streamEpoch = 0;
|
|
552
584
|
}
|
|
553
585
|
/**
|
|
554
586
|
* Creates and returns an AI-ready Orchestrator instance.
|
|
555
587
|
* @param deps Core dependencies (layer/field registry plus optional map views).
|
|
556
588
|
* @returns Ready Orchestrator.
|
|
557
589
|
*/
|
|
558
|
-
static async init(
|
|
590
|
+
static async init(t) {
|
|
559
591
|
const r = new ee();
|
|
560
592
|
try {
|
|
561
|
-
if (
|
|
562
|
-
await H.whenOnce(() =>
|
|
563
|
-
const n = await Ge(
|
|
593
|
+
if (t.view?.map) {
|
|
594
|
+
await H.whenOnce(() => t.view.ready);
|
|
595
|
+
const n = await Ge(t.view), s = Ve(
|
|
564
596
|
n.layers,
|
|
565
|
-
|
|
597
|
+
t.view.map
|
|
566
598
|
);
|
|
567
599
|
r.layersAndFieldsRegistry = s, r.embeddingsWorker = await we(n);
|
|
568
600
|
}
|
|
569
|
-
return
|
|
601
|
+
return t.agents?.forEach((n) => {
|
|
570
602
|
r.agentRegistry.register(n);
|
|
571
603
|
}), r.orchestratorReady = !0, r;
|
|
572
604
|
} catch (n) {
|
|
@@ -581,15 +613,15 @@ class ee {
|
|
|
581
613
|
* - `completed`: final result with chat history + layer styling
|
|
582
614
|
* - `cancelled`: user aborted the run
|
|
583
615
|
*/
|
|
584
|
-
async *ask(
|
|
616
|
+
async *ask(t) {
|
|
585
617
|
if (!this.orchestratorReady)
|
|
586
618
|
throw new Error("Orchestrator is not ready yet.");
|
|
587
619
|
if (!this.agentRegistry.list().length)
|
|
588
620
|
throw new Error("Orchestrator has no registered agents.");
|
|
589
|
-
if (++this.streamEpoch, !
|
|
621
|
+
if (++this.streamEpoch, !t.trim())
|
|
590
622
|
return;
|
|
591
|
-
this.threadId = String(Date.now()), this.graph || (this.graph =
|
|
592
|
-
const r = this.embeddingsWorker ?
|
|
623
|
+
this.threadId = String(Date.now()), this.graph || (this.graph = qe().compile({ checkpointer: new ae() }));
|
|
624
|
+
const r = this.embeddingsWorker ? je({ worker: this.embeddingsWorker }) : void 0, n = this.embeddingsWorker ? He({ worker: this.embeddingsWorker }) : void 0, s = /* @__PURE__ */ new Map(), i = {
|
|
593
625
|
version: "v2",
|
|
594
626
|
streamMode: "custom",
|
|
595
627
|
configurable: {
|
|
@@ -606,24 +638,24 @@ class ee {
|
|
|
606
638
|
},
|
|
607
639
|
subgraphs: !0
|
|
608
640
|
}, c = this.graph?.streamEvents(
|
|
609
|
-
{ agentExecutionContext: { userRequest:
|
|
641
|
+
{ agentExecutionContext: { userRequest: t, messages: this.chatHistory, priorSteps: this.priorSteps } },
|
|
610
642
|
i
|
|
611
643
|
), o = ++this.streamEpoch;
|
|
612
644
|
for (yield* this.pipeStream(c, o); ; ) {
|
|
613
|
-
const
|
|
614
|
-
if (!
|
|
645
|
+
const p = (await this.graph.getState(i, { subgraphs: !0 })).tasks.find((g) => g.interrupts.length > 0)?.interrupts[0]?.value;
|
|
646
|
+
if (!p)
|
|
615
647
|
break;
|
|
616
|
-
this.currentInterrupt =
|
|
648
|
+
this.currentInterrupt = p, this.interruptHandler = new _e(this.graph, i), yield { runId: this.threadId, timestamp: Date.now(), type: "interrupt", interrupt: p };
|
|
617
649
|
try {
|
|
618
|
-
const
|
|
619
|
-
yield* this.pipeStream(
|
|
620
|
-
} catch (
|
|
621
|
-
if (
|
|
650
|
+
const g = await this.interruptHandler.waitForUser(), S = ++this.streamEpoch;
|
|
651
|
+
yield* this.pipeStream(g, S);
|
|
652
|
+
} catch (g) {
|
|
653
|
+
if (g) {
|
|
622
654
|
yield {
|
|
623
655
|
runId: this.threadId,
|
|
624
656
|
timestamp: Date.now(),
|
|
625
657
|
type: "error",
|
|
626
|
-
error: { message:
|
|
658
|
+
error: { message: g?.message }
|
|
627
659
|
};
|
|
628
660
|
return;
|
|
629
661
|
}
|
|
@@ -631,12 +663,12 @@ class ee {
|
|
|
631
663
|
return;
|
|
632
664
|
}
|
|
633
665
|
}
|
|
634
|
-
const
|
|
635
|
-
this.chatHistory =
|
|
666
|
+
const u = (await this.graph.getState(i, { subgraphs: !0 })).values;
|
|
667
|
+
this.chatHistory = u.agentExecutionContext.messages.length ? u.agentExecutionContext.messages : this.chatHistory, this.priorSteps = u.agentExecutionContext.priorSteps?.slice(-5) ?? [], yield {
|
|
636
668
|
runId: this.threadId,
|
|
637
669
|
timestamp: Date.now(),
|
|
638
670
|
type: "completed",
|
|
639
|
-
result: { content:
|
|
671
|
+
result: { content: Pe(u.agentExecutionContext.messages) }
|
|
640
672
|
};
|
|
641
673
|
}
|
|
642
674
|
/**
|
|
@@ -649,10 +681,10 @@ class ee {
|
|
|
649
681
|
* Generic resume for any HITL interrupt.
|
|
650
682
|
* The payload is whatever the UI collected (e.g. "yes", "no", layerId, etc).
|
|
651
683
|
*/
|
|
652
|
-
resumeInterrupt(
|
|
684
|
+
resumeInterrupt(t) {
|
|
653
685
|
if (!this.currentInterrupt || !this.interruptHandler)
|
|
654
686
|
throw new Error("No pending interrupt to resume.");
|
|
655
|
-
this.interruptHandler.handle(this.currentInterrupt,
|
|
687
|
+
this.interruptHandler.handle(this.currentInterrupt, t);
|
|
656
688
|
}
|
|
657
689
|
/**
|
|
658
690
|
* Optional: allow UI to cancel the current HITL.
|
|
@@ -660,8 +692,8 @@ class ee {
|
|
|
660
692
|
cancelInterrupt() {
|
|
661
693
|
this.interruptHandler && this.interruptHandler.cancel();
|
|
662
694
|
}
|
|
663
|
-
async *pipeStream(
|
|
664
|
-
for await (const n of
|
|
695
|
+
async *pipeStream(t, r) {
|
|
696
|
+
for await (const n of t) {
|
|
665
697
|
if (r !== this.streamEpoch) {
|
|
666
698
|
console.log("Stale stream detected, aborting.");
|
|
667
699
|
break;
|
|
@@ -682,31 +714,31 @@ class ee {
|
|
|
682
714
|
this.embeddingsWorker && (this.embeddingsWorker.terminate(), this.embeddingsWorker = void 0), this.orchestratorReady = !1;
|
|
683
715
|
}
|
|
684
716
|
}
|
|
685
|
-
const Ke = (
|
|
686
|
-
const
|
|
687
|
-
for (const n of
|
|
717
|
+
const Ke = (e) => {
|
|
718
|
+
const t = /* @__PURE__ */ new Set();
|
|
719
|
+
for (const n of e)
|
|
688
720
|
if (oe(n)) {
|
|
689
721
|
const s = n;
|
|
690
722
|
s.tool_calls && s.tool_calls.length > 0 && s.tool_calls.forEach((a) => {
|
|
691
|
-
a.id &&
|
|
723
|
+
a.id && t.add(a.id);
|
|
692
724
|
});
|
|
693
725
|
}
|
|
694
|
-
return
|
|
726
|
+
return e.filter((n) => {
|
|
695
727
|
if (ce(n)) {
|
|
696
728
|
const s = n;
|
|
697
|
-
return
|
|
729
|
+
return t.has(s.tool_call_id);
|
|
698
730
|
}
|
|
699
731
|
return !0;
|
|
700
732
|
});
|
|
701
|
-
}, D = (
|
|
702
|
-
const r = de.fromTemplate(
|
|
703
|
-
return N.fromMessages([r, ...
|
|
704
|
-
}, Be = async (
|
|
705
|
-
const { promptText:
|
|
733
|
+
}, D = (e, t) => {
|
|
734
|
+
const r = de.fromTemplate(e);
|
|
735
|
+
return N.fromMessages([r, ...t]);
|
|
736
|
+
}, Be = async (e) => {
|
|
737
|
+
const { promptText: t, modelTier: r, temperature: n, messages: s } = e, a = D(t, s ?? []), i = await b(r, n);
|
|
706
738
|
return a.pipe(i);
|
|
707
|
-
}, pt = async (
|
|
708
|
-
const { promptText:
|
|
709
|
-
promptText:
|
|
739
|
+
}, pt = async (e) => {
|
|
740
|
+
const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables: a } = e, c = await (await Be({
|
|
741
|
+
promptText: t,
|
|
710
742
|
modelTier: r,
|
|
711
743
|
temperature: n,
|
|
712
744
|
messages: s
|
|
@@ -715,75 +747,75 @@ const Ke = (t) => {
|
|
|
715
747
|
return c;
|
|
716
748
|
const o = c.content;
|
|
717
749
|
return typeof o == "string" ? o : JSON.stringify(o);
|
|
718
|
-
}, te = async (
|
|
719
|
-
const { promptText:
|
|
750
|
+
}, te = async (e) => {
|
|
751
|
+
const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables: a, schema: i } = e, c = D(t, s ?? []), d = (await b(r, n)).withStructuredOutput(i);
|
|
720
752
|
return await c.pipe(d).invoke(a ?? {});
|
|
721
|
-
}, ht = async (
|
|
722
|
-
const { promptText:
|
|
753
|
+
}, ht = async (e) => {
|
|
754
|
+
const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables: a, tools: i } = e, c = i.length > 0 ? Ke(s ?? []) : s ?? [], o = D(t, c), d = await b(r, n);
|
|
723
755
|
return await o.pipe(d.bindTools(i)).invoke(a ?? {});
|
|
724
|
-
}, Je =
|
|
725
|
-
name:
|
|
726
|
-
description:
|
|
727
|
-
valueType:
|
|
728
|
-
alias:
|
|
729
|
-
}), Xe =
|
|
730
|
-
fields:
|
|
756
|
+
}, Je = h.object({
|
|
757
|
+
name: h.string(),
|
|
758
|
+
description: h.string(),
|
|
759
|
+
valueType: h.string(),
|
|
760
|
+
alias: h.string()
|
|
761
|
+
}), Xe = h.object({
|
|
762
|
+
fields: h.array(Je)
|
|
731
763
|
});
|
|
732
|
-
function
|
|
764
|
+
function _(e, t) {
|
|
733
765
|
const r = /* @__PURE__ */ new Map();
|
|
734
|
-
for (const n of
|
|
735
|
-
const s =
|
|
766
|
+
for (const n of e.fields) {
|
|
767
|
+
const s = t.fields.find((i) => i.name === n.name), a = {
|
|
736
768
|
name: n.name,
|
|
737
769
|
type: n.type,
|
|
738
770
|
alias: s?.alias ?? n.alias ?? "",
|
|
739
771
|
description: s?.description ?? n.description ?? "",
|
|
740
772
|
valueType: s?.valueType ?? n.valueType ?? "",
|
|
741
|
-
domain:
|
|
773
|
+
domain: e.getFieldDomain(n.name) ?? void 0
|
|
742
774
|
};
|
|
743
775
|
r.set(n.name, a);
|
|
744
776
|
}
|
|
745
777
|
return r;
|
|
746
778
|
}
|
|
747
|
-
const Qe = async (
|
|
748
|
-
const r = await
|
|
749
|
-
const { name: c, type: o, alias: d, description:
|
|
750
|
-
return [`Name: ${c}`, `Type: ${o}`, `Alias: ${d}`, `Description: ${
|
|
779
|
+
const Qe = async (e) => {
|
|
780
|
+
const r = await C("field_descriptions_prompt"), n = e.fields.filter((i) => !(i.alias && i.description)).map((i) => {
|
|
781
|
+
const { name: c, type: o, alias: d, description: u } = i;
|
|
782
|
+
return [`Name: ${c}`, `Type: ${o}`, `Alias: ${d}`, `Description: ${u ?? "N/A"}`].join(", ");
|
|
751
783
|
}).join(`
|
|
752
784
|
`);
|
|
753
785
|
if (n.length === 0)
|
|
754
|
-
return
|
|
786
|
+
return _(e, { fields: [] });
|
|
755
787
|
const s = {
|
|
756
|
-
existingItemTitle:
|
|
757
|
-
existingItemDescription:
|
|
758
|
-
existingLayerTitle:
|
|
759
|
-
existingLayerDescription:
|
|
788
|
+
existingItemTitle: e.portalItem?.title,
|
|
789
|
+
existingItemDescription: e.portalItem?.description,
|
|
790
|
+
existingLayerTitle: e.title,
|
|
791
|
+
existingLayerDescription: e.portalItem?.description,
|
|
760
792
|
fieldInformation: n
|
|
761
793
|
}, a = await te({
|
|
762
794
|
promptText: r,
|
|
763
795
|
schema: Xe,
|
|
764
796
|
inputVariables: s
|
|
765
797
|
});
|
|
766
|
-
return
|
|
767
|
-
}, Ye =
|
|
768
|
-
title:
|
|
769
|
-
description:
|
|
770
|
-
name:
|
|
771
|
-
}), Ze = async (
|
|
772
|
-
const n = await
|
|
798
|
+
return _(e, a);
|
|
799
|
+
}, Ye = h.object({
|
|
800
|
+
title: h.string(),
|
|
801
|
+
description: h.string(),
|
|
802
|
+
name: h.string().nullable()
|
|
803
|
+
}), Ze = async (e, t) => {
|
|
804
|
+
const n = await C("layer_descriptions_prompt"), s = Array.from(t.values()), a = {
|
|
773
805
|
fieldInformation: JSON.stringify(s, null, 2),
|
|
774
|
-
existingLayerTitle:
|
|
775
|
-
existingLayerDescription:
|
|
776
|
-
existingLayerSnippet:
|
|
777
|
-
layerGeometryType:
|
|
806
|
+
existingLayerTitle: e.title,
|
|
807
|
+
existingLayerDescription: e.portalItem?.description,
|
|
808
|
+
existingLayerSnippet: e.portalItem?.snippet,
|
|
809
|
+
layerGeometryType: e.geometryType
|
|
778
810
|
};
|
|
779
811
|
return { ...await te({
|
|
780
812
|
promptText: n,
|
|
781
813
|
schema: Ye,
|
|
782
814
|
inputVariables: a
|
|
783
|
-
}), name:
|
|
784
|
-
}, et = async (
|
|
785
|
-
const
|
|
786
|
-
for (const s of
|
|
815
|
+
}), name: e.title ?? null };
|
|
816
|
+
}, et = async (e) => {
|
|
817
|
+
const t = e.allLayers.toArray(), r = [], n = /* @__PURE__ */ new Map();
|
|
818
|
+
for (const s of t)
|
|
787
819
|
if (s instanceof O) {
|
|
788
820
|
const a = (async () => {
|
|
789
821
|
const i = await Qe(s), c = await Ze(s, i);
|
|
@@ -792,9 +824,9 @@ const Qe = async (t) => {
|
|
|
792
824
|
r.push(a);
|
|
793
825
|
}
|
|
794
826
|
return await Promise.all(r), n;
|
|
795
|
-
}, ft = async (
|
|
796
|
-
await H.whenOnce(() =>
|
|
797
|
-
const
|
|
827
|
+
}, ft = async (e) => {
|
|
828
|
+
await H.whenOnce(() => e.ready);
|
|
829
|
+
const t = await et(e.map), { layers: r } = await tt(t), n = {
|
|
798
830
|
schemaVersion: X,
|
|
799
831
|
modified: Date.now(),
|
|
800
832
|
embeddings: {
|
|
@@ -803,7 +835,7 @@ const Qe = async (t) => {
|
|
|
803
835
|
dimensions: w,
|
|
804
836
|
templates: {
|
|
805
837
|
layer: A,
|
|
806
|
-
field:
|
|
838
|
+
field: F
|
|
807
839
|
}
|
|
808
840
|
},
|
|
809
841
|
layers: r
|
|
@@ -811,16 +843,16 @@ const Qe = async (t) => {
|
|
|
811
843
|
if (!s.success)
|
|
812
844
|
throw console.error("Schema Mismatch:", s.error.format()), new Error("Webmap embedding generation failed validation.");
|
|
813
845
|
return s.data;
|
|
814
|
-
}, tt = async (
|
|
815
|
-
const
|
|
816
|
-
for (const [i, { fieldRegistry: c, layerItem: o }] of
|
|
817
|
-
const d =
|
|
846
|
+
}, tt = async (e) => {
|
|
847
|
+
const t = [], r = [];
|
|
848
|
+
for (const [i, { fieldRegistry: c, layerItem: o }] of e.entries()) {
|
|
849
|
+
const d = P(A, {
|
|
818
850
|
name: o.name,
|
|
819
851
|
title: o.title,
|
|
820
852
|
description: o.description
|
|
821
853
|
});
|
|
822
|
-
|
|
823
|
-
const
|
|
854
|
+
t.push(d);
|
|
855
|
+
const u = {
|
|
824
856
|
id: i,
|
|
825
857
|
name: o.name ?? "",
|
|
826
858
|
title: o.title,
|
|
@@ -828,32 +860,32 @@ const Qe = async (t) => {
|
|
|
828
860
|
vector: [],
|
|
829
861
|
fields: []
|
|
830
862
|
};
|
|
831
|
-
for (const [,
|
|
832
|
-
const y =
|
|
833
|
-
name:
|
|
834
|
-
alias:
|
|
835
|
-
description:
|
|
863
|
+
for (const [, m] of c.entries()) {
|
|
864
|
+
const y = P(F, {
|
|
865
|
+
name: m.name,
|
|
866
|
+
alias: m.alias,
|
|
867
|
+
description: m.description
|
|
836
868
|
});
|
|
837
|
-
|
|
838
|
-
name:
|
|
839
|
-
alias:
|
|
840
|
-
description:
|
|
869
|
+
t.push(y), u.fields.push({
|
|
870
|
+
name: m.name,
|
|
871
|
+
alias: m.alias,
|
|
872
|
+
description: m.description,
|
|
841
873
|
vector: []
|
|
842
874
|
});
|
|
843
875
|
}
|
|
844
|
-
r.push(
|
|
876
|
+
r.push(u);
|
|
845
877
|
}
|
|
846
|
-
const n = await B(
|
|
878
|
+
const n = await B(t);
|
|
847
879
|
let s = 0;
|
|
848
880
|
return { layers: r.map((i) => (i.vector = n[s++], i.fields.forEach((c) => {
|
|
849
881
|
c.vector = n[s++];
|
|
850
882
|
}), i)) };
|
|
851
|
-
},
|
|
852
|
-
if (
|
|
883
|
+
}, P = (e, t) => e.replace(/\{(\w+)\}/gu, (r, n) => t[n] ?? ""), yt = (e, t) => {
|
|
884
|
+
if (e.length !== t.length)
|
|
853
885
|
throw new Error("Vectors must be the same length");
|
|
854
886
|
let r = 0, n = 0, s = 0;
|
|
855
|
-
for (let c = 0; c <
|
|
856
|
-
const o =
|
|
887
|
+
for (let c = 0; c < e.length; ++c) {
|
|
888
|
+
const o = e[c], d = t[c];
|
|
857
889
|
r += o * d, n += o * o, s += d * d;
|
|
858
890
|
}
|
|
859
891
|
const a = Math.sqrt(n * s);
|
|
@@ -865,12 +897,12 @@ const Qe = async (t) => {
|
|
|
865
897
|
export {
|
|
866
898
|
ee as Orchestrator,
|
|
867
899
|
yt as cosineSimilarity,
|
|
868
|
-
|
|
900
|
+
b as createChatModel,
|
|
869
901
|
ft as createWebmapEmbeddings,
|
|
870
902
|
B as getEmbeddings,
|
|
871
903
|
te as invokeStructuredPrompt,
|
|
872
904
|
pt as invokeTextPrompt,
|
|
873
905
|
ht as invokeToolPrompt,
|
|
874
|
-
|
|
875
|
-
|
|
906
|
+
f as sendTraceMessage,
|
|
907
|
+
gt as sendUXSuggestion
|
|
876
908
|
};
|
|
@@ -19,6 +19,11 @@ Return either:
|
|
|
19
19
|
3. \`requiresFollowUp\` — whether another orchestration step will likely be needed after this agent succeeds
|
|
20
20
|
- or \`null\` if no registered agent applies
|
|
21
21
|
|
|
22
|
+
Important
|
|
23
|
+
|
|
24
|
+
- Return null only when the request is clearly outside the scope of all registered agents.
|
|
25
|
+
- If any agent can take the next useful step, select the best one instead of returning null.
|
|
26
|
+
|
|
22
27
|
Latest user request:
|
|
23
28
|
{userRequest}
|
|
24
29
|
|
|
@@ -34,12 +39,11 @@ Each step has:
|
|
|
34
39
|
- agentId: string
|
|
35
40
|
- assignedTask: string
|
|
36
41
|
- summary: string
|
|
37
|
-
- status: "success" | "failed" | "
|
|
42
|
+
- status: "success" | "failed" | "unknown"
|
|
38
43
|
|
|
39
44
|
Use prior steps to:
|
|
40
45
|
|
|
41
46
|
- Avoid repeating work that has already succeeded
|
|
42
|
-
- Continue or refine steps that were partial
|
|
43
47
|
- Retry or adjust steps that failed when appropriate
|
|
44
48
|
|
|
45
49
|
{priorSteps}
|
|
@@ -52,6 +56,9 @@ Rules:
|
|
|
52
56
|
- Do not plan the full workflow up front. Only decide the next best step.
|
|
53
57
|
- Prefer an agent that can directly complete the user’s request.
|
|
54
58
|
- Only break the request into multiple steps when necessary.
|
|
59
|
+
- When multiple agents could help, choose the best fit instead of returning \`null\`.
|
|
60
|
+
- Base the choice on the registered agent descriptions, not on whether the user used exact matching keywords.
|
|
61
|
+
- If no agent can fully complete the request, but one agent can take the next useful step, choose that agent and set requiresFollowUp to true.
|
|
55
62
|
|
|
56
63
|
Assigned Task Guidelines (IMPORTANT):
|
|
57
64
|
|
package/dist/types/types.d.ts
CHANGED
|
@@ -62,7 +62,7 @@ export interface AgentExecutionContext {
|
|
|
62
62
|
userRequest: string;
|
|
63
63
|
assignedTask: string;
|
|
64
64
|
messages: ChatHistory;
|
|
65
|
-
priorSteps
|
|
65
|
+
priorSteps: PriorStep[];
|
|
66
66
|
}
|
|
67
67
|
export interface PriorStep {
|
|
68
68
|
agentId: string;
|
|
@@ -71,8 +71,8 @@ export interface PriorStep {
|
|
|
71
71
|
status: AgentStatus;
|
|
72
72
|
}
|
|
73
73
|
export interface AgentResult {
|
|
74
|
-
outputMessage?: string;
|
|
75
|
-
summary: string;
|
|
76
74
|
status: AgentStatus;
|
|
75
|
+
outputMessage?: string;
|
|
76
|
+
summary?: string;
|
|
77
77
|
}
|
|
78
|
-
export type AgentStatus = "failed" | "
|
|
78
|
+
export type AgentStatus = "failed" | "success" | "unknown";
|