@agent-smith/server 0.0.7 → 0.0.9

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 ADDED
@@ -0,0 +1,349 @@
1
+ # @agent-smith/server
2
+
3
+ A Koa v3 backend server that exposes the Agent Smith runtime via REST API (`/api/*`) and WebSocket (`/ws`), enabling remote AI agent execution with real-time token streaming. Part of the [Agent Smith toolkit](https://github.com/lynxai-team/agent-smith).
4
+
5
+ ## Features
6
+
7
+ - 🌐 **REST API** — Full CRUD for agents, workflows, backends, models, settings, and configurations
8
+ - 🔌 **WebSocket Execution** — Real-time bidirectional communication for agent inference with streaming tokens
9
+ - ⚒️ **Tool Call Confirmation** — Async confirmation pattern for user-approved tool executions
10
+ - 📡 **Streaming Events** — Token, thinking, tool call, and turn events streamed over WebSocket
11
+ - 🔧 **Plugin Support** — Install npm plugins and add feature search folders via API
12
+ - 🏗️ **Programmatic API** — Use `runServer()` to embed the server in your own applications
13
+ - 🌍 **CORS Enabled** — Cross-origin requests supported with credentials
14
+
15
+ ## Documentation
16
+
17
+ ### For AI Agents
18
+
19
+ - [Codebase Summary](.agents/documentation/codebase-summary.md) — Architecture, key files, and patterns for the server package
20
+ - [API Reference](https://raw.githubusercontent.com/lynxai-team/agent-smith/refs/heads/main/docsite/public/doc/server/2.api.md) — Complete REST endpoints and WebSocket protocol
21
+ - [Client Usage](https://raw.githubusercontent.com/lynxai-team/agent-smith/refs/heads/main/docsite/public/doc/server/3.client-usage.md) — Integration patterns with wscli and HTTP clients
22
+ - [Deployment](https://raw.githubusercontent.com/lynxai-team/agent-smith/refs/heads/main/docsite/public/doc/server/4.deployment.md) — Production deployment considerations
23
+
24
+ ### For Humans
25
+
26
+ - [Get Started](https://lynxai-team.github.io/agent-smith/server/get-started) — Installation and basic usage
27
+ - [API Reference](https://lynxai-team.github.io/agent-smith/server/api) — Complete REST endpoints and WebSocket protocol
28
+ - [Client Usage](https://lynxai-team.github.io/agent-smith/server/client-usage) — Integration patterns with wscli and HTTP clients
29
+ - [Deployment](https://lynxai-team.github.io/agent-smith/server/deployment) — Production deployment considerations
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ npm install @agent-smith/server
35
+ ```
36
+
37
+ Or build from source:
38
+
39
+ ```bash
40
+ cd agent-smith/server
41
+ npm install
42
+ npm run build
43
+ ```
44
+
45
+ ## Quick Start
46
+
47
+ ### Running the Server
48
+
49
+ ```bash
50
+ # Development mode with hot-reload
51
+ npm run devserver
52
+
53
+ # Production mode
54
+ npm run server
55
+ ```
56
+
57
+ The server listens on port **5184** by default. Verify it's running:
58
+
59
+ ```bash
60
+ curl http://localhost:5184/ping
61
+ # Response: { "ok": true }
62
+ ```
63
+
64
+ ### Executing an Agent via WebSocket
65
+
66
+ ```typescript
67
+ import { useWsServer } from "@agent-smith/wscli";
68
+
69
+ const ws = useWsServer({
70
+ url: "ws://localhost:5184/ws",
71
+ onToken: (token) => process.stdout.write(token),
72
+ });
73
+
74
+ ws.executeAgent("my-agent", { prompt: "Hello, world!" });
75
+ ```
76
+
77
+ ## Usage
78
+
79
+ ### Programmatic Server Startup
80
+
81
+ Use `runServer()` to embed the server in your application:
82
+
83
+ ```typescript
84
+ import { runServer } from "@agent-smith/server";
85
+
86
+ // Start with default routes and no static directory
87
+ runServer();
88
+
89
+ // Or with custom routes and static file serving
90
+ runServer(
91
+ undefined, // Custom route functions (optional)
92
+ "/path/to/static" // Static file directory (optional)
93
+ );
94
+ ```
95
+
96
+ ### REST API Examples
97
+
98
+ ```typescript
99
+ // List all agents
100
+ const agentsRes = await fetch("http://localhost:5184/api/agents");
101
+ const agents = await agentsRes.json();
102
+
103
+ // Get a specific agent
104
+ const agentRes = await fetch("http://localhost:5184/api/agent/my-agent");
105
+ const agent = await agentRes.json();
106
+
107
+ // List inference backends
108
+ const backendsRes = await fetch("http://localhost:5184/api/backends");
109
+ const backends = await backendsRes.json();
110
+
111
+ // Get available models for a backend
112
+ const modelsRes = await fetch("http://localhost:5184/api/models/openai");
113
+ const models = await modelsRes.json();
114
+
115
+ // Update agent settings
116
+ const settingsRes = await fetch("http://localhost:5184/api/agentSettings", {
117
+ method: "POST",
118
+ headers: { "Content-Type": "application/json" },
119
+ body: JSON.stringify({ name: "my-agent", settings: { temperature: 0.5 } }),
120
+ });
121
+ ```
122
+
123
+ ### WebSocket Agent Execution
124
+
125
+ Connect directly to the WebSocket endpoint for real-time streaming:
126
+
127
+ ```typescript
128
+ const ws = new WebSocket('ws://localhost:5184/ws');
129
+
130
+ ws.onmessage = (event) => {
131
+ const msg = JSON.parse(event.data);
132
+ switch (msg.type) {
133
+ case 'token':
134
+ process.stdout.write(msg.msg);
135
+ break;
136
+ case 'thinkingtoken':
137
+ console.log(`\x1b[2m${msg.msg}\x1b[0m`);
138
+ break;
139
+ case 'toolcall':
140
+ const payload = JSON.parse(msg.msg);
141
+ console.log(`Tool call: ${payload.tc.name}`);
142
+ break;
143
+ case 'endemit':
144
+ const result = JSON.parse(msg.msg);
145
+ console.log('\nDone:', result);
146
+ ws.close();
147
+ break;
148
+ case 'error':
149
+ console.error('Error:', msg.msg);
150
+ ws.close();
151
+ break;
152
+ }
153
+ };
154
+
155
+ ws.onopen = () => {
156
+ ws.send(JSON.stringify({
157
+ type: "command",
158
+ command: "my-agent",
159
+ feature: "agent",
160
+ payload: { prompt: "Write a poem" },
161
+ options: {}
162
+ }));
163
+ };
164
+ ```
165
+
166
+ ### System Commands (Stop & Confirm)
167
+
168
+ ```typescript
169
+ // Stop current execution
170
+ ws.send(JSON.stringify({
171
+ type: "system",
172
+ command: "stop"
173
+ }));
174
+
175
+ // Confirm or reject a tool call
176
+ ws.send(JSON.stringify({
177
+ type: "system",
178
+ command: "confirmtool",
179
+ payload: { confirm: true, id: "tool-call-uuid" }
180
+ }));
181
+ ```
182
+
183
+ ### Full Callback Example with wscli
184
+
185
+ ```typescript
186
+ import { useWsServer } from "@agent-smith/wscli";
187
+ import type { ToolCallSpec } from "@agent-smith/types";
188
+
189
+ const ws = useWsServer({
190
+ url: "ws://localhost:5184/ws",
191
+ onToken: (token, from) => process.stdout.write(token),
192
+ onThinkingToken: (token, from) => console.log(`\x1b[2m${token}\x1b[0m`),
193
+ onToolCall: (tc, type, from) => {
194
+ console.log(`\n⚒️ Tool: ${tc.name}`);
195
+ },
196
+ onToolCallEnd: (tc, content, type, from) => {
197
+ console.log(` Result: ${content?.slice(0, 100)}`);
198
+ },
199
+ onConfirmToolUsage: async (tool: ToolCallSpec) => {
200
+ return true; // Return false to deny
201
+ },
202
+ onEndEmit: (result, from) => {
203
+ console.log(`\nInference complete. Tokens: ${result.stats?.totalTokens}`);
204
+ },
205
+ onError: (msg, from) => {
206
+ console.error(`[${from}] ${msg}`);
207
+ },
208
+ });
209
+
210
+ ws.executeAgent("code-review", { prompt: "Review this function" });
211
+ ```
212
+
213
+ ## Complete Example
214
+
215
+ ```typescript
216
+ import { useWsServer } from "@agent-smith/wscli";
217
+
218
+ async function runAgent() {
219
+ const tokenStream: string[] = [];
220
+
221
+ const ws = useWsServer({
222
+ url: "ws://localhost:5184/ws",
223
+ onToken: (token) => tokenStream.push(token),
224
+ onThinkingToken: (token) => console.log(`[thinking] ${token}`),
225
+ onError: (msg) => console.error(`Error: ${msg}`),
226
+ });
227
+
228
+ try {
229
+ await ws.executeAgent("summarize", {
230
+ prompt: "Summarize the key points of quantum computing"
231
+ });
232
+
233
+ const fullText = tokenStream.join("");
234
+ console.log("\nFull response:", fullText);
235
+ } catch (err) {
236
+ console.error("Execution failed:", err);
237
+ } finally {
238
+ ws.close();
239
+ }
240
+ }
241
+
242
+ runAgent();
243
+ ```
244
+
245
+ ## API Reference
246
+
247
+ ### Factory Function: `runServer()`
248
+
249
+ ```typescript
250
+ function runServer(
251
+ routes?: ((r: Router) => void)[],
252
+ staticDir?: string
253
+ ): void;
254
+ ```
255
+
256
+ | Parameter | Type | Description |
257
+ |-----------|------|-------------|
258
+ | `routes` | `(r: Router) => void[]` | Optional custom route functions to compose with base routes |
259
+ | `staticDir` | `string` | Optional directory path for static file serving |
260
+
261
+ ### REST Endpoints
262
+
263
+ All REST routes are prefixed with `/api`.
264
+
265
+ | Method | Endpoint | Description |
266
+ |--------|----------|-------------|
267
+ | `GET` | `/ping` | Health check — returns `{ ok: true }` |
268
+ | `GET` | `/api/agents` | List all agents |
269
+ | `GET` | `/api/agent/:id` | Get agent spec by ID |
270
+ | `GET` | `/api/workflows` | List all workflows |
271
+ | `GET` | `/api/workflow/:id` | Get workflow spec by ID |
272
+ | `GET` | `/api/backends` | List inference backends |
273
+ | `GET` | `/api/backend/:name` | Set default backend |
274
+ | `POST` | `/api/tools` | Get tool definitions for tool names |
275
+ | `GET` | `/api/models/:backend` | List models for a backend |
276
+ | `GET` | `/api/models/presets/read` | List model sampling presets |
277
+ | `POST` | `/api/models/preset/update` | Create or update a preset |
278
+ | `DELETE` | `/api/models/preset/delete/:name` | Delete a preset |
279
+ | `GET` | `/api/agentsettings` | Get per-agent inference config |
280
+ | `POST` | `/api/agentsettings/update` | Update agent settings |
281
+ | `GET` | `/api/state` | Get server state |
282
+ | `GET` | `/api/conf` | Get current configuration |
283
+ | `GET` | `/api/conf/create` | Create config file if missing |
284
+ | `POST` | `/api/plugins/install` | Install npm plugins |
285
+ | `POST` | `/api/folders/add` | Add feature search folders |
286
+ | `GET` | `/api/app/:name/conf` | Get app config |
287
+ | `POST` | `/api/app/:name/update` | Update app config |
288
+ | `GET` | `/api/workspace` | Get workspace info |
289
+ | `POST` | `/api/workspace` | Create or update workspace |
290
+ | `POST` | `/api/workspace/update` | Set default workspace |
291
+ | `GET` | `/api/settings` | Get application settings |
292
+
293
+ ### WebSocket Protocol
294
+
295
+ **Endpoint:** `ws://localhost:5184/ws`
296
+
297
+ #### Client Messages (`WsClientMsg`)
298
+
299
+ ```typescript
300
+ interface WsClientMsg {
301
+ command: string; // Agent or workflow name
302
+ type: 'command' | 'system';
303
+ feature?: 'agent' | 'workflow';
304
+ payload?: any; // Prompt and execution context
305
+ options?: Record<string, any>; // Abort controller, variables, etc.
306
+ }
307
+ ```
308
+
309
+ #### Server Messages (`WsRawServerMsg`)
310
+
311
+ ```typescript
312
+ interface WsRawServerMsg {
313
+ type: string;
314
+ from: string;
315
+ msg: string;
316
+ }
317
+ ```
318
+
319
+ | Type | Description |
320
+ |------|-------------|
321
+ | `error` | Error message |
322
+ | `startemit` | Inference started |
323
+ | `token` | Generated token |
324
+ | `thinkingtoken` | Thinking/reasoning token |
325
+ | `turnstart` | New conversation turn |
326
+ | `turnend` | Turn completed |
327
+ | `assistant` | Assistant text output |
328
+ | `think` | Model thinking content |
329
+ | `toolcall` | Tool call initiated |
330
+ | `toolcallend` | Tool call completed |
331
+ | `toolcallconfirm` | Awaiting tool confirmation |
332
+ | `finalresult` | Final inference result |
333
+ | `endemit` | Inference complete |
334
+
335
+ ## Important Notes
336
+
337
+ - **Port**: The server listens on port **5184** by default. Change it in `src/server/server.ts` or use a reverse proxy.
338
+ - **Authentication**: No built-in authentication — intended for local use. Deploy behind a reverse proxy for production.
339
+ - **CORS**: Enabled with credentials by default. Restrict origins in production deployments.
340
+ - **Static Files**: Served from project root when `NODE_ENV` is not `"development"`.
341
+ - **Dependencies**: Requires `@agent-smith/core` and `@agent-smith/types` packages.
342
+ - **Related Packages**:
343
+ - [`@agent-smith/wscli`](https://www.npmjs.com/package/@agent-smith/wscli) — WebSocket client for the server
344
+ - [`@agent-smith/core`](https://www.npmjs.com/package/@agent-smith/core) — Runtime engine (DB, features, execution)
345
+ - [`@agent-smith/types`](https://www.npmjs.com/package/@agent-smith/types) — Shared interfaces
346
+
347
+ ## License
348
+
349
+ MIT
@@ -0,0 +1,4 @@
1
+ import type { WsClientMsg } from "@agent-smith/types";
2
+ import type { Context } from "koa";
3
+ declare function buildCallbacks(msg: WsClientMsg, ctx: Context, confirmToolCalls: Record<string, (value: boolean) => void>): void;
4
+ export { buildCallbacks, };
@@ -0,0 +1,182 @@
1
+ import { default as color } from "ansi-colors";
2
+ import { createAwaiter } from "./utils.js";
3
+ function buildCallbacks(msg, ctx, confirmToolCalls) {
4
+ if (!msg?.options) {
5
+ msg.options = {};
6
+ }
7
+ msg.options.onStartEmit = (p, from) => {
8
+ const rsm = {
9
+ type: "startemit",
10
+ from: from,
11
+ msg: JSON.stringify(p),
12
+ };
13
+ ctx.websocket.send(JSON.stringify(rsm));
14
+ };
15
+ msg.options.onThinkingToken = (t, from) => {
16
+ const rsm = {
17
+ type: "thinkingtoken",
18
+ from: from,
19
+ msg: t,
20
+ };
21
+ ctx.websocket.send(JSON.stringify(rsm));
22
+ process.stdout.write(`\x1b[2m${t}\x1b[0m`);
23
+ };
24
+ msg.options.onToken = (t, from) => {
25
+ const rsm2 = {
26
+ type: "token",
27
+ from: from,
28
+ msg: t,
29
+ };
30
+ ctx.websocket.send(JSON.stringify(rsm2));
31
+ process.stdout.write(t);
32
+ };
33
+ msg.options.onStartThinking = (from) => {
34
+ const rsm = {
35
+ type: "thinkingstart",
36
+ from: from,
37
+ msg: "",
38
+ };
39
+ ctx.websocket.send(JSON.stringify(rsm));
40
+ };
41
+ msg.options.onEndThinking = (from) => {
42
+ const rsm = {
43
+ type: "thinkingend",
44
+ from: from,
45
+ msg: "",
46
+ };
47
+ ctx.websocket.send(JSON.stringify(rsm));
48
+ };
49
+ msg.options.onTurnStart = (from) => {
50
+ const rsm = {
51
+ type: "turnstart",
52
+ from: from,
53
+ msg: "",
54
+ };
55
+ ctx.websocket.send(JSON.stringify(rsm));
56
+ };
57
+ msg.options.onTurnEnd = (ht, from) => {
58
+ const rsm = {
59
+ type: "turnend",
60
+ from: from,
61
+ msg: JSON.stringify(ht),
62
+ };
63
+ ctx.websocket.send(JSON.stringify(rsm));
64
+ };
65
+ msg.options.onAssistant = (txt, from) => {
66
+ const rsm = {
67
+ type: "assistant",
68
+ from: from,
69
+ msg: txt,
70
+ };
71
+ ctx.websocket.send(JSON.stringify(rsm));
72
+ };
73
+ msg.options.onThink = (txt, from) => {
74
+ const rsm = {
75
+ type: "think",
76
+ from: from,
77
+ msg: txt,
78
+ };
79
+ ctx.websocket.send(JSON.stringify(rsm));
80
+ };
81
+ msg.options.onEndEmit = (res, from) => {
82
+ const rsm = {
83
+ type: "endemit",
84
+ from: from,
85
+ msg: JSON.stringify(res),
86
+ };
87
+ ctx.websocket.send(JSON.stringify(rsm));
88
+ };
89
+ msg.options.onToolCallToken = (t, from) => {
90
+ const rsm = {
91
+ type: "toolcalltoken",
92
+ from: from,
93
+ msg: JSON.stringify(t),
94
+ };
95
+ ctx.websocket.send(JSON.stringify(rsm));
96
+ };
97
+ msg.options.onToolCallInProgress = (tcs, from) => {
98
+ const rsm = {
99
+ type: "toolcallinprogress",
100
+ from: from,
101
+ msg: JSON.stringify(tcs),
102
+ };
103
+ ctx.websocket.send(JSON.stringify(rsm));
104
+ };
105
+ msg.options.onPromptProcessingProgress = (progress, from) => {
106
+ const rsm = {
107
+ type: "promptprocessingprogress",
108
+ from: from,
109
+ msg: JSON.stringify(progress),
110
+ };
111
+ ctx.websocket.send(JSON.stringify(rsm));
112
+ };
113
+ msg.options.onToolsTurnStart = (tcs, from) => {
114
+ const rsm = {
115
+ type: "toolsturnstart",
116
+ from: from,
117
+ msg: JSON.stringify(tcs),
118
+ };
119
+ ctx.websocket.send(JSON.stringify(rsm));
120
+ };
121
+ msg.options.onToolsTurnEnd = (tr, from) => {
122
+ const rsm = {
123
+ type: "toolsturnend",
124
+ from: from,
125
+ msg: JSON.stringify(tr),
126
+ };
127
+ ctx.websocket.send(JSON.stringify(rsm));
128
+ };
129
+ msg.options.onToolCall = (tc, type, from) => {
130
+ if (!tc?.id) {
131
+ tc.id = crypto.randomUUID();
132
+ }
133
+ const payload = { tc: tc, type: type, from: from };
134
+ const rsm = {
135
+ type: "toolcall",
136
+ from: from,
137
+ msg: JSON.stringify(payload),
138
+ };
139
+ ctx.websocket.send(JSON.stringify(rsm));
140
+ console.log("\n⚒️ ", color.bold(msg.command), "=>", `${color.yellowBright(tc.name)}`, tc.arguments);
141
+ };
142
+ msg.options.onToolCallEnd = (tc, tr, type, from) => {
143
+ let toolResData;
144
+ if (typeof tr == 'object') {
145
+ tr.type = type;
146
+ if (tr?.text) {
147
+ // comes from an inference task
148
+ toolResData = tr.text;
149
+ }
150
+ else {
151
+ toolResData = JSON.stringify(tr);
152
+ }
153
+ }
154
+ else {
155
+ toolResData = tr.toString();
156
+ }
157
+ const payload = { tc: tc, type: type, from: from };
158
+ const rsm = {
159
+ type: "toolcallend",
160
+ from: from,
161
+ msg: `${JSON.stringify(payload)}<|xtool_call_id|>` + toolResData,
162
+ };
163
+ //console.log("TOOL CALL END", toolResData);
164
+ ctx.websocket.send(JSON.stringify(rsm));
165
+ };
166
+ msg.options.confirmToolUsage = async (tc, from) => {
167
+ if (!tc?.id) {
168
+ tc.id = crypto.randomUUID();
169
+ }
170
+ const rsm = {
171
+ type: "toolcallconfirm",
172
+ from: from,
173
+ msg: JSON.stringify(tc),
174
+ };
175
+ const { promise, resolve } = createAwaiter();
176
+ confirmToolCalls[tc.id] = resolve;
177
+ ctx.websocket.send(JSON.stringify(rsm));
178
+ const res = await promise;
179
+ return res;
180
+ };
181
+ }
182
+ export { buildCallbacks, };
@@ -0,0 +1,4 @@
1
+ import type Router from '@koa/router';
2
+ declare function getAgentSettingsCmd(r: Router): void;
3
+ declare function updateAgentSettingsCmd(r: Router): void;
4
+ export { getAgentSettingsCmd, updateAgentSettingsCmd, };
@@ -0,0 +1,20 @@
1
+ import { db, state } from '@agent-smith/core';
2
+ function getAgentSettingsCmd(r) {
3
+ r.get('/agentsettings', async (ctx, next) => {
4
+ const ts = state.getAgentSettings(true);
5
+ ctx.body = ts;
6
+ ctx.status = 200;
7
+ });
8
+ }
9
+ function updateAgentSettingsCmd(r) {
10
+ r.post('/agentsettings/update', async (ctx, next) => {
11
+ const data = ctx.request.body;
12
+ //console.log("DATA", data);
13
+ const name = data.name;
14
+ const settings = data.settings;
15
+ const ts = db.upsertAgentSettings(name, settings);
16
+ ctx.body = ts;
17
+ ctx.status = 200;
18
+ });
19
+ }
20
+ export { getAgentSettingsCmd, updateAgentSettingsCmd, };
@@ -1,8 +1,20 @@
1
- import { db, fs } from '@agent-smith/cli';
1
+ import { db, fs } from '@agent-smith/core';
2
+ import { excludedTaskTypes } from '../utils.js';
2
3
  function getAgentsRoute(r) {
3
4
  r.get('/agents', async (ctx, next) => {
4
5
  const agents = db.readFeaturesType("agent");
5
- ctx.body = agents;
6
+ let ag = {};
7
+ for (const [name, feat] of Object.entries(agents)) {
8
+ if (feat?.type) {
9
+ if (!excludedTaskTypes.includes(feat.type)) {
10
+ ag[name] = feat;
11
+ }
12
+ }
13
+ else {
14
+ ag[name] = feat;
15
+ }
16
+ }
17
+ ctx.body = ag;
6
18
  ctx.status = 200;
7
19
  //console.log("AGENTS", ctx.status);
8
20
  //await next()
@@ -11,8 +23,16 @@ function getAgentsRoute(r) {
11
23
  function getAgentRoute(r) {
12
24
  r.get('/agent/:id', async (ctx, next) => {
13
25
  //console.log(ctx.params.id)
14
- const taskSpec = fs.openTaskSpec(ctx.params.id, true);
15
- ctx.body = taskSpec.taskFileSpec;
26
+ let spec;
27
+ try {
28
+ spec = fs.openAgentSpec(ctx.params.id);
29
+ }
30
+ catch (e) {
31
+ ctx.body = `error reading the agent spec file ${ctx.params.id}`;
32
+ ctx.status = 500;
33
+ return;
34
+ }
35
+ ctx.body = spec.agentSpec;
16
36
  ctx.status = 200;
17
37
  //await next()
18
38
  });
@@ -1,9 +1,9 @@
1
- import { getConfigPath } from "@agent-smith/cli";
1
+ import { conf } from "@agent-smith/core";
2
2
  import fs, { existsSync } from "node:fs";
3
3
  import path from "node:path";
4
4
  import yaml from "yaml";
5
5
  function getOrCreateAppConfigFile(appName) {
6
- const { confDir } = getConfigPath("agent-smith/" + appName, "config.db");
6
+ const { confDir } = conf.getConfigPath("agent-smith/" + appName, "config.db");
7
7
  if (!fs.existsSync(confDir)) {
8
8
  fs.mkdirSync(confDir);
9
9
  }
@@ -19,7 +19,7 @@ function getOrCreateAppConfigFile(appName) {
19
19
  }
20
20
  }
21
21
  function updateAppConfigFile(appName, content) {
22
- const { confDir } = getConfigPath("agent-smith/" + appName, "config.db");
22
+ const { confDir } = conf.getConfigPath("agent-smith/" + appName, "config.db");
23
23
  const fp = path.join(confDir, "config.yml");
24
24
  const txt = yaml.stringify(content);
25
25
  fs.writeFileSync(fp, txt, { encoding: "utf-8" });
@@ -1,4 +1,4 @@
1
- import { db, setBackend } from '@agent-smith/cli';
1
+ import { db, state } from '@agent-smith/core';
2
2
  function getBackendsRoute(r) {
3
3
  r.get('/backends', async (ctx, next) => {
4
4
  const backends = db.readBackends();
@@ -10,7 +10,7 @@ function setBackendRoute(r) {
10
10
  r.get('/backend/:name', async (ctx, next) => {
11
11
  const name = ctx.params.name;
12
12
  console.log("Loading backend", name);
13
- const ok = await setBackend(name, true);
13
+ const ok = await state.setBackend(name, true);
14
14
  if (!ok) {
15
15
  ctx.status = 400;
16
16
  ctx.body = "backend not found";
@@ -1,4 +1,4 @@
1
- import { createConfigFile, updateConfCmd } from '@agent-smith/cli';
1
+ import { conf } from '@agent-smith/core';
2
2
  import { getConfig } from '../utils.js';
3
3
  function getConfRoute(r) {
4
4
  r.get('/conf', async (ctx, next) => {
@@ -17,7 +17,7 @@ function createConfRoute(r) {
17
17
  r.get('/conf/create', async (ctx, next) => {
18
18
  let cfp = null;
19
19
  try {
20
- cfp = createConfigFile(undefined, ["llamacpp"]);
20
+ cfp = conf.createConfigFileIfNotExists();
21
21
  }
22
22
  catch (e) {
23
23
  console.error("500", e);
@@ -27,7 +27,7 @@ function createConfRoute(r) {
27
27
  if (cfp) {
28
28
  ctx.body = cfp;
29
29
  ctx.status = 201;
30
- await updateConfCmd([cfp]);
30
+ await conf.updateConfCmd([cfp]);
31
31
  }
32
32
  });
33
33
  }
@@ -1,9 +1,8 @@
1
- import { updateConfCmd, updateConfigFile, init } from '@agent-smith/cli';
1
+ import { conf as c } from '@agent-smith/core';
2
2
  import { getConfig } from '../utils.js';
3
3
  function addFolderRoute(r) {
4
4
  r.post('/folders/add', async (ctx, next) => {
5
5
  const payload = ctx.request.body;
6
- await init();
7
6
  const { found, conf, path } = getConfig();
8
7
  if (!found) {
9
8
  throw new Error("no config file found");
@@ -18,9 +17,9 @@ function addFolderRoute(r) {
18
17
  ;
19
18
  console.log("Updating config file at", path);
20
19
  console.dir(conf, { depth: 3 });
21
- updateConfigFile(conf, path);
20
+ c.updateConfigFile(conf, path);
22
21
  console.log("Updating db features from config file");
23
- await updateConfCmd([path]);
22
+ await c.updateConfCmd([path]);
24
23
  ctx.status = 202;
25
24
  });
26
25
  }