@xalia/agent 0.5.0 → 0.5.2
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.
- package/README.md +46 -7
- package/dist/{agent.js → agent/src/agent/agent.js} +5 -4
- package/dist/{agentUtils.js → agent/src/agent/agentUtils.js} +10 -9
- package/dist/{mcpServerManager.js → agent/src/agent/mcpServerManager.js} +2 -1
- package/dist/{sudoMcpServerManager.js → agent/src/agent/sudoMcpServerManager.js} +4 -4
- package/dist/agent/src/chat/apiKeyManager.js +23 -0
- package/dist/agent/src/chat/asyncQueue.js +41 -0
- package/dist/agent/src/chat/client.js +126 -0
- package/dist/agent/src/chat/conversationManager.js +173 -0
- package/dist/agent/src/chat/db.js +186 -0
- package/dist/agent/src/chat/messages.js +2 -0
- package/dist/agent/src/chat/server.js +158 -0
- package/dist/agent/src/index.js +2 -0
- package/dist/agent/src/test/db.test.js +73 -0
- package/dist/{test → agent/src/test}/imageLoad.test.js +1 -1
- package/dist/{test → agent/src/test}/mcpServerManager.test.js +1 -1
- package/dist/{test → agent/src/test}/prompt.test.js +1 -1
- package/dist/{test → agent/src/test}/sudoMcpServerManager.test.js +3 -3
- package/dist/{chat.js → agent/src/tool/agentChat.js} +5 -5
- package/dist/{main.js → agent/src/tool/agentMain.js} +9 -15
- package/dist/agent/src/tool/chatMain.js +207 -0
- package/dist/agent/src/tool/main.js +54 -0
- package/dist/{options.js → agent/src/tool/options.js} +36 -2
- package/dist/agent/src/utils/asyncLock.js +45 -0
- package/dist/supabase/database.types.js +8 -0
- package/eslint.config.mjs +14 -14
- package/package.json +9 -15
- package/scripts/test_chat +84 -0
- package/src/{agent.ts → agent/agent.ts} +22 -11
- package/src/{agentUtils.ts → agent/agentUtils.ts} +13 -14
- package/src/{mcpServerManager.ts → agent/mcpServerManager.ts} +2 -1
- package/src/{sudoMcpServerManager.ts → agent/sudoMcpServerManager.ts} +3 -3
- package/src/chat/apiKeyManager.ts +24 -0
- package/src/chat/asyncQueue.ts +51 -0
- package/src/chat/client.ts +142 -0
- package/src/chat/conversationManager.ts +283 -0
- package/src/chat/db.ts +264 -0
- package/src/chat/messages.ts +91 -0
- package/src/chat/server.ts +177 -0
- package/src/test/db.test.ts +103 -0
- package/src/test/imageLoad.test.ts +1 -1
- package/src/test/mcpServerManager.test.ts +1 -1
- package/src/test/prompt.test.ts +1 -1
- package/src/test/sudoMcpServerManager.test.ts +6 -10
- package/src/{chat.ts → tool/agentChat.ts} +26 -24
- package/src/{main.ts → tool/agentMain.ts} +12 -19
- package/src/tool/chatMain.ts +250 -0
- package/src/{files.ts → tool/files.ts} +1 -1
- package/src/tool/main.ts +25 -0
- package/src/{nodePlatform.ts → tool/nodePlatform.ts} +1 -1
- package/src/{options.ts → tool/options.ts} +40 -1
- package/src/utils/asyncLock.ts +43 -0
- package/test_data/simplecalc_profile.json +1 -1
- package/test_data/sudomcp_import_profile.json +1 -1
- package/test_data/test_script_profile.json +1 -1
- package/tsconfig.json +1 -1
- package/scripts/test_script +0 -60
- /package/dist/{dummyLLM.js → agent/src/agent/dummyLLM.js} +0 -0
- /package/dist/{iplatform.js → agent/src/agent/iplatform.js} +0 -0
- /package/dist/{llm.js → agent/src/agent/llm.js} +0 -0
- /package/dist/{openAILLM.js → agent/src/agent/openAILLM.js} +0 -0
- /package/dist/{openAILLMStreaming.js → agent/src/agent/openAILLMStreaming.js} +0 -0
- /package/dist/{tokenAuth.js → agent/src/agent/tokenAuth.js} +0 -0
- /package/dist/{tools.js → agent/src/agent/tools.js} +0 -0
- /package/dist/{files.js → agent/src/tool/files.js} +0 -0
- /package/dist/{nodePlatform.js → agent/src/tool/nodePlatform.js} +0 -0
- /package/dist/{prompt.js → agent/src/tool/prompt.js} +0 -0
- /package/src/{dummyLLM.ts → agent/dummyLLM.ts} +0 -0
- /package/src/{iplatform.ts → agent/iplatform.ts} +0 -0
- /package/src/{llm.ts → agent/llm.ts} +0 -0
- /package/src/{openAILLM.ts → agent/openAILLM.ts} +0 -0
- /package/src/{openAILLMStreaming.ts → agent/openAILLMStreaming.ts} +0 -0
- /package/src/{tokenAuth.ts → agent/tokenAuth.ts} +0 -0
- /package/src/{tools.ts → agent/tools.ts} +0 -0
- /package/src/{test/prompt.test.src → index.ts} +0 -0
- /package/src/{prompt.ts → tool/prompt.ts} +0 -0
@@ -0,0 +1,186 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.Database = exports.SUPABASE_LOCAL_KEY = exports.SUPABASE_LOCAL_URL = void 0;
|
4
|
+
exports.resolveCompoundName = resolveCompoundName;
|
5
|
+
const supabase_js_1 = require("@supabase/supabase-js");
|
6
|
+
const sdk_1 = require("@xalia/xmcp/sdk");
|
7
|
+
const logger = (0, sdk_1.getLogger)();
|
8
|
+
exports.SUPABASE_LOCAL_URL = "http://127.0.0.1:54321";
|
9
|
+
exports.SUPABASE_LOCAL_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiw" +
|
10
|
+
"icm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJz" +
|
11
|
+
"dJsyH-qQwv8Hdp7fsn3W0YpN81IU";
|
12
|
+
/**
|
13
|
+
* 'name' -> 'name'
|
14
|
+
* 'space/name' -> ['space', 'name']
|
15
|
+
*/
|
16
|
+
function resolveCompoundName(name) {
|
17
|
+
const components = name.split("/");
|
18
|
+
if (components.length === 1) {
|
19
|
+
return name;
|
20
|
+
}
|
21
|
+
if (components.length !== 2) {
|
22
|
+
throw "invalid compound name";
|
23
|
+
}
|
24
|
+
return components;
|
25
|
+
}
|
26
|
+
class Database {
|
27
|
+
constructor(supabaseUrl, supabaseKey) {
|
28
|
+
this.client = (0, supabase_js_1.createClient)(supabaseUrl, supabaseKey);
|
29
|
+
}
|
30
|
+
async getUserDataFromApiKey(apiKey) {
|
31
|
+
const { data, error } = await this.client
|
32
|
+
.from("api_keys")
|
33
|
+
.select("user_uuid, users ( nickname )")
|
34
|
+
.eq("api_key", apiKey)
|
35
|
+
.maybeSingle();
|
36
|
+
logger.debug(`[getUserDataFromApiKey]: got ${JSON.stringify({ data, error })}`);
|
37
|
+
if (error) {
|
38
|
+
throw error;
|
39
|
+
}
|
40
|
+
if (data === null) {
|
41
|
+
return undefined;
|
42
|
+
}
|
43
|
+
return {
|
44
|
+
user_uuid: data.user_uuid,
|
45
|
+
nickname: data.users.nickname || `user ${data.user_uuid}`,
|
46
|
+
};
|
47
|
+
}
|
48
|
+
async createUser(user_uuid, email, nickname, timezone) {
|
49
|
+
const payload = {
|
50
|
+
uuid: user_uuid,
|
51
|
+
email,
|
52
|
+
nickname,
|
53
|
+
timezone: timezone || "UTC",
|
54
|
+
};
|
55
|
+
const { error } = await this.client.from("users").insert(payload);
|
56
|
+
if (error) {
|
57
|
+
throw error;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
async addApiKey(user_uuid, api_key, name, scopes, is_default = false) {
|
61
|
+
const payload = {
|
62
|
+
user_uuid,
|
63
|
+
api_key,
|
64
|
+
name,
|
65
|
+
scopes,
|
66
|
+
is_default,
|
67
|
+
};
|
68
|
+
const { data, error } = await this.client
|
69
|
+
.from("api_keys")
|
70
|
+
.insert(payload)
|
71
|
+
.select("*")
|
72
|
+
.maybeSingle();
|
73
|
+
if (error) {
|
74
|
+
throw error;
|
75
|
+
}
|
76
|
+
return data;
|
77
|
+
}
|
78
|
+
async getSavedAgentProfileById(agentProfileId) {
|
79
|
+
const { data, error } = await this.client
|
80
|
+
.from("agent_profiles")
|
81
|
+
.select("*")
|
82
|
+
.eq("uuid", agentProfileId)
|
83
|
+
.maybeSingle();
|
84
|
+
if (error) {
|
85
|
+
throw error;
|
86
|
+
}
|
87
|
+
return data
|
88
|
+
? sdk_1.SavedAgentProfile.fromJSONObj(data)
|
89
|
+
: undefined;
|
90
|
+
}
|
91
|
+
async getSavedAgentProfileByName(user_uuid, agentProfileName) {
|
92
|
+
const { data, error } = await this.client
|
93
|
+
.from("agent_profiles")
|
94
|
+
.select("*")
|
95
|
+
.eq("user_uuid", user_uuid)
|
96
|
+
.eq("profile_name", agentProfileName)
|
97
|
+
.maybeSingle();
|
98
|
+
if (error) {
|
99
|
+
throw error;
|
100
|
+
}
|
101
|
+
return data
|
102
|
+
? sdk_1.SavedAgentProfile.fromJSONObj(data)
|
103
|
+
: undefined;
|
104
|
+
}
|
105
|
+
async getAgentProfileById(agentProfileId) {
|
106
|
+
const { data, error } = await this.client
|
107
|
+
.from("agent_profiles")
|
108
|
+
.select("profile")
|
109
|
+
.eq("uuid", agentProfileId)
|
110
|
+
.maybeSingle();
|
111
|
+
if (error) {
|
112
|
+
throw error;
|
113
|
+
}
|
114
|
+
return data
|
115
|
+
? sdk_1.AgentProfile.fromJSONObj(data.profile)
|
116
|
+
: undefined;
|
117
|
+
}
|
118
|
+
async createAgentProfile(user_uuid, profileName, profile) {
|
119
|
+
const payload = {
|
120
|
+
profile: profile,
|
121
|
+
user_uuid,
|
122
|
+
profile_name: profileName,
|
123
|
+
};
|
124
|
+
const { data, error } = await this.client
|
125
|
+
.from("agent_profiles")
|
126
|
+
.upsert(payload)
|
127
|
+
.select("uuid");
|
128
|
+
if (error) {
|
129
|
+
throw error;
|
130
|
+
}
|
131
|
+
if (!data || !data[0] || !data[0].uuid) {
|
132
|
+
return undefined;
|
133
|
+
}
|
134
|
+
return data[0].uuid;
|
135
|
+
}
|
136
|
+
async clearAgentProfiles() {
|
137
|
+
await this.client.from("agent_profiles").delete().neq("uuid", "");
|
138
|
+
}
|
139
|
+
// TODO: is there a session model?
|
140
|
+
async getSessionById(session_uuid) {
|
141
|
+
const { data, error } = await this.client
|
142
|
+
.from("sessions")
|
143
|
+
.select("*")
|
144
|
+
.eq("uuid", session_uuid)
|
145
|
+
.maybeSingle();
|
146
|
+
if (error) {
|
147
|
+
throw error;
|
148
|
+
}
|
149
|
+
return data;
|
150
|
+
}
|
151
|
+
async getSessionByName(user_uuid, session_name) {
|
152
|
+
const { data, error } = await this.client
|
153
|
+
.from("sessions")
|
154
|
+
.select("*")
|
155
|
+
.eq("user_uuid", user_uuid)
|
156
|
+
.eq("title", session_name)
|
157
|
+
.maybeSingle();
|
158
|
+
if (error) {
|
159
|
+
throw error;
|
160
|
+
}
|
161
|
+
return data;
|
162
|
+
}
|
163
|
+
async createSession(user_uuid, title, agentProfileId) {
|
164
|
+
const payload = {
|
165
|
+
agent_profile_uuid: agentProfileId,
|
166
|
+
user_uuid,
|
167
|
+
title: title,
|
168
|
+
conversation: [],
|
169
|
+
};
|
170
|
+
const { data, error } = await this.client
|
171
|
+
.from("sessions")
|
172
|
+
.upsert(payload)
|
173
|
+
.select("uuid");
|
174
|
+
if (error) {
|
175
|
+
throw error;
|
176
|
+
}
|
177
|
+
if (!data || !data[0] || !data[0].uuid) {
|
178
|
+
return undefined;
|
179
|
+
}
|
180
|
+
return data[0].uuid;
|
181
|
+
}
|
182
|
+
async clearSessions() {
|
183
|
+
await this.client.from("sessions").delete().neq("uuid", "");
|
184
|
+
}
|
185
|
+
}
|
186
|
+
exports.Database = Database;
|
@@ -0,0 +1,158 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
"use strict";
|
3
|
+
// -*- typescript -*-
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
5
|
+
if (k2 === undefined) k2 = k;
|
6
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
7
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
8
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
9
|
+
}
|
10
|
+
Object.defineProperty(o, k2, desc);
|
11
|
+
}) : (function(o, m, k, k2) {
|
12
|
+
if (k2 === undefined) k2 = k;
|
13
|
+
o[k2] = m[k];
|
14
|
+
}));
|
15
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
16
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
17
|
+
}) : function(o, v) {
|
18
|
+
o["default"] = v;
|
19
|
+
});
|
20
|
+
var __importStar = (this && this.__importStar) || (function () {
|
21
|
+
var ownKeys = function(o) {
|
22
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
23
|
+
var ar = [];
|
24
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
25
|
+
return ar;
|
26
|
+
};
|
27
|
+
return ownKeys(o);
|
28
|
+
};
|
29
|
+
return function (mod) {
|
30
|
+
if (mod && mod.__esModule) return mod;
|
31
|
+
var result = {};
|
32
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
33
|
+
__setModuleDefault(result, mod);
|
34
|
+
return result;
|
35
|
+
};
|
36
|
+
})();
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
38
|
+
exports.runServer = runServer;
|
39
|
+
const dotenv = __importStar(require("dotenv"));
|
40
|
+
const sdk_1 = require("@xalia/xmcp/sdk");
|
41
|
+
const ws = __importStar(require("ws"));
|
42
|
+
const url_1 = require("url");
|
43
|
+
const conversationManager_1 = require("./conversationManager");
|
44
|
+
const db_1 = require("./db");
|
45
|
+
const apiKeyManager_1 = require("./apiKeyManager");
|
46
|
+
dotenv.config();
|
47
|
+
const logger = (0, sdk_1.getLogger)();
|
48
|
+
/**
|
49
|
+
* Try as id, then by user/name and return the AgentProfile uuid.
|
50
|
+
*/
|
51
|
+
async function resolveAgentProfileId(db, userData, agentProfileIdentifier) {
|
52
|
+
let ap = await db.getSavedAgentProfileById(agentProfileIdentifier);
|
53
|
+
logger.debug(`[resolveAgentProfileId]: by id: {JSON.stringify(ap)}`);
|
54
|
+
if (ap) {
|
55
|
+
return agentProfileIdentifier;
|
56
|
+
}
|
57
|
+
ap = await db.getSavedAgentProfileByName(userData.user_uuid, agentProfileIdentifier);
|
58
|
+
logger.debug(`[resolveAgentProfileId]: by name: {JSON.stringify(ap)}`);
|
59
|
+
if (ap) {
|
60
|
+
return ap.uuid;
|
61
|
+
}
|
62
|
+
logger.debug("[resolveAgentProfileId]: agent profile not found");
|
63
|
+
return undefined;
|
64
|
+
}
|
65
|
+
async function resolveSessionIdFromIdentifier(db, userData, sessionIdentifier) {
|
66
|
+
let session = undefined;
|
67
|
+
const compound = (0, db_1.resolveCompoundName)(sessionIdentifier);
|
68
|
+
if (typeof compound === "string") {
|
69
|
+
// Interpret as an id, or as a number under the current user.
|
70
|
+
session = await db.getSessionById(compound);
|
71
|
+
if (!session) {
|
72
|
+
session = await db.getSessionByName(userData.user_uuid, compound);
|
73
|
+
}
|
74
|
+
}
|
75
|
+
else {
|
76
|
+
session = await db.getSessionByName(compound[0], compound[1]);
|
77
|
+
}
|
78
|
+
return session?.uuid;
|
79
|
+
}
|
80
|
+
/**
|
81
|
+
* Expect parameters to be either:
|
82
|
+
* session_id - uuid, name, user/name
|
83
|
+
* agent_profile_id (optional) - uuid, name
|
84
|
+
*
|
85
|
+
* If session_idd resolves to an existing session, it is used (and
|
86
|
+
* agent_profile_id is ignored). Otherwise, session_id is used as the name of
|
87
|
+
* a new session to create using `agent_profile_id`. The session UUID is
|
88
|
+
* returned in either case.
|
89
|
+
*/
|
90
|
+
async function findOrCreateSession(db, userData, query) {
|
91
|
+
logger.debug(`[findOrCreateSession]: query: ${JSON.stringify(query)}`);
|
92
|
+
if (!query.session_id || typeof query.session_id !== "string") {
|
93
|
+
throw "session_id invalid or not present";
|
94
|
+
}
|
95
|
+
const sessionId = await resolveSessionIdFromIdentifier(db, userData, query.session_id);
|
96
|
+
if (sessionId) {
|
97
|
+
return sessionId;
|
98
|
+
}
|
99
|
+
const agentProfileIdParam = query.agent_profile_id;
|
100
|
+
logger.debug(`[findOrCreateSession]: agent: ${agentProfileIdParam}`);
|
101
|
+
if (!agentProfileIdParam) {
|
102
|
+
throw "no existing session, and no agent_profile_id given";
|
103
|
+
}
|
104
|
+
if (typeof agentProfileIdParam !== "string") {
|
105
|
+
throw "no existing session and invalid agent_profile_id";
|
106
|
+
}
|
107
|
+
logger.debug(`[findOrCreateSession]: creating session: ${query.session_id}`);
|
108
|
+
const agentProfileId = await resolveAgentProfileId(db, userData, agentProfileIdParam);
|
109
|
+
logger.debug(`[findOrCreateSession]: resolved agentProfileId: ${agentProfileId}`);
|
110
|
+
if (!agentProfileId) {
|
111
|
+
throw `no agent profile: ${agentProfileIdParam}`;
|
112
|
+
}
|
113
|
+
return db.createSession(userData.user_uuid, query.session_id, agentProfileId);
|
114
|
+
}
|
115
|
+
async function runServer(port, supabaseUrl, supabaseKey, llmUrl, xmcpUrl) {
|
116
|
+
return new Promise((r, _e) => {
|
117
|
+
const wss = new ws.Server({ port });
|
118
|
+
const db = new db_1.Database(supabaseUrl, supabaseKey);
|
119
|
+
const apiKeyManager = new apiKeyManager_1.ApiKeyManager(db);
|
120
|
+
const cm = new conversationManager_1.ConversationManager(db, llmUrl, xmcpUrl);
|
121
|
+
wss.on("connection", async (ws, req) => {
|
122
|
+
try {
|
123
|
+
logger.info(`[server] connection: ${req}`);
|
124
|
+
// Check header
|
125
|
+
logger.info(`[server] headers: ${JSON.stringify(req.headers)}`);
|
126
|
+
const apiKey = req.headers["sec-websocket-protocol"];
|
127
|
+
if (!apiKey) {
|
128
|
+
throw "empty api key";
|
129
|
+
}
|
130
|
+
const userData = await apiKeyManager.verifyApiKey(apiKey);
|
131
|
+
if (!userData) {
|
132
|
+
throw "invalid api key";
|
133
|
+
}
|
134
|
+
// Get sessionId
|
135
|
+
const { query } = (0, url_1.parse)(req.url || "", true);
|
136
|
+
const sessionId = await findOrCreateSession(db, userData, query);
|
137
|
+
logger.debug(`resolved session id: ${sessionId}`);
|
138
|
+
if (!sessionId) {
|
139
|
+
throw "failed to find/create session";
|
140
|
+
}
|
141
|
+
// Associate the ws, username with the conversation
|
142
|
+
await cm.join(sessionId, apiKey, apiKey, userData, ws);
|
143
|
+
}
|
144
|
+
catch (e) {
|
145
|
+
if (typeof e === "string") {
|
146
|
+
logger.warn(`[server]: error: ${e}`);
|
147
|
+
ws.close(4000, e);
|
148
|
+
}
|
149
|
+
else {
|
150
|
+
logger.error(`other error: ${JSON.stringify(e)}`);
|
151
|
+
throw e;
|
152
|
+
}
|
153
|
+
}
|
154
|
+
});
|
155
|
+
logger.info(`[server] started: ws://localhost:${port}/`);
|
156
|
+
r(wss);
|
157
|
+
});
|
158
|
+
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const chai_1 = require("chai");
|
4
|
+
const db_1 = require("../chat/db");
|
5
|
+
const assert_1 = require("assert");
|
6
|
+
const sdk_1 = require("@xalia/xmcp/sdk");
|
7
|
+
const sudoMcpServerManager_1 = require("../agent/sudoMcpServerManager");
|
8
|
+
function getLocalDB() {
|
9
|
+
return new db_1.Database(db_1.SUPABASE_LOCAL_URL, db_1.SUPABASE_LOCAL_KEY);
|
10
|
+
}
|
11
|
+
const AGENT_PROFILE = {
|
12
|
+
model: undefined,
|
13
|
+
system_prompt: "You are an unhelpful agent",
|
14
|
+
mcp_settings: {},
|
15
|
+
};
|
16
|
+
async function createDummyUser(db) {
|
17
|
+
const apiClient = new sdk_1.ApiClient(sudoMcpServerManager_1.LOCAL_SERVER_URL, "dummy_key");
|
18
|
+
const user = await apiClient.getUserBrief("dummy_user");
|
19
|
+
if (!user) {
|
20
|
+
await db.createUser("dummy_user", "a@b.com", "Dummy User");
|
21
|
+
await db.addApiKey("dummy_user", "dummy_key", "default", [], true);
|
22
|
+
if (!apiClient.getUserBrief("dummy_user")) {
|
23
|
+
throw "unable to create dummy user";
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
describe("DB", () => {
|
28
|
+
it("should get existing user", async function () {
|
29
|
+
const db = getLocalDB();
|
30
|
+
await createDummyUser(db);
|
31
|
+
const dummyUser = await db.getUserDataFromApiKey("dummy_key");
|
32
|
+
(0, chai_1.expect)(dummyUser).eql({
|
33
|
+
user_uuid: "dummy_user",
|
34
|
+
nickname: "Dummy User",
|
35
|
+
});
|
36
|
+
});
|
37
|
+
it("should return undefined for non-existant user", async function () {
|
38
|
+
const db = getLocalDB();
|
39
|
+
const dummyUser = await db.getUserDataFromApiKey("no_such_key");
|
40
|
+
(0, chai_1.expect)(dummyUser).to.equal(undefined);
|
41
|
+
});
|
42
|
+
it("should create and retrieve agent profiles", async function () {
|
43
|
+
const db = getLocalDB();
|
44
|
+
await db.clearAgentProfiles();
|
45
|
+
const agentProfileId = await db.createAgentProfile("dummy_user", "test_profile", AGENT_PROFILE);
|
46
|
+
(0, chai_1.expect)(agentProfileId).to.not.equal(undefined);
|
47
|
+
(0, assert_1.strict)(agentProfileId);
|
48
|
+
const savedAgentProfile = (await db.getSavedAgentProfileById(agentProfileId));
|
49
|
+
const savedAgentProfileByName = (await db.getSavedAgentProfileByName("dummy_user", "test_profile"));
|
50
|
+
const agentProfile = (await db.getAgentProfileById(agentProfileId));
|
51
|
+
(0, chai_1.expect)(savedAgentProfile.uuid).eql(agentProfileId);
|
52
|
+
(0, chai_1.expect)(savedAgentProfile.profile).eql(AGENT_PROFILE);
|
53
|
+
(0, chai_1.expect)(savedAgentProfile?.user_uuid).eql("dummy_user");
|
54
|
+
(0, chai_1.expect)(savedAgentProfile?.profile_name).eql("test_profile");
|
55
|
+
(0, chai_1.expect)(savedAgentProfileByName).eql(savedAgentProfile);
|
56
|
+
(0, chai_1.expect)(agentProfile).eql(AGENT_PROFILE);
|
57
|
+
});
|
58
|
+
it("should create and retrieve sessions", async function () {
|
59
|
+
const db = getLocalDB();
|
60
|
+
await db.clearAgentProfiles();
|
61
|
+
await db.clearSessions();
|
62
|
+
const agentProfileId = await db.createAgentProfile("dummy_user", "test_profile", AGENT_PROFILE);
|
63
|
+
(0, assert_1.strict)(agentProfileId);
|
64
|
+
const sessionId = await db.createSession("dummy_user", "test_session", agentProfileId);
|
65
|
+
(0, assert_1.strict)(sessionId);
|
66
|
+
const session = (await db.getSessionById(sessionId));
|
67
|
+
(0, chai_1.expect)(session.agent_profile_uuid).eql(agentProfileId);
|
68
|
+
(0, chai_1.expect)(session.conversation).eql([]);
|
69
|
+
(0, chai_1.expect)(session.title).eql("test_session");
|
70
|
+
(0, chai_1.expect)(session.user_uuid).eql("dummy_user");
|
71
|
+
(0, chai_1.expect)(session.uuid).eql(sessionId);
|
72
|
+
});
|
73
|
+
});
|
@@ -1,7 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
const chai_1 = require("chai");
|
4
|
-
const files_1 = require("../files");
|
4
|
+
const files_1 = require("../tool/files");
|
5
5
|
const assert_1 = require("assert");
|
6
6
|
describe("Image loading", () => {
|
7
7
|
it("convert to data url", async function () {
|
@@ -1,7 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
const chai_1 = require("chai");
|
4
|
-
const mcpServerManager_1 = require("../mcpServerManager");
|
4
|
+
const mcpServerManager_1 = require("../agent/mcpServerManager");
|
5
5
|
// Handle automatically closing at the end of tests.
|
6
6
|
let managers = {};
|
7
7
|
let idx = 0;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
const chai_1 = require("chai");
|
4
|
-
const prompt_1 = require("../prompt");
|
4
|
+
const prompt_1 = require("../tool/prompt");
|
5
5
|
describe("Prompt", () => {
|
6
6
|
it("should recognise commands", async function () {
|
7
7
|
const expectedResults = {
|
@@ -5,14 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
6
|
exports.prettyPrintTool = prettyPrintTool;
|
7
7
|
const chai_1 = require("chai");
|
8
|
-
const mcpServerManager_1 = require("../mcpServerManager");
|
9
|
-
const sudoMcpServerManager_1 = require("../sudoMcpServerManager");
|
10
8
|
const chalk_1 = __importDefault(require("chalk"));
|
9
|
+
const mcpServerManager_1 = require("../agent/mcpServerManager");
|
10
|
+
const sudoMcpServerManager_1 = require("../agent/sudoMcpServerManager");
|
11
11
|
let managers = undefined;
|
12
12
|
async function getServerManagers() {
|
13
13
|
if (!managers) {
|
14
14
|
const tm = new mcpServerManager_1.McpServerManager();
|
15
|
-
const sm = await sudoMcpServerManager_1.
|
15
|
+
const sm = await sudoMcpServerManager_1.SkillManager.initialize(tm, (_url) => {
|
16
16
|
throw "unexpected call to openUrl";
|
17
17
|
}, sudoMcpServerManager_1.LOCAL_SERVER_URL, "dummy_key");
|
18
18
|
managers = [tm, sm];
|
@@ -39,13 +39,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.runChat = runChat;
|
40
40
|
const yocto_spinner_1 = __importDefault(require("yocto-spinner"));
|
41
41
|
const fs = __importStar(require("fs"));
|
42
|
-
const tools_1 = require("./tools");
|
43
|
-
const files_1 = require("./files");
|
44
|
-
const prompt_1 = require("./prompt");
|
45
42
|
const chalk_1 = __importDefault(require("chalk"));
|
46
43
|
const tool_1 = require("@xalia/xmcp/tool");
|
47
44
|
const sdk_1 = require("@xalia/xmcp/sdk");
|
48
|
-
const
|
45
|
+
const tools_1 = require("../agent/tools");
|
46
|
+
const agentUtils_1 = require("../agent/agentUtils");
|
47
|
+
const files_1 = require("./files");
|
48
|
+
const prompt_1 = require("./prompt");
|
49
49
|
const nodePlatform_1 = require("./nodePlatform");
|
50
50
|
const logger = (0, sdk_1.getLogger)();
|
51
51
|
async function write(msg) {
|
@@ -93,7 +93,7 @@ async function runChat(llmUrl, agentProfile, conversation, prompt, image, llmApi
|
|
93
93
|
return result;
|
94
94
|
};
|
95
95
|
// Create agent
|
96
|
-
const [agent, sudoMcpServerManager] = await (0, agentUtils_1.
|
96
|
+
const [agent, sudoMcpServerManager] = await (0, agentUtils_1.createAgentWithSkills)(llmUrl, agentProfile, onMessage, onToolCall, nodePlatform_1.NODE_PLATFORM, llmApiKey, sudomcpConfig, tool_1.utils.FRONTEND_PROD_AUTHORIZED_URL, undefined, stream);
|
97
97
|
if (conversation) {
|
98
98
|
agent.setConversation(conversation);
|
99
99
|
}
|
@@ -1,6 +1,4 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
1
|
"use strict";
|
3
|
-
// -*- typescript -*-
|
4
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
5
3
|
if (k2 === undefined) k2 = k;
|
6
4
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
@@ -35,21 +33,22 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
35
33
|
};
|
36
34
|
})();
|
37
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
36
|
+
exports.agentMain = void 0;
|
38
37
|
const fs = __importStar(require("fs"));
|
39
38
|
const dotenv = __importStar(require("dotenv"));
|
40
39
|
const cmd_ts_1 = require("cmd-ts");
|
41
|
-
const
|
42
|
-
const options_1 = require("./options");
|
43
|
-
const files_1 = require("./files");
|
40
|
+
const assert_1 = require("assert");
|
44
41
|
const tool_1 = require("@xalia/xmcp/tool");
|
45
42
|
const sdk_1 = require("@xalia/xmcp/sdk");
|
46
|
-
const
|
47
|
-
const
|
43
|
+
const agent_1 = require("../agent/agent");
|
44
|
+
const agentUtils_1 = require("../agent/agentUtils");
|
45
|
+
const options_1 = require("./options");
|
46
|
+
const files_1 = require("./files");
|
47
|
+
const agentChat_1 = require("./agentChat");
|
48
48
|
const nodePlatform_1 = require("./nodePlatform");
|
49
|
-
const assert_1 = require("assert");
|
50
49
|
dotenv.config();
|
51
50
|
const logger = (0, sdk_1.getLogger)();
|
52
|
-
|
51
|
+
exports.agentMain = (0, cmd_ts_1.command)({
|
53
52
|
name: "main",
|
54
53
|
args: {
|
55
54
|
promptFile: options_1.promptFile,
|
@@ -136,12 +135,7 @@ const main = (0, cmd_ts_1.command)({
|
|
136
135
|
}
|
137
136
|
else {
|
138
137
|
const prompt = (0, files_1.loadFileOrUndefined)(promptFile);
|
139
|
-
return (0,
|
138
|
+
return (0, agentChat_1.runChat)(llmUrl, agentProfile, startingConversation, prompt, imageFile, llmApiKey, sudomcpConfig, approveToolsUpTo, !noStreaming);
|
140
139
|
}
|
141
140
|
},
|
142
141
|
});
|
143
|
-
function handleError(msg) {
|
144
|
-
console.error(msg);
|
145
|
-
process.exit(1);
|
146
|
-
}
|
147
|
-
(0, cmd_ts_1.run)(main, process.argv.slice(2)).catch(handleError);
|