@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.
Files changed (190) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +40 -20
  3. package/dist/agent/agent-loop.d.ts +7 -1
  4. package/dist/agent/agent-loop.d.ts.map +1 -1
  5. package/dist/agent/agent-loop.js +150 -20
  6. package/dist/agent/agent-loop.js.map +1 -1
  7. package/dist/agent/code-act/host-bridge.d.ts +3 -1
  8. package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
  9. package/dist/agent/code-act/host-bridge.js +28 -4
  10. package/dist/agent/code-act/host-bridge.js.map +1 -1
  11. package/dist/agent/delegation-executor.d.ts +49 -0
  12. package/dist/agent/delegation-executor.d.ts.map +1 -0
  13. package/dist/agent/delegation-executor.js +692 -0
  14. package/dist/agent/delegation-executor.js.map +1 -0
  15. package/dist/agent/gateway-tool-executor.d.ts +41 -14
  16. package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
  17. package/dist/agent/gateway-tool-executor.js +718 -685
  18. package/dist/agent/gateway-tool-executor.js.map +1 -1
  19. package/dist/agent/gateway-tools.md +3 -1
  20. package/dist/agent/mama-tool-handlers.d.ts +2 -2
  21. package/dist/agent/mama-tool-handlers.d.ts.map +1 -1
  22. package/dist/agent/mama-tool-handlers.js +60 -10
  23. package/dist/agent/mama-tool-handlers.js.map +1 -1
  24. package/dist/agent/persistent-cli-process.d.ts +35 -0
  25. package/dist/agent/persistent-cli-process.d.ts.map +1 -1
  26. package/dist/agent/persistent-cli-process.js +193 -16
  27. package/dist/agent/persistent-cli-process.js.map +1 -1
  28. package/dist/agent/post-tool-handler.d.ts +3 -2
  29. package/dist/agent/post-tool-handler.d.ts.map +1 -1
  30. package/dist/agent/post-tool-handler.js +22 -11
  31. package/dist/agent/post-tool-handler.js.map +1 -1
  32. package/dist/agent/pre-compact-handler.d.ts +3 -2
  33. package/dist/agent/pre-compact-handler.d.ts.map +1 -1
  34. package/dist/agent/pre-compact-handler.js +8 -12
  35. package/dist/agent/pre-compact-handler.js.map +1 -1
  36. package/dist/agent/tool-registry.d.ts.map +1 -1
  37. package/dist/agent/tool-registry.js +1 -1
  38. package/dist/agent/tool-registry.js.map +1 -1
  39. package/dist/agent/types.d.ts +125 -1
  40. package/dist/agent/types.d.ts.map +1 -1
  41. package/dist/agent/types.js.map +1 -1
  42. package/dist/api/agent-graph-handler.d.ts +9 -0
  43. package/dist/api/agent-graph-handler.d.ts.map +1 -0
  44. package/dist/api/agent-graph-handler.js +543 -0
  45. package/dist/api/agent-graph-handler.js.map +1 -0
  46. package/dist/api/agent-raw-handler.d.ts +56 -0
  47. package/dist/api/agent-raw-handler.d.ts.map +1 -0
  48. package/dist/api/agent-raw-handler.js +248 -0
  49. package/dist/api/agent-raw-handler.js.map +1 -0
  50. package/dist/api/agent-situation-handler.d.ts +14 -0
  51. package/dist/api/agent-situation-handler.d.ts.map +1 -0
  52. package/dist/api/agent-situation-handler.js +383 -0
  53. package/dist/api/agent-situation-handler.js.map +1 -0
  54. package/dist/api/auth-middleware.d.ts +1 -0
  55. package/dist/api/auth-middleware.d.ts.map +1 -1
  56. package/dist/api/auth-middleware.js +30 -0
  57. package/dist/api/auth-middleware.js.map +1 -1
  58. package/dist/api/graph-api.d.ts.map +1 -1
  59. package/dist/api/graph-api.js +62 -0
  60. package/dist/api/graph-api.js.map +1 -1
  61. package/dist/api/index.d.ts +20 -0
  62. package/dist/api/index.d.ts.map +1 -1
  63. package/dist/api/index.js +49 -2
  64. package/dist/api/index.js.map +1 -1
  65. package/dist/api/memory-provenance-handler.d.ts +3 -0
  66. package/dist/api/memory-provenance-handler.d.ts.map +1 -0
  67. package/dist/api/memory-provenance-handler.js +120 -0
  68. package/dist/api/memory-provenance-handler.js.map +1 -0
  69. package/dist/api/worker-envelope.d.ts +26 -0
  70. package/dist/api/worker-envelope.d.ts.map +1 -0
  71. package/dist/api/worker-envelope.js +176 -0
  72. package/dist/api/worker-envelope.js.map +1 -0
  73. package/dist/cli/commands/start.d.ts.map +1 -1
  74. package/dist/cli/commands/start.js +145 -16
  75. package/dist/cli/commands/start.js.map +1 -1
  76. package/dist/cli/commands/stop.d.ts +5 -0
  77. package/dist/cli/commands/stop.d.ts.map +1 -1
  78. package/dist/cli/commands/stop.js +220 -18
  79. package/dist/cli/commands/stop.js.map +1 -1
  80. package/dist/cli/config/types.d.ts +6 -0
  81. package/dist/cli/config/types.d.ts.map +1 -1
  82. package/dist/cli/config/types.js.map +1 -1
  83. package/dist/cli/runtime/agent-loop-init.d.ts +2 -0
  84. package/dist/cli/runtime/agent-loop-init.d.ts.map +1 -1
  85. package/dist/cli/runtime/agent-loop-init.js +3 -4
  86. package/dist/cli/runtime/agent-loop-init.js.map +1 -1
  87. package/dist/cli/runtime/api-server-init.d.ts +5 -2
  88. package/dist/cli/runtime/api-server-init.d.ts.map +1 -1
  89. package/dist/cli/runtime/api-server-init.js +4 -1
  90. package/dist/cli/runtime/api-server-init.js.map +1 -1
  91. package/dist/cli/runtime/connector-init.d.ts +12 -4
  92. package/dist/cli/runtime/connector-init.d.ts.map +1 -1
  93. package/dist/cli/runtime/connector-init.js +44 -51
  94. package/dist/cli/runtime/connector-init.js.map +1 -1
  95. package/dist/cli/runtime/envelope-bootstrap.d.ts +16 -0
  96. package/dist/cli/runtime/envelope-bootstrap.d.ts.map +1 -0
  97. package/dist/cli/runtime/envelope-bootstrap.js +39 -0
  98. package/dist/cli/runtime/envelope-bootstrap.js.map +1 -0
  99. package/dist/cli/runtime/memory-agent-init.d.ts.map +1 -1
  100. package/dist/cli/runtime/memory-agent-init.js +4 -1
  101. package/dist/cli/runtime/memory-agent-init.js.map +1 -1
  102. package/dist/connectors/framework/polling-scheduler.d.ts +3 -1
  103. package/dist/connectors/framework/polling-scheduler.d.ts.map +1 -1
  104. package/dist/connectors/framework/polling-scheduler.js +6 -1
  105. package/dist/connectors/framework/polling-scheduler.js.map +1 -1
  106. package/dist/connectors/framework/raw-store.d.ts +29 -0
  107. package/dist/connectors/framework/raw-store.d.ts.map +1 -1
  108. package/dist/connectors/framework/raw-store.js +154 -4
  109. package/dist/connectors/framework/raw-store.js.map +1 -1
  110. package/dist/connectors/framework/types.d.ts +6 -0
  111. package/dist/connectors/framework/types.d.ts.map +1 -1
  112. package/dist/db/agent-store.d.ts +29 -1
  113. package/dist/db/agent-store.d.ts.map +1 -1
  114. package/dist/db/agent-store.js +89 -6
  115. package/dist/db/agent-store.js.map +1 -1
  116. package/dist/db/migrations/agent-activity-envelope-hash.d.ts +3 -0
  117. package/dist/db/migrations/agent-activity-envelope-hash.d.ts.map +1 -0
  118. package/dist/db/migrations/agent-activity-envelope-hash.js +29 -0
  119. package/dist/db/migrations/agent-activity-envelope-hash.js.map +1 -0
  120. package/dist/db/migrations/agent-activity-gateway-call-id.d.ts +3 -0
  121. package/dist/db/migrations/agent-activity-gateway-call-id.d.ts.map +1 -0
  122. package/dist/db/migrations/agent-activity-gateway-call-id.js +17 -0
  123. package/dist/db/migrations/agent-activity-gateway-call-id.js.map +1 -0
  124. package/dist/db/migrations/agent-store-tables.d.ts.map +1 -1
  125. package/dist/db/migrations/agent-store-tables.js +5 -0
  126. package/dist/db/migrations/agent-store-tables.js.map +1 -1
  127. package/dist/db/migrations/envelope-tables.d.ts +3 -0
  128. package/dist/db/migrations/envelope-tables.d.ts.map +1 -0
  129. package/dist/db/migrations/envelope-tables.js +38 -0
  130. package/dist/db/migrations/envelope-tables.js.map +1 -0
  131. package/dist/envelope/authority.d.ts +15 -0
  132. package/dist/envelope/authority.d.ts.map +1 -0
  133. package/dist/envelope/authority.js +95 -0
  134. package/dist/envelope/authority.js.map +1 -0
  135. package/dist/envelope/canonical.d.ts +14 -0
  136. package/dist/envelope/canonical.d.ts.map +1 -0
  137. package/dist/envelope/canonical.js +68 -0
  138. package/dist/envelope/canonical.js.map +1 -0
  139. package/dist/envelope/enforcer.d.ts +15 -0
  140. package/dist/envelope/enforcer.d.ts.map +1 -0
  141. package/dist/envelope/enforcer.js +177 -0
  142. package/dist/envelope/enforcer.js.map +1 -0
  143. package/dist/envelope/expiry.d.ts +2 -0
  144. package/dist/envelope/expiry.d.ts.map +1 -0
  145. package/dist/envelope/expiry.js +15 -0
  146. package/dist/envelope/expiry.js.map +1 -0
  147. package/dist/envelope/index.d.ts +10 -0
  148. package/dist/envelope/index.d.ts.map +1 -0
  149. package/dist/envelope/index.js +26 -0
  150. package/dist/envelope/index.js.map +1 -0
  151. package/dist/envelope/key-provider.d.ts +6 -0
  152. package/dist/envelope/key-provider.d.ts.map +1 -0
  153. package/dist/envelope/key-provider.js +51 -0
  154. package/dist/envelope/key-provider.js.map +1 -0
  155. package/dist/envelope/reactive-config.d.ts +24 -0
  156. package/dist/envelope/reactive-config.d.ts.map +1 -0
  157. package/dist/envelope/reactive-config.js +154 -0
  158. package/dist/envelope/reactive-config.js.map +1 -0
  159. package/dist/envelope/signature.d.ts +16 -0
  160. package/dist/envelope/signature.d.ts.map +1 -0
  161. package/dist/envelope/signature.js +82 -0
  162. package/dist/envelope/signature.js.map +1 -0
  163. package/dist/envelope/store.d.ts +16 -0
  164. package/dist/envelope/store.d.ts.map +1 -0
  165. package/dist/envelope/store.js +118 -0
  166. package/dist/envelope/store.js.map +1 -0
  167. package/dist/envelope/subset.d.ts +9 -0
  168. package/dist/envelope/subset.d.ts.map +1 -0
  169. package/dist/envelope/subset.js +67 -0
  170. package/dist/envelope/subset.js.map +1 -0
  171. package/dist/envelope/types.d.ts +60 -0
  172. package/dist/envelope/types.d.ts.map +1 -0
  173. package/dist/envelope/types.js +9 -0
  174. package/dist/envelope/types.js.map +1 -0
  175. package/dist/gateways/message-router.d.ts +17 -29
  176. package/dist/gateways/message-router.d.ts.map +1 -1
  177. package/dist/gateways/message-router.js +97 -41
  178. package/dist/gateways/message-router.js.map +1 -1
  179. package/dist/memory/audit-task-queue.d.ts +1 -0
  180. package/dist/memory/audit-task-queue.d.ts.map +1 -1
  181. package/dist/memory/audit-task-queue.js.map +1 -1
  182. package/dist/multi-agent/agent-process-manager.d.ts.map +1 -1
  183. package/dist/multi-agent/agent-process-manager.js +4 -4
  184. package/dist/multi-agent/agent-process-manager.js.map +1 -1
  185. package/dist/multi-agent/swarm/swarm-mama-adapter.d.ts +33 -2
  186. package/dist/multi-agent/swarm/swarm-mama-adapter.d.ts.map +1 -1
  187. package/dist/multi-agent/swarm/swarm-mama-adapter.js +7 -8
  188. package/dist/multi-agent/swarm/swarm-mama-adapter.js.map +1 -1
  189. package/package.json +2 -2
  190. 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
