@inbrowser/agent 0.0.0-placeholder → 0.1.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 (202) hide show
  1. package/AGENTS.md +270 -0
  2. package/README.md +117 -2
  3. package/bin/agent.ts +10 -0
  4. package/dist/cli/commands/describe.d.ts +14 -0
  5. package/dist/cli/commands/describe.d.ts.map +1 -0
  6. package/dist/cli/commands/describe.js +179 -0
  7. package/dist/cli/commands/describe.js.map +1 -0
  8. package/dist/cli/commands/events.d.ts +21 -0
  9. package/dist/cli/commands/events.d.ts.map +1 -0
  10. package/dist/cli/commands/events.js +59 -0
  11. package/dist/cli/commands/events.js.map +1 -0
  12. package/dist/cli/commands/fleet.d.ts +15 -0
  13. package/dist/cli/commands/fleet.d.ts.map +1 -0
  14. package/dist/cli/commands/fleet.js +149 -0
  15. package/dist/cli/commands/fleet.js.map +1 -0
  16. package/dist/cli/commands/help.d.ts +15 -0
  17. package/dist/cli/commands/help.d.ts.map +1 -0
  18. package/dist/cli/commands/help.js +93 -0
  19. package/dist/cli/commands/help.js.map +1 -0
  20. package/dist/cli/commands/migrate.d.ts +27 -0
  21. package/dist/cli/commands/migrate.d.ts.map +1 -0
  22. package/dist/cli/commands/migrate.js +109 -0
  23. package/dist/cli/commands/migrate.js.map +1 -0
  24. package/dist/cli/commands/run.d.ts +38 -0
  25. package/dist/cli/commands/run.d.ts.map +1 -0
  26. package/dist/cli/commands/run.js +535 -0
  27. package/dist/cli/commands/run.js.map +1 -0
  28. package/dist/cli/commands/schema.d.ts +8 -0
  29. package/dist/cli/commands/schema.d.ts.map +1 -0
  30. package/dist/cli/commands/schema.js +12 -0
  31. package/dist/cli/commands/schema.js.map +1 -0
  32. package/dist/cli/commands/serve.d.ts +39 -0
  33. package/dist/cli/commands/serve.d.ts.map +1 -0
  34. package/dist/cli/commands/serve.js +65 -0
  35. package/dist/cli/commands/serve.js.map +1 -0
  36. package/dist/cli/commands/undo.d.ts +36 -0
  37. package/dist/cli/commands/undo.d.ts.map +1 -0
  38. package/dist/cli/commands/undo.js +132 -0
  39. package/dist/cli/commands/undo.js.map +1 -0
  40. package/dist/cli/fixtures.d.ts +17 -0
  41. package/dist/cli/fixtures.d.ts.map +1 -0
  42. package/dist/cli/fixtures.js +107 -0
  43. package/dist/cli/fixtures.js.map +1 -0
  44. package/dist/cli/hardening.d.ts +39 -0
  45. package/dist/cli/hardening.d.ts.map +1 -0
  46. package/dist/cli/hardening.js +68 -0
  47. package/dist/cli/hardening.js.map +1 -0
  48. package/dist/cli/index.d.ts +28 -0
  49. package/dist/cli/index.d.ts.map +1 -0
  50. package/dist/cli/index.js +19 -0
  51. package/dist/cli/index.js.map +1 -0
  52. package/dist/cli/llm/openrouter.d.ts +33 -0
  53. package/dist/cli/llm/openrouter.d.ts.map +1 -0
  54. package/dist/cli/llm/openrouter.js +285 -0
  55. package/dist/cli/llm/openrouter.js.map +1 -0
  56. package/dist/cli/main.d.ts +32 -0
  57. package/dist/cli/main.d.ts.map +1 -0
  58. package/dist/cli/main.js +106 -0
  59. package/dist/cli/main.js.map +1 -0
  60. package/dist/cli/output.d.ts +36 -0
  61. package/dist/cli/output.d.ts.map +1 -0
  62. package/dist/cli/output.js +95 -0
  63. package/dist/cli/output.js.map +1 -0
  64. package/dist/cli/parse.d.ts +26 -0
  65. package/dist/cli/parse.d.ts.map +1 -0
  66. package/dist/cli/parse.js +160 -0
  67. package/dist/cli/parse.js.map +1 -0
  68. package/dist/cli/session-log.d.ts +34 -0
  69. package/dist/cli/session-log.d.ts.map +1 -0
  70. package/dist/cli/session-log.js +52 -0
  71. package/dist/cli/session-log.js.map +1 -0
  72. package/dist/cli/spec.d.ts +62 -0
  73. package/dist/cli/spec.d.ts.map +1 -0
  74. package/dist/cli/spec.js +510 -0
  75. package/dist/cli/spec.js.map +1 -0
  76. package/dist/cli/ui/RunView.d.ts +134 -0
  77. package/dist/cli/ui/RunView.d.ts.map +1 -0
  78. package/dist/cli/ui/RunView.js +341 -0
  79. package/dist/cli/ui/RunView.js.map +1 -0
  80. package/dist/events/codec.d.ts +79 -0
  81. package/dist/events/codec.d.ts.map +1 -0
  82. package/dist/events/codec.js +142 -0
  83. package/dist/events/codec.js.map +1 -0
  84. package/dist/events/log-core.d.ts +76 -0
  85. package/dist/events/log-core.d.ts.map +1 -0
  86. package/dist/events/log-core.js +73 -0
  87. package/dist/events/log-core.js.map +1 -0
  88. package/dist/events/log.d.ts +60 -0
  89. package/dist/events/log.d.ts.map +1 -0
  90. package/dist/events/log.js +193 -0
  91. package/dist/events/log.js.map +1 -0
  92. package/dist/events/replay.d.ts +106 -0
  93. package/dist/events/replay.d.ts.map +1 -0
  94. package/dist/events/replay.js +137 -0
  95. package/dist/events/replay.js.map +1 -0
  96. package/dist/events/wrap.d.ts +100 -0
  97. package/dist/events/wrap.d.ts.map +1 -0
  98. package/dist/events/wrap.js +141 -0
  99. package/dist/events/wrap.js.map +1 -0
  100. package/dist/index.d.ts +52 -0
  101. package/dist/index.d.ts.map +1 -0
  102. package/dist/index.js +37 -0
  103. package/dist/index.js.map +1 -0
  104. package/dist/llm-adapter.d.ts +96 -0
  105. package/dist/llm-adapter.d.ts.map +1 -0
  106. package/dist/llm-adapter.js +132 -0
  107. package/dist/llm-adapter.js.map +1 -0
  108. package/dist/mcp/serve.d.ts +70 -0
  109. package/dist/mcp/serve.d.ts.map +1 -0
  110. package/dist/mcp/serve.js +154 -0
  111. package/dist/mcp/serve.js.map +1 -0
  112. package/dist/metrics/runs.d.ts +58 -0
  113. package/dist/metrics/runs.d.ts.map +1 -0
  114. package/dist/metrics/runs.js +99 -0
  115. package/dist/metrics/runs.js.map +1 -0
  116. package/dist/metrics.d.ts +38 -0
  117. package/dist/metrics.d.ts.map +1 -0
  118. package/dist/metrics.js +123 -0
  119. package/dist/metrics.js.map +1 -0
  120. package/dist/node.d.ts +22 -0
  121. package/dist/node.d.ts.map +1 -0
  122. package/dist/node.js +22 -0
  123. package/dist/node.js.map +1 -0
  124. package/dist/session.d.ts +10 -0
  125. package/dist/session.d.ts.map +1 -0
  126. package/dist/session.js +179 -0
  127. package/dist/session.js.map +1 -0
  128. package/dist/storage.d.ts +14 -0
  129. package/dist/storage.d.ts.map +1 -0
  130. package/dist/storage.js +58 -0
  131. package/dist/storage.js.map +1 -0
  132. package/dist/strategy.d.ts +26 -0
  133. package/dist/strategy.d.ts.map +1 -0
  134. package/dist/strategy.js +200 -0
  135. package/dist/strategy.js.map +1 -0
  136. package/dist/tools.d.ts +26 -0
  137. package/dist/tools.d.ts.map +1 -0
  138. package/dist/tools.js +129 -0
  139. package/dist/tools.js.map +1 -0
  140. package/dist/types/agent.d.ts +94 -0
  141. package/dist/types/agent.d.ts.map +1 -0
  142. package/dist/types/agent.js +17 -0
  143. package/dist/types/agent.js.map +1 -0
  144. package/dist/types/capabilities.d.ts +17 -0
  145. package/dist/types/capabilities.d.ts.map +1 -0
  146. package/dist/types/capabilities.js +13 -0
  147. package/dist/types/capabilities.js.map +1 -0
  148. package/dist/types/chat.d.ts +74 -0
  149. package/dist/types/chat.d.ts.map +1 -0
  150. package/dist/types/chat.js +10 -0
  151. package/dist/types/chat.js.map +1 -0
  152. package/dist/types/events.d.ts +115 -0
  153. package/dist/types/events.d.ts.map +1 -0
  154. package/dist/types/events.js +30 -0
  155. package/dist/types/events.js.map +1 -0
  156. package/dist/types/llm.d.ts +89 -0
  157. package/dist/types/llm.d.ts.map +1 -0
  158. package/dist/types/llm.js +12 -0
  159. package/dist/types/llm.js.map +1 -0
  160. package/dist/types/metrics.d.ts +34 -0
  161. package/dist/types/metrics.d.ts.map +1 -0
  162. package/dist/types/metrics.js +10 -0
  163. package/dist/types/metrics.js.map +1 -0
  164. package/dist/types/observer.d.ts +41 -0
  165. package/dist/types/observer.d.ts.map +1 -0
  166. package/dist/types/observer.js +41 -0
  167. package/dist/types/observer.js.map +1 -0
  168. package/dist/types/project-context.d.ts +18 -0
  169. package/dist/types/project-context.d.ts.map +1 -0
  170. package/dist/types/project-context.js +11 -0
  171. package/dist/types/project-context.js.map +1 -0
  172. package/dist/types/runtime.d.ts +71 -0
  173. package/dist/types/runtime.d.ts.map +1 -0
  174. package/dist/types/runtime.js +21 -0
  175. package/dist/types/runtime.js.map +1 -0
  176. package/dist/types/session.d.ts +103 -0
  177. package/dist/types/session.d.ts.map +1 -0
  178. package/dist/types/session.js +11 -0
  179. package/dist/types/session.js.map +1 -0
  180. package/dist/types/storage.d.ts +20 -0
  181. package/dist/types/storage.d.ts.map +1 -0
  182. package/dist/types/storage.js +41 -0
  183. package/dist/types/storage.js.map +1 -0
  184. package/dist/types/strategy.d.ts +76 -0
  185. package/dist/types/strategy.d.ts.map +1 -0
  186. package/dist/types/strategy.js +10 -0
  187. package/dist/types/strategy.js.map +1 -0
  188. package/dist/types/tools.d.ts +136 -0
  189. package/dist/types/tools.d.ts.map +1 -0
  190. package/dist/types/tools.js +11 -0
  191. package/dist/types/tools.js.map +1 -0
  192. package/dist/types/trace.d.ts +125 -0
  193. package/dist/types/trace.d.ts.map +1 -0
  194. package/dist/types/trace.js +24 -0
  195. package/dist/types/trace.js.map +1 -0
  196. package/dist/types/workspace.d.ts +29 -0
  197. package/dist/types/workspace.d.ts.map +1 -0
  198. package/dist/types/workspace.js +18 -0
  199. package/dist/types/workspace.js.map +1 -0
  200. package/package.json +45 -14
  201. package/skills/agent-cli.md +218 -0
  202. package/index.js +0 -2
