@xalia/agent 0.5.8 → 0.6.1

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 (185) hide show
  1. package/README.md +23 -8
  2. package/dist/agent/src/agent/agent.js +173 -96
  3. package/dist/agent/src/agent/agentUtils.js +82 -53
  4. package/dist/agent/src/agent/compressingContextManager.js +102 -0
  5. package/dist/agent/src/agent/context.js +189 -0
  6. package/dist/agent/src/agent/dummyLLM.js +46 -5
  7. package/dist/agent/src/agent/iAgentEventHandler.js +2 -0
  8. package/dist/agent/src/agent/mcpServerManager.js +22 -23
  9. package/dist/agent/src/agent/nullAgentEventHandler.js +21 -0
  10. package/dist/agent/src/agent/nullPlatform.js +14 -0
  11. package/dist/agent/src/agent/openAILLMStreaming.js +12 -7
  12. package/dist/agent/src/agent/promptProvider.js +63 -0
  13. package/dist/agent/src/agent/repeatLLM.js +5 -5
  14. package/dist/agent/src/agent/sudoMcpServerManager.js +11 -9
  15. package/dist/agent/src/agent/tokenAuth.js +7 -7
  16. package/dist/agent/src/agent/tools.js +1 -1
  17. package/dist/agent/src/chat/client/chatClient.js +733 -0
  18. package/dist/agent/src/chat/client/connection.js +209 -0
  19. package/dist/agent/src/chat/client/connection.test.js +188 -0
  20. package/dist/agent/src/chat/client/constants.js +5 -0
  21. package/dist/agent/src/chat/client/index.js +15 -0
  22. package/dist/agent/src/chat/client/interfaces.js +2 -0
  23. package/dist/agent/src/chat/client/responseHandler.js +105 -0
  24. package/dist/agent/src/chat/client/sessionClient.js +331 -0
  25. package/dist/agent/src/chat/client/teamManager.js +2 -0
  26. package/dist/agent/src/chat/{apiKeyManager.js → data/apiKeyManager.js} +4 -0
  27. package/dist/agent/src/chat/data/dataModels.js +2 -0
  28. package/dist/agent/src/chat/data/database.js +749 -0
  29. package/dist/agent/src/chat/data/dbMcpServerConfigs.js +47 -0
  30. package/dist/agent/src/chat/protocol/connectionMessages.js +5 -0
  31. package/dist/agent/src/chat/protocol/constants.js +50 -0
  32. package/dist/agent/src/chat/protocol/errors.js +22 -0
  33. package/dist/agent/src/chat/protocol/messages.js +110 -0
  34. package/dist/agent/src/chat/server/chatContextManager.js +405 -0
  35. package/dist/agent/src/chat/server/connectionManager.js +352 -0
  36. package/dist/agent/src/chat/server/connectionManager.test.js +159 -0
  37. package/dist/agent/src/chat/server/conversation.js +198 -0
  38. package/dist/agent/src/chat/server/errorUtils.js +23 -0
  39. package/dist/agent/src/chat/server/openSession.js +869 -0
  40. package/dist/agent/src/chat/server/server.js +177 -0
  41. package/dist/agent/src/chat/server/sessionFileManager.js +161 -0
  42. package/dist/agent/src/chat/server/sessionRegistry.js +700 -0
  43. package/dist/agent/src/chat/server/sessionRegistry.test.js +97 -0
  44. package/dist/agent/src/chat/server/test-utils/mockFactories.js +307 -0
  45. package/dist/agent/src/chat/server/tools.js +243 -0
  46. package/dist/agent/src/chat/utils/agentSessionMap.js +66 -0
  47. package/dist/agent/src/chat/utils/approvalManager.js +85 -0
  48. package/dist/agent/src/{utils → chat/utils}/asyncLock.js +3 -3
  49. package/dist/agent/src/chat/{asyncQueue.js → utils/asyncQueue.js} +12 -2
  50. package/dist/agent/src/chat/utils/htmlToText.js +84 -0
  51. package/dist/agent/src/chat/utils/multiAsyncQueue.js +42 -0
  52. package/dist/agent/src/chat/utils/search.js +145 -0
  53. package/dist/agent/src/chat/utils/userResolver.js +46 -0
  54. package/dist/agent/src/chat/{websocket.js → utils/websocket.js} +2 -0
  55. package/dist/agent/src/test/agent.test.js +332 -0
  56. package/dist/agent/src/test/approvalManager.test.js +58 -0
  57. package/dist/agent/src/test/chatContextManager.test.js +392 -0
  58. package/dist/agent/src/test/clientServerConnection.test.js +158 -0
  59. package/dist/agent/src/test/compressingContextManager.test.js +65 -0
  60. package/dist/agent/src/test/context.test.js +83 -0
  61. package/dist/agent/src/test/conversation.test.js +89 -0
  62. package/dist/agent/src/test/db.test.js +262 -90
  63. package/dist/agent/src/test/dbMcpServerConfigs.test.js +72 -0
  64. package/dist/agent/src/test/dbTestTools.js +99 -0
  65. package/dist/agent/src/test/imageLoad.test.js +8 -7
  66. package/dist/agent/src/test/mcpServerManager.test.js +21 -18
  67. package/dist/agent/src/test/multiAsyncQueue.test.js +101 -0
  68. package/dist/agent/src/test/openaiStreaming.test.js +12 -11
  69. package/dist/agent/src/test/prompt.test.js +5 -4
  70. package/dist/agent/src/test/promptProvider.test.js +28 -0
  71. package/dist/agent/src/test/responseHandler.test.js +61 -0
  72. package/dist/agent/src/test/sudoMcpServerManager.test.js +14 -12
  73. package/dist/agent/src/test/testTools.js +109 -0
  74. package/dist/agent/src/test/tools.test.js +31 -0
  75. package/dist/agent/src/tool/agentChat.js +21 -10
  76. package/dist/agent/src/tool/agentMain.js +1 -1
  77. package/dist/agent/src/tool/chatMain.js +235 -58
  78. package/dist/agent/src/tool/commandPrompt.js +15 -9
  79. package/dist/agent/src/tool/files.js +20 -16
  80. package/dist/agent/src/tool/nodePlatform.js +47 -3
  81. package/dist/agent/src/tool/options.js +4 -4
  82. package/dist/agent/src/tool/prompt.js +19 -13
  83. package/eslint.config.mjs +14 -1
  84. package/package.json +14 -6
  85. package/scripts/chat_server +8 -0
  86. package/scripts/setup_chat +7 -2
  87. package/scripts/shutdown_chat_server +3 -0
  88. package/scripts/test_chat +135 -17
  89. package/src/agent/agent.ts +270 -135
  90. package/src/agent/agentUtils.ts +136 -95
  91. package/src/agent/compressingContextManager.ts +164 -0
  92. package/src/agent/context.ts +268 -0
  93. package/src/agent/dummyLLM.ts +76 -8
  94. package/src/agent/iAgentEventHandler.ts +54 -0
  95. package/src/agent/iplatform.ts +1 -0
  96. package/src/agent/mcpServerManager.ts +32 -30
  97. package/src/agent/nullAgentEventHandler.ts +20 -0
  98. package/src/agent/nullPlatform.ts +13 -0
  99. package/src/agent/openAILLMStreaming.ts +12 -6
  100. package/src/agent/promptProvider.ts +87 -0
  101. package/src/agent/repeatLLM.ts +5 -5
  102. package/src/agent/sudoMcpServerManager.ts +13 -11
  103. package/src/agent/tokenAuth.ts +7 -7
  104. package/src/agent/tools.ts +3 -1
  105. package/src/chat/client/chatClient.ts +900 -0
  106. package/src/chat/client/connection.test.ts +241 -0
  107. package/src/chat/client/connection.ts +276 -0
  108. package/src/chat/client/constants.ts +3 -0
  109. package/src/chat/client/index.ts +18 -0
  110. package/src/chat/client/interfaces.ts +34 -0
  111. package/src/chat/client/responseHandler.ts +131 -0
  112. package/src/chat/client/sessionClient.ts +443 -0
  113. package/src/chat/client/teamManager.ts +29 -0
  114. package/src/chat/{apiKeyManager.ts → data/apiKeyManager.ts} +6 -2
  115. package/src/chat/data/dataModels.ts +85 -0
  116. package/src/chat/data/database.ts +982 -0
  117. package/src/chat/data/dbMcpServerConfigs.ts +59 -0
  118. package/src/chat/protocol/connectionMessages.ts +49 -0
  119. package/src/chat/protocol/constants.ts +55 -0
  120. package/src/chat/protocol/errors.ts +16 -0
  121. package/src/chat/protocol/messages.ts +682 -0
  122. package/src/chat/server/README.md +127 -0
  123. package/src/chat/server/chatContextManager.ts +612 -0
  124. package/src/chat/server/connectionManager.test.ts +266 -0
  125. package/src/chat/server/connectionManager.ts +541 -0
  126. package/src/chat/server/conversation.ts +269 -0
  127. package/src/chat/server/errorUtils.ts +28 -0
  128. package/src/chat/server/openSession.ts +1332 -0
  129. package/src/chat/server/server.ts +177 -0
  130. package/src/chat/server/sessionFileManager.ts +239 -0
  131. package/src/chat/server/sessionRegistry.test.ts +138 -0
  132. package/src/chat/server/sessionRegistry.ts +1064 -0
  133. package/src/chat/server/test-utils/mockFactories.ts +422 -0
  134. package/src/chat/server/tools.ts +265 -0
  135. package/src/chat/utils/agentSessionMap.ts +76 -0
  136. package/src/chat/utils/approvalManager.ts +111 -0
  137. package/src/{utils → chat/utils}/asyncLock.ts +3 -3
  138. package/src/chat/{asyncQueue.ts → utils/asyncQueue.ts} +14 -3
  139. package/src/chat/utils/htmlToText.ts +61 -0
  140. package/src/chat/utils/multiAsyncQueue.ts +52 -0
  141. package/src/chat/utils/search.ts +139 -0
  142. package/src/chat/utils/userResolver.ts +48 -0
  143. package/src/chat/{websocket.ts → utils/websocket.ts} +2 -0
  144. package/src/test/agent.test.ts +487 -0
  145. package/src/test/approvalManager.test.ts +73 -0
  146. package/src/test/chatContextManager.test.ts +521 -0
  147. package/src/test/clientServerConnection.test.ts +207 -0
  148. package/src/test/compressingContextManager.test.ts +82 -0
  149. package/src/test/context.test.ts +105 -0
  150. package/src/test/conversation.test.ts +109 -0
  151. package/src/test/db.test.ts +351 -103
  152. package/src/test/dbMcpServerConfigs.test.ts +112 -0
  153. package/src/test/dbTestTools.ts +153 -0
  154. package/src/test/imageLoad.test.ts +7 -6
  155. package/src/test/mcpServerManager.test.ts +19 -14
  156. package/src/test/multiAsyncQueue.test.ts +125 -0
  157. package/src/test/openaiStreaming.test.ts +11 -10
  158. package/src/test/prompt.test.ts +4 -3
  159. package/src/test/promptProvider.test.ts +33 -0
  160. package/src/test/responseHandler.test.ts +78 -0
  161. package/src/test/sudoMcpServerManager.test.ts +22 -15
  162. package/src/test/testTools.ts +146 -0
  163. package/src/test/tools.test.ts +39 -0
  164. package/src/tool/agentChat.ts +26 -12
  165. package/src/tool/agentMain.ts +1 -1
  166. package/src/tool/chatMain.ts +283 -100
  167. package/src/tool/commandPrompt.ts +25 -9
  168. package/src/tool/files.ts +25 -19
  169. package/src/tool/nodePlatform.ts +52 -3
  170. package/src/tool/options.ts +4 -2
  171. package/src/tool/prompt.ts +22 -15
  172. package/test_data/dummyllm_script_crash.json +32 -0
  173. package/test_data/frog.png.b64 +1 -0
  174. package/vitest.config.ts +39 -0
  175. package/dist/agent/src/chat/client.js +0 -310
  176. package/dist/agent/src/chat/conversationManager.js +0 -502
  177. package/dist/agent/src/chat/db.js +0 -218
  178. package/dist/agent/src/chat/messages.js +0 -29
  179. package/dist/agent/src/chat/server.js +0 -158
  180. package/src/chat/client.ts +0 -445
  181. package/src/chat/conversationManager.ts +0 -730
  182. package/src/chat/db.ts +0 -304
  183. package/src/chat/messages.ts +0 -266
  184. package/src/chat/server.ts +0 -177
  185. /package/{frog.png → test_data/frog.png} +0 -0
