@livekit/agents 1.0.46 → 1.0.48

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 (228) hide show
  1. package/dist/beta/index.cjs +29 -0
  2. package/dist/beta/index.cjs.map +1 -0
  3. package/dist/beta/index.d.cts +2 -0
  4. package/dist/beta/index.d.ts +2 -0
  5. package/dist/beta/index.d.ts.map +1 -0
  6. package/dist/beta/index.js +7 -0
  7. package/dist/beta/index.js.map +1 -0
  8. package/dist/beta/workflows/index.cjs +29 -0
  9. package/dist/beta/workflows/index.cjs.map +1 -0
  10. package/dist/beta/workflows/index.d.cts +2 -0
  11. package/dist/beta/workflows/index.d.ts +2 -0
  12. package/dist/beta/workflows/index.d.ts.map +1 -0
  13. package/dist/beta/workflows/index.js +7 -0
  14. package/dist/beta/workflows/index.js.map +1 -0
  15. package/dist/beta/workflows/task_group.cjs +162 -0
  16. package/dist/beta/workflows/task_group.cjs.map +1 -0
  17. package/dist/beta/workflows/task_group.d.cts +32 -0
  18. package/dist/beta/workflows/task_group.d.ts +32 -0
  19. package/dist/beta/workflows/task_group.d.ts.map +1 -0
  20. package/dist/beta/workflows/task_group.js +138 -0
  21. package/dist/beta/workflows/task_group.js.map +1 -0
  22. package/dist/cli.cjs +14 -20
  23. package/dist/cli.cjs.map +1 -1
  24. package/dist/cli.d.ts.map +1 -1
  25. package/dist/cli.js +14 -20
  26. package/dist/cli.js.map +1 -1
  27. package/dist/index.cjs +3 -0
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +2 -1
  30. package/dist/index.d.ts +2 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +2 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/inference/api_protos.d.cts +59 -59
  35. package/dist/inference/api_protos.d.ts +59 -59
  36. package/dist/ipc/job_proc_lazy_main.cjs +14 -5
  37. package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
  38. package/dist/ipc/job_proc_lazy_main.js +14 -5
  39. package/dist/ipc/job_proc_lazy_main.js.map +1 -1
  40. package/dist/llm/chat_context.cjs +108 -1
  41. package/dist/llm/chat_context.cjs.map +1 -1
  42. package/dist/llm/chat_context.d.cts +14 -1
  43. package/dist/llm/chat_context.d.ts +14 -1
  44. package/dist/llm/chat_context.d.ts.map +1 -1
  45. package/dist/llm/chat_context.js +108 -1
  46. package/dist/llm/chat_context.js.map +1 -1
  47. package/dist/llm/chat_context.test.cjs +43 -0
  48. package/dist/llm/chat_context.test.cjs.map +1 -1
  49. package/dist/llm/chat_context.test.js +43 -0
  50. package/dist/llm/chat_context.test.js.map +1 -1
  51. package/dist/llm/index.cjs +2 -0
  52. package/dist/llm/index.cjs.map +1 -1
  53. package/dist/llm/index.d.cts +1 -1
  54. package/dist/llm/index.d.ts +1 -1
  55. package/dist/llm/index.d.ts.map +1 -1
  56. package/dist/llm/index.js +3 -1
  57. package/dist/llm/index.js.map +1 -1
  58. package/dist/llm/provider_format/index.cjs +2 -0
  59. package/dist/llm/provider_format/index.cjs.map +1 -1
  60. package/dist/llm/provider_format/index.d.cts +2 -2
  61. package/dist/llm/provider_format/index.d.ts +2 -2
  62. package/dist/llm/provider_format/index.d.ts.map +1 -1
  63. package/dist/llm/provider_format/index.js +6 -1
  64. package/dist/llm/provider_format/index.js.map +1 -1
  65. package/dist/llm/provider_format/openai.cjs +82 -2
  66. package/dist/llm/provider_format/openai.cjs.map +1 -1
  67. package/dist/llm/provider_format/openai.d.cts +1 -0
  68. package/dist/llm/provider_format/openai.d.ts +1 -0
  69. package/dist/llm/provider_format/openai.d.ts.map +1 -1
  70. package/dist/llm/provider_format/openai.js +80 -1
  71. package/dist/llm/provider_format/openai.js.map +1 -1
  72. package/dist/llm/provider_format/openai.test.cjs +326 -0
  73. package/dist/llm/provider_format/openai.test.cjs.map +1 -1
  74. package/dist/llm/provider_format/openai.test.js +327 -1
  75. package/dist/llm/provider_format/openai.test.js.map +1 -1
  76. package/dist/llm/provider_format/utils.cjs +4 -3
  77. package/dist/llm/provider_format/utils.cjs.map +1 -1
  78. package/dist/llm/provider_format/utils.d.ts.map +1 -1
  79. package/dist/llm/provider_format/utils.js +4 -3
  80. package/dist/llm/provider_format/utils.js.map +1 -1
  81. package/dist/llm/realtime.cjs.map +1 -1
  82. package/dist/llm/realtime.d.cts +1 -0
  83. package/dist/llm/realtime.d.ts +1 -0
  84. package/dist/llm/realtime.d.ts.map +1 -1
  85. package/dist/llm/realtime.js.map +1 -1
  86. package/dist/llm/tool_context.cjs +7 -0
  87. package/dist/llm/tool_context.cjs.map +1 -1
  88. package/dist/llm/tool_context.d.cts +10 -2
  89. package/dist/llm/tool_context.d.ts +10 -2
  90. package/dist/llm/tool_context.d.ts.map +1 -1
  91. package/dist/llm/tool_context.js +6 -0
  92. package/dist/llm/tool_context.js.map +1 -1
  93. package/dist/log.cjs +5 -2
  94. package/dist/log.cjs.map +1 -1
  95. package/dist/log.d.ts.map +1 -1
  96. package/dist/log.js +5 -2
  97. package/dist/log.js.map +1 -1
  98. package/dist/stream/deferred_stream.cjs +15 -6
  99. package/dist/stream/deferred_stream.cjs.map +1 -1
  100. package/dist/stream/deferred_stream.d.ts.map +1 -1
  101. package/dist/stream/deferred_stream.js +15 -6
  102. package/dist/stream/deferred_stream.js.map +1 -1
  103. package/dist/utils.cjs +32 -2
  104. package/dist/utils.cjs.map +1 -1
  105. package/dist/utils.d.cts +7 -0
  106. package/dist/utils.d.ts +7 -0
  107. package/dist/utils.d.ts.map +1 -1
  108. package/dist/utils.js +32 -2
  109. package/dist/utils.js.map +1 -1
  110. package/dist/utils.test.cjs +71 -0
  111. package/dist/utils.test.cjs.map +1 -1
  112. package/dist/utils.test.js +71 -0
  113. package/dist/utils.test.js.map +1 -1
  114. package/dist/version.cjs +1 -1
  115. package/dist/version.cjs.map +1 -1
  116. package/dist/version.d.cts +1 -1
  117. package/dist/version.d.ts +1 -1
  118. package/dist/version.d.ts.map +1 -1
  119. package/dist/version.js +1 -1
  120. package/dist/version.js.map +1 -1
  121. package/dist/voice/agent.cjs +153 -12
  122. package/dist/voice/agent.cjs.map +1 -1
  123. package/dist/voice/agent.d.cts +30 -4
  124. package/dist/voice/agent.d.ts +30 -4
  125. package/dist/voice/agent.d.ts.map +1 -1
  126. package/dist/voice/agent.js +149 -11
  127. package/dist/voice/agent.js.map +1 -1
  128. package/dist/voice/agent.test.cjs +120 -0
  129. package/dist/voice/agent.test.cjs.map +1 -1
  130. package/dist/voice/agent.test.js +122 -2
  131. package/dist/voice/agent.test.js.map +1 -1
  132. package/dist/voice/agent_activity.cjs +406 -298
  133. package/dist/voice/agent_activity.cjs.map +1 -1
  134. package/dist/voice/agent_activity.d.cts +41 -7
  135. package/dist/voice/agent_activity.d.ts +41 -7
  136. package/dist/voice/agent_activity.d.ts.map +1 -1
  137. package/dist/voice/agent_activity.js +407 -294
  138. package/dist/voice/agent_activity.js.map +1 -1
  139. package/dist/voice/agent_session.cjs +140 -40
  140. package/dist/voice/agent_session.cjs.map +1 -1
  141. package/dist/voice/agent_session.d.cts +19 -7
  142. package/dist/voice/agent_session.d.ts +19 -7
  143. package/dist/voice/agent_session.d.ts.map +1 -1
  144. package/dist/voice/agent_session.js +137 -37
  145. package/dist/voice/agent_session.js.map +1 -1
  146. package/dist/voice/audio_recognition.cjs +4 -0
  147. package/dist/voice/audio_recognition.cjs.map +1 -1
  148. package/dist/voice/audio_recognition.d.ts.map +1 -1
  149. package/dist/voice/audio_recognition.js +4 -0
  150. package/dist/voice/audio_recognition.js.map +1 -1
  151. package/dist/voice/generation.cjs +39 -19
  152. package/dist/voice/generation.cjs.map +1 -1
  153. package/dist/voice/generation.d.ts.map +1 -1
  154. package/dist/voice/generation.js +44 -20
  155. package/dist/voice/generation.js.map +1 -1
  156. package/dist/voice/index.cjs +2 -0
  157. package/dist/voice/index.cjs.map +1 -1
  158. package/dist/voice/index.d.cts +1 -1
  159. package/dist/voice/index.d.ts +1 -1
  160. package/dist/voice/index.d.ts.map +1 -1
  161. package/dist/voice/index.js +2 -1
  162. package/dist/voice/index.js.map +1 -1
  163. package/dist/voice/room_io/room_io.cjs +11 -2
  164. package/dist/voice/room_io/room_io.cjs.map +1 -1
  165. package/dist/voice/room_io/room_io.d.ts.map +1 -1
  166. package/dist/voice/room_io/room_io.js +12 -3
  167. package/dist/voice/room_io/room_io.js.map +1 -1
  168. package/dist/voice/speech_handle.cjs +7 -1
  169. package/dist/voice/speech_handle.cjs.map +1 -1
  170. package/dist/voice/speech_handle.d.cts +2 -0
  171. package/dist/voice/speech_handle.d.ts +2 -0
  172. package/dist/voice/speech_handle.d.ts.map +1 -1
  173. package/dist/voice/speech_handle.js +8 -2
  174. package/dist/voice/speech_handle.js.map +1 -1
  175. package/dist/voice/testing/fake_llm.cjs +127 -0
  176. package/dist/voice/testing/fake_llm.cjs.map +1 -0
  177. package/dist/voice/testing/fake_llm.d.cts +30 -0
  178. package/dist/voice/testing/fake_llm.d.ts +30 -0
  179. package/dist/voice/testing/fake_llm.d.ts.map +1 -0
  180. package/dist/voice/testing/fake_llm.js +103 -0
  181. package/dist/voice/testing/fake_llm.js.map +1 -0
  182. package/dist/voice/testing/index.cjs +3 -0
  183. package/dist/voice/testing/index.cjs.map +1 -1
  184. package/dist/voice/testing/index.d.cts +1 -0
  185. package/dist/voice/testing/index.d.ts +1 -0
  186. package/dist/voice/testing/index.d.ts.map +1 -1
  187. package/dist/voice/testing/index.js +2 -0
  188. package/dist/voice/testing/index.js.map +1 -1
  189. package/dist/voice/testing/run_result.cjs +66 -15
  190. package/dist/voice/testing/run_result.cjs.map +1 -1
  191. package/dist/voice/testing/run_result.d.cts +14 -3
  192. package/dist/voice/testing/run_result.d.ts +14 -3
  193. package/dist/voice/testing/run_result.d.ts.map +1 -1
  194. package/dist/voice/testing/run_result.js +66 -15
  195. package/dist/voice/testing/run_result.js.map +1 -1
  196. package/package.json +1 -1
  197. package/src/beta/index.ts +9 -0
  198. package/src/beta/workflows/index.ts +9 -0
  199. package/src/beta/workflows/task_group.ts +194 -0
  200. package/src/cli.ts +20 -33
  201. package/src/index.ts +2 -1
  202. package/src/ipc/job_proc_lazy_main.ts +16 -5
  203. package/src/llm/chat_context.test.ts +48 -0
  204. package/src/llm/chat_context.ts +158 -0
  205. package/src/llm/index.ts +1 -0
  206. package/src/llm/provider_format/index.ts +7 -2
  207. package/src/llm/provider_format/openai.test.ts +385 -1
  208. package/src/llm/provider_format/openai.ts +103 -0
  209. package/src/llm/provider_format/utils.ts +6 -4
  210. package/src/llm/realtime.ts +1 -0
  211. package/src/llm/tool_context.ts +14 -0
  212. package/src/log.ts +5 -2
  213. package/src/stream/deferred_stream.ts +17 -6
  214. package/src/utils.test.ts +87 -0
  215. package/src/utils.ts +41 -2
  216. package/src/version.ts +1 -1
  217. package/src/voice/agent.test.ts +140 -2
  218. package/src/voice/agent.ts +200 -10
  219. package/src/voice/agent_activity.ts +466 -290
  220. package/src/voice/agent_session.ts +178 -40
  221. package/src/voice/audio_recognition.ts +4 -0
  222. package/src/voice/generation.ts +52 -23
  223. package/src/voice/index.ts +1 -1
  224. package/src/voice/room_io/room_io.ts +14 -3
  225. package/src/voice/speech_handle.ts +9 -2
  226. package/src/voice/testing/fake_llm.ts +138 -0
  227. package/src/voice/testing/index.ts +2 -0
  228. package/src/voice/testing/run_result.ts +81 -23
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var beta_exports = {};
20
+ __export(beta_exports, {
21
+ TaskGroup: () => import_workflows.TaskGroup
22
+ });
23
+ module.exports = __toCommonJS(beta_exports);
24
+ var import_workflows = require("./workflows/index.cjs");
25
+ // Annotate the CommonJS export names for ESM import in node:
26
+ 0 && (module.exports = {
27
+ TaskGroup
28
+ });
29
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/beta/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nexport {\n TaskGroup,\n type TaskCompletedEvent,\n type TaskGroupOptions,\n type TaskGroupResult,\n} from './workflows/index.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,uBAKO;","names":[]}
@@ -0,0 +1,2 @@
1
+ export { TaskGroup, type TaskCompletedEvent, type TaskGroupOptions, type TaskGroupResult, } from './workflows/index.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { TaskGroup, type TaskCompletedEvent, type TaskGroupOptions, type TaskGroupResult, } from './workflows/index.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/beta/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,SAAS,EACT,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import {
2
+ TaskGroup
3
+ } from "./workflows/index.js";
4
+ export {
5
+ TaskGroup
6
+ };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/beta/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nexport {\n TaskGroup,\n type TaskCompletedEvent,\n type TaskGroupOptions,\n type TaskGroupResult,\n} from './workflows/index.js';\n"],"mappings":"AAGA;AAAA,EACE;AAAA,OAIK;","names":[]}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var workflows_exports = {};
20
+ __export(workflows_exports, {
21
+ TaskGroup: () => import_task_group.TaskGroup
22
+ });
23
+ module.exports = __toCommonJS(workflows_exports);
24
+ var import_task_group = require("./task_group.cjs");
25
+ // Annotate the CommonJS export names for ESM import in node:
26
+ 0 && (module.exports = {
27
+ TaskGroup
28
+ });
29
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/beta/workflows/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nexport {\n TaskGroup,\n type TaskCompletedEvent,\n type TaskGroupOptions,\n type TaskGroupResult,\n} from './task_group.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,wBAKO;","names":[]}
@@ -0,0 +1,2 @@
1
+ export { TaskGroup, type TaskCompletedEvent, type TaskGroupOptions, type TaskGroupResult, } from './task_group.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { TaskGroup, type TaskCompletedEvent, type TaskGroupOptions, type TaskGroupResult, } from './task_group.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/beta/workflows/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,SAAS,EACT,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import {
2
+ TaskGroup
3
+ } from "./task_group.js";
4
+ export {
5
+ TaskGroup
6
+ };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/beta/workflows/index.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nexport {\n TaskGroup,\n type TaskCompletedEvent,\n type TaskGroupOptions,\n type TaskGroupResult,\n} from './task_group.js';\n"],"mappings":"AAGA;AAAA,EACE;AAAA,OAIK;","names":[]}
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var task_group_exports = {};
20
+ __export(task_group_exports, {
21
+ TaskGroup: () => TaskGroup
22
+ });
23
+ module.exports = __toCommonJS(task_group_exports);
24
+ var import_zod = require("zod");
25
+ var import_llm = require("../../llm/index.cjs");
26
+ var import_agent = require("../../voice/agent.cjs");
27
+ class OutOfScopeError extends import_llm.ToolError {
28
+ targetTaskIds;
29
+ constructor(targetTaskIds) {
30
+ super("out_of_scope");
31
+ this.targetTaskIds = targetTaskIds;
32
+ }
33
+ }
34
+ class TaskGroup extends import_agent.AgentTask {
35
+ _summarizeChatCtx;
36
+ _returnExceptions;
37
+ _visitedTasks = /* @__PURE__ */ new Set();
38
+ _registeredFactories = /* @__PURE__ */ new Map();
39
+ _taskCompletedCallback;
40
+ _currentTask;
41
+ constructor(options = {}) {
42
+ const { summarizeChatCtx = true, returnExceptions = false, chatCtx, onTaskCompleted } = options;
43
+ super({ instructions: "*empty*", chatCtx });
44
+ this._summarizeChatCtx = summarizeChatCtx;
45
+ this._returnExceptions = returnExceptions;
46
+ this._taskCompletedCallback = onTaskCompleted;
47
+ }
48
+ add(task, { id, description }) {
49
+ this._registeredFactories.set(id, { taskFactory: task, id, description });
50
+ return this;
51
+ }
52
+ async onEnter() {
53
+ const taskStack = [...this._registeredFactories.keys()];
54
+ const taskResults = {};
55
+ while (taskStack.length > 0) {
56
+ const taskId = taskStack.shift();
57
+ const factoryInfo = this._registeredFactories.get(taskId);
58
+ this._currentTask = factoryInfo.taskFactory();
59
+ const sharedChatCtx = this._chatCtx.copy();
60
+ await this._currentTask.updateChatCtx(sharedChatCtx);
61
+ const outOfScopeTool = this.buildOutOfScopeTool(taskId);
62
+ if (outOfScopeTool) {
63
+ await this._currentTask.updateTools({
64
+ ...this._currentTask.toolCtx,
65
+ out_of_scope: outOfScopeTool
66
+ });
67
+ }
68
+ try {
69
+ this._visitedTasks.add(taskId);
70
+ const res = await this._currentTask.run();
71
+ taskResults[taskId] = res;
72
+ if (this._taskCompletedCallback) {
73
+ await this._taskCompletedCallback({
74
+ agentTask: this._currentTask,
75
+ taskId,
76
+ result: res
77
+ });
78
+ }
79
+ } catch (e) {
80
+ if (e instanceof OutOfScopeError) {
81
+ taskStack.unshift(taskId);
82
+ for (let i = e.targetTaskIds.length - 1; i >= 0; i--) {
83
+ taskStack.unshift(e.targetTaskIds[i]);
84
+ }
85
+ continue;
86
+ }
87
+ if (this._returnExceptions) {
88
+ taskResults[taskId] = e;
89
+ continue;
90
+ } else {
91
+ this.complete(e instanceof Error ? e : new Error(String(e)));
92
+ return;
93
+ }
94
+ }
95
+ }
96
+ try {
97
+ if (this._summarizeChatCtx) {
98
+ const sessionLlm = this.session.llm;
99
+ if (!(sessionLlm instanceof import_llm.LLM)) {
100
+ throw new Error("summarizeChatCtx requires a standard LLM on the session");
101
+ }
102
+ const ctxToSummarize = this._chatCtx.copy({
103
+ excludeInstructions: true,
104
+ excludeHandoff: true,
105
+ excludeEmptyMessage: true,
106
+ excludeFunctionCall: true
107
+ });
108
+ const summarizedChatCtx = await ctxToSummarize._summarize(sessionLlm, {
109
+ keepLastTurns: 0
110
+ });
111
+ await this.updateChatCtx(summarizedChatCtx);
112
+ }
113
+ } catch (e) {
114
+ this.complete(new Error(`failed to summarize the chat_ctx: ${e}`));
115
+ return;
116
+ }
117
+ this.complete({ taskResults });
118
+ }
119
+ buildOutOfScopeTool(activeTaskId) {
120
+ if (this._visitedTasks.size === 0) {
121
+ return void 0;
122
+ }
123
+ const regressionTaskIds = new Set(this._visitedTasks);
124
+ regressionTaskIds.delete(activeTaskId);
125
+ if (regressionTaskIds.size === 0) {
126
+ return void 0;
127
+ }
128
+ const taskRepr = {};
129
+ for (const [id, info] of this._registeredFactories) {
130
+ if (regressionTaskIds.has(id)) {
131
+ taskRepr[id] = info.description;
132
+ }
133
+ }
134
+ const taskIdValues = [...regressionTaskIds];
135
+ const description = `Call to regress to other tasks according to what the user requested to modify, return the corresponding task ids. For example, if the user wants to change their email and there is a task with id "email_task" with a description of "Collect the user's email", return the id ("get_email_task"). If the user requests to regress to multiple tasks, such as changing their phone number and email, return both task ids in the order they were requested. The following are the IDs and their corresponding task description. ${JSON.stringify(taskRepr)}`;
136
+ const currentTask = this._currentTask;
137
+ const registeredFactories = this._registeredFactories;
138
+ const visitedTasks = this._visitedTasks;
139
+ return (0, import_llm.tool)({
140
+ description,
141
+ flags: import_llm.ToolFlag.IGNORE_ON_ENTER,
142
+ parameters: import_zod.z.object({
143
+ task_ids: import_zod.z.array(import_zod.z.enum(taskIdValues)).describe("The IDs of the tasks requested")
144
+ }),
145
+ execute: async ({ task_ids }) => {
146
+ for (const tid of task_ids) {
147
+ if (!registeredFactories.has(tid) || !visitedTasks.has(tid)) {
148
+ throw new import_llm.ToolError(`Unable to regress, invalid task id ${tid}`);
149
+ }
150
+ }
151
+ if (currentTask && !currentTask.done) {
152
+ currentTask.complete(new OutOfScopeError(task_ids));
153
+ }
154
+ }
155
+ });
156
+ }
157
+ }
158
+ // Annotate the CommonJS export names for ESM import in node:
159
+ 0 && (module.exports = {
160
+ TaskGroup
161
+ });
162
+ //# sourceMappingURL=task_group.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/beta/workflows/task_group.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { z } from 'zod';\nimport type { ChatContext } from '../../llm/chat_context.js';\nimport { LLM, ToolError, ToolFlag, tool } from '../../llm/index.js';\nimport { AgentTask } from '../../voice/agent.js';\n\ninterface FactoryInfo {\n taskFactory: () => AgentTask;\n id: string;\n description: string;\n}\n\nexport interface TaskGroupResult {\n taskResults: Record<string, unknown>;\n}\n\nexport interface TaskCompletedEvent {\n agentTask: AgentTask;\n taskId: string;\n result: unknown;\n}\n\nclass OutOfScopeError extends ToolError {\n readonly targetTaskIds: string[];\n\n constructor(targetTaskIds: string[]) {\n super('out_of_scope');\n this.targetTaskIds = targetTaskIds;\n }\n}\n\nexport interface TaskGroupOptions {\n summarizeChatCtx?: boolean;\n returnExceptions?: boolean;\n chatCtx?: ChatContext;\n onTaskCompleted?: (event: TaskCompletedEvent) => Promise<void>;\n}\n\nexport class TaskGroup extends AgentTask<TaskGroupResult> {\n private _summarizeChatCtx: boolean;\n private _returnExceptions: boolean;\n private _visitedTasks = new Set<string>();\n private _registeredFactories = new Map<string, FactoryInfo>();\n private _taskCompletedCallback?: (event: TaskCompletedEvent) => Promise<void>;\n private _currentTask?: AgentTask;\n\n constructor(options: TaskGroupOptions = {}) {\n const { summarizeChatCtx = true, returnExceptions = false, chatCtx, onTaskCompleted } = options;\n\n super({ instructions: '*empty*', chatCtx });\n\n this._summarizeChatCtx = summarizeChatCtx;\n this._returnExceptions = returnExceptions;\n this._taskCompletedCallback = onTaskCompleted;\n }\n\n add(task: () => AgentTask, { id, description }: { id: string; description: string }): this {\n this._registeredFactories.set(id, { taskFactory: task, id, description });\n return this;\n }\n\n async onEnter(): Promise<void> {\n const taskStack = [...this._registeredFactories.keys()];\n const taskResults: Record<string, unknown> = {};\n\n while (taskStack.length > 0) {\n const taskId = taskStack.shift()!;\n const factoryInfo = this._registeredFactories.get(taskId)!;\n\n this._currentTask = factoryInfo.taskFactory();\n\n const sharedChatCtx = this._chatCtx.copy();\n await this._currentTask.updateChatCtx(sharedChatCtx);\n\n const outOfScopeTool = this.buildOutOfScopeTool(taskId);\n if (outOfScopeTool) {\n await this._currentTask.updateTools({\n ...this._currentTask.toolCtx,\n out_of_scope: outOfScopeTool,\n });\n }\n\n try {\n this._visitedTasks.add(taskId);\n const res = await this._currentTask.run();\n taskResults[taskId] = res;\n\n if (this._taskCompletedCallback) {\n await this._taskCompletedCallback({\n agentTask: this._currentTask,\n taskId,\n result: res,\n });\n }\n } catch (e) {\n if (e instanceof OutOfScopeError) {\n taskStack.unshift(taskId);\n for (let i = e.targetTaskIds.length - 1; i >= 0; i--) {\n taskStack.unshift(e.targetTaskIds[i]!);\n }\n continue;\n }\n\n if (this._returnExceptions) {\n taskResults[taskId] = e;\n continue;\n } else {\n this.complete(e instanceof Error ? e : new Error(String(e)));\n return;\n }\n }\n }\n\n try {\n if (this._summarizeChatCtx) {\n const sessionLlm = this.session.llm;\n if (!(sessionLlm instanceof LLM)) {\n throw new Error('summarizeChatCtx requires a standard LLM on the session');\n }\n\n // TODO(parity): Add excludeConfigUpdate when AgentConfigUpdate is ported\n const ctxToSummarize = this._chatCtx.copy({\n excludeInstructions: true,\n excludeHandoff: true,\n excludeEmptyMessage: true,\n excludeFunctionCall: true,\n });\n\n const summarizedChatCtx = await ctxToSummarize._summarize(sessionLlm, {\n keepLastTurns: 0,\n });\n await this.updateChatCtx(summarizedChatCtx);\n }\n } catch (e) {\n this.complete(new Error(`failed to summarize the chat_ctx: ${e}`));\n return;\n }\n\n this.complete({ taskResults });\n }\n\n private buildOutOfScopeTool(activeTaskId: string) {\n if (this._visitedTasks.size === 0) {\n return undefined;\n }\n\n const regressionTaskIds = new Set(this._visitedTasks);\n regressionTaskIds.delete(activeTaskId);\n\n if (regressionTaskIds.size === 0) {\n return undefined;\n }\n\n const taskRepr: Record<string, string> = {};\n for (const [id, info] of this._registeredFactories) {\n if (regressionTaskIds.has(id)) {\n taskRepr[id] = info.description;\n }\n }\n\n const taskIdValues = [...regressionTaskIds] as [string, ...string[]];\n\n const description =\n 'Call to regress to other tasks according to what the user requested to modify, return the corresponding task ids. ' +\n 'For example, if the user wants to change their email and there is a task with id \"email_task\" with a description of \"Collect the user\\'s email\", return the id (\"get_email_task\"). ' +\n 'If the user requests to regress to multiple tasks, such as changing their phone number and email, return both task ids in the order they were requested. ' +\n `The following are the IDs and their corresponding task description. ${JSON.stringify(taskRepr)}`;\n\n const currentTask = this._currentTask;\n const registeredFactories = this._registeredFactories;\n const visitedTasks = this._visitedTasks;\n\n return tool({\n description,\n flags: ToolFlag.IGNORE_ON_ENTER,\n parameters: z.object({\n task_ids: z.array(z.enum(taskIdValues)).describe('The IDs of the tasks requested'),\n }),\n execute: async ({ task_ids }: { task_ids: string[] }) => {\n for (const tid of task_ids) {\n if (!registeredFactories.has(tid) || !visitedTasks.has(tid)) {\n throw new ToolError(`Unable to regress, invalid task id ${tid}`);\n }\n }\n\n if (currentTask && !currentTask.done) {\n currentTask.complete(new OutOfScopeError(task_ids));\n }\n },\n });\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,32 @@
1
+ import type { ChatContext } from '../../llm/chat_context.js';
2
+ import { AgentTask } from '../../voice/agent.js';
3
+ export interface TaskGroupResult {
4
+ taskResults: Record<string, unknown>;
5
+ }
6
+ export interface TaskCompletedEvent {
7
+ agentTask: AgentTask;
8
+ taskId: string;
9
+ result: unknown;
10
+ }
11
+ export interface TaskGroupOptions {
12
+ summarizeChatCtx?: boolean;
13
+ returnExceptions?: boolean;
14
+ chatCtx?: ChatContext;
15
+ onTaskCompleted?: (event: TaskCompletedEvent) => Promise<void>;
16
+ }
17
+ export declare class TaskGroup extends AgentTask<TaskGroupResult> {
18
+ private _summarizeChatCtx;
19
+ private _returnExceptions;
20
+ private _visitedTasks;
21
+ private _registeredFactories;
22
+ private _taskCompletedCallback?;
23
+ private _currentTask?;
24
+ constructor(options?: TaskGroupOptions);
25
+ add(task: () => AgentTask, { id, description }: {
26
+ id: string;
27
+ description: string;
28
+ }): this;
29
+ onEnter(): Promise<void>;
30
+ private buildOutOfScopeTool;
31
+ }
32
+ //# sourceMappingURL=task_group.d.ts.map
@@ -0,0 +1,32 @@
1
+ import type { ChatContext } from '../../llm/chat_context.js';
2
+ import { AgentTask } from '../../voice/agent.js';
3
+ export interface TaskGroupResult {
4
+ taskResults: Record<string, unknown>;
5
+ }
6
+ export interface TaskCompletedEvent {
7
+ agentTask: AgentTask;
8
+ taskId: string;
9
+ result: unknown;
10
+ }
11
+ export interface TaskGroupOptions {
12
+ summarizeChatCtx?: boolean;
13
+ returnExceptions?: boolean;
14
+ chatCtx?: ChatContext;
15
+ onTaskCompleted?: (event: TaskCompletedEvent) => Promise<void>;
16
+ }
17
+ export declare class TaskGroup extends AgentTask<TaskGroupResult> {
18
+ private _summarizeChatCtx;
19
+ private _returnExceptions;
20
+ private _visitedTasks;
21
+ private _registeredFactories;
22
+ private _taskCompletedCallback?;
23
+ private _currentTask?;
24
+ constructor(options?: TaskGroupOptions);
25
+ add(task: () => AgentTask, { id, description }: {
26
+ id: string;
27
+ description: string;
28
+ }): this;
29
+ onEnter(): Promise<void>;
30
+ private buildOutOfScopeTool;
31
+ }
32
+ //# sourceMappingURL=task_group.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task_group.d.ts","sourceRoot":"","sources":["../../../src/beta/workflows/task_group.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAQjD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;CACjB;AAWD,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE;AAED,qBAAa,SAAU,SAAQ,SAAS,CAAC,eAAe,CAAC;IACvD,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,sBAAsB,CAAC,CAA+C;IAC9E,OAAO,CAAC,YAAY,CAAC,CAAY;gBAErB,OAAO,GAAE,gBAAqB;IAU1C,GAAG,CAAC,IAAI,EAAE,MAAM,SAAS,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAKpF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAgF9B,OAAO,CAAC,mBAAmB;CAkD5B"}
@@ -0,0 +1,138 @@
1
+ import { z } from "zod";
2
+ import { LLM, ToolError, ToolFlag, tool } from "../../llm/index.js";
3
+ import { AgentTask } from "../../voice/agent.js";
4
+ class OutOfScopeError extends ToolError {
5
+ targetTaskIds;
6
+ constructor(targetTaskIds) {
7
+ super("out_of_scope");
8
+ this.targetTaskIds = targetTaskIds;
9
+ }
10
+ }
11
+ class TaskGroup extends AgentTask {
12
+ _summarizeChatCtx;
13
+ _returnExceptions;
14
+ _visitedTasks = /* @__PURE__ */ new Set();
15
+ _registeredFactories = /* @__PURE__ */ new Map();
16
+ _taskCompletedCallback;
17
+ _currentTask;
18
+ constructor(options = {}) {
19
+ const { summarizeChatCtx = true, returnExceptions = false, chatCtx, onTaskCompleted } = options;
20
+ super({ instructions: "*empty*", chatCtx });
21
+ this._summarizeChatCtx = summarizeChatCtx;
22
+ this._returnExceptions = returnExceptions;
23
+ this._taskCompletedCallback = onTaskCompleted;
24
+ }
25
+ add(task, { id, description }) {
26
+ this._registeredFactories.set(id, { taskFactory: task, id, description });
27
+ return this;
28
+ }
29
+ async onEnter() {
30
+ const taskStack = [...this._registeredFactories.keys()];
31
+ const taskResults = {};
32
+ while (taskStack.length > 0) {
33
+ const taskId = taskStack.shift();
34
+ const factoryInfo = this._registeredFactories.get(taskId);
35
+ this._currentTask = factoryInfo.taskFactory();
36
+ const sharedChatCtx = this._chatCtx.copy();
37
+ await this._currentTask.updateChatCtx(sharedChatCtx);
38
+ const outOfScopeTool = this.buildOutOfScopeTool(taskId);
39
+ if (outOfScopeTool) {
40
+ await this._currentTask.updateTools({
41
+ ...this._currentTask.toolCtx,
42
+ out_of_scope: outOfScopeTool
43
+ });
44
+ }
45
+ try {
46
+ this._visitedTasks.add(taskId);
47
+ const res = await this._currentTask.run();
48
+ taskResults[taskId] = res;
49
+ if (this._taskCompletedCallback) {
50
+ await this._taskCompletedCallback({
51
+ agentTask: this._currentTask,
52
+ taskId,
53
+ result: res
54
+ });
55
+ }
56
+ } catch (e) {
57
+ if (e instanceof OutOfScopeError) {
58
+ taskStack.unshift(taskId);
59
+ for (let i = e.targetTaskIds.length - 1; i >= 0; i--) {
60
+ taskStack.unshift(e.targetTaskIds[i]);
61
+ }
62
+ continue;
63
+ }
64
+ if (this._returnExceptions) {
65
+ taskResults[taskId] = e;
66
+ continue;
67
+ } else {
68
+ this.complete(e instanceof Error ? e : new Error(String(e)));
69
+ return;
70
+ }
71
+ }
72
+ }
73
+ try {
74
+ if (this._summarizeChatCtx) {
75
+ const sessionLlm = this.session.llm;
76
+ if (!(sessionLlm instanceof LLM)) {
77
+ throw new Error("summarizeChatCtx requires a standard LLM on the session");
78
+ }
79
+ const ctxToSummarize = this._chatCtx.copy({
80
+ excludeInstructions: true,
81
+ excludeHandoff: true,
82
+ excludeEmptyMessage: true,
83
+ excludeFunctionCall: true
84
+ });
85
+ const summarizedChatCtx = await ctxToSummarize._summarize(sessionLlm, {
86
+ keepLastTurns: 0
87
+ });
88
+ await this.updateChatCtx(summarizedChatCtx);
89
+ }
90
+ } catch (e) {
91
+ this.complete(new Error(`failed to summarize the chat_ctx: ${e}`));
92
+ return;
93
+ }
94
+ this.complete({ taskResults });
95
+ }
96
+ buildOutOfScopeTool(activeTaskId) {
97
+ if (this._visitedTasks.size === 0) {
98
+ return void 0;
99
+ }
100
+ const regressionTaskIds = new Set(this._visitedTasks);
101
+ regressionTaskIds.delete(activeTaskId);
102
+ if (regressionTaskIds.size === 0) {
103
+ return void 0;
104
+ }
105
+ const taskRepr = {};
106
+ for (const [id, info] of this._registeredFactories) {
107
+ if (regressionTaskIds.has(id)) {
108
+ taskRepr[id] = info.description;
109
+ }
110
+ }
111
+ const taskIdValues = [...regressionTaskIds];
112
+ const description = `Call to regress to other tasks according to what the user requested to modify, return the corresponding task ids. For example, if the user wants to change their email and there is a task with id "email_task" with a description of "Collect the user's email", return the id ("get_email_task"). If the user requests to regress to multiple tasks, such as changing their phone number and email, return both task ids in the order they were requested. The following are the IDs and their corresponding task description. ${JSON.stringify(taskRepr)}`;
113
+ const currentTask = this._currentTask;
114
+ const registeredFactories = this._registeredFactories;
115
+ const visitedTasks = this._visitedTasks;
116
+ return tool({
117
+ description,
118
+ flags: ToolFlag.IGNORE_ON_ENTER,
119
+ parameters: z.object({
120
+ task_ids: z.array(z.enum(taskIdValues)).describe("The IDs of the tasks requested")
121
+ }),
122
+ execute: async ({ task_ids }) => {
123
+ for (const tid of task_ids) {
124
+ if (!registeredFactories.has(tid) || !visitedTasks.has(tid)) {
125
+ throw new ToolError(`Unable to regress, invalid task id ${tid}`);
126
+ }
127
+ }
128
+ if (currentTask && !currentTask.done) {
129
+ currentTask.complete(new OutOfScopeError(task_ids));
130
+ }
131
+ }
132
+ });
133
+ }
134
+ }
135
+ export {
136
+ TaskGroup
137
+ };
138
+ //# sourceMappingURL=task_group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/beta/workflows/task_group.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { z } from 'zod';\nimport type { ChatContext } from '../../llm/chat_context.js';\nimport { LLM, ToolError, ToolFlag, tool } from '../../llm/index.js';\nimport { AgentTask } from '../../voice/agent.js';\n\ninterface FactoryInfo {\n taskFactory: () => AgentTask;\n id: string;\n description: string;\n}\n\nexport interface TaskGroupResult {\n taskResults: Record<string, unknown>;\n}\n\nexport interface TaskCompletedEvent {\n agentTask: AgentTask;\n taskId: string;\n result: unknown;\n}\n\nclass OutOfScopeError extends ToolError {\n readonly targetTaskIds: string[];\n\n constructor(targetTaskIds: string[]) {\n super('out_of_scope');\n this.targetTaskIds = targetTaskIds;\n }\n}\n\nexport interface TaskGroupOptions {\n summarizeChatCtx?: boolean;\n returnExceptions?: boolean;\n chatCtx?: ChatContext;\n onTaskCompleted?: (event: TaskCompletedEvent) => Promise<void>;\n}\n\nexport class TaskGroup extends AgentTask<TaskGroupResult> {\n private _summarizeChatCtx: boolean;\n private _returnExceptions: boolean;\n private _visitedTasks = new Set<string>();\n private _registeredFactories = new Map<string, FactoryInfo>();\n private _taskCompletedCallback?: (event: TaskCompletedEvent) => Promise<void>;\n private _currentTask?: AgentTask;\n\n constructor(options: TaskGroupOptions = {}) {\n const { summarizeChatCtx = true, returnExceptions = false, chatCtx, onTaskCompleted } = options;\n\n super({ instructions: '*empty*', chatCtx });\n\n this._summarizeChatCtx = summarizeChatCtx;\n this._returnExceptions = returnExceptions;\n this._taskCompletedCallback = onTaskCompleted;\n }\n\n add(task: () => AgentTask, { id, description }: { id: string; description: string }): this {\n this._registeredFactories.set(id, { taskFactory: task, id, description });\n return this;\n }\n\n async onEnter(): Promise<void> {\n const taskStack = [...this._registeredFactories.keys()];\n const taskResults: Record<string, unknown> = {};\n\n while (taskStack.length > 0) {\n const taskId = taskStack.shift()!;\n const factoryInfo = this._registeredFactories.get(taskId)!;\n\n this._currentTask = factoryInfo.taskFactory();\n\n const sharedChatCtx = this._chatCtx.copy();\n await this._currentTask.updateChatCtx(sharedChatCtx);\n\n const outOfScopeTool = this.buildOutOfScopeTool(taskId);\n if (outOfScopeTool) {\n await this._currentTask.updateTools({\n ...this._currentTask.toolCtx,\n out_of_scope: outOfScopeTool,\n });\n }\n\n try {\n this._visitedTasks.add(taskId);\n const res = await this._currentTask.run();\n taskResults[taskId] = res;\n\n if (this._taskCompletedCallback) {\n await this._taskCompletedCallback({\n agentTask: this._currentTask,\n taskId,\n result: res,\n });\n }\n } catch (e) {\n if (e instanceof OutOfScopeError) {\n taskStack.unshift(taskId);\n for (let i = e.targetTaskIds.length - 1; i >= 0; i--) {\n taskStack.unshift(e.targetTaskIds[i]!);\n }\n continue;\n }\n\n if (this._returnExceptions) {\n taskResults[taskId] = e;\n continue;\n } else {\n this.complete(e instanceof Error ? e : new Error(String(e)));\n return;\n }\n }\n }\n\n try {\n if (this._summarizeChatCtx) {\n const sessionLlm = this.session.llm;\n if (!(sessionLlm instanceof LLM)) {\n throw new Error('summarizeChatCtx requires a standard LLM on the session');\n }\n\n // TODO(parity): Add excludeConfigUpdate when AgentConfigUpdate is ported\n const ctxToSummarize = this._chatCtx.copy({\n excludeInstructions: true,\n excludeHandoff: true,\n excludeEmptyMessage: true,\n excludeFunctionCall: true,\n });\n\n const summarizedChatCtx = await ctxToSummarize._summarize(sessionLlm, {\n keepLastTurns: 0,\n });\n await this.updateChatCtx(summarizedChatCtx);\n }\n } catch (e) {\n this.complete(new Error(`failed to summarize the chat_ctx: ${e}`));\n return;\n }\n\n this.complete({ taskResults });\n }\n\n private buildOutOfScopeTool(activeTaskId: string) {\n if (this._visitedTasks.size === 0) {\n return undefined;\n }\n\n const regressionTaskIds = new Set(this._visitedTasks);\n regressionTaskIds.delete(activeTaskId);\n\n if (regressionTaskIds.size === 0) {\n return undefined;\n }\n\n const taskRepr: Record<string, string> = {};\n for (const [id, info] of this._registeredFactories) {\n if (regressionTaskIds.has(id)) {\n taskRepr[id] = info.description;\n }\n }\n\n const taskIdValues = [...regressionTaskIds] as [string, ...string[]];\n\n const description =\n 'Call to regress to other tasks according to what the user requested to modify, return the corresponding task ids. ' +\n 'For example, if the user wants to change their email and there is a task with id \"email_task\" with a description of \"Collect the user\\'s email\", return the id (\"get_email_task\"). ' +\n 'If the user requests to regress to multiple tasks, such as changing their phone number and email, return both task ids in the order they were requested. ' +\n `The following are the IDs and their corresponding task description. ${JSON.stringify(taskRepr)}`;\n\n const currentTask = this._currentTask;\n const registeredFactories = this._registeredFactories;\n const visitedTasks = this._visitedTasks;\n\n return tool({\n description,\n flags: ToolFlag.IGNORE_ON_ENTER,\n parameters: z.object({\n task_ids: z.array(z.enum(taskIdValues)).describe('The IDs of the tasks requested'),\n }),\n execute: async ({ task_ids }: { task_ids: string[] }) => {\n for (const tid of task_ids) {\n if (!registeredFactories.has(tid) || !visitedTasks.has(tid)) {\n throw new ToolError(`Unable to regress, invalid task id ${tid}`);\n }\n }\n\n if (currentTask && !currentTask.done) {\n currentTask.complete(new OutOfScopeError(task_ids));\n }\n },\n });\n }\n}\n"],"mappings":"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","names":[]}
package/dist/cli.cjs CHANGED
@@ -69,9 +69,8 @@ const runServer = async (args) => {
69
69
  }
