@arcgis/ai-orchestrator 5.1.0-next.102 → 5.1.0-next.103

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.
@@ -3,6 +3,7 @@ type WritableAgentExecutionContext<TState extends SharedState = SharedState> = A
3
3
  export declare const DispatcherGraphState: import('@langchain/langgraph').AnnotationRoot<{
4
4
  agentExecutionContext: import('@langchain/langgraph').BaseChannel<WritableAgentExecutionContext<SharedState<Record<string, unknown>>>, WritableAgentExecutionContext<SharedState<Record<string, unknown>>> | import('@langchain/langgraph').OverwriteValue<WritableAgentExecutionContext<SharedState<Record<string, unknown>>>>, unknown>;
5
5
  currentIntent: import('@langchain/langgraph').BaseChannel<string, string | import('@langchain/langgraph').OverwriteValue<string>, unknown>;
6
+ lastExecutedAgent: import('@langchain/langgraph').BaseChannel<string, string | import('@langchain/langgraph').OverwriteValue<string>, unknown>;
6
7
  requiresFollowUp: import('@langchain/langgraph').BaseChannel<boolean, boolean | import('@langchain/langgraph').OverwriteValue<boolean>, unknown>;
7
8
  stepCount: import('@langchain/langgraph').BaseChannel<number, number | import('@langchain/langgraph').OverwriteValue<number>, unknown>;
8
9
  finalOutputMessage: import('@langchain/langgraph').BaseChannel<string, string | import('@langchain/langgraph').OverwriteValue<string>, unknown>;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import A from "@arcgis/core/identity/IdentityManager.js";
2
2
  import I from "@arcgis/core/portal/Portal.js";
3
- import { Annotation as h, isGraphInterrupt as oe, StateGraph as ce, START as de, END as le, MemorySaver as ue } from "@langchain/langgraph/web";
3
+ import { Annotation as p, isGraphInterrupt as oe, StateGraph as ce, START as de, END as le, MemorySaver as ue } from "@langchain/langgraph/web";
4
4
  import { HumanMessage as ge, AIMessage as W, isAIMessage as me, isToolMessage as pe } from "@langchain/core/messages";
5
5
  import { dispatchCustomEvent as N } from "@langchain/core/callbacks/dispatch/web";
6
6
  import f, { z as l } from "zod";
@@ -9,7 +9,7 @@ import { createAgent as fe, summarizationMiddleware as ye, modelCallLimitMiddlew
9
9
  import { ChatOpenAI as ve, OpenAIEmbeddings as xe } from "@langchain/openai";
10
10
  import * as H from "@arcgis/core/core/reactiveUtils.js";
11
11
  import V from "@arcgis/core/layers/FeatureLayer.js";
12
- import be from "@arcgis/core/request.js";
12
+ import Ee from "@arcgis/core/request.js";
13
13
  const z = {
14
14
  advanced: "gpt-5.2",
15
15
  default: "gpt-5-mini",
@@ -18,13 +18,13 @@ const z = {
18
18
  default: "text-embedding-ada-002"
19
19
  }, k = /* @__PURE__ */ new Map();
20
20
  let S = null;
21
- const Ee = () => {
21
+ const be = () => {
22
22
  const t = I.getDefault().helperServices;
23
23
  if (!t?.aiModels?.url)
24
24
  throw new Error("AI Models Service URL is not defined in the portal's helper services.");
25
25
  return t.aiModels.url;
26
26
  }, B = async (e) => {
27
- const t = Ee();
27
+ const t = be();
28
28
  k.size === 0 && (S || (S = (async () => {
29
29
  try {
30
30
  const n = await fetch(`${t}/models`);
@@ -58,7 +58,7 @@ const Ee = () => {
58
58
  const e = (await import("./embeddings.worker-GH7zdYqF.js")).default;
59
59
  return new e();
60
60
  }
61
- }, b = (e, t) => t, K = (e, t) => ({
61
+ }, x = (e, t) => t, K = (e, t) => ({
62
62
  ...e,
63
63
  ...t
64
64
  }), J = (e = "", t) => {
@@ -83,50 +83,54 @@ ${r}`;
83
83
  priorSteps: [],
84
84
  sharedState: {}
85
85
  }), ke = () => ({
86
- agentExecutionContext: h({
86
+ agentExecutionContext: p({
87
87
  reducer: K,
88
88
  default: X
89
89
  }),
90
- outputMessage: h({
90
+ outputMessage: p({
91
91
  reducer: J,
92
92
  default: () => ""
93
93
  }),
94
- summary: h({
95
- reducer: b,
94
+ summary: p({
95
+ reducer: x,
96
96
  default: () => ""
97
97
  }),
98
- status: h({
99
- reducer: b
98
+ status: p({
99
+ reducer: x
100
100
  })
101
- }), bt = () => ({
101
+ }), Et = () => ({
102
102
  ...ke(),
103
- sharedStatePatch: h({
104
- reducer: b
103
+ sharedStatePatch: p({
104
+ reducer: x
105
105
  })
106
- }), Re = h.Root({
107
- agentExecutionContext: h({
106
+ }), Re = p.Root({
107
+ agentExecutionContext: p({
108
108
  default: X,
109
109
  reducer: K
110
110
  }),
111
- currentIntent: h({
111
+ currentIntent: p({
112
112
  default: () => "none",
113
- reducer: b
113
+ reducer: x
114
114
  }),
115
- requiresFollowUp: h({
115
+ lastExecutedAgent: p({
116
+ default: () => "",
117
+ reducer: x
118
+ }),
119
+ requiresFollowUp: p({
116
120
  default: () => !0,
117
- reducer: b
121
+ reducer: x
118
122
  }),
119
- stepCount: h({
123
+ stepCount: p({
120
124
  default: () => 0,
121
125
  reducer: (e, t) => t ?? e + 1
122
126
  }),
123
- finalOutputMessage: h({
127
+ finalOutputMessage: p({
124
128
  default: () => "",
125
129
  reducer: J
126
130
  })
127
131
  }), y = async (e, t) => {
128
132
  await N("trace_message", e, t);
129
- }, Et = async (e, t) => {
133
+ }, bt = async (e, t) => {
130
134
  await N("graph_ux_suggestion", e, t);
131
135
  }, Ae = (e) => {
132
136
  e.currentIntent = "none";
@@ -243,6 +247,7 @@ ${r}`;
243
247
  return {
244
248
  ...e,
245
249
  stepCount: e.stepCount + 1,
250
+ lastExecutedAgent: s.agent.id,
246
251
  requiresFollowUp: i.status === "failed" ? !0 : e.requiresFollowUp,
247
252
  finalOutputMessage: o ?? "",
248
253
  agentExecutionContext: {
@@ -269,7 +274,7 @@ ${r}`;
269
274
  return n ? typeof n == "function" ? n() : Promise.resolve(n) : new Promise((s, a) => {
270
275
  (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." : ""))));
271
276
  });
272
- }, T = async (e) => (await qe(/* @__PURE__ */ Object.assign({ "./field_descriptions_prompt.md": () => import("./field_descriptions_prompt-haMV_aoG.js"), "./intent_prompt.md": () => import("./intent_prompt-D6yvMy34.js"), "./layer_descriptions_prompt.md": () => import("./layer_descriptions_prompt-NAaKWdJi.js") }), `./${e}.md`, 2)).default, Ue = async (e) => {
277
+ }, T = async (e) => (await qe(/* @__PURE__ */ Object.assign({ "./field_descriptions_prompt.md": () => import("./field_descriptions_prompt-haMV_aoG.js"), "./intent_prompt.md": () => import("./intent_prompt-BiBrlJFJ.js"), "./layer_descriptions_prompt.md": () => import("./layer_descriptions_prompt-NAaKWdJi.js") }), `./${e}.md`, 2)).default, Ue = async (e) => {
273
278
  const { agent: t, messages: r, config: n } = e;
274
279
  return { structuredResponse: (await t.invoke(
275
280
  {
@@ -283,7 +288,7 @@ ${r}`;
283
288
  ...r,
284
289
  headers: n
285
290
  });
286
- }, E = async (e = "default", t = 0) => {
291
+ }, b = async (e = "default", t = 0) => {
287
292
  const r = I.getDefault(), n = await A.getCredential(`${r.url}/sharing`), s = z[e], a = await Se(e);
288
293
  return new ve({
289
294
  modelName: s,
@@ -323,10 +328,10 @@ const U = (e) => JSON.stringify(e, null, 2), We = (e) => {
323
328
  }, Ne = async (e, t) => {
324
329
  try {
325
330
  await y({ text: "Asking LLM to route to an agent" }, t);
326
- const s = (t?.configurable?.services.agentRegistry?.list() ?? []).map(({ agent: x }) => ({
327
- id: x.id,
328
- name: x.name,
329
- description: x.description
331
+ const s = (t?.configurable?.services.agentRegistry?.list() ?? []).map(({ agent: E }) => ({
332
+ id: E.id,
333
+ name: E.name,
334
+ description: E.description
330
335
  }));
331
336
  if (!s.length)
332
337
  return await y({ text: "No agents registered; skipping intent detection" }, t), { ...e, currentIntent: "none" };
@@ -335,7 +340,7 @@ const U = (e) => JSON.stringify(e, null, 2), We = (e) => {
335
340
  priorSteps: U(e.agentExecutionContext.priorSteps),
336
341
  userRequest: e.agentExecutionContext.userRequest
337
342
  }, u = await O.fromTemplate(a).format(c), g = fe({
338
- model: await E("fast"),
343
+ model: await b("fast"),
339
344
  tools: [],
340
345
  systemPrompt: u,
341
346
  checkpointer: !0,
@@ -345,7 +350,7 @@ const U = (e) => JSON.stringify(e, null, 2), We = (e) => {
345
350
  // to control token usage without losing important intent signals.
346
351
  // The trigger and keep parameters can be tuned based on token limits and behavior.
347
352
  ye({
348
- model: await E("fast"),
353
+ model: await b("fast"),
349
354
  trigger: { tokens: 4e3 },
350
355
  keep: { messages: 6 }
351
356
  }),
@@ -357,19 +362,19 @@ const U = (e) => JSON.stringify(e, null, 2), We = (e) => {
357
362
  agent: g,
358
363
  messages: e.agentExecutionContext.messages,
359
364
  config: t
360
- }), p = o.parse(
365
+ }), h = o.parse(
361
366
  w ?? { intent: null, assignedTask: null, requiresFollowUp: !1 }
362
- ), m = p.intent ?? "none", M = {
367
+ ), m = h.intent ?? "none", M = {
363
368
  ...e,
364
369
  currentIntent: m,
365
- requiresFollowUp: p.requiresFollowUp,
370
+ requiresFollowUp: h.requiresFollowUp,
366
371
  agentExecutionContext: {
367
372
  ...e.agentExecutionContext,
368
- assignedTask: p.assignedTask ?? ""
373
+ assignedTask: h.assignedTask ?? ""
369
374
  }
370
375
  };
371
376
  if (m === "none") {
372
- const x = "I could not find a matching agent for that request. Please rephrase your question with more detail.";
377
+ const E = "I could not find a matching agent for that request. Please rephrase your question with more detail.";
373
378
  return await y({ text: "LLM did not identify a clear intent." }, t), {
374
379
  ...e,
375
380
  currentIntent: m,
@@ -377,7 +382,7 @@ const U = (e) => JSON.stringify(e, null, 2), We = (e) => {
377
382
  agentExecutionContext: {
378
383
  ...e.agentExecutionContext,
379
384
  assignedTask: "",
380
- messages: [...e.agentExecutionContext.messages, new W(x)],
385
+ messages: [...e.agentExecutionContext.messages, new W(E)],
381
386
  priorSteps: [
382
387
  ...e.agentExecutionContext.priorSteps ?? [],
383
388
  {
@@ -393,15 +398,15 @@ const U = (e) => JSON.stringify(e, null, 2), We = (e) => {
393
398
  return await y(
394
399
  {
395
400
  text: `Agent picked: ${m}
396
- Task Assigned: ${p.assignedTask ?? ""}
397
- Requires Follow-Up: ${p.requiresFollowUp}`
401
+ Task Assigned: ${h.assignedTask ?? ""}
402
+ Requires Follow-Up: ${h.requiresFollowUp}`
398
403
  },
399
404
  t
400
405
  ), M;
401
406
  } catch (r) {
402
407
  throw await y({ text: "Error during intent detection" }, t), new Error(`Error during intent detection: ${r instanceof Error ? r.message : String(r)}`);
403
408
  }
404
- }, Oe = 3, He = () => new ce(Re).addNode("ingestInput", Ce).addNode("intentLLM", Ne).addNode("executeRegisteredAgent", Le).addNode("exit", Te).addEdge(de, "ingestInput").addEdge("ingestInput", "intentLLM").addConditionalEdges("intentLLM", (t) => t.currentIntent === "none" ? "exit" : "executeRegisteredAgent").addConditionalEdges(
409
+ }, Oe = 3, He = () => new ce(Re).addNode("ingestInput", Ce).addNode("intentLLM", Ne).addNode("executeRegisteredAgent", Le).addNode("exit", Te).addEdge(de, "ingestInput").addEdge("ingestInput", "intentLLM").addConditionalEdges("intentLLM", (t) => t.currentIntent === "none" || t.currentIntent === t.lastExecutedAgent ? "exit" : "executeRegisteredAgent").addConditionalEdges(
405
410
  "executeRegisteredAgent",
406
411
  (t) => t.stepCount >= Oe || !t.requiresFollowUp ? "exit" : "intentLLM"
407
412
  ).addEdge("exit", le);
@@ -528,8 +533,8 @@ const Ke = async ({
528
533
  const u = (g) => {
529
534
  if (g.data.requestId !== i)
530
535
  return;
531
- const w = g.data.results.map(({ layerId: p, results: m }) => ({
532
- layerId: p,
536
+ const w = g.data.results.map(({ layerId: h, results: m }) => ({
537
+ layerId: h,
533
538
  results: m
534
539
  }));
535
540
  d(w);
@@ -638,7 +643,7 @@ Description: {description}`, re = l.object({
638
643
  return r;
639
644
  }, Ye = async (e) => {
640
645
  try {
641
- return (await be(e, {
646
+ return (await Ee(e, {
642
647
  responseType: "json"
643
648
  })).data;
644
649
  } catch (t) {
@@ -725,10 +730,10 @@ class se {
725
730
  i
726
731
  ), c = ++this.streamEpoch;
727
732
  for (yield* this.pipeStream(o, c); ; ) {
728
- const p = (await this.graph.getState(i, { subgraphs: !0 })).tasks.find((m) => m.interrupts.length > 0)?.interrupts[0]?.value;
729
- if (!p)
733
+ const h = (await this.graph.getState(i, { subgraphs: !0 })).tasks.find((m) => m.interrupts.length > 0)?.interrupts[0]?.value;
734
+ if (!h)
730
735
  break;
731
- this.currentInterrupt = p, this.interruptHandler = new ze(this.graph, i), yield { runId: this.threadId, timestamp: Date.now(), type: "interrupt", interrupt: p };
736
+ this.currentInterrupt = h, this.interruptHandler = new ze(this.graph, i), yield { runId: this.threadId, timestamp: Date.now(), type: "interrupt", interrupt: h };
732
737
  try {
733
738
  const m = await this.interruptHandler.waitForUser(), M = ++this.streamEpoch;
734
739
  yield* this.pipeStream(m, M);
@@ -817,7 +822,7 @@ const et = (e) => {
817
822
  const r = he.fromTemplate(e);
818
823
  return O.fromMessages([r, ...t]);
819
824
  }, tt = async (e) => {
820
- const { promptText: t, modelTier: r, temperature: n, messages: s } = e, a = $(t, s ?? []), i = await E(r, n);
825
+ const { promptText: t, modelTier: r, temperature: n, messages: s } = e, a = $(t, s ?? []), i = await b(r, n);
821
826
  return a.pipe(i);
822
827
  }, St = async (e) => {
823
828
  const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables: a } = e, o = await (await tt({
@@ -831,10 +836,10 @@ const et = (e) => {
831
836
  const c = o.content;
832
837
  return typeof c == "string" ? c : JSON.stringify(c);
833
838
  }, ae = async (e) => {
834
- const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables: a, schema: i } = e, o = $(t, s ?? []), d = (await E(r, n)).withStructuredOutput(i);
839
+ const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables: a, schema: i } = e, o = $(t, s ?? []), d = (await b(r, n)).withStructuredOutput(i);
835
840
  return await o.pipe(d).invoke(a ?? {});
836
841
  }, It = async (e) => {
837
- const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables: a, tools: i } = e, o = i.length > 0 ? et(s ?? []) : s ?? [], c = $(t, o), d = await E(r, n);
842
+ const { promptText: t, modelTier: r = "default", temperature: n = 0, messages: s, inputVariables: a, tools: i } = e, o = i.length > 0 ? et(s ?? []) : s ?? [], c = $(t, o), d = await b(r, n);
838
843
  return await c.pipe(d.bindTools(i)).invoke(a ?? {});
839
844
  }, nt = f.object({
840
845
  name: f.string(),
@@ -984,13 +989,13 @@ export {
984
989
  se as Orchestrator,
985
990
  kt as cosineSimilarity,
986
991
  ke as createAgentRuntimeState,
987
- bt as createAgentRuntimeStateWithSharedState,
988
- E as createChatModel,
992
+ Et as createAgentRuntimeStateWithSharedState,
993
+ b as createChatModel,
989
994
  Mt as createWebmapEmbeddings,
990
995
  Y as getEmbeddings,
991
996
  ae as invokeStructuredPrompt,
992
997
  St as invokeTextPrompt,
993
998
  It as invokeToolPrompt,
994
999
  y as sendTraceMessage,
995
- Et as sendUXSuggestion
1000
+ bt as sendUXSuggestion
996
1001
  };
@@ -78,7 +78,7 @@ Use prior steps to:
78
78
  - Only break the request into multiple steps when necessary.
79
79
  - When multiple agents could help, choose the best fit instead of returning \`null\`.
80
80
  - Base the choice on the registered agent descriptions, not on whether the user used exact matching keywords.
81
- - If no agent can fully complete the request, but one agent can take the next useful step, choose that agent and set \`requiresFollowUp\` to \`true\`.
81
+ - If no agent can fully complete the request, but one agent can take the next useful step, choose that agent.
82
82
  - Do NOT reuse constraints from prior steps unless the current user request explicitly requires them.
83
83
  - Each step must reflect the current user request exactly.
84
84
 
@@ -116,6 +116,7 @@ Do not reinterpret the request into a different form.
116
116
  - \`requiresFollowUp\` should indicate a likely next agent step, not uncertainty about the current request
117
117
  - Set \`requiresFollowUp\` to \`true\` only when another orchestration step will likely be needed after this agent succeeds
118
118
  - Set \`requiresFollowUp\` to \`false\` when a successful result from this agent would likely complete the user-visible task
119
+ - Default to \`false\`
119
120
  `;
120
121
  export {
121
122
  e as default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcgis/ai-orchestrator",
3
- "version": "5.1.0-next.102",
3
+ "version": "5.1.0-next.103",
4
4
  "description": "ArcGIS AI Orchestrator Package",
5
5
  "homepage": "https://developers.arcgis.com/javascript/latest/",
6
6
  "type": "module",