@arcgis/ai-orchestrator 5.1.0-next.67 → 5.1.0-next.69
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/dispatcherAgent/state/dispatcherGraphState.d.ts +2 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +310 -283
- package/dist/intent_prompt-DULnCkLt.js +77 -0
- package/dist/models/types.d.ts +1 -1
- package/dist/orchestrator/orchestrator.d.ts +2 -1
- package/dist/types/types.d.ts +3 -2
- package/package.json +1 -1
- package/dist/dispatcherAgent/nodes/intentDispatcher.d.ts +0 -2
- package/dist/intent_prompt-CRmsldou.js +0 -22
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { AgentExecutionContext } from '../../types/types';
|
|
2
2
|
export declare const DispatcherGraphState: import('@langchain/langgraph').AnnotationRoot<{
|
|
3
3
|
agentExecutionContext: import('@langchain/langgraph').BaseChannel<AgentExecutionContext, AgentExecutionContext | import('@langchain/langgraph').OverwriteValue<AgentExecutionContext>, unknown>;
|
|
4
|
-
pendingIntents: import('@langchain/langgraph').BaseChannel<string[], string[] | import('@langchain/langgraph').OverwriteValue<string[]>, unknown>;
|
|
5
4
|
currentIntent: import('@langchain/langgraph').BaseChannel<string, string | import('@langchain/langgraph').OverwriteValue<string>, unknown>;
|
|
5
|
+
requiresFollowUp: import('@langchain/langgraph').BaseChannel<boolean, boolean | import('@langchain/langgraph').OverwriteValue<boolean>, unknown>;
|
|
6
|
+
stepCount: import('@langchain/langgraph').BaseChannel<number, number | import('@langchain/langgraph').OverwriteValue<number>, unknown>;
|
|
6
7
|
}>;
|
|
7
8
|
export type DispatcherGraphStateType = typeof DispatcherGraphState.State;
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ export { invokeTextPrompt, invokeStructuredPrompt, invokeToolPrompt } from './pr
|
|
|
4
4
|
export { createWebmapEmbeddings } from './embeddings/webmapEmbeddings';
|
|
5
5
|
export { getEmbeddings } from './embeddings/embeddingsUtil';
|
|
6
6
|
export { cosineSimilarity } from './embeddings/cosineSimilarity';
|
|
7
|
-
export type { CustomConfigurableType, VectorSearchFieldResults, LayersAndFieldsRegistry, Services, FieldInfo, FieldStatistics, ChatHistory, AgentExecutionContext, } from './types/types';
|
|
7
|
+
export type { CustomConfigurableType, VectorSearchFieldResults, LayersAndFieldsRegistry, Services, FieldInfo, FieldStatistics, ChatHistory, AgentExecutionContext, AgentStatus, PriorStep, } from './types/types';
|
|
8
8
|
export type { UiInterrupt } from './hitl/types';
|
|
9
9
|
export type { AgentRegistration, AgentWithContext } from './registry/agentRegistry';
|
package/dist/index.js
CHANGED
|
@@ -1,65 +1,66 @@
|
|
|
1
|
-
import
|
|
1
|
+
import I from "@arcgis/core/identity/IdentityManager.js";
|
|
2
2
|
import x from "@arcgis/core/portal/Portal.js";
|
|
3
|
-
import { Annotation as b, StateGraph as
|
|
4
|
-
import { HumanMessage as W, AIMessage as N, isAIMessage as
|
|
3
|
+
import { Annotation as b, StateGraph as te, START as ne, END as re, MemorySaver as se } from "@langchain/langgraph/web";
|
|
4
|
+
import { HumanMessage as W, AIMessage as N, isAIMessage as ie, isToolMessage as ae } from "@langchain/core/messages";
|
|
5
5
|
import { dispatchCustomEvent as P } from "@langchain/core/callbacks/dispatch/web";
|
|
6
|
-
import
|
|
7
|
-
import { SystemMessagePromptTemplate as
|
|
8
|
-
import { OpenAIEmbeddings as
|
|
9
|
-
import * as
|
|
6
|
+
import u, { z as d } from "zod";
|
|
7
|
+
import { SystemMessagePromptTemplate as oe, ChatPromptTemplate as ce } from "@langchain/core/prompts";
|
|
8
|
+
import { OpenAIEmbeddings as de, ChatOpenAI as le } from "@langchain/openai";
|
|
9
|
+
import * as q from "@arcgis/core/core/reactiveUtils.js";
|
|
10
10
|
import H from "@arcgis/core/layers/FeatureLayer.js";
|
|
11
|
-
import
|
|
12
|
-
const
|
|
11
|
+
import me from "@arcgis/core/request.js";
|
|
12
|
+
const O = {
|
|
13
13
|
advanced: "gpt-5.2",
|
|
14
|
-
default: "gpt-5-mini"
|
|
14
|
+
default: "gpt-5-mini",
|
|
15
|
+
fast: "gpt-5.4-nano"
|
|
15
16
|
}, S = {
|
|
16
17
|
default: "text-embedding-ada-002"
|
|
17
|
-
},
|
|
18
|
-
let
|
|
19
|
-
const
|
|
18
|
+
}, E = /* @__PURE__ */ new Map();
|
|
19
|
+
let v = null;
|
|
20
|
+
const pe = () => {
|
|
20
21
|
const t = x.getDefault().helperServices;
|
|
21
22
|
if (!t?.aiModels?.url)
|
|
22
23
|
throw new Error("AI Models Service URL is not defined in the portal's helper services.");
|
|
23
24
|
return t.aiModels.url;
|
|
24
|
-
},
|
|
25
|
-
const t =
|
|
26
|
-
|
|
25
|
+
}, V = async (e) => {
|
|
26
|
+
const t = pe();
|
|
27
|
+
E.size === 0 && (v || (v = (async () => {
|
|
27
28
|
try {
|
|
28
29
|
const n = await fetch(`${t}/models`);
|
|
29
30
|
if (!n.ok)
|
|
30
31
|
throw new Error("Failed to fetch AI service discovery data.");
|
|
31
|
-
(await n.json()).models.forEach((
|
|
32
|
+
(await n.json()).models.forEach((i) => E.set(i.name, i));
|
|
32
33
|
} catch (n) {
|
|
33
|
-
throw
|
|
34
|
+
throw v = null, n;
|
|
34
35
|
}
|
|
35
|
-
})()), await
|
|
36
|
-
const r =
|
|
36
|
+
})()), await v);
|
|
37
|
+
const r = E.get(e);
|
|
37
38
|
if (!r)
|
|
38
39
|
throw new Error(`Model '${e}' is not available in the discovery service.`);
|
|
39
40
|
return r.endpoint;
|
|
40
|
-
},
|
|
41
|
-
const t = await
|
|
41
|
+
}, ge = async (e = "default") => await V(O[e]), z = async (e = "default") => await V(S[e]), ue = async (e) => {
|
|
42
|
+
const t = await he(), r = await z("default"), n = x.getDefault(), i = (await I.getCredential(`${n.url}/sharing`)).token, a = {
|
|
42
43
|
type: "generateEmbeddings",
|
|
43
44
|
webmapEmbeddings: e,
|
|
44
|
-
auth: { apiUrl: r, token:
|
|
45
|
+
auth: { apiUrl: r, token: i }
|
|
45
46
|
};
|
|
46
|
-
return t.postMessage(
|
|
47
|
-
const l = (
|
|
48
|
-
|
|
49
|
-
}, m = (
|
|
50
|
-
t.removeEventListener("message", l), o(
|
|
47
|
+
return t.postMessage(a), await new Promise((c, o) => {
|
|
48
|
+
const l = (p) => {
|
|
49
|
+
p.data === "completed" && (t.removeEventListener("message", l), c());
|
|
50
|
+
}, m = (p) => {
|
|
51
|
+
t.removeEventListener("message", l), o(p instanceof Error ? p : new Error("Embeddings worker error"));
|
|
51
52
|
};
|
|
52
53
|
t.addEventListener("message", l), t.addEventListener("error", m, { once: !0 });
|
|
53
54
|
}), t;
|
|
54
|
-
},
|
|
55
|
+
}, he = async () => {
|
|
55
56
|
{
|
|
56
57
|
const e = (await import("./embeddings.worker-GH7zdYqF.js")).default;
|
|
57
58
|
return new e();
|
|
58
59
|
}
|
|
59
|
-
},
|
|
60
|
+
}, D = (e, t) => t, fe = (e, t) => ({
|
|
60
61
|
...e,
|
|
61
62
|
...t
|
|
62
|
-
}),
|
|
63
|
+
}), ye = b.Root({
|
|
63
64
|
agentExecutionContext: b({
|
|
64
65
|
default: () => ({
|
|
65
66
|
userRequest: "",
|
|
@@ -67,54 +68,60 @@ const le = () => {
|
|
|
67
68
|
priorSteps: [],
|
|
68
69
|
messages: []
|
|
69
70
|
}),
|
|
70
|
-
reducer:
|
|
71
|
-
}),
|
|
72
|
-
pendingIntents: b({
|
|
73
|
-
default: () => [],
|
|
74
|
-
reducer: L
|
|
71
|
+
reducer: fe
|
|
75
72
|
}),
|
|
76
73
|
currentIntent: b({
|
|
77
74
|
default: () => "none",
|
|
78
|
-
reducer:
|
|
75
|
+
reducer: D
|
|
76
|
+
}),
|
|
77
|
+
requiresFollowUp: b({
|
|
78
|
+
default: () => !0,
|
|
79
|
+
reducer: D
|
|
80
|
+
}),
|
|
81
|
+
stepCount: b({
|
|
82
|
+
default: () => 0,
|
|
83
|
+
reducer: (e, t) => t ?? e + 1
|
|
79
84
|
})
|
|
80
|
-
}),
|
|
85
|
+
}), h = async (e, t) => {
|
|
81
86
|
await P("trace_message", e, t);
|
|
82
|
-
},
|
|
87
|
+
}, ot = async (e, t) => {
|
|
83
88
|
await P("graph_ux_suggestion", e, t);
|
|
84
|
-
},
|
|
85
|
-
e.currentIntent = "none"
|
|
86
|
-
},
|
|
89
|
+
}, we = (e) => {
|
|
90
|
+
e.currentIntent = "none";
|
|
91
|
+
}, be = async (e, t) => {
|
|
87
92
|
if (e.agentExecutionContext.userRequest) {
|
|
88
93
|
const n = new W(e.agentExecutionContext.userRequest.trim());
|
|
89
|
-
e.agentExecutionContext.messages = [...e.agentExecutionContext.messages, n],
|
|
94
|
+
e.agentExecutionContext.messages = [...e.agentExecutionContext.messages, n], we(e);
|
|
90
95
|
}
|
|
91
96
|
const r = t?.configurable?.services.agentRegistry.list().map((n) => n.agent.id) ?? [];
|
|
92
|
-
return await
|
|
93
|
-
},
|
|
94
|
-
if (e
|
|
95
|
-
return
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const
|
|
97
|
+
return await h({ text: `Available agents: ${[...r].join(", ")}` }, t), await h({ text: "Analyzing user input" }, t), e;
|
|
98
|
+
}, ve = async (e, t) => (await h({ text: "Exiting..." }, t), e), F = 4e3, L = (e) => {
|
|
99
|
+
if (typeof e != "string")
|
|
100
|
+
return;
|
|
101
|
+
const t = e.trim();
|
|
102
|
+
return t || void 0;
|
|
103
|
+
}, $ = (e) => e === "failed" || e === "partial" || e === "success", xe = (e) => e === "failed" ? "Agent failed without a summary." : e === "partial" ? "Agent partially completed without a summary." : "Agent completed without a summary.", Ee = (e, t) => {
|
|
104
|
+
const r = L(t?.outputMessage), n = L(t?.summary), s = t?.status;
|
|
105
|
+
$(s) || console.warn(`Registered agent "${e}" returned an invalid or missing status:`, s);
|
|
106
|
+
const i = $(s) ? s : r || n ? "partial" : "failed";
|
|
100
107
|
return {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
108
|
+
outputMessage: r,
|
|
109
|
+
summary: n ?? r ?? xe(i),
|
|
110
|
+
status: i
|
|
104
111
|
};
|
|
105
|
-
},
|
|
112
|
+
}, Ie = async (e, t) => {
|
|
106
113
|
const r = t?.configurable, { agentRegistry: n } = r.services, s = n?.get(e.currentIntent);
|
|
107
114
|
if (!s)
|
|
108
115
|
return console.warn(`No agent found for intent: ${e.currentIntent}`), e;
|
|
109
|
-
await
|
|
110
|
-
const
|
|
116
|
+
await h({ text: `Executing registered agent: ${s.agent.name}` }, t);
|
|
117
|
+
const i = {
|
|
111
118
|
...t ?? {},
|
|
112
119
|
configurable: {
|
|
113
120
|
...r ?? {},
|
|
114
121
|
agentId: s.agent.id,
|
|
115
122
|
context: s.getContext ? await s.getContext() : void 0
|
|
116
123
|
}
|
|
117
|
-
},
|
|
124
|
+
}, a = await s.agent.createGraph().compile().invoke(
|
|
118
125
|
{
|
|
119
126
|
agentExecutionContext: {
|
|
120
127
|
...e.agentExecutionContext,
|
|
@@ -122,32 +129,38 @@ const le = () => {
|
|
|
122
129
|
priorSteps: [...e.agentExecutionContext.priorSteps ?? []]
|
|
123
130
|
}
|
|
124
131
|
},
|
|
125
|
-
|
|
132
|
+
i
|
|
126
133
|
);
|
|
127
|
-
await
|
|
128
|
-
const c =
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
if (!l)
|
|
135
|
-
return e;
|
|
136
|
-
const m = l.length > _ ? `${l.slice(0, _ - 14)}
|
|
137
|
-
[truncated]` : l;
|
|
134
|
+
await h({ text: `Finished executing registered agent: ${s.agent.name}` }, t);
|
|
135
|
+
const c = Ee(s.agent.name, a), o = c.outputMessage, l = [...e.agentExecutionContext.messages];
|
|
136
|
+
if (o) {
|
|
137
|
+
const m = o.length > F ? `${o.slice(0, F - 14)}
|
|
138
|
+
[truncated]` : o;
|
|
139
|
+
l.push(new N(m));
|
|
140
|
+
}
|
|
138
141
|
return {
|
|
139
142
|
...e,
|
|
143
|
+
stepCount: e.stepCount + 1,
|
|
140
144
|
agentExecutionContext: {
|
|
141
145
|
...e.agentExecutionContext,
|
|
142
|
-
messages:
|
|
146
|
+
messages: l,
|
|
147
|
+
priorSteps: [
|
|
148
|
+
...e.agentExecutionContext.priorSteps ?? [],
|
|
149
|
+
{
|
|
150
|
+
agentId: s.agent.id,
|
|
151
|
+
assignedTask: e.agentExecutionContext.assignedTask,
|
|
152
|
+
summary: c.summary,
|
|
153
|
+
status: c.status
|
|
154
|
+
}
|
|
155
|
+
]
|
|
143
156
|
}
|
|
144
157
|
};
|
|
145
|
-
},
|
|
158
|
+
}, Se = (e, t, r) => {
|
|
146
159
|
const n = e[t];
|
|
147
|
-
return n ? typeof n == "function" ? n() : Promise.resolve(n) : new Promise((s,
|
|
148
|
-
(typeof queueMicrotask == "function" ? queueMicrotask : setTimeout)(
|
|
160
|
+
return n ? typeof n == "function" ? n() : Promise.resolve(n) : new Promise((s, i) => {
|
|
161
|
+
(typeof queueMicrotask == "function" ? queueMicrotask : setTimeout)(i.bind(null, /* @__PURE__ */ new Error("Unknown variable dynamic import: " + t + (t.split("/").length !== r ? ". Note that variables only represent file names one level deep." : ""))));
|
|
149
162
|
});
|
|
150
|
-
},
|
|
163
|
+
}, M = async (e) => (await Se(/* @__PURE__ */ Object.assign({ "./field_descriptions_prompt.md": () => import("./field_descriptions_prompt-haMV_aoG.js"), "./intent_prompt.md": () => import("./intent_prompt-DULnCkLt.js"), "./layer_descriptions_prompt.md": () => import("./layer_descriptions_prompt-NAaKWdJi.js") }), `./${e}.md`, 2)).default, Me = (e, t = 3) => e.filter((r) => r.type === "human").slice(-t), Re = (e) => {
|
|
151
164
|
let t = -1;
|
|
152
165
|
for (let r = e.length - 1; r >= 0; r--)
|
|
153
166
|
if (e[r] instanceof W) {
|
|
@@ -156,123 +169,137 @@ const le = () => {
|
|
|
156
169
|
}
|
|
157
170
|
return t === -1 ? "" : e.slice(t + 1).filter((r) => r instanceof N).map((r) => r.content).join(`
|
|
158
171
|
`);
|
|
159
|
-
},
|
|
172
|
+
}, G = (e) => async (t, r) => {
|
|
160
173
|
const n = new Headers(r?.headers);
|
|
161
174
|
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, {
|
|
162
175
|
...r,
|
|
163
176
|
headers: n
|
|
164
177
|
});
|
|
165
|
-
},
|
|
166
|
-
const r = x.getDefault(), n = await
|
|
167
|
-
return new
|
|
178
|
+
}, R = async (e = "default", t = 0) => {
|
|
179
|
+
const r = x.getDefault(), n = await I.getCredential(`${r.url}/sharing`), s = O[e], i = await ge(e);
|
|
180
|
+
return new le({
|
|
168
181
|
modelName: s,
|
|
169
182
|
apiKey: "dummy-key",
|
|
170
183
|
// 5-mini does not support temperature parameter
|
|
171
184
|
...e !== "default" && { temperature: t },
|
|
172
185
|
configuration: {
|
|
173
|
-
baseURL:
|
|
174
|
-
fetch:
|
|
186
|
+
baseURL: i,
|
|
187
|
+
fetch: G(n.token)
|
|
175
188
|
}
|
|
176
189
|
});
|
|
177
|
-
},
|
|
178
|
-
const t = x.getDefault(), r = await
|
|
179
|
-
return new
|
|
190
|
+
}, ke = async (e = "default") => {
|
|
191
|
+
const t = x.getDefault(), r = await I.getCredential(`${t.url}/sharing`), n = S[e], s = await z(e);
|
|
192
|
+
return new de({
|
|
180
193
|
modelName: n,
|
|
181
194
|
apiKey: "dummy-key",
|
|
182
195
|
configuration: {
|
|
183
196
|
baseURL: s,
|
|
184
|
-
fetch:
|
|
197
|
+
fetch: G(r.token)
|
|
185
198
|
},
|
|
186
199
|
batchSize: 2048,
|
|
187
200
|
maxConcurrency: 10
|
|
188
201
|
});
|
|
189
|
-
},
|
|
202
|
+
}, Te = (e) => {
|
|
190
203
|
const t = /* @__PURE__ */ new Set();
|
|
191
204
|
for (const n of e)
|
|
192
|
-
if (
|
|
205
|
+
if (ie(n)) {
|
|
193
206
|
const s = n;
|
|
194
|
-
s.tool_calls && s.tool_calls.length > 0 && s.tool_calls.forEach((
|
|
195
|
-
|
|
207
|
+
s.tool_calls && s.tool_calls.length > 0 && s.tool_calls.forEach((i) => {
|
|
208
|
+
i.id && t.add(i.id);
|
|
196
209
|
});
|
|
197
210
|
}
|
|
198
211
|
return e.filter((n) => {
|
|
199
|
-
if (
|
|
212
|
+
if (ae(n)) {
|
|
200
213
|
const s = n;
|
|
201
214
|
return t.has(s.tool_call_id);
|
|
202
215
|
}
|
|
203
216
|
return !0;
|
|
204
217
|
});
|
|
205
|
-
},
|
|
206
|
-
const r =
|
|
207
|
-
return
|
|
208
|
-
},
|
|
209
|
-
const { promptText: t, modelTier: r, temperature: n, messages: s } = e,
|
|
210
|
-
return
|
|
211
|
-
},
|
|
212
|
-
const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables:
|
|
218
|
+
}, k = (e, t) => {
|
|
219
|
+
const r = oe.fromTemplate(e);
|
|
220
|
+
return ce.fromMessages([r, ...t]);
|
|
221
|
+
}, Ce = async (e) => {
|
|
222
|
+
const { promptText: t, modelTier: r, temperature: n, messages: s } = e, i = k(t, s ?? []), a = await R(r, n);
|
|
223
|
+
return i.pipe(a);
|
|
224
|
+
}, ct = async (e) => {
|
|
225
|
+
const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables: i } = e, c = await (await Ce({
|
|
213
226
|
promptText: t,
|
|
214
227
|
modelTier: r,
|
|
215
228
|
temperature: n,
|
|
216
229
|
messages: s
|
|
217
|
-
})).invoke(
|
|
230
|
+
})).invoke(i ?? {});
|
|
218
231
|
if (typeof c == "string")
|
|
219
232
|
return c;
|
|
220
233
|
const o = c.content;
|
|
221
234
|
return typeof o == "string" ? o : JSON.stringify(o);
|
|
222
|
-
},
|
|
223
|
-
const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables:
|
|
224
|
-
return await c.pipe(l).invoke(
|
|
225
|
-
},
|
|
226
|
-
const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables:
|
|
227
|
-
return await o.pipe(l.bindTools(
|
|
228
|
-
},
|
|
235
|
+
}, T = async (e) => {
|
|
236
|
+
const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables: i, schema: a } = e, c = k(t, s ?? []), l = (await R(r, n)).withStructuredOutput(a);
|
|
237
|
+
return await c.pipe(l).invoke(i ?? {});
|
|
238
|
+
}, dt = async (e) => {
|
|
239
|
+
const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables: i, tools: a } = e, c = a.length > 0 ? Te(s ?? []) : s ?? [], o = k(t, c), l = await R(r, n);
|
|
240
|
+
return await o.pipe(l.bindTools(a)).invoke(i ?? {});
|
|
241
|
+
}, Ae = d.object({
|
|
229
242
|
id: d.string().min(1),
|
|
230
243
|
name: d.string().min(1),
|
|
231
244
|
description: d.string().min(1)
|
|
232
245
|
});
|
|
233
|
-
d.array(
|
|
246
|
+
d.array(Ae);
|
|
234
247
|
const De = (e) => {
|
|
235
248
|
const t = e.map((n) => n.id), r = d.enum(t);
|
|
236
249
|
return d.object({
|
|
237
|
-
|
|
250
|
+
intent: r.nullable(),
|
|
251
|
+
assignedTask: d.string().nullable(),
|
|
252
|
+
requiresFollowUp: d.boolean()
|
|
238
253
|
});
|
|
239
|
-
},
|
|
254
|
+
}, Fe = async (e, t) => {
|
|
240
255
|
try {
|
|
241
|
-
await
|
|
242
|
-
const n = await
|
|
243
|
-
id:
|
|
244
|
-
name:
|
|
245
|
-
description:
|
|
256
|
+
await h({ text: "Asking LLM to detect intent" }, t);
|
|
257
|
+
const n = await M("intent_prompt"), a = (t?.configurable?.services.agentRegistry?.list() ?? []).map(({ agent: g }) => ({
|
|
258
|
+
id: g.id,
|
|
259
|
+
name: g.name,
|
|
260
|
+
description: g.description
|
|
246
261
|
}));
|
|
247
|
-
if (!
|
|
248
|
-
return await
|
|
262
|
+
if (!a.length)
|
|
263
|
+
return await h({ text: "No agents registered; skipping intent detection" }, t), {
|
|
249
264
|
...e,
|
|
250
|
-
currentIntent: "none"
|
|
251
|
-
pendingIntents: []
|
|
265
|
+
currentIntent: "none"
|
|
252
266
|
};
|
|
253
|
-
const c =
|
|
254
|
-
`), o =
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
267
|
+
const c = a.map((g) => JSON.stringify(g)).join(`
|
|
268
|
+
`), o = De(a), l = {
|
|
269
|
+
registeredAgents: c,
|
|
270
|
+
priorSteps: e.agentExecutionContext.priorSteps,
|
|
271
|
+
userRequest: e.agentExecutionContext.userRequest
|
|
272
|
+
}, m = await T({
|
|
258
273
|
promptText: n,
|
|
259
|
-
schema:
|
|
260
|
-
messages:
|
|
261
|
-
inputVariables:
|
|
262
|
-
})
|
|
274
|
+
schema: o,
|
|
275
|
+
messages: Me(e.agentExecutionContext.messages),
|
|
276
|
+
inputVariables: l
|
|
277
|
+
});
|
|
278
|
+
console.log("Raw intent detection output:", m);
|
|
279
|
+
const p = m.intent ?? "none", y = {
|
|
263
280
|
...e,
|
|
264
|
-
currentIntent:
|
|
265
|
-
|
|
281
|
+
currentIntent: p,
|
|
282
|
+
requiresFollowUp: m.requiresFollowUp,
|
|
283
|
+
agentExecutionContext: {
|
|
284
|
+
...e.agentExecutionContext,
|
|
285
|
+
assignedTask: m.assignedTask ?? ""
|
|
286
|
+
}
|
|
266
287
|
};
|
|
267
|
-
return await
|
|
288
|
+
return await h({ text: `Intent came back as: ${p}` }, t), await h(
|
|
289
|
+
{ text: `Agent picked: ${p}
|
|
290
|
+
Task Assigned: ${m.assignedTask ?? ""}` },
|
|
291
|
+
t
|
|
292
|
+
), y;
|
|
268
293
|
} catch (r) {
|
|
269
|
-
throw await
|
|
294
|
+
throw await h({ text: "Error during intent detection" }, t), new Error(`Error during intent detection: ${r instanceof Error ? r.message : String(r)}`);
|
|
270
295
|
}
|
|
271
|
-
},
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
296
|
+
}, _ = 3, Le = () => new te(ye).addNode("ingestInput", be).addNode("intentLLM", Fe).addNode("executeRegisteredAgent", Ie).addNode("exit", ve).addEdge(ne, "ingestInput").addEdge("ingestInput", "intentLLM").addConditionalEdges("intentLLM", (t) => t.currentIntent === "none" ? "exit" : "executeRegisteredAgent").addConditionalEdges("executeRegisteredAgent", (t) => (console.log("[Dispatcher][executeRegisteredAgent]", {
|
|
297
|
+
intent: t.currentIntent,
|
|
298
|
+
followUp: t.requiresFollowUp,
|
|
299
|
+
step: t.stepCount,
|
|
300
|
+
maxSteps: _
|
|
301
|
+
}), !t.requiresFollowUp || t.stepCount >= _ ? "exit" : "intentLLM")).addEdge("exit", re);
|
|
302
|
+
class $e {
|
|
276
303
|
constructor() {
|
|
277
304
|
this.agentRegistry = /* @__PURE__ */ new Map();
|
|
278
305
|
}
|
|
@@ -289,7 +316,7 @@ class Ce {
|
|
|
289
316
|
return [...this.agentRegistry.values()];
|
|
290
317
|
}
|
|
291
318
|
}
|
|
292
|
-
class
|
|
319
|
+
class _e {
|
|
293
320
|
/**
|
|
294
321
|
* Create a new InterruptHandler tied to a specific compiled graph and config.
|
|
295
322
|
*/
|
|
@@ -336,23 +363,23 @@ class Fe {
|
|
|
336
363
|
this.rejectWait && (this.rejectWait(new Error("Request cancelled by user.")), this.resolveWait = void 0, this.rejectWait = void 0);
|
|
337
364
|
}
|
|
338
365
|
}
|
|
339
|
-
const
|
|
366
|
+
const K = async (e) => {
|
|
340
367
|
try {
|
|
341
|
-
return await (await
|
|
368
|
+
return await (await ke()).embedDocuments(e);
|
|
342
369
|
} catch (t) {
|
|
343
370
|
throw console.error("Failed to generate embeddings:", t), t;
|
|
344
371
|
}
|
|
345
|
-
},
|
|
372
|
+
}, B = async (e, t) => {
|
|
346
373
|
const r = t.get(e);
|
|
347
374
|
if (r)
|
|
348
375
|
return r;
|
|
349
|
-
const n = await
|
|
376
|
+
const n = await K([e]);
|
|
350
377
|
return t.set(e, n[0]), n[0];
|
|
351
378
|
};
|
|
352
|
-
async function
|
|
353
|
-
const s = `req-${Date.now()}`,
|
|
379
|
+
async function je(e, t, r, n) {
|
|
380
|
+
const s = `req-${Date.now()}`, a = {
|
|
354
381
|
type: "layerSearch",
|
|
355
|
-
precomputedEmbedding: n ? await
|
|
382
|
+
precomputedEmbedding: n ? await B(e, n) : void 0,
|
|
356
383
|
requestId: s,
|
|
357
384
|
minScore: r
|
|
358
385
|
};
|
|
@@ -360,10 +387,10 @@ async function Le(e, t, r, n) {
|
|
|
360
387
|
const o = (l) => {
|
|
361
388
|
l.data.requestId === s && c(l.data.results);
|
|
362
389
|
};
|
|
363
|
-
t.addEventListener("message", o, { once: !0 }), t.postMessage(
|
|
390
|
+
t.addEventListener("message", o, { once: !0 }), t.postMessage(a);
|
|
364
391
|
});
|
|
365
392
|
}
|
|
366
|
-
function
|
|
393
|
+
function Ue(e) {
|
|
367
394
|
const { worker: t } = e;
|
|
368
395
|
return {
|
|
369
396
|
async searchLayers({
|
|
@@ -371,68 +398,68 @@ function _e(e) {
|
|
|
371
398
|
minScore: n,
|
|
372
399
|
embeddingCache: s
|
|
373
400
|
}) {
|
|
374
|
-
return await
|
|
401
|
+
return await je(r, t, n, s);
|
|
375
402
|
}
|
|
376
403
|
};
|
|
377
404
|
}
|
|
378
|
-
const
|
|
405
|
+
const We = async ({
|
|
379
406
|
combinedQuery: e,
|
|
380
407
|
layerIds: t,
|
|
381
408
|
embeddingsWorker: r,
|
|
382
409
|
minScore: n,
|
|
383
410
|
topResults: s,
|
|
384
|
-
embeddingCache:
|
|
411
|
+
embeddingCache: i
|
|
385
412
|
}) => {
|
|
386
|
-
const
|
|
413
|
+
const a = `req-${Date.now()}`, c = i ? await B(e, i) : void 0, o = {
|
|
387
414
|
type: "fieldSearch",
|
|
388
415
|
layerIdForFieldsSearch: t,
|
|
389
416
|
precomputedEmbedding: c,
|
|
390
|
-
requestId:
|
|
417
|
+
requestId: a,
|
|
391
418
|
minScore: n,
|
|
392
419
|
topResults: s
|
|
393
420
|
};
|
|
394
421
|
return await new Promise((l) => {
|
|
395
|
-
const m = (
|
|
396
|
-
if (
|
|
422
|
+
const m = (p) => {
|
|
423
|
+
if (p.data.requestId !== a)
|
|
397
424
|
return;
|
|
398
|
-
const
|
|
399
|
-
layerId:
|
|
400
|
-
results:
|
|
425
|
+
const y = p.data.results.map(({ layerId: g, results: f }) => ({
|
|
426
|
+
layerId: g,
|
|
427
|
+
results: f
|
|
401
428
|
}));
|
|
402
|
-
l(
|
|
429
|
+
l(y);
|
|
403
430
|
};
|
|
404
431
|
r.addEventListener("message", m, { once: !0 }), r.postMessage(o);
|
|
405
432
|
});
|
|
406
433
|
};
|
|
407
|
-
function
|
|
434
|
+
function Ne(e) {
|
|
408
435
|
const { worker: t } = e;
|
|
409
436
|
return {
|
|
410
|
-
async searchFields({ text: r, layerIds: n, minScore: s, topResults:
|
|
411
|
-
return await
|
|
437
|
+
async searchFields({ text: r, layerIds: n, minScore: s, topResults: i, embeddingCache: a }) {
|
|
438
|
+
return await We({
|
|
412
439
|
combinedQuery: r,
|
|
413
440
|
layerIds: n,
|
|
414
441
|
embeddingsWorker: t,
|
|
415
442
|
minScore: s,
|
|
416
|
-
topResults:
|
|
417
|
-
embeddingCache:
|
|
443
|
+
topResults: i,
|
|
444
|
+
embeddingCache: a
|
|
418
445
|
});
|
|
419
446
|
}
|
|
420
447
|
};
|
|
421
448
|
}
|
|
422
|
-
const
|
|
449
|
+
const J = "0.1", w = 1536, X = "openai", Q = S.default, C = `Name: {name}
|
|
423
450
|
Title: {title}
|
|
424
|
-
Description: {description}`,
|
|
451
|
+
Description: {description}`, A = `Name: {name}
|
|
425
452
|
Alias: {alias}
|
|
426
|
-
Description: {description}`,
|
|
427
|
-
schemaVersion: d.literal(
|
|
453
|
+
Description: {description}`, Y = d.object({
|
|
454
|
+
schemaVersion: d.literal(J),
|
|
428
455
|
modified: d.number().int().nonnegative(),
|
|
429
456
|
embeddings: d.object({
|
|
430
|
-
modelProvider: d.literal(
|
|
431
|
-
model: d.literal(
|
|
432
|
-
dimensions: d.literal(
|
|
457
|
+
modelProvider: d.literal(X),
|
|
458
|
+
model: d.literal(Q),
|
|
459
|
+
dimensions: d.literal(w),
|
|
433
460
|
templates: d.object({
|
|
434
461
|
layer: d.string().default(C),
|
|
435
|
-
field: d.string().default(
|
|
462
|
+
field: d.string().default(A)
|
|
436
463
|
})
|
|
437
464
|
}),
|
|
438
465
|
layers: d.array(
|
|
@@ -441,49 +468,49 @@ Description: {description}`, Q = d.object({
|
|
|
441
468
|
name: d.string().min(1),
|
|
442
469
|
title: d.string().catch(""),
|
|
443
470
|
description: d.string().catch(""),
|
|
444
|
-
vector: d.array(d.number()).length(
|
|
445
|
-
message: `Layer vector must be exactly ${
|
|
471
|
+
vector: d.array(d.number()).length(w, {
|
|
472
|
+
message: `Layer vector must be exactly ${w} dimensions`
|
|
446
473
|
}),
|
|
447
474
|
fields: d.array(
|
|
448
475
|
d.object({
|
|
449
476
|
name: d.string().min(1),
|
|
450
477
|
alias: d.string().catch(""),
|
|
451
478
|
description: d.string().catch(""),
|
|
452
|
-
vector: d.array(d.number()).length(
|
|
453
|
-
message: `Field vector must be exactly ${
|
|
479
|
+
vector: d.array(d.number()).length(w, {
|
|
480
|
+
message: `Field vector must be exactly ${w} dimensions`
|
|
454
481
|
})
|
|
455
482
|
})
|
|
456
483
|
)
|
|
457
484
|
})
|
|
458
485
|
).default([])
|
|
459
|
-
}),
|
|
460
|
-
const t =
|
|
486
|
+
}), Pe = (e) => {
|
|
487
|
+
const t = Y.safeParse(e);
|
|
461
488
|
if (!t.success)
|
|
462
489
|
throw new Error("Embeddings response validation failed. Regenerate embeddings.");
|
|
463
490
|
return t.data;
|
|
464
|
-
},
|
|
491
|
+
}, qe = (e, t) => {
|
|
465
492
|
const r = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
|
|
466
493
|
if (t.allLayers.forEach((s) => {
|
|
467
494
|
s instanceof H && n.set(s.id, s);
|
|
468
495
|
}), e.length !== n.size)
|
|
469
496
|
throw new Error("Layer count mismatch during registry restoration. Regenerate embeddings.");
|
|
470
497
|
for (const s of e) {
|
|
471
|
-
const
|
|
472
|
-
if (!
|
|
498
|
+
const i = n.get(s.id);
|
|
499
|
+
if (!i)
|
|
473
500
|
throw new Error(
|
|
474
501
|
`Layer with ID ${s.id} not found in the original map during registry restoration. Regenerate embeddings.`
|
|
475
502
|
);
|
|
476
|
-
if (s.fields.length !==
|
|
503
|
+
if (s.fields.length !== i.fields.length)
|
|
477
504
|
throw new Error(
|
|
478
505
|
`Field count mismatch for layer ID ${s.id} during registry restoration. Regenerate embeddings.`
|
|
479
506
|
);
|
|
480
|
-
const
|
|
507
|
+
const a = {
|
|
481
508
|
name: s.name,
|
|
482
509
|
title: s.title,
|
|
483
510
|
description: s.description
|
|
484
511
|
}, c = /* @__PURE__ */ new Map();
|
|
485
512
|
for (const o of s.fields) {
|
|
486
|
-
const l =
|
|
513
|
+
const l = i.fieldsIndex.get(o.name);
|
|
487
514
|
if (!l)
|
|
488
515
|
throw new Error(
|
|
489
516
|
`Field with name ${o.name} not found in the original layer ${s.id} during registry restoration. Regenerate embeddings.`
|
|
@@ -494,36 +521,36 @@ Description: {description}`, Q = d.object({
|
|
|
494
521
|
description: o.description,
|
|
495
522
|
type: l.type || "unknown",
|
|
496
523
|
valueType: l.valueType || "unknown",
|
|
497
|
-
domain:
|
|
524
|
+
domain: i.getFieldDomain(o.name) ?? void 0
|
|
498
525
|
});
|
|
499
526
|
}
|
|
500
527
|
r.set(s.id, {
|
|
501
|
-
layerItem:
|
|
528
|
+
layerItem: a,
|
|
502
529
|
fieldRegistry: c
|
|
503
530
|
});
|
|
504
531
|
}
|
|
505
532
|
return r;
|
|
506
|
-
},
|
|
533
|
+
}, He = async (e) => {
|
|
507
534
|
try {
|
|
508
|
-
return (await
|
|
535
|
+
return (await me(e, {
|
|
509
536
|
responseType: "json"
|
|
510
537
|
})).data;
|
|
511
538
|
} catch (t) {
|
|
512
539
|
throw new Error(`Failed to fetch data from ${e}: ${String(t)}`);
|
|
513
540
|
}
|
|
514
|
-
},
|
|
541
|
+
}, Oe = async (e) => {
|
|
515
542
|
const t = e.map;
|
|
516
543
|
if (!t?.portalItem)
|
|
517
544
|
throw new Error("WebMap portal item is missing.");
|
|
518
|
-
const { resources: r } = await t.portalItem.fetchResources(), n = r.find((
|
|
545
|
+
const { resources: r } = await t.portalItem.fetchResources(), n = r.find((a) => a.resource.path === "embeddings-v01.json");
|
|
519
546
|
if (!n?.resource.url)
|
|
520
547
|
throw new Error("Embeddings resource 'embeddings-v01.json' not found in the webmap portal item.");
|
|
521
|
-
const s = await
|
|
522
|
-
return
|
|
548
|
+
const s = await He(n.resource.url);
|
|
549
|
+
return Pe(s);
|
|
523
550
|
};
|
|
524
|
-
class
|
|
551
|
+
class Z {
|
|
525
552
|
constructor() {
|
|
526
|
-
this.orchestratorReady = !1, this.chatHistory = [], this.threadId = "", this.agentRegistry = new
|
|
553
|
+
this.orchestratorReady = !1, this.chatHistory = [], this.priorSteps = [], this.threadId = "", this.agentRegistry = new $e(), this.streamEpoch = 0;
|
|
527
554
|
}
|
|
528
555
|
/**
|
|
529
556
|
* Creates and returns an AI-ready Orchestrator instance.
|
|
@@ -531,15 +558,15 @@ class Y {
|
|
|
531
558
|
* @returns Ready Orchestrator.
|
|
532
559
|
*/
|
|
533
560
|
static async init(t) {
|
|
534
|
-
const r = new
|
|
561
|
+
const r = new Z();
|
|
535
562
|
try {
|
|
536
563
|
if (t.view?.map) {
|
|
537
|
-
await
|
|
538
|
-
const n = await
|
|
564
|
+
await q.whenOnce(() => t.view.ready);
|
|
565
|
+
const n = await Oe(t.view), s = qe(
|
|
539
566
|
n.layers,
|
|
540
567
|
t.view.map
|
|
541
568
|
);
|
|
542
|
-
r.layersAndFieldsRegistry = s, r.embeddingsWorker = await
|
|
569
|
+
r.layersAndFieldsRegistry = s, r.embeddingsWorker = await ue(n);
|
|
543
570
|
}
|
|
544
571
|
return t.agents?.forEach((n) => {
|
|
545
572
|
r.agentRegistry.register(n);
|
|
@@ -563,8 +590,8 @@ class Y {
|
|
|
563
590
|
throw new Error("Orchestrator has no registered agents.");
|
|
564
591
|
if (++this.streamEpoch, !t.trim())
|
|
565
592
|
return;
|
|
566
|
-
this.threadId = String(Date.now()), this.graph || (this.graph =
|
|
567
|
-
const r = this.embeddingsWorker ?
|
|
593
|
+
this.threadId = String(Date.now()), this.graph || (this.graph = Le().compile({ checkpointer: new se() }));
|
|
594
|
+
const r = this.embeddingsWorker ? Ue({ worker: this.embeddingsWorker }) : void 0, n = this.embeddingsWorker ? Ne({ worker: this.embeddingsWorker }) : void 0, s = /* @__PURE__ */ new Map(), a = {
|
|
568
595
|
version: "v2",
|
|
569
596
|
streamMode: "custom",
|
|
570
597
|
configurable: {
|
|
@@ -581,24 +608,24 @@ class Y {
|
|
|
581
608
|
},
|
|
582
609
|
subgraphs: !0
|
|
583
610
|
}, c = this.graph?.streamEvents(
|
|
584
|
-
{ agentExecutionContext: { userRequest: t, messages: this.chatHistory } },
|
|
585
|
-
|
|
611
|
+
{ agentExecutionContext: { userRequest: t, messages: this.chatHistory, priorSteps: this.priorSteps } },
|
|
612
|
+
a
|
|
586
613
|
), o = ++this.streamEpoch;
|
|
587
614
|
for (yield* this.pipeStream(c, o); ; ) {
|
|
588
|
-
const
|
|
589
|
-
if (!
|
|
615
|
+
const g = (await this.graph.getState(a, { subgraphs: !0 })).tasks.find((f) => f.interrupts.length > 0)?.interrupts[0]?.value;
|
|
616
|
+
if (!g)
|
|
590
617
|
break;
|
|
591
|
-
this.currentInterrupt =
|
|
618
|
+
this.currentInterrupt = g, this.interruptHandler = new _e(this.graph, a), yield { runId: this.threadId, timestamp: Date.now(), type: "interrupt", interrupt: g };
|
|
592
619
|
try {
|
|
593
|
-
const
|
|
594
|
-
yield* this.pipeStream(
|
|
595
|
-
} catch (
|
|
596
|
-
if (
|
|
620
|
+
const f = await this.interruptHandler.waitForUser(), ee = ++this.streamEpoch;
|
|
621
|
+
yield* this.pipeStream(f, ee);
|
|
622
|
+
} catch (f) {
|
|
623
|
+
if (f) {
|
|
597
624
|
yield {
|
|
598
625
|
runId: this.threadId,
|
|
599
626
|
timestamp: Date.now(),
|
|
600
627
|
type: "error",
|
|
601
|
-
error: { message:
|
|
628
|
+
error: { message: f?.message }
|
|
602
629
|
};
|
|
603
630
|
return;
|
|
604
631
|
}
|
|
@@ -606,19 +633,19 @@ class Y {
|
|
|
606
633
|
return;
|
|
607
634
|
}
|
|
608
635
|
}
|
|
609
|
-
const m = (await this.graph.getState(
|
|
610
|
-
this.chatHistory = m.agentExecutionContext.messages.length ? m.agentExecutionContext.messages : this.chatHistory, yield {
|
|
636
|
+
const m = (await this.graph.getState(a, { subgraphs: !0 })).values;
|
|
637
|
+
this.chatHistory = m.agentExecutionContext.messages.length ? m.agentExecutionContext.messages : this.chatHistory, this.priorSteps = m.agentExecutionContext.priorSteps?.slice(-5) ?? [], yield {
|
|
611
638
|
runId: this.threadId,
|
|
612
639
|
timestamp: Date.now(),
|
|
613
640
|
type: "completed",
|
|
614
|
-
result: { content:
|
|
641
|
+
result: { content: Re(m.agentExecutionContext.messages) }
|
|
615
642
|
};
|
|
616
643
|
}
|
|
617
644
|
/**
|
|
618
|
-
* Start a new conversation by clearing chat history.
|
|
645
|
+
* Start a new conversation by clearing chat history and prior steps.
|
|
619
646
|
*/
|
|
620
647
|
newConversation() {
|
|
621
|
-
this.chatHistory = [];
|
|
648
|
+
this.chatHistory = [], this.priorSteps = [];
|
|
622
649
|
}
|
|
623
650
|
/**
|
|
624
651
|
* Generic resume for any HITL interrupt.
|
|
@@ -657,18 +684,18 @@ class Y {
|
|
|
657
684
|
this.embeddingsWorker && (this.embeddingsWorker.terminate(), this.embeddingsWorker = void 0), this.orchestratorReady = !1;
|
|
658
685
|
}
|
|
659
686
|
}
|
|
660
|
-
const
|
|
661
|
-
name:
|
|
662
|
-
description:
|
|
663
|
-
valueType:
|
|
664
|
-
alias:
|
|
665
|
-
}),
|
|
666
|
-
fields:
|
|
687
|
+
const Ve = u.object({
|
|
688
|
+
name: u.string(),
|
|
689
|
+
description: u.string(),
|
|
690
|
+
valueType: u.string(),
|
|
691
|
+
alias: u.string()
|
|
692
|
+
}), ze = u.object({
|
|
693
|
+
fields: u.array(Ve)
|
|
667
694
|
});
|
|
668
|
-
function
|
|
695
|
+
function j(e, t) {
|
|
669
696
|
const r = /* @__PURE__ */ new Map();
|
|
670
697
|
for (const n of e.fields) {
|
|
671
|
-
const s = t.fields.find((
|
|
698
|
+
const s = t.fields.find((a) => a.name === n.name), i = {
|
|
672
699
|
name: n.name,
|
|
673
700
|
type: n.type,
|
|
674
701
|
alias: s?.alias ?? n.alias ?? "",
|
|
@@ -676,115 +703,115 @@ function $(e, t) {
|
|
|
676
703
|
valueType: s?.valueType ?? n.valueType ?? "",
|
|
677
704
|
domain: e.getFieldDomain(n.name) ?? void 0
|
|
678
705
|
};
|
|
679
|
-
r.set(n.name,
|
|
706
|
+
r.set(n.name, i);
|
|
680
707
|
}
|
|
681
708
|
return r;
|
|
682
709
|
}
|
|
683
|
-
const
|
|
684
|
-
const r = await
|
|
685
|
-
const { name: c, type: o, alias: l, description: m } =
|
|
710
|
+
const Ge = async (e) => {
|
|
711
|
+
const r = await M("field_descriptions_prompt"), n = e.fields.filter((a) => !(a.alias && a.description)).map((a) => {
|
|
712
|
+
const { name: c, type: o, alias: l, description: m } = a;
|
|
686
713
|
return [`Name: ${c}`, `Type: ${o}`, `Alias: ${l}`, `Description: ${m ?? "N/A"}`].join(", ");
|
|
687
714
|
}).join(`
|
|
688
715
|
`);
|
|
689
716
|
if (n.length === 0)
|
|
690
|
-
return
|
|
717
|
+
return j(e, { fields: [] });
|
|
691
718
|
const s = {
|
|
692
719
|
existingItemTitle: e.portalItem?.title,
|
|
693
720
|
existingItemDescription: e.portalItem?.description,
|
|
694
721
|
existingLayerTitle: e.title,
|
|
695
722
|
existingLayerDescription: e.portalItem?.description,
|
|
696
723
|
fieldInformation: n
|
|
697
|
-
},
|
|
724
|
+
}, i = await T({
|
|
698
725
|
promptText: r,
|
|
699
|
-
schema:
|
|
726
|
+
schema: ze,
|
|
700
727
|
inputVariables: s
|
|
701
728
|
});
|
|
702
|
-
return
|
|
703
|
-
},
|
|
704
|
-
title:
|
|
705
|
-
description:
|
|
706
|
-
name:
|
|
707
|
-
}),
|
|
708
|
-
const n = await
|
|
729
|
+
return j(e, i);
|
|
730
|
+
}, Ke = u.object({
|
|
731
|
+
title: u.string(),
|
|
732
|
+
description: u.string(),
|
|
733
|
+
name: u.string().nullable()
|
|
734
|
+
}), Be = async (e, t) => {
|
|
735
|
+
const n = await M("layer_descriptions_prompt"), s = Array.from(t.values()), i = {
|
|
709
736
|
fieldInformation: JSON.stringify(s, null, 2),
|
|
710
737
|
existingLayerTitle: e.title,
|
|
711
738
|
existingLayerDescription: e.portalItem?.description,
|
|
712
739
|
existingLayerSnippet: e.portalItem?.snippet,
|
|
713
740
|
layerGeometryType: e.geometryType
|
|
714
741
|
};
|
|
715
|
-
return { ...await
|
|
742
|
+
return { ...await T({
|
|
716
743
|
promptText: n,
|
|
717
|
-
schema:
|
|
718
|
-
inputVariables:
|
|
744
|
+
schema: Ke,
|
|
745
|
+
inputVariables: i
|
|
719
746
|
}), name: e.title ?? null };
|
|
720
|
-
},
|
|
747
|
+
}, Je = async (e) => {
|
|
721
748
|
const t = e.allLayers.toArray(), r = [], n = /* @__PURE__ */ new Map();
|
|
722
749
|
for (const s of t)
|
|
723
750
|
if (s instanceof H) {
|
|
724
|
-
const
|
|
725
|
-
const
|
|
726
|
-
n.set(s.id, { layerItem: c, fieldRegistry:
|
|
751
|
+
const i = (async () => {
|
|
752
|
+
const a = await Ge(s), c = await Be(s, a);
|
|
753
|
+
n.set(s.id, { layerItem: c, fieldRegistry: a });
|
|
727
754
|
})();
|
|
728
|
-
r.push(
|
|
755
|
+
r.push(i);
|
|
729
756
|
}
|
|
730
757
|
return await Promise.all(r), n;
|
|
731
|
-
},
|
|
732
|
-
await
|
|
733
|
-
const t = await
|
|
734
|
-
schemaVersion:
|
|
758
|
+
}, lt = async (e) => {
|
|
759
|
+
await q.whenOnce(() => e.ready);
|
|
760
|
+
const t = await Je(e.map), { layers: r } = await Xe(t), n = {
|
|
761
|
+
schemaVersion: J,
|
|
735
762
|
modified: Date.now(),
|
|
736
763
|
embeddings: {
|
|
737
|
-
modelProvider:
|
|
738
|
-
model:
|
|
739
|
-
dimensions:
|
|
764
|
+
modelProvider: X,
|
|
765
|
+
model: Q,
|
|
766
|
+
dimensions: w,
|
|
740
767
|
templates: {
|
|
741
768
|
layer: C,
|
|
742
|
-
field:
|
|
769
|
+
field: A
|
|
743
770
|
}
|
|
744
771
|
},
|
|
745
772
|
layers: r
|
|
746
|
-
}, s =
|
|
773
|
+
}, s = Y.safeParse(n);
|
|
747
774
|
if (!s.success)
|
|
748
775
|
throw console.error("Schema Mismatch:", s.error.format()), new Error("Webmap embedding generation failed validation.");
|
|
749
776
|
return s.data;
|
|
750
|
-
},
|
|
777
|
+
}, Xe = async (e) => {
|
|
751
778
|
const t = [], r = [];
|
|
752
|
-
for (const [
|
|
753
|
-
const l =
|
|
779
|
+
for (const [a, { fieldRegistry: c, layerItem: o }] of e.entries()) {
|
|
780
|
+
const l = U(C, {
|
|
754
781
|
name: o.name,
|
|
755
782
|
title: o.title,
|
|
756
783
|
description: o.description
|
|
757
784
|
});
|
|
758
785
|
t.push(l);
|
|
759
786
|
const m = {
|
|
760
|
-
id:
|
|
787
|
+
id: a,
|
|
761
788
|
name: o.name ?? "",
|
|
762
789
|
title: o.title,
|
|
763
790
|
description: o.description,
|
|
764
791
|
vector: [],
|
|
765
792
|
fields: []
|
|
766
793
|
};
|
|
767
|
-
for (const [,
|
|
768
|
-
const
|
|
769
|
-
name:
|
|
770
|
-
alias:
|
|
771
|
-
description:
|
|
794
|
+
for (const [, p] of c.entries()) {
|
|
795
|
+
const y = U(A, {
|
|
796
|
+
name: p.name,
|
|
797
|
+
alias: p.alias,
|
|
798
|
+
description: p.description
|
|
772
799
|
});
|
|
773
|
-
t.push(
|
|
774
|
-
name:
|
|
775
|
-
alias:
|
|
776
|
-
description:
|
|
800
|
+
t.push(y), m.fields.push({
|
|
801
|
+
name: p.name,
|
|
802
|
+
alias: p.alias,
|
|
803
|
+
description: p.description,
|
|
777
804
|
vector: []
|
|
778
805
|
});
|
|
779
806
|
}
|
|
780
807
|
r.push(m);
|
|
781
808
|
}
|
|
782
|
-
const n = await
|
|
809
|
+
const n = await K(t);
|
|
783
810
|
let s = 0;
|
|
784
|
-
return { layers: r.map((
|
|
811
|
+
return { layers: r.map((a) => (a.vector = n[s++], a.fields.forEach((c) => {
|
|
785
812
|
c.vector = n[s++];
|
|
786
|
-
}),
|
|
787
|
-
},
|
|
813
|
+
}), a)) };
|
|
814
|
+
}, U = (e, t) => e.replace(/\{(\w+)\}/gu, (r, n) => t[n] ?? ""), mt = (e, t) => {
|
|
788
815
|
if (e.length !== t.length)
|
|
789
816
|
throw new Error("Vectors must be the same length");
|
|
790
817
|
let r = 0, n = 0, s = 0;
|
|
@@ -792,20 +819,20 @@ const Oe = async (e) => {
|
|
|
792
819
|
const o = e[c], l = t[c];
|
|
793
820
|
r += o * l, n += o * o, s += l * l;
|
|
794
821
|
}
|
|
795
|
-
const
|
|
796
|
-
if (
|
|
822
|
+
const i = Math.sqrt(n * s);
|
|
823
|
+
if (i === 0)
|
|
797
824
|
return 0;
|
|
798
|
-
const
|
|
799
|
-
return Math.max(-1, Math.min(1,
|
|
825
|
+
const a = r / i;
|
|
826
|
+
return Math.max(-1, Math.min(1, a));
|
|
800
827
|
};
|
|
801
828
|
export {
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
829
|
+
Z as Orchestrator,
|
|
830
|
+
mt as cosineSimilarity,
|
|
831
|
+
lt as createWebmapEmbeddings,
|
|
832
|
+
K as getEmbeddings,
|
|
833
|
+
T as invokeStructuredPrompt,
|
|
834
|
+
ct as invokeTextPrompt,
|
|
835
|
+
dt as invokeToolPrompt,
|
|
836
|
+
h as sendTraceMessage,
|
|
837
|
+
ot as sendUXSuggestion
|
|
811
838
|
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const e = `## GIS Agent Orchestrator
|
|
2
|
+
|
|
3
|
+
You are an orchestrator for an ArcGIS Maps SDK for JavaScript system.
|
|
4
|
+
|
|
5
|
+
Your job is to decide the single best next agent to execute for the current step.
|
|
6
|
+
|
|
7
|
+
You are given:
|
|
8
|
+
|
|
9
|
+
- the latest user request
|
|
10
|
+
- relevant chat history
|
|
11
|
+
- the list of registered agents
|
|
12
|
+
- optional prior steps from earlier agent executions
|
|
13
|
+
|
|
14
|
+
Return either:
|
|
15
|
+
|
|
16
|
+
- one decision with:
|
|
17
|
+
1. \`agentId\` — the next agent to execute
|
|
18
|
+
2. \`assignedTask\` — a clear, actionable task for that agent
|
|
19
|
+
3. \`requiresFollowUp\` — whether another orchestration step will likely be needed after this agent succeeds
|
|
20
|
+
- or \`null\` if no registered agent applies
|
|
21
|
+
|
|
22
|
+
Latest user request:
|
|
23
|
+
{userRequest}
|
|
24
|
+
|
|
25
|
+
Registered agents are provided in this format:
|
|
26
|
+
{{id: string, name: string, description: string}}[]
|
|
27
|
+
|
|
28
|
+
{registeredAgents}
|
|
29
|
+
|
|
30
|
+
Prior steps performed by agents are provided:
|
|
31
|
+
|
|
32
|
+
Each step has:
|
|
33
|
+
|
|
34
|
+
- agentId: string
|
|
35
|
+
- assignedTask: string
|
|
36
|
+
- summary: string
|
|
37
|
+
- status: "success" | "failed" | "partial"
|
|
38
|
+
|
|
39
|
+
Use prior steps to:
|
|
40
|
+
|
|
41
|
+
- Avoid repeating work that has already succeeded
|
|
42
|
+
- Continue or refine steps that were partial
|
|
43
|
+
- Retry or adjust steps that failed when appropriate
|
|
44
|
+
|
|
45
|
+
{priorSteps}
|
|
46
|
+
|
|
47
|
+
Rules:
|
|
48
|
+
|
|
49
|
+
- Focus primarily on the latest user request.
|
|
50
|
+
- Use relevant chat history only when the latest request clearly depends on earlier context; otherwise ignore it.
|
|
51
|
+
- Use prior steps to determine what has already been attempted or completed.
|
|
52
|
+
- Do not plan the full workflow up front. Only decide the next best step.
|
|
53
|
+
- Prefer an agent that can directly complete the user’s request.
|
|
54
|
+
- Only break the request into multiple steps when necessary.
|
|
55
|
+
|
|
56
|
+
Assigned Task Guidelines (IMPORTANT):
|
|
57
|
+
|
|
58
|
+
- The assignedTask should be specific, short, and directly executable by the selected agent.
|
|
59
|
+
- Keep it as close as possible to the user’s request.
|
|
60
|
+
- Prefer minimal transformation of the user’s wording.
|
|
61
|
+
- It should be a concise restatement, not a rewritten or expanded version.
|
|
62
|
+
- Do not rephrase into more detailed or formal language than the user’s request.
|
|
63
|
+
- Use only information explicitly present in the user request or provided context.
|
|
64
|
+
- Do not enrich, elaborate, or add unstated details.
|
|
65
|
+
- Do not clarify or expand the request beyond what the user explicitly stated.
|
|
66
|
+
- Do not add implementation details, UI behavior, or inferred steps.
|
|
67
|
+
- The assignedTask may represent only part of the user’s full request when multiple steps are necessary.
|
|
68
|
+
|
|
69
|
+
requiresFollowUp Guidelines:
|
|
70
|
+
|
|
71
|
+
- requiresFollowUp should indicate a likely next agent step, not uncertainty about the current request.
|
|
72
|
+
- Set requiresFollowUp to true only when another orchestration step will likely be needed after this agent succeeds.
|
|
73
|
+
- Set requiresFollowUp to false when a successful result from this agent would likely complete the user-visible task.
|
|
74
|
+
`;
|
|
75
|
+
export {
|
|
76
|
+
e as default
|
|
77
|
+
};
|
package/dist/models/types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type ChatModelTier = "advanced" | "default";
|
|
1
|
+
export type ChatModelTier = "advanced" | "default" | "fast";
|
|
2
2
|
export type EmbeddingModelTier = "default";
|
|
@@ -23,6 +23,7 @@ export declare class Orchestrator {
|
|
|
23
23
|
private embeddingsWorker?;
|
|
24
24
|
private graph?;
|
|
25
25
|
private chatHistory;
|
|
26
|
+
private priorSteps;
|
|
26
27
|
private threadId;
|
|
27
28
|
private agentRegistry;
|
|
28
29
|
private layersAndFieldsRegistry?;
|
|
@@ -46,7 +47,7 @@ export declare class Orchestrator {
|
|
|
46
47
|
*/
|
|
47
48
|
ask(userInput: string): AsyncGenerator<OrchestratorEvent>;
|
|
48
49
|
/**
|
|
49
|
-
* Start a new conversation by clearing chat history.
|
|
50
|
+
* Start a new conversation by clearing chat history and prior steps.
|
|
50
51
|
*/
|
|
51
52
|
newConversation(): void;
|
|
52
53
|
/**
|
package/dist/types/types.d.ts
CHANGED
|
@@ -66,12 +66,13 @@ export interface AgentExecutionContext {
|
|
|
66
66
|
}
|
|
67
67
|
export interface PriorStep {
|
|
68
68
|
agentId: string;
|
|
69
|
+
assignedTask: string;
|
|
69
70
|
summary: string;
|
|
70
71
|
status: AgentStatus;
|
|
71
72
|
}
|
|
72
73
|
export interface AgentResult {
|
|
73
|
-
status?: AgentStatus;
|
|
74
74
|
outputMessage?: string;
|
|
75
|
-
summary
|
|
75
|
+
summary: string;
|
|
76
|
+
status: AgentStatus;
|
|
76
77
|
}
|
|
77
78
|
export type AgentStatus = "failed" | "partial" | "success";
|
package/package.json
CHANGED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
const e = `## GIS Feature Layer Intent Classifier
|
|
2
|
-
|
|
3
|
-
You are an assistant that classifies user intent in ArcGIS Online Map Viewer.
|
|
4
|
-
|
|
5
|
-
Return **up to {maxIntents} intents in the exact order they should be executed** for the user's request.
|
|
6
|
-
If none apply, return an **empty list** (no "none" label).
|
|
7
|
-
|
|
8
|
-
Choose only from registered agents. Input format will be: {{id: string, name: string, description: string}}[]
|
|
9
|
-
{registeredAgents}
|
|
10
|
-
|
|
11
|
-
Rules:
|
|
12
|
-
|
|
13
|
-
- Pay primary attention to the **latest user query** when determining intents. Use the full context only if the latest query explicitly depends on it.
|
|
14
|
-
- Output 0–{maxIntents} items, ordered for execution.
|
|
15
|
-
- Do **not** include any labels outside the list above.
|
|
16
|
-
- Do **not** include "none"; return an empty list instead when unrelated questions like labels, popups, etc.
|
|
17
|
-
- If none apply, return an empty array [].
|
|
18
|
-
- Each returned intent must be supported by evidence in the user request. Don’t add ‘nice-to-have’ follow-up intents.
|
|
19
|
-
`;
|
|
20
|
-
export {
|
|
21
|
-
e as default
|
|
22
|
-
};
|