@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
@@ -4,7 +4,7 @@ exports.pidFile = exports.supabaseKey = exports.supabaseUrl = exports.apiKey = e
4
4
  exports.secretOption = secretOption;
5
5
  const cmd_ts_1 = require("cmd-ts");
6
6
  const agentUtils_1 = require("../agent/agentUtils");
7
- const db_1 = require("../chat/db");
7
+ const database_1 = require("../chat/data/database");
8
8
  /// Prevents env content from being displayed in the help text.
9
9
  function secretOption({ long, short, env, description, }) {
10
10
  if (env) {
@@ -21,7 +21,7 @@ function secretOption({ long, short, env, description, }) {
21
21
  type: (0, cmd_ts_1.optional)(cmd_ts_1.string),
22
22
  long,
23
23
  short,
24
- description: `${description} (can also be set via ${env} env var)`,
24
+ description: `${description} (can also be set via ${env ?? "undefined"} env var)`,
25
25
  });
26
26
  }
27
27
  exports.promptFile = (0, cmd_ts_1.option)({
@@ -97,14 +97,14 @@ exports.supabaseUrl = (0, cmd_ts_1.option)({
97
97
  long: "supabase-url",
98
98
  description: "Supabase URL",
99
99
  env: "SUPABASE_URL",
100
- defaultValue: () => db_1.SUPABASE_LOCAL_URL,
100
+ defaultValue: () => database_1.SUPABASE_LOCAL_URL,
101
101
  });
102
102
  exports.supabaseKey = (0, cmd_ts_1.option)({
103
103
  type: cmd_ts_1.string,
104
104
  long: "supabase-key",
105
105
  description: "Supabase Key",
106
106
  env: "SUPABASE_KEY",
107
- defaultValue: () => db_1.SUPABASE_LOCAL_KEY,
107
+ defaultValue: () => database_1.SUPABASE_LOCAL_KEY,
108
108
  });
109
109
  exports.pidFile = (0, cmd_ts_1.option)({
110
110
  type: (0, cmd_ts_1.optional)(cmd_ts_1.string),
@@ -16,19 +16,22 @@ class Prompt {
16
16
  prompt: DEFAULT_PROMPT,
17
17
  });
18
18
  this.prompt.on("line", (line) => {
19
- this.line = line;
20
- this.resolve();
19
+ this.resolve(line);
21
20
  });
22
21
  this.prompt.on("close", () => {
23
- this.line = undefined;
24
- this.resolve();
22
+ this.resolve("");
25
23
  });
26
24
  }
27
25
  async run(prompt) {
28
- // Clear any line
29
- this.line = "";
26
+ const savedOnline = this.online;
30
27
  return new Promise((r) => {
31
- this.online = r;
28
+ // The "resolve" callback puts back any previous `online` callback.
29
+ // This allows nested prompts (e.g. toolcall approval in the middle of a
30
+ // message prompt).
31
+ this.online = (line) => {
32
+ r(line);
33
+ this.online = savedOnline;
34
+ };
32
35
  if (prompt) {
33
36
  this.prompt.setPrompt(prompt);
34
37
  }
@@ -40,12 +43,12 @@ class Prompt {
40
43
  }
41
44
  async shutdown() {
42
45
  this.prompt.close();
46
+ return Promise.resolve();
43
47
  }
44
- resolve() {
48
+ resolve(line) {
45
49
  if (this.online) {
46
- this.online(this.line);
50
+ this.online(line);
47
51
  }
48
- this.online = undefined;
49
52
  }
50
53
  }
51
54
  exports.Prompt = Prompt;
@@ -59,14 +62,17 @@ class ScriptPrompt {
59
62
  run(_prompt) {
60
63
  return new Promise((r) => {
61
64
  setTimeout(() => {
62
- logger.debug(`[ScriptPrompt.run]: ${this.lines.length} remaining`);
65
+ logger.debug(`[ScriptPrompt.run]: ${String(this.lines.length)} remaining`);
63
66
  if (this.lines.length === 0) {
64
67
  logger.debug("[ScriptPrompt.run]: returning undefined");
65
- r(undefined);
68
+ setTimeout(() => {
69
+ r(undefined);
70
+ }, 1000);
66
71
  }
67
72
  else {
68
73
  const line = this.lines.shift();
69
- logger.debug(`[ScriptPrompt.run]: returning: ${line}`);
74
+ logger.debug(`[ScriptPrompt.run]: returning: ${line ?? "undefined"}`);
75
+ console.log(`[USER(script)] ${JSON.stringify(line)}`);
70
76
  r(line);
71
77
  }
72
78
  }, 1000);
package/eslint.config.mjs CHANGED
@@ -3,7 +3,16 @@ import tseslint from "typescript-eslint";
3
3
 
4
4
  export default tseslint.config(
5
5
  eslint.configs.recommended,
6
- tseslint.configs.recommended,
6
+ ...tseslint.configs.strict,
7
+ ...tseslint.configs.strictTypeChecked,
8
+ {
9
+ languageOptions: {
10
+ parserOptions: {
11
+ project: "./tsconfig.json",
12
+ tsconfigRootDir: import.meta.dirname,
13
+ },
14
+ },
15
+ },
7
16
  {
8
17
  rules: {
9
18
  "@typescript-eslint/no-unused-vars": [
@@ -22,4 +31,8 @@ export default tseslint.config(
22
31
  "linebreak-style": ["error", "unix"],
23
32
  },
24
33
  },
34
+ {
35
+ files: ["**/*.mjs", "**/*.js"],
36
+ ...tseslint.configs.disableTypeChecked,
37
+ },
25
38
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xalia/agent",
3
- "version": "0.5.8",
3
+ "version": "0.6.1",
4
4
  "keywords": [],
5
5
  "author": "",
6
6
  "license": "ISC",
@@ -13,24 +13,32 @@
13
13
  },
14
14
  "scripts": {
15
15
  "build": "tsc && node -e \"require('fs').chmodSync('dist/agent/src/tool/main.js', '755')\"",
16
- "lint": "eslint src && yarn prettier --check src/**/*.ts",
16
+ "lint": "eslint src --max-warnings 0 && yarn prettier --check src/**/*.ts",
17
17
  "format": "yarn prettier --write src/**/*.ts",
18
- "test": "yarn --emoji false build && mocha dist/agent/src/test/**.js --reporter-option maxDiffSize=0"
18
+ "test": "yarn build && vitest run"
19
19
  },
20
20
  "dependencies": {
21
21
  "@modelcontextprotocol/sdk": "=1.11.1",
22
22
  "@supabase/supabase-js": "2.49.7",
23
23
  "@types/readline-sync": "^1.4.8",
24
24
  "chalk": "^4.1.2",
25
+ "cheerio": "^1.1.2",
25
26
  "cmd-ts": "^0.13.0",
26
27
  "dotenv": "^16.5.0",
28
+ "exa-js": "^1.9.2",
29
+ "expr-eval": "^2.0.2",
30
+ "google-search-ts": "^1.0.1",
31
+ "html-to-text": "^9.0.5",
32
+ "node-fetch": "^3.3.2",
27
33
  "openai": "=4.98.0",
28
34
  "readline-sync": "^1.4.10",
29
35
  "uuid": "^11.1.0",
30
- "yocto-spinner": "^0.2.2",
31
- "ws": "8.18.2"
36
+ "ws": "8.18.2",
37
+ "yocto-spinner": "^0.2.2"
32
38
  },
33
39
  "devDependencies": {
34
- "@types/ws": "^8.18.0"
40
+ "@types/html-to-text": "^9.0.4",
41
+ "@types/ws": "^8.18.0",
42
+ "vitest": "^3.1.1"
35
43
  }
36
44
  }
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Script to run the chat server so deployment logic does not have to know the
4
+ # location of the entrypoint (which can change easily).
5
+
6
+ this_dir=`dirname ${BASH_SOURCE[0]}`
7
+ agent_dir=`realpath ${this_dir}/..`
8
+ ${agent_dir}/dist/agent/src/tool/main.js chat server $@
@@ -67,6 +67,9 @@ pushd _test_chat
67
67
  apikey1=`${client} admin create-api-key chatuser1 default [] | jq -r .api_key`
68
68
  fi
69
69
 
70
+ ${client} admin set-default-api-key chatuser0 default
71
+ ${client} admin set-default-api-key chatuser1 default
72
+
70
73
  echo "${apikey0}" > chatuser0.apikey
71
74
  echo "${apikey1}" > chatuser1.apikey
72
75
 
@@ -75,11 +78,13 @@ pushd _test_chat
75
78
 
76
79
  echo '{"system_prompt":"You are a helpful agent talking to multiple users. Users put their name at the beginning of their messages, e.g. `chatuser1: <message>`.","mcp_settings":{"duckduckgo-search":[]}}' > profile0.json
77
80
  ${client} config --force --dev --api-key ${apikey0}
78
- ${client} agent-profile set profile0 --profile profile0.json
81
+ ${client} agent-profile set profile0 --profile profile0.json | jq -r .uuid > profile0.uuid
79
82
 
80
83
  popd
81
84
 
85
+ set +e
86
+ set +x
82
87
 
83
88
  echo "================================"
84
- echo "== CHAT SETUP COMPLETED =="
89
+ echo "== CHAT SETUP COMPLETED =="
85
90
  echo "================================"
@@ -34,6 +34,9 @@ stop_chat_server
34
34
  # Stop MCP server
35
35
  stop_mcppro_server
36
36
 
37
+ set +e
38
+ set +x
39
+
37
40
  echo "=========================="
38
41
  echo "== SHUTDOWN COMPLETE =="
39
42
  echo "=========================="
package/scripts/test_chat CHANGED
@@ -44,7 +44,14 @@ function stop_chat_server() {
44
44
 
45
45
  stop_chat_server
46
46
 
47
- LOG_LEVEL=debug ${agent} chat server --pid-file chat.pid > chat_server.log 2>&1 &
47
+ # Start the server with full logging and short heartbeat timeout.
48
+ export DEFAULT_LLM_MODEL=repeat
49
+ export DEVELOPMENT=1
50
+
51
+ LOG_LEVEL=debug \
52
+ COMPRESSION_TRIGGER_NUM_MESSAGES=3 \
53
+ HEARTBEAT_INTERVAL_MS=1000 \
54
+ scripts/chat_server --pid-file chat.pid > chat_server.log 2>&1 &
48
55
  sleep 1
49
56
 
50
57
  mkdir -p _test_chat
@@ -68,41 +75,152 @@ pushd _test_chat
68
75
  apikey1=`${client} admin create-api-key chatuser1 default [] | jq -r .api_key`
69
76
  fi
70
77
 
78
+ ${client} admin set-default-api-key chatuser0 default
79
+ ${client} admin set-default-api-key chatuser1 default
80
+
71
81
  echo "${apikey0}" > chatuser0.apikey
72
82
  echo "${apikey1}" > chatuser1.apikey
73
83
 
74
- # User 0 creates an agent profile
75
-
76
- echo '{"system_prompt":"You are a helpful agent in a multi-user chat session. If you have nothing to contribute and are not being addressed, just say `No comment`.","model":"repeat","mcp_settings":{"duckduckgo-search":[]}}' > profile0.json
77
84
  ${client} config --force --dev --api-key ${apikey0}
78
- ${client} agent-profile set profile0 --profile profile0.json
79
85
 
80
- # User 0 creates a session and asks for a joke
86
+ # Create an agent to test crash scenarios using script:
87
+ # test_data/dummyllm_script_crash.json (relative to server cwd)
88
+
89
+ echo '{"system_prompt":"blah","model":"dummy:test_data/dummyllm_script_crash.json","mcp_settings":{}}' > crash_agent_profile.json
90
+ ${client} agent-profile set crash_agent_profile \
91
+ --profile crash_agent_profile.json \
92
+ | jq -r .uuid > crash_agent_profile.uuid
93
+ crash_agent_profile_id=`cat crash_agent_profile.uuid`
94
+
95
+ # Create an agent for the single-user tests
96
+
97
+ echo '{"system_prompt":"You are a helpful agent in a multi-user chat session. If you have nothing to contribute and are not being addressed, just say `No comment`.","model":"'${DEFAULT_LLM_MODEL}'","mcp_settings":{}}' > agent_profile.json
98
+ ${client} agent-profile set profile0 --profile agent_profile.json | jq -r .uuid > agent_profile.uuid
99
+ agent_profile_id=`cat agent_profile.uuid`
100
+
101
+ # User 0 tries to join with invalid API key - fails with "invalid api key" error
102
+
103
+ invalid_apikey0="invalid_api_key"
104
+ ${agent} chat client --session-id no_such_session --api-key "${invalid_apikey0}" 2>&1 | tee invalid_apikey_test.log | grep -i "invalid api key" || \
105
+ (echo "Expected 'invalid api key' error message"; cat invalid_apikey_test.log; exit 1)
106
+
107
+ # User 0 tries to join non-existant session - fails
108
+
109
+ ${agent} chat clear-sessions
110
+ ${agent} chat client --session-id no_such_session && \
111
+ (echo "Should not be able to join"; exit 1)
112
+
113
+ # User 0 creates a new session with `crash_agent_profile` and interacts with
114
+ # it, exercising LLM error conditions.
115
+
116
+ echo ':si crash_session.id' > crash_script
117
+ echo 'Hello' >> crash_script
118
+ echo 'Hello again' >> crash_script
119
+ ${agent} chat client --session-title crash_test_session \
120
+ --agent-profile-id ${crash_agent_profile_id} \
121
+ --script crash_script
122
+
123
+ # User 0 creates empty session, which should not appear in the DB.
124
+
125
+ echo ':si empty_session.id' > empty_session
126
+ ${agent} chat client --session-title test_session \
127
+ --agent-profile-id ${agent_profile_id} \
128
+ --script empty_session
129
+ empty_session_id=`cat empty_session.id`
130
+ ${agent} chat list-sessions | grep `cat empty_session.id` && \
131
+ (echo "Empty session should not be persisted"; exit 1)
132
+
133
+ # User 0 creates a user session, sends message and writes session id to file
134
+
135
+ echo 'tell me a joke' > init_session
136
+ echo ':si session.id' >> init_session
137
+ ${agent} chat client --session-title test_session \
138
+ --agent-profile-id ${agent_profile_id} \
139
+ --script init_session
140
+ session_id=`cat session.id`
141
+
142
+ # Check that the session got saved with the updated title
143
+
144
+ ${agent} chat list-sessions | grep '"title":"tell me a joke"'
145
+
146
+ # User 1 tries to join the session. Should be rejected.
81
147
 
82
- echo 'tell me a joke' > script0
83
- ${agent} chat client --session test_session --agent-profile profile0 --script script0
148
+ ${agent} chat client --session-id ${session_id} --api-key ${apikey1} \
149
+ --script init_session > join_unauthorized.log 2>&1 && \
150
+ (echo "Should exit with error when joining invalid session"; exit 1)
84
151
 
152
+ grep -i "not authorized" join_unauthorized.log || \
153
+ (echo "Should include error message"; exit 1)
154
+
155
+ # User 0 create a team, and write team id to a file
156
+
157
+ echo ':ct team0' > script_create_team
158
+ echo ':ci team0.id' >> script_create_team
159
+ ${agent} chat client --session-id ${session_id} --script script_create_team
160
+ team_id=`cat team0.id`
161
+
162
+ # User 0 create a new team session (including a new agent), and write
163
+ # session id to a file.
164
+
165
+ echo 'tell me a joke' > script_team_chat
166
+ echo ':si team_session.id' >> script_team_chat
167
+ ${agent} chat client --session-title test_team_session \
168
+ --team-id ${team_id} \
169
+ --script script_team_chat
170
+ team_session_id=`cat team_session.id`
171
+
172
+ # Extract the agent uuid form the new session
173
+
174
+ get_profile_id_query='.[] | select(.uuid=="'${team_session_id}'") | .agent_profile_uuid'
175
+ ${agent} chat list-sessions | jq -r "${get_profile_id_query}" > team_agent.id
176
+ team_agent_id=`cat team_agent.id`
177
+
178
+ # User 1 tries to join the team session. Should be rejected.
179
+
180
+ ${agent} chat client --session-id ${team_session_id} --api-key ${apikey1} \
181
+ --script init_session > join_unauthorized_team.log 2>&1 && \
182
+ (echo "Should exit with error when joining invalid team session"; exit 1)
183
+ grep -i "not authorized" join_unauthorized_team.log || \
184
+ (echo "Should include error message (no auth team session)"; exit 1)
185
+
186
+ # User 0 adds user 1 as a participant in team and checks the DB
187
+
188
+ echo ":ap ${team_id} chatuser1" > script_add_chatuser1
189
+ echo ':lp' >> script_add_chatuser1
190
+ ${agent} chat client --session-id ${team_session_id} --script script_add_chatuser1
191
+ ${agent} chat list-participants --session ${team_session_id} | grep chatuser1
192
+
193
+ # Have a participant add duckduckgo-search
85
194
  # Check that the duckduckgo-search server is available
86
195
  # Have a participant remove it and check that got reflected in the db
87
- # Have a participant re-add it and check that got reflected in the db
88
196
 
89
- ${client} agent-profile get profile0 | grep duckduckgo
197
+ echo ":as duckduckgo-search" > script_add_duckduckgo
198
+ ${agent} chat client --session-id ${team_session_id} --script script_add_duckduckgo
199
+ ${client} agent-profile get ${team_agent_id} | grep duckduckgo
200
+ sleep 1
201
+
90
202
  echo ":rs duckduckgo-search" > script_rm_duckduckgo
91
- ${agent} chat client --session chatuser0/test_session --script script_rm_duckduckgo
203
+ ${agent} chat client --session-id ${team_session_id} --script script_rm_duckduckgo
92
204
  sleep 1
93
- (${client} agent-profile get profile0 | grep duckduckgo) && ( \
205
+ (${client} agent-profile get ${team_session_id} | grep duckduckgo) && ( \
94
206
  echo "ERROR: expected duckduckgo to be removed from agent profile" ; \
95
207
  exit 1 \
96
208
  )
97
- echo ":as duckduckgo-search" > script_add_duckduckgo
98
- ${agent} chat client --session chatuser0/test_session --script script_add_duckduckgo
99
- ${client} agent-profile get profile0 | grep duckduckgo
209
+
210
+ # Set an image to the workspace and asks a question
211
+
212
+ echo ':sw file:../test_data/frog.png For context, this image represents our shared workspace' > script_set_workspace
213
+ echo 'Tell me about the image in our workspace?' >> script_set_workspace
214
+ echo ':sw' >> script_set_workspace
215
+ ${agent} chat client --session-id ${session_id} --script script_set_workspace
100
216
 
101
217
  # Run both clients with a script that continues the conversation
102
218
 
103
219
  echo -e "why is that funny?\ntell me another.\nwhat is my name?\nhow old are you?\nwhere are your parents?" > script1
104
- ${agent} chat client --session chatuser0/test_session --api-key ${apikey1} --script script1 >chatuser1.output &
105
- ${agent} chat client --session chatuser0/test_session --script script1
220
+ ${agent} chat client --session-id ${team_session_id} --script script1 &
221
+ pid0=$!
222
+ ${agent} chat client --session-id ${team_session_id} --api-key ${apikey1} --script script1 >chatuser1.output
223
+ wait ${pid0}
106
224
 
107
225
  # The name chatuser0 should appear in chatuser1's session output
108
226