@@ -0,0 +1,200 @@
1
+ /**
2
+ * `createReactLoopStrategy()` — the default `AgentStrategy`.
3
+ *
4
+ * Implements the playground's current ReAct-style behavior:
5
+ *
6
+ * 1. Compose `[system, ...history, user(prompt)]` as the message
7
+ * array.
8
+ * 2. Issue one chat call against the LLM with the tool list.
9
+ * 3. Stream `text` / `thinking` / `tool_call` events through.
10
+ * 4. When the LLM produces tool calls, dispatch each one, append
11
+ * the result message, and loop back to step 2.
12
+ * 5. When the LLM produces no tool calls in a turn, emit
13
+ * `turn_complete` and finish.
14
+ *
15
+ * Future strategies (planner-executor, graph-of-thoughts,
16
+ * parallel-branch ensembling) sit alongside this one — same
17
+ * `AgentStrategy` interface, different control flow.
18
+ */
19
+ export function createReactLoopStrategy(options = {}) {
20
+ const maxTurns = options.maxTurns ?? 24;
21
+ return {
22
+ id: 'react-loop',
23
+ async *run(input, signal) {
24
+ const messages = buildMessages(input);
25
+ for (let turn = 0; turn < maxTurns; turn++) {
26
+ if (signal.aborted) {
27
+ yield { kind: 'error', message: 'aborted' };
28
+ return;
29
+ }
30
+ const toolDecls = input.toolList.map((h) => ({
31
+ name: h.name,
32
+ description: h.description,
33
+ parameters: h.parameters,
34
+ }));
35
+ const chatRequest = {
36
+ messages,
37
+ tools: toolDecls,
38
+ toolUseEnabled: toolDecls.length > 0 && input.llm.supportsTools,
39
+ };
40
+ // Emit the trace BEFORE dispatch. Captures the request as the
41
+ // strategy assembled it — agent-layer view, not provider-
42
+ // specific. The `requestId` is `${turnId}#${iteration}`
43
+ // when the session passed a `turnId`; otherwise we synthesize
44
+ // a per-iteration id so the trace stays consistent for
45
+ // standalone strategy callers (CLI, eval harness).
46
+ if (input.tracer) {
47
+ const turnIdForReq = input.turnId ?? 'turn-anon';
48
+ input.tracer.emit({
49
+ kind: 'llm_request',
50
+ data: {
51
+ requestId: `${turnIdForReq}#${turn}`,
52
+ turnId: turnIdForReq,
53
+ iteration: turn,
54
+ ts: Date.now(),
55
+ systemPrompt: input.systemPrompt,
56
+ // Shallow-clone arrays to detach the captured view from
57
+ // the in-loop `messages` array that grows under our
58
+ // feet on each ReAct iteration. Each iteration's trace
59
+ // must reflect the messages AS-SENT at that iteration.
60
+ messages: messages.map((m) => ({ ...m })),
61
+ tools: toolDecls.map((t) => ({ ...t })),
62
+ llm: { id: input.llm.id, supportsTools: input.llm.supportsTools },
63
+ },
64
+ });
65
+ }
66
+ const pendingToolCalls = [];
67
+ let turnUsage;
68
+ let turnDetails;
69
+ let assistantText = '';
70
+ // Stream the model's reply.
71
+ for await (const ev of input.llm.chat(chatRequest, signal)) {
72
+ if (ev.kind === 'text') {
73
+ assistantText += ev.chunk;
74
+ yield { kind: 'text', chunk: ev.chunk };
75
+ }
76
+ else if (ev.kind === 'thinking') {
77
+ yield { kind: 'thinking', chunk: ev.chunk };
78
+ }
79
+ else if (ev.kind === 'tool_call') {
80
+ pendingToolCalls.push({
81
+ id: ev.id,
82
+ name: ev.name,
83
+ args: ev.args,
84
+ ...(ev.signature ? { signature: ev.signature } : {}),
85
+ });
86
+ yield {
87
+ kind: 'tool_call',
88
+ id: ev.id,
89
+ name: ev.name,
90
+ args: ev.args,
91
+ ...(ev.signature ? { signature: ev.signature } : {}),
92
+ };
93
+ }
94
+ else if (ev.kind === 'turn_complete') {
95
+ turnUsage = ev.usage;
96
+ turnDetails = ev.details;
97
+ }
98
+ else if (ev.kind === 'error') {
99
+ yield { kind: 'error', message: ev.message };
100
+ return;
101
+ }
102
+ }
103
+ // No tool calls → final assistant turn, emit turn_complete + done.
104
+ if (pendingToolCalls.length === 0) {
105
+ if (turnUsage && turnDetails) {
106
+ yield { kind: 'turn_complete', usage: turnUsage, details: turnDetails };
107
+ }
108
+ return;
109
+ }
110
+ // Tool calls → run each, append result message, loop.
111
+ messages.push({
112
+ role: 'assistant',
113
+ text: assistantText,
114
+ toolCalls: pendingToolCalls.map((tc) => ({
115
+ callId: tc.id,
116
+ name: tc.name,
117
+ args: tc.args,
118
+ ...(tc.signature ? { signature: tc.signature } : {}),
119
+ })),
120
+ });
121
+ for (const call of pendingToolCalls) {
122
+ const result = await input.tools.execute({ id: call.id, name: call.name, args: call.args }, input.toolContext());
123
+ yield { kind: 'tool_result', id: call.id, result };
124
+ messages.push({
125
+ role: 'tool',
126
+ callId: call.id,
127
+ name: call.name,
128
+ resultJson: JSON.stringify(safeSerializable(result)),
129
+ text: '',
130
+ });
131
+ }
132
+ // Loop to next turn.
133
+ if (turnUsage && turnDetails) {
134
+ yield { kind: 'turn_complete', usage: turnUsage, details: turnDetails };
135
+ }
136
+ }
137
+ yield {
138
+ kind: 'error',
139
+ message: `react-loop: exceeded maxTurns (${maxTurns}) without settling`,
140
+ };
141
+ },
142
+ };
143
+ }
144
+ function buildMessages(input) {
145
+ const out = [];
146
+ out.push({ role: 'system', text: input.systemPrompt });
147
+ for (const m of input.history) {
148
+ if (m.role === 'system')
149
+ continue; // already emitted
150
+ if (m.role === 'assistant') {
151
+ const tc = m.toolCalls?.map((c) => ({
152
+ callId: c.id,
153
+ name: c.name,
154
+ args: safeParse(c.argsJson),
155
+ ...(c.signature ? { signature: c.signature } : {}),
156
+ })) ?? [];
157
+ out.push({
158
+ role: 'assistant',
159
+ text: m.text,
160
+ ...(tc.length > 0 ? { toolCalls: tc } : {}),
161
+ });
162
+ for (const c of m.toolCalls ?? []) {
163
+ if (c.resultJson !== undefined) {
164
+ out.push({
165
+ role: 'tool',
166
+ callId: c.id,
167
+ name: c.name,
168
+ resultJson: c.resultJson,
169
+ text: '',
170
+ });
171
+ }
172
+ }
173
+ }
174
+ else {
175
+ out.push({ role: m.role, text: m.text });
176
+ }
177
+ }
178
+ out.push({ role: 'user', text: input.prompt });
179
+ return out;
180
+ }
181
+ function safeParse(s) {
182
+ try {
183
+ return JSON.parse(s);
184
+ }
185
+ catch {
186
+ return s;
187
+ }
188
+ }
189
+ function safeSerializable(value) {
190
+ // Strip non-serializable fields (functions, symbols) that might
191
+ // sneak into ToolResult.data. Most handlers return plain objects;
192
+ // this is belt-and-suspenders.
193
+ try {
194
+ return JSON.parse(JSON.stringify(value));
195
+ }
196
+ catch {
197
+ return { ok: value.ok, summary: value.summary };
198
+ }
199
+ }
200
+ //# sourceMappingURL=strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy.js","sourceRoot":"","sources":["../src/strategy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * `ToolRegistry` + `ToolDispatch` runtime implementations.
3
+ *
4
+ * The interfaces ship in slice 1 (`./types/tools.ts`). This module
5
+ * provides:
6
+ *
7
+ * - `createToolRegistry()` — the basic in-memory registry.
8
+ * - `createDispatch(registry)` — stateless executor that looks up
9
+ * by name and invokes the handler with the supplied `ToolContext`.
10
+ *
11
+ * Both are pure-TS — no React, no stores, no localStorage.
12
+ */
13
+ import type { ToolDispatch, ToolRegistry } from './types/tools.js';
14
+ export declare function createToolRegistry(): ToolRegistry;
15
+ /**
16
+ * Create a stateless dispatcher over a registry. The dispatcher
17
+ * holds a reference to the registry — list/register/unregister calls
18
+ * on the registry are seen by the dispatcher on the next `execute`.
19
+ *
20
+ * Error shape: handlers that throw turn into `{ ok: false, summary:
21
+ * <message> }` results so the caller's `for await` loop doesn't have
22
+ * to wrap every tool invocation in a try/catch. The thrown value is
23
+ * stringified into the summary.
24
+ */
25
+ export declare function createDispatch(registry: ToolRegistry): ToolDispatch;
26
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAGV,YAAY,EAEZ,YAAY,EAEb,MAAM,kBAAkB,CAAC;AAE1B,wBAAgB,kBAAkB,IAAI,YAAY,CA8DjD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG,YAAY,CA0BnE"}
package/dist/tools.js ADDED
@@ -0,0 +1,129 @@
1
+ /**
2
+ * `ToolRegistry` + `ToolDispatch` runtime implementations.
3
+ *
4
+ * The interfaces ship in slice 1 (`./types/tools.ts`). This module
5
+ * provides:
6
+ *
7
+ * - `createToolRegistry()` — the basic in-memory registry.
8
+ * - `createDispatch(registry)` — stateless executor that looks up
9
+ * by name and invokes the handler with the supplied `ToolContext`.
10
+ *
11
+ * Both are pure-TS — no React, no stores, no localStorage.
12
+ */
13
+ export function createToolRegistry() {
14
+ const handlers = new Map();
15
+ function clone() {
16
+ return new Map(handlers);
17
+ }
18
+ function makeFromMap(map) {
19
+ return {
20
+ register(handler) {
21
+ const existing = map.get(handler.name);
22
+ if (existing) {
23
+ // Include both descriptions when available so the
24
+ // composer can spot which two factories shipped the
25
+ // same tool name without spelunking through stack
26
+ // traces.
27
+ const existingDesc = truncate(existing.description ?? '', 80);
28
+ const newDesc = truncate(handler.description ?? '', 80);
29
+ throw new Error(`ToolRegistry: tool '${handler.name}' is already registered.\n` +
30
+ ` Previously registered: ${existingDesc || '(no description)'}\n` +
31
+ ` New registration: ${newDesc || '(no description)'}\n` +
32
+ ` Use \`registry.replace(handler)\` if this overlay is intentional.`);
33
+ }
34
+ map.set(handler.name, handler);
35
+ },
36
+ replace(handler) {
37
+ map.set(handler.name, handler);
38
+ },
39
+ unregister(name) {
40
+ return map.delete(name);
41
+ },
42
+ list(opts) {
43
+ // No capability filter → return every registered handler.
44
+ // With a capability filter → drop handlers whose `available`
45
+ // hook returns false. Handlers without an `available` hook
46
+ // always pass.
47
+ const out = [];
48
+ if (opts?.capabilities === undefined) {
49
+ for (const h of map.values())
50
+ out.push(h);
51
+ return out;
52
+ }
53
+ const caps = opts.capabilities;
54
+ for (const h of map.values()) {
55
+ if (h.available && !h.available(caps))
56
+ continue;
57
+ out.push(h);
58
+ }
59
+ return out;
60
+ },
61
+ has(name) {
62
+ return map.has(name);
63
+ },
64
+ fork() {
65
+ // Fresh map cloning the current snapshot; later registrations
66
+ // on the forked registry don't affect the parent.
67
+ return makeFromMap(new Map(map));
68
+ },
69
+ };
70
+ }
71
+ return makeFromMap(handlers);
72
+ }
73
+ /**
74
+ * Create a stateless dispatcher over a registry. The dispatcher
75
+ * holds a reference to the registry — list/register/unregister calls
76
+ * on the registry are seen by the dispatcher on the next `execute`.
77
+ *
78
+ * Error shape: handlers that throw turn into `{ ok: false, summary:
79
+ * <message> }` results so the caller's `for await` loop doesn't have
80
+ * to wrap every tool invocation in a try/catch. The thrown value is
81
+ * stringified into the summary.
82
+ */
83
+ export function createDispatch(registry) {
84
+ return {
85
+ async execute(call, ctx) {
86
+ // We look up via the underlying `list` to avoid exposing a
87
+ // public `get(name)` on the registry — `list()` already enforces
88
+ // capability filtering, but for `execute` we should run any
89
+ // registered handler the caller has on file regardless of
90
+ // capability (the caller's job to gate before calling).
91
+ const candidate = findByName(registry, call.name);
92
+ if (!candidate) {
93
+ return {
94
+ ok: false,
95
+ summary: `Unknown tool: ${call.name}`,
96
+ };
97
+ }
98
+ try {
99
+ const args = call.args;
100
+ return await candidate.execute(args, ctx);
101
+ }
102
+ catch (e) {
103
+ return {
104
+ ok: false,
105
+ summary: `Tool ${call.name} threw: ${e instanceof Error ? e.message : String(e)}`,
106
+ };
107
+ }
108
+ },
109
+ };
110
+ }
111
+ /**
112
+ * Find a handler by name without exposing a `get` method on the
113
+ * registry interface. Public consumers always go through `list()`;
114
+ * the dispatcher (a friend of the registry) uses this internal
115
+ * lookup.
116
+ */
117
+ function findByName(registry, name) {
118
+ if (!registry.has(name))
119
+ return undefined;
120
+ // The registry doesn't expose a `get`; list() with no capability
121
+ // filter returns every handler — find by name from there.
122
+ const all = registry.list();
123
+ return all.find((h) => h.name === name);
124
+ }
125
+ /** Trim a string to `max` chars with an ellipsis marker. */
126
+ function truncate(s, max) {
127
+ return s.length <= max ? s : `${s.slice(0, max)}…`;
128
+ }
129
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Inverse-mode types — see `plans/inverse-mode-architecture.md`.
3
+ *
4
+ * In inference mode, an agent owns its LlmClient + conversation and the
5
+ * strategy drives a turn-by-turn loop calling `ToolHandler`s. In inverse
6
+ * mode, an external LLM host (Claude Code, Claude Desktop) drives the
7
+ * conversation and calls *behavior-named* `AgentTool`s one-shot.
8
+ *
9
+ * AgentTool is intentionally distinct from ToolHandler:
10
+ * - `ToolHandler` carries session-coupled context (workspace, runtime,
11
+ * sandbox, lint) that the inference loop maintains across turns.
12
+ * - `AgentTool` is a pure(-ish) function over input + minimal context.
13
+ * No conversation state. Plan/commit chaining is per-tool, enforced
14
+ * via planHash, not framework-level.
15
+ */
16
+ import type { EventLog } from '../events/log-core.js';
17
+ import type { JsonSchema } from './llm.js';
18
+ import type { ProjectContext } from './project-context.js';
19
+ import type { SandboxHandle } from './tools.js';
20
+ /**
21
+ * A bundle of behavior-named tools that share a domain + (where
22
+ * applicable) a planHash chain.
23
+ *
24
+ * `name` is the developer-facing id (`'hello-firestore'`,
25
+ * `'firestore-data-modeling'`). It surfaces in `agent describe` and
26
+ * `--agent` flags. It is NOT what the host LLM sees — each tool's own
27
+ * `name` is.
28
+ */
29
+ export interface AgentDefinition {
30
+ name: string;
31
+ description: string;
32
+ tools: AgentTool[];
33
+ }
34
+ /**
35
+ * One MCP-exposable behavior. The `name` and `description` are what the
36
+ * host LLM matches against user intent — phrase them as verbs the user
37
+ * would utter ("design_firestore_schema", not "data_modeling__plan").
38
+ */
39
+ export interface AgentTool<I = unknown, O = unknown> {
40
+ name: string;
41
+ description: string;
42
+ inputSchema: JsonSchema;
43
+ execute(input: I, ctx: AgentContext): Promise<AgentToolResult<O>>;
44
+ }
45
+ /**
46
+ * Per-call context. Distinct from `ToolContext` (the inference-mode
47
+ * shape): no workspace, no runtime, no lint — those concepts live in
48
+ * the conversation owner. AgentTools are one-shot from the host's POV.
49
+ */
50
+ export interface AgentContext {
51
+ /** Unique per call; correlates the run record + any events emitted. */
52
+ runId: string;
53
+ /** Firebase project id — routes the event log + runs log. */
54
+ projectId: string;
55
+ /** Append-only mutation log; same one `wrapMutating` writes to. */
56
+ events: EventLog;
57
+ /** Cancellation signal. Host typically supplies one per RPC. */
58
+ signal: AbortSignal;
59
+ /** Optional sandbox handle for tools that need it. Absent for pure
60
+ * computation (e.g. schema design). */
61
+ sandbox?: SandboxHandle;
62
+ /** Injectable clock for deterministic tests. */
63
+ now?: () => number;
64
+ /**
65
+ * Initialized `ProjectContext` for tools that need live project
66
+ * access (admin Firestore reads, REST API rules fetch). Present
67
+ * when `agent serve` was launched with FIREBASE_SA_BASE64 in env;
68
+ * absent otherwise. Tools should fail with a clear "needs SA"
69
+ * message when this is required and missing, not silently no-op.
70
+ *
71
+ * Field name preserved (vs. `projectContext`) so the public
72
+ * AgentContext shape doesn't break external tools that destructure
73
+ * `ctx.agentApp`; the *type* migrated from `AgentApp` to
74
+ * `ProjectContext` in Phase C step 13 of the legacy-SDK migration.
75
+ */
76
+ agentApp?: ProjectContext;
77
+ }
78
+ export interface AgentToolResult<O = unknown> {
79
+ ok: boolean;
80
+ /** One-line summary the host LLM can quote back to the user. */
81
+ summary: string;
82
+ /** Structured payload. Host LLM may reference it in follow-up tool calls. */
83
+ data?: O;
84
+ /**
85
+ * Set by preview/plan tools; consumed by the corresponding commit
86
+ * tool to enforce that the user-approved plan is what gets executed.
87
+ * Hash content is at the tool author's discretion (typically a SHA
88
+ * of the canonical JSON of `data`).
89
+ */
90
+ planHash?: string;
91
+ /** Event log ids produced this call. Surfaces to the run record. */
92
+ eventIds?: string[];
93
+ }
94
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/types/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;CACnE;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,MAAM,EAAE,QAAQ,CAAC;IACjB,gEAAgE;IAChE,MAAM,EAAE,WAAW,CAAC;IACpB;4CACwC;IACxC,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,EAAE,EAAE,OAAO,CAAC;IACZ,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,CAAC,CAAC;IACT;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Inverse-mode types — see `plans/inverse-mode-architecture.md`.
3
+ *
4
+ * In inference mode, an agent owns its LlmClient + conversation and the
5
+ * strategy drives a turn-by-turn loop calling `ToolHandler`s. In inverse
6
+ * mode, an external LLM host (Claude Code, Claude Desktop) drives the
7
+ * conversation and calls *behavior-named* `AgentTool`s one-shot.
8
+ *
9
+ * AgentTool is intentionally distinct from ToolHandler:
10
+ * - `ToolHandler` carries session-coupled context (workspace, runtime,
11
+ * sandbox, lint) that the inference loop maintains across turns.
12
+ * - `AgentTool` is a pure(-ish) function over input + minimal context.
13
+ * No conversation state. Plan/commit chaining is per-tool, enforced
14
+ * via planHash, not framework-level.
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/types/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `Capabilities` — what the current session can do.
3
+ *
4
+ * Computed once per session at start, refreshed at start of each
5
+ * turn. Drives which tools the agent is told about and which
6
+ * behaviors the system prompt mentions.
7
+ */
8
+ export interface Capabilities {
9
+ /** The active LLM provider advertises tool-use support. */
10
+ llmSupportsTools: boolean;
11
+ /** Stitch design tools are available (BYOK present + feature-flag on). */
12
+ stitchAvailable: boolean;
13
+ /** Sandbox is initialized and ready to receive tool calls. */
14
+ sandboxReady: boolean;
15
+ }
16
+ export declare const DEFAULT_CAPABILITIES: Capabilities;
17
+ //# sourceMappingURL=capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/types/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,gBAAgB,EAAE,OAAO,CAAC;IAC1B,0EAA0E;IAC1E,eAAe,EAAE,OAAO,CAAC;IACzB,8DAA8D;IAC9D,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,oBAAoB,EAAE,YAIjB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * `Capabilities` — what the current session can do.
3
+ *
4
+ * Computed once per session at start, refreshed at start of each
5
+ * turn. Drives which tools the agent is told about and which
6
+ * behaviors the system prompt mentions.
7
+ */
8
+ export const DEFAULT_CAPABILITIES = Object.freeze({
9
+ llmSupportsTools: true,
10
+ stitchAvailable: false,
11
+ sandboxReady: false,
12
+ });
13
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/types/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,MAAM,CAAC,MAAM,oBAAoB,GAAiB,MAAM,CAAC,MAAM,CAAC;IAC9D,gBAAgB,EAAE,IAAI;IACtB,eAAe,EAAE,KAAK;IACtB,YAAY,EAAE,KAAK;CACpB,CAAiB,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Chat message shape — the cross-session transcript surface.
3
+ *
4
+ * Matches the playground's existing `ChatMessage` shape closely so
5
+ * the React host can drop in `@inbrowser/agent` types without
6
+ * rewriting render code. The neutral shape lets non-React hosts
7
+ * (CLI, eval harness) consume the same transcripts.
8
+ */
9
+ export type ChatRole = 'system' | 'user' | 'assistant' | 'tool';
10
+ export interface ChatMessage {
11
+ id: string;
12
+ role: ChatRole;
13
+ text: string;
14
+ /** Streaming flag — true while the LLM is still emitting chunks. */
15
+ streaming?: boolean;
16
+ /** Hidden reasoning ("thinking") text — surface only when the host opts in. */
17
+ thinking?: string;
18
+ toolCalls?: ToolCall[];
19
+ /** Turn-scoped usage + cost — stamped on the assistant message at turn end. */
20
+ metrics?: TurnMetrics;
21
+ /** Per-turn detail block (servedModel, requestedModel, fingerprint, …). */
22
+ details?: TurnDetails;
23
+ /** Wall-clock milliseconds the turn took. */
24
+ timestamp?: number;
25
+ }
26
+ export interface ToolCall {
27
+ id: string;
28
+ name: string;
29
+ argsJson: string;
30
+ /** Stringified result; absent while the call is in flight. */
31
+ resultJson?: string;
32
+ ok?: boolean;
33
+ /** Optional human-readable one-liner the model can quote on the next turn. */
34
+ summary?: string;
35
+ /** Provider-specific signature carried through round-trips (Gemini thoughtSignature). */
36
+ signature?: string;
37
+ }
38
+ export interface TurnMetrics {
39
+ tokensIn: number;
40
+ tokensOut: number;
41
+ tokensCached: number;
42
+ tokensReasoning: number;
43
+ costUsd: number;
44
+ /** True when cost is computed client-side from a pricing table vs returned by the provider. */
45
+ costEstimated?: boolean;
46
+ /** True when the user supplied their own key — affects billing display. */
47
+ isByok?: boolean;
48
+ }
49
+ export interface TurnDetails {
50
+ /** The model name the host requested. */
51
+ requestedModel: string;
52
+ /** The model name the provider actually served (e.g. an OpenRouter routing fallback). */
53
+ servedModel?: string;
54
+ /** Provider-stable fingerprint when offered (Gemini systemFingerprint, OpenAI fingerprint). */
55
+ fingerprint?: string;
56
+ /** Free-form provider routing info (OpenRouter "provider" field, etc.). */
57
+ routing?: Record<string, unknown>;
58
+ }
59
+ /** A normalized message shape providers consume — drops React-specific fields like `streaming`. */
60
+ export interface NormalizedMessage {
61
+ role: ChatRole;
62
+ text: string;
63
+ toolCalls?: {
64
+ callId: string;
65
+ name: string;
66
+ args: unknown;
67
+ signature?: string;
68
+ }[];
69
+ /** For `role: 'tool'` only — the result of a previous tool call. */
70
+ callId?: string;
71
+ name?: string;
72
+ resultJson?: string;
73
+ }
74
+ //# sourceMappingURL=chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/types/chat.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yFAAyF;IACzF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,+FAA+F;IAC/F,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,yFAAyF;IACzF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+FAA+F;IAC/F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,mGAAmG;AACnG,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClF,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Chat message shape — the cross-session transcript surface.
3
+ *
4
+ * Matches the playground's existing `ChatMessage` shape closely so
5
+ * the React host can drop in `@inbrowser/agent` types without
6
+ * rewriting render code. The neutral shape lets non-React hosts
7
+ * (CLI, eval harness) consume the same transcripts.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/types/chat.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}