@dexto/agent-management 1.5.7 → 1.5.8

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.
Files changed (45) hide show
  1. package/dist/config/config-enrichment.cjs +2 -1
  2. package/dist/config/config-enrichment.d.ts.map +1 -1
  3. package/dist/config/config-enrichment.js +2 -1
  4. package/dist/index.cjs +11 -0
  5. package/dist/index.d.ts +2 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +12 -0
  8. package/dist/models/custom-models.cjs +1 -1
  9. package/dist/models/custom-models.d.ts +7 -7
  10. package/dist/models/custom-models.d.ts.map +1 -1
  11. package/dist/models/custom-models.js +1 -1
  12. package/dist/plugins/discover-skills.cjs +4 -0
  13. package/dist/plugins/discover-skills.d.ts +6 -3
  14. package/dist/plugins/discover-skills.d.ts.map +1 -1
  15. package/dist/plugins/discover-skills.js +4 -0
  16. package/dist/preferences/errors.cjs +11 -0
  17. package/dist/preferences/errors.d.ts +1 -0
  18. package/dist/preferences/errors.d.ts.map +1 -1
  19. package/dist/preferences/errors.js +11 -0
  20. package/dist/preferences/loader.cjs +119 -6
  21. package/dist/preferences/loader.d.ts +21 -1
  22. package/dist/preferences/loader.d.ts.map +1 -1
  23. package/dist/preferences/loader.js +102 -1
  24. package/dist/preferences/schemas.cjs +12 -0
  25. package/dist/preferences/schemas.d.ts +38 -12
  26. package/dist/preferences/schemas.d.ts.map +1 -1
  27. package/dist/preferences/schemas.js +10 -0
  28. package/dist/tool-provider/llm-resolution.cjs +1 -1
  29. package/dist/tool-provider/llm-resolution.d.ts +4 -4
  30. package/dist/tool-provider/llm-resolution.js +1 -1
  31. package/dist/tool-provider/runtime-service.cjs +90 -13
  32. package/dist/tool-provider/runtime-service.d.ts +2 -0
  33. package/dist/tool-provider/runtime-service.d.ts.map +1 -1
  34. package/dist/tool-provider/runtime-service.js +80 -13
  35. package/dist/tool-provider/tool-provider.cjs +152 -1
  36. package/dist/tool-provider/tool-provider.d.ts +7 -1
  37. package/dist/tool-provider/tool-provider.d.ts.map +1 -1
  38. package/dist/tool-provider/tool-provider.js +159 -1
  39. package/dist/utils/api-key-resolver.cjs +1 -1
  40. package/dist/utils/api-key-resolver.js +1 -1
  41. package/dist/utils/feature-flags.cjs +3 -1
  42. package/dist/utils/feature-flags.d.ts +2 -2
  43. package/dist/utils/feature-flags.d.ts.map +1 -1
  44. package/dist/utils/feature-flags.js +3 -1
  45. package/package.json +3 -2
@@ -3,6 +3,9 @@ import { AgentRuntime } from "../runtime/AgentRuntime.js";
3
3
  import { createDelegatingApprovalHandler } from "../runtime/approval-delegation.js";
4
4
  import { loadAgentConfig } from "../config/loader.js";
5
5
  import { getAgentRegistry } from "../registry/registry.js";
6
+ import { deriveDisplayName } from "../registry/types.js";
7
+ import { resolveBundledScript } from "../utils/path.js";
8
+ import * as path from "path";
6
9
  import { resolveSubAgentLLM } from "./llm-resolution.js";
