agent-world 0.12.3 → 0.15.0
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 +105 -17
- package/dist/cli/commands.d.ts +7 -1
- package/dist/cli/commands.js +27 -10
- package/dist/cli/hitl.d.ts +9 -2
- package/dist/cli/hitl.js +61 -20
- package/dist/cli/index.js +250 -96
- package/dist/cli/system-events.d.ts +27 -0
- package/dist/cli/system-events.js +63 -0
- package/dist/core/activity-tracker.d.ts +38 -2
- package/dist/core/activity-tracker.d.ts.map +1 -1
- package/dist/core/activity-tracker.js +62 -9
- package/dist/core/activity-tracker.js.map +1 -1
- package/dist/core/anthropic-direct.d.ts +2 -0
- package/dist/core/anthropic-direct.d.ts.map +1 -1
- package/dist/core/anthropic-direct.js +43 -1
- package/dist/core/anthropic-direct.js.map +1 -1
- package/dist/core/chat-constants.d.ts +12 -0
- package/dist/core/chat-constants.d.ts.map +1 -1
- package/dist/core/chat-constants.js +5 -0
- package/dist/core/chat-constants.js.map +1 -1
- package/dist/core/create-agent-tool.d.ts +28 -25
- package/dist/core/create-agent-tool.d.ts.map +1 -1
- package/dist/core/create-agent-tool.js +264 -141
- package/dist/core/create-agent-tool.js.map +1 -1
- package/dist/core/events/index.d.ts +5 -2
- package/dist/core/events/index.d.ts.map +1 -1
- package/dist/core/events/index.js +5 -2
- package/dist/core/events/index.js.map +1 -1
- package/dist/core/events/memory-manager.d.ts +26 -1
- package/dist/core/events/memory-manager.d.ts.map +1 -1
- package/dist/core/events/memory-manager.js +877 -72
- package/dist/core/events/memory-manager.js.map +1 -1
- package/dist/core/events/orchestrator.d.ts +8 -0
- package/dist/core/events/orchestrator.d.ts.map +1 -1
- package/dist/core/events/orchestrator.js +214 -38
- package/dist/core/events/orchestrator.js.map +1 -1
- package/dist/core/events/persistence.d.ts +21 -14
- package/dist/core/events/persistence.d.ts.map +1 -1
- package/dist/core/events/persistence.js +100 -61
- package/dist/core/events/persistence.js.map +1 -1
- package/dist/core/events/publishers.d.ts +13 -16
- package/dist/core/events/publishers.d.ts.map +1 -1
- package/dist/core/events/publishers.js +54 -55
- package/dist/core/events/publishers.js.map +1 -1
- package/dist/core/events/subscribers.d.ts +17 -14
- package/dist/core/events/subscribers.d.ts.map +1 -1
- package/dist/core/events/subscribers.js +68 -147
- package/dist/core/events/subscribers.js.map +1 -1
- package/dist/core/events/title-scheduler.d.ts +27 -0
- package/dist/core/events/title-scheduler.d.ts.map +1 -0
- package/dist/core/events/title-scheduler.js +135 -0
- package/dist/core/events/title-scheduler.js.map +1 -0
- package/dist/core/events/tool-bridge-logging.d.ts +4 -1
- package/dist/core/events/tool-bridge-logging.d.ts.map +1 -1
- package/dist/core/events/tool-bridge-logging.js +112 -13
- package/dist/core/events/tool-bridge-logging.js.map +1 -1
- package/dist/core/events-metadata.d.ts.map +1 -1
- package/dist/core/events-metadata.js +8 -4
- package/dist/core/events-metadata.js.map +1 -1
- package/dist/core/export.d.ts +1 -1
- package/dist/core/export.d.ts.map +1 -1
- package/dist/core/export.js +2 -15
- package/dist/core/export.js.map +1 -1
- package/dist/core/feature-path-logging.d.ts +50 -0
- package/dist/core/feature-path-logging.d.ts.map +1 -0
- package/dist/core/feature-path-logging.js +130 -0
- package/dist/core/feature-path-logging.js.map +1 -0
- package/dist/core/file-tools.d.ts +57 -1
- package/dist/core/file-tools.d.ts.map +1 -1
- package/dist/core/file-tools.js +329 -29
- package/dist/core/file-tools.js.map +1 -1
- package/dist/core/google-direct.d.ts +6 -1
- package/dist/core/google-direct.d.ts.map +1 -1
- package/dist/core/google-direct.js +76 -7
- package/dist/core/google-direct.js.map +1 -1
- package/dist/core/heartbeat.d.ts +34 -0
- package/dist/core/heartbeat.d.ts.map +1 -0
- package/dist/core/heartbeat.js +153 -0
- package/dist/core/heartbeat.js.map +1 -0
- package/dist/core/hitl-tool.d.ts +73 -0
- package/dist/core/hitl-tool.d.ts.map +1 -0
- package/dist/core/hitl-tool.js +284 -0
- package/dist/core/hitl-tool.js.map +1 -0
- package/dist/core/hitl.d.ts +85 -8
- package/dist/core/hitl.d.ts.map +1 -1
- package/dist/core/hitl.js +375 -61
- package/dist/core/hitl.js.map +1 -1
- package/dist/core/index.d.ts +12 -7
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +11 -6
- package/dist/core/index.js.map +1 -1
- package/dist/core/llm-manager.d.ts +17 -0
- package/dist/core/llm-manager.d.ts.map +1 -1
- package/dist/core/llm-manager.js +335 -43
- package/dist/core/llm-manager.js.map +1 -1
- package/dist/core/load-skill-tool.d.ts +36 -3
- package/dist/core/load-skill-tool.d.ts.map +1 -1
- package/dist/core/load-skill-tool.js +807 -93
- package/dist/core/load-skill-tool.js.map +1 -1
- package/dist/core/logger.d.ts +14 -0
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +15 -0
- package/dist/core/logger.js.map +1 -1
- package/dist/core/managers.d.ts +41 -52
- package/dist/core/managers.d.ts.map +1 -1
- package/dist/core/managers.js +422 -533
- package/dist/core/managers.js.map +1 -1
- package/dist/core/mcp-server-registry.d.ts +19 -2
- package/dist/core/mcp-server-registry.d.ts.map +1 -1
- package/dist/core/mcp-server-registry.js +168 -12
- package/dist/core/mcp-server-registry.js.map +1 -1
- package/dist/core/message-cutoff.d.ts +29 -0
- package/dist/core/message-cutoff.d.ts.map +1 -0
- package/dist/core/message-cutoff.js +63 -0
- package/dist/core/message-cutoff.js.map +1 -0
- package/dist/core/message-edit-manager.d.ts +54 -0
- package/dist/core/message-edit-manager.d.ts.map +1 -0
- package/dist/core/message-edit-manager.js +602 -0
- package/dist/core/message-edit-manager.js.map +1 -0
- package/dist/core/message-prep.d.ts +2 -0
- package/dist/core/message-prep.d.ts.map +1 -1
- package/dist/core/message-prep.js +39 -12
- package/dist/core/message-prep.js.map +1 -1
- package/dist/core/message-processing-control.d.ts +1 -0
- package/dist/core/message-processing-control.d.ts.map +1 -1
- package/dist/core/message-processing-control.js +23 -6
- package/dist/core/message-processing-control.js.map +1 -1
- package/dist/core/openai-direct.d.ts +9 -3
- package/dist/core/openai-direct.d.ts.map +1 -1
- package/dist/core/openai-direct.js +267 -33
- package/dist/core/openai-direct.js.map +1 -1
- package/dist/core/optional-tracers/opik-runtime.d.ts +32 -0
- package/dist/core/optional-tracers/opik-runtime.d.ts.map +1 -0
- package/dist/core/optional-tracers/opik-runtime.js +141 -0
- package/dist/core/optional-tracers/opik-runtime.js.map +1 -0
- package/dist/core/queue-manager.d.ts +84 -0
- package/dist/core/queue-manager.d.ts.map +1 -0
- package/dist/core/queue-manager.js +814 -0
- package/dist/core/queue-manager.js.map +1 -0
- package/dist/core/reasoning-controls.d.ts +30 -0
- package/dist/core/reasoning-controls.d.ts.map +1 -0
- package/dist/core/reasoning-controls.js +118 -0
- package/dist/core/reasoning-controls.js.map +1 -0
- package/dist/core/reliability-config.d.ts +82 -0
- package/dist/core/reliability-config.d.ts.map +1 -0
- package/dist/core/reliability-config.js +106 -0
- package/dist/core/reliability-config.js.map +1 -0
- package/dist/core/reliability-runtime.d.ts +53 -0
- package/dist/core/reliability-runtime.d.ts.map +1 -0
- package/dist/core/reliability-runtime.js +92 -0
- package/dist/core/reliability-runtime.js.map +1 -0
- package/dist/core/security/guardrails.d.ts +21 -0
- package/dist/core/security/guardrails.d.ts.map +1 -0
- package/dist/core/security/guardrails.js +111 -0
- package/dist/core/security/guardrails.js.map +1 -0
- package/dist/core/send-message-tool.d.ts +79 -0
- package/dist/core/send-message-tool.d.ts.map +1 -0
- package/dist/core/send-message-tool.js +222 -0
- package/dist/core/send-message-tool.js.map +1 -0
- package/dist/core/shell-cmd-tool.d.ts +82 -1
- package/dist/core/shell-cmd-tool.d.ts.map +1 -1
- package/dist/core/shell-cmd-tool.js +854 -42
- package/dist/core/shell-cmd-tool.js.map +1 -1
- package/dist/core/skill-registry.d.ts +2 -0
- package/dist/core/skill-registry.d.ts.map +1 -1
- package/dist/core/skill-registry.js +52 -2
- package/dist/core/skill-registry.js.map +1 -1
- package/dist/core/storage/eventStorage/fileEventStorage.d.ts +5 -0
- package/dist/core/storage/eventStorage/fileEventStorage.d.ts.map +1 -1
- package/dist/core/storage/eventStorage/fileEventStorage.js +61 -0
- package/dist/core/storage/eventStorage/fileEventStorage.js.map +1 -1
- package/dist/core/storage/eventStorage/memoryEventStorage.d.ts +5 -0
- package/dist/core/storage/eventStorage/memoryEventStorage.d.ts.map +1 -1
- package/dist/core/storage/eventStorage/memoryEventStorage.js +34 -0
- package/dist/core/storage/eventStorage/memoryEventStorage.js.map +1 -1
- package/dist/core/storage/eventStorage/sqliteEventStorage.d.ts +1 -0
- package/dist/core/storage/eventStorage/sqliteEventStorage.d.ts.map +1 -1
- package/dist/core/storage/eventStorage/sqliteEventStorage.js +19 -2
- package/dist/core/storage/eventStorage/sqliteEventStorage.js.map +1 -1
- package/dist/core/storage/eventStorage/types.d.ts +6 -0
- package/dist/core/storage/eventStorage/types.d.ts.map +1 -1
- package/dist/core/storage/eventStorage/types.js +1 -0
- package/dist/core/storage/eventStorage/types.js.map +1 -1
- package/dist/core/storage/eventStorage/validation.d.ts.map +1 -1
- package/dist/core/storage/eventStorage/validation.js +2 -1
- package/dist/core/storage/eventStorage/validation.js.map +1 -1
- package/dist/core/storage/github-world-import.d.ts +84 -0
- package/dist/core/storage/github-world-import.d.ts.map +1 -0
- package/dist/core/storage/github-world-import.js +365 -0
- package/dist/core/storage/github-world-import.js.map +1 -0
- package/dist/core/storage/memory-storage.d.ts +19 -8
- package/dist/core/storage/memory-storage.d.ts.map +1 -1
- package/dist/core/storage/memory-storage.js +147 -49
- package/dist/core/storage/memory-storage.js.map +1 -1
- package/dist/core/storage/queue-storage.d.ts +1 -0
- package/dist/core/storage/queue-storage.d.ts.map +1 -1
- package/dist/core/storage/queue-storage.js +3 -2
- package/dist/core/storage/queue-storage.js.map +1 -1
- package/dist/core/storage/sqlite-storage.d.ts +14 -9
- package/dist/core/storage/sqlite-storage.d.ts.map +1 -1
- package/dist/core/storage/sqlite-storage.js +131 -154
- package/dist/core/storage/sqlite-storage.js.map +1 -1
- package/dist/core/storage/storage-factory.d.ts +3 -0
- package/dist/core/storage/storage-factory.d.ts.map +1 -1
- package/dist/core/storage/storage-factory.js +175 -89
- package/dist/core/storage/storage-factory.js.map +1 -1
- package/dist/core/storage/world-storage.d.ts +1 -1
- package/dist/core/storage/world-storage.d.ts.map +1 -1
- package/dist/core/storage/world-storage.js +5 -1
- package/dist/core/storage/world-storage.js.map +1 -1
- package/dist/core/storage-init.d.ts +11 -0
- package/dist/core/storage-init.d.ts.map +1 -0
- package/dist/core/storage-init.js +122 -0
- package/dist/core/storage-init.js.map +1 -0
- package/dist/core/subscription.d.ts +8 -1
- package/dist/core/subscription.d.ts.map +1 -1
- package/dist/core/subscription.js +130 -23
- package/dist/core/subscription.js.map +1 -1
- package/dist/core/tool-approval.d.ts +45 -0
- package/dist/core/tool-approval.d.ts.map +1 -0
- package/dist/core/tool-approval.js +223 -0
- package/dist/core/tool-approval.js.map +1 -0
- package/dist/core/tool-execution-envelope.d.ts +87 -0
- package/dist/core/tool-execution-envelope.d.ts.map +1 -0
- package/dist/core/tool-execution-envelope.js +168 -0
- package/dist/core/tool-execution-envelope.js.map +1 -0
- package/dist/core/tool-utils.d.ts +9 -2
- package/dist/core/tool-utils.d.ts.map +1 -1
- package/dist/core/tool-utils.js +122 -28
- package/dist/core/tool-utils.js.map +1 -1
- package/dist/core/types.d.ts +69 -36
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +3 -2
- package/dist/core/types.js.map +1 -1
- package/dist/core/utils.d.ts +16 -0
- package/dist/core/utils.d.ts.map +1 -1
- package/dist/core/utils.js +99 -24
- package/dist/core/utils.js.map +1 -1
- package/dist/core/web-fetch-tool.d.ts +72 -0
- package/dist/core/web-fetch-tool.d.ts.map +1 -0
- package/dist/core/web-fetch-tool.js +491 -0
- package/dist/core/web-fetch-tool.js.map +1 -0
- package/dist/core/world-registry.d.ts +84 -0
- package/dist/core/world-registry.d.ts.map +1 -0
- package/dist/core/world-registry.js +247 -0
- package/dist/core/world-registry.js.map +1 -0
- package/dist/public/assets/index-Be-1xtV-.js +104 -0
- package/dist/public/assets/index-tsDdiXDU.css +1 -0
- package/dist/public/index.html +2 -2
- package/dist/public/mcp-sandbox-proxy.html +148 -0
- package/dist/server/api.js +288 -58
- package/dist/server/error-response.d.ts +27 -0
- package/dist/server/error-response.js +77 -0
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.js +6 -2
- package/dist/server/sse-handler.d.ts +13 -2
- package/dist/server/sse-handler.js +194 -26
- package/migrations/0015_add_message_queue.sql +36 -0
- package/migrations/0016_add_world_heartbeat.sql +13 -0
- package/migrations/0017_add_title_provenance.sql +7 -0
- package/package.json +31 -10
- package/dist/public/assets/index-BO20H4xt.js +0 -96
- package/dist/public/assets/index-ETY7W5_S.css +0 -1
package/dist/server/index.d.ts
CHANGED
|
@@ -15,15 +15,16 @@
|
|
|
15
15
|
* Endpoints: /health + API routes from ./api.ts
|
|
16
16
|
*
|
|
17
17
|
* Recent Changes:
|
|
18
|
+
* - 2026-02-26: Added specific global API error mapping for oversized JSON payloads, invalid JSON bodies, and readonly database errors to avoid generic INTERNAL_ERROR responses.
|
|
18
19
|
* - 2026-02-08: Fixed auto-run detection to only trigger on direct execution
|
|
19
20
|
* - 2026-02-08: Made browser auto-open configurable via AGENT_WORLD_AUTO_OPEN env var
|
|
20
21
|
* - 2026-02-08: Prevented duplicate process signal handler registration using WeakSet
|
|
21
22
|
* - 2026-02-08: Added shutdown guard to prevent race conditions during graceful shutdown
|
|
22
23
|
*/
|
|
23
24
|
import { Server } from 'http';
|
|
25
|
+
export { getErrorResponse } from './error-response.js';
|
|
24
26
|
type StartWebServerOptions = {
|
|
25
27
|
openBrowser?: boolean;
|
|
26
28
|
registerProcessHandlers?: boolean;
|
|
27
29
|
};
|
|
28
30
|
export declare function startWebServer(port?: number, host?: string, options?: StartWebServerOptions): Promise<Server>;
|
|
29
|
-
export {};
|
package/dist/server/index.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* Endpoints: /health + API routes from ./api.ts
|
|
16
16
|
*
|
|
17
17
|
* Recent Changes:
|
|
18
|
+
* - 2026-02-26: Added specific global API error mapping for oversized JSON payloads, invalid JSON bodies, and readonly database errors to avoid generic INTERNAL_ERROR responses.
|
|
18
19
|
* - 2026-02-08: Fixed auto-run detection to only trigger on direct execution
|
|
19
20
|
* - 2026-02-08: Made browser auto-open configurable via AGENT_WORLD_AUTO_OPEN env var
|
|
20
21
|
* - 2026-02-08: Prevented duplicate process signal handler registration using WeakSet
|
|
@@ -32,11 +33,13 @@ import path from 'path';
|
|
|
32
33
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
33
34
|
import apiRouter from './api.js';
|
|
34
35
|
import { initializeMCPRegistry, shutdownAllMCPServers } from '../core/mcp-server-registry.js';
|
|
36
|
+
import { getErrorResponse } from './error-response.js';
|
|
37
|
+
export { getErrorResponse } from './error-response.js';
|
|
35
38
|
// ES modules setup
|
|
36
39
|
const __filename = fileURLToPath(import.meta.url);
|
|
37
40
|
const __dirname = path.dirname(__filename);
|
|
38
41
|
// Configuration
|
|
39
|
-
const PORT = Number(process.env.PORT) ||
|
|
42
|
+
const PORT = Number(process.env.PORT) || 3000;
|
|
40
43
|
const HOST = process.env.HOST || '127.0.0.1';
|
|
41
44
|
// Create server logger after logger auto-initialization
|
|
42
45
|
const serverLogger = createCategoryLogger('server');
|
|
@@ -117,7 +120,8 @@ app.get('*', (req, res) => {
|
|
|
117
120
|
// Error handling middleware
|
|
118
121
|
app.use((error, req, res, next) => {
|
|
119
122
|
console.error('Unhandled error:', error);
|
|
120
|
-
|
|
123
|
+
const { status, payload } = getErrorResponse(error);
|
|
124
|
+
res.status(status).json(payload);
|
|
121
125
|
});
|
|
122
126
|
// 404 handler
|
|
123
127
|
app.use((req, res) => {
|
|
@@ -5,10 +5,9 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Features:
|
|
7
7
|
* - Sets up SSE response headers and connection
|
|
8
|
-
* - Wires world event listeners (MESSAGE, SSE, SYSTEM, WORLD
|
|
8
|
+
* - Wires world event listeners (MESSAGE, SSE, SYSTEM, WORLD)
|
|
9
9
|
* - Handles world activity state tracking (response-start, idle)
|
|
10
10
|
* - Forwards tool events (tool-start, tool-result, tool-error, tool-progress) as SSE events
|
|
11
|
-
* - Forwards CRUD events so frontends can refresh world/agent state in real time
|
|
12
11
|
* - Automatic stream completion when world becomes idle
|
|
13
12
|
* - Timeout fallback (60s) if world never becomes idle
|
|
14
13
|
* - Proper cleanup on client disconnect or stream end
|
|
@@ -30,6 +29,14 @@
|
|
|
30
29
|
* ```
|
|
31
30
|
*
|
|
32
31
|
* Created: 2025-11-10 - Extracted from api.ts for reusability
|
|
32
|
+
* Updated: 2026-03-01 - Skip synthesis for 'edit' context to prevent duplicate "From human" messages after message edits.
|
|
33
|
+
* Updated: 2026-03-11 - Exposed a readiness promise so chat/edit dispatch waits until SSE listeners are attached, preventing the web client from missing the initial user-message echo.
|
|
34
|
+
* Updated: 2026-03-11 - Replaced optional-call resolution of the readiness promise with an explicit helper to satisfy
|
|
35
|
+
* strict TypeScript control-flow analysis in the build config.
|
|
36
|
+
* Updated: 2026-02-27 - Scoped realtime log forwarding by world/chat to prevent cross-chat log leakage in chat-scoped streams.
|
|
37
|
+
* Updated: 2026-02-26 - Added realtime log-stream forwarding (`type: 'log'`) to SSE clients to align web error visibility with Electron.
|
|
38
|
+
* Updated: 2026-02-20 - Removed stale legacy event-channel SSE forwarding from this handler.
|
|
39
|
+
* Updated: 2026-02-21 - Refresh fallback timeout on shell assistant-stream SSE activity (`start`/`chunk`/`end` + `toolName='shell_cmd'`) as well as legacy `tool-stream`.
|
|
33
40
|
* Updated: 2026-02-11 - Extended fallback timeout on tool-stream events to prevent premature timeout
|
|
34
41
|
* Updated: 2026-02-08 - Removed manual tool-intervention SSE commentary and kept generic tool_call forwarding
|
|
35
42
|
* Updated: 2025-11-10 - Added tool event forwarding to SSE channel
|
|
@@ -37,6 +44,10 @@
|
|
|
37
44
|
import { Request, Response } from 'express';
|
|
38
45
|
import { World } from '../core/index.js';
|
|
39
46
|
export interface SSEHandler {
|
|
47
|
+
/**
|
|
48
|
+
* Resolves once synthesis has finished and live listeners are attached.
|
|
49
|
+
*/
|
|
50
|
+
ready: Promise<void>;
|
|
40
51
|
/**
|
|
41
52
|
* Send a Server-Sent Event to the client
|
|
42
53
|
* @param data - Data object to send (will be JSON stringified)
|
|
@@ -5,10 +5,9 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Features:
|
|
7
7
|
* - Sets up SSE response headers and connection
|
|
8
|
-
* - Wires world event listeners (MESSAGE, SSE, SYSTEM, WORLD
|
|
8
|
+
* - Wires world event listeners (MESSAGE, SSE, SYSTEM, WORLD)
|
|
9
9
|
* - Handles world activity state tracking (response-start, idle)
|
|
10
10
|
* - Forwards tool events (tool-start, tool-result, tool-error, tool-progress) as SSE events
|
|
11
|
-
* - Forwards CRUD events so frontends can refresh world/agent state in real time
|
|
12
11
|
* - Automatic stream completion when world becomes idle
|
|
13
12
|
* - Timeout fallback (60s) if world never becomes idle
|
|
14
13
|
* - Proper cleanup on client disconnect or stream end
|
|
@@ -30,14 +29,23 @@
|
|
|
30
29
|
* ```
|
|
31
30
|
*
|
|
32
31
|
* Created: 2025-11-10 - Extracted from api.ts for reusability
|
|
32
|
+
* Updated: 2026-03-01 - Skip synthesis for 'edit' context to prevent duplicate "From human" messages after message edits.
|
|
33
|
+
* Updated: 2026-03-11 - Exposed a readiness promise so chat/edit dispatch waits until SSE listeners are attached, preventing the web client from missing the initial user-message echo.
|
|
34
|
+
* Updated: 2026-03-11 - Replaced optional-call resolution of the readiness promise with an explicit helper to satisfy
|
|
35
|
+
* strict TypeScript control-flow analysis in the build config.
|
|
36
|
+
* Updated: 2026-02-27 - Scoped realtime log forwarding by world/chat to prevent cross-chat log leakage in chat-scoped streams.
|
|
37
|
+
* Updated: 2026-02-26 - Added realtime log-stream forwarding (`type: 'log'`) to SSE clients to align web error visibility with Electron.
|
|
38
|
+
* Updated: 2026-02-20 - Removed stale legacy event-channel SSE forwarding from this handler.
|
|
39
|
+
* Updated: 2026-02-21 - Refresh fallback timeout on shell assistant-stream SSE activity (`start`/`chunk`/`end` + `toolName='shell_cmd'`) as well as legacy `tool-stream`.
|
|
33
40
|
* Updated: 2026-02-11 - Extended fallback timeout on tool-stream events to prevent premature timeout
|
|
34
41
|
* Updated: 2026-02-08 - Removed manual tool-intervention SSE commentary and kept generic tool_call forwarding
|
|
35
42
|
* Updated: 2025-11-10 - Added tool event forwarding to SSE channel
|
|
36
43
|
*/
|
|
37
|
-
import { createCategoryLogger, EventType } from '../core/index.js';
|
|
44
|
+
import { addLogStreamCallback, createCategoryLogger, EventType, getMemory, listPendingHitlPromptEventsFromMessages } from '../core/index.js';
|
|
38
45
|
const loggerStream = createCategoryLogger('api.stream');
|
|
39
46
|
// Timeout constants for streaming (fallback only)
|
|
40
47
|
const STREAM_TIMEOUT_NO_EVENTS_MS = 15000;
|
|
48
|
+
const STREAM_IDLE_CLOSE_DELAY_MS = 2000;
|
|
41
49
|
/**
|
|
42
50
|
* Create and configure an SSE handler for streaming world events
|
|
43
51
|
*
|
|
@@ -55,6 +63,7 @@ export function createSSEHandler(req, res, world, context = 'sse', scopedChatId)
|
|
|
55
63
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
56
64
|
res.setHeader('Access-Control-Allow-Headers', 'Cache-Control');
|
|
57
65
|
let timeoutTimer;
|
|
66
|
+
let idleCloseTimer;
|
|
58
67
|
let hasReceivedEvents = false;
|
|
59
68
|
let isResponseEnded = false;
|
|
60
69
|
let lastEventTime = Date.now();
|
|
@@ -89,6 +98,10 @@ export function createSSEHandler(req, res, world, context = 'sse', scopedChatId)
|
|
|
89
98
|
clearTimeout(timeoutTimer);
|
|
90
99
|
timeoutTimer = undefined;
|
|
91
100
|
}
|
|
101
|
+
if (idleCloseTimer) {
|
|
102
|
+
clearTimeout(idleCloseTimer);
|
|
103
|
+
idleCloseTimer = undefined;
|
|
104
|
+
}
|
|
92
105
|
loggerStream.debug(`[${context}] Ending SSE response. Stats: events=${hasReceivedEvents}, awaitingWorldIdle=${awaitingWorldIdle}`);
|
|
93
106
|
try {
|
|
94
107
|
if (!res.destroyed) {
|
|
@@ -123,7 +136,22 @@ export function createSSEHandler(req, res, world, context = 'sse', scopedChatId)
|
|
|
123
136
|
const normalizedEventChatId = eventChatId === null ? null : String(eventChatId);
|
|
124
137
|
return normalizedEventChatId === normalizedScopedChatId;
|
|
125
138
|
};
|
|
126
|
-
//
|
|
139
|
+
// Track already-sent ids to avoid double-emitting synthesized -> live events
|
|
140
|
+
const sentMessageIds = new Set();
|
|
141
|
+
const sentToolCallIds = new Set();
|
|
142
|
+
let resolveReady = null;
|
|
143
|
+
const ready = new Promise((resolve) => {
|
|
144
|
+
resolveReady = resolve;
|
|
145
|
+
});
|
|
146
|
+
const markReady = () => {
|
|
147
|
+
if (!resolveReady) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const resolve = resolveReady;
|
|
151
|
+
resolveReady = null;
|
|
152
|
+
resolve();
|
|
153
|
+
};
|
|
154
|
+
// Attach direct listeners to world.eventEmitter (defined inside attach to allow synth-before-attach)
|
|
127
155
|
const worldListener = (eventData) => {
|
|
128
156
|
// Check if this is a tool event (tool-start, tool-result, tool-error, tool-progress)
|
|
129
157
|
const isToolEvent = eventData?.type && ['tool-start', 'tool-result', 'tool-error', 'tool-progress'].includes(eventData.type);
|
|
@@ -146,6 +174,10 @@ export function createSSEHandler(req, res, world, context = 'sse', scopedChatId)
|
|
|
146
174
|
}
|
|
147
175
|
// Handle world activity events for stream completion
|
|
148
176
|
if (eventData?.type === 'response-start') {
|
|
177
|
+
if (idleCloseTimer) {
|
|
178
|
+
clearTimeout(idleCloseTimer);
|
|
179
|
+
idleCloseTimer = undefined;
|
|
180
|
+
}
|
|
149
181
|
awaitingWorldIdle = true;
|
|
150
182
|
loggerStream.debug(`[${context}] World processing started`, {
|
|
151
183
|
activityId: eventData.activityId,
|
|
@@ -156,20 +188,24 @@ export function createSSEHandler(req, res, world, context = 'sse', scopedChatId)
|
|
|
156
188
|
loggerStream.debug(`[${context}] World idle detected, ending stream`, {
|
|
157
189
|
activityId: eventData.activityId
|
|
158
190
|
});
|
|
159
|
-
// Stream all pending events, then end
|
|
160
191
|
sendSSE({ type: EventType.WORLD, data: eventData });
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
192
|
+
awaitingWorldIdle = false;
|
|
193
|
+
if (idleCloseTimer) {
|
|
194
|
+
clearTimeout(idleCloseTimer);
|
|
195
|
+
}
|
|
196
|
+
idleCloseTimer = setTimeout(() => {
|
|
197
|
+
// If no new response-start arrived during the grace window,
|
|
198
|
+
// treat this idle as final and close the stream.
|
|
199
|
+
if (!awaitingWorldIdle) {
|
|
200
|
+
endResponse();
|
|
201
|
+
}
|
|
202
|
+
}, STREAM_IDLE_CLOSE_DELAY_MS);
|
|
165
203
|
return;
|
|
166
204
|
}
|
|
167
205
|
if (isChatEventInScope(eventData?.chatId, true)) {
|
|
168
206
|
sendSSE({ type: EventType.WORLD, data: eventData });
|
|
169
207
|
}
|
|
170
208
|
};
|
|
171
|
-
world.eventEmitter.on(EventType.WORLD, worldListener);
|
|
172
|
-
listeners.set(EventType.WORLD, worldListener);
|
|
173
209
|
const messageListener = (eventData) => {
|
|
174
210
|
if (!isChatEventInScope(eventData?.chatId, false)) {
|
|
175
211
|
return;
|
|
@@ -186,46 +222,177 @@ export function createSSEHandler(req, res, world, context = 'sse', scopedChatId)
|
|
|
186
222
|
replyToMessageId: eventData.replyToMessageId,
|
|
187
223
|
createdAt: eventData.timestamp || new Date().toISOString(),
|
|
188
224
|
role: eventData.role,
|
|
189
|
-
tool_calls: eventData.tool_calls
|
|
225
|
+
tool_calls: eventData.tool_calls,
|
|
226
|
+
tool_call_id: eventData.tool_call_id
|
|
190
227
|
};
|
|
191
228
|
sendSSE({ type: EventType.MESSAGE, data: messageData });
|
|
192
229
|
};
|
|
193
|
-
world.eventEmitter.on(EventType.MESSAGE, messageListener);
|
|
194
|
-
listeners.set(EventType.MESSAGE, messageListener);
|
|
195
230
|
const sseListener = (eventData) => {
|
|
196
231
|
if (!isChatEventInScope(eventData?.chatId, false)) {
|
|
197
232
|
return;
|
|
198
233
|
}
|
|
199
|
-
// Extend fallback timeout
|
|
200
|
-
|
|
234
|
+
// Extend fallback timeout for long-running shell stream activity.
|
|
235
|
+
const isLegacyToolStream = eventData.type === 'tool-stream';
|
|
236
|
+
const isShellAssistantStream = eventData.toolName === 'shell_cmd' &&
|
|
237
|
+
(eventData.type === 'start' || eventData.type === 'chunk' || eventData.type === 'end');
|
|
238
|
+
if (isLegacyToolStream || isShellAssistantStream) {
|
|
201
239
|
startTimeoutFallback();
|
|
202
240
|
}
|
|
203
241
|
sendSSE({ type: EventType.SSE, data: eventData });
|
|
204
242
|
};
|
|
205
|
-
world.eventEmitter.on(EventType.SSE, sseListener);
|
|
206
|
-
listeners.set(EventType.SSE, sseListener);
|
|
207
243
|
const systemListener = (eventData) => {
|
|
208
|
-
if (!isChatEventInScope(eventData?.chatId,
|
|
244
|
+
if (!isChatEventInScope(eventData?.chatId, false)) {
|
|
209
245
|
return;
|
|
210
246
|
}
|
|
211
247
|
sendSSE({ type: EventType.SYSTEM, data: eventData });
|
|
212
248
|
};
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const
|
|
216
|
-
|
|
249
|
+
// Mirror Electron's global log forwarding pattern:
|
|
250
|
+
// stream backend logger events as SSE `type: 'log'` payloads during the active request.
|
|
251
|
+
const logListener = (logEvent) => {
|
|
252
|
+
const logData = logEvent?.data && typeof logEvent.data === 'object' ? logEvent.data : null;
|
|
253
|
+
const logWorldId = (typeof logEvent?.worldId === 'string' && logEvent.worldId.trim()) ? logEvent.worldId.trim()
|
|
254
|
+
: (typeof logData?.worldId === 'string' && String(logData.worldId).trim())
|
|
255
|
+
? String(logData.worldId).trim()
|
|
256
|
+
: undefined;
|
|
257
|
+
if (logWorldId && logWorldId !== world.id) {
|
|
217
258
|
return;
|
|
218
259
|
}
|
|
219
|
-
|
|
260
|
+
const logChatId = (typeof logEvent?.chatId === 'string' && logEvent.chatId.trim()) ? logEvent.chatId.trim()
|
|
261
|
+
: (logEvent?.chatId === null ? null
|
|
262
|
+
: (typeof logData?.chatId === 'string' && logData.chatId.trim()) ? logData.chatId.trim()
|
|
263
|
+
: (logData?.chatId === null ? null : undefined));
|
|
264
|
+
if (!isChatEventInScope(logChatId, false)) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
sendSSE({
|
|
268
|
+
type: EventType.SSE,
|
|
269
|
+
data: {
|
|
270
|
+
type: 'log',
|
|
271
|
+
chatId: logChatId,
|
|
272
|
+
messageId: logEvent?.messageId || `log-${Date.now()}`,
|
|
273
|
+
logEvent: {
|
|
274
|
+
level: logEvent?.level || 'info',
|
|
275
|
+
category: logEvent?.category || 'unknown',
|
|
276
|
+
message: logEvent?.message || '',
|
|
277
|
+
timestamp: logEvent?.timestamp || new Date().toISOString(),
|
|
278
|
+
data: logData ?? null,
|
|
279
|
+
messageId: logEvent?.messageId || `log-${Date.now()}`,
|
|
280
|
+
chatId: logChatId
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
});
|
|
220
284
|
};
|
|
221
|
-
|
|
222
|
-
listeners
|
|
285
|
+
let unsubscribeLogStream = null;
|
|
286
|
+
// NOTE: listeners are attached after an initial synthesis step below to avoid race
|
|
287
|
+
// where core resume emits events before the client has subscribed.
|
|
288
|
+
async function attachListeners() {
|
|
289
|
+
world.eventEmitter.on(EventType.WORLD, worldListener);
|
|
290
|
+
listeners.set(EventType.WORLD, worldListener);
|
|
291
|
+
world.eventEmitter.on(EventType.MESSAGE, messageListener);
|
|
292
|
+
listeners.set(EventType.MESSAGE, messageListener);
|
|
293
|
+
world.eventEmitter.on(EventType.SSE, sseListener);
|
|
294
|
+
listeners.set(EventType.SSE, sseListener);
|
|
295
|
+
world.eventEmitter.on(EventType.SYSTEM, systemListener);
|
|
296
|
+
listeners.set(EventType.SYSTEM, systemListener);
|
|
297
|
+
unsubscribeLogStream = addLogStreamCallback(logListener);
|
|
298
|
+
}
|
|
299
|
+
// Synthesis: use persisted memory as the source of truth to restore UI state
|
|
300
|
+
(async () => {
|
|
301
|
+
try {
|
|
302
|
+
// Skip synthesis for edit operations: the edit flow removes old messages and immediately
|
|
303
|
+
// publishes a fresh user message via publishMessage, so synthesizing the pre-edit last
|
|
304
|
+
// user message would cause a duplicate "From human" message in the UI.
|
|
305
|
+
if (context === 'edit') {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (!normalizedScopedChatId) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
// Try to read canonical chat memory using public core helper
|
|
312
|
+
const memory = await getMemory(world.id, normalizedScopedChatId);
|
|
313
|
+
if (Array.isArray(memory) && memory.length > 0) {
|
|
314
|
+
// Send the most recent user message if the last message is a user message
|
|
315
|
+
const lastMessage = memory[memory.length - 1];
|
|
316
|
+
if (lastMessage && lastMessage.messageId) {
|
|
317
|
+
// Mark as sent to avoid double-emitting when live listeners arrive
|
|
318
|
+
sentMessageIds.add(String(lastMessage.messageId));
|
|
319
|
+
if (lastMessage.role === 'user') {
|
|
320
|
+
const messageData = {
|
|
321
|
+
type: 'message',
|
|
322
|
+
sender: lastMessage.sender,
|
|
323
|
+
content: lastMessage.content,
|
|
324
|
+
messageId: lastMessage.messageId,
|
|
325
|
+
chatId: lastMessage.chatId,
|
|
326
|
+
replyToMessageId: lastMessage.replyToMessageId,
|
|
327
|
+
createdAt: lastMessage.createdAt || new Date().toISOString(),
|
|
328
|
+
role: lastMessage.role,
|
|
329
|
+
tool_calls: lastMessage.tool_calls
|
|
330
|
+
};
|
|
331
|
+
sendSSE({ type: EventType.MESSAGE, data: messageData });
|
|
332
|
+
}
|
|
333
|
+
else if (lastMessage.role === 'assistant' && Array.isArray(lastMessage.tool_calls) && lastMessage.tool_calls.length > 0) {
|
|
334
|
+
// Detect unresolved tool calls by scanning persisted memory for completed tool messages
|
|
335
|
+
const completedToolCallIds = new Set();
|
|
336
|
+
for (const m of memory) {
|
|
337
|
+
if (m.role === 'tool' && typeof m.tool_call_id === 'string') {
|
|
338
|
+
completedToolCallIds.add(String(m.tool_call_id));
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
for (const tc of lastMessage.tool_calls) {
|
|
342
|
+
const toolCallId = String(tc?.id || '').trim();
|
|
343
|
+
const toolName = String(tc?.function?.name || '').trim();
|
|
344
|
+
if (!toolCallId || completedToolCallIds.has(toolCallId))
|
|
345
|
+
continue;
|
|
346
|
+
// Synthesize a tool-start event so the UI can show pending work / HITL
|
|
347
|
+
sentToolCallIds.add(toolCallId);
|
|
348
|
+
sendSSE({
|
|
349
|
+
type: EventType.SSE,
|
|
350
|
+
data: {
|
|
351
|
+
type: 'tool-start',
|
|
352
|
+
messageId: toolCallId,
|
|
353
|
+
agentName: lastMessage.agentId || undefined,
|
|
354
|
+
chatId: lastMessage.chatId,
|
|
355
|
+
toolExecution: {
|
|
356
|
+
toolName,
|
|
357
|
+
toolCallId,
|
|
358
|
+
input: tc?.function?.arguments || {}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
// Also synthesize any pending HITL prompts derived from memory
|
|
365
|
+
try {
|
|
366
|
+
const pendingHitl = listPendingHitlPromptEventsFromMessages(memory || [], normalizedScopedChatId === undefined ? null : normalizedScopedChatId);
|
|
367
|
+
for (const h of pendingHitl) {
|
|
368
|
+
sendSSE({ type: EventType.SYSTEM, data: h });
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
catch (hitlErr) {
|
|
372
|
+
loggerStream.debug(`[${context}] failed to synthesize HITL prompts:`, hitlErr);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
catch (error) {
|
|
378
|
+
loggerStream.debug(`[${context}] failed to synthesize persisted state:`, error);
|
|
379
|
+
}
|
|
380
|
+
finally {
|
|
381
|
+
// Attach live listeners after synthesis to avoid race where resume emits before client subscribed
|
|
382
|
+
attachListeners();
|
|
383
|
+
markReady();
|
|
384
|
+
}
|
|
385
|
+
})();
|
|
223
386
|
// Cleanup function to remove all listeners
|
|
224
387
|
const cleanupListeners = () => {
|
|
225
388
|
for (const [eventType, listener] of listeners.entries()) {
|
|
226
389
|
world.eventEmitter.removeListener(eventType, listener);
|
|
227
390
|
}
|
|
228
391
|
listeners.clear();
|
|
392
|
+
if (unsubscribeLogStream) {
|
|
393
|
+
unsubscribeLogStream();
|
|
394
|
+
unsubscribeLogStream = null;
|
|
395
|
+
}
|
|
229
396
|
};
|
|
230
397
|
// Handle client disconnect
|
|
231
398
|
req.on('close', () => {
|
|
@@ -236,6 +403,7 @@ export function createSSEHandler(req, res, world, context = 'sse', scopedChatId)
|
|
|
236
403
|
// Start the fallback timeout
|
|
237
404
|
startTimeoutFallback();
|
|
238
405
|
return {
|
|
406
|
+
ready,
|
|
239
407
|
sendSSE,
|
|
240
408
|
endResponse,
|
|
241
409
|
isEnded: () => isResponseEnded
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
-- Migration: Create message_queue table for user message queue feature
|
|
2
|
+
-- Version: 15
|
|
3
|
+
-- Date: 2026-03-01
|
|
4
|
+
--
|
|
5
|
+
-- Creates a dedicated message_queue table to persist user messages that are
|
|
6
|
+
-- queued for sequential processing. A separate table (rather than an
|
|
7
|
+
-- agent_memory status column) is used to avoid the agent_id FK constraint
|
|
8
|
+
-- on agent_memory, since queued messages are not yet associated with a
|
|
9
|
+
-- specific agent.
|
|
10
|
+
--
|
|
11
|
+
-- Status lifecycle:
|
|
12
|
+
-- queued -> sending -> (row deleted when processed successfully)
|
|
13
|
+
-- queued -> cancelled (when user stops/clears queue)
|
|
14
|
+
-- sending -> queued (startup recovery: interrupted sessions reset)
|
|
15
|
+
-- sending -> error (after max retries exhausted)
|
|
16
|
+
|
|
17
|
+
CREATE TABLE IF NOT EXISTS message_queue (
|
|
18
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
19
|
+
world_id TEXT NOT NULL,
|
|
20
|
+
chat_id TEXT NOT NULL,
|
|
21
|
+
message_id TEXT NOT NULL,
|
|
22
|
+
content TEXT NOT NULL,
|
|
23
|
+
sender TEXT NOT NULL DEFAULT 'human',
|
|
24
|
+
status TEXT NOT NULL DEFAULT 'queued',
|
|
25
|
+
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
26
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
27
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
28
|
+
FOREIGN KEY (world_id) REFERENCES worlds(id) ON DELETE CASCADE,
|
|
29
|
+
FOREIGN KEY (chat_id) REFERENCES world_chats(id) ON DELETE CASCADE
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_message_queue_message_id
|
|
33
|
+
ON message_queue(message_id);
|
|
34
|
+
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_message_queue_chat
|
|
36
|
+
ON message_queue(world_id, chat_id, status);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
-- Migration: Add world heartbeat configuration fields
|
|
2
|
+
-- Version: 16
|
|
3
|
+
-- Date: 2026-03-04
|
|
4
|
+
--
|
|
5
|
+
-- Adds persisted world heartbeat controls used by Electron main runtime.
|
|
6
|
+
-- Fields:
|
|
7
|
+
-- heartbeat_enabled - whether heartbeat scheduling is enabled
|
|
8
|
+
-- heartbeat_interval - cron expression (product policy: strict 5-field)
|
|
9
|
+
-- heartbeat_prompt - message content published on each tick
|
|
10
|
+
|
|
11
|
+
ALTER TABLE worlds ADD COLUMN heartbeat_enabled INTEGER DEFAULT 0;
|
|
12
|
+
ALTER TABLE worlds ADD COLUMN heartbeat_interval TEXT;
|
|
13
|
+
ALTER TABLE worlds ADD COLUMN heartbeat_prompt TEXT;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
-- Migration: Add title_provenance column to world_chats
|
|
2
|
+
-- Purpose: Track whether a chat title was set by default, auto-generated, or manually assigned.
|
|
3
|
+
-- Notes:
|
|
4
|
+
-- - DEFAULT 'default' ensures existing rows are treated as legacy (favor-preserve) per REQ-11.
|
|
5
|
+
-- - Valid values: 'default' (untitled/legacy), 'auto' (auto-generated), 'manual' (user-renamed).
|
|
6
|
+
ALTER TABLE world_chats
|
|
7
|
+
ADD COLUMN title_provenance TEXT DEFAULT 'default';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-world",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"type": "module",
|
|
18
18
|
"workspaces": [
|
|
19
19
|
"core",
|
|
20
|
-
"web"
|
|
20
|
+
"web",
|
|
21
|
+
"packages/opik"
|
|
21
22
|
],
|
|
22
23
|
"bin": {
|
|
23
24
|
"agent-world": "bin/agent-world.js",
|
|
@@ -25,6 +26,7 @@
|
|
|
25
26
|
"agent-world-server": "bin/agent-world-server.js"
|
|
26
27
|
},
|
|
27
28
|
"scripts": {
|
|
29
|
+
"install:all": "npm install && npm install --prefix electron",
|
|
28
30
|
"dev": "npm run web:dev",
|
|
29
31
|
"dev:reset": "for p in 3000 8080; do pids=$(lsof -tiTCP:$p -sTCP:LISTEN 2>/dev/null || true); if [ -n \"$pids\" ]; then kill $pids; fi; done",
|
|
30
32
|
"web:dev": "npm-run-all --parallel server:watch web:vite:wait",
|
|
@@ -35,25 +37,39 @@
|
|
|
35
37
|
"web:start": "npm run build && npm run server:start",
|
|
36
38
|
"cli:start": "npm run build && node dist/cli/index.js",
|
|
37
39
|
"electron:start": "npm run build:core && npm run start --prefix electron",
|
|
38
|
-
"build": "npm run build --
|
|
40
|
+
"electron:main:build": "npm run main:build --prefix electron",
|
|
41
|
+
"electron:renderer:build": "npm run renderer:build --prefix electron",
|
|
42
|
+
"build": "npm run build --workspace=core && npm run build --workspace=packages/opik && tsc --project tsconfig.build.json && npm run build --workspace=web && npm run main:build --prefix electron",
|
|
39
43
|
"build:core": "npm run build --workspace=core",
|
|
40
44
|
"build:core:watch": "npm run build --workspace=core -- --watch --preserveWatchOutput",
|
|
41
|
-
"check": "tsc --noEmit --project tsconfig.build.json && npm run check --workspace=core && npm run check --workspace=web && npm run
|
|
45
|
+
"check": "tsc --noEmit --project tsconfig.build.json && npm run check --workspace=core && npm run check --workspace=web && npm run check --prefix electron",
|
|
42
46
|
"server:dev": "npx tsx server/index.ts",
|
|
43
47
|
"server:watch": "npx tsx --watch server/index.ts",
|
|
44
48
|
"server:start": "node dist/server/index.js",
|
|
45
49
|
"web:vite": "npm run dev --workspace=web",
|
|
50
|
+
"web:vite:e2e": "vite dev --config web/vite.config.js --host 127.0.0.1 --port 8080 --strictPort",
|
|
46
51
|
"web:vite:wait": "wait-on tcp:127.0.0.1:3000 && npm run web:vite",
|
|
52
|
+
"web:e2e:serve": "node tests/web-e2e/support/start-web-servers.mjs",
|
|
47
53
|
"electron:vite": "npm run dev --prefix electron",
|
|
48
54
|
"test": "vitest run",
|
|
49
55
|
"test:watch": "vitest",
|
|
50
56
|
"test:ui": "vitest --ui",
|
|
51
57
|
"test:coverage": "vitest run --coverage",
|
|
58
|
+
"coverage:scorecard": "node scripts/coverage-scorecard.mjs",
|
|
59
|
+
"test:coverage:gate": "npm run test:coverage && npm run coverage:scorecard",
|
|
52
60
|
"test:db": "npx tsx tests/db/migration-tests.ts",
|
|
53
61
|
"test:e2e": "npx tsx tests/e2e/test-agent-response-rules.ts",
|
|
54
62
|
"test:e2e:interactive": "npx tsx tests/e2e/test-agent-response-rules.ts -i",
|
|
63
|
+
"test:web:e2e:run": "playwright test --config playwright.web.config.ts",
|
|
64
|
+
"test:web:e2e": "npm run test:web:e2e:run",
|
|
65
|
+
"test:electron:e2e:run": "playwright test --config playwright.electron.config.ts",
|
|
66
|
+
"test:electron:e2e": "npm-run-all --sequential build:core electron:main:build electron:renderer:build test:electron:e2e:run",
|
|
55
67
|
"integration": "vitest run --config vitest.integration.config.ts",
|
|
56
|
-
"
|
|
68
|
+
"ci:test": "npm run test:coverage:gate && npm run integration",
|
|
69
|
+
"pkill": "pkill -f tsx",
|
|
70
|
+
"opik:eval": "npx tsx tests/opik/eval-robustness.ts",
|
|
71
|
+
"opik:storage-export-world": "npx tsx scripts/opik-export-world-storage.ts",
|
|
72
|
+
"test:integration": "npm run integration"
|
|
57
73
|
},
|
|
58
74
|
"description": "World-mediated agent management system with clean API surface",
|
|
59
75
|
"keywords": [
|
|
@@ -71,23 +87,28 @@
|
|
|
71
87
|
"@google/generative-ai": "^0.24.1",
|
|
72
88
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
73
89
|
"chalk": "^5.5.0",
|
|
90
|
+
"commander": "^14.0.0",
|
|
74
91
|
"cors": "^2.8.5",
|
|
75
92
|
"dotenv": "^17.2.3",
|
|
76
93
|
"enquirer": "^2.4.1",
|
|
77
|
-
"express": "^4.22.1",
|
|
78
94
|
"events": "^3.3.0",
|
|
95
|
+
"express": "^4.22.1",
|
|
79
96
|
"fast-glob": "^3.3.3",
|
|
80
97
|
"nanoid": "^5.1.5",
|
|
81
98
|
"open": "^11.0.0",
|
|
82
|
-
"
|
|
83
|
-
"
|
|
99
|
+
"node-cron": "^4.2.1",
|
|
100
|
+
"openai": "^6.25.0",
|
|
84
101
|
"pino": "^10.0.0",
|
|
85
102
|
"pino-pretty": "^13.1.3",
|
|
86
103
|
"sqlite3": "^5.1.7",
|
|
87
|
-
"
|
|
88
|
-
"
|
|
104
|
+
"turndown": "^7.2.0",
|
|
105
|
+
"turndown-plugin-gfm": "^1.0.2",
|
|
106
|
+
"tsx": "^4.21.0",
|
|
107
|
+
"zod": "^4.2.1"
|
|
89
108
|
},
|
|
90
109
|
"devDependencies": {
|
|
110
|
+
"@types/node-cron": "^3.0.11",
|
|
111
|
+
"@playwright/test": "^1.54.2",
|
|
91
112
|
"@tailwindcss/postcss": "^4.1.18",
|
|
92
113
|
"@types/cors": "^2.8.19",
|
|
93
114
|
"@types/express": "^4.17.25",
|