@jungjaehoon/mama-os 0.19.1 → 0.20.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/CHANGELOG.md +43 -0
- package/README.md +40 -20
- package/dist/agent/agent-loop.d.ts +7 -1
- package/dist/agent/agent-loop.d.ts.map +1 -1
- package/dist/agent/agent-loop.js +150 -20
- package/dist/agent/agent-loop.js.map +1 -1
- package/dist/agent/code-act/host-bridge.d.ts +3 -1
- package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
- package/dist/agent/code-act/host-bridge.js +28 -4
- package/dist/agent/code-act/host-bridge.js.map +1 -1
- package/dist/agent/delegation-executor.d.ts +49 -0
- package/dist/agent/delegation-executor.d.ts.map +1 -0
- package/dist/agent/delegation-executor.js +692 -0
- package/dist/agent/delegation-executor.js.map +1 -0
- package/dist/agent/gateway-tool-executor.d.ts +41 -14
- package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
- package/dist/agent/gateway-tool-executor.js +718 -685
- package/dist/agent/gateway-tool-executor.js.map +1 -1
- package/dist/agent/gateway-tools.md +3 -1
- package/dist/agent/mama-tool-handlers.d.ts +2 -2
- package/dist/agent/mama-tool-handlers.d.ts.map +1 -1
- package/dist/agent/mama-tool-handlers.js +60 -10
- package/dist/agent/mama-tool-handlers.js.map +1 -1
- package/dist/agent/persistent-cli-process.d.ts +35 -0
- package/dist/agent/persistent-cli-process.d.ts.map +1 -1
- package/dist/agent/persistent-cli-process.js +193 -16
- package/dist/agent/persistent-cli-process.js.map +1 -1
- package/dist/agent/post-tool-handler.d.ts +3 -2
- package/dist/agent/post-tool-handler.d.ts.map +1 -1
- package/dist/agent/post-tool-handler.js +22 -11
- package/dist/agent/post-tool-handler.js.map +1 -1
- package/dist/agent/pre-compact-handler.d.ts +3 -2
- package/dist/agent/pre-compact-handler.d.ts.map +1 -1
- package/dist/agent/pre-compact-handler.js +8 -12
- package/dist/agent/pre-compact-handler.js.map +1 -1
- package/dist/agent/tool-registry.d.ts.map +1 -1
- package/dist/agent/tool-registry.js +1 -1
- package/dist/agent/tool-registry.js.map +1 -1
- package/dist/agent/types.d.ts +125 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/api/agent-graph-handler.d.ts +9 -0
- package/dist/api/agent-graph-handler.d.ts.map +1 -0
- package/dist/api/agent-graph-handler.js +543 -0
- package/dist/api/agent-graph-handler.js.map +1 -0
- package/dist/api/agent-raw-handler.d.ts +56 -0
- package/dist/api/agent-raw-handler.d.ts.map +1 -0
- package/dist/api/agent-raw-handler.js +248 -0
- package/dist/api/agent-raw-handler.js.map +1 -0
- package/dist/api/agent-situation-handler.d.ts +14 -0
- package/dist/api/agent-situation-handler.d.ts.map +1 -0
- package/dist/api/agent-situation-handler.js +383 -0
- package/dist/api/agent-situation-handler.js.map +1 -0
- package/dist/api/auth-middleware.d.ts +1 -0
- package/dist/api/auth-middleware.d.ts.map +1 -1
- package/dist/api/auth-middleware.js +30 -0
- package/dist/api/auth-middleware.js.map +1 -1
- package/dist/api/graph-api.d.ts.map +1 -1
- package/dist/api/graph-api.js +62 -0
- package/dist/api/graph-api.js.map +1 -1
- package/dist/api/index.d.ts +20 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +49 -2
- package/dist/api/index.js.map +1 -1
- package/dist/api/memory-provenance-handler.d.ts +3 -0
- package/dist/api/memory-provenance-handler.d.ts.map +1 -0
- package/dist/api/memory-provenance-handler.js +120 -0
- package/dist/api/memory-provenance-handler.js.map +1 -0
- package/dist/api/worker-envelope.d.ts +26 -0
- package/dist/api/worker-envelope.d.ts.map +1 -0
- package/dist/api/worker-envelope.js +176 -0
- package/dist/api/worker-envelope.js.map +1 -0
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +145 -16
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/stop.d.ts +5 -0
- package/dist/cli/commands/stop.d.ts.map +1 -1
- package/dist/cli/commands/stop.js +220 -18
- package/dist/cli/commands/stop.js.map +1 -1
- package/dist/cli/config/types.d.ts +6 -0
- package/dist/cli/config/types.d.ts.map +1 -1
- package/dist/cli/config/types.js.map +1 -1
- package/dist/cli/runtime/agent-loop-init.d.ts +2 -0
- package/dist/cli/runtime/agent-loop-init.d.ts.map +1 -1
- package/dist/cli/runtime/agent-loop-init.js +3 -4
- package/dist/cli/runtime/agent-loop-init.js.map +1 -1
- package/dist/cli/runtime/api-server-init.d.ts +5 -2
- package/dist/cli/runtime/api-server-init.d.ts.map +1 -1
- package/dist/cli/runtime/api-server-init.js +4 -1
- package/dist/cli/runtime/api-server-init.js.map +1 -1
- package/dist/cli/runtime/connector-init.d.ts +12 -4
- package/dist/cli/runtime/connector-init.d.ts.map +1 -1
- package/dist/cli/runtime/connector-init.js +44 -51
- package/dist/cli/runtime/connector-init.js.map +1 -1
- package/dist/cli/runtime/envelope-bootstrap.d.ts +16 -0
- package/dist/cli/runtime/envelope-bootstrap.d.ts.map +1 -0
- package/dist/cli/runtime/envelope-bootstrap.js +39 -0
- package/dist/cli/runtime/envelope-bootstrap.js.map +1 -0
- package/dist/cli/runtime/memory-agent-init.d.ts.map +1 -1
- package/dist/cli/runtime/memory-agent-init.js +4 -1
- package/dist/cli/runtime/memory-agent-init.js.map +1 -1
- package/dist/connectors/framework/polling-scheduler.d.ts +3 -1
- package/dist/connectors/framework/polling-scheduler.d.ts.map +1 -1
- package/dist/connectors/framework/polling-scheduler.js +6 -1
- package/dist/connectors/framework/polling-scheduler.js.map +1 -1
- package/dist/connectors/framework/raw-store.d.ts +29 -0
- package/dist/connectors/framework/raw-store.d.ts.map +1 -1
- package/dist/connectors/framework/raw-store.js +154 -4
- package/dist/connectors/framework/raw-store.js.map +1 -1
- package/dist/connectors/framework/types.d.ts +6 -0
- package/dist/connectors/framework/types.d.ts.map +1 -1
- package/dist/db/agent-store.d.ts +29 -1
- package/dist/db/agent-store.d.ts.map +1 -1
- package/dist/db/agent-store.js +89 -6
- package/dist/db/agent-store.js.map +1 -1
- package/dist/db/migrations/agent-activity-envelope-hash.d.ts +3 -0
- package/dist/db/migrations/agent-activity-envelope-hash.d.ts.map +1 -0
- package/dist/db/migrations/agent-activity-envelope-hash.js +29 -0
- package/dist/db/migrations/agent-activity-envelope-hash.js.map +1 -0
- package/dist/db/migrations/agent-activity-gateway-call-id.d.ts +3 -0
- package/dist/db/migrations/agent-activity-gateway-call-id.d.ts.map +1 -0
- package/dist/db/migrations/agent-activity-gateway-call-id.js +17 -0
- package/dist/db/migrations/agent-activity-gateway-call-id.js.map +1 -0
- package/dist/db/migrations/agent-store-tables.d.ts.map +1 -1
- package/dist/db/migrations/agent-store-tables.js +5 -0
- package/dist/db/migrations/agent-store-tables.js.map +1 -1
- package/dist/db/migrations/envelope-tables.d.ts +3 -0
- package/dist/db/migrations/envelope-tables.d.ts.map +1 -0
- package/dist/db/migrations/envelope-tables.js +38 -0
- package/dist/db/migrations/envelope-tables.js.map +1 -0
- package/dist/envelope/authority.d.ts +15 -0
- package/dist/envelope/authority.d.ts.map +1 -0
- package/dist/envelope/authority.js +95 -0
- package/dist/envelope/authority.js.map +1 -0
- package/dist/envelope/canonical.d.ts +14 -0
- package/dist/envelope/canonical.d.ts.map +1 -0
- package/dist/envelope/canonical.js +68 -0
- package/dist/envelope/canonical.js.map +1 -0
- package/dist/envelope/enforcer.d.ts +15 -0
- package/dist/envelope/enforcer.d.ts.map +1 -0
- package/dist/envelope/enforcer.js +177 -0
- package/dist/envelope/enforcer.js.map +1 -0
- package/dist/envelope/expiry.d.ts +2 -0
- package/dist/envelope/expiry.d.ts.map +1 -0
- package/dist/envelope/expiry.js +15 -0
- package/dist/envelope/expiry.js.map +1 -0
- package/dist/envelope/index.d.ts +10 -0
- package/dist/envelope/index.d.ts.map +1 -0
- package/dist/envelope/index.js +26 -0
- package/dist/envelope/index.js.map +1 -0
- package/dist/envelope/key-provider.d.ts +6 -0
- package/dist/envelope/key-provider.d.ts.map +1 -0
- package/dist/envelope/key-provider.js +51 -0
- package/dist/envelope/key-provider.js.map +1 -0
- package/dist/envelope/reactive-config.d.ts +24 -0
- package/dist/envelope/reactive-config.d.ts.map +1 -0
- package/dist/envelope/reactive-config.js +154 -0
- package/dist/envelope/reactive-config.js.map +1 -0
- package/dist/envelope/signature.d.ts +16 -0
- package/dist/envelope/signature.d.ts.map +1 -0
- package/dist/envelope/signature.js +82 -0
- package/dist/envelope/signature.js.map +1 -0
- package/dist/envelope/store.d.ts +16 -0
- package/dist/envelope/store.d.ts.map +1 -0
- package/dist/envelope/store.js +118 -0
- package/dist/envelope/store.js.map +1 -0
- package/dist/envelope/subset.d.ts +9 -0
- package/dist/envelope/subset.d.ts.map +1 -0
- package/dist/envelope/subset.js +67 -0
- package/dist/envelope/subset.js.map +1 -0
- package/dist/envelope/types.d.ts +60 -0
- package/dist/envelope/types.d.ts.map +1 -0
- package/dist/envelope/types.js +9 -0
- package/dist/envelope/types.js.map +1 -0
- package/dist/gateways/message-router.d.ts +17 -29
- package/dist/gateways/message-router.d.ts.map +1 -1
- package/dist/gateways/message-router.js +97 -41
- package/dist/gateways/message-router.js.map +1 -1
- package/dist/memory/audit-task-queue.d.ts +1 -0
- package/dist/memory/audit-task-queue.d.ts.map +1 -1
- package/dist/memory/audit-task-queue.js.map +1 -1
- package/dist/multi-agent/agent-process-manager.d.ts.map +1 -1
- package/dist/multi-agent/agent-process-manager.js +4 -4
- package/dist/multi-agent/agent-process-manager.js.map +1 -1
- package/dist/multi-agent/swarm/swarm-mama-adapter.d.ts +33 -2
- package/dist/multi-agent/swarm/swarm-mama-adapter.d.ts.map +1 -1
- package/dist/multi-agent/swarm/swarm-mama-adapter.js +7 -8
- package/dist/multi-agent/swarm/swarm-mama-adapter.js.map +1 -1
- package/package.json +2 -2
- package/scripts/generate-gateway-tools.ts +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,49 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.20.0] - 2026-05-01
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Reactive envelope runtime** — Standalone now issues and stores signed gateway envelopes, exposes
|
|
15
|
+
public health separately from authenticated envelope status, and audits scope mismatches through
|
|
16
|
+
`agent_activity`
|
|
17
|
+
- **Worker evidence APIs** — Added authenticated memory provenance, raw search, agent situation,
|
|
18
|
+
and agent graph/entity API handlers so workers can retrieve bounded evidence without direct DB
|
|
19
|
+
access
|
|
20
|
+
- **Envelope-aware gateway tooling** — Code-Act, gateway execution, internal agent-loop calls, and
|
|
21
|
+
model/tool trace paths now propagate envelope context for trusted provenance
|
|
22
|
+
- **Strict `mama_search` controls** — Gateway, MCP, Code-Act, ToolRegistry, and generated tool docs
|
|
23
|
+
now expose `scopes`, `strict`, `strictness`, `threshold`, `disableRecency`, `includeRelated`,
|
|
24
|
+
`topicPrefix`, `minLexicalSupport`, and `diagnostics`
|
|
25
|
+
- **Persistent process cleanup settings** — `timeouts.persistent_process_idle_ms`,
|
|
26
|
+
`timeouts.persistent_process_cleanup_ms`, and `timeouts.persistent_process_pending_tool_ms`
|
|
27
|
+
let operators tune how aggressively idle CLI processes are reclaimed
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- **Gateway executor architecture** — Delegation execution and gateway tool execution were split
|
|
32
|
+
into clearer modules, with ToolRegistry kept as the valid-tool source of truth for generated
|
|
33
|
+
prompts and executor validation
|
|
34
|
+
- **Connector raw stores** — Raw connector persistence now writes provenance and unified indexes so
|
|
35
|
+
worker APIs can query raw evidence consistently
|
|
36
|
+
- **Envelope-aware memory search** — `mama_search` now defaults to effective envelope scopes and
|
|
37
|
+
rejects caller scopes outside the active envelope before searching
|
|
38
|
+
- **Search diagnostics preservation** — Standalone search result types and handler responses now
|
|
39
|
+
keep `diagnostics`, `retrieval_diagnostics`, and `contributing_leaf_diagnostics` instead of
|
|
40
|
+
dropping them at API boundaries
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
- **Envelope hardening** — Reactive envelope startup, internal tool contexts, scope mismatch
|
|
45
|
+
logging, authenticated status reporting, worker graph/entity visibility, and graph API internal
|
|
46
|
+
error responses now have review-driven regression coverage
|
|
47
|
+
- **Scoped recent-list search** — No-query `mama_search` now passes scopes into recent decision
|
|
48
|
+
listing instead of returning global recent decisions
|
|
49
|
+
- **Long-lived Claude process buildup** — Persistent CLI processes are now reclaimed after idle
|
|
50
|
+
timeouts while active tool-result loops keep a bounded lease; `mama stop` also avoids unsafe
|
|
51
|
+
broad kills and handles large `ps` output safely
|
|
52
|
+
|
|
10
53
|
## [0.19.1] - 2026-04-20
|
|
11
54
|
|
|
12
55
|
### Fixed
|
package/README.md
CHANGED
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
# @jungjaehoon/mama-os
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Bounded, provenance-backed working context for AI agents running on your machine.
|
|
4
4
|
|
|
5
5
|
## The Problem
|
|
6
6
|
|
|
7
7
|
Your knowledge is everywhere — Slack threads, email chains, code reviews, meeting notes, spreadsheets, Telegram messages. No human can track all of it. Important decisions get buried. Context gets lost between tools. When you need to make a decision, the information that would help is scattered across ten different apps and three months of history.
|
|
8
8
|
|
|
9
|
-
This isn't a memory problem. It's
|
|
9
|
+
This isn't just a memory problem. It's a bounded context problem. You don't just need to
|
|
10
|
+
_store_ information — you need something that reads everything, connects the dots, identifies what
|
|
11
|
+
matters, proves where it came from, and keeps agents inside the scope they were given.
|
|
10
12
|
|
|
11
13
|
## What MAMA OS Does
|
|
12
14
|
|
|
13
|
-
MAMA OS is a local AI runtime that connects to your apps, reads
|
|
15
|
+
MAMA OS is a local AI runtime that connects to your apps, reads continuously, and turns scattered
|
|
16
|
+
records into scoped, auditable context for agents and humans.
|
|
14
17
|
|
|
15
18
|
**What the agents actually do:**
|
|
16
19
|
|
|
17
20
|
- **Identify what matters** — Out of thousands of daily messages, surface the decisions, deadlines, and changes that affect your work
|
|
18
21
|
- **Connect across sources** — A Slack conversation + a Trello card + an email attachment about the same project are linked automatically
|
|
19
22
|
- **Track decision evolution** — Not just what was decided, but what it replaced, what it builds on, and what it contradicts
|
|
23
|
+
- **Operate inside envelopes** — Gateway and worker calls carry signed scope boundaries and audit rows
|
|
24
|
+
- **Preserve provenance** — Memory writes can point back to source refs, model runs, tool traces, and envelope hashes
|
|
25
|
+
- **Search with evidence** — Strict memory search can reject vector-only noise and show which lexical, entity, scope, or graph signals confirmed a result
|
|
20
26
|
- **Compile actionable knowledge** — Raw conversations become structured wiki pages with priorities, gaps, and suggested next steps
|
|
21
27
|
- **Brief you proactively** — When you start working, relevant context from all sources is already there — you didn't ask for it
|
|
22
28
|
|
|
@@ -28,7 +34,8 @@ With MAMA: Agents already read everything. You get a briefing with
|
|
|
28
34
|
what changed, what's at risk, and what needs your decision.
|
|
29
35
|
```
|
|
30
36
|
|
|
31
|
-
**This is what AI agents
|
|
37
|
+
**This is what local AI agents should do** — read every channel, every thread, every document, every
|
|
38
|
+
day, then explain exactly which evidence they used and which permission boundary they were inside.
|
|
32
39
|
|
|
33
40
|
- **Private by design** — All data stays on your device. Nothing leaves your machine.
|
|
34
41
|
- **AI-independent** — Works with Claude, Codex, or any future backend. Your memory outlives any AI provider.
|
|
@@ -49,6 +56,10 @@ mama start # That's it. MAMA uses your existing CLI authentication.
|
|
|
49
56
|
MAMA OS has full system access — so security is not optional, it's foundational.
|
|
50
57
|
|
|
51
58
|
- **Local-only by default** — Binds to localhost. External access requires explicit tunnel setup with authentication (Cloudflare Zero Trust).
|
|
59
|
+
- **Signed runtime envelopes** — Gateway and worker tool calls carry verifiable scope, expiry, and
|
|
60
|
+
actor context before irreversible side effects are allowed.
|
|
61
|
+
- **Provenance ledger** — Memory writes, raw refs, model runs, and tool traces can be audited after
|
|
62
|
+
the fact without exposing prompt bodies or hidden connector payloads.
|
|
52
63
|
- **5-layer prompt injection defense** — Output sanitization, channel trust boundaries, silent mode for unknown sources, bulk extraction limits. Built from a real incident, not theory.
|
|
53
64
|
- **Intrusion detection** — Honeypot traps for scanner probes (`.git`, `.env`, `wp-login.php`), per-IP suspicion scoring, automatic tarpit delays, and IP deny-listing when thresholds are exceeded.
|
|
54
65
|
- **Agent permission tiers** — Tier 1 (full access), Tier 2 (read-only), Tier 3 (scoped read-only). Each agent only gets the tools it needs.
|
|
@@ -139,20 +150,21 @@ Run MAMA as a bot in Discord, Slack, Telegram, or Chatwork. Configure via `mama
|
|
|
139
150
|
## Architecture
|
|
140
151
|
|
|
141
152
|
```
|
|
142
|
-
Connectors (15)
|
|
143
|
-
Slack, Gmail, Sheets...
|
|
144
|
-
|
|
|
145
|
-
v
|
|
146
|
-
3-Pass Extraction
|
|
147
|
-
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
Connectors (15) Gateways (4)
|
|
154
|
+
Slack, Gmail, Sheets... Discord, Slack, Telegram, Chatwork
|
|
155
|
+
| |
|
|
156
|
+
v v
|
|
157
|
+
3-Pass Extraction Reactive Runtime Envelopes
|
|
158
|
+
| scope, expiry, signature, audit
|
|
159
|
+
+------------+---------------+
|
|
160
|
+
|
|
|
161
|
+
MAMA Core (mama-memory.db)
|
|
162
|
+
memory, raw refs, model runs,
|
|
163
|
+
tool traces, twin edges, packets
|
|
164
|
+
|
|
|
165
|
+
+------+------+
|
|
166
|
+
| |
|
|
167
|
+
Viewer UI Claude Code Plugin / MCP
|
|
156
168
|
```
|
|
157
169
|
|
|
158
170
|
## CLI
|
|
@@ -176,6 +188,14 @@ Main config: `~/.mama/config.yaml`
|
|
|
176
188
|
| `MAMA_HTTP_PORT` | `3847` |
|
|
177
189
|
| `MAMA_WORKSPACE` | `~/.mama/workspace` |
|
|
178
190
|
|
|
191
|
+
Timeout tuning lives under `timeouts` in `config.yaml`. The persistent CLI process pool supports:
|
|
192
|
+
|
|
193
|
+
| Option | Default | Purpose |
|
|
194
|
+
| ------------------------------------ | --------------------------- | ------------------------------------------- |
|
|
195
|
+
| `persistent_process_idle_ms` | `session_ms` | Reclaim idle Claude/Codex CLI processes |
|
|
196
|
+
| `persistent_process_cleanup_ms` | `session_cleanup_ms` | How often idle-process cleanup runs |
|
|
197
|
+
| `persistent_process_pending_tool_ms` | `max(4 * idle, 30 minutes)` | Max wait for pending tool-result handshakes |
|
|
198
|
+
|
|
179
199
|
## Related Packages
|
|
180
200
|
|
|
181
201
|
| Package | Purpose |
|
|
@@ -189,7 +209,7 @@ Main config: `~/.mama/config.yaml`
|
|
|
189
209
|
```bash
|
|
190
210
|
git clone https://github.com/jungjaehoon-lifegamez/MAMA.git
|
|
191
211
|
cd MAMA && pnpm install && pnpm build
|
|
192
|
-
pnpm test #
|
|
212
|
+
pnpm test # 3000+ tests across all packages
|
|
193
213
|
```
|
|
194
214
|
|
|
195
215
|
## Links
|
|
@@ -202,4 +222,4 @@ MIT
|
|
|
202
222
|
|
|
203
223
|
---
|
|
204
224
|
|
|
205
|
-
**Last Updated:** 2026-04-
|
|
225
|
+
**Last Updated:** 2026-04-30
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* - Loops until stop_reason is "end_turn" or max turns reached
|
|
11
11
|
*/
|
|
12
12
|
import type { OAuthManager } from '../auth/index.js';
|
|
13
|
-
import type { ContentBlock, ToolDefinition, AgentLoopOptions, AgentLoopResult, ClaudeClientOptions, GatewayToolExecutorOptions, AgentContext } from './types.js';
|
|
13
|
+
import type { ContentBlock, ToolDefinition, AgentLoopOptions, AgentLoopResult, ClaudeClientOptions, GatewayToolExecutorOptions, AgentContext, GatewayToolExecutionContext } from './types.js';
|
|
14
14
|
/**
|
|
15
15
|
* Load composed system prompt with persona layers + CLAUDE.md + optional context
|
|
16
16
|
* Tries to load persona files from ~/.mama/ in order:
|
|
@@ -32,6 +32,8 @@ import type { ContentBlock, ToolDefinition, AgentLoopOptions, AgentLoopResult, C
|
|
|
32
32
|
export declare function loadBackendAgentsMd(backend?: string, verbose?: boolean): string;
|
|
33
33
|
export declare function loadComposedSystemPrompt(verbose?: boolean, context?: AgentContext): string;
|
|
34
34
|
export declare function getGatewayToolsPrompt(disallowed?: string[]): string;
|
|
35
|
+
export type AgentToolExecutionContext = GatewayToolExecutionContext;
|
|
36
|
+
export declare function buildAgentToolExecutionContext(options?: AgentLoopOptions): AgentToolExecutionContext | null;
|
|
35
37
|
export declare class AgentLoop {
|
|
36
38
|
private readonly agent;
|
|
37
39
|
private readonly persistentCLI;
|
|
@@ -172,6 +174,10 @@ export declare class AgentLoop {
|
|
|
172
174
|
* Internal implementation of runWithContent (without lane queueing)
|
|
173
175
|
*/
|
|
174
176
|
private runWithContentInternal;
|
|
177
|
+
private shouldBeginModelRun;
|
|
178
|
+
private withBackgroundTaskRegistry;
|
|
179
|
+
private drainBackgroundTasks;
|
|
180
|
+
private buildModelRunInput;
|
|
175
181
|
/**
|
|
176
182
|
* Execute tools from response content blocks
|
|
177
183
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../../src/agent/agent-loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAqBH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAIrD,OAAO,KAAK,EAEV,YAAY,EAIZ,cAAc,EACd,gBAAgB,EAChB,eAAe,EAIf,mBAAmB,EACnB,0BAA0B,
|
|
1
|
+
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../../src/agent/agent-loop.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/agent-loop.js
CHANGED
|
@@ -48,6 +48,7 @@ exports.AgentLoop = void 0;
|
|
|
48
48
|
exports.loadBackendAgentsMd = loadBackendAgentsMd;
|
|
49
49
|
exports.loadComposedSystemPrompt = loadComposedSystemPrompt;
|
|
50
50
|
exports.getGatewayToolsPrompt = getGatewayToolsPrompt;
|
|
51
|
+
exports.buildAgentToolExecutionContext = buildAgentToolExecutionContext;
|
|
51
52
|
const fs_1 = require("fs");
|
|
52
53
|
const prompt_size_monitor_js_1 = require("./prompt-size-monitor.js");
|
|
53
54
|
const skill_loader_js_1 = require("./skill-loader.js");
|
|
@@ -249,6 +250,53 @@ function getGatewayToolsPrompt(disallowed) {
|
|
|
249
250
|
}
|
|
250
251
|
return filtered;
|
|
251
252
|
}
|
|
253
|
+
function buildAgentToolExecutionContext(options) {
|
|
254
|
+
if (!options ||
|
|
255
|
+
(options.agentContext === undefined &&
|
|
256
|
+
options.source === undefined &&
|
|
257
|
+
options.channelId === undefined &&
|
|
258
|
+
options.envelope === undefined &&
|
|
259
|
+
options.sourceTurnId === undefined &&
|
|
260
|
+
options.sourceMessageRef === undefined &&
|
|
261
|
+
options.modelRunId === undefined)) {
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
const agentContext = options.agentContext;
|
|
265
|
+
const context = {
|
|
266
|
+
agentContext,
|
|
267
|
+
agentId: agentContext
|
|
268
|
+
? agentContext.source === 'viewer'
|
|
269
|
+
? 'os-agent'
|
|
270
|
+
: agentContext.roleName
|
|
271
|
+
: undefined,
|
|
272
|
+
source: options.source,
|
|
273
|
+
channelId: options.channelId,
|
|
274
|
+
envelope: options.envelope,
|
|
275
|
+
executionSurface: 'model_tool',
|
|
276
|
+
};
|
|
277
|
+
if (options.sourceTurnId !== undefined) {
|
|
278
|
+
context.sourceTurnId = options.sourceTurnId;
|
|
279
|
+
}
|
|
280
|
+
if (options.sourceMessageRef !== undefined) {
|
|
281
|
+
context.sourceMessageRef = options.sourceMessageRef;
|
|
282
|
+
}
|
|
283
|
+
if (options.modelRunId !== undefined) {
|
|
284
|
+
context.modelRunId = options.modelRunId;
|
|
285
|
+
}
|
|
286
|
+
return context;
|
|
287
|
+
}
|
|
288
|
+
function withExecutionSurface(executionContext, executionSurface) {
|
|
289
|
+
if (!executionContext) {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
if (executionContext.executionSurface === executionSurface) {
|
|
293
|
+
return executionContext;
|
|
294
|
+
}
|
|
295
|
+
return {
|
|
296
|
+
...executionContext,
|
|
297
|
+
executionSurface,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
252
300
|
class AgentLoop {
|
|
253
301
|
agent;
|
|
254
302
|
persistentCLI = null;
|
|
@@ -469,7 +517,7 @@ class AgentLoop {
|
|
|
469
517
|
this.sessionPool = (0, session_pool_js_1.getSessionPool)();
|
|
470
518
|
// Initialize PostToolHandler (fire-and-forget after tool execution)
|
|
471
519
|
if (options.postToolUse?.enabled) {
|
|
472
|
-
this.postToolHandler = new post_tool_handler_js_1.PostToolHandler((name, input) => this.mcpExecutor.execute(name, input), { enabled: true, contractSaveLimit: options.postToolUse.contractSaveLimit });
|
|
520
|
+
this.postToolHandler = new post_tool_handler_js_1.PostToolHandler((name, input, executionContext) => this.mcpExecutor.execute(name, input, executionContext ?? undefined), { enabled: true, contractSaveLimit: options.postToolUse.contractSaveLimit });
|
|
473
521
|
console.log('[AgentLoop] PostToolHandler enabled');
|
|
474
522
|
}
|
|
475
523
|
else {
|
|
@@ -477,7 +525,7 @@ class AgentLoop {
|
|
|
477
525
|
}
|
|
478
526
|
// Initialize PreCompactHandler (unsaved decision detection)
|
|
479
527
|
if (options.preCompact?.enabled) {
|
|
480
|
-
this.preCompactHandler = new pre_compact_handler_js_1.PreCompactHandler((name, input) => this.mcpExecutor.execute(name, input), { enabled: true, maxDecisionsToDetect: options.preCompact.maxDecisionsToDetect });
|
|
528
|
+
this.preCompactHandler = new pre_compact_handler_js_1.PreCompactHandler((name, input, executionContext) => this.mcpExecutor.execute(name, input, executionContext ?? undefined), { enabled: true, maxDecisionsToDetect: options.preCompact.maxDecisionsToDetect });
|
|
481
529
|
console.log('[AgentLoop] PreCompactHandler enabled');
|
|
482
530
|
}
|
|
483
531
|
else {
|
|
@@ -525,15 +573,7 @@ class AgentLoop {
|
|
|
525
573
|
return SOURCE_GLOBAL_LANES[source];
|
|
526
574
|
}
|
|
527
575
|
buildToolExecutionContext(options) {
|
|
528
|
-
|
|
529
|
-
return null;
|
|
530
|
-
}
|
|
531
|
-
return {
|
|
532
|
-
agentContext: options.agentContext,
|
|
533
|
-
agentId: options.agentContext.source === 'viewer' ? 'os-agent' : options.agentContext.roleName,
|
|
534
|
-
source: options.source,
|
|
535
|
-
channelId: options.channelId,
|
|
536
|
-
};
|
|
576
|
+
return buildAgentToolExecutionContext(options);
|
|
537
577
|
}
|
|
538
578
|
/**
|
|
539
579
|
* Set system prompt override (for per-message context injection)
|
|
@@ -675,7 +715,19 @@ class AgentLoop {
|
|
|
675
715
|
const totalUsage = { input_tokens: 0, output_tokens: 0 };
|
|
676
716
|
let turn = 0;
|
|
677
717
|
let stopReason = 'end_turn';
|
|
678
|
-
|
|
718
|
+
let ownedModelRunId = null;
|
|
719
|
+
let ownedModelRunCommitted = false;
|
|
720
|
+
const pendingBackgroundTasks = [];
|
|
721
|
+
const backgroundTasks = {
|
|
722
|
+
register(task) {
|
|
723
|
+
const observedTask = Promise.resolve(task);
|
|
724
|
+
observedTask.catch(() => {
|
|
725
|
+
// Re-thrown later by drainBackgroundTasks; attach now to prevent unhandled rejections.
|
|
726
|
+
});
|
|
727
|
+
pendingBackgroundTasks.push(observedTask);
|
|
728
|
+
},
|
|
729
|
+
};
|
|
730
|
+
let toolExecutionContext = this.withBackgroundTaskRegistry(this.buildToolExecutionContext(options), backgroundTasks);
|
|
679
731
|
// Track current tier for code-act execution and prompt sizing.
|
|
680
732
|
if (options?.agentContext) {
|
|
681
733
|
const rawTier = options.agentContext.tier ?? 1;
|
|
@@ -700,6 +752,7 @@ class AgentLoop {
|
|
|
700
752
|
// Claude PersistentCLI: process alive → CONTINUE (stdin message), process dead → NEW (spawn with --session-id)
|
|
701
753
|
// Codex: threadId alive → CONTINUE (codex-reply), threadId null → NEW (codex tool)
|
|
702
754
|
const isCodex = this.backend === 'codex-mcp';
|
|
755
|
+
let resolvedCliSessionId = options?.cliSessionId ?? null;
|
|
703
756
|
const sessionLabel = (isNew) => {
|
|
704
757
|
if (isCodex) {
|
|
705
758
|
return isNew ? 'NEW thread' : 'CONTINUE thread';
|
|
@@ -719,10 +772,19 @@ class AgentLoop {
|
|
|
719
772
|
}
|
|
720
773
|
sessionIsNew = isNew;
|
|
721
774
|
ownedSession = true;
|
|
775
|
+
resolvedCliSessionId = cliSessionId;
|
|
722
776
|
this.agent.setSessionId(cliSessionId);
|
|
723
777
|
console.log(`[AgentLoop] [${isCodex ? 'codex' : 'claude'}] ${channelKey} (${sessionLabel(isNew)})`);
|
|
724
778
|
}
|
|
725
779
|
try {
|
|
780
|
+
if (this.shouldBeginModelRun(options)) {
|
|
781
|
+
const modelRun = await this.mcpExecutor.beginRuntimeModelRun(this.buildModelRunInput(options, resolvedCliSessionId));
|
|
782
|
+
ownedModelRunId = modelRun.model_run_id;
|
|
783
|
+
toolExecutionContext = this.withBackgroundTaskRegistry(this.buildToolExecutionContext({
|
|
784
|
+
...options,
|
|
785
|
+
modelRunId: ownedModelRunId,
|
|
786
|
+
}), backgroundTasks);
|
|
787
|
+
}
|
|
726
788
|
if (options?.systemPrompt) {
|
|
727
789
|
// Skip gateway tools if already embedded in systemPrompt (e.g. by MessageRouter)
|
|
728
790
|
const alreadyHasTools = options.systemPrompt.includes('## Gateway Tools') ||
|
|
@@ -968,7 +1030,7 @@ class AgentLoop {
|
|
|
968
1030
|
.map((b) => b.text)
|
|
969
1031
|
.join('\n');
|
|
970
1032
|
});
|
|
971
|
-
const compactResult = await this.preCompactHandler.process(historyText);
|
|
1033
|
+
const compactResult = await this.preCompactHandler.process(historyText, withExecutionSurface(toolExecutionContext, 'reactive_internal'));
|
|
972
1034
|
if (compactResult.compactionPrompt) {
|
|
973
1035
|
history.push({
|
|
974
1036
|
role: 'user',
|
|
@@ -1061,13 +1123,39 @@ class AgentLoop {
|
|
|
1061
1123
|
}
|
|
1062
1124
|
// Extract final text response
|
|
1063
1125
|
const finalResponse = this.extractTextResponse(history);
|
|
1064
|
-
|
|
1126
|
+
const result = {
|
|
1065
1127
|
response: finalResponse,
|
|
1066
1128
|
turns: turn,
|
|
1067
1129
|
history,
|
|
1068
1130
|
totalUsage,
|
|
1069
1131
|
stopReason,
|
|
1132
|
+
modelRunId: ownedModelRunId ?? options?.modelRunId ?? null,
|
|
1070
1133
|
};
|
|
1134
|
+
try {
|
|
1135
|
+
await this.drainBackgroundTasks(pendingBackgroundTasks);
|
|
1136
|
+
if (ownedModelRunId) {
|
|
1137
|
+
await this.mcpExecutor.commitRuntimeModelRun(ownedModelRunId, 'agent_loop completed');
|
|
1138
|
+
ownedModelRunCommitted = true;
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
catch (finalizationError) {
|
|
1142
|
+
logger.warn(`AgentLoop post-run finalization failed: ${finalizationError instanceof Error
|
|
1143
|
+
? finalizationError.message
|
|
1144
|
+
: String(finalizationError)}`);
|
|
1145
|
+
}
|
|
1146
|
+
return result;
|
|
1147
|
+
}
|
|
1148
|
+
catch (error) {
|
|
1149
|
+
if (ownedModelRunId && !ownedModelRunCommitted) {
|
|
1150
|
+
try {
|
|
1151
|
+
const summary = error instanceof Error ? error.message : String(error);
|
|
1152
|
+
await this.mcpExecutor.failRuntimeModelRun(ownedModelRunId, summary);
|
|
1153
|
+
}
|
|
1154
|
+
catch (failError) {
|
|
1155
|
+
logger.warn(`Failed to mark model run ${ownedModelRunId} failed: ${failError instanceof Error ? failError.message : String(failError)}`);
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
throw error;
|
|
1071
1159
|
}
|
|
1072
1160
|
finally {
|
|
1073
1161
|
// Always release session lock, even on error
|
|
@@ -1078,10 +1166,51 @@ class AgentLoop {
|
|
|
1078
1166
|
this.currentStreamCallbacks = undefined;
|
|
1079
1167
|
}
|
|
1080
1168
|
}
|
|
1169
|
+
shouldBeginModelRun(options) {
|
|
1170
|
+
return this.isGatewayMode && !options?.modelRunId;
|
|
1171
|
+
}
|
|
1172
|
+
withBackgroundTaskRegistry(context, backgroundTasks) {
|
|
1173
|
+
if (!context) {
|
|
1174
|
+
return null;
|
|
1175
|
+
}
|
|
1176
|
+
return {
|
|
1177
|
+
...context,
|
|
1178
|
+
backgroundTasks,
|
|
1179
|
+
};
|
|
1180
|
+
}
|
|
1181
|
+
async drainBackgroundTasks(tasks) {
|
|
1182
|
+
for (let index = 0; index < tasks.length; index += 1) {
|
|
1183
|
+
await tasks[index];
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
buildModelRunInput(options, resolvedCliSessionId) {
|
|
1187
|
+
const agentContext = options?.agentContext;
|
|
1188
|
+
return {
|
|
1189
|
+
model_id: options?.model ?? this.model ?? null,
|
|
1190
|
+
model_provider: this.backend,
|
|
1191
|
+
agent_id: agentContext?.source === 'viewer'
|
|
1192
|
+
? 'os-agent'
|
|
1193
|
+
: (agentContext?.roleName ?? options?.source ?? 'agent'),
|
|
1194
|
+
instance_id: agentContext?.session?.sessionId ?? null,
|
|
1195
|
+
envelope_hash: options?.envelope?.envelope_hash ?? null,
|
|
1196
|
+
parent_model_run_id: options?.parentModelRunId ?? null,
|
|
1197
|
+
status: 'running',
|
|
1198
|
+
input_refs: {
|
|
1199
|
+
source: options?.source ?? agentContext?.source ?? 'default',
|
|
1200
|
+
channelId: options?.channelId ?? agentContext?.session?.channelId ?? this.sessionKey,
|
|
1201
|
+
entrypoint: 'agent_loop',
|
|
1202
|
+
...(options?.sourceTurnId ? { sourceTurnId: options.sourceTurnId } : {}),
|
|
1203
|
+
...(options?.sourceMessageRef ? { sourceMessageRef: options.sourceMessageRef } : {}),
|
|
1204
|
+
...(resolvedCliSessionId ? { cliSessionId: resolvedCliSessionId } : {}),
|
|
1205
|
+
},
|
|
1206
|
+
};
|
|
1207
|
+
}
|
|
1081
1208
|
/**
|
|
1082
1209
|
* Execute tools from response content blocks
|
|
1083
1210
|
*/
|
|
1084
1211
|
async executeTools(content, stopAfterSuccessfulTools = [], executionContext = null) {
|
|
1212
|
+
const modelToolContext = withExecutionSurface(executionContext, 'model_tool');
|
|
1213
|
+
const reactiveInternalContext = withExecutionSurface(executionContext, 'reactive_internal');
|
|
1085
1214
|
const toolUseBlocks = content.filter((block) => block.type === 'tool_use');
|
|
1086
1215
|
const results = [];
|
|
1087
1216
|
for (const toolUse of toolUseBlocks) {
|
|
@@ -1097,7 +1226,7 @@ class AgentLoop {
|
|
|
1097
1226
|
const codeInput = toolUse.input;
|
|
1098
1227
|
const code = typeof codeInput?.code === 'string' ? codeInput.code : '';
|
|
1099
1228
|
const codeActResult = code
|
|
1100
|
-
? await this.executeCodeAct(code, this.currentTier)
|
|
1229
|
+
? await this.executeCodeAct(code, this.currentTier, modelToolContext)
|
|
1101
1230
|
: {
|
|
1102
1231
|
success: false,
|
|
1103
1232
|
error: {
|
|
@@ -1118,9 +1247,9 @@ class AgentLoop {
|
|
|
1118
1247
|
// PreToolUse: search MAMA for contracts before Write operations
|
|
1119
1248
|
let contractContext = '';
|
|
1120
1249
|
if (toolUse.name === 'Write' && toolUse.input) {
|
|
1121
|
-
contractContext = await this.searchContractsForTool(toolUse.name, toolUse.input,
|
|
1250
|
+
contractContext = await this.searchContractsForTool(toolUse.name, toolUse.input, reactiveInternalContext);
|
|
1122
1251
|
}
|
|
1123
|
-
const toolResult = await this.mcpExecutor.execute(toolUse.name, toolUse.input,
|
|
1252
|
+
const toolResult = await this.mcpExecutor.execute(toolUse.name, toolUse.input, modelToolContext ?? undefined);
|
|
1124
1253
|
result = JSON.stringify(toolResult, null, 2);
|
|
1125
1254
|
// Check if tool execution failed
|
|
1126
1255
|
const hasSuccess = 'success' in toolResult;
|
|
@@ -1134,7 +1263,7 @@ class AgentLoop {
|
|
|
1134
1263
|
// Notify tool use callback
|
|
1135
1264
|
this.onToolUse?.(toolUse.name, toolUse.input, toolResult);
|
|
1136
1265
|
// PostToolUse: auto-extract contracts (fire-and-forget)
|
|
1137
|
-
this.postToolHandler?.processInBackground(toolUse.name, toolUse.input, toolResult);
|
|
1266
|
+
this.postToolHandler?.processInBackground(toolUse.name, toolUse.input, toolResult, reactiveInternalContext);
|
|
1138
1267
|
// Notify stream: tool completed (check actual status)
|
|
1139
1268
|
this.currentStreamCallbacks?.onToolComplete?.(toolUse.name, toolUse.id, isError);
|
|
1140
1269
|
}
|
|
@@ -1255,10 +1384,11 @@ class AgentLoop {
|
|
|
1255
1384
|
/**
|
|
1256
1385
|
* Execute Code-Act JS code in a sandboxed QuickJS environment
|
|
1257
1386
|
*/
|
|
1258
|
-
async executeCodeAct(code, tier = 1) {
|
|
1387
|
+
async executeCodeAct(code, tier = 1, executionContext = null) {
|
|
1259
1388
|
try {
|
|
1260
1389
|
const sandbox = new index_js_1.CodeActSandbox();
|
|
1261
|
-
const
|
|
1390
|
+
const bridgeContext = withExecutionSurface(executionContext, 'code_act');
|
|
1391
|
+
const bridge = new index_js_1.HostBridge(this.mcpExecutor, undefined, bridgeContext);
|
|
1262
1392
|
bridge.onToolUse = (toolName, input, result) => {
|
|
1263
1393
|
if (result === undefined) {
|
|
1264
1394
|
// Tool starting — surface to stream
|