7
10
  class RuntimeService {
8
11
  runtime;
@@ -10,6 +13,37 @@ class RuntimeService {
10
13
  parentAgent;
11
14
  config;
12
15
  logger;
16
+ resolveBundledAgentConfig(agentId) {
17
+ const baseDir = "agents";
18
+ const normalizedPath = path.relative(baseDir, path.join(baseDir, agentId));
19
+ if (normalizedPath.startsWith("..") || path.isAbsolute(normalizedPath)) {
20
+ return null;
21
+ }
22
+ const candidates = [
23
+ `agents/${agentId}/${agentId}.yml`,
24
+ `agents/${agentId}/${agentId}.yaml`,
25
+ `agents/${agentId}.yml`,
26
+ `agents/${agentId}.yaml`
27
+ ];
28
+ for (const candidate of candidates) {
29
+ try {
30
+ return resolveBundledScript(candidate);
31
+ } catch {
32
+ }
33
+ }
34
+ return null;
35
+ }
36
+ createFallbackRegistryEntry(agentId) {
37
+ return {
38
+ id: agentId,
39
+ name: deriveDisplayName(agentId),
40
+ description: "Agent specified in config (registry entry not found)",
41
+ author: "unknown",
42
+ tags: [],
43
+ source: agentId,
44
+ type: "custom"
45
+ };
46
+ }
13
47
  constructor(parentAgent, config, logger) {
14
48
  this.parentAgent = parentAgent;
15
49
  this.config = config;
@@ -407,12 +441,26 @@ class RuntimeService {
407
441
  );
408
442
  const toolConfirmationMode = autoApprove ? "auto-approve" : "manual";
409
443
  if (agentId) {
410
- const registry = getAgentRegistry();
411
- if (!registry.hasAgent(agentId)) {
412
- this.logger.warn(`Agent '${agentId}' not found in registry. Using default config.`);
413
- } else {
414
- const configPath = await registry.resolveAgent(agentId);
415
- this.logger.debug(`Loading agent config from registry: ${configPath}`);
444
+ let configPath = null;
445
+ try {
446
+ const registry = getAgentRegistry();
447
+ if (!registry.hasAgent(agentId)) {
448
+ this.logger.warn(
449
+ `Agent '${agentId}' not found in registry. Trying bundled config paths.`
450
+ );
451
+ } else {
452
+ configPath = await registry.resolveAgent(agentId);
453
+ }
454
+ } catch (error) {
455
+ this.logger.warn(
456
+ `Failed to load agent registry for '${agentId}'. Trying bundled config paths. (${error instanceof Error ? error.message : String(error)})`
457
+ );
458
+ }
459
+ if (!configPath) {
460
+ configPath = this.resolveBundledAgentConfig(agentId);
461
+ }
462
+ if (configPath) {
463
+ this.logger.debug(`Loading agent config from registry/bundled path: ${configPath}`);
416
464
  const loadedConfig = await loadAgentConfig(configPath, this.logger);
417
465
  let llmConfig = loadedConfig.llm;
418
466
  if (inheritLlm) {
@@ -429,6 +477,9 @@ class RuntimeService {
429
477
  this.logger.debug(`Sub-agent LLM resolution: ${resolution.reason}`);
430
478
  llmConfig = resolution.llm;
431
479
  }
480
+ const filteredCustomTools = loadedConfig.customTools ? loadedConfig.customTools.filter(
481
+ (tool) => typeof tool === "object" && tool !== null && "type" in tool && tool.type !== "agent-spawner"
482
+ ) : void 0;
432
483
  return {
433
484
  ...loadedConfig,
434
485
  llm: llmConfig,
@@ -436,6 +487,7 @@ class RuntimeService {
436
487
  ...loadedConfig.toolConfirmation,
437
488
  mode: toolConfirmationMode
438
489
  },
490
+ customTools: filteredCustomTools,
439
491
  // Suppress sub-agent console logs entirely using silent transport
440
492
  logger: {
441
493
  level: "error",
@@ -443,6 +495,9 @@ class RuntimeService {
443
495
  }
444
496
  };
445
497
  }
498
+ this.logger.warn(
499
+ `Agent '${agentId}' not found in registry or bundled paths. Using default config.`
500
+ );
446
501
  }
447
502
  const config = {
448
503
  llm: { ...currentParentLLM },
@@ -459,8 +514,11 @@ class RuntimeService {
459
514
  internalTools: parentConfig.internalTools ? parentConfig.internalTools.filter(
460
515
  (tool) => tool !== "ask_user" && tool !== "invoke_skill"
461
516
  ) : [],
462
- // Inherit custom tools from parent
463
- customTools: parentConfig.customTools ? [...parentConfig.customTools] : [],
517
+ // Inherit custom tools from parent, excluding agent-spawner to prevent nested spawning (depth=1 limit)
518
+ // - agent-spawner: Sub-agents should not spawn their own sub-agents
519
+ customTools: parentConfig.customTools ? parentConfig.customTools.filter(
520
+ (tool) => typeof tool === "object" && tool !== null && "type" in tool && tool.type !== "agent-spawner"
521
+ ) : [],
464
522
  // Suppress sub-agent console logs entirely using silent transport
465
523
  logger: {
466
524
  level: "error",
@@ -474,15 +532,24 @@ class RuntimeService {
474
532
  * Returns agent metadata from registry, filtered by allowedAgents if configured.
475
533
  */
476
534
  getAvailableAgents() {
477
- const registry = getAgentRegistry();
478
- const allAgents = registry.getAvailableAgents();
535
+ let allAgents;
536
+ try {
537
+ const registry = getAgentRegistry();
538
+ allAgents = registry.getAvailableAgents();
539
+ } catch (error) {
540
+ this.logger.warn(
541
+ `Failed to load agent registry for spawn_agent description: ${error instanceof Error ? error.message : String(error)}`
542
+ );
543
+ if (this.config.allowedAgents && this.config.allowedAgents.length > 0) {
544
+ return this.config.allowedAgents.map((id) => this.createFallbackRegistryEntry(id));
545
+ }
546
+ return [];
547
+ }
479
548
  if (this.config.allowedAgents && this.config.allowedAgents.length > 0) {
480
549
  const result = [];
481
550
  for (const id of this.config.allowedAgents) {
482
551
  const agent = allAgents[id];
483
- if (agent) {
484
- result.push(agent);
485
- }
552
+ result.push(agent ?? this.createFallbackRegistryEntry(id));
486
553
  }
487
554
  return result;
488
555
  }
@@ -21,18 +21,169 @@ __export(tool_provider_exports, {
21
21
  agentSpawnerToolsProvider: () => agentSpawnerToolsProvider
22
22
  });
23
23
  module.exports = __toCommonJS(tool_provider_exports);
24
+ var import_orchestration = require("@dexto/orchestration");
24
25
  var import_schemas = require("./schemas.js");
25
26
  var import_runtime_service = require("./runtime-service.js");
26
27
  var import_spawn_agent_tool = require("./spawn-agent-tool.js");
28
+ function bindOrchestrationTool(tool, context) {
29
+ return {
30
+ id: tool.id,
31
+ description: tool.description,
32
+ inputSchema: tool.inputSchema,
33
+ execute: (input) => tool.execute(input, context)
34
+ };
35
+ }
27
36
  const agentSpawnerToolsProvider = {
28
37
  type: "agent-spawner",
29
38
  configSchema: import_schemas.AgentSpawnerConfigSchema,
30
39
  create: (config, context) => {
31
40
  const { logger, agent } = context;
41
+ const signalBus = new import_orchestration.SignalBus();
42
+ const taskRegistry = new import_orchestration.TaskRegistry(signalBus);
43
+ const conditionEngine = new import_orchestration.ConditionEngine(taskRegistry, signalBus, logger);
44
+ const toolContext = {
45
+ taskRegistry,
46
+ conditionEngine,
47
+ signalBus
48
+ };
32
49
  const service = new import_runtime_service.RuntimeService(agent, config, logger);
33
50
  agent.toolManager.setTaskForker(service);
34
51
  logger.debug("RuntimeService wired as taskForker for context:fork skill support");
35
- return [(0, import_spawn_agent_tool.createSpawnAgentTool)(service)];
52
+ const taskSessions = /* @__PURE__ */ new Map();
53
+ const emitTasksUpdate = (sessionId) => {
54
+ const tasks = taskRegistry.list({
55
+ status: ["running", "completed", "failed", "cancelled"]
56
+ });
57
+ const scopedTasks = sessionId ? tasks.filter((task) => taskSessions.get(task.taskId) === sessionId) : tasks;
58
+ const runningCount = scopedTasks.filter((task) => task.status === "running").length;
59
+ agent.agentEventBus.emit("service:event", {
60
+ service: "orchestration",
61
+ event: "tasks-updated",
62
+ sessionId: sessionId ?? "",
63
+ data: {
64
+ runningCount,
65
+ tasks: scopedTasks.map((task) => ({
66
+ taskId: task.taskId,
67
+ status: task.status,
68
+ ...task.description !== void 0 && { description: task.description }
69
+ }))
70
+ }
71
+ });
72
+ };
73
+ const triggerBackgroundCompletion = (taskId, sessionId) => {
74
+ if (!sessionId) {
75
+ return;
76
+ }
77
+ agent.agentEventBus.emit("tool:background-completed", {
78
+ toolCallId: taskId,
79
+ sessionId
80
+ });
81
+ const taskInfo = taskRegistry.getInfo(taskId);
82
+ const resultText = (() => {
83
+ if (taskInfo?.status === "failed") {
84
+ return taskInfo.error ?? "Unknown error.";
85
+ }
86
+ if (taskInfo?.result !== void 0) {
87
+ if (typeof taskInfo.result === "string") {
88
+ return taskInfo.result;
89
+ }
90
+ try {
91
+ return JSON.stringify(taskInfo.result, null, 2);
92
+ } catch {
93
+ return String(taskInfo.result ?? "<unserializable result>");
94
+ }
95
+ }
96
+ return "No result available.";
97
+ })();
98
+ const sanitizeCdata = (value) => value.replace(/\]\]>/g, "]]]]><![CDATA[>");
99
+ const safeDescription = taskInfo?.description ? sanitizeCdata(taskInfo.description) : null;
100
+ const safeResultText = sanitizeCdata(resultText);
101
+ const descriptionTag = safeDescription ? ` <description><![CDATA[${safeDescription}]]></description>
102
+ ` : "";
103
+ const statusTag = taskInfo?.status ? ` <status>${taskInfo.status}</status>
104
+ ` : "";
105
+ const content = [
106
+ {
107
+ type: "text",
108
+ text: `<background-task-completion>
109
+ <origin>task</origin>
110
+ <note>The following response was reported by the background task (not user input).</note>
111
+ <taskId>${taskId}</taskId>
112
+ ` + statusTag + descriptionTag + ` <result><![CDATA[${safeResultText}]]></result>
113
+ </background-task-completion>`
114
+ }
115
+ ];
116
+ agent.isSessionBusy(sessionId).then((isBusy) => {
117
+ if (isBusy) {
118
+ agent.queueMessage(sessionId, {
119
+ content,
120
+ kind: "background"
121
+ }).catch(() => void 0);
122
+ } else {
123
+ agent.agentEventBus.emit("run:invoke", {
124
+ sessionId,
125
+ content,
126
+ source: "external",
127
+ metadata: { taskId }
128
+ });
129
+ agent.generate(content, sessionId).catch(() => void 0);
130
+ }
131
+ }).catch(() => {
132
+ });
133
+ };
134
+ const handleBackground = (event) => {
135
+ const taskId = event.toolCallId;
136
+ if (taskRegistry.has(taskId)) {
137
+ return;
138
+ }
139
+ if (event.sessionId) {
140
+ taskSessions.set(taskId, event.sessionId);
141
+ }
142
+ try {
143
+ taskRegistry.register(
144
+ {
145
+ type: "generic",
146
+ taskId,
147
+ description: event.description ?? `Tool ${event.toolName}`,
148
+ promise: event.promise
149
+ },
150
+ {
151
+ ...event.timeoutMs !== void 0 && { timeout: event.timeoutMs },
152
+ ...event.notifyOnComplete !== void 0 && {
153
+ notify: event.notifyOnComplete
154
+ }
155
+ }
156
+ );
157
+ } catch (error) {
158
+ taskSessions.delete(taskId);
159
+ event.promise.catch(() => void 0);
160
+ logger.warn(
161
+ `Failed to register background task ${taskId}: ${error instanceof Error ? error.message : String(error)}`,
162
+ { color: "yellow" }
163
+ );
164
+ return;
165
+ }
166
+ emitTasksUpdate(event.sessionId);
167
+ event.promise.finally(() => {
168
+ taskSessions.delete(taskId);
169
+ emitTasksUpdate(event.sessionId);
170
+ triggerBackgroundCompletion(taskId, event.sessionId);
171
+ });
172
+ };
173
+ const backgroundAbortController = new AbortController();
174
+ agent.agentEventBus.on("tool:background", handleBackground, {
175
+ signal: backgroundAbortController.signal
176
+ });
177
+ agent.agentEventBus.on("agent:stopped", () => {
178
+ backgroundAbortController.abort();
179
+ });
180
+ const tool = (0, import_spawn_agent_tool.createSpawnAgentTool)(service);
181
+ return [
182
+ tool,
183
+ bindOrchestrationTool((0, import_orchestration.createWaitForTool)(), toolContext),
184
+ bindOrchestrationTool((0, import_orchestration.createCheckTaskTool)(), toolContext),
185
+ bindOrchestrationTool((0, import_orchestration.createListTasksTool)(), toolContext)
186
+ ];
36
187
  },
37
188
  metadata: {
38
189
  displayName: "Agent Spawner",
@@ -8,7 +8,13 @@ import { type AgentSpawnerConfig } from './schemas.js';
8
8
  /**
9
9
  * Agent Spawner Tools Provider
10
10
  *
11
- * Provides the spawn_agent tool for task delegation to sub-agents.
11
+ * Provides tools for spawning and managing sub-agents:
12
+ * - spawn_agent: Spawn a sub-agent to handle a task
13
+ *
14
+ * Orchestration tools (for background task management):
15
+ * - wait_for: Wait for background task(s) to complete
16
+ * - check_task: Check status of a background task
17
+ * - list_tasks: List all tracked background tasks
12
18
  *
13
19
  * Configuration:
14
20
  * ```yaml
@@ -1 +1 @@
1
- {"version":3,"file":"tool-provider.d.ts","sourceRoot":"","sources":["../../src/tool-provider/tool-provider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAgB,MAAM,aAAa,CAAC;AACpE,OAAO,EAA4B,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAIjF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,yBAAyB,EAAE,kBAAkB,CAAC,eAAe,EAAE,kBAAkB,CAwB7F,CAAC"}
1
+ {"version":3,"file":"tool-provider.d.ts","sourceRoot":"","sources":["../../src/tool-provider/tool-provider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAgB,MAAM,aAAa,CAAC;AAYpE,OAAO,EAA4B,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAmBjF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,yBAAyB,EAAE,kBAAkB,CAAC,eAAe,EAAE,kBAAkB,CAsM7F,CAAC"}
@@ -1,15 +1,173 @@
1
+ import {
2
+ ConditionEngine,
3
+ SignalBus,
4
+ TaskRegistry,
5
+ createCheckTaskTool,
6
+ createListTasksTool,
7
+ createWaitForTool
8
+ } from "@dexto/orchestration";
1
9
  import { AgentSpawnerConfigSchema } from "./schemas.js";
2
10
  import { RuntimeService } from "./runtime-service.js";
3
11
  import { createSpawnAgentTool } from "./spawn-agent-tool.js";
12
+ function bindOrchestrationTool(tool, context) {
13
+ return {
14
+ id: tool.id,
15
+ description: tool.description,
16
+ inputSchema: tool.inputSchema,
17
+ execute: (input) => tool.execute(input, context)
18
+ };
19
+ }
4
20
  const agentSpawnerToolsProvider = {
5
21
  type: "agent-spawner",
6
22
  configSchema: AgentSpawnerConfigSchema,
7
23
  create: (config, context) => {
8
24
  const { logger, agent } = context;
25
+ const signalBus = new SignalBus();
26
+ const taskRegistry = new TaskRegistry(signalBus);
27
+ const conditionEngine = new ConditionEngine(taskRegistry, signalBus, logger);
28
+ const toolContext = {
29
+ taskRegistry,
30
+ conditionEngine,
31
+ signalBus
32
+ };
9
33
  const service = new RuntimeService(agent, config, logger);
10
34
  agent.toolManager.setTaskForker(service);
11
35
  logger.debug("RuntimeService wired as taskForker for context:fork skill support");
12
- return [createSpawnAgentTool(service)];
36
+ const taskSessions = /* @__PURE__ */ new Map();
37
+ const emitTasksUpdate = (sessionId) => {
38
+ const tasks = taskRegistry.list({
39
+ status: ["running", "completed", "failed", "cancelled"]
40
+ });
41
+ const scopedTasks = sessionId ? tasks.filter((task) => taskSessions.get(task.taskId) === sessionId) : tasks;
42
+ const runningCount = scopedTasks.filter((task) => task.status === "running").length;
43
+ agent.agentEventBus.emit("service:event", {
44
+ service: "orchestration",
45
+ event: "tasks-updated",
46
+ sessionId: sessionId ?? "",
47
+ data: {
48
+ runningCount,
49
+ tasks: scopedTasks.map((task) => ({
50
+ taskId: task.taskId,
51
+ status: task.status,
52
+ ...task.description !== void 0 && { description: task.description }
53
+ }))
54
+ }
55
+ });
56
+ };
57
+ const triggerBackgroundCompletion = (taskId, sessionId) => {
58
+ if (!sessionId) {
59
+ return;
60
+ }
61
+ agent.agentEventBus.emit("tool:background-completed", {
62
+ toolCallId: taskId,
63
+ sessionId
64
+ });
65
+ const taskInfo = taskRegistry.getInfo(taskId);
66
+ const resultText = (() => {
67
+ if (taskInfo?.status === "failed") {
68
+ return taskInfo.error ?? "Unknown error.";
69
+ }
70
+ if (taskInfo?.result !== void 0) {
71
+ if (typeof taskInfo.result === "string") {
72
+ return taskInfo.result;
73
+ }
74
+ try {
75
+ return JSON.stringify(taskInfo.result, null, 2);
76
+ } catch {
77
+ return String(taskInfo.result ?? "<unserializable result>");
78
+ }
79
+ }
80
+ return "No result available.";
81
+ })();
82
+ const sanitizeCdata = (value) => value.replace(/\]\]>/g, "]]]]><![CDATA[>");
83
+ const safeDescription = taskInfo?.description ? sanitizeCdata(taskInfo.description) : null;
84
+ const safeResultText = sanitizeCdata(resultText);
85
+ const descriptionTag = safeDescription ? ` <description><![CDATA[${safeDescription}]]></description>
86
+ ` : "";
87
+ const statusTag = taskInfo?.status ? ` <status>${taskInfo.status}</status>
88
+ ` : "";
89
+ const content = [
90
+ {
91
+ type: "text",
92
+ text: `<background-task-completion>
93
+ <origin>task</origin>
94
+ <note>The following response was reported by the background task (not user input).</note>
95
+ <taskId>${taskId}</taskId>
96
+ ` + statusTag + descriptionTag + ` <result><![CDATA[${safeResultText}]]></result>
97
+ </background-task-completion>`
98
+ }
99
+ ];
100
+ agent.isSessionBusy(sessionId).then((isBusy) => {
101
+ if (isBusy) {
102
+ agent.queueMessage(sessionId, {
103
+ content,
104
+ kind: "background"
105
+ }).catch(() => void 0);
106
+ } else {
107
+ agent.agentEventBus.emit("run:invoke", {
108
+ sessionId,
109
+ content,
110
+ source: "external",
111
+ metadata: { taskId }
112
+ });
113
+ agent.generate(content, sessionId).catch(() => void 0);
114
+ }
115
+ }).catch(() => {
116
+ });
117
+ };
118
+ const handleBackground = (event) => {
119
+ const taskId = event.toolCallId;
120
+ if (taskRegistry.has(taskId)) {
121
+ return;
122
+ }
123
+ if (event.sessionId) {
124
+ taskSessions.set(taskId, event.sessionId);
125
+ }
126
+ try {
127
+ taskRegistry.register(
128
+ {
129
+ type: "generic",
130
+ taskId,
131
+ description: event.description ?? `Tool ${event.toolName}`,
132
+ promise: event.promise
133
+ },
134
+ {
135
+ ...event.timeoutMs !== void 0 && { timeout: event.timeoutMs },
136
+ ...event.notifyOnComplete !== void 0 && {
137
+ notify: event.notifyOnComplete
138
+ }
139
+ }
140
+ );
141
+ } catch (error) {
142
+ taskSessions.delete(taskId);
143
+ event.promise.catch(() => void 0);
144
+ logger.warn(
145
+ `Failed to register background task ${taskId}: ${error instanceof Error ? error.message : String(error)}`,
146
+ { color: "yellow" }
147
+ );
148
+ return;
149
+ }
150
+ emitTasksUpdate(event.sessionId);
151
+ event.promise.finally(() => {
152
+ taskSessions.delete(taskId);
153
+ emitTasksUpdate(event.sessionId);
154
+ triggerBackgroundCompletion(taskId, event.sessionId);
155
+ });
156
+ };
157
+ const backgroundAbortController = new AbortController();
158
+ agent.agentEventBus.on("tool:background", handleBackground, {
159
+ signal: backgroundAbortController.signal
160
+ });
161
+ agent.agentEventBus.on("agent:stopped", () => {
162
+ backgroundAbortController.abort();
163
+ });
164
+ const tool = createSpawnAgentTool(service);
165
+ return [
166
+ tool,
167
+ bindOrchestrationTool(createWaitForTool(), toolContext),
168
+ bindOrchestrationTool(createCheckTaskTool(), toolContext),
169
+ bindOrchestrationTool(createListTasksTool(), toolContext)
170
+ ];
13
171
  },
14
172
  metadata: {
15
173
  displayName: "Agent Spawner",
@@ -52,7 +52,7 @@ const PROVIDER_API_KEY_MAP = {
52
52
  ollama: [],
53
53
  // Ollama server (may optionally use OLLAMA_API_KEY for remote servers)
54
54
  // Dexto gateway - requires key from `dexto login`
55
- dexto: ["DEXTO_API_KEY"]
55
+ "dexto-nova": ["DEXTO_API_KEY"]
56
56
  // perplexity: ['PERPLEXITY_API_KEY'],
57
57
  // together: ['TOGETHER_API_KEY'],
58
58
  // fireworks: ['FIREWORKS_API_KEY'],
@@ -27,7 +27,7 @@ const PROVIDER_API_KEY_MAP = {
27
27
  ollama: [],
28
28
  // Ollama server (may optionally use OLLAMA_API_KEY for remote servers)
29
29
  // Dexto gateway - requires key from `dexto login`
30
- dexto: ["DEXTO_API_KEY"]
30
+ "dexto-nova": ["DEXTO_API_KEY"]
31
31
  // perplexity: ['PERPLEXITY_API_KEY'],
32
32
  // together: ['TOGETHER_API_KEY'],
33
33
  // fireworks: ['FIREWORKS_API_KEY'],
@@ -22,7 +22,9 @@ __export(feature_flags_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(feature_flags_exports);
24
24
  function isDextoAuthEnabled() {
25
- return process.env.DEXTO_FEATURE_AUTH === "true";
25
+ const flag = process.env.DEXTO_FEATURE_AUTH;
26
+ if (flag === void 0) return true;
27
+ return flag === "true";
26
28
  }
27
29
  // Annotate the CommonJS export names for ESM import in node:
28
30
  0 && (module.exports = {
@@ -7,7 +7,7 @@
7
7
  /**
8
8
  * Check if Dexto authentication/provider is enabled.
9
9
  *
10
- * When disabled (default), the Dexto provider option is hidden from:
10
+ * When disabled (set DEXTO_FEATURE_AUTH=false), the Dexto provider option is hidden from:
11
11
  * - Onboarding/setup wizard
12
12
  * - Model selectors (CLI and WebUI)
13
13
  * - LLM catalog API responses
@@ -15,7 +15,7 @@
15
15
  * The underlying auth commands (dexto login, logout, billing) remain functional
16
16
  * for users who need to manage their account.
17
17
  *
18
- * Enable by setting DEXTO_FEATURE_AUTH=true in environment.
18
+ * Enabled by default. Set DEXTO_FEATURE_AUTH=false to disable.
19
19
  */
20
20
  export declare function isDextoAuthEnabled(): boolean;
21
21
  //# sourceMappingURL=feature-flags.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature-flags.d.ts","sourceRoot":"","sources":["../../src/utils/feature-flags.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C"}
1
+ {"version":3,"file":"feature-flags.d.ts","sourceRoot":"","sources":["../../src/utils/feature-flags.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAI5C"}
@@ -1,5 +1,7 @@
1
1
  function isDextoAuthEnabled() {
2
- return process.env.DEXTO_FEATURE_AUTH === "true";
2
+ const flag = process.env.DEXTO_FEATURE_AUTH;
3
+ if (flag === void 0) return true;
4
+ return flag === "true";
3
5
  }
4
6
  export {
5
7
  isDextoAuthEnabled
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dexto/agent-management",
3
- "version": "1.5.7",
3
+ "version": "1.5.8",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -16,7 +16,8 @@
16
16
  "dependencies": {
17
17
  "yaml": "^2.7.1",
18
18
  "zod": "^3.25.0",
19
- "@dexto/core": "1.5.7"
19
+ "@dexto/core": "1.5.8",
20
+ "@dexto/orchestration": "1.5.8"
20
21
  },
21
22
  "devDependencies": {
22
23
  "@types/node": "^22.13.5"