70
70
  };
71
71
  const runApp = (opts) => {
72
+ const logLevelOption = (defaultLevel) => new import_commander.Option("--log-level <level>", "Set the logging level").choices(["trace", "debug", "info", "warn", "error", "fatal"]).default(defaultLevel).env("LOG_LEVEL");
72
73
  const program = new import_commander.Command().name("agents").description("LiveKit Agents CLI").version(import_version.version).addOption(
73
- new import_commander.Option("--log-level <level>", "Set the logging level").choices(["trace", "debug", "info", "warn", "error", "fatal"]).default("info").env("LOG_LEVEL")
74
- ).addOption(
75
74
  new import_commander.Option("--url <string>", "LiveKit server or Cloud project websocket URL").env(
76
75
  "LIVEKIT_URL"
77
76
  )
@@ -93,28 +92,27 @@ const runApp = (opts) => {
93
92
  program.help();
94
93
  }
95
94
  });
96
- program.command("start").description("Start the worker in production mode").action(() => {
97
- const options = program.optsWithGlobals();
98
- opts.wsURL = options.url || opts.wsURL;
99
- opts.apiKey = options.apiKey || opts.apiKey;
100
- opts.apiSecret = options.apiSecret || opts.apiSecret;
101
- opts.logLevel = options.logLevel || opts.logLevel;
102
- opts.workerToken = options.workerToken || opts.workerToken;
95
+ program.command("start").description("Start the worker in production mode").addOption(logLevelOption("info")).action((...[, command]) => {
96
+ const globalOptions = program.optsWithGlobals();
97
+ const commandOptions = command.opts();
98
+ opts.wsURL = globalOptions.url || opts.wsURL;
99
+ opts.apiKey = globalOptions.apiKey || opts.apiKey;
100
+ opts.apiSecret = globalOptions.apiSecret || opts.apiSecret;
101
+ opts.logLevel = commandOptions.logLevel;
102
+ opts.workerToken = globalOptions.workerToken || opts.workerToken;
103
103
  runServer({
104
104
  opts,
105
105
  production: true,
106
106
  watch: false
107
107
  });
108
108
  });
109
- program.command("dev").description("Start the worker in development mode").addOption(
110
- new import_commander.Option("--log-level <level>", "Set the logging level").choices(["trace", "debug", "info", "warn", "error", "fatal"]).default("debug").env("LOG_LEVEL")
111
- ).action((...[, command]) => {
109
+ program.command("dev").description("Start the worker in development mode").addOption(logLevelOption("debug")).action((...[, command]) => {
112
110
  const globalOptions = program.optsWithGlobals();
113
111
  const commandOptions = command.opts();
114
112
  opts.wsURL = globalOptions.url || opts.wsURL;
115
113
  opts.apiKey = globalOptions.apiKey || opts.apiKey;
116
114
  opts.apiSecret = globalOptions.apiSecret || opts.apiSecret;
117
- opts.logLevel = commandOptions.logLevel || globalOptions.logLevel || opts.logLevel;
115
+ opts.logLevel = commandOptions.logLevel;
118
116
  opts.workerToken = globalOptions.workerToken || opts.workerToken;
119
117
  runServer({
120
118
  opts,
@@ -122,15 +120,13 @@ const runApp = (opts) => {
122
120
  watch: false
123
121
  });
124
122
  });
125
- program.command("connect").description("Connect to a specific room").requiredOption("--room <string>", "Room name to connect to").option("--participant-identity <string>", "Identity of user to listen to").addOption(
126
- new import_commander.Option("--log-level <level>", "Set the logging level").choices(["trace", "debug", "info", "warn", "error", "fatal"]).default("debug").env("LOG_LEVEL")
127
- ).action((...[, command]) => {
123
+ program.command("connect").description("Connect to a specific room").requiredOption("--room <string>", "Room name to connect to").option("--participant-identity <string>", "Identity of user to listen to").addOption(logLevelOption("info")).action((...[, command]) => {
128
124
  const globalOptions = program.optsWithGlobals();
129
125
  const commandOptions = command.opts();
130
126
  opts.wsURL = globalOptions.url || opts.wsURL;
131
127
  opts.apiKey = globalOptions.apiKey || opts.apiKey;
132
128
  opts.apiSecret = globalOptions.apiSecret || opts.apiSecret;
133
- opts.logLevel = commandOptions.logLevel || globalOptions.logLevel || opts.logLevel;
129
+ opts.logLevel = commandOptions.logLevel;
134
130
  opts.workerToken = globalOptions.workerToken || opts.workerToken;
135
131
  runServer({
136
132
  opts,
@@ -140,9 +136,7 @@ const runApp = (opts) => {
140
136
  participantIdentity: commandOptions.participantIdentity
141
137
  });
142
138
  });
143
- program.command("download-files").description("Download plugin dependency files").addOption(
144
- new import_commander.Option("--log-level <level>", "Set the logging level").choices(["trace", "debug", "info", "warn", "error", "fatal"]).default("debug").env("LOG_LEVEL")
145
- ).action((...[, command]) => {
139
+ program.command("download-files").description("Download plugin dependency files").addOption(logLevelOption("debug")).action((...[, command]) => {
146
140
  const commandOptions = command.opts();
147
141
  (0, import_log.initializeLogger)({ pretty: true, level: commandOptions.logLevel });
148
142
  const logger = (0, import_log.log)();