@inbrowser/agent 0.0.0-placeholder → 0.2.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/AGENTS.md +270 -0
- package/LICENSE +21 -0
- package/README.md +117 -2
- package/bin/agent.ts +10 -0
- package/dist/cli/commands/describe.d.ts +14 -0
- package/dist/cli/commands/describe.d.ts.map +1 -0
- package/dist/cli/commands/describe.js +179 -0
- package/dist/cli/commands/describe.js.map +1 -0
- package/dist/cli/commands/events.d.ts +21 -0
- package/dist/cli/commands/events.d.ts.map +1 -0
- package/dist/cli/commands/events.js +59 -0
- package/dist/cli/commands/events.js.map +1 -0
- package/dist/cli/commands/fleet.d.ts +15 -0
- package/dist/cli/commands/fleet.d.ts.map +1 -0
- package/dist/cli/commands/fleet.js +149 -0
- package/dist/cli/commands/fleet.js.map +1 -0
- package/dist/cli/commands/help.d.ts +15 -0
- package/dist/cli/commands/help.d.ts.map +1 -0
- package/dist/cli/commands/help.js +93 -0
- package/dist/cli/commands/help.js.map +1 -0
- package/dist/cli/commands/migrate.d.ts +27 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -0
- package/dist/cli/commands/migrate.js +109 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/cli/commands/run.d.ts +38 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +535 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/schema.d.ts +8 -0
- package/dist/cli/commands/schema.d.ts.map +1 -0
- package/dist/cli/commands/schema.js +12 -0
- package/dist/cli/commands/schema.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +39 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +65 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/undo.d.ts +36 -0
- package/dist/cli/commands/undo.d.ts.map +1 -0
- package/dist/cli/commands/undo.js +132 -0
- package/dist/cli/commands/undo.js.map +1 -0
- package/dist/cli/fixtures.d.ts +17 -0
- package/dist/cli/fixtures.d.ts.map +1 -0
- package/dist/cli/fixtures.js +107 -0
- package/dist/cli/fixtures.js.map +1 -0
- package/dist/cli/hardening.d.ts +39 -0
- package/dist/cli/hardening.d.ts.map +1 -0
- package/dist/cli/hardening.js +68 -0
- package/dist/cli/hardening.js.map +1 -0
- package/dist/cli/index.d.ts +28 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +19 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/llm/openrouter.d.ts +33 -0
- package/dist/cli/llm/openrouter.d.ts.map +1 -0
- package/dist/cli/llm/openrouter.js +285 -0
- package/dist/cli/llm/openrouter.js.map +1 -0
- package/dist/cli/main.d.ts +32 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +106 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/output.d.ts +36 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +95 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/parse.d.ts +26 -0
- package/dist/cli/parse.d.ts.map +1 -0
- package/dist/cli/parse.js +160 -0
- package/dist/cli/parse.js.map +1 -0
- package/dist/cli/session-log.d.ts +34 -0
- package/dist/cli/session-log.d.ts.map +1 -0
- package/dist/cli/session-log.js +52 -0
- package/dist/cli/session-log.js.map +1 -0
- package/dist/cli/spec.d.ts +62 -0
- package/dist/cli/spec.d.ts.map +1 -0
- package/dist/cli/spec.js +510 -0
- package/dist/cli/spec.js.map +1 -0
- package/dist/cli/ui/RunView.d.ts +134 -0
- package/dist/cli/ui/RunView.d.ts.map +1 -0
- package/dist/cli/ui/RunView.js +341 -0
- package/dist/cli/ui/RunView.js.map +1 -0
- package/dist/diagnostics/index.d.ts +5 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +3 -0
- package/dist/diagnostics/index.js.map +1 -0
- package/dist/diagnostics/timing.d.ts +48 -0
- package/dist/diagnostics/timing.d.ts.map +1 -0
- package/dist/diagnostics/timing.js +85 -0
- package/dist/diagnostics/timing.js.map +1 -0
- package/dist/diagnostics/truthfulness.d.ts +36 -0
- package/dist/diagnostics/truthfulness.d.ts.map +1 -0
- package/dist/diagnostics/truthfulness.js +180 -0
- package/dist/diagnostics/truthfulness.js.map +1 -0
- package/dist/dispatch-memoization.d.ts +84 -0
- package/dist/dispatch-memoization.d.ts.map +1 -0
- package/dist/dispatch-memoization.js +197 -0
- package/dist/dispatch-memoization.js.map +1 -0
- package/dist/eval/comparison-report.d.ts +164 -0
- package/dist/eval/comparison-report.d.ts.map +1 -0
- package/dist/eval/comparison-report.js +316 -0
- package/dist/eval/comparison-report.js.map +1 -0
- package/dist/eval/fixture.d.ts +74 -0
- package/dist/eval/fixture.d.ts.map +1 -0
- package/dist/eval/fixture.js +217 -0
- package/dist/eval/fixture.js.map +1 -0
- package/dist/eval/index.d.ts +13 -0
- package/dist/eval/index.d.ts.map +1 -0
- package/dist/eval/index.js +7 -0
- package/dist/eval/index.js.map +1 -0
- package/dist/eval/load-node.d.ts +16 -0
- package/dist/eval/load-node.d.ts.map +1 -0
- package/dist/eval/load-node.js +58 -0
- package/dist/eval/load-node.js.map +1 -0
- package/dist/eval/metric-collector.d.ts +209 -0
- package/dist/eval/metric-collector.d.ts.map +1 -0
- package/dist/eval/metric-collector.js +293 -0
- package/dist/eval/metric-collector.js.map +1 -0
- package/dist/eval/run-record.d.ts +76 -0
- package/dist/eval/run-record.d.ts.map +1 -0
- package/dist/eval/run-record.js +32 -0
- package/dist/eval/run-record.js.map +1 -0
- package/dist/eval/runner.d.ts +140 -0
- package/dist/eval/runner.d.ts.map +1 -0
- package/dist/eval/runner.js +310 -0
- package/dist/eval/runner.js.map +1 -0
- package/dist/eval/spec-framework.d.ts +113 -0
- package/dist/eval/spec-framework.d.ts.map +1 -0
- package/dist/eval/spec-framework.js +100 -0
- package/dist/eval/spec-framework.js.map +1 -0
- package/dist/eval/spec-helpers.d.ts +245 -0
- package/dist/eval/spec-helpers.d.ts.map +1 -0
- package/dist/eval/spec-helpers.js +605 -0
- package/dist/eval/spec-helpers.js.map +1 -0
- package/dist/events/codec.d.ts +79 -0
- package/dist/events/codec.d.ts.map +1 -0
- package/dist/events/codec.js +142 -0
- package/dist/events/codec.js.map +1 -0
- package/dist/events/log-core.d.ts +76 -0
- package/dist/events/log-core.d.ts.map +1 -0
- package/dist/events/log-core.js +73 -0
- package/dist/events/log-core.js.map +1 -0
- package/dist/events/log.d.ts +60 -0
- package/dist/events/log.d.ts.map +1 -0
- package/dist/events/log.js +193 -0
- package/dist/events/log.js.map +1 -0
- package/dist/events/replay.d.ts +106 -0
- package/dist/events/replay.d.ts.map +1 -0
- package/dist/events/replay.js +137 -0
- package/dist/events/replay.js.map +1 -0
- package/dist/events/wrap.d.ts +100 -0
- package/dist/events/wrap.d.ts.map +1 -0
- package/dist/events/wrap.js +141 -0
- package/dist/events/wrap.js.map +1 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/llm-adapter.d.ts +96 -0
- package/dist/llm-adapter.d.ts.map +1 -0
- package/dist/llm-adapter.js +132 -0
- package/dist/llm-adapter.js.map +1 -0
- package/dist/mcp/serve.d.ts +70 -0
- package/dist/mcp/serve.d.ts.map +1 -0
- package/dist/mcp/serve.js +154 -0
- package/dist/mcp/serve.js.map +1 -0
- package/dist/metrics/runs.d.ts +58 -0
- package/dist/metrics/runs.d.ts.map +1 -0
- package/dist/metrics/runs.js +99 -0
- package/dist/metrics/runs.js.map +1 -0
- package/dist/metrics.d.ts +38 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +123 -0
- package/dist/metrics.js.map +1 -0
- package/dist/node.d.ts +23 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +23 -0
- package/dist/node.js.map +1 -0
- package/dist/planner-executor.d.ts +132 -0
- package/dist/planner-executor.d.ts.map +1 -0
- package/dist/planner-executor.js +274 -0
- package/dist/planner-executor.js.map +1 -0
- package/dist/session.d.ts +10 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +179 -0
- package/dist/session.js.map +1 -0
- package/dist/skill-catalog.d.ts +81 -0
- package/dist/skill-catalog.d.ts.map +1 -0
- package/dist/skill-catalog.js +388 -0
- package/dist/skill-catalog.js.map +1 -0
- package/dist/skill-router.d.ts +95 -0
- package/dist/skill-router.d.ts.map +1 -0
- package/dist/skill-router.js +130 -0
- package/dist/skill-router.js.map +1 -0
- package/dist/storage.d.ts +14 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +58 -0
- package/dist/storage.js.map +1 -0
- package/dist/strategy.d.ts +45 -0
- package/dist/strategy.d.ts.map +1 -0
- package/dist/strategy.js +520 -0
- package/dist/strategy.js.map +1 -0
- package/dist/tools.d.ts +40 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +147 -0
- package/dist/tools.js.map +1 -0
- package/dist/types/agent.d.ts +94 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +17 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/capabilities.d.ts +17 -0
- package/dist/types/capabilities.d.ts.map +1 -0
- package/dist/types/capabilities.js +13 -0
- package/dist/types/capabilities.js.map +1 -0
- package/dist/types/chat.d.ts +74 -0
- package/dist/types/chat.d.ts.map +1 -0
- package/dist/types/chat.js +10 -0
- package/dist/types/chat.js.map +1 -0
- package/dist/types/events.d.ts +115 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +30 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/llm.d.ts +89 -0
- package/dist/types/llm.d.ts.map +1 -0
- package/dist/types/llm.js +12 -0
- package/dist/types/llm.js.map +1 -0
- package/dist/types/metrics.d.ts +34 -0
- package/dist/types/metrics.d.ts.map +1 -0
- package/dist/types/metrics.js +10 -0
- package/dist/types/metrics.js.map +1 -0
- package/dist/types/observer.d.ts +41 -0
- package/dist/types/observer.d.ts.map +1 -0
- package/dist/types/observer.js +41 -0
- package/dist/types/observer.js.map +1 -0
- package/dist/types/project-context.d.ts +18 -0
- package/dist/types/project-context.d.ts.map +1 -0
- package/dist/types/project-context.js +11 -0
- package/dist/types/project-context.js.map +1 -0
- package/dist/types/runtime.d.ts +71 -0
- package/dist/types/runtime.d.ts.map +1 -0
- package/dist/types/runtime.js +21 -0
- package/dist/types/runtime.js.map +1 -0
- package/dist/types/session.d.ts +103 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +11 -0
- package/dist/types/session.js.map +1 -0
- package/dist/types/storage.d.ts +20 -0
- package/dist/types/storage.d.ts.map +1 -0
- package/dist/types/storage.js +41 -0
- package/dist/types/storage.js.map +1 -0
- package/dist/types/strategy.d.ts +124 -0
- package/dist/types/strategy.d.ts.map +1 -0
- package/dist/types/strategy.js +10 -0
- package/dist/types/strategy.js.map +1 -0
- package/dist/types/tools.d.ts +154 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +11 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/types/trace.d.ts +175 -0
- package/dist/types/trace.d.ts.map +1 -0
- package/dist/types/trace.js +26 -0
- package/dist/types/trace.js.map +1 -0
- package/dist/types/workspace.d.ts +29 -0
- package/dist/types/workspace.d.ts.map +1 -0
- package/dist/types/workspace.js +18 -0
- package/dist/types/workspace.js.map +1 -0
- package/package.json +45 -14
- package/skills/agent-cli.md +218 -0
- package/index.js +0 -2
package/dist/tools.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
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
|
+
/**
|
|
126
|
+
* Read `handler.parallelSafe` with the conservative default. The default
|
|
127
|
+
* when the field is absent or `false` is `false` — callers must opt in
|
|
128
|
+
* explicitly. Centralised so parallel-dispatch and any future scheduler
|
|
129
|
+
* apply the same rule.
|
|
130
|
+
*/
|
|
131
|
+
export function isParallelSafe(handler) {
|
|
132
|
+
return handler.parallelSafe === true;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Read `handler.pure` with the conservative default. The default when
|
|
136
|
+
* the field is absent or `false` is `false` — callers must opt in. The
|
|
137
|
+
* memoization layer reads this through here so a future change to the
|
|
138
|
+
* default (not in this branch) lands in a single spot.
|
|
139
|
+
*/
|
|
140
|
+
export function isPure(handler) {
|
|
141
|
+
return handler.pure === true;
|
|
142
|
+
}
|
|
143
|
+
/** Trim a string to `max` chars with an ellipsis marker. */
|
|
144
|
+
function truncate(s, max) {
|
|
145
|
+
return s.length <= max ? s : `${s.slice(0, max)}…`;
|
|
146
|
+
}
|
|
147
|
+
//# 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"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `MutationEvent` — the canonical record a mutating tool emits to the
|
|
3
|
+
* project event log. Three phases:
|
|
4
|
+
*
|
|
5
|
+
* - `plan` — emitted before the tool actually runs. Records intent +
|
|
6
|
+
* captured "before" snapshot. Always present.
|
|
7
|
+
* - `commit` — emitted after the tool returns successfully. Records
|
|
8
|
+
* "after" snapshot + the `reverseOp` (when one exists) so `agent
|
|
9
|
+
* undo` can roll it back.
|
|
10
|
+
* - `rollback` — emitted when execution failed mid-flight, or when
|
|
11
|
+
* `agent undo` reverses a previously-committed event. Helps the
|
|
12
|
+
* auditor distinguish "started but never finished" from "finished
|
|
13
|
+
* and later undone."
|
|
14
|
+
*
|
|
15
|
+
* The log is **append-only NDJSON** at
|
|
16
|
+
* `~/.pyric/projects/<projectId>/events.ndjson`. The whole point is
|
|
17
|
+
* that the file is replayable + diffable — never overwrite, never
|
|
18
|
+
* mutate previous lines.
|
|
19
|
+
*
|
|
20
|
+
* See `plans/specialized-firebase-agents.md` §7 for the design rationale.
|
|
21
|
+
*/
|
|
22
|
+
export type MutationPhase = 'plan' | 'commit' | 'rollback';
|
|
23
|
+
export type TargetKind = 'doc' | 'collection' | 'rules' | 'index' | 'service' | 'bucket' | 'hosting' | 'functions' | 'workspace' | 'other';
|
|
24
|
+
export interface MutationTarget {
|
|
25
|
+
kind: TargetKind;
|
|
26
|
+
/**
|
|
27
|
+
* Stable, fully-qualified identifier for the target. Examples:
|
|
28
|
+
* - `users/alice`
|
|
29
|
+
* - `projects/my-app/rulesets/active`
|
|
30
|
+
* - `firebasestorage.googleapis.com`
|
|
31
|
+
* - `my-app.firebasestorage.app`
|
|
32
|
+
* - `workspace.rules`
|
|
33
|
+
*/
|
|
34
|
+
path: string;
|
|
35
|
+
/** Optional friendly label. */
|
|
36
|
+
label?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface ReverseOp {
|
|
39
|
+
/** Tool name to invoke to reverse the committed mutation. */
|
|
40
|
+
tool: string;
|
|
41
|
+
/** Arguments to pass. The tool MUST be registered in the same
|
|
42
|
+
* ToolRegistry the caller used; otherwise undo cannot resolve it. */
|
|
43
|
+
args: unknown;
|
|
44
|
+
/** Free-form human-readable description of the reverse action. */
|
|
45
|
+
description?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface MutationEvent {
|
|
48
|
+
/** Sortable, opaque event id (timestamp-prefixed). */
|
|
49
|
+
id: string;
|
|
50
|
+
/** ISO-8601 timestamp the event was emitted at. */
|
|
51
|
+
ts: string;
|
|
52
|
+
/** Agent that emitted it. `'host'` for direct CLI / library use. */
|
|
53
|
+
agent: string;
|
|
54
|
+
/** Session id from `AgentSession`. */
|
|
55
|
+
sessionId: string;
|
|
56
|
+
/** Tool that did (or planned) the mutation. */
|
|
57
|
+
tool: string;
|
|
58
|
+
/** Args the tool was invoked with. Stored verbatim so the event can
|
|
59
|
+
* be **replayed** against a different `ToolDispatch` (e.g. a
|
|
60
|
+
* production registry pointed at live Firestore). Optional for
|
|
61
|
+
* back-compat with legacy event files written before this field
|
|
62
|
+
* existed; legacy events can't be replayed without it. */
|
|
63
|
+
args?: unknown;
|
|
64
|
+
/** Lifecycle phase. */
|
|
65
|
+
phase: MutationPhase;
|
|
66
|
+
/** What was (or would be) mutated. */
|
|
67
|
+
target: MutationTarget;
|
|
68
|
+
/** Captured pre-image. Absent when the API doesn't expose one or the
|
|
69
|
+
* caller opted out. */
|
|
70
|
+
before?: unknown;
|
|
71
|
+
/** Captured post-image. Always present for `commit` phase. */
|
|
72
|
+
after?: unknown;
|
|
73
|
+
/** Whether the API supports reversing this mutation. Hard-false for
|
|
74
|
+
* irreversible ops (service enablement, hosting release rollbacks
|
|
75
|
+
* past retention window, etc) — `agent undo` refuses with the
|
|
76
|
+
* message in `irreversibleReason`. */
|
|
77
|
+
reversible: boolean;
|
|
78
|
+
/** When `reversible: false`, why. Surfaced to the user. */
|
|
79
|
+
irreversibleReason?: string;
|
|
80
|
+
/** When `reversible: true`, the tool+args to invoke to roll back.
|
|
81
|
+
* Absent during `plan` phase (intent, not commitment); always
|
|
82
|
+
* present on `commit` phase for reversible events. */
|
|
83
|
+
reverseOp?: ReverseOp;
|
|
84
|
+
/** Free-form metadata the host can stash on the event. The event log
|
|
85
|
+
* treats this as opaque — readers can use it to correlate with their
|
|
86
|
+
* own systems (Linear ticket id, deploy build number, etc). */
|
|
87
|
+
metadata?: Record<string, unknown>;
|
|
88
|
+
}
|
|
89
|
+
export interface MutationEventFilter {
|
|
90
|
+
/** Restrict to a single session. */
|
|
91
|
+
sessionId?: string;
|
|
92
|
+
/** Restrict to a single tool name. */
|
|
93
|
+
tool?: string;
|
|
94
|
+
/** Restrict to a single agent. */
|
|
95
|
+
agent?: string;
|
|
96
|
+
/** ISO-8601 lower bound (inclusive). */
|
|
97
|
+
since?: string;
|
|
98
|
+
/** ISO-8601 upper bound (exclusive). */
|
|
99
|
+
until?: string;
|
|
100
|
+
/** Restrict to a single phase. */
|
|
101
|
+
phase?: MutationPhase;
|
|
102
|
+
/** Restrict to a single target kind. */
|
|
103
|
+
targetKind?: TargetKind;
|
|
104
|
+
/** Restrict by event id (for undo). */
|
|
105
|
+
id?: string;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Identifier used in event records when the host didn't name an agent.
|
|
109
|
+
* Lives in the types module (zero side effects) so it's safe on the
|
|
110
|
+
* universal `@inbrowser/agent` entry — the value lives in `events/log.ts`
|
|
111
|
+
* too, but that file imports `node:fs` / `node:os` and can't ship to
|
|
112
|
+
* the browser.
|
|
113
|
+
*/
|
|
114
|
+
export declare const HOST_AGENT_ID = "host";
|
|
115
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/types/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE3D,MAAM,MAAM,UAAU,GAClB,KAAK,GACL,YAAY,GACZ,OAAO,GACP,OAAO,GACP,SAAS,GACT,QAAQ,GACR,SAAS,GACT,WAAW,GACX,WAAW,GACX,OAAO,CAAC;AAEZ,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB;;;;;;;OAOG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb;0EACsE;IACtE,IAAI,EAAE,OAAO,CAAC;IACd,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb;;;;+DAI2D;IAC3D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uBAAuB;IACvB,KAAK,EAAE,aAAa,CAAC;IACrB,sCAAsC;IACtC,MAAM,EAAE,cAAc,CAAC;IACvB;4BACwB;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;2CAGuC;IACvC,UAAU,EAAE,OAAO,CAAC;IACpB,2DAA2D;IAC3D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;2DAEuD;IACvD,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;oEAEgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB;IAClC,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,wCAAwC;IACxC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,uCAAuC;IACvC,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,SAAS,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `MutationEvent` — the canonical record a mutating tool emits to the
|
|
3
|
+
* project event log. Three phases:
|
|
4
|
+
*
|
|
5
|
+
* - `plan` — emitted before the tool actually runs. Records intent +
|
|
6
|
+
* captured "before" snapshot. Always present.
|
|
7
|
+
* - `commit` — emitted after the tool returns successfully. Records
|
|
8
|
+
* "after" snapshot + the `reverseOp` (when one exists) so `agent
|
|
9
|
+
* undo` can roll it back.
|
|
10
|
+
* - `rollback` — emitted when execution failed mid-flight, or when
|
|
11
|
+
* `agent undo` reverses a previously-committed event. Helps the
|
|
12
|
+
* auditor distinguish "started but never finished" from "finished
|
|
13
|
+
* and later undone."
|
|
14
|
+
*
|
|
15
|
+
* The log is **append-only NDJSON** at
|
|
16
|
+
* `~/.pyric/projects/<projectId>/events.ndjson`. The whole point is
|
|
17
|
+
* that the file is replayable + diffable — never overwrite, never
|
|
18
|
+
* mutate previous lines.
|
|
19
|
+
*
|
|
20
|
+
* See `plans/specialized-firebase-agents.md` §7 for the design rationale.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Identifier used in event records when the host didn't name an agent.
|
|
24
|
+
* Lives in the types module (zero side effects) so it's safe on the
|
|
25
|
+
* universal `@inbrowser/agent` entry — the value lives in `events/log.ts`
|
|
26
|
+
* too, but that file imports `node:fs` / `node:os` and can't ship to
|
|
27
|
+
* the browser.
|
|
28
|
+
*/
|
|
29
|
+
export const HOST_AGENT_ID = 'host';
|
|
30
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/types/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAuGH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `LlmClient` — narrow provider interface.
|
|
3
|
+
*
|
|
4
|
+
* Implementations live in adapter packages (one per provider). The
|
|
5
|
+
* client knows about model calls and streamed events; it knows
|
|
6
|
+
* **nothing** about BYOK forms, localStorage, model pickers, or
|
|
7
|
+
* pricing tables. Receives its config explicitly at construction
|
|
8
|
+
* time so concurrent sessions can use different keys/models against
|
|
9
|
+
* the same provider without contention.
|
|
10
|
+
*/
|
|
11
|
+
import type { NormalizedMessage } from './chat.js';
|
|
12
|
+
import type { TurnDetails, TurnMetrics } from './chat.js';
|
|
13
|
+
export interface LlmConfig {
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
model: string;
|
|
16
|
+
/** Base URL override (e.g. for OpenAI-compatible proxies). */
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
/** Reasoning effort for providers that support it (OpenRouter). */
|
|
19
|
+
reasoningEffort?: 'low' | 'medium' | 'high';
|
|
20
|
+
/** Caller-side flag — affects metrics' `isByok`. */
|
|
21
|
+
isByok?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface ChatRequest {
|
|
24
|
+
messages: NormalizedMessage[];
|
|
25
|
+
/** Tool declarations the model may invoke. Empty array → plain chat. */
|
|
26
|
+
tools: ToolDeclaration[];
|
|
27
|
+
/** Lighter than `tools.length === 0`; lets adapters skip tool-mode encoding entirely. */
|
|
28
|
+
toolUseEnabled: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface ToolDeclaration {
|
|
31
|
+
name: string;
|
|
32
|
+
description: string;
|
|
33
|
+
/** JSON Schema describing the tool's arguments. */
|
|
34
|
+
parameters: JsonSchema;
|
|
35
|
+
}
|
|
36
|
+
export type JsonSchema = {
|
|
37
|
+
type?: string;
|
|
38
|
+
description?: string;
|
|
39
|
+
properties?: Record<string, JsonSchema>;
|
|
40
|
+
required?: string[];
|
|
41
|
+
items?: JsonSchema | JsonSchema[];
|
|
42
|
+
enum?: unknown[];
|
|
43
|
+
[key: string]: unknown;
|
|
44
|
+
};
|
|
45
|
+
export interface LlmClient {
|
|
46
|
+
readonly id: string;
|
|
47
|
+
readonly supportsTools: boolean;
|
|
48
|
+
chat(req: ChatRequest, signal: AbortSignal): AsyncIterable<ChatEvent>;
|
|
49
|
+
}
|
|
50
|
+
export type ChatEvent = {
|
|
51
|
+
kind: 'text';
|
|
52
|
+
chunk: string;
|
|
53
|
+
} | {
|
|
54
|
+
kind: 'thinking';
|
|
55
|
+
chunk: string;
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'tool_call';
|
|
58
|
+
id: string;
|
|
59
|
+
name: string;
|
|
60
|
+
args: unknown;
|
|
61
|
+
signature?: string;
|
|
62
|
+
} | {
|
|
63
|
+
kind: 'turn_complete';
|
|
64
|
+
usage: RawUsage;
|
|
65
|
+
details: TurnDetails;
|
|
66
|
+
} | {
|
|
67
|
+
kind: 'error';
|
|
68
|
+
message: string;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Raw token usage as the provider reports it — interpreted by
|
|
72
|
+
* `MetricsCollector` to derive `TurnMetrics` (cost, cached
|
|
73
|
+
* fraction, reasoning fraction). Different providers report
|
|
74
|
+
* different shapes; the collector handles them.
|
|
75
|
+
*/
|
|
76
|
+
export interface RawUsage {
|
|
77
|
+
promptTokens: number;
|
|
78
|
+
completionTokens: number;
|
|
79
|
+
cachedTokens?: number;
|
|
80
|
+
reasoningTokens?: number;
|
|
81
|
+
/** Provider-supplied cost (OpenRouter), when available — bypasses pricing tables. */
|
|
82
|
+
costUsd?: number;
|
|
83
|
+
}
|
|
84
|
+
export interface LlmClientFactory {
|
|
85
|
+
create(config: LlmConfig): LlmClient;
|
|
86
|
+
}
|
|
87
|
+
/** Re-export so consumers don't have to dig into `./chat.js`. */
|
|
88
|
+
export type { TurnDetails, TurnMetrics };
|
|
89
|
+
//# sourceMappingURL=llm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/types/llm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE1D,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,eAAe,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC5C,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,wEAAwE;IACxE,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,yFAAyF;IACzF,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,UAAU,GAAG,UAAU,EAAE,CAAC;IAClC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;CACvE;AAED,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClF;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qFAAqF;IACrF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;CACtC;AAED,iEAAiE;AACjE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC"}
|