agent-world 0.13.0 → 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 +90 -17
- package/dist/cli/commands.d.ts +7 -1
- package/dist/cli/commands.js +27 -10
- package/dist/cli/hitl.d.ts +4 -1
- package/dist/cli/hitl.js +55 -20
- package/dist/cli/index.js +249 -97
- package/dist/cli/system-events.d.ts +27 -0
- package/dist/cli/system-events.js +63 -0
- package/dist/core/activity-tracker.d.ts +26 -0
- package/dist/core/activity-tracker.d.ts.map +1 -1
- package/dist/core/activity-tracker.js +21 -4
- 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 +5 -0
- package/dist/core/create-agent-tool.d.ts.map +1 -1
- package/dist/core/create-agent-tool.js +57 -34
- 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 +203 -36
- 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 -35
- package/dist/core/events/persistence.js.map +1 -1
- package/dist/core/events/publishers.d.ts +13 -7
- package/dist/core/events/publishers.d.ts.map +1 -1
- package/dist/core/events/publishers.js +53 -37
- 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 +61 -148
- 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 +6 -12
- package/dist/core/hitl-tool.d.ts.map +1 -1
- package/dist/core/hitl-tool.js +66 -88
- package/dist/core/hitl-tool.js.map +1 -1
- package/dist/core/hitl.d.ts +61 -4
- package/dist/core/hitl.d.ts.map +1 -1
- package/dist/core/hitl.js +324 -60
- package/dist/core/hitl.js.map +1 -1
- package/dist/core/index.d.ts +11 -7
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +10 -6
- package/dist/core/index.js.map +1 -1
- package/dist/core/llm-manager.d.ts +15 -0
- package/dist/core/llm-manager.d.ts.map +1 -1
- package/dist/core/llm-manager.js +325 -40
- 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 +18 -50
- package/dist/core/managers.d.ts.map +1 -1
- package/dist/core/managers.js +340 -502
- package/dist/core/managers.js.map +1 -1
- package/dist/core/mcp-server-registry.d.ts +16 -1
- package/dist/core/mcp-server-registry.d.ts.map +1 -1
- package/dist/core/mcp-server-registry.js +162 -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 +7 -2
- package/dist/core/tool-utils.d.ts.map +1 -1
- package/dist/core/tool-utils.js +81 -17
- package/dist/core/tool-utils.js.map +1 -1
- package/dist/core/types.d.ts +67 -19
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +3 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/utils.d.ts +7 -0
- package/dist/core/utils.d.ts.map +1 -1
- package/dist/core/utils.js +71 -21
- 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 +260 -18
- 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 +11 -1
- package/dist/server/sse-handler.js +194 -34
- 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-BW41BxMy.css +0 -1
- package/dist/public/assets/index-kO6UJFwK.js +0 -96
package/README.md
CHANGED
|
@@ -37,25 +37,31 @@ Paste that prompt. Agents come alive instantly.
|
|
|
37
37
|
- ✅ Built-in Rules for Messages - Turn limits to prevent loops
|
|
38
38
|
- ✅ Concurrent Chat Sessions - Isolated `chatId` routing enables parallel conversations
|
|
39
39
|
- ✅ Progressive Agent Skills - Skills are discovered and loaded on demand via `load_skill`
|
|
40
|
+
- ✅ World-Level Tool Permissions - `Read`, `Ask`, and `Auto` modes control write and execution capabilities
|
|
40
41
|
- ✅ Cross-Client HITL Approval - Option-based approvals in CLI, Web, and Electron
|
|
42
|
+
- ✅ Reasoning Controls - World-scoped reasoning effort with separate reasoning-token rendering
|
|
43
|
+
- ✅ Heartbeats & Queueing - Queue-backed world prompts and cron scheduling with explicit controls
|
|
44
|
+
- ✅ Marketplace & Imports - Bring in worlds, agents, and skills from local folders or curated GitHub sources
|
|
41
45
|
- ✅ Runtime Controls - Session-scoped send/stop flows and tool lifecycle visibility
|
|
42
46
|
- ✅ Safer Tool Execution - Trusted-CWD and argument-scope guards for `shell_cmd`
|
|
43
47
|
- ✅ Multiple AI Providers - Use different models for different agents
|
|
44
48
|
- ✅ Web + CLI + Electron - Modern interfaces with real-time streaming and status feedback
|
|
45
49
|
|
|
46
|
-
## Latest Highlights (
|
|
50
|
+
## Latest Highlights (v0.15.0)
|
|
47
51
|
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
- Electron now
|
|
52
|
-
-
|
|
53
|
-
-
|
|
52
|
+
- World-level tool permissions add `Read`, `Ask`, and `Auto` control modes in both the web and Electron composers
|
|
53
|
+
- Supported providers can use world-scoped `reasoning_effort`, with reasoning tokens streamed and rendered separately from final answers
|
|
54
|
+
- World and heartbeat prompts now enter the same queue-backed message flow as human turns, with explicit heartbeat controls and next-run visibility
|
|
55
|
+
- Electron now includes marketplace-style import flows for discovering and importing worlds, agents, and skills
|
|
56
|
+
- Web and Electron transcripts have tighter parity with compact tool rows, improved status rendering, and cleaner working indicators
|
|
57
|
+
- Clicking markdown links in Electron messages now opens the external browser instead of attempting in-app navigation
|
|
54
58
|
|
|
55
59
|
## Release Notes
|
|
56
60
|
|
|
61
|
+
- **v0.15.0** - Tool permission modes, reasoning-token support, queue-backed world/heartbeat flow, marketplace imports, and transcript/UI refinements
|
|
62
|
+
- **v0.14.0** - User message queue, `write_file`/`web_fetch`/`send_message`, shell risk gating, E2E harnesses, skill editor, and heartbeat scheduling
|
|
63
|
+
- **v0.13.0** - Better HITL prompts, improved streaming/main-agent UX, and smoother message rendering
|
|
57
64
|
- **v0.12.0** - Web settings/search/branching, built-in `create_agent`, new file tools, Electron folder import/export, and chat/status UX improvements
|
|
58
|
-
- **v0.11.0** - Electron desktop workflow, concurrent chat sessions, main-agent routing, progressive skills + HITL, and runtime safety hardening
|
|
59
65
|
- Full history: [CHANGELOG.md](CHANGELOG.md)
|
|
60
66
|
|
|
61
67
|
## What You Can Build
|
|
@@ -102,25 +108,24 @@ Each Agent World has a collection of agents that can communicate through a share
|
|
|
102
108
|
|
|
103
109
|
### Message Rules
|
|
104
110
|
|
|
105
|
-
| Message
|
|
111
|
+
| Message Shape | Example | Who Responds |
|
|
106
112
|
|--------------|---------|--------------|
|
|
107
|
-
| **
|
|
108
|
-
| **
|
|
109
|
-
| **Paragraph mention** | `Please review this:\n@alice` | Only
|
|
110
|
-
| **Mid-text mention** | `I think @alice should help` | Nobody (event is persisted; no agent-memory save) |
|
|
113
|
+
| **Public human or world message** | `Hello everyone!` | All active agents |
|
|
114
|
+
| **Paragraph-start mention** | `@alice Can you help?` | Only mentioned agents |
|
|
115
|
+
| **Paragraph-start mention after text** | `Please review this:\n@alice` | Only mentioned agents |
|
|
116
|
+
| **Mid-text mention only** | `I think @alice should help` | Nobody (event is persisted; no agent-memory save) |
|
|
111
117
|
| **Stop World** | `<world>pass</world>` | No agents |
|
|
112
118
|
|
|
113
119
|
### Agent Behavior
|
|
114
120
|
|
|
115
121
|
**Agents always respond to:**
|
|
116
|
-
-
|
|
122
|
+
- Public human or world messages when there is no paragraph-start mention
|
|
117
123
|
- Direct @mentions at paragraph start
|
|
118
|
-
- World messages
|
|
119
124
|
|
|
120
125
|
**Agents never respond to:**
|
|
121
126
|
- Their own messages
|
|
122
127
|
- Other agents (unless @mentioned at paragraph start)
|
|
123
|
-
- Mid-text mentions (not at paragraph start)
|
|
128
|
+
- Mid-text mentions (not at paragraph start), including world prompts
|
|
124
129
|
|
|
125
130
|
**When messages are saved to agent memory:**
|
|
126
131
|
- Incoming messages are saved only for agents that will respond
|
|
@@ -169,7 +174,13 @@ npm run electron:dev
|
|
|
169
174
|
|
|
170
175
|
## Project Structure
|
|
171
176
|
|
|
172
|
-
|
|
177
|
+
- `core/` - shared runtime, storage, tools, provider integrations, and event flow
|
|
178
|
+
- `server/` - REST API and SSE transport
|
|
179
|
+
- `web/` - browser app
|
|
180
|
+
- `electron/` - desktop app (main, preload, renderer)
|
|
181
|
+
- `cli/` - terminal interface
|
|
182
|
+
|
|
183
|
+
For broader architecture and usage docs, start with [Docs Home](docs/docs-home.md).
|
|
173
184
|
|
|
174
185
|
## Development Scripts
|
|
175
186
|
|
|
@@ -237,6 +248,38 @@ AZURE_OPENAI_API_VERSION=2024-10-21-preview
|
|
|
237
248
|
OLLAMA_BASE_URL=http://localhost:11434
|
|
238
249
|
```
|
|
239
250
|
|
|
251
|
+
### Optional Opik Layer
|
|
252
|
+
|
|
253
|
+
Opik is optional and fully gated.
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
OPIK_ENABLED=false
|
|
257
|
+
OPIK_SAFETY_ENABLED=false
|
|
258
|
+
OPIK_EVAL_ENABLED=false
|
|
259
|
+
OPIK_API_KEY=
|
|
260
|
+
OPIK_WORKSPACE=
|
|
261
|
+
OPIK_PROJECT=agent-world-debugging
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Rules:
|
|
265
|
+
- `OPIK_ENABLED=false`: all Opik integration/safety/eval paths are inert.
|
|
266
|
+
- `OPIK_ENABLED=true`: tracing can attach only if `OPIK_API_KEY` + `OPIK_WORKSPACE` are set.
|
|
267
|
+
- Safety and eval still require their sub-flags (`OPIK_SAFETY_ENABLED`, `OPIK_EVAL_ENABLED`).
|
|
268
|
+
|
|
269
|
+
#### Fallback Behavior
|
|
270
|
+
|
|
271
|
+
When Opik is enabled but something is missing, startup always continues normally — no crashes.
|
|
272
|
+
|
|
273
|
+
| Condition | Result | Log |
|
|
274
|
+
|-----------|--------|-----|
|
|
275
|
+
| `OPIK_ENABLED=false` | No Opik code runs | none |
|
|
276
|
+
| Enabled but `OPIK_API_KEY` or `OPIK_WORKSPACE` missing | Tracer skipped | warning: `Opik enabled but required env is missing` |
|
|
277
|
+
| Enabled + config present but `packages/opik` not installed | Tracer skipped | warning: `Opik enabled but optional dependency is unavailable` |
|
|
278
|
+
| Enabled + config present + module loaded but tracer init fails | Tracer skipped | warning: `Opik module loaded but tracer initialization failed` |
|
|
279
|
+
| Enabled + config present + module loaded + tracer created | Tracer attaches to world | info: `Opik tracer attached` |
|
|
280
|
+
|
|
281
|
+
Opik is storage-agnostic — it attaches to `world.eventEmitter` and works identically with sqlite, file, or memory storage backends.
|
|
282
|
+
|
|
240
283
|
## Testing
|
|
241
284
|
|
|
242
285
|
**Run all tests:**
|
|
@@ -245,6 +288,7 @@ npm test # Run all unit tests
|
|
|
245
288
|
npm run test:watch # Watch mode with hot reload
|
|
246
289
|
npm run test:ui # Visual test UI
|
|
247
290
|
npm run test:coverage # Generate coverage report
|
|
291
|
+
npm run test:coverage:gate # Coverage + core threshold gate + subsystem scorecard
|
|
248
292
|
```
|
|
249
293
|
|
|
250
294
|
**Run specific tests:**
|
|
@@ -256,10 +300,23 @@ npm test -- message-saving # Test files matching pattern
|
|
|
256
300
|
**Integration tests:**
|
|
257
301
|
```bash
|
|
258
302
|
npm run test:integration # Run integration tests with real filesystem
|
|
303
|
+
npm run ci:test # CI gate: coverage threshold + integration
|
|
259
304
|
```
|
|
260
305
|
|
|
261
306
|
Agent World uses Vitest for fast, modern testing with native TypeScript support.
|
|
262
307
|
|
|
308
|
+
### Coverage Gates
|
|
309
|
+
|
|
310
|
+
`npm run test:coverage:gate` enforces minimum core coverage thresholds and generates a subsystem scorecard:
|
|
311
|
+
- core statements >= 68%
|
|
312
|
+
- core branches >= 56%
|
|
313
|
+
- core functions >= 75%
|
|
314
|
+
- core lines >= 69%
|
|
315
|
+
|
|
316
|
+
The scorecard is written to:
|
|
317
|
+
- `coverage/scorecard.md`
|
|
318
|
+
- `coverage/scorecard.json`
|
|
319
|
+
|
|
263
320
|
## Logging and Debugging
|
|
264
321
|
|
|
265
322
|
Agent World uses **scenario-based logging** to help you debug specific issues without noise. Enable only the logs you need for your current task.
|
|
@@ -275,6 +332,9 @@ LOG_MCP=debug npm run web:dev
|
|
|
275
332
|
|
|
276
333
|
# Agent response debugging
|
|
277
334
|
LOG_EVENTS_AGENT=debug LOG_LLM=debug npm run web:dev
|
|
335
|
+
|
|
336
|
+
# Chat restore/HITL replay debugging
|
|
337
|
+
LOG_CHAT_RESTORE=debug LOG_CHAT_RESTORE_RESUME=debug LOG_CHAT_RESTORE_RESUME_TOOLS=debug LOG_HITL=debug npm run web:dev
|
|
278
338
|
```
|
|
279
339
|
|
|
280
340
|
**For complete logging documentation**, see [Logging Guide](docs/logging-guide.md).
|
|
@@ -299,6 +359,7 @@ export AGENT_WORLD_DATA_PATH=./data/worlds
|
|
|
299
359
|
- **[Building Agents with Just Words](docs/Building%20Agents%20with%20Just%20Words.md)** - Complete guide with examples
|
|
300
360
|
- **[Shell Command Tool (shell_cmd)](docs/shell-cmd-tool.md)** - Built-in tool for executing shell commands
|
|
301
361
|
- **[HITL Approval Flow](docs/hitl-approval-flow.md)** - Option-based approval flow across Core/Electron/Web/CLI
|
|
362
|
+
- **[API Reference](openapi.yaml)** - OpenAPI 3.1 spec for the REST API
|
|
302
363
|
- **[Using Core from npm](docs/core-npm-usage.md)** - Integration guide for server and browser apps
|
|
303
364
|
- **[Electron Desktop App](docs/electron-desktop.md)** - Open-folder workflow and local world creation
|
|
304
365
|
|
|
@@ -307,6 +368,17 @@ export AGENT_WORLD_DATA_PATH=./data/worlds
|
|
|
307
368
|
|
|
308
369
|
Agent World includes built-in tools that are automatically available to all agents:
|
|
309
370
|
|
|
371
|
+
- `read_file`, `list_files`, `grep` - inspect project files and source trees
|
|
372
|
+
- `write_file` - update files inside trusted workspace scope
|
|
373
|
+
- `web_fetch` - fetch web pages and convert them to Markdown for agent use
|
|
374
|
+
- `send_message` - dispatch trusted chat-context messages to other agents
|
|
375
|
+
- `create_agent` - create new agents during a conversation
|
|
376
|
+
- `shell_cmd` - run shell commands with trusted-scope validation and lifecycle controls
|
|
377
|
+
- `load_skill` - progressively load `SKILL.md` instructions and related scripts
|
|
378
|
+
- `human_intervention_request` - ask the user for structured options and approvals
|
|
379
|
+
|
|
380
|
+
World owners can set built-in tool access to `Read`, `Ask`, or `Auto` so write/execute actions are blocked, approval-gated, or automatic depending on the world.
|
|
381
|
+
|
|
310
382
|
### shell_cmd
|
|
311
383
|
Execute shell commands with full output capture and execution history. Perfect for file operations, system information, and automation tasks.
|
|
312
384
|
|
|
@@ -333,6 +405,7 @@ Agent World includes progressive skill loading through the `load_skill` built-in
|
|
|
333
405
|
- User roots: `~/.agents/skills`, `~/.codex/skills`
|
|
334
406
|
- The model receives compact skill summaries first, then calls `load_skill` only when full instructions are needed.
|
|
335
407
|
- Skill activation in interactive runtimes is HITL-gated.
|
|
408
|
+
- `load_skill` always performs the same preflight flow: script references are discovered from instructions, script execution is HITL-approved and scope-validated, and reference-file context is collected when active resources are present.
|
|
336
409
|
|
|
337
410
|
Minimal `SKILL.md` example:
|
|
338
411
|
|
package/dist/cli/commands.d.ts
CHANGED
|
@@ -43,6 +43,11 @@
|
|
|
43
43
|
* - Creates target directory if it doesn't exist
|
|
44
44
|
* - Supports migration between storage types
|
|
45
45
|
* - Event history preserved across different storage backends
|
|
46
|
+
*
|
|
47
|
+
* Recent Changes:
|
|
48
|
+
* - 2026-03-06: Removed runtime message/export fallback to `world.currentChatId`; CLI execution now requires explicit selected chat state.
|
|
49
|
+
* - 2026-03-10: Switched CLI user message send path to the queue-only `enqueueAndProcessUserTurn` API.
|
|
50
|
+
* - 2026-03-04: Added queue metadata (`messageId`, `queueStatus`, `queueRetryCount`) to successful message-send CLI results for queue error visibility.
|
|
46
51
|
*/
|
|
47
52
|
import { World } from '../core/types.js';
|
|
48
53
|
export interface CLIResponse {
|
|
@@ -57,6 +62,7 @@ export interface CLIResponse {
|
|
|
57
62
|
export interface CLIContext {
|
|
58
63
|
currentWorldName?: string;
|
|
59
64
|
currentWorld?: World | null;
|
|
65
|
+
selectedChatId?: string | null;
|
|
60
66
|
}
|
|
61
67
|
export type PromptFunction = (question: string, options?: string[]) => Promise<string>;
|
|
62
68
|
/**
|
|
@@ -105,5 +111,5 @@ export declare function deleteExistingData(targetPath: string, storageType: 'fil
|
|
|
105
111
|
}>;
|
|
106
112
|
export declare function performWorldSave(world: World, storageType: 'file' | 'sqlite', targetPath: string): Promise<CLIResponse>;
|
|
107
113
|
export declare function processCLICommand(input: string, context: CLIContext, promptFn: PromptFunction): Promise<CLIResponse>;
|
|
108
|
-
export declare function processCLIInput(input: string, world: World | null, sender?: string): Promise<CLIResponse>;
|
|
114
|
+
export declare function processCLIInput(input: string, world: World | null, sender?: string, selectedChatId?: string | null): Promise<CLIResponse>;
|
|
109
115
|
export {};
|
package/dist/cli/commands.js
CHANGED
|
@@ -43,8 +43,13 @@
|
|
|
43
43
|
* - Creates target directory if it doesn't exist
|
|
44
44
|
* - Supports migration between storage types
|
|
45
45
|
* - Event history preserved across different storage backends
|
|
46
|
+
*
|
|
47
|
+
* Recent Changes:
|
|
48
|
+
* - 2026-03-06: Removed runtime message/export fallback to `world.currentChatId`; CLI execution now requires explicit selected chat state.
|
|
49
|
+
* - 2026-03-10: Switched CLI user message send path to the queue-only `enqueueAndProcessUserTurn` API.
|
|
50
|
+
* - 2026-03-04: Added queue metadata (`messageId`, `queueStatus`, `queueRetryCount`) to successful message-send CLI results for queue error visibility.
|
|
46
51
|
*/
|
|
47
|
-
import { LLMProvider, createWorld, getWorld, updateWorld,
|
|
52
|
+
import { LLMProvider, createWorld, getWorld, updateWorld, enqueueAndProcessUserTurn, listWorlds, deleteWorld, listAgents, getAgent, updateAgent, deleteAgent, createAgent, clearAgentMemory, listChats, updateChat, exportWorldToMarkdown, exportChatToMarkdown, newChat, restoreChat, deleteChat, getMemory } from '../core/index.js';
|
|
48
53
|
import { createStorage } from '../core/storage/storage-factory.js';
|
|
49
54
|
import { createCategoryLogger } from '../core/logger.js';
|
|
50
55
|
import readline from 'readline';
|
|
@@ -83,7 +88,12 @@ const boldRed = (text) => `\x1b[1m\x1b[31m${text}\x1b[0m`;
|
|
|
83
88
|
*/
|
|
84
89
|
export async function displayChatMessages(worldId, chatId) {
|
|
85
90
|
try {
|
|
86
|
-
const
|
|
91
|
+
const resolvedChatId = String(chatId || '').trim();
|
|
92
|
+
if (!resolvedChatId) {
|
|
93
|
+
console.log(gray('\n No active chat selected.\n'));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const messages = await getMemory(worldId, resolvedChatId);
|
|
87
97
|
if (!messages || messages.length === 0) {
|
|
88
98
|
console.log(gray('\n No messages in current chat.\n'));
|
|
89
99
|
return;
|
|
@@ -1900,7 +1910,7 @@ export async function processCLICommand(input, context, promptFn) {
|
|
|
1900
1910
|
const worldError = requireWorldOrError(world, command);
|
|
1901
1911
|
if (worldError)
|
|
1902
1912
|
return worldError;
|
|
1903
|
-
const chatId = collectedParams.chatId ||
|
|
1913
|
+
const chatId = collectedParams.chatId || context.selectedChatId;
|
|
1904
1914
|
if (!chatId) {
|
|
1905
1915
|
cliResponse = {
|
|
1906
1916
|
success: false,
|
|
@@ -1946,10 +1956,11 @@ export async function processCLICommand(input, context, promptFn) {
|
|
|
1946
1956
|
}
|
|
1947
1957
|
}
|
|
1948
1958
|
// Main CLI input processor - handles both commands and messages
|
|
1949
|
-
export async function processCLIInput(input, world, sender = 'human') {
|
|
1959
|
+
export async function processCLIInput(input, world, sender = 'human', selectedChatId = null) {
|
|
1950
1960
|
const context = {
|
|
1951
1961
|
currentWorld: world,
|
|
1952
|
-
currentWorldName: world?.name
|
|
1962
|
+
currentWorldName: world?.name,
|
|
1963
|
+
selectedChatId,
|
|
1953
1964
|
};
|
|
1954
1965
|
// Simple prompt function for CLI
|
|
1955
1966
|
const promptFunction = async (question, options) => {
|
|
@@ -1989,7 +2000,7 @@ export async function processCLIInput(input, world, sender = 'human') {
|
|
|
1989
2000
|
};
|
|
1990
2001
|
}
|
|
1991
2002
|
try {
|
|
1992
|
-
const currentChatId = String(
|
|
2003
|
+
const currentChatId = String(selectedChatId || '').trim();
|
|
1993
2004
|
if (!currentChatId) {
|
|
1994
2005
|
return {
|
|
1995
2006
|
success: false,
|
|
@@ -1998,19 +2009,25 @@ export async function processCLIInput(input, world, sender = 'human') {
|
|
|
1998
2009
|
};
|
|
1999
2010
|
}
|
|
2000
2011
|
const restoredWorld = await restoreChat(world.id, currentChatId);
|
|
2001
|
-
if (!restoredWorld || restoredWorld.currentChatId
|
|
2012
|
+
if (!restoredWorld || !restoredWorld.chats?.has?.(currentChatId)) {
|
|
2002
2013
|
return {
|
|
2003
2014
|
success: false,
|
|
2004
2015
|
message: `Cannot send message - chat not found: ${currentChatId}`,
|
|
2005
2016
|
technicalDetails: `Failed to restore active chat '${currentChatId}' before message publish`
|
|
2006
2017
|
};
|
|
2007
2018
|
}
|
|
2008
|
-
|
|
2019
|
+
const queuedMessage = await enqueueAndProcessUserTurn(world.id, currentChatId, input, sender, world);
|
|
2009
2020
|
return {
|
|
2010
2021
|
success: true,
|
|
2011
2022
|
message: '',
|
|
2012
|
-
data: {
|
|
2013
|
-
|
|
2023
|
+
data: {
|
|
2024
|
+
sender,
|
|
2025
|
+
chatId: currentChatId,
|
|
2026
|
+
messageId: queuedMessage?.messageId || null,
|
|
2027
|
+
queueStatus: queuedMessage?.status || null,
|
|
2028
|
+
queueRetryCount: typeof queuedMessage?.retryCount === 'number' ? queuedMessage.retryCount : null,
|
|
2029
|
+
},
|
|
2030
|
+
technicalDetails: `Message enqueued for world '${world.name}' (chat '${currentChatId}')`
|
|
2014
2031
|
};
|
|
2015
2032
|
}
|
|
2016
2033
|
catch (error) {
|
package/dist/cli/hitl.d.ts
CHANGED
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
* - Provide pure parsing/selection helpers for HITL option requests used by the CLI.
|
|
6
6
|
*
|
|
7
7
|
* Key Features:
|
|
8
|
-
* - Parse
|
|
8
|
+
* - Parse HITL prompt payloads from tool-progress metadata and pending prompt envelopes.
|
|
9
9
|
* - Resolve user input into option IDs (by number or option id).
|
|
10
10
|
* - Provide deterministic fallback option resolution.
|
|
11
|
+
* - Guard duplicate replayed requests via requestId-tracking helper.
|
|
11
12
|
*
|
|
12
13
|
* Implementation Notes:
|
|
13
14
|
* - Parser accepts generic event payloads and rejects incomplete requests.
|
|
@@ -33,5 +34,7 @@ export interface HitlOptionRequestPayload {
|
|
|
33
34
|
}
|
|
34
35
|
export type HitlPromptRequestPayload = HitlOptionRequestPayload;
|
|
35
36
|
export declare function parseHitlPromptRequest(eventData: unknown): HitlPromptRequestPayload | null;
|
|
37
|
+
export declare function parseHitlPromptFromToolEvent(eventData: unknown): HitlPromptRequestPayload | null;
|
|
36
38
|
export declare function parseHitlOptionRequest(eventData: unknown): HitlOptionRequestPayload | null;
|
|
37
39
|
export declare function resolveHitlOptionSelectionInput(options: HitlOptionPayload[], rawInput: string, fallbackOptionId: string): string | null;
|
|
40
|
+
export declare function markHitlRequestHandled(handledRequestIds: Set<string>, requestId: string): boolean;
|
package/dist/cli/hitl.js
CHANGED
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
* - Provide pure parsing/selection helpers for HITL option requests used by the CLI.
|
|
6
6
|
*
|
|
7
7
|
* Key Features:
|
|
8
|
-
* - Parse
|
|
8
|
+
* - Parse HITL prompt payloads from tool-progress metadata and pending prompt envelopes.
|
|
9
9
|
* - Resolve user input into option IDs (by number or option id).
|
|
10
10
|
* - Provide deterministic fallback option resolution.
|
|
11
|
+
* - Guard duplicate replayed requests via requestId-tracking helper.
|
|
11
12
|
*
|
|
12
13
|
* Implementation Notes:
|
|
13
14
|
* - Parser accepts generic event payloads and rejects incomplete requests.
|
|
@@ -17,24 +18,13 @@
|
|
|
17
18
|
* - 2026-02-20: Enforced options-only HITL parsing in CLI helpers.
|
|
18
19
|
* - 2026-02-14: Added initial helper module for CLI HITL response flow support.
|
|
19
20
|
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
const payload = eventData;
|
|
25
|
-
const content = payload.content && typeof payload.content === 'object'
|
|
26
|
-
? payload.content
|
|
27
|
-
: null;
|
|
28
|
-
const eventType = String(content?.eventType || '').trim();
|
|
29
|
-
if (!content || eventType !== 'hitl-option-request') {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
const requestId = String(content.requestId || '').trim();
|
|
21
|
+
function normalizePromptPayload(promptData, fallbackChatId) {
|
|
22
|
+
const requestId = String(promptData.requestId || '').trim();
|
|
33
23
|
if (!requestId) {
|
|
34
24
|
return null;
|
|
35
25
|
}
|
|
36
|
-
const options = Array.isArray(
|
|
37
|
-
?
|
|
26
|
+
const options = Array.isArray(promptData.options)
|
|
27
|
+
? promptData.options
|
|
38
28
|
.map((option) => {
|
|
39
29
|
const optionRecord = option && typeof option === 'object'
|
|
40
30
|
? option
|
|
@@ -50,20 +40,54 @@ export function parseHitlPromptRequest(eventData) {
|
|
|
50
40
|
if (options.length === 0) {
|
|
51
41
|
return null;
|
|
52
42
|
}
|
|
53
|
-
const preferredDefault = String(
|
|
43
|
+
const preferredDefault = String(promptData.defaultOptionId || '').trim();
|
|
54
44
|
const defaultOptionId = options.some((option) => option.id === preferredDefault)
|
|
55
45
|
? preferredDefault
|
|
56
46
|
: (options.find((option) => option.id === 'no')?.id || options[0].id);
|
|
57
47
|
return {
|
|
58
48
|
requestId,
|
|
59
|
-
title: String(
|
|
60
|
-
message: String(
|
|
61
|
-
chatId:
|
|
49
|
+
title: String(promptData.title || 'Approval required').trim() || 'Approval required',
|
|
50
|
+
message: String(promptData.message || '').trim(),
|
|
51
|
+
chatId: fallbackChatId,
|
|
62
52
|
mode: 'option',
|
|
63
53
|
options,
|
|
64
54
|
defaultOptionId
|
|
65
55
|
};
|
|
66
56
|
}
|
|
57
|
+
export function parseHitlPromptRequest(eventData) {
|
|
58
|
+
if (!eventData || typeof eventData !== 'object') {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
const payload = eventData;
|
|
62
|
+
const prompt = payload.prompt && typeof payload.prompt === 'object'
|
|
63
|
+
? payload.prompt
|
|
64
|
+
: null;
|
|
65
|
+
if (!prompt) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const chatId = payload.chatId ? String(payload.chatId) : null;
|
|
69
|
+
return normalizePromptPayload(prompt, chatId);
|
|
70
|
+
}
|
|
71
|
+
export function parseHitlPromptFromToolEvent(eventData) {
|
|
72
|
+
if (!eventData || typeof eventData !== 'object') {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
const payload = eventData;
|
|
76
|
+
const toolExecution = payload.toolExecution && typeof payload.toolExecution === 'object'
|
|
77
|
+
? payload.toolExecution
|
|
78
|
+
: null;
|
|
79
|
+
const metadata = toolExecution?.metadata && typeof toolExecution.metadata === 'object'
|
|
80
|
+
? toolExecution.metadata
|
|
81
|
+
: null;
|
|
82
|
+
const prompt = metadata?.hitlPrompt && typeof metadata.hitlPrompt === 'object'
|
|
83
|
+
? metadata.hitlPrompt
|
|
84
|
+
: null;
|
|
85
|
+
if (!toolExecution || !prompt) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
const chatId = prompt.chatId ? String(prompt.chatId) : (payload.chatId ? String(payload.chatId) : null);
|
|
89
|
+
return normalizePromptPayload(prompt, chatId);
|
|
90
|
+
}
|
|
67
91
|
export function parseHitlOptionRequest(eventData) {
|
|
68
92
|
return parseHitlPromptRequest(eventData);
|
|
69
93
|
}
|
|
@@ -85,3 +109,14 @@ export function resolveHitlOptionSelectionInput(options, rawInput, fallbackOptio
|
|
|
85
109
|
}
|
|
86
110
|
return null;
|
|
87
111
|
}
|
|
112
|
+
export function markHitlRequestHandled(handledRequestIds, requestId) {
|
|
113
|
+
const normalizedRequestId = String(requestId || '').trim();
|
|
114
|
+
if (!normalizedRequestId) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
if (handledRequestIds.has(normalizedRequestId)) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
handledRequestIds.add(normalizedRequestId);
|
|
121
|
+
return true;
|
|
122
|
+
}
|