@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.
@@ -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 R from "@arcgis/core/identity/IdentityManager.js";
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 Z, START as ee, END as te, MemorySaver as ne } from "@langchain/langgraph/web";
4
- import { HumanMessage as W, AIMessage as N, isAIMessage as re, isToolMessage as se } from "@langchain/core/messages";
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 p, { z as d } from "zod";
7
- import { SystemMessagePromptTemplate as ie, ChatPromptTemplate as ae } from "@langchain/core/prompts";
8
- import { OpenAIEmbeddings as oe, ChatOpenAI as ce } from "@langchain/openai";
9
- import * as U from "@arcgis/core/core/reactiveUtils.js";
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 de from "@arcgis/core/request.js";
12
- const q = {
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
- }, M = /* @__PURE__ */ new Map();
18
- let E = null;
19
- const le = () => {
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
- }, O = async (e) => {
25
- const t = le();
26
- M.size === 0 && (E || (E = (async () => {
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((a) => M.set(a.name, a));
32
+ (await n.json()).models.forEach((i) => E.set(i.name, i));
32
33
  } catch (n) {
33
- throw E = null, n;
34
+ throw v = null, n;
34
35
  }
35
- })()), await E);
36
- const r = M.get(e);
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
- }, me = async (e = "default") => await O(q[e]), V = async (e = "default") => await O(S[e]), ge = async (e) => {
41
- const t = await pe(), r = await V("default"), n = x.getDefault(), a = (await R.getCredential(`${n.url}/sharing`)).token, i = {
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: a }
45
+ auth: { apiUrl: r, token: i }
45
46
  };
