agent-sh 0.13.7 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/agent/agent-loop.d.ts +13 -17
- package/dist/agent/agent-loop.js +118 -224
- package/dist/agent/conversation-state.d.ts +1 -1
- package/dist/agent/events.d.ts +218 -0
- package/dist/agent/events.js +1 -0
- package/dist/agent/host-types.d.ts +20 -0
- package/dist/agent/index.d.ts +5 -9
- package/dist/agent/index.js +269 -167
- package/dist/agent/llm-facade.d.ts +13 -0
- package/dist/{utils → agent}/llm-facade.js +1 -1
- package/dist/agent/nuclear-form.d.ts +1 -1
- package/dist/agent/providers/deepseek.js +2 -5
- package/dist/agent/providers/openai-compatible.js +2 -2
- package/dist/agent/providers/openai.js +2 -5
- package/dist/agent/providers/openrouter.js +5 -5
- package/dist/agent/subagent.d.ts +1 -1
- package/dist/agent/tool-protocol.d.ts +1 -1
- package/dist/agent/tool-registry.d.ts +1 -1
- package/dist/cli/auth/cli.js +11 -6
- package/dist/cli/auth/discover.d.ts +5 -0
- package/dist/cli/auth/discover.js +25 -0
- package/dist/cli/auth/keys.d.ts +5 -2
- package/dist/cli/auth/keys.js +22 -2
- package/dist/cli/index.d.ts +16 -0
- package/dist/cli/index.js +12 -2
- package/dist/core/event-bus.d.ts +28 -371
- package/dist/core/extension-loader.js +6 -6
- package/dist/core/index.d.ts +10 -29
- package/dist/core/index.js +32 -84
- package/dist/extensions/index.d.ts +2 -1
- package/dist/extensions/index.js +1 -1
- package/dist/extensions/slash-commands/events.d.ts +18 -0
- package/dist/extensions/slash-commands/events.js +1 -0
- package/dist/extensions/slash-commands/index.d.ts +15 -0
- package/dist/extensions/{slash-commands.js → slash-commands/index.js} +4 -3
- package/dist/shell/events.d.ts +85 -0
- package/dist/shell/events.js +1 -0
- package/dist/shell/index.d.ts +1 -0
- package/dist/shell/index.js +6 -0
- package/dist/shell/tui-renderer.js +0 -1
- package/examples/extensions/ash-acp-bridge/src/index.ts +2 -2
- package/examples/extensions/ashi/package.json +1 -1
- package/examples/extensions/ollama.ts +47 -42
- package/examples/extensions/opencode-bridge/README.md +4 -0
- package/examples/extensions/opencode-bridge/index.ts +3 -1
- package/examples/extensions/pi-bridge/index.ts +3 -4
- package/examples/extensions/zai-coding-plan.ts +2 -6
- package/package.json +1 -1
- package/dist/extensions/slash-commands.d.ts +0 -2
- package/dist/utils/llm-facade.d.ts +0 -11
- /package/dist/{utils → agent}/llm-client.d.ts +0 -0
- /package/dist/{utils → agent}/llm-client.js +0 -0
package/dist/agent/subagent.d.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Used by the subagent extension to delegate tasks from the main agent.
|
|
11
11
|
*/
|
|
12
12
|
import type { EventBus } from "../core/event-bus.js";
|
|
13
|
-
import type { LlmClient } from "
|
|
13
|
+
import type { LlmClient } from "./llm-client.js";
|
|
14
14
|
import type { ToolDefinition } from "./types.js";
|
|
15
15
|
export interface SubagentOptions {
|
|
16
16
|
/** LLM client to use. */
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* The agent loop uses this interface uniformly so the rest of the code
|
|
10
10
|
* doesn't need to know which mode is active.
|
|
11
11
|
*/
|
|
12
|
-
import type { ChatCompletionTool } from "
|
|
12
|
+
import type { ChatCompletionTool } from "./llm-client.js";
|
|
13
13
|
import type { ToolDefinition } from "./types.js";
|
|
14
14
|
import type { ConversationState } from "./conversation-state.js";
|
|
15
15
|
export interface PendingToolCall {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ToolDefinition, ToolResult } from "./types.js";
|
|
2
|
-
import type { ChatCompletionTool } from "
|
|
2
|
+
import type { ChatCompletionTool } from "./llm-client.js";
|
|
3
3
|
import type { HandlerFunctions } from "../utils/handler-registry.js";
|
|
4
4
|
/**
|
|
5
5
|
* Registry for agent tools. Execution is routed through the named-handler
|
package/dist/cli/auth/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as readline from "node:readline";
|
|
2
2
|
import { palette as p } from "../../utils/palette.js";
|
|
3
|
-
import { KNOWN_PROVIDERS, KEYS_PATH, loadKeysFile, saveKeysFile, resolveApiKey,
|
|
3
|
+
import { KNOWN_PROVIDERS, KEYS_PATH, loadKeysFile, saveKeysFile, resolveApiKey, listAllProvidersWithDiscovery, findProvider as findProviderById, } from "./keys.js";
|
|
4
4
|
export async function runAuth(args) {
|
|
5
5
|
const sub = args[0];
|
|
6
6
|
if (!sub || sub === "--help" || sub === "-h") {
|
|
@@ -16,7 +16,7 @@ export async function runAuth(args) {
|
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
18
|
if (sub === "list" || sub === "ls" || sub === "status") {
|
|
19
|
-
runList();
|
|
19
|
+
await runList();
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
22
|
console.error(`agent-sh auth: unknown subcommand "${sub}"`);
|
|
@@ -90,8 +90,8 @@ function runLogout(providerArg) {
|
|
|
90
90
|
saveKeysFile(keys);
|
|
91
91
|
console.log(`${p.success}✓${p.reset} Removed ${id} key from ${KEYS_PATH}`);
|
|
92
92
|
}
|
|
93
|
-
function runList() {
|
|
94
|
-
const providers =
|
|
93
|
+
async function runList() {
|
|
94
|
+
const providers = await listAllProvidersWithDiscovery();
|
|
95
95
|
console.log("Provider key status:\n");
|
|
96
96
|
const idWidth = Math.max(...providers.map((p) => p.id.length));
|
|
97
97
|
for (const info of providers) {
|
|
@@ -105,6 +105,9 @@ function runList() {
|
|
|
105
105
|
if (resolved.key) {
|
|
106
106
|
console.log(` ${p.success}●${p.reset} ${padded} ${p.dim}(${sourceLabel(resolved.source, info)})${p.reset}${marker}`);
|
|
107
107
|
}
|
|
108
|
+
else if (info.noAuth) {
|
|
109
|
+
console.log(` ${p.success}●${p.reset} ${padded} ${p.dim}(no auth required)${p.reset}${marker}`);
|
|
110
|
+
}
|
|
108
111
|
else {
|
|
109
112
|
console.log(` ${p.muted}○${p.reset} ${padded} ${p.dim}(not configured)${p.reset}${marker}`);
|
|
110
113
|
}
|
|
@@ -117,13 +120,15 @@ async function pickProvider() {
|
|
|
117
120
|
console.error("agent-sh auth: no provider specified and stdin is not a TTY.");
|
|
118
121
|
return null;
|
|
119
122
|
}
|
|
120
|
-
const providers =
|
|
123
|
+
const providers = await listAllProvidersWithDiscovery();
|
|
121
124
|
console.log("Select a provider:");
|
|
122
125
|
providers.forEach((info, i) => {
|
|
123
126
|
const resolved = resolveApiKey(info.id);
|
|
124
127
|
const tag = resolved.key
|
|
125
128
|
? `${p.dim}(currently from ${sourceLabel(resolved.source, info)})${p.reset}`
|
|
126
|
-
:
|
|
129
|
+
: info.noAuth
|
|
130
|
+
? `${p.dim}(no auth required)${p.reset}`
|
|
131
|
+
: `${p.dim}(not configured)${p.reset}`;
|
|
127
132
|
const labelStr = info.custom
|
|
128
133
|
? `${p.dim}custom${p.reset}`
|
|
129
134
|
: info.unattached
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Bootstrap a throwaway core to enumerate provider ids extensions
|
|
2
|
+
* would register, so `auth list` shows ids the user hasn't keyed yet. */
|
|
3
|
+
import { createCore } from "../../core/index.js";
|
|
4
|
+
import { activateAgent } from "../../agent/index.js";
|
|
5
|
+
import { loadExtensions } from "../../core/extension-loader.js";
|
|
6
|
+
import { loadBuiltinExtensions } from "../../extensions/index.js";
|
|
7
|
+
import { getSettings } from "../../core/settings.js";
|
|
8
|
+
let cached = null;
|
|
9
|
+
export async function discoverExtensionProviders() {
|
|
10
|
+
if (cached)
|
|
11
|
+
return cached;
|
|
12
|
+
const core = createCore({});
|
|
13
|
+
try {
|
|
14
|
+
const ctx = core.extensionContext({ quit: () => { } });
|
|
15
|
+
activateAgent(ctx);
|
|
16
|
+
await loadBuiltinExtensions(ctx, getSettings().disabledBuiltins);
|
|
17
|
+
await loadExtensions(ctx).catch(() => { });
|
|
18
|
+
const { providers } = core.bus.emitPipe("agent:providers", { providers: [] });
|
|
19
|
+
cached = providers.map((p) => ({ id: p.id, noAuth: p.noAuth }));
|
|
20
|
+
return cached;
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
core.kill();
|
|
24
|
+
}
|
|
25
|
+
}
|
package/dist/cli/auth/keys.d.ts
CHANGED
|
@@ -9,11 +9,14 @@ export interface ProviderAuthInfo {
|
|
|
9
9
|
/** True for ids only present in keys.json — likely owned by an extension
|
|
10
10
|
* that registers a provider at runtime. */
|
|
11
11
|
unattached?: boolean;
|
|
12
|
+
/** Auth UI shows "no auth required" instead of "not configured". */
|
|
13
|
+
noAuth?: boolean;
|
|
12
14
|
}
|
|
13
15
|
export declare const KNOWN_PROVIDERS: ProviderAuthInfo[];
|
|
14
|
-
/** Built-ins
|
|
15
|
-
* appear in keys.json (likely registered by an extension at runtime). */
|
|
16
|
+
/** Built-ins + settings + keys.json. Sync, no extension load. */
|
|
16
17
|
export declare function listAllProviders(): ProviderAuthInfo[];
|
|
18
|
+
/** Augments listAllProviders with extension-registered ids. */
|
|
19
|
+
export declare function listAllProvidersWithDiscovery(): Promise<ProviderAuthInfo[]>;
|
|
17
20
|
/** Resolve an id against known + settings entries only. Returns null for
|
|
18
21
|
* unattached or unknown ids — callers decide whether to accept them. */
|
|
19
22
|
export declare function findProvider(id: string): ProviderAuthInfo | null;
|
package/dist/cli/auth/keys.js
CHANGED
|
@@ -8,8 +8,7 @@ export const KNOWN_PROVIDERS = [
|
|
|
8
8
|
{ id: "openrouter", label: "OpenRouter", envVar: "OPENROUTER_API_KEY" },
|
|
9
9
|
{ id: "deepseek", label: "DeepSeek", envVar: "DEEPSEEK_API_KEY" },
|
|
10
10
|
];
|
|
11
|
-
/** Built-ins
|
|
12
|
-
* appear in keys.json (likely registered by an extension at runtime). */
|
|
11
|
+
/** Built-ins + settings + keys.json. Sync, no extension load. */
|
|
13
12
|
export function listAllProviders() {
|
|
14
13
|
const out = [...KNOWN_PROVIDERS];
|
|
15
14
|
const seen = new Set(out.map((p) => p.id));
|
|
@@ -28,6 +27,27 @@ export function listAllProviders() {
|
|
|
28
27
|
}
|
|
29
28
|
return out;
|
|
30
29
|
}
|
|
30
|
+
/** Augments listAllProviders with extension-registered ids. */
|
|
31
|
+
export async function listAllProvidersWithDiscovery() {
|
|
32
|
+
const out = listAllProviders();
|
|
33
|
+
const byId = new Map(out.map((p) => [p.id, p]));
|
|
34
|
+
const { discoverExtensionProviders } = await import("./discover.js");
|
|
35
|
+
try {
|
|
36
|
+
for (const d of await discoverExtensionProviders()) {
|
|
37
|
+
const existing = byId.get(d.id);
|
|
38
|
+
if (existing) {
|
|
39
|
+
if (d.noAuth && !existing.noAuth)
|
|
40
|
+
existing.noAuth = true;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const entry = { id: d.id, label: d.id, custom: true, noAuth: d.noAuth };
|
|
44
|
+
out.push(entry);
|
|
45
|
+
byId.set(d.id, entry);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch { }
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
31
51
|
/** Resolve an id against known + settings entries only. Returns null for
|
|
32
52
|
* unattached or unknown ids — callers decide whether to accept them. */
|
|
33
53
|
export function findProvider(id) {
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -1,2 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
declare module "../core/event-bus.js" {
|
|
3
|
+
interface BusEvents {
|
|
4
|
+
/** Startup banner collection (sync pipe). Extensions contribute
|
|
5
|
+
* labeled item lists; the CLI renders them between the product
|
|
6
|
+
* name and the help hint. */
|
|
7
|
+
"banner:collect": {
|
|
8
|
+
sections: Array<{
|
|
9
|
+
label: string;
|
|
10
|
+
items: string[];
|
|
11
|
+
}>;
|
|
12
|
+
/** Name of the backend being launched. Extensions should gate
|
|
13
|
+
* per-backend sections on this rather than settings.defaultBackend. */
|
|
14
|
+
activeBackend?: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
2
18
|
export {};
|
package/dist/cli/index.js
CHANGED
|
@@ -60,9 +60,18 @@ async function main() {
|
|
|
60
60
|
// ── Core (frontend-agnostic) ──────────────────────────────────
|
|
61
61
|
const core = createCore(config);
|
|
62
62
|
const { bus } = core;
|
|
63
|
-
// Track agent info from bus events (populated by extension backends)
|
|
64
63
|
let agentInfo = null;
|
|
65
|
-
bus.on("agent:info", (info) => {
|
|
64
|
+
bus.on("agent:info", (info) => {
|
|
65
|
+
agentInfo = info;
|
|
66
|
+
// Redraw so late agent:info emits (opencode-bridge after session.create) reach the prompt.
|
|
67
|
+
bus.emit("config:changed", {});
|
|
68
|
+
});
|
|
69
|
+
// tui-renderer subscribes to ui:error inside activateShell, after backend
|
|
70
|
+
// activation — pipe to stderr until the shell is up so boot failures surface.
|
|
71
|
+
const bootUiError = (e) => {
|
|
72
|
+
process.stderr.write(`agent-sh: ${e.message}\n`);
|
|
73
|
+
};
|
|
74
|
+
bus.on("ui:error", bootUiError);
|
|
66
75
|
// ── Interactive frontend ──────────────────────────────────────
|
|
67
76
|
if (process.env.DEBUG) {
|
|
68
77
|
console.error('[agent-sh] Setting up interactive frontend...');
|
|
@@ -157,6 +166,7 @@ async function main() {
|
|
|
157
166
|
return { info: "" };
|
|
158
167
|
},
|
|
159
168
|
});
|
|
169
|
+
bus.off("ui:error", bootUiError);
|
|
160
170
|
bus.emit("input-mode:register", {
|
|
161
171
|
id: "agent",
|
|
162
172
|
trigger: ">",
|
package/dist/core/event-bus.d.ts
CHANGED
|
@@ -1,181 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
11
|
-
"shell:command-done": {
|
|
12
|
-
command: string;
|
|
13
|
-
output: string;
|
|
14
|
-
cwd: string;
|
|
15
|
-
exitCode: number | null;
|
|
16
|
-
};
|
|
17
|
-
"shell:cwd-change": {
|
|
18
|
-
cwd: string;
|
|
19
|
-
};
|
|
20
|
-
"shell:foreground-busy": {
|
|
21
|
-
busy: boolean;
|
|
22
|
-
};
|
|
23
|
-
"shell:agent-exec-start": Record<string, never>;
|
|
24
|
-
"shell:agent-exec-done": Record<string, never>;
|
|
25
|
-
"shell:pty-data": {
|
|
26
|
-
raw: string;
|
|
27
|
-
};
|
|
28
|
-
"shell:pty-write": {
|
|
29
|
-
data: string;
|
|
30
|
-
};
|
|
31
|
-
"shell:pty-resize": {
|
|
32
|
-
cols: number;
|
|
33
|
-
rows: number;
|
|
34
|
-
};
|
|
35
|
-
"shell:buffer-request": Record<string, never>;
|
|
36
|
-
"shell:buffer-snapshot": {
|
|
37
|
-
text: string;
|
|
38
|
-
altScreen: boolean;
|
|
39
|
-
cursor: {
|
|
40
|
-
x: number;
|
|
41
|
-
y: number;
|
|
42
|
-
};
|
|
43
|
-
};
|
|
44
|
-
"agent:submit": {
|
|
45
|
-
query: string;
|
|
46
|
-
};
|
|
47
|
-
"agent:cancel-request": {
|
|
48
|
-
silent?: boolean;
|
|
49
|
-
};
|
|
50
|
-
"agent:append-user-message": {
|
|
51
|
-
text: string;
|
|
52
|
-
};
|
|
53
|
-
"input-mode:register": import("../shell/host-types.js").InputModeConfig;
|
|
54
|
-
"agent:query": {
|
|
55
|
-
query: string;
|
|
56
|
-
};
|
|
57
|
-
"agent:thinking-chunk": {
|
|
58
|
-
text: string;
|
|
59
|
-
};
|
|
60
|
-
"agent:response-chunk": {
|
|
61
|
-
blocks: ContentBlock[];
|
|
62
|
-
};
|
|
63
|
-
"agent:response-done": {
|
|
64
|
-
response: string;
|
|
65
|
-
};
|
|
66
|
-
"agent:usage": {
|
|
67
|
-
prompt_tokens: number;
|
|
68
|
-
completion_tokens: number;
|
|
69
|
-
total_tokens: number;
|
|
70
|
-
};
|
|
71
|
-
"llm:request": {
|
|
72
|
-
messages: unknown[];
|
|
73
|
-
tools?: unknown;
|
|
74
|
-
model?: string;
|
|
75
|
-
max_tokens?: number;
|
|
76
|
-
reasoning_effort?: string;
|
|
77
|
-
};
|
|
78
|
-
"llm:chunk": {
|
|
79
|
-
chunk: unknown;
|
|
80
|
-
};
|
|
81
|
-
"agent:processing-start": Record<string, never>;
|
|
82
|
-
"agent:processing-done": Record<string, never>;
|
|
83
|
-
"agent:cancelled": Record<string, never>;
|
|
84
|
-
"agent:error": {
|
|
85
|
-
message: string;
|
|
86
|
-
};
|
|
87
|
-
"agent:tool-call": {
|
|
88
|
-
tool: string;
|
|
89
|
-
args: Record<string, unknown>;
|
|
90
|
-
};
|
|
91
|
-
"agent:tool-output": {
|
|
92
|
-
tool: string;
|
|
93
|
-
output: string;
|
|
94
|
-
exitCode: number | null;
|
|
95
|
-
};
|
|
96
|
-
"agent:tool-batch": {
|
|
97
|
-
groups: Array<{
|
|
98
|
-
kind: string;
|
|
99
|
-
tools: Array<{
|
|
100
|
-
name: string;
|
|
101
|
-
displayDetail?: string;
|
|
102
|
-
}>;
|
|
103
|
-
}>;
|
|
104
|
-
};
|
|
105
|
-
"agent:tool-batch-complete": {
|
|
106
|
-
results: Array<{
|
|
107
|
-
name: string;
|
|
108
|
-
isError: boolean;
|
|
109
|
-
errorSummary?: string;
|
|
110
|
-
}>;
|
|
111
|
-
};
|
|
112
|
-
"conversation:message-appended": {
|
|
113
|
-
role: "user" | "assistant" | "tool" | "system";
|
|
114
|
-
content: string;
|
|
115
|
-
/** For role="tool": name of the tool whose result this is. */
|
|
116
|
-
toolName?: string;
|
|
117
|
-
/** For role="tool": parsed arguments passed to the tool. */
|
|
118
|
-
toolArgs?: Record<string, unknown>;
|
|
119
|
-
/** For role="tool": whether the tool errored. */
|
|
120
|
-
isError?: boolean;
|
|
121
|
-
};
|
|
122
|
-
"conversation:after-compact": {
|
|
123
|
-
beforeTokens: number;
|
|
124
|
-
afterTokens: number;
|
|
125
|
-
evictedCount: number;
|
|
126
|
-
};
|
|
127
|
-
"agent:tool-started": {
|
|
128
|
-
title: string;
|
|
129
|
-
toolCallId?: string;
|
|
130
|
-
kind?: string;
|
|
131
|
-
icon?: string;
|
|
132
|
-
locations?: {
|
|
133
|
-
path: string;
|
|
134
|
-
line?: number | null;
|
|
135
|
-
}[];
|
|
136
|
-
rawInput?: unknown;
|
|
137
|
-
/** Pre-formatted display detail from tool's formatCall(). */
|
|
138
|
-
displayDetail?: string;
|
|
139
|
-
/** highlight.js-style identifier for syntax-highlighting `rawInput.source`. */
|
|
140
|
-
sourceLanguage?: string;
|
|
141
|
-
batchIndex?: number;
|
|
142
|
-
batchTotal?: number;
|
|
143
|
-
};
|
|
144
|
-
"agent:tool-completed": {
|
|
145
|
-
toolCallId?: string;
|
|
146
|
-
exitCode: number | null;
|
|
147
|
-
rawOutput?: unknown;
|
|
148
|
-
kind?: string;
|
|
149
|
-
/** Structured result display — set by formatResult or defaults, overridable via onPipe. */
|
|
150
|
-
resultDisplay?: ToolResultDisplay;
|
|
151
|
-
};
|
|
152
|
-
"agent:tool-output-chunk": {
|
|
153
|
-
chunk: string;
|
|
154
|
-
};
|
|
155
|
-
"agent:subagent-started": {
|
|
156
|
-
taskId: string;
|
|
157
|
-
task: string;
|
|
158
|
-
};
|
|
159
|
-
"agent:subagent-completed": {
|
|
160
|
-
taskId: string;
|
|
161
|
-
task: string;
|
|
162
|
-
result: string;
|
|
163
|
-
isError: boolean;
|
|
164
|
-
};
|
|
165
|
-
"tool:interactive-start": Record<string, never>;
|
|
166
|
-
"tool:interactive-end": Record<string, never>;
|
|
167
|
-
"command:register": {
|
|
168
|
-
name: string;
|
|
169
|
-
description: string;
|
|
170
|
-
handler: (args: string) => Promise<void> | void;
|
|
171
|
-
};
|
|
172
|
-
"command:unregister": {
|
|
173
|
-
name: string;
|
|
174
|
-
};
|
|
175
|
-
"command:execute": {
|
|
176
|
-
name: string;
|
|
177
|
-
args: string;
|
|
1
|
+
export interface BackendRegistration {
|
|
2
|
+
name: string;
|
|
3
|
+
kill: () => void;
|
|
4
|
+
start?: () => Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
/** Typed event map — every event has a known payload shape. */
|
|
7
|
+
export interface BusEvents {
|
|
8
|
+
"core:extensions-loaded": {
|
|
9
|
+
names: string[];
|
|
178
10
|
};
|
|
11
|
+
/** Cross-cutting "config might have changed, repaint" signal. */
|
|
12
|
+
"config:changed": Record<string, never>;
|
|
13
|
+
/** Universal UI feedback channel (any frontend may render; silently
|
|
14
|
+
* ignored without one). */
|
|
179
15
|
"ui:info": {
|
|
180
16
|
message: string;
|
|
181
17
|
};
|
|
@@ -185,196 +21,17 @@ export interface ShellEvents {
|
|
|
185
21
|
"ui:suggestion": {
|
|
186
22
|
text: string;
|
|
187
23
|
};
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
};
|
|
192
|
-
"input:keypress": {
|
|
193
|
-
key: string;
|
|
194
|
-
};
|
|
195
|
-
"input:intercept": {
|
|
196
|
-
data: string;
|
|
197
|
-
consumed: boolean;
|
|
198
|
-
};
|
|
199
|
-
"shell:stdout-hold": Record<string, never>;
|
|
200
|
-
"shell:stdout-release": Record<string, never>;
|
|
201
|
-
"shell:stdout-show": Record<string, never>;
|
|
202
|
-
"shell:stdout-hide": Record<string, never>;
|
|
203
|
-
"agent:terminal-intercept": {
|
|
204
|
-
command: string;
|
|
205
|
-
cwd: string;
|
|
206
|
-
intercepted: boolean;
|
|
207
|
-
output: string;
|
|
208
|
-
};
|
|
209
|
-
"shell:redraw-prompt": {
|
|
210
|
-
cwd: string;
|
|
211
|
-
kind: "fresh" | "redraw";
|
|
212
|
-
handled: boolean;
|
|
213
|
-
};
|
|
214
|
-
"shell:exec-request": {
|
|
215
|
-
command: string;
|
|
216
|
-
output: string;
|
|
217
|
-
cwd: string;
|
|
218
|
-
exitCode: number | null;
|
|
219
|
-
done: boolean;
|
|
220
|
-
};
|
|
221
|
-
"agent:info": {
|
|
222
|
-
name: string;
|
|
223
|
-
version: string;
|
|
224
|
-
model?: string;
|
|
225
|
-
provider?: string;
|
|
226
|
-
contextWindow?: number;
|
|
227
|
-
};
|
|
228
|
-
"agent:reset-session": Record<string, never>;
|
|
229
|
-
"agent:compact-request": Record<string, never>;
|
|
230
|
-
"context:get-stats": {
|
|
231
|
-
activeTokens: number;
|
|
232
|
-
totalTokens: number;
|
|
233
|
-
budgetTokens: number;
|
|
234
|
-
};
|
|
235
|
-
"context:snapshot": {
|
|
236
|
-
messages: unknown[];
|
|
237
|
-
contextWindow: number;
|
|
238
|
-
activeTokens: number;
|
|
239
|
-
};
|
|
240
|
-
"context:compact": {
|
|
241
|
-
strategy?: {
|
|
242
|
-
kind: "two-tier-pin";
|
|
243
|
-
target: number;
|
|
244
|
-
keepRecent?: number;
|
|
245
|
-
force?: boolean;
|
|
246
|
-
} | {
|
|
247
|
-
kind: "rewind";
|
|
248
|
-
toIndex: number;
|
|
249
|
-
} | {
|
|
250
|
-
kind: "replace";
|
|
251
|
-
messages: unknown[];
|
|
252
|
-
};
|
|
253
|
-
stats?: {
|
|
254
|
-
before: number;
|
|
255
|
-
after: number;
|
|
256
|
-
evictedCount: number;
|
|
257
|
-
};
|
|
258
|
-
};
|
|
259
|
-
"agent:register-backend": {
|
|
260
|
-
name: string;
|
|
261
|
-
kill: () => void;
|
|
262
|
-
start?: () => Promise<void>;
|
|
263
|
-
};
|
|
264
|
-
"config:switch-backend": {
|
|
265
|
-
name: string;
|
|
266
|
-
};
|
|
267
|
-
"config:list-backends": Record<string, never>;
|
|
24
|
+
/** Backend registry — core owns these; every backend (ash, bridges)
|
|
25
|
+
* emits register, switch/list flow through here too. */
|
|
26
|
+
"agent:register-backend": BackendRegistration;
|
|
268
27
|
"config:get-backends": {
|
|
269
28
|
names: string[];
|
|
270
29
|
active: string | null;
|
|
271
30
|
};
|
|
272
|
-
"config:
|
|
273
|
-
"config:switch-model": {
|
|
274
|
-
model: string;
|
|
275
|
-
};
|
|
276
|
-
"config:get-models": {
|
|
277
|
-
models: {
|
|
278
|
-
model: string;
|
|
279
|
-
provider: string;
|
|
280
|
-
}[];
|
|
281
|
-
active: {
|
|
282
|
-
model: string;
|
|
283
|
-
provider: string;
|
|
284
|
-
} | null;
|
|
285
|
-
};
|
|
286
|
-
"config:set-thinking": {
|
|
287
|
-
level: string;
|
|
288
|
-
};
|
|
289
|
-
"config:get-thinking": {
|
|
290
|
-
level: string;
|
|
291
|
-
levels: string[];
|
|
292
|
-
supported: boolean;
|
|
293
|
-
};
|
|
294
|
-
"config:switch-provider": {
|
|
295
|
-
provider: string;
|
|
296
|
-
};
|
|
297
|
-
"config:get-initial-modes": {
|
|
298
|
-
modes: AgentMode[];
|
|
299
|
-
initialModeIndex: number;
|
|
300
|
-
};
|
|
301
|
-
"config:set-modes": {
|
|
302
|
-
modes: AgentMode[];
|
|
303
|
-
activeIndex?: number;
|
|
304
|
-
};
|
|
305
|
-
"config:add-modes": {
|
|
306
|
-
modes: AgentMode[];
|
|
307
|
-
};
|
|
308
|
-
"core:extensions-loaded": {
|
|
309
|
-
names: string[];
|
|
310
|
-
};
|
|
311
|
-
"provider:register": {
|
|
312
|
-
id: string;
|
|
313
|
-
apiKey?: string;
|
|
314
|
-
baseURL?: string;
|
|
315
|
-
/** Optional — providers for custom endpoints may not know the catalog
|
|
316
|
-
* at registration time. Falls back to models[0] when absent. */
|
|
317
|
-
defaultModel?: string;
|
|
318
|
-
models?: (string | {
|
|
319
|
-
id: string;
|
|
320
|
-
reasoning?: boolean;
|
|
321
|
-
contextWindow?: number;
|
|
322
|
-
maxTokens?: number;
|
|
323
|
-
echoReasoning?: boolean;
|
|
324
|
-
})[];
|
|
325
|
-
/** Provider supports the reasoning_effort parameter. Default: true. */
|
|
326
|
-
supportsReasoningEffort?: boolean;
|
|
327
|
-
};
|
|
328
|
-
"provider:configure": {
|
|
329
|
-
id: string;
|
|
330
|
-
reasoningParams?: (level: string, model?: string) => Record<string, unknown>;
|
|
331
|
-
};
|
|
332
|
-
"agent:register-tool": {
|
|
333
|
-
tool: import("../agent/types.js").ToolDefinition;
|
|
334
|
-
extensionName?: string;
|
|
335
|
-
};
|
|
336
|
-
"agent:unregister-tool": {
|
|
337
|
-
name: string;
|
|
338
|
-
};
|
|
339
|
-
"agent:get-tools": {
|
|
340
|
-
tools: import("../agent/types.js").ToolDefinition[];
|
|
341
|
-
};
|
|
342
|
-
"agent:register-instruction": {
|
|
343
|
-
name: string;
|
|
344
|
-
text: string;
|
|
345
|
-
extensionName: string;
|
|
346
|
-
};
|
|
347
|
-
"agent:remove-instruction": {
|
|
348
|
-
name: string;
|
|
349
|
-
};
|
|
350
|
-
"agent:register-skill": {
|
|
351
|
-
name: string;
|
|
352
|
-
description: string;
|
|
353
|
-
filePath: string;
|
|
354
|
-
extensionName: string;
|
|
355
|
-
};
|
|
356
|
-
"agent:remove-skill": {
|
|
31
|
+
"config:switch-backend": {
|
|
357
32
|
name: string;
|
|
358
33
|
};
|
|
359
|
-
"
|
|
360
|
-
sections: Array<{
|
|
361
|
-
label: string;
|
|
362
|
-
items: string[];
|
|
363
|
-
}>;
|
|
364
|
-
/** Name of the backend being launched. Extensions should gate per-backend sections on this rather than settings.defaultBackend. */
|
|
365
|
-
activeBackend?: string;
|
|
366
|
-
};
|
|
367
|
-
"autocomplete:request": {
|
|
368
|
-
buffer: string;
|
|
369
|
-
/** Parsed slash command name (e.g. "/backend"), or null if not a command. */
|
|
370
|
-
command: string | null;
|
|
371
|
-
/** Text after the command name (e.g. "clau" for "/backend clau"), or null. */
|
|
372
|
-
commandArgs: string | null;
|
|
373
|
-
items: {
|
|
374
|
-
name: string;
|
|
375
|
-
description: string;
|
|
376
|
-
}[];
|
|
377
|
-
};
|
|
34
|
+
"config:list-backends": Record<string, never>;
|
|
378
35
|
}
|
|
379
36
|
export type ContentBlock = {
|
|
380
37
|
type: "text";
|
|
@@ -421,11 +78,11 @@ export declare class EventBus {
|
|
|
421
78
|
/** Stamp + dispatch — used by every emit path. */
|
|
422
79
|
private dispatch;
|
|
423
80
|
/** Subscribe to a fire-and-forget event. */
|
|
424
|
-
on<K extends keyof
|
|
81
|
+
on<K extends keyof BusEvents>(event: K, fn: Listener<BusEvents[K]>): void;
|
|
425
82
|
/** Unsubscribe from a fire-and-forget event. */
|
|
426
|
-
off<K extends keyof
|
|
83
|
+
off<K extends keyof BusEvents>(event: K, fn: Listener<BusEvents[K]>): void;
|
|
427
84
|
/** Emit a fire-and-forget event. */
|
|
428
|
-
emit<K extends keyof
|
|
85
|
+
emit<K extends keyof BusEvents>(event: K, payload: BusEvents[K]): void;
|
|
429
86
|
/** Re-dispatch an event with externally-supplied meta. Used by bridges
|
|
430
87
|
* and replay tools to preserve the original source/ts/id of remote or
|
|
431
88
|
* recorded events instead of restamping them as locally originated. */
|
|
@@ -436,21 +93,21 @@ export declare class EventBus {
|
|
|
436
93
|
* listeners (renderers). This enables content pipelines where extensions
|
|
437
94
|
* modify data (e.g. render LaTeX → terminal image) before renderers see it.
|
|
438
95
|
*/
|
|
439
|
-
emitTransform<K extends keyof
|
|
96
|
+
emitTransform<K extends keyof BusEvents>(event: K, payload: BusEvents[K]): void;
|
|
440
97
|
/** Register a transform listener for a pipeline event. */
|
|
441
|
-
onPipe<K extends keyof
|
|
98
|
+
onPipe<K extends keyof BusEvents>(event: K, fn: PipeListener<BusEvents[K]>): void;
|
|
442
99
|
/** Remove a transform listener from a pipeline event. */
|
|
443
|
-
offPipe<K extends keyof
|
|
100
|
+
offPipe<K extends keyof BusEvents>(event: K, fn: PipeListener<BusEvents[K]>): void;
|
|
444
101
|
/**
|
|
445
102
|
* Emit a pipeline event — each registered pipe listener receives the
|
|
446
103
|
* output of the previous one. Returns the final transformed payload.
|
|
447
104
|
* If no listeners are registered, returns the original payload unchanged.
|
|
448
105
|
*/
|
|
449
|
-
emitPipe<K extends keyof
|
|
106
|
+
emitPipe<K extends keyof BusEvents>(event: K, payload: BusEvents[K]): BusEvents[K];
|
|
450
107
|
/** Remove an async transform listener from a pipeline event. */
|
|
451
|
-
offPipeAsync<K extends keyof
|
|
108
|
+
offPipeAsync<K extends keyof BusEvents>(event: K, fn: AsyncPipeListener<BusEvents[K]>): void;
|
|
452
109
|
/** Register an async transform listener for a pipeline event. */
|
|
453
|
-
onPipeAsync<K extends keyof
|
|
110
|
+
onPipeAsync<K extends keyof BusEvents>(event: K, fn: AsyncPipeListener<BusEvents[K]>): void;
|
|
454
111
|
/**
|
|
455
112
|
* Emit an async pipeline event. Two phases:
|
|
456
113
|
* 1. Notify — fire regular `on` listeners synchronously (e.g., TUI flushes state)
|
|
@@ -460,6 +117,6 @@ export declare class EventBus {
|
|
|
460
117
|
* Returns the final transformed payload. If no pipe listeners are registered,
|
|
461
118
|
* returns the original payload unchanged (with safe defaults).
|
|
462
119
|
*/
|
|
463
|
-
emitPipeAsync<K extends keyof
|
|
120
|
+
emitPipeAsync<K extends keyof BusEvents>(event: K, payload: BusEvents[K]): Promise<BusEvents[K]>;
|
|
464
121
|
}
|
|
465
122
|
export {};
|