- > Your scattered knowledge, organized by AI agents that never sleep.
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 an intelligence problem. You don't just need to _store_ information — you need something that reads everything, connects the dots, identifies what matters, and tells you what you're missing.
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 everything continuously, and turns scattered records into organized knowledge.
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 can do that humans can't** — read every channel, every thread, every document, every day, and never miss a connection.
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) Gateways (4)
143
- Slack, Gmail, Sheets... Discord, Slack, Telegram, Chatwork
144
- | |
145
- v v
146
- 3-Pass Extraction Multi-Agent System
147
- | |
148
- +--------+-------+------+
149
- |
150
- MAMA Core (mama-memory.db)
151
- Local SQLite + 1024-dim embeddings
152
- |
153
- +------+------+
154
- | |
155
- Viewer UI Claude Code Plugin
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 # 2800+ tests across all packages
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-20
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,EAE1B,YAAY,EAEb,MAAM,YAAY,CAAC;AA+DpB;;;;;;;;;;;;;GAaG;AACH;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG,MAAM,CAuB7E;AAED,wBAAgB,wBAAwB,CAAC,OAAO,UAAQ,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAsExF;AAWD,wBAAgB,qBAAqB,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAuBnE;AASD,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqC;IACnE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;IAClD,OAAO,CAAC,oBAAoB,CAAC,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAA8D;IACzF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAOnB;IACX,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAIhB;IACV,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8B;IAC1D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAyB;IACzD,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAiC;IACzE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA2B;IAC7D,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,sBAAsB,CAAC,CAAkB;IACjD,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAW;gBAG1C,aAAa,EAAE,YAAY,EAC3B,OAAO,GAAE,gBAAqB,EAC9B,cAAc,CAAC,EAAE,mBAAmB,EACpC,eAAe,CAAC,EAAE,0BAA0B;IAkQ9C;;;OAGG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIhC;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB,OAAO,CAAC,2BAA2B;IAQnC,OAAO,CAAC,yBAAyB;IAajC;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAIjD;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE;QACzB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/D,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/E,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAClF,GAAG,IAAI;IAIR;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE;QAC1B,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACzD,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5E,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9E,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KACzE,GAAG,IAAI;IAIR;;OAEG;IACH,aAAa,CAAC,EAAE,EAAE,OAAO,cAAc,EAAE,OAAO,GAAG,IAAI;IAIvD;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,OAAO,8BAA8B,EAAE,cAAc,GAAG,IAAI;IAIrF;;OAEG;IACH,oBAAoB,CAClB,GAAG,EAAE,OAAO,kCAAkC,EAAE,wBAAwB,GACvE,IAAI;IAIP;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,OAAO,sCAAsC,EAAE,QAAQ,GAAG,IAAI;IAIjF;;OAEG;IACH,kBAAkB,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,GAAG,IAAI;IAIrE;;OAEG;IACH,gBAAgB,CACd,EAAE,EAAE,CACF,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,KACC,IAAI,GACR,IAAI;IAIP;;OAEG;IACH,sBAAsB,CACpB,EAAE,EAAE,OAAO,yCAAyC,EAAE,mBAAmB,GACxE,IAAI;IAIP;;OAEG;IACH,oBAAoB,CAAC,EAAE,EAAE,OAAO,sCAAsC,EAAE,iBAAiB,GAAG,IAAI;IAIhG;;OAEG;IACH,wBAAwB,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI;IAI/F;;OAEG;IACH,yBAAyB,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI;IAIhF;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,OAAO,mCAAmC,EAAE,aAAa,GAAG,IAAI;IAI3F;;;;;;;;;;;;OAYG;IACG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAkB/E;;;;;;;;;OASG;IACG,cAAc,CAClB,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,eAAe,CAAC;IAiB3B;;OAEG;YACW,sBAAsB;IAugBpC;;OAEG;YACW,YAAY;IAsH1B;;;;;;OAMG;YACW,sBAAsB;IAiDpC;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IA0B9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;OAEG;YACW,cAAc;IAgD5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,sBAAsB;IAO9B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAuB3B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IA8E7B;;OAEG;IACH,MAAM,CAAC,kBAAkB,IAAI,cAAc,EAAE;IAI7C;;OAEG;IACH,MAAM,CAAC,sBAAsB,IAAI,MAAM;IAIvC;;OAEG;IACH,OAAO,CAAC,OAAO,CAAS;IAElB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAsB5B"}
1
+ {"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../../src/agent/agent-loop.ts"],"names":[],"mappings":"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"}
@@ -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
- if (!options?.agentContext) {
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
- const toolExecutionContext = this.buildToolExecutionContext(options);
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
- return {
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, executionContext);
1250
+ contractContext = await this.searchContractsForTool(toolUse.name, toolUse.input, reactiveInternalContext);
1122
1251
  }
1123
- const toolResult = await this.mcpExecutor.execute(toolUse.name, toolUse.input, executionContext ?? undefined);
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 bridge = new index_js_1.HostBridge(this.mcpExecutor);
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