46
- return t.postMessage(i), await new Promise((c, o) => {
47
- const l = (g) => {
48
- g.data === "completed" && (t.removeEventListener("message", l), c());
49
- }, m = (g) => {
50
- t.removeEventListener("message", l), o(g instanceof Error ? g : new Error("Embeddings worker error"));
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
- }, pe = async () => {
55
+ }, he = async () => {
55
56
  {
56
57
  const e = (await import("./embeddings.worker-GH7zdYqF.js")).default;
57
58
  return new e();
58
59
  }
59
- }, L = (e, t) => t, ue = (e, t) => ({
60
+ }, D = (e, t) => t, fe = (e, t) => ({
60
61
  ...e,
61
62
  ...t
62
- }), he = b.Root({
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: ue
71
- }),
72
- pendingIntents: b({
73
- default: () => [],
74
- reducer: L
71
+ reducer: fe
75
72
  }),
76
73
  currentIntent: b({
77
74
  default: () => "none",
78
- reducer: L
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
- }), f = async (e, t) => {
85
+ }), h = async (e, t) => {
81
86
  await P("trace_message", e, t);
82
- }, st = async (e, t) => {
87
+ }, ot = async (e, t) => {
83
88
  await P("graph_ux_suggestion", e, t);
84
- }, fe = (e) => {
85
- e.currentIntent = "none", e.pendingIntents = [];
86
- }, ye = async (e, t) => {
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], fe(e);
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 f({ text: `Available agents: ${[...r].join(", ")}` }, t), await f({ text: "Analyzing user input" }, t), e;
93
- }, we = async (e, t) => (await f({ text: "Exiting..." }, t), e), ve = (e) => {
94
- if (e.pendingIntents.length === 0)
95
- return {
96
- ...e,
97
- currentIntent: "none"
98
- };
99
- const [t, ...r] = e.pendingIntents;
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
- ...e,
102
- currentIntent: t,
103
- pendingIntents: r
108
+ outputMessage: r,
109
+ summary: n ?? r ?? xe(i),
110
+ status: i
104
111
  };
105
- }, _ = 4e3, be = async (e, t) => {
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 f({ text: `Executing registered agent: ${s.agent.name}` }, t);
110
- const a = {
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
- }, i = await s.agent.createGraph().compile().invoke(
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
- a
132
+ i
126
133
  );
127
- await f({ text: `Finished executing registered agent: ${s.agent.name}` }, t);
128
- const c = typeof i?.outputMessage == "string" ? i.outputMessage.trim() : "", o = {
129
- outputMessage: c,
130
- // TODO: handle summary and status in the agent graph and return here
131
- summary: typeof i?.summary == "string" ? i.summary.trim() : c,
132
- status: typeof i?.status == "string" ? i.status : "partial"
133
- }, l = typeof o?.outputMessage == "string" ? o.outputMessage.trim() : "";
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: [...e.agentExecutionContext.messages, new N(m)]
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
- }, Ee = (e, t, r) => {
158
+ }, Se = (e, t, r) => {
146
159
  const n = e[t];
147
- return n ? typeof n == "function" ? n() : Promise.resolve(n) : new Promise((s, a) => {
148
- (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." : ""))));
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
- }, k = async (e) => (await Ee(/* @__PURE__ */ Object.assign({ "./field_descriptions_prompt.md": () => import("./field_descriptions_prompt-haMV_aoG.js"), "./intent_prompt.md": () => import("./intent_prompt-CRmsldou.js"), "./layer_descriptions_prompt.md": () => import("./layer_descriptions_prompt-NAaKWdJi.js") }), `./${e}.md`, 2)).default, xe = (e, t = 3) => e.filter((r) => r.type === "human").slice(-t), Ie = (e) => {
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
- }, z = (e) => async (t, r) => {
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
- }, D = async (e = "default", t = 0) => {
166
- const r = x.getDefault(), n = await R.getCredential(`${r.url}/sharing`), s = q[e], a = await me(e);
167
- return new ce({
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: a,
174
- fetch: z(n.token)
186
+ baseURL: i,
187
+ fetch: G(n.token)
175
188
  }
176
189
  });
177
- }, Me = async (e = "default") => {
178
- const t = x.getDefault(), r = await R.getCredential(`${t.url}/sharing`), n = S[e], s = await V(e);
179
- return new oe({
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: z(r.token)
197
+ fetch: G(r.token)
185
198
  },
186
199
  batchSize: 2048,
187
200
  maxConcurrency: 10
188
201
  });
189
- }, Re = (e) => {
202
+ }, Te = (e) => {
190
203
  const t = /* @__PURE__ */ new Set();
191
204
  for (const n of e)
192
- if (re(n)) {
205
+ if (ie(n)) {
193
206
  const s = n;
194
- s.tool_calls && s.tool_calls.length > 0 && s.tool_calls.forEach((a) => {
195
- a.id && t.add(a.id);
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 (se(n)) {
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
- }, T = (e, t) => {
206
- const r = ie.fromTemplate(e);
207
- return ae.fromMessages([r, ...t]);
208
- }, Se = async (e) => {
209
- const { promptText: t, modelTier: r, temperature: n, messages: s } = e, a = T(t, s ?? []), i = await D(r, n);
210
- return a.pipe(i);
211
- }, it = async (e) => {
212
- const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables: a } = e, c = await (await Se({
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(a ?? {});
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
- }, A = async (e) => {
223
- const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables: a, schema: i } = e, c = T(t, s ?? []), l = (await D(r, n)).withStructuredOutput(i);
224
- return await c.pipe(l).invoke(a ?? {});
225
- }, at = async (e) => {
226
- const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables: a, tools: i } = e, c = i.length > 0 ? Re(s ?? []) : s ?? [], o = T(t, c), l = await D(r, n);
227
- return await o.pipe(l.bindTools(i)).invoke(a ?? {});
228
- }, ke = d.object({
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(ke);
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
- intents: d.array(r)
250
+ intent: r.nullable(),
251
+ assignedTask: d.string().nullable(),
252
+ requiresFollowUp: d.boolean()
238
253
  });
239
- }, Te = async (e, t) => {
254
+ }, Fe = async (e, t) => {
240
255
  try {
241
- await f({ text: "Asking LLM to detect intents" }, t);
242
- const n = await k("intent_prompt"), i = (t?.configurable?.services.agentRegistry?.list() ?? []).map(({ agent: y }) => ({
243
- id: y.id,
244
- name: y.name,
245
- description: y.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 (!i.length)
248
- return await f({ text: "No agents registered; skipping intent detection" }, t), {
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 = i.map((y) => JSON.stringify(y)).join(`
254
- `), o = i.length, l = De(i), m = {
255
- maxIntents: o,
256
- registeredAgents: c
257
- }, g = await A({
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: l,
260
- messages: xe(e.agentExecutionContext.messages),
261
- inputVariables: m
262
- }), w = /* @__PURE__ */ new Set(), h = (g.intents ?? []).filter((y) => w.has(y) ? !1 : (w.add(y), !0)).slice(0, o), u = h[0] ?? "none", I = {
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: u,
265
- pendingIntents: h
281
+ currentIntent: p,
282
+ requiresFollowUp: m.requiresFollowUp,
283
+ agentExecutionContext: {
284
+ ...e.agentExecutionContext,
285
+ assignedTask: m.assignedTask ?? ""
286
+ }
266
287
  };
267
- return await f({ text: `Intents came back as: ${h.join(", ") || "none"}` }, t), I;
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 f({ text: "Error during intent detection" }, t), new Error(`Error during intent detection: ${r instanceof Error ? r.message : String(r)}`);
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
- }, Ae = () => new Z(he).addNode("ingestInput", ye).addNode("intentLLM", Te).addNode("intentDispatcher", ve).addNode("executeRegisteredAgent", be).addNode("exit", we).addEdge(ee, "ingestInput").addEdge("ingestInput", "intentLLM").addEdge("intentLLM", "intentDispatcher").addConditionalEdges(
272
- "intentDispatcher",
273
- (t) => t.currentIntent === "none" ? "exit" : "executeRegisteredAgent"
274
- ).addEdge("executeRegisteredAgent", "intentDispatcher").addEdge("exit", te);
275
- class Ce {
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 Fe {
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 G = async (e) => {
366
+ const K = async (e) => {
340
367
  try {
341
- return await (await Me()).embedDocuments(e);
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
- }, K = async (e, t) => {
372
+ }, B = async (e, t) => {
346
373
  const r = t.get(e);
347
374
  if (r)
348
375
  return r;
349
- const n = await G([e]);
376
+ const n = await K([e]);
350
377
  return t.set(e, n[0]), n[0];
351
378
  };
352
- async function Le(e, t, r, n) {
353
- const s = `req-${Date.now()}`, i = {
379
+ async function je(e, t, r, n) {
380
+ const s = `req-${Date.now()}`, a = {
354
381
  type: "layerSearch",
355
- precomputedEmbedding: n ? await K(e, n) : void 0,
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(i);
390
+ t.addEventListener("message", o, { once: !0 }), t.postMessage(a);
364
391
  });
365
392
  }
366
- function _e(e) {
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 Le(r, t, n, s);
401
+ return await je(r, t, n, s);
375
402
  }
376
403
  };
377
404
  }
378
- const $e = async ({
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: a
411
+ embeddingCache: i
385
412
  }) => {
386
- const i = `req-${Date.now()}`, c = a ? await K(e, a) : void 0, o = {
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: i,
417
+ requestId: a,
391
418
  minScore: n,
392
419
  topResults: s
393
420
  };
394
421
  return await new Promise((l) => {
395
- const m = (g) => {
396
- if (g.data.requestId !== i)
422
+ const m = (p) => {
423
+ if (p.data.requestId !== a)
397
424
  return;
398
- const w = g.data.results.map(({ layerId: h, results: u }) => ({
399
- layerId: h,
400
- results: u
425
+ const y = p.data.results.map(({ layerId: g, results: f }) => ({
426
+ layerId: g,
427
+ results: f
401
428
  }));
402
- l(w);
429
+ l(y);
403
430
  };
404
431
  r.addEventListener("message", m, { once: !0 }), r.postMessage(o);
405
432
  });
406
433
  };
407
- function je(e) {
434
+ function Ne(e) {
408
435
  const { worker: t } = e;
409
436
  return {
410
- async searchFields({ text: r, layerIds: n, minScore: s, topResults: a, embeddingCache: i }) {
411
- return await $e({
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: a,
417
- embeddingCache: i
443
+ topResults: i,
444
+ embeddingCache: a
418
445
  });
419
446
  }
420
447
  };
421
448
  }
422
- const B = "0.1", v = 1536, J = "openai", X = S.default, C = `Name: {name}
449
+ const J = "0.1", w = 1536, X = "openai", Q = S.default, C = `Name: {name}
423
450
  Title: {title}
424
- Description: {description}`, F = `Name: {name}
451
+ Description: {description}`, A = `Name: {name}
425
452
  Alias: {alias}
426
- Description: {description}`, Q = d.object({
427
- schemaVersion: d.literal(B),
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(J),
431
- model: d.literal(X),
432
- dimensions: d.literal(v),
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(F)
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(v, {
445
- message: `Layer vector must be exactly ${v} dimensions`
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(v, {
453
- message: `Field vector must be exactly ${v} dimensions`
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
- }), We = (e) => {
460
- const t = Q.safeParse(e);
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
- }, Ne = (e, t) => {
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 a = n.get(s.id);
472
- if (!a)
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 !== a.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 i = {
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 = a.fieldsIndex.get(o.name);
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: a.getFieldDomain(o.name) ?? void 0
524
+ domain: i.getFieldDomain(o.name) ?? void 0
498
525
  });
499
526
  }
500
527
  r.set(s.id, {
501
- layerItem: i,
528
+ layerItem: a,
502
529
  fieldRegistry: c
503
530
  });
504
531
  }
505
532
  return r;
506
- }, Pe = async (e) => {
533
+ }, He = async (e) => {
507
534
  try {
508
- return (await de(e, {
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
- }, Ue = async (e) => {
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((i) => i.resource.path === "embeddings-v01.json");
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 Pe(n.resource.url);
522
- return We(s);
548
+ const s = await He(n.resource.url);
549
+ return Pe(s);
523
550
  };
524
- class Y {
551
+ class Z {
525
552
  constructor() {
526
- this.orchestratorReady = !1, this.chatHistory = [], this.threadId = "", this.agentRegistry = new Ce(), this.streamEpoch = 0;
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 Y();
561
+ const r = new Z();
535
562
  try {
536
563
  if (t.view?.map) {
537
- await U.whenOnce(() => t.view.ready);
538
- const n = await Ue(t.view), s = Ne(
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 ge(n);
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 = Ae().compile({ checkpointer: new ne() }));
567
- const r = this.embeddingsWorker ? _e({ worker: this.embeddingsWorker }) : void 0, n = this.embeddingsWorker ? je({ worker: this.embeddingsWorker }) : void 0, s = /* @__PURE__ */ new Map(), i = {
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
- i
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 h = (await this.graph.getState(i, { subgraphs: !0 })).tasks.find((u) => u.interrupts.length > 0)?.interrupts[0]?.value;
589
- if (!h)
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 = h, this.interruptHandler = new Fe(this.graph, i), yield { runId: this.threadId, timestamp: Date.now(), type: "interrupt", interrupt: h };
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 u = await this.interruptHandler.waitForUser(), I = ++this.streamEpoch;
594
- yield* this.pipeStream(u, I);
595
- } catch (u) {
596
- if (u) {
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: u?.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(i, { subgraphs: !0 })).values;
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: Ie(m.agentExecutionContext.messages) }
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 He = p.object({
661
- name: p.string(),
662
- description: p.string(),
663
- valueType: p.string(),
664
- alias: p.string()
665
- }), qe = p.object({
666
- fields: p.array(He)
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 $(e, t) {
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((i) => i.name === n.name), a = {
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, a);
706
+ r.set(n.name, i);
680
707
  }
681
708
  return r;
682
709
  }
683
- const Oe = async (e) => {
684
- const r = await k("field_descriptions_prompt"), n = e.fields.filter((i) => !(i.alias && i.description)).map((i) => {
685
- const { name: c, type: o, alias: l, description: m } = i;
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 $(e, { fields: [] });
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
- }, a = await A({
724
+ }, i = await T({
698
725
  promptText: r,
699
- schema: qe,
726
+ schema: ze,
700
727
  inputVariables: s
701
728
  });
702
- return $(e, a);
703
- }, Ve = p.object({
704
- title: p.string(),
705
- description: p.string(),
706
- name: p.string().nullable()
707
- }), ze = async (e, t) => {
708
- const n = await k("layer_descriptions_prompt"), s = Array.from(t.values()), a = {
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 A({
742
+ return { ...await T({
716
743
  promptText: n,
717
- schema: Ve,
718
- inputVariables: a
744
+ schema: Ke,
745
+ inputVariables: i
719
746
  }), name: e.title ?? null };
720
- }, Ge = async (e) => {
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 a = (async () => {
725
- const i = await Oe(s), c = await ze(s, i);
726
- n.set(s.id, { layerItem: c, fieldRegistry: i });
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(a);
755
+ r.push(i);
729
756
  }
730
757
  return await Promise.all(r), n;
731
- }, ot = async (e) => {
732
- await U.whenOnce(() => e.ready);
733
- const t = await Ge(e.map), { layers: r } = await Ke(t), n = {
734
- schemaVersion: B,
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: J,
738
- model: X,
739
- dimensions: v,
764
+ modelProvider: X,
765
+ model: Q,
766
+ dimensions: w,
740
767
  templates: {
741
768
  layer: C,
742
- field: F
769
+ field: A
743
770
  }
744
771
  },
745
772
  layers: r
746
- }, s = Q.safeParse(n);
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
- }, Ke = async (e) => {
777
+ }, Xe = async (e) => {
751
778
  const t = [], r = [];
752
- for (const [i, { fieldRegistry: c, layerItem: o }] of e.entries()) {
753
- const l = j(C, {
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: i,
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 [, g] of c.entries()) {
768
- const w = j(F, {
769
- name: g.name,
770
- alias: g.alias,
771
- description: g.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(w), m.fields.push({
774
- name: g.name,
775
- alias: g.alias,
776
- description: g.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 G(t);
809
+ const n = await K(t);
783
810
  let s = 0;
784
- return { layers: r.map((i) => (i.vector = n[s++], i.fields.forEach((c) => {
811
+ return { layers: r.map((a) => (a.vector = n[s++], a.fields.forEach((c) => {
785
812
  c.vector = n[s++];
786
- }), i)) };
787
- }, j = (e, t) => e.replace(/\{(\w+)\}/gu, (r, n) => t[n] ?? ""), ct = (e, t) => {
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 a = Math.sqrt(n * s);
796
- if (a === 0)
822
+ const i = Math.sqrt(n * s);
823
+ if (i === 0)
797
824
  return 0;
798
- const i = r / a;
799
- return Math.max(-1, Math.min(1, i));
825
+ const a = r / i;
826
+ return Math.max(-1, Math.min(1, a));
800
827
  };
801
828
  export {
802
- Y as Orchestrator,
803
- ct as cosineSimilarity,
804
- ot as createWebmapEmbeddings,
805
- G as getEmbeddings,
806
- A as invokeStructuredPrompt,
807
- it as invokeTextPrompt,
808
- at as invokeToolPrompt,
809
- f as sendTraceMessage,
810
- st as sendUXSuggestion
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
+ };
@@ -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
  /**
@@ -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?: string;
75
+ summary: string;
76
+ status: AgentStatus;
76
77
  }
77
78
  export type AgentStatus = "failed" | "partial" | "success";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcgis/ai-orchestrator",
3
- "version": "5.1.0-next.67",
3
+ "version": "5.1.0-next.69",
4
4
  "description": "ArcGIS AI Orchestrator Package",
5
5
  "homepage": "https://developers.arcgis.com/javascript/latest/",
6
6
  "type": "module",
@@ -1,2 +0,0 @@
1
- import { DispatcherGraphStateType } from '../state/dispatcherGraphState';
2
- export declare const intentDispatcher: (state: DispatcherGraphStateType) => DispatcherGraphStateType;
@@ -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
- };