@@ -47,9 +47,6 @@ function updateToolCallFunction(
47
47
  // `arguments` has been observered to arrive in chunks. The same is
48
48
  // probably true of `name`.
49
49
 
50
- if (!deltaFn) {
51
- return;
52
- }
53
50
  if (deltaFn.name) {
54
51
  existingFn.name += deltaFn.name;
55
52
  }
@@ -131,8 +128,10 @@ function updateToolCalls(
131
128
  if (typeof toolCalls === "undefined") {
132
129
  toolCalls = [];
133
130
  }
134
- const existing = toolCalls[deltaToolCall.index];
135
- if (!existing) {
131
+ if (
132
+ deltaToolCall.index >= toolCalls.length ||
133
+ !toolCalls[deltaToolCall.index]
134
+ ) {
136
135
  toolCalls[deltaToolCall.index] = initialToolCall(deltaToolCall);
137
136
  } else {
138
137
  updateToolCall(toolCalls[deltaToolCall.index], deltaToolCall);
@@ -144,6 +143,7 @@ function initializeCompletionMessage(
144
143
  delta: OpenAI.Chat.Completions.ChatCompletionChunk.Choice.Delta
145
144
  ): OpenAI.Chat.Completions.ChatCompletionMessage {
146
145
  assert(delta.role === undefined || delta.role == "assistant");
146
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
147
147
  assert(!delta.function_call);
148
148
 
149
149
  // export interface ChatCompletionChunk.Choice.Delta {
@@ -190,7 +190,9 @@ function updateCompletionMessage(
190
190
  message: OpenAI.Chat.Completions.ChatCompletionMessage,
191
191
  delta: OpenAI.Chat.Completions.ChatCompletionChunk.Choice.Delta
192
192
  ) {
193
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
193
194
  assert(message.role === "assistant");
195
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
194
196
  assert(!message.function_call);
195
197
  assert(!message.audio);
196
198
  assert(
@@ -225,6 +227,7 @@ function updateCompletionMessage(
225
227
  message.content = delta.content;
226
228
  }
227
229
  }
230
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
228
231
  assert(!delta.function_call);
229
232
  if (delta.refusal) {
230
233
  if (message.refusal) {
@@ -303,6 +306,7 @@ function updateCompletionChoice(
303
306
  updateCompletionMessage(completionChoice.message, chunkChoice.delta);
304
307
  if (chunkChoice.finish_reason) {
305
308
  assert(
309
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
306
310
  completionChoice.finish_reason === null,
307
311
  `finish_reason already set: (${completionChoice.finish_reason})`
308
312
  );
@@ -490,13 +494,14 @@ export class OpenAILLMStreaming implements ILLM {
490
494
 
491
495
  // Check the type casting above
492
496
  if (!(chunks as unknown as { iterator: unknown }).iterator) {
493
- throw "not a stream";
497
+ throw new Error("not a stream");
494
498
  }
495
499
 
496
500
  let aggregatedMessage: OpenAI.Chat.Completions.ChatCompletion | undefined;
497
501
  for await (const chunk of chunks) {
498
502
  logger.debug(`[stream] chunk: ${JSON.stringify(chunk)}`);
499
503
 
504
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
500
505
  if (chunk.object !== "chat.completion.chunk") {
501
506
  // logger.warn("[stream]: unexpected message");
502
507
  continue;
@@ -516,6 +521,7 @@ export class OpenAILLMStreaming implements ILLM {
516
521
  // we safely access the first choice.
517
522
 
518
523
  const delta = chunk.choices[0]?.delta;
524
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
519
525
  if (delta?.content) {
520
526
  await onMessage(delta.content, false);
521
527
  }
@@ -0,0 +1,87 @@
1
+ import { strict as assert } from "assert";
2
+
3
+ /**
4
+ * Manage a structured system-prompt, built up of several components which can
5
+ * be updated at different frequencies.
6
+ */
7
+ export class SystemPromptProvider {
8
+ /**
9
+ * A global prompt, common to all agents.
10
+ */
11
+ private static globalPrompt: string = "";
12
+
13
+ /**
14
+ * Specific to this particular agent. AgentProfile.system_prompt.
15
+ */
16
+ private agentPrompt: string;
17
+
18
+ /**
19
+ * Prompt components defined by tools or client code. Fragments are
20
+ * identified by ID strings, so they can later be updated or removed.
21
+ */
22
+ private fragments: Map<string, string>;
23
+
24
+ private fullPrompt: string;
25
+ private updatePrompt: boolean;
26
+
27
+ constructor(agentPrompt: string) {
28
+ this.agentPrompt = agentPrompt;
29
+ this.fragments = new Map();
30
+ this.fullPrompt = "";
31
+ this.updatePrompt = true;
32
+ }
33
+
34
+ /**
35
+ * This is not expected to change dynamically, but to be set exactly once at
36
+ * startup. Thus existing prompts are not recomputed if this is updated.
37
+ */
38
+ static setGlobalPrompt(globalPrompt: string | undefined) {
39
+ SystemPromptProvider.globalPrompt = globalPrompt || "";
40
+ }
41
+
42
+ getAgentPrompt(): string {
43
+ return this.agentPrompt;
44
+ }
45
+
46
+ setAgentPrompt(agentPrompt: string) {
47
+ this.agentPrompt = agentPrompt;
48
+ this.updatePrompt = true;
49
+ }
50
+
51
+ setFragment(fragmentID: string, prompt: string) {
52
+ this.fragments.set(fragmentID, prompt);
53
+ this.updatePrompt = true;
54
+ }
55
+
56
+ removeFragment(fragmentID: string) {
57
+ this.fragments.delete(fragmentID);
58
+ this.updatePrompt = true;
59
+ }
60
+
61
+ getSystemPrompt(): string {
62
+ if (this.updatePrompt) {
63
+ this.computePrompt();
64
+ }
65
+ assert(!this.updatePrompt);
66
+ return this.fullPrompt;
67
+ }
68
+
69
+ private computePrompt() {
70
+ const global = SystemPromptProvider.globalPrompt.trimEnd();
71
+ const globalPost = global.length > 0 ? "\n" : "";
72
+
73
+ let prompt =
74
+ SystemPromptProvider.globalPrompt.trimEnd() +
75
+ globalPost +
76
+ this.agentPrompt.trimEnd();
77
+
78
+ // TODO: allow some control over the ordering?
79
+
80
+ for (const v of this.fragments.values()) {
81
+ prompt += "\n" + v.trimEnd();
82
+ }
83
+
84
+ this.fullPrompt = prompt;
85
+ this.updatePrompt = false;
86
+ }
87
+ }
@@ -10,7 +10,7 @@ export class RepeatLLM implements ILLM {
10
10
  }
11
11
 
12
12
  public getUrl(): string {
13
- throw "cannot get url for RepeatLLM";
13
+ throw new Error("cannot get url for RepeatLLM");
14
14
  }
15
15
 
16
16
  public async getConversationResponse(
@@ -18,9 +18,9 @@ export class RepeatLLM implements ILLM {
18
18
  _tools?: OpenAI.Chat.Completions.ChatCompletionTool[],
19
19
  onMessage?: (msg: string, msgEnd: boolean) => Promise<void>
20
20
  ): Promise<OpenAI.Chat.Completions.ChatCompletion> {
21
- await new Promise((r) => setTimeout(r, 0));
21
+ await new Promise((r) => setTimeout(r, 1000));
22
22
 
23
- const content = `Message number ${this.idx++}`;
23
+ const content = `Message number ${String(this.idx++)}`;
24
24
  const response: OpenAI.Chat.Completions.ChatCompletion.Choice = {
25
25
  finish_reason: "stop",
26
26
  index: 0,
@@ -33,11 +33,11 @@ export class RepeatLLM implements ILLM {
33
33
  };
34
34
 
35
35
  if (onMessage) {
36
- onMessage(content, true);
36
+ void onMessage(content, true);
37
37
  }
38
38
 
39
39
  return {
40
- id: "" + this.idx,
40
+ id: String(this.idx),
41
41
  choices: [response],
42
42
  created: Date.now(),
43
43
  model: "dummyLlmModel",
@@ -67,7 +67,7 @@ export class SkillManager extends McpServerManager implements ISkillManager {
67
67
  private apiClient: ApiClient,
68
68
  private serverBriefs: SanitizedServerBrief[],
69
69
  private serverBriefsMap: { [serverName: string]: SanitizedServerBrief },
70
- private toolCache: { [serverName: string]: Tool[] },
70
+ private toolCache: Map<string, Tool[]>,
71
71
  private openUrl: (
72
72
  url: string,
73
73
  authResultP: Promise<boolean>,
@@ -106,7 +106,7 @@ export class SkillManager extends McpServerManager implements ISkillManager {
106
106
  apiClient,
107
107
  mcpServers,
108
108
  mcpServersMap,
109
- {},
109
+ new Map(),
110
110
  openUrl,
111
111
  authorized_url
112
112
  );
@@ -121,7 +121,7 @@ export class SkillManager extends McpServerManager implements ISkillManager {
121
121
  public async restoreMcpSettings(
122
122
  mcpSettings: McpServerSettings
123
123
  ): Promise<void> {
124
- await this.restoreConfiguration(mcpSettings);
124
+ return this.restoreConfiguration(mcpSettings);
125
125
  }
126
126
 
127
127
  /**
@@ -156,7 +156,9 @@ export class SkillManager extends McpServerManager implements ISkillManager {
156
156
  this.enableTool(serverName, toolName);
157
157
  }
158
158
  };
159
- Object.entries(mcpConfig).map((e) => enableTools(e));
159
+ Object.entries(mcpConfig).map((e) => {
160
+ enableTools(e);
161
+ });
160
162
  }
161
163
 
162
164
  /**
@@ -167,10 +169,10 @@ export class SkillManager extends McpServerManager implements ISkillManager {
167
169
  const [mcpServers, mcpServersMap] = buildServersList(servers);
168
170
  this.serverBriefs = mcpServers;
169
171
  this.serverBriefsMap = mcpServersMap;
170
- this.toolCache = {};
172
+ this.toolCache = new Map();
171
173
  }
172
174
 
173
- public hasServer(serverName: string): boolean {
175
+ public hasServerBrief(serverName: string): boolean {
174
176
  return !!this.serverBriefsMap[serverName];
175
177
  }
176
178
 
@@ -184,7 +186,7 @@ export class SkillManager extends McpServerManager implements ISkillManager {
184
186
  */
185
187
  public async getServerTools(serverName: string): Promise<Tool[]> {
186
188
  // Check cache
187
- let tools = this.toolCache[serverName];
189
+ let tools = this.toolCache.get(serverName);
188
190
  if (tools) {
189
191
  return tools;
190
192
  }
@@ -192,7 +194,7 @@ export class SkillManager extends McpServerManager implements ISkillManager {
192
194
  // Query backend (using the original name)
193
195
  const originalName = this.serverBriefsMap[serverName].originalName;
194
196
  tools = await this.apiClient.listTools(originalName);
195
- this.toolCache[serverName] = tools;
197
+ this.toolCache.set(serverName, tools);
196
198
  return tools;
197
199
  }
198
200
 
@@ -252,7 +254,7 @@ async function connectServer(
252
254
  ): Promise<void> {
253
255
  const transport = apiClient.mcpSession(mcpServer);
254
256
 
255
- await client.connect(transport).catch(async (e) => {
257
+ await client.connect(transport).catch(async (e: unknown) => {
256
258
  if (e instanceof AuthenticationRequired && !noRetry) {
257
259
  logger.info("authentication required: " + e.msg);
258
260
 
@@ -263,9 +265,9 @@ async function connectServer(
263
265
  logger.info(`authenticate at url: ${url}`);
264
266
  openUrl(url, authenticatedP, mcpServer.title);
265
267
  const authResult = await authenticatedP;
266
- logger.info(`authResult: ${authResult}`);
268
+ logger.info(`authResult: ${String(authResult)}`);
267
269
  if (!authResult) {
268
- throw "authentication failed";
270
+ throw new Error("authentication failed");
269
271
  }
270
272
  return connectServer(
271
273
  client,
@@ -13,10 +13,10 @@ export class TokenAuth implements OAuthClientProvider {
13
13
  }
14
14
 
15
15
  get redirectUrl(): string {
16
- throw "unimpl";
16
+ throw new Error("unimpl: redirectUrl");
17
17
  }
18
18
  get clientMetadata(): OAuthClientMetadata {
19
- throw "unimpl";
19
+ throw new Error("unimpl: clientMetadata");
20
20
  }
21
21
 
22
22
  clientInformation(): undefined {
@@ -26,7 +26,7 @@ export class TokenAuth implements OAuthClientProvider {
26
26
  saveClientInformation?(
27
27
  _clientInformation: OAuthClientInformationFull
28
28
  ): void | Promise<void> {
29
- throw "unimpl";
29
+ throw new Error("unimpl: saveClientInformation");
30
30
  }
31
31
 
32
32
  tokens(): OAuthTokens | undefined | Promise<OAuthTokens | undefined> {
@@ -36,15 +36,15 @@ export class TokenAuth implements OAuthClientProvider {
36
36
  };
37
37
  }
38
38
  saveTokens(_tokens: OAuthTokens): void | Promise<void> {
39
- throw "unimpl";
39
+ throw new Error("unimpl: saveTokens");
40
40
  }
41
41
  redirectToAuthorization(_authorizationUrl: URL): void | Promise<void> {
42
- throw "unimpl";
42
+ throw new Error("unimpl: redirectToAuthorization");
43
43
  }
44
44
  saveCodeVerifier(_codeVerifier: string): void | Promise<void> {
45
- throw "unimpl";
45
+ throw new Error("unimpl: saveCodeVerifier");
46
46
  }
47
47
  codeVerifier(): string | Promise<string> {
48
- throw "unimpl";
48
+ throw new Error("unimpl: codeVerifier");
49
49
  }
50
50
  }
@@ -45,7 +45,9 @@ export const toolCallbacks: {
45
45
  if (!isTemperatureArgs(args) || !args.location) {
46
46
  return `Location required`;
47
47
  }
48
- return `The temperature in ${args.location} is 22 degrees ${args.unit}`;
48
+ return `The temperature in ${args.location} is 22 degrees ${
49
+ args.unit ?? "celsius"
50
+ }`;
49
51
  },
50
52
  };
51
53