@amodalai/runtime 0.2.0 → 0.2.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.
- package/dist/src/__fixtures__/README.md +4 -0
- package/dist/src/__fixtures__/e2e.test.d.ts +6 -0
- package/dist/src/__fixtures__/e2e.test.js +211 -0
- package/dist/src/__fixtures__/e2e.test.js.map +1 -0
- package/dist/src/__fixtures__/smoke-agent/automations/delivery-callback-test.json +9 -0
- package/dist/src/__fixtures__/smoke-agent/connections/mock-mcp/spec.json +1 -1
- package/dist/src/__fixtures__/smoke.test.js +715 -29
- package/dist/src/__fixtures__/smoke.test.js.map +1 -1
- package/dist/src/__fixtures__/test-env.d.ts +27 -0
- package/dist/src/__fixtures__/test-env.js +64 -0
- package/dist/src/__fixtures__/test-env.js.map +1 -0
- package/dist/src/__fixtures__/test-helpers.d.ts +30 -0
- package/dist/src/__fixtures__/test-helpers.js +120 -0
- package/dist/src/__fixtures__/test-helpers.js.map +1 -0
- package/dist/src/agent/agent-types.d.ts +22 -0
- package/dist/src/agent/agent-types.js.map +1 -1
- package/dist/src/agent/automation-bridge.d.ts +9 -0
- package/dist/src/agent/automation-bridge.js +26 -0
- package/dist/src/agent/automation-bridge.js.map +1 -1
- package/dist/src/agent/automation-bridge.test.js +63 -0
- package/dist/src/agent/automation-bridge.test.js.map +1 -1
- package/dist/src/agent/local-server.d.ts +0 -7
- package/dist/src/agent/local-server.js +230 -86
- package/dist/src/agent/local-server.js.map +1 -1
- package/dist/src/agent/local-server.test.js +14 -8
- package/dist/src/agent/local-server.test.js.map +1 -1
- package/dist/src/agent/loop-types.d.ts +81 -2
- package/dist/src/agent/loop-types.js +4 -0
- package/dist/src/agent/loop-types.js.map +1 -1
- package/dist/src/agent/loop.js +16 -3
- package/dist/src/agent/loop.js.map +1 -1
- package/dist/src/agent/loop.test.js +572 -8
- package/dist/src/agent/loop.test.js.map +1 -1
- package/dist/src/agent/proactive/delivery-router.d.ts +68 -0
- package/dist/src/agent/proactive/delivery-router.js +337 -0
- package/dist/src/agent/proactive/delivery-router.js.map +1 -0
- package/dist/src/agent/proactive/delivery-router.test.d.ts +6 -0
- package/dist/src/agent/proactive/delivery-router.test.js +455 -0
- package/dist/src/agent/proactive/delivery-router.test.js.map +1 -0
- package/dist/src/agent/proactive/proactive-runner.d.ts +23 -1
- package/dist/src/agent/proactive/proactive-runner.js +42 -10
- package/dist/src/agent/proactive/proactive-runner.js.map +1 -1
- package/dist/src/agent/proactive/proactive-runner.test.js +0 -2
- package/dist/src/agent/proactive/proactive-runner.test.js.map +1 -1
- package/dist/src/agent/routes/admin-chat-abort.test.d.ts +6 -0
- package/dist/src/agent/routes/admin-chat-abort.test.js +206 -0
- package/dist/src/agent/routes/admin-chat-abort.test.js.map +1 -0
- package/dist/src/agent/routes/admin-chat.js +0 -2
- package/dist/src/agent/routes/admin-chat.js.map +1 -1
- package/dist/src/agent/routes/task.test.js +0 -2
- package/dist/src/agent/routes/task.test.js.map +1 -1
- package/dist/src/agent/snapshot-server.js +0 -2
- package/dist/src/agent/snapshot-server.js.map +1 -1
- package/dist/src/agent/states/compacting.js +5 -3
- package/dist/src/agent/states/compacting.js.map +1 -1
- package/dist/src/agent/states/confirming.js +3 -0
- package/dist/src/agent/states/confirming.js.map +1 -1
- package/dist/src/agent/states/dispatching.js +45 -1
- package/dist/src/agent/states/dispatching.js.map +1 -1
- package/dist/src/agent/states/executing.js +225 -81
- package/dist/src/agent/states/executing.js.map +1 -1
- package/dist/src/agent/states/streaming.js +14 -0
- package/dist/src/agent/states/streaming.js.map +1 -1
- package/dist/src/agent/states/thinking.d.ts +1 -1
- package/dist/src/agent/states/thinking.js +246 -29
- package/dist/src/agent/states/thinking.js.map +1 -1
- package/dist/src/agent/token-estimate.d.ts +20 -6
- package/dist/src/agent/token-estimate.js +24 -3
- package/dist/src/agent/token-estimate.js.map +1 -1
- package/dist/src/agent/token-estimate.test.d.ts +6 -0
- package/dist/src/agent/token-estimate.test.js +44 -0
- package/dist/src/agent/token-estimate.test.js.map +1 -0
- package/dist/src/api/create-agent.js +0 -3
- package/dist/src/api/create-agent.js.map +1 -1
- package/dist/src/api/types.d.ts +0 -2
- package/dist/src/env-ref.d.ts +13 -0
- package/dist/src/env-ref.js +31 -0
- package/dist/src/env-ref.js.map +1 -0
- package/dist/src/env-ref.test.d.ts +6 -0
- package/dist/src/env-ref.test.js +34 -0
- package/dist/src/env-ref.test.js.map +1 -0
- package/dist/src/errors.d.ts +15 -0
- package/dist/src/errors.js +22 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/errors.test.js +2 -2
- package/dist/src/errors.test.js.map +1 -1
- package/dist/src/events/event-bus.d.ts +54 -0
- package/dist/src/events/event-bus.js +84 -0
- package/dist/src/events/event-bus.js.map +1 -0
- package/dist/src/events/event-bus.test.d.ts +6 -0
- package/dist/src/events/event-bus.test.js +112 -0
- package/dist/src/events/event-bus.test.js.map +1 -0
- package/dist/src/events/events-route.d.ts +36 -0
- package/dist/src/events/events-route.js +80 -0
- package/dist/src/events/events-route.js.map +1 -0
- package/dist/src/events/events-route.test.d.ts +6 -0
- package/dist/src/events/events-route.test.js +134 -0
- package/dist/src/events/events-route.test.js.map +1 -0
- package/dist/src/events/store-event-wrapper.d.ts +19 -0
- package/dist/src/events/store-event-wrapper.js +57 -0
- package/dist/src/events/store-event-wrapper.js.map +1 -0
- package/dist/src/events/store-event-wrapper.test.d.ts +6 -0
- package/dist/src/events/store-event-wrapper.test.js +91 -0
- package/dist/src/events/store-event-wrapper.test.js.map +1 -0
- package/dist/src/middleware/auth.d.ts +0 -2
- package/dist/src/middleware/auth.js.map +1 -1
- package/dist/src/providers/search-provider.d.ts +64 -0
- package/dist/src/providers/search-provider.js +174 -0
- package/dist/src/providers/search-provider.js.map +1 -0
- package/dist/src/providers/types.d.ts +8 -0
- package/dist/src/routes/ai-stream.d.ts +15 -0
- package/dist/src/routes/ai-stream.js +9 -0
- package/dist/src/routes/ai-stream.js.map +1 -1
- package/dist/src/routes/chat-stream.d.ts +6 -0
- package/dist/src/routes/chat-stream.js +2 -0
- package/dist/src/routes/chat-stream.js.map +1 -1
- package/dist/src/routes/chat.d.ts +6 -0
- package/dist/src/routes/chat.js +2 -0
- package/dist/src/routes/chat.js.map +1 -1
- package/dist/src/routes/session-resolver.d.ts +5 -0
- package/dist/src/routes/session-resolver.js +1 -15
- package/dist/src/routes/session-resolver.js.map +1 -1
- package/dist/src/routes/session-resolver.test.js +7 -6
- package/dist/src/routes/session-resolver.test.js.map +1 -1
- package/dist/src/server.d.ts +6 -0
- package/dist/src/server.js +2 -0
- package/dist/src/server.js.map +1 -1
- package/dist/src/session/drizzle-session-store.d.ts +56 -0
- package/dist/src/session/drizzle-session-store.js +203 -0
- package/dist/src/session/drizzle-session-store.js.map +1 -0
- package/dist/src/session/manager.d.ts +6 -3
- package/dist/src/session/manager.js +46 -16
- package/dist/src/session/manager.js.map +1 -1
- package/dist/src/session/manager.test.js +12 -18
- package/dist/src/session/manager.test.js.map +1 -1
- package/dist/src/session/pglite-session-store.d.ts +23 -0
- package/dist/src/session/pglite-session-store.js +70 -0
- package/dist/src/session/pglite-session-store.js.map +1 -0
- package/dist/src/session/postgres-session-store.d.ts +44 -0
- package/dist/src/session/postgres-session-store.js +138 -0
- package/dist/src/session/postgres-session-store.js.map +1 -0
- package/dist/src/session/session-builder.d.ts +0 -2
- package/dist/src/session/session-builder.js +22 -2
- package/dist/src/session/session-builder.js.map +1 -1
- package/dist/src/session/session-builder.test.js +0 -2
- package/dist/src/session/session-builder.test.js.map +1 -1
- package/dist/src/session/session-store-selector.d.ts +49 -0
- package/dist/src/session/session-store-selector.js +60 -0
- package/dist/src/session/session-store-selector.js.map +1 -0
- package/dist/src/session/session-store-selector.test.d.ts +6 -0
- package/dist/src/session/session-store-selector.test.js +79 -0
- package/dist/src/session/session-store-selector.test.js.map +1 -0
- package/dist/src/session/store.d.ts +146 -32
- package/dist/src/session/store.js +126 -138
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/session/store.test.js +385 -107
- package/dist/src/session/store.test.js.map +1 -1
- package/dist/src/session/tool-context-factory.d.ts +3 -2
- package/dist/src/session/tool-context-factory.js +1 -2
- package/dist/src/session/tool-context-factory.js.map +1 -1
- package/dist/src/session/tool-context-factory.test.js +1 -4
- package/dist/src/session/tool-context-factory.test.js.map +1 -1
- package/dist/src/session/types.d.ts +13 -6
- package/dist/src/stores/schema.d.ts +0 -34
- package/dist/src/stores/schema.js +6 -4
- package/dist/src/stores/schema.js.map +1 -1
- package/dist/src/tools/admin-file-tools.d.ts +29 -0
- package/dist/src/tools/admin-file-tools.js +525 -11
- package/dist/src/tools/admin-file-tools.js.map +1 -1
- package/dist/src/tools/admin-file-tools.test.js +373 -4
- package/dist/src/tools/admin-file-tools.test.js.map +1 -1
- package/dist/src/tools/custom-tool-adapter.test.js +0 -1
- package/dist/src/tools/custom-tool-adapter.test.js.map +1 -1
- package/dist/src/tools/dispatch-tool.d.ts +4 -4
- package/dist/src/tools/fetch-url-tool.d.ts +23 -0
- package/dist/src/tools/fetch-url-tool.js +333 -0
- package/dist/src/tools/fetch-url-tool.js.map +1 -0
- package/dist/src/tools/fetch-url-tool.test.d.ts +6 -0
- package/dist/src/tools/fetch-url-tool.test.js +228 -0
- package/dist/src/tools/fetch-url-tool.test.js.map +1 -0
- package/dist/src/tools/mcp-tool-adapter.test.js +0 -1
- package/dist/src/tools/mcp-tool-adapter.test.js.map +1 -1
- package/dist/src/tools/registry.test.js +0 -1
- package/dist/src/tools/registry.test.js.map +1 -1
- package/dist/src/tools/request-tool.test.js +0 -1
- package/dist/src/tools/request-tool.test.js.map +1 -1
- package/dist/src/tools/store-tools.test.js +0 -1
- package/dist/src/tools/store-tools.test.js.map +1 -1
- package/dist/src/tools/types.d.ts +20 -2
- package/dist/src/tools/web-search-tool.d.ts +31 -0
- package/dist/src/tools/web-search-tool.js +170 -0
- package/dist/src/tools/web-search-tool.js.map +1 -0
- package/dist/src/tools/web-search-tool.test.d.ts +6 -0
- package/dist/src/tools/web-search-tool.test.js +153 -0
- package/dist/src/tools/web-search-tool.test.js.map +1 -0
- package/dist/src/tools/web-tools-shared.d.ts +21 -0
- package/dist/src/tools/web-tools-shared.js +32 -0
- package/dist/src/tools/web-tools-shared.js.map +1 -0
- package/dist/src/types.d.ts +20 -0
- package/dist/src/types.js +13 -0
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +17 -3
- package/dist/src/agent/session-store.d.ts +0 -71
- package/dist/src/agent/session-store.js +0 -151
- package/dist/src/agent/session-store.js.map +0 -1
- package/dist/src/session/admin-file-tools.d.ts +0 -136
- package/dist/src/session/admin-file-tools.js +0 -240
- package/dist/src/session/admin-file-tools.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amodalai/runtime",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Agent Runtime Platform — HTTP server for repo and platform modes",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -23,18 +23,21 @@
|
|
|
23
23
|
"@ai-sdk/openai": "^3.0.50",
|
|
24
24
|
"@anthropic-ai/sdk": "^0.39.0",
|
|
25
25
|
"@electric-sql/pglite": "^0.3.15",
|
|
26
|
+
"@mozilla/readability": "^0.6.0",
|
|
26
27
|
"ai": "^6.0.145",
|
|
27
28
|
"drizzle-orm": "^0.45.2",
|
|
28
29
|
"esbuild": "0.25.5",
|
|
29
30
|
"express": "^4.21.0",
|
|
30
31
|
"express-rate-limit": "^7.5.0",
|
|
32
|
+
"glob": "^10.5.0",
|
|
31
33
|
"jose": "^6.0.0",
|
|
34
|
+
"linkedom": "^0.18.12",
|
|
32
35
|
"node-cron": "^3.0.3",
|
|
33
36
|
"pg": "^8.13.1",
|
|
34
37
|
"zod": "^3.25.0",
|
|
35
38
|
"zod-to-json-schema": "^3.25.2",
|
|
36
|
-
"@amodalai/core": "0.2.
|
|
37
|
-
"@amodalai/types": "0.2.
|
|
39
|
+
"@amodalai/core": "0.2.1",
|
|
40
|
+
"@amodalai/types": "0.2.1"
|
|
38
41
|
},
|
|
39
42
|
"devDependencies": {
|
|
40
43
|
"@types/express": "^4.17.21",
|
|
@@ -55,6 +58,17 @@
|
|
|
55
58
|
"format": "prettier --write .",
|
|
56
59
|
"test": "vitest run",
|
|
57
60
|
"test:smoke": "vitest run src/__fixtures__/smoke.test.ts",
|
|
61
|
+
"test:smoke:quick": "vitest run src/__fixtures__/smoke.test.ts -t 'health endpoint|streams chat with init|makes at least one tool call|persists data across store|calls MCP tool|reason=model_stop|reason=budget_exceeded'",
|
|
62
|
+
"test:smoke:anthropic": "SMOKE_TARGET=anthropic vitest run src/__fixtures__/smoke.test.ts",
|
|
63
|
+
"test:smoke:google": "SMOKE_TARGET=google vitest run src/__fixtures__/smoke.test.ts",
|
|
64
|
+
"test:smoke:openai": "SMOKE_TARGET=openai vitest run src/__fixtures__/smoke.test.ts",
|
|
65
|
+
"test:smoke:groq": "SMOKE_TARGET=groq vitest run src/__fixtures__/smoke.test.ts",
|
|
66
|
+
"test:e2e": "vitest run src/__fixtures__/e2e.test.ts",
|
|
67
|
+
"test:e2e:google": "E2E_TARGETS=google vitest run src/__fixtures__/e2e.test.ts",
|
|
68
|
+
"test:e2e:anthropic": "E2E_TARGETS=anthropic vitest run src/__fixtures__/e2e.test.ts",
|
|
69
|
+
"test:e2e:openai": "E2E_TARGETS=openai vitest run src/__fixtures__/e2e.test.ts",
|
|
70
|
+
"test:e2e:groq": "E2E_TARGETS=groq vitest run src/__fixtures__/e2e.test.ts",
|
|
71
|
+
"test:e2e:all": "E2E_TARGETS=google,anthropic,openai,groq vitest run src/__fixtures__/e2e.test.ts",
|
|
58
72
|
"test:ci": "pnpm --filter @amodalai/core run build && vitest run",
|
|
59
73
|
"typecheck": "tsc --emitDeclarationOnly",
|
|
60
74
|
"start": "node dist/src/index.js",
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
-
* SPDX-License-Identifier: MIT
|
|
5
|
-
*/
|
|
6
|
-
/** Minimal session shape needed for persistence. */
|
|
7
|
-
interface SessionLike {
|
|
8
|
-
id: string;
|
|
9
|
-
appId?: string;
|
|
10
|
-
title?: string;
|
|
11
|
-
conversationHistory?: unknown[];
|
|
12
|
-
messages?: unknown[];
|
|
13
|
-
createdAt: number;
|
|
14
|
-
lastAccessedAt: number;
|
|
15
|
-
}
|
|
16
|
-
interface PersistedSession {
|
|
17
|
-
id: string;
|
|
18
|
-
appId: string;
|
|
19
|
-
title?: string;
|
|
20
|
-
conversationHistory: unknown[];
|
|
21
|
-
createdAt: number;
|
|
22
|
-
lastAccessedAt: number;
|
|
23
|
-
automationName?: string;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Persists session conversation history to disk.
|
|
27
|
-
* Sessions are stored as JSON files in .amodal/sessions/ under the repo root.
|
|
28
|
-
*/
|
|
29
|
-
export declare class SessionStore {
|
|
30
|
-
private readonly dir;
|
|
31
|
-
constructor(repoPath: string);
|
|
32
|
-
private ensureDir;
|
|
33
|
-
/**
|
|
34
|
-
* Resolve a session ID to a safe file path within the sessions directory.
|
|
35
|
-
* Returns the full path if valid, null if the ID is suspicious.
|
|
36
|
-
*/
|
|
37
|
-
private resolvePath;
|
|
38
|
-
/**
|
|
39
|
-
* Save a session's conversation history to disk.
|
|
40
|
-
*/
|
|
41
|
-
save(session: SessionLike, automationName?: string): void;
|
|
42
|
-
/**
|
|
43
|
-
* Load a session's persisted data by ID.
|
|
44
|
-
*/
|
|
45
|
-
load(sessionId: string): PersistedSession | null;
|
|
46
|
-
/**
|
|
47
|
-
* List all persisted sessions, newest first.
|
|
48
|
-
*/
|
|
49
|
-
list(): Array<{
|
|
50
|
-
id: string;
|
|
51
|
-
appId: string;
|
|
52
|
-
title?: string;
|
|
53
|
-
createdAt: number;
|
|
54
|
-
lastAccessedAt: number;
|
|
55
|
-
summary: string;
|
|
56
|
-
automationName?: string;
|
|
57
|
-
}>;
|
|
58
|
-
/**
|
|
59
|
-
* Update a session's title.
|
|
60
|
-
*/
|
|
61
|
-
updateTitle(sessionId: string, title: string): boolean;
|
|
62
|
-
/**
|
|
63
|
-
* Delete a session file.
|
|
64
|
-
*/
|
|
65
|
-
delete(sessionId: string): boolean;
|
|
66
|
-
/**
|
|
67
|
-
* Get the most recent session ID.
|
|
68
|
-
*/
|
|
69
|
-
latest(): string | null;
|
|
70
|
-
}
|
|
71
|
-
export {};
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
-
* SPDX-License-Identifier: MIT
|
|
5
|
-
*/
|
|
6
|
-
import { existsSync, mkdirSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
7
|
-
import { join, resolve } from 'node:path';
|
|
8
|
-
/**
|
|
9
|
-
* Persists session conversation history to disk.
|
|
10
|
-
* Sessions are stored as JSON files in .amodal/sessions/ under the repo root.
|
|
11
|
-
*/
|
|
12
|
-
export class SessionStore {
|
|
13
|
-
dir;
|
|
14
|
-
constructor(repoPath) {
|
|
15
|
-
this.dir = join(repoPath, '.amodal', 'sessions');
|
|
16
|
-
}
|
|
17
|
-
ensureDir() {
|
|
18
|
-
if (!existsSync(this.dir)) {
|
|
19
|
-
mkdirSync(this.dir, { recursive: true });
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Resolve a session ID to a safe file path within the sessions directory.
|
|
24
|
-
* Returns the full path if valid, null if the ID is suspicious.
|
|
25
|
-
*/
|
|
26
|
-
resolvePath(sessionId) {
|
|
27
|
-
const trimmed = sessionId.trim();
|
|
28
|
-
if (trimmed.length === 0 || trimmed.length > 128)
|
|
29
|
-
return null;
|
|
30
|
-
if (!/^[A-Za-z0-9_-]+$/.test(trimmed))
|
|
31
|
-
return null;
|
|
32
|
-
const resolved = resolve(this.dir, `${trimmed}.json`);
|
|
33
|
-
// Ensure the resolved path is still inside the sessions directory
|
|
34
|
-
if (!resolved.startsWith(resolve(this.dir) + '/'))
|
|
35
|
-
return null;
|
|
36
|
-
return resolved;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Save a session's conversation history to disk.
|
|
40
|
-
*/
|
|
41
|
-
save(session, automationName) {
|
|
42
|
-
const file = this.resolvePath(session.id);
|
|
43
|
-
if (!file)
|
|
44
|
-
return;
|
|
45
|
-
this.ensureDir();
|
|
46
|
-
const data = {
|
|
47
|
-
id: session.id,
|
|
48
|
-
appId: session.appId ?? 'local',
|
|
49
|
-
title: session.title,
|
|
50
|
-
conversationHistory: session.conversationHistory ?? session.messages ?? [],
|
|
51
|
-
createdAt: session.createdAt,
|
|
52
|
-
lastAccessedAt: session.lastAccessedAt,
|
|
53
|
-
automationName,
|
|
54
|
-
};
|
|
55
|
-
writeFileSync(file, JSON.stringify(data, null, 2));
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Load a session's persisted data by ID.
|
|
59
|
-
*/
|
|
60
|
-
load(sessionId) {
|
|
61
|
-
const file = this.resolvePath(sessionId);
|
|
62
|
-
if (!file)
|
|
63
|
-
return null;
|
|
64
|
-
if (!existsSync(file))
|
|
65
|
-
return null;
|
|
66
|
-
try {
|
|
67
|
-
const raw = JSON.parse(readFileSync(file, 'utf-8'));
|
|
68
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Trusted local file we wrote
|
|
69
|
-
return raw;
|
|
70
|
-
}
|
|
71
|
-
catch {
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* List all persisted sessions, newest first.
|
|
77
|
-
*/
|
|
78
|
-
list() {
|
|
79
|
-
if (!existsSync(this.dir))
|
|
80
|
-
return [];
|
|
81
|
-
const files = readdirSync(this.dir).filter((f) => f.endsWith('.json'));
|
|
82
|
-
const sessions = [];
|
|
83
|
-
for (const file of files) {
|
|
84
|
-
try {
|
|
85
|
-
const raw = JSON.parse(readFileSync(join(this.dir, file), 'utf-8'));
|
|
86
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Trusted local file we wrote
|
|
87
|
-
const data = raw;
|
|
88
|
-
// Use title if set, otherwise extract first user message
|
|
89
|
-
let summary = 'Untitled';
|
|
90
|
-
if (data.title) {
|
|
91
|
-
summary = data.title;
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
// SessionMessage format: {type: 'user', text: string}
|
|
95
|
-
// Legacy LLMMessage format: {role: 'user', content: string}
|
|
96
|
-
const isUserMsg = (m) => typeof m === 'object' && m !== null && ((('type' in m && m['type'] === 'user' && 'text' in m && typeof m['text'] === 'string')) ||
|
|
97
|
-
(('role' in m && m['role'] === 'user' && 'content' in m && typeof m['content'] === 'string')));
|
|
98
|
-
const firstUserMsg = data.conversationHistory.find(isUserMsg);
|
|
99
|
-
if (firstUserMsg) {
|
|
100
|
-
summary = ('text' in firstUserMsg ? firstUserMsg.text : firstUserMsg.content).slice(0, 80);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
sessions.push({
|
|
104
|
-
id: data.id,
|
|
105
|
-
appId: data.appId,
|
|
106
|
-
title: data.title,
|
|
107
|
-
createdAt: data.createdAt,
|
|
108
|
-
lastAccessedAt: data.lastAccessedAt,
|
|
109
|
-
summary,
|
|
110
|
-
automationName: data.automationName,
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
catch {
|
|
114
|
-
// Skip corrupt files
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
return sessions.sort((a, b) => b.lastAccessedAt - a.lastAccessedAt);
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Update a session's title.
|
|
121
|
-
*/
|
|
122
|
-
updateTitle(sessionId, title) {
|
|
123
|
-
const file = this.resolvePath(sessionId);
|
|
124
|
-
if (!file || !existsSync(file))
|
|
125
|
-
return false;
|
|
126
|
-
const raw = JSON.parse(readFileSync(file, 'utf-8'));
|
|
127
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Trusted local file we wrote
|
|
128
|
-
const data = raw;
|
|
129
|
-
data.title = title;
|
|
130
|
-
writeFileSync(file, JSON.stringify(data, null, 2));
|
|
131
|
-
return true;
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Delete a session file.
|
|
135
|
-
*/
|
|
136
|
-
delete(sessionId) {
|
|
137
|
-
const file = this.resolvePath(sessionId);
|
|
138
|
-
if (!file || !existsSync(file))
|
|
139
|
-
return false;
|
|
140
|
-
unlinkSync(file);
|
|
141
|
-
return true;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Get the most recent session ID.
|
|
145
|
-
*/
|
|
146
|
-
latest() {
|
|
147
|
-
const sessions = this.list();
|
|
148
|
-
return sessions.length > 0 ? sessions[0].id : null;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
//# sourceMappingURL=session-store.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session-store.js","sourceRoot":"","sources":["../../../src/agent/session-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
-
* SPDX-License-Identifier: MIT
|
|
5
|
-
*/
|
|
6
|
-
/** @internal Exported for testing */
|
|
7
|
-
export declare function isAllowedRepoPath(relPath: string): boolean;
|
|
8
|
-
interface ToolResult {
|
|
9
|
-
llmContent: string;
|
|
10
|
-
returnDisplay?: string;
|
|
11
|
-
error?: {
|
|
12
|
-
message: string;
|
|
13
|
-
type: string;
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
export declare function createReadRepoFileTool(repoRoot: string): {
|
|
17
|
-
name: string;
|
|
18
|
-
displayName: string;
|
|
19
|
-
description: string;
|
|
20
|
-
kind: "declarative";
|
|
21
|
-
parameterSchema: Record<string, unknown>;
|
|
22
|
-
readonly isReadOnly: boolean;
|
|
23
|
-
readonly toolAnnotations: undefined;
|
|
24
|
-
readonly schema: {
|
|
25
|
-
name: string;
|
|
26
|
-
description: string;
|
|
27
|
-
parametersJsonSchema: Record<string, unknown>;
|
|
28
|
-
};
|
|
29
|
-
getSchema(): {
|
|
30
|
-
name: string;
|
|
31
|
-
description: string;
|
|
32
|
-
parametersJsonSchema: Record<string, unknown>;
|
|
33
|
-
};
|
|
34
|
-
build(params: Record<string, unknown>): {
|
|
35
|
-
name: string;
|
|
36
|
-
params: Record<string, unknown>;
|
|
37
|
-
execute: () => Promise<ToolResult>;
|
|
38
|
-
};
|
|
39
|
-
silentBuild(params: Record<string, unknown>): {
|
|
40
|
-
name: string;
|
|
41
|
-
params: Record<string, unknown>;
|
|
42
|
-
execute: () => Promise<ToolResult>;
|
|
43
|
-
};
|
|
44
|
-
validateBuildAndExecute(params: Record<string, unknown>): Promise<ToolResult>;
|
|
45
|
-
};
|
|
46
|
-
export declare function createWriteRepoFileTool(repoRoot: string): {
|
|
47
|
-
name: string;
|
|
48
|
-
displayName: string;
|
|
49
|
-
description: string;
|
|
50
|
-
kind: "declarative";
|
|
51
|
-
parameterSchema: Record<string, unknown>;
|
|
52
|
-
readonly isReadOnly: boolean;
|
|
53
|
-
readonly toolAnnotations: undefined;
|
|
54
|
-
readonly schema: {
|
|
55
|
-
name: string;
|
|
56
|
-
description: string;
|
|
57
|
-
parametersJsonSchema: Record<string, unknown>;
|
|
58
|
-
};
|
|
59
|
-
getSchema(): {
|
|
60
|
-
name: string;
|
|
61
|
-
description: string;
|
|
62
|
-
parametersJsonSchema: Record<string, unknown>;
|
|
63
|
-
};
|
|
64
|
-
build(params: Record<string, unknown>): {
|
|
65
|
-
name: string;
|
|
66
|
-
params: Record<string, unknown>;
|
|
67
|
-
execute: () => Promise<ToolResult>;
|
|
68
|
-
};
|
|
69
|
-
silentBuild(params: Record<string, unknown>): {
|
|
70
|
-
name: string;
|
|
71
|
-
params: Record<string, unknown>;
|
|
72
|
-
execute: () => Promise<ToolResult>;
|
|
73
|
-
};
|
|
74
|
-
validateBuildAndExecute(params: Record<string, unknown>): Promise<ToolResult>;
|
|
75
|
-
};
|
|
76
|
-
export declare function createDeleteRepoFileTool(repoRoot: string): {
|
|
77
|
-
name: string;
|
|
78
|
-
displayName: string;
|
|
79
|
-
description: string;
|
|
80
|
-
kind: "declarative";
|
|
81
|
-
parameterSchema: Record<string, unknown>;
|
|
82
|
-
readonly isReadOnly: boolean;
|
|
83
|
-
readonly toolAnnotations: undefined;
|
|
84
|
-
readonly schema: {
|
|
85
|
-
name: string;
|
|
86
|
-
description: string;
|
|
87
|
-
parametersJsonSchema: Record<string, unknown>;
|
|
88
|
-
};
|
|
89
|
-
getSchema(): {
|
|
90
|
-
name: string;
|
|
91
|
-
description: string;
|
|
92
|
-
parametersJsonSchema: Record<string, unknown>;
|
|
93
|
-
};
|
|
94
|
-
build(params: Record<string, unknown>): {
|
|
95
|
-
name: string;
|
|
96
|
-
params: Record<string, unknown>;
|
|
97
|
-
execute: () => Promise<ToolResult>;
|
|
98
|
-
};
|
|
99
|
-
silentBuild(params: Record<string, unknown>): {
|
|
100
|
-
name: string;
|
|
101
|
-
params: Record<string, unknown>;
|
|
102
|
-
execute: () => Promise<ToolResult>;
|
|
103
|
-
};
|
|
104
|
-
validateBuildAndExecute(params: Record<string, unknown>): Promise<ToolResult>;
|
|
105
|
-
};
|
|
106
|
-
export declare function createInternalApiTool(getPort: () => number | null): {
|
|
107
|
-
name: string;
|
|
108
|
-
displayName: string;
|
|
109
|
-
description: string;
|
|
110
|
-
kind: "declarative";
|
|
111
|
-
parameterSchema: Record<string, unknown>;
|
|
112
|
-
readonly isReadOnly: boolean;
|
|
113
|
-
readonly toolAnnotations: undefined;
|
|
114
|
-
readonly schema: {
|
|
115
|
-
name: string;
|
|
116
|
-
description: string;
|
|
117
|
-
parametersJsonSchema: Record<string, unknown>;
|
|
118
|
-
};
|
|
119
|
-
getSchema(): {
|
|
120
|
-
name: string;
|
|
121
|
-
description: string;
|
|
122
|
-
parametersJsonSchema: Record<string, unknown>;
|
|
123
|
-
};
|
|
124
|
-
build(params: Record<string, unknown>): {
|
|
125
|
-
name: string;
|
|
126
|
-
params: Record<string, unknown>;
|
|
127
|
-
execute: () => Promise<ToolResult>;
|
|
128
|
-
};
|
|
129
|
-
silentBuild(params: Record<string, unknown>): {
|
|
130
|
-
name: string;
|
|
131
|
-
params: Record<string, unknown>;
|
|
132
|
-
execute: () => Promise<ToolResult>;
|
|
133
|
-
};
|
|
134
|
-
validateBuildAndExecute(params: Record<string, unknown>): Promise<ToolResult>;
|
|
135
|
-
};
|
|
136
|
-
export {};
|
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
-
* SPDX-License-Identifier: MIT
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Admin-only file tools for reading, writing, and deleting agent config files.
|
|
8
|
-
* These tools are registered on admin sessions only, and only for local repos.
|
|
9
|
-
*
|
|
10
|
-
* Ported from the old agent-runner.ts admin tool implementation.
|
|
11
|
-
*/
|
|
12
|
-
import { readFile, writeFile, unlink, mkdir } from 'node:fs/promises';
|
|
13
|
-
import * as path from 'node:path';
|
|
14
|
-
// ---------------------------------------------------------------------------
|
|
15
|
-
// Path validation
|
|
16
|
-
// ---------------------------------------------------------------------------
|
|
17
|
-
const ALLOWED_REPO_DIRS = [
|
|
18
|
-
'skills/',
|
|
19
|
-
'knowledge/',
|
|
20
|
-
'connections/',
|
|
21
|
-
'stores/',
|
|
22
|
-
'pages/',
|
|
23
|
-
'automations/',
|
|
24
|
-
'evals/',
|
|
25
|
-
'agents/',
|
|
26
|
-
'tools/',
|
|
27
|
-
'amodal_packages/', // installed packages (read-only)
|
|
28
|
-
];
|
|
29
|
-
const BLOCKED_FILENAMES = [
|
|
30
|
-
'.env',
|
|
31
|
-
'amodal.json',
|
|
32
|
-
'package.json',
|
|
33
|
-
'pnpm-lock.yaml',
|
|
34
|
-
'tsconfig.json',
|
|
35
|
-
];
|
|
36
|
-
const READ_ONLY_DIRS = [
|
|
37
|
-
'amodal_packages/',
|
|
38
|
-
];
|
|
39
|
-
/** @internal Exported for testing */
|
|
40
|
-
export function isAllowedRepoPath(relPath) {
|
|
41
|
-
const basename = path.basename(relPath);
|
|
42
|
-
if (BLOCKED_FILENAMES.includes(basename))
|
|
43
|
-
return false;
|
|
44
|
-
return ALLOWED_REPO_DIRS.some((dir) => relPath.startsWith(dir));
|
|
45
|
-
}
|
|
46
|
-
function isReadOnlyPath(relPath) {
|
|
47
|
-
return READ_ONLY_DIRS.some((dir) => relPath.startsWith(dir));
|
|
48
|
-
}
|
|
49
|
-
function validatePath(repoRoot, rawPath) {
|
|
50
|
-
if (!rawPath || rawPath.startsWith('/')) {
|
|
51
|
-
return { error: 'Path must be relative to the repo root (no leading /)' };
|
|
52
|
-
}
|
|
53
|
-
if (rawPath.includes('..')) {
|
|
54
|
-
return { error: 'Path traversal (..) is not allowed' };
|
|
55
|
-
}
|
|
56
|
-
const normalized = path.normalize(rawPath);
|
|
57
|
-
if (!isAllowedRepoPath(normalized)) {
|
|
58
|
-
return { error: `Path "${normalized}" is not in an allowed directory. Allowed: ${ALLOWED_REPO_DIRS.join(', ')}. Blocked files: ${BLOCKED_FILENAMES.join(', ')}` };
|
|
59
|
-
}
|
|
60
|
-
const resolved = path.resolve(repoRoot, normalized);
|
|
61
|
-
if (!resolved.startsWith(repoRoot)) {
|
|
62
|
-
return { error: 'Resolved path escapes the repo directory' };
|
|
63
|
-
}
|
|
64
|
-
return { resolved, relative: normalized };
|
|
65
|
-
}
|
|
66
|
-
// ---------------------------------------------------------------------------
|
|
67
|
-
// Base adapter matching upstream DeclarativeTool interface
|
|
68
|
-
// ---------------------------------------------------------------------------
|
|
69
|
-
function createToolAdapter(opts) {
|
|
70
|
-
return {
|
|
71
|
-
name: opts.name,
|
|
72
|
-
displayName: opts.name,
|
|
73
|
-
description: opts.description,
|
|
74
|
-
kind: 'declarative',
|
|
75
|
-
parameterSchema: opts.parameters,
|
|
76
|
-
get isReadOnly() { return opts.name === 'read_repo_file'; },
|
|
77
|
-
get toolAnnotations() { return undefined; },
|
|
78
|
-
get schema() { return this.getSchema(); },
|
|
79
|
-
getSchema() {
|
|
80
|
-
return {
|
|
81
|
-
name: opts.name,
|
|
82
|
-
description: opts.description,
|
|
83
|
-
parametersJsonSchema: opts.parameters,
|
|
84
|
-
};
|
|
85
|
-
},
|
|
86
|
-
build(params) {
|
|
87
|
-
return {
|
|
88
|
-
name: opts.name,
|
|
89
|
-
params,
|
|
90
|
-
execute: async () => opts.execute(params),
|
|
91
|
-
};
|
|
92
|
-
},
|
|
93
|
-
silentBuild(params) {
|
|
94
|
-
return this.build(params);
|
|
95
|
-
},
|
|
96
|
-
async validateBuildAndExecute(params) {
|
|
97
|
-
return opts.execute(params);
|
|
98
|
-
},
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
// ---------------------------------------------------------------------------
|
|
102
|
-
// Tool factories
|
|
103
|
-
// ---------------------------------------------------------------------------
|
|
104
|
-
export function createReadRepoFileTool(repoRoot) {
|
|
105
|
-
return createToolAdapter({
|
|
106
|
-
name: 'read_repo_file',
|
|
107
|
-
description: 'Read a file from the agent repo. Path is relative to repo root. Allowed directories: skills/, knowledge/, connections/, stores/, pages/, automations/, evals/, agents/, tools/.',
|
|
108
|
-
parameters: {
|
|
109
|
-
type: 'object',
|
|
110
|
-
properties: {
|
|
111
|
-
path: { type: 'string', description: 'File path relative to repo root (e.g. "knowledge/formatting-rules.md")' },
|
|
112
|
-
},
|
|
113
|
-
required: ['path'],
|
|
114
|
-
},
|
|
115
|
-
async execute(params) {
|
|
116
|
-
const rawPath = String(params['path'] ?? '');
|
|
117
|
-
const validation = validatePath(repoRoot, rawPath);
|
|
118
|
-
if ('error' in validation) {
|
|
119
|
-
return { llmContent: `Error: ${validation.error}`, error: { message: validation.error, type: 'VALIDATION_ERROR' } };
|
|
120
|
-
}
|
|
121
|
-
try {
|
|
122
|
-
const content = await readFile(validation.resolved, 'utf-8');
|
|
123
|
-
return { llmContent: content, returnDisplay: `Read ${validation.relative}` };
|
|
124
|
-
}
|
|
125
|
-
catch (err) {
|
|
126
|
-
const isNotFound = err instanceof Error && 'code' in err && (err.code) === 'ENOENT'; // eslint-disable-line @typescript-eslint/no-unsafe-type-assertion -- checking errno;
|
|
127
|
-
const msg = isNotFound ? `File not found: ${validation.relative}` : (err instanceof Error ? err.message : String(err));
|
|
128
|
-
return { llmContent: `Error: ${msg}`, error: { message: msg, type: 'EXECUTION_FAILED' } };
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
export function createWriteRepoFileTool(repoRoot) {
|
|
134
|
-
return createToolAdapter({
|
|
135
|
-
name: 'write_repo_file',
|
|
136
|
-
description: 'Create or update a file in the agent repo. Use this to add skills, knowledge, pages, automations, tools, store schemas, evals, connection docs, or agent overrides. Path is relative to repo root. Allowed directories: skills/, knowledge/, connections/, stores/, pages/, automations/, evals/, agents/, tools/.',
|
|
137
|
-
parameters: {
|
|
138
|
-
type: 'object',
|
|
139
|
-
properties: {
|
|
140
|
-
path: { type: 'string', description: 'File path relative to repo root (e.g. "knowledge/formatting-rules.md")' },
|
|
141
|
-
content: { type: 'string', description: 'Full file content to write' },
|
|
142
|
-
},
|
|
143
|
-
required: ['path', 'content'],
|
|
144
|
-
},
|
|
145
|
-
async execute(params) {
|
|
146
|
-
const rawPath = String(params['path'] ?? '');
|
|
147
|
-
const content = String(params['content'] ?? '');
|
|
148
|
-
const validation = validatePath(repoRoot, rawPath);
|
|
149
|
-
if ('error' in validation) {
|
|
150
|
-
return { llmContent: `Error: ${validation.error}`, error: { message: validation.error, type: 'VALIDATION_ERROR' } };
|
|
151
|
-
}
|
|
152
|
-
if (isReadOnlyPath(validation.relative)) {
|
|
153
|
-
return { llmContent: `Error: ${validation.relative} is read-only (installed package)`, error: { message: 'Cannot write to installed packages', type: 'VALIDATION_ERROR' } };
|
|
154
|
-
}
|
|
155
|
-
if (!content) {
|
|
156
|
-
return { llmContent: 'Error: Content must not be empty', error: { message: 'Content must not be empty', type: 'VALIDATION_ERROR' } };
|
|
157
|
-
}
|
|
158
|
-
try {
|
|
159
|
-
await mkdir(path.dirname(validation.resolved), { recursive: true });
|
|
160
|
-
await writeFile(validation.resolved, content, 'utf-8');
|
|
161
|
-
return { llmContent: `Wrote ${validation.relative} (${String(content.length)} bytes)`, returnDisplay: `Wrote ${validation.relative}` };
|
|
162
|
-
}
|
|
163
|
-
catch (err) {
|
|
164
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
165
|
-
return { llmContent: `Error: ${msg}`, error: { message: msg, type: 'EXECUTION_FAILED' } };
|
|
166
|
-
}
|
|
167
|
-
},
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
export function createDeleteRepoFileTool(repoRoot) {
|
|
171
|
-
return createToolAdapter({
|
|
172
|
-
name: 'delete_repo_file',
|
|
173
|
-
description: 'Delete a file from the agent repo. Always confirm with the user before deleting. Path is relative to repo root. Same directory restrictions as write_repo_file.',
|
|
174
|
-
parameters: {
|
|
175
|
-
type: 'object',
|
|
176
|
-
properties: {
|
|
177
|
-
path: { type: 'string', description: 'File path relative to repo root (e.g. "evals/old-test.md")' },
|
|
178
|
-
},
|
|
179
|
-
required: ['path'],
|
|
180
|
-
},
|
|
181
|
-
async execute(params) {
|
|
182
|
-
const rawPath = String(params['path'] ?? '');
|
|
183
|
-
const validation = validatePath(repoRoot, rawPath);
|
|
184
|
-
if ('error' in validation) {
|
|
185
|
-
return { llmContent: `Error: ${validation.error}`, error: { message: validation.error, type: 'VALIDATION_ERROR' } };
|
|
186
|
-
}
|
|
187
|
-
if (isReadOnlyPath(validation.relative)) {
|
|
188
|
-
return { llmContent: `Error: ${validation.relative} is read-only (installed package)`, error: { message: 'Cannot delete installed packages', type: 'VALIDATION_ERROR' } };
|
|
189
|
-
}
|
|
190
|
-
try {
|
|
191
|
-
await unlink(validation.resolved);
|
|
192
|
-
return { llmContent: `Deleted ${validation.relative}`, returnDisplay: `Deleted ${validation.relative}` };
|
|
193
|
-
}
|
|
194
|
-
catch (err) {
|
|
195
|
-
const isNotFound = err instanceof Error && 'code' in err && (err.code) === 'ENOENT'; // eslint-disable-line @typescript-eslint/no-unsafe-type-assertion -- checking errno;
|
|
196
|
-
const msg = isNotFound ? `File not found: ${validation.relative}` : (err instanceof Error ? err.message : String(err));
|
|
197
|
-
return { llmContent: `Error: ${msg}`, error: { message: msg, type: 'EXECUTION_FAILED' } };
|
|
198
|
-
}
|
|
199
|
-
},
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
// ---------------------------------------------------------------------------
|
|
203
|
-
// Internal API tool — lets admin query the local runtime's own endpoints
|
|
204
|
-
// ---------------------------------------------------------------------------
|
|
205
|
-
export function createInternalApiTool(getPort) {
|
|
206
|
-
return createToolAdapter({
|
|
207
|
-
name: 'internal_api',
|
|
208
|
-
description: `Query the amodal runtime's internal API. Use this to check eval results, connection health, agent context, store data, and automation status. The endpoint is relative to the local server (e.g. "/api/evals/runs" or "/inspect/health"). Only GET requests are supported.`,
|
|
209
|
-
parameters: {
|
|
210
|
-
type: 'object',
|
|
211
|
-
properties: {
|
|
212
|
-
endpoint: { type: 'string', description: 'API path (e.g. "/api/evals/runs", "/inspect/health", "/api/stores")' },
|
|
213
|
-
},
|
|
214
|
-
required: ['endpoint'],
|
|
215
|
-
},
|
|
216
|
-
async execute(params) {
|
|
217
|
-
const endpoint = String(params['endpoint'] ?? '');
|
|
218
|
-
const port = getPort();
|
|
219
|
-
if (!port) {
|
|
220
|
-
return { llmContent: 'Error: Server not ready', error: { message: 'Server not ready', type: 'EXECUTION_FAILED' } };
|
|
221
|
-
}
|
|
222
|
-
try {
|
|
223
|
-
const resp = await fetch(`http://127.0.0.1:${port}${endpoint}`);
|
|
224
|
-
const text = await resp.text();
|
|
225
|
-
try {
|
|
226
|
-
const json = JSON.parse(text);
|
|
227
|
-
return { llmContent: JSON.stringify(json, null, 2), returnDisplay: `GET ${endpoint} → ${resp.status}` };
|
|
228
|
-
}
|
|
229
|
-
catch {
|
|
230
|
-
return { llmContent: text, returnDisplay: `GET ${endpoint} → ${resp.status}` };
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
catch (err) {
|
|
234
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
235
|
-
return { llmContent: `Error: ${msg}`, error: { message: msg, type: 'EXECUTION_FAILED' } };
|
|
236
|
-
}
|
|
237
|
-
},
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
//# sourceMappingURL=admin-file-tools.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"admin-file-tools.js","sourceRoot":"","sources":["../../../src/session/admin-file-tools.ts"],"names":[],"mappings":"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"}
|