indusagi-coding-agent 0.2.5 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/README.md +9 -5
- package/dist/entry.js +14267 -24282
- package/dist/guardrails.js +924 -7867
- package/dist/index.js +13706 -23775
- package/package.json +3 -2
- package/src/_decls/entry.ts +18 -0
- package/src/_decls/guardrails.ts +35 -0
- package/src/_decls/index.ts +26 -0
- package/src/addons/contract.ts +236 -0
- package/src/addons/dispatch/event-dispatcher.ts +164 -0
- package/src/addons/dispatch/index.ts +25 -0
- package/src/addons/dispatch/tool-interceptor.ts +208 -0
- package/src/addons/host.ts +225 -0
- package/src/addons/index.ts +112 -0
- package/src/addons/manifest.ts +158 -0
- package/src/addons/sandbox.ts +170 -0
- package/src/addons/surface.ts +78 -0
- package/src/boot/auth-vault.ts +195 -0
- package/src/boot/boot.ts +138 -0
- package/src/boot/contract.ts +238 -0
- package/src/boot/heap.ts +59 -0
- package/src/boot/index.ts +28 -0
- package/src/boot/invocation.ts +93 -0
- package/src/boot/runners/addon-wiring.ts +153 -0
- package/src/boot/runners/checkpoint.ts +169 -0
- package/src/boot/runners/delegate-runner.ts +294 -0
- package/src/boot/runners/index.ts +13 -0
- package/src/boot/runners/link-runner.ts +45 -0
- package/src/boot/runners/memdir.ts +168 -0
- package/src/boot/runners/oneshot-runner.ts +58 -0
- package/src/boot/runners/read-state.ts +90 -0
- package/src/boot/runners/registry.ts +42 -0
- package/src/boot/runners/repl-runner.ts +143 -0
- package/src/boot/runners/server-mode.ts +121 -0
- package/src/boot/runners/session.ts +641 -0
- package/src/boot/server-token.ts +148 -0
- package/src/boot/stages.ts +167 -0
- package/src/boot/upgrade/apply.ts +94 -0
- package/src/boot/upgrade/index.ts +13 -0
- package/src/boot/upgrade/upgrades.ts +289 -0
- package/src/briefing/compose.ts +150 -0
- package/src/briefing/context-docs.ts +19 -0
- package/src/briefing/contract.ts +717 -0
- package/src/briefing/index.ts +31 -0
- package/src/briefing/macros.ts +97 -0
- package/src/briefing/skills.ts +47 -0
- package/src/capability-deck/bridge-ledger/index.ts +27 -0
- package/src/capability-deck/bridge-ledger/key.ts +67 -0
- package/src/capability-deck/bridge-ledger/ledger.ts +131 -0
- package/src/capability-deck/bridge-ledger/network.ts +117 -0
- package/src/capability-deck/builtin-bridge.ts +312 -0
- package/src/capability-deck/cards/bg-process-card.ts +335 -0
- package/src/capability-deck/cards/index.ts +115 -0
- package/src/capability-deck/cards/memory-card.ts +146 -0
- package/src/capability-deck/cards/plan-file.ts +97 -0
- package/src/capability-deck/cards/plan-tools.ts +185 -0
- package/src/capability-deck/cards/saas-card.ts +183 -0
- package/src/capability-deck/cards/task-card.ts +207 -0
- package/src/capability-deck/cards/todo-card.ts +168 -0
- package/src/capability-deck/cards/workflow-card.ts +247 -0
- package/src/capability-deck/contract.ts +388 -0
- package/src/capability-deck/index.ts +48 -0
- package/src/capability-deck/manifest.ts +109 -0
- package/src/capability-deck/provision.ts +169 -0
- package/src/channels/contract.ts +191 -0
- package/src/channels/framer.ts +50 -0
- package/src/channels/index.ts +101 -0
- package/src/channels/link/dialog.ts +129 -0
- package/src/channels/link/driver.ts +190 -0
- package/src/channels/link/index.ts +34 -0
- package/src/channels/link/server.ts +134 -0
- package/src/channels/oneshot.ts +90 -0
- package/src/channels/ops.ts +65 -0
- package/src/channels/session-ops.ts +81 -0
- package/src/conductor/bash-guard.ts +599 -0
- package/src/conductor/catalog/catalog.ts +116 -0
- package/src/conductor/catalog/index.ts +8 -0
- package/src/conductor/catalog/matcher.ts +134 -0
- package/src/conductor/conductor.ts +234 -0
- package/src/conductor/contract.ts +842 -0
- package/src/conductor/diagnostics.ts +227 -0
- package/src/conductor/index.ts +33 -0
- package/src/conductor/permissions.ts +588 -0
- package/src/conductor/quota-error.ts +49 -0
- package/src/conductor/signal-hub/hub.ts +46 -0
- package/src/conductor/signal-hub/index.ts +2 -0
- package/src/conductor/signal-hub/translate.test.ts +81 -0
- package/src/conductor/signal-hub/translate.ts +74 -0
- package/src/conductor/skill-parse/index.ts +2 -0
- package/src/conductor/skill-parse/parse.ts +108 -0
- package/src/conductor/transcript-store/index.ts +22 -0
- package/src/conductor/transcript-store/serialize.ts +116 -0
- package/src/conductor/transcript-store/store.ts +205 -0
- package/src/console/auth-status.ts +56 -0
- package/src/console/components/AgentsView.ts +165 -0
- package/src/console/components/BackgroundAgents.ts +155 -0
- package/src/console/components/Banner.ts +334 -0
- package/src/console/components/Composer.ts +94 -0
- package/src/console/components/StatusBar.ts +49 -0
- package/src/console/components/TerminalConsole.ts +1090 -0
- package/src/console/components/WorkingIndicator.ts +98 -0
- package/src/console/components/banner-sweep.ts +24 -0
- package/src/console/components/welcome.ts +74 -0
- package/src/console/contract.ts +630 -0
- package/src/console/index.ts +34 -0
- package/src/console/input/complete.ts +127 -0
- package/src/console/input/dir-reader.ts +34 -0
- package/src/console/input/index.ts +23 -0
- package/src/console/input/keymap.ts +159 -0
- package/src/console/input/paste.ts +104 -0
- package/src/console/mount.ts +56 -0
- package/src/console/overlays/approval-queue.ts +57 -0
- package/src/console/overlays/approval.ts +130 -0
- package/src/console/overlays/auth.ts +342 -0
- package/src/console/overlays/boards.ts +308 -0
- package/src/console/overlays/host.ts +36 -0
- package/src/console/overlays/index.ts +26 -0
- package/src/console/overlays/pickers.ts +258 -0
- package/src/console/overlays/sessions.ts +190 -0
- package/src/console/reducer.ts +182 -0
- package/src/console/slash/builtins.ts +81 -0
- package/src/console/slash/commands/dynamic.ts +83 -0
- package/src/console/slash/commands/integrations.ts +695 -0
- package/src/console/slash/commands/shared.ts +75 -0
- package/src/console/slash/commands/transcript.ts +263 -0
- package/src/console/slash/commands/workbench.ts +246 -0
- package/src/console/slash/index.ts +15 -0
- package/src/console/slash/registry.ts +70 -0
- package/src/console/slash/resolve.ts +63 -0
- package/src/console/startup.ts +209 -0
- package/src/console/theme/adapter.ts +45 -0
- package/src/console/theme/index.ts +7 -0
- package/src/console/theme/palette.ts +68 -0
- package/src/console/theme/resolve.ts +39 -0
- package/src/console/theme/tokens.ts +71 -0
- package/src/entry.ts +55 -0
- package/src/guardrails.ts +37 -0
- package/src/index.ts +18 -0
- package/src/insight/channel.ts +88 -0
- package/src/insight/contract.ts +185 -0
- package/src/insight/index.ts +110 -0
- package/src/insight/recorder.ts +213 -0
- package/src/insight/redaction.ts +157 -0
- package/src/insight/replay.ts +158 -0
- package/src/insight/sampling.ts +70 -0
- package/src/insight/serialize.ts +50 -0
- package/src/insight/sinks/console.ts +64 -0
- package/src/insight/sinks/file.ts +40 -0
- package/src/insight/sinks/index.ts +24 -0
- package/src/insight/sinks/stream.ts +54 -0
- package/src/integrations/sarvam/attach.ts +239 -0
- package/src/integrations/sarvam/config.ts +156 -0
- package/src/integrations/sarvam/index.ts +25 -0
- package/src/integrations/sarvam/sarvam.test.ts +60 -0
- package/src/integrations/sarvam/types.ts +27 -0
- package/src/integrations/zoho/attach.ts +342 -0
- package/src/integrations/zoho/config.ts +125 -0
- package/src/integrations/zoho/index.ts +27 -0
- package/src/integrations/zoho/types.ts +21 -0
- package/src/integrations/zoho/zoho.test.ts +50 -0
- package/src/kit/clipboard-image.ts +107 -0
- package/src/kit/external-editor.ts +48 -0
- package/src/kit/image.ts +59 -0
- package/src/kit/index.ts +51 -0
- package/src/kit/shell.ts +19 -0
- package/src/kit/tool-fetch.ts +85 -0
- package/src/launch/catalog.ts +148 -0
- package/src/launch/contract.ts +187 -0
- package/src/launch/credentials.ts +625 -0
- package/src/launch/index.ts +98 -0
- package/src/launch/invocation/attachments.ts +179 -0
- package/src/launch/invocation/flags.ts +196 -0
- package/src/launch/invocation/index.ts +25 -0
- package/src/launch/invocation/read.ts +260 -0
- package/src/launch/invocation/usage.ts +67 -0
- package/src/launch/login.ts +324 -0
- package/src/launch/oauth.test.ts +18 -0
- package/src/launch/oauth.ts +203 -0
- package/src/launch/packages.ts +194 -0
- package/src/launch/pickers.ts +189 -0
- package/src/runtime-bridge/bridges/_drive.ts +96 -0
- package/src/runtime-bridge/bridges/builtins.ts +68 -0
- package/src/runtime-bridge/bridges/claude-cli.ts +123 -0
- package/src/runtime-bridge/bridges/codex-cli.ts +142 -0
- package/src/runtime-bridge/bridges/index.ts +33 -0
- package/src/runtime-bridge/bridges/indusagi-cli.ts +155 -0
- package/src/runtime-bridge/broker.ts +227 -0
- package/src/runtime-bridge/contract.ts +122 -0
- package/src/runtime-bridge/index.ts +79 -0
- package/src/runtime-bridge/sink.ts +180 -0
- package/src/sessions/contract.ts +81 -0
- package/src/sessions/index.ts +13 -0
- package/src/sessions/library.ts +229 -0
- package/src/settings/contract.ts +114 -0
- package/src/settings/index.ts +32 -0
- package/src/settings/manager.ts +117 -0
- package/src/transcript-export/index.ts +45 -0
- package/src/transcript-export/publish.ts +260 -0
- package/src/transcript-export/sgr.ts +315 -0
- package/src/transcript-export/template.ts +272 -0
- package/src/transcript-export/theme-bridge.ts +150 -0
- package/src/window-budget/budget/estimate.ts +135 -0
- package/src/window-budget/budget/gate.ts +33 -0
- package/src/window-budget/budget/index.ts +16 -0
- package/src/window-budget/budget/slice.ts +56 -0
- package/src/window-budget/condenser.ts +58 -0
- package/src/window-budget/contract.ts +184 -0
- package/src/window-budget/index.ts +19 -0
- package/src/window-budget/microcompact.ts +95 -0
- package/src/window-budget/rehydrate.ts +136 -0
- package/src/window-budget/summarize/condense.ts +103 -0
- package/src/window-budget/summarize/index.ts +14 -0
- package/src/window-budget/summarize/prompt.ts +149 -0
- package/src/workflow-engine/agent-runner.ts +181 -0
- package/src/workflow-engine/display.ts +224 -0
- package/src/workflow-engine/engine.ts +294 -0
- package/src/workflow-engine/index.ts +23 -0
- package/src/workflow-engine/parse.ts +172 -0
- package/src/workflow-engine/structured-output.ts +35 -0
- package/src/workspace/brand.ts +29 -0
- package/src/workspace/index.ts +18 -0
- package/src/workspace/locator.ts +103 -0
- package/src/workspace/runtime-detect.ts +64 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in external-runtime catalog — the shipped {@link ExternalRuntimeSpec}
|
|
3
|
+
* entries and the helper that *annotates* a model with one.
|
|
4
|
+
*/
|
|
5
|
+
import type { Api, Model } from "indusagi/ai";
|
|
6
|
+
import type { CatalogCard } from "../../conductor/catalog/index.js";
|
|
7
|
+
import {
|
|
8
|
+
RUNTIME_ENDPOINT_SCHEME,
|
|
9
|
+
type ExternalRuntimeSpec,
|
|
10
|
+
type RuntimeAdapterId,
|
|
11
|
+
} from "../contract.js";
|
|
12
|
+
|
|
13
|
+
export const BUILTIN_RUNTIME_SPECS: Readonly<Record<RuntimeAdapterId, ExternalRuntimeSpec>> = {
|
|
14
|
+
"claude-cli": {
|
|
15
|
+
adapter: "claude-cli",
|
|
16
|
+
authMode: "external-cli",
|
|
17
|
+
binaryPath: "claude",
|
|
18
|
+
args: ["--output-format", "stream-json", "--verbose"],
|
|
19
|
+
},
|
|
20
|
+
"codex-cli": {
|
|
21
|
+
adapter: "codex-cli",
|
|
22
|
+
authMode: "external-cli",
|
|
23
|
+
binaryPath: "codex",
|
|
24
|
+
args: ["--json"],
|
|
25
|
+
},
|
|
26
|
+
"indusagi-cli": {
|
|
27
|
+
adapter: "indusagi-cli",
|
|
28
|
+
authMode: "external-cli",
|
|
29
|
+
binaryPath: "indusagi",
|
|
30
|
+
args: ["--rpc"],
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const BUILTIN_ADAPTERS: readonly RuntimeAdapterId[] = [
|
|
35
|
+
"claude-cli",
|
|
36
|
+
"codex-cli",
|
|
37
|
+
"indusagi-cli",
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
export function builtinRuntimeSpec(adapter: RuntimeAdapterId): ExternalRuntimeSpec | undefined {
|
|
41
|
+
return BUILTIN_RUNTIME_SPECS[adapter];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface RuntimeAnnotatedModel {
|
|
45
|
+
readonly model: Model<Api>;
|
|
46
|
+
readonly spec: ExternalRuntimeSpec;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function withRuntimeEndpoint(model: Model<Api>, spec: ExternalRuntimeSpec): Model<Api> {
|
|
50
|
+
return { ...model, baseUrl: `${RUNTIME_ENDPOINT_SCHEME}${spec.adapter}` };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function annotateCard(
|
|
54
|
+
card: CatalogCard,
|
|
55
|
+
adapter: RuntimeAdapterId,
|
|
56
|
+
spec?: ExternalRuntimeSpec,
|
|
57
|
+
): RuntimeAnnotatedModel | undefined {
|
|
58
|
+
const resolved = spec ?? builtinRuntimeSpec(adapter);
|
|
59
|
+
if (!resolved) return undefined;
|
|
60
|
+
return { model: withRuntimeEndpoint(card.model, resolved), spec: resolved };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function specFromModel(model: Model<Api>): ExternalRuntimeSpec | undefined {
|
|
64
|
+
const baseUrl = model.baseUrl;
|
|
65
|
+
if (!baseUrl.startsWith(RUNTIME_ENDPOINT_SCHEME)) return undefined;
|
|
66
|
+
const adapter = baseUrl.slice(RUNTIME_ENDPOINT_SCHEME.length);
|
|
67
|
+
return adapter.length > 0 ? builtinRuntimeSpec(adapter) : undefined;
|
|
68
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `claude-cli` bridge — drives an Anthropic-flavoured CLI that emits
|
|
3
|
+
* line-delimited stream-json content blocks.
|
|
4
|
+
*/
|
|
5
|
+
import type {
|
|
6
|
+
Context,
|
|
7
|
+
ExchangeOptions,
|
|
8
|
+
ExternalRuntimeSpec,
|
|
9
|
+
RuntimeAdapterId,
|
|
10
|
+
RuntimeBridge,
|
|
11
|
+
ToolCall,
|
|
12
|
+
} from "../contract.js";
|
|
13
|
+
import {
|
|
14
|
+
asRecord,
|
|
15
|
+
driveExchange,
|
|
16
|
+
strField,
|
|
17
|
+
type ChildParser,
|
|
18
|
+
} from "./_drive.js";
|
|
19
|
+
|
|
20
|
+
const ADAPTER: RuntimeAdapterId = "claude-cli";
|
|
21
|
+
const CONTINUE = { status: "continue" } as const;
|
|
22
|
+
const DONE = { status: "done" } as const;
|
|
23
|
+
|
|
24
|
+
function mapStopReason(raw: string | undefined): "stop" | "length" | "toolUse" {
|
|
25
|
+
switch (raw) {
|
|
26
|
+
case "max_tokens":
|
|
27
|
+
return "length";
|
|
28
|
+
case "tool_use":
|
|
29
|
+
return "toolUse";
|
|
30
|
+
default:
|
|
31
|
+
return "stop";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function toolCallFromBlock(block: Record<string, unknown>): ToolCall | undefined {
|
|
36
|
+
const id = strField(block, "id");
|
|
37
|
+
const name = strField(block, "name");
|
|
38
|
+
if (id === undefined || name === undefined) return undefined;
|
|
39
|
+
const input = asRecord(block["input"]) ?? {};
|
|
40
|
+
return { type: "toolCall", id, name, arguments: input };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function makeParser(): ChildParser {
|
|
44
|
+
let stopReason: "stop" | "length" | "toolUse" = "stop";
|
|
45
|
+
return (message, sink) => {
|
|
46
|
+
const payload = asRecord(message.payload);
|
|
47
|
+
if (!payload) return CONTINUE;
|
|
48
|
+
const type = strField(payload, "type");
|
|
49
|
+
switch (type) {
|
|
50
|
+
case "system": {
|
|
51
|
+
if (strField(payload, "subtype") === "init") {
|
|
52
|
+
const sessionId = strField(payload, "session_id");
|
|
53
|
+
if (sessionId !== undefined) {
|
|
54
|
+
sink.emit({ kind: "resume", resumeToken: sessionId });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return CONTINUE;
|
|
58
|
+
}
|
|
59
|
+
case "content_block_start": {
|
|
60
|
+
const block = asRecord(payload["content_block"]);
|
|
61
|
+
if (block && strField(block, "type") === "tool_use") {
|
|
62
|
+
const call = toolCallFromBlock(block);
|
|
63
|
+
if (call) sink.toolCall(call);
|
|
64
|
+
}
|
|
65
|
+
return CONTINUE;
|
|
66
|
+
}
|
|
67
|
+
case "content_block_delta": {
|
|
68
|
+
const delta = asRecord(payload["delta"]);
|
|
69
|
+
if (!delta) return CONTINUE;
|
|
70
|
+
const deltaType = strField(delta, "type");
|
|
71
|
+
if (deltaType === "text_delta") {
|
|
72
|
+
const text = strField(delta, "text");
|
|
73
|
+
if (text !== undefined) sink.text(text);
|
|
74
|
+
} else if (deltaType === "thinking_delta") {
|
|
75
|
+
const thinking = strField(delta, "thinking");
|
|
76
|
+
if (thinking !== undefined) sink.thinking(thinking);
|
|
77
|
+
}
|
|
78
|
+
return CONTINUE;
|
|
79
|
+
}
|
|
80
|
+
case "message_delta": {
|
|
81
|
+
const delta = asRecord(payload["delta"]);
|
|
82
|
+
stopReason = mapStopReason(delta ? strField(delta, "stop_reason") : undefined);
|
|
83
|
+
return CONTINUE;
|
|
84
|
+
}
|
|
85
|
+
case "error": {
|
|
86
|
+
const error = asRecord(payload["error"]);
|
|
87
|
+
const detail =
|
|
88
|
+
(error && strField(error, "message")) ?? "claude-cli error";
|
|
89
|
+
sink.finishError({ message: detail, cause: payload["error"] });
|
|
90
|
+
return DONE;
|
|
91
|
+
}
|
|
92
|
+
case "message_stop":
|
|
93
|
+
case "result": {
|
|
94
|
+
sink.finishSuccess(stopReason);
|
|
95
|
+
return DONE;
|
|
96
|
+
}
|
|
97
|
+
default:
|
|
98
|
+
return CONTINUE;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function openingRequest(context: Context, opts: ExchangeOptions): { body: unknown } {
|
|
104
|
+
return {
|
|
105
|
+
body: {
|
|
106
|
+
type: "user",
|
|
107
|
+
context,
|
|
108
|
+
resume: opts.resume,
|
|
109
|
+
cwd: opts.cwd,
|
|
110
|
+
sessionId: opts.sessionId,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const claudeCliBridge: RuntimeBridge = {
|
|
116
|
+
adapter: ADAPTER,
|
|
117
|
+
runExchange(model, context, opts, transport) {
|
|
118
|
+
return driveExchange(model, opts, transport, openingRequest(context, opts), makeParser());
|
|
119
|
+
},
|
|
120
|
+
requiresCredential(spec: ExternalRuntimeSpec): boolean {
|
|
121
|
+
return spec.authMode === "api-key";
|
|
122
|
+
},
|
|
123
|
+
};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codex-cli` bridge — drives an OpenAI-flavoured CLI emitting `--json`
|
|
3
|
+
* turn/item events.
|
|
4
|
+
*/
|
|
5
|
+
import type {
|
|
6
|
+
Context,
|
|
7
|
+
ExchangeOptions,
|
|
8
|
+
ExternalRuntimeSpec,
|
|
9
|
+
RuntimeAdapterId,
|
|
10
|
+
RuntimeBridge,
|
|
11
|
+
ToolCall,
|
|
12
|
+
} from "../contract.js";
|
|
13
|
+
import {
|
|
14
|
+
asRecord,
|
|
15
|
+
driveExchange,
|
|
16
|
+
strField,
|
|
17
|
+
type ChildParser,
|
|
18
|
+
} from "./_drive.js";
|
|
19
|
+
|
|
20
|
+
const ADAPTER: RuntimeAdapterId = "codex-cli";
|
|
21
|
+
const CONTINUE = { status: "continue" } as const;
|
|
22
|
+
const DONE = { status: "done" } as const;
|
|
23
|
+
|
|
24
|
+
function parseArguments(value: unknown): Record<string, unknown> {
|
|
25
|
+
if (typeof value === "string") {
|
|
26
|
+
if (value.length === 0) return {};
|
|
27
|
+
try {
|
|
28
|
+
const parsed = JSON.parse(value);
|
|
29
|
+
return asRecord(parsed) ?? {};
|
|
30
|
+
} catch {
|
|
31
|
+
return {};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return asRecord(value) ?? {};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function toolCallFromItem(item: Record<string, unknown>): ToolCall | undefined {
|
|
38
|
+
const name = strField(item, "name");
|
|
39
|
+
if (name === undefined) return undefined;
|
|
40
|
+
const id = strField(item, "call_id") ?? strField(item, "id") ?? name;
|
|
41
|
+
return {
|
|
42
|
+
type: "toolCall",
|
|
43
|
+
id,
|
|
44
|
+
name,
|
|
45
|
+
arguments: parseArguments(item["arguments"]),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function isToolItem(item: Record<string, unknown>): boolean {
|
|
50
|
+
const itemType = strField(item, "type");
|
|
51
|
+
return itemType === "function_call" || itemType === "tool_call";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function makeParser(): ChildParser {
|
|
55
|
+
let sawToolCall = false;
|
|
56
|
+
const handleCompletedItem = (item: Record<string, unknown>, sink: {
|
|
57
|
+
toolCall: (call: ToolCall) => void;
|
|
58
|
+
text: (delta: string) => void;
|
|
59
|
+
}): void => {
|
|
60
|
+
if (isToolItem(item)) {
|
|
61
|
+
const call = toolCallFromItem(item);
|
|
62
|
+
if (call) {
|
|
63
|
+
sink.toolCall(call);
|
|
64
|
+
sawToolCall = true;
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const text = strField(item, "text");
|
|
69
|
+
if (text !== undefined && text.length > 0) sink.text(text);
|
|
70
|
+
};
|
|
71
|
+
return (message, sink) => {
|
|
72
|
+
const payload = asRecord(message.payload);
|
|
73
|
+
if (!payload) return CONTINUE;
|
|
74
|
+
const type = strField(payload, "type");
|
|
75
|
+
switch (type) {
|
|
76
|
+
case "thread.started": {
|
|
77
|
+
const threadId = strField(payload, "thread_id");
|
|
78
|
+
if (threadId !== undefined) {
|
|
79
|
+
sink.emit({ kind: "resume", resumeToken: threadId });
|
|
80
|
+
}
|
|
81
|
+
return CONTINUE;
|
|
82
|
+
}
|
|
83
|
+
case "response.output_text.delta": {
|
|
84
|
+
const delta = strField(payload, "delta");
|
|
85
|
+
if (delta !== undefined) sink.text(delta);
|
|
86
|
+
return CONTINUE;
|
|
87
|
+
}
|
|
88
|
+
case "response.reasoning_text.delta":
|
|
89
|
+
case "response.reasoning.delta": {
|
|
90
|
+
const delta = strField(payload, "delta");
|
|
91
|
+
if (delta !== undefined) sink.thinking(delta);
|
|
92
|
+
return CONTINUE;
|
|
93
|
+
}
|
|
94
|
+
case "response.output_item.done":
|
|
95
|
+
case "item.completed": {
|
|
96
|
+
const item = asRecord(payload["item"]);
|
|
97
|
+
if (item) handleCompletedItem(item, sink);
|
|
98
|
+
return CONTINUE;
|
|
99
|
+
}
|
|
100
|
+
case "error":
|
|
101
|
+
case "turn.failed": {
|
|
102
|
+
const error = asRecord(payload["error"]);
|
|
103
|
+
const detail =
|
|
104
|
+
(error && strField(error, "message")) ??
|
|
105
|
+
strField(payload, "message") ??
|
|
106
|
+
"codex-cli error";
|
|
107
|
+
sink.finishError({ message: detail, cause: payload["error"] ?? payload });
|
|
108
|
+
return DONE;
|
|
109
|
+
}
|
|
110
|
+
case "turn.completed":
|
|
111
|
+
case "response.completed": {
|
|
112
|
+
const reason = sawToolCall ? "toolUse" : "stop";
|
|
113
|
+
sink.finishSuccess(reason);
|
|
114
|
+
return DONE;
|
|
115
|
+
}
|
|
116
|
+
default:
|
|
117
|
+
return CONTINUE;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function openingRequest(context: Context, opts: ExchangeOptions): { body: unknown } {
|
|
123
|
+
return {
|
|
124
|
+
body: {
|
|
125
|
+
type: "turn",
|
|
126
|
+
context,
|
|
127
|
+
thread: opts.resume,
|
|
128
|
+
cwd: opts.cwd,
|
|
129
|
+
sessionId: opts.sessionId,
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export const codexCliBridge: RuntimeBridge = {
|
|
135
|
+
adapter: ADAPTER,
|
|
136
|
+
runExchange(model, context, opts, transport) {
|
|
137
|
+
return driveExchange(model, opts, transport, openingRequest(context, opts), makeParser());
|
|
138
|
+
},
|
|
139
|
+
requiresCredential(spec: ExternalRuntimeSpec): boolean {
|
|
140
|
+
return spec.authMode === "api-key";
|
|
141
|
+
},
|
|
142
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
// Type declarations recovered from dist/types (no runtime body)
|
|
3
|
+
/**
|
|
4
|
+
* Bridges subsystem — public barrel.
|
|
5
|
+
*
|
|
6
|
+
* Bundles the three shipped external-runtime {@link RuntimeBridge}s — the
|
|
7
|
+
* Anthropic-flavoured `claude-cli`, the OpenAI-flavoured `codex-cli`, and the
|
|
8
|
+
* peer JSON-RPC `indusagi-cli` — plus the built-in runtime spec catalog and the
|
|
9
|
+
* model-annotation helpers. Consumers register the bridges with a
|
|
10
|
+
* {@link RuntimeBroker} and annotate catalog cards via this barrel rather than
|
|
11
|
+
* reaching into the individual modules.
|
|
12
|
+
*/
|
|
13
|
+
export { claudeCliBridge } from "./claude-cli.js";
|
|
14
|
+
export { codexCliBridge } from "./codex-cli.js";
|
|
15
|
+
export { indusagiCliBridge, makeIndusagiCliBridge } from "./indusagi-cli.js";
|
|
16
|
+
export {
|
|
17
|
+
BUILTIN_RUNTIME_SPECS,
|
|
18
|
+
BUILTIN_ADAPTERS,
|
|
19
|
+
builtinRuntimeSpec,
|
|
20
|
+
annotateCard,
|
|
21
|
+
withRuntimeEndpoint,
|
|
22
|
+
specFromModel,
|
|
23
|
+
type RuntimeAnnotatedModel,
|
|
24
|
+
} from "./builtins.js";
|
|
25
|
+
export {
|
|
26
|
+
driveExchange,
|
|
27
|
+
seedFromModel,
|
|
28
|
+
asRecord,
|
|
29
|
+
strField,
|
|
30
|
+
errorText,
|
|
31
|
+
type ChildParser,
|
|
32
|
+
type ParseStep,
|
|
33
|
+
} from "./_drive.js";
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `indusagi-cli` bridge — drives a peer agent over JSON-RPC.
|
|
3
|
+
*/
|
|
4
|
+
import type {
|
|
5
|
+
Context,
|
|
6
|
+
ExchangeOptions,
|
|
7
|
+
ExternalRuntimeSpec,
|
|
8
|
+
RuntimeAdapterId,
|
|
9
|
+
RuntimeBridge,
|
|
10
|
+
ToolCall,
|
|
11
|
+
} from "../contract.js";
|
|
12
|
+
import {
|
|
13
|
+
asRecord,
|
|
14
|
+
driveExchange,
|
|
15
|
+
strField,
|
|
16
|
+
type ChildParser,
|
|
17
|
+
} from "./_drive.js";
|
|
18
|
+
|
|
19
|
+
const ADAPTER: RuntimeAdapterId = "indusagi-cli";
|
|
20
|
+
const RPC_METHOD = "runExchange";
|
|
21
|
+
const CONTINUE = { status: "continue" } as const;
|
|
22
|
+
const DONE = { status: "done" } as const;
|
|
23
|
+
|
|
24
|
+
function asFinishReason(raw: string | undefined): "stop" | "length" | "toolUse" {
|
|
25
|
+
const allowed = ["stop", "length", "toolUse"];
|
|
26
|
+
return (allowed as string[]).includes(raw ?? "") ? (raw as "stop" | "length" | "toolUse") : "stop";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function toolCallFromParams(params: Record<string, unknown> | undefined): ToolCall | undefined {
|
|
30
|
+
const id = params && strField(params, "id");
|
|
31
|
+
const name = params && strField(params, "name");
|
|
32
|
+
if (id === undefined || name === undefined) return undefined;
|
|
33
|
+
return {
|
|
34
|
+
type: "toolCall",
|
|
35
|
+
id,
|
|
36
|
+
name,
|
|
37
|
+
arguments: (params && asRecord(params["arguments"])) ?? {},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface NotificationSink {
|
|
42
|
+
text: (delta: string) => void;
|
|
43
|
+
thinking: (delta: string) => void;
|
|
44
|
+
toolCall: (call: ToolCall) => void;
|
|
45
|
+
emit: (event: { kind: "resume"; resumeToken: string }) => void;
|
|
46
|
+
finishSuccess: (reason: "stop" | "length" | "toolUse") => void;
|
|
47
|
+
finishError: (error: { message: string; aborted: boolean; cause?: unknown }) => void;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function handleNotification(
|
|
51
|
+
method: string,
|
|
52
|
+
params: Record<string, unknown> | undefined,
|
|
53
|
+
sink: NotificationSink,
|
|
54
|
+
): { status: "continue" | "done" } {
|
|
55
|
+
switch (method) {
|
|
56
|
+
case "stream/text": {
|
|
57
|
+
const delta = params && strField(params, "delta");
|
|
58
|
+
if (delta !== undefined) sink.text(delta);
|
|
59
|
+
return CONTINUE;
|
|
60
|
+
}
|
|
61
|
+
case "stream/thinking": {
|
|
62
|
+
const delta = params && strField(params, "delta");
|
|
63
|
+
if (delta !== undefined) sink.thinking(delta);
|
|
64
|
+
return CONTINUE;
|
|
65
|
+
}
|
|
66
|
+
case "stream/toolCall": {
|
|
67
|
+
const call = toolCallFromParams(params);
|
|
68
|
+
if (call) sink.toolCall(call);
|
|
69
|
+
return CONTINUE;
|
|
70
|
+
}
|
|
71
|
+
case "session/resume": {
|
|
72
|
+
const token = params && strField(params, "resumeToken");
|
|
73
|
+
if (token !== undefined) sink.emit({ kind: "resume", resumeToken: token });
|
|
74
|
+
return CONTINUE;
|
|
75
|
+
}
|
|
76
|
+
case "stream/done": {
|
|
77
|
+
sink.finishSuccess(asFinishReason(params ? strField(params, "reason") : undefined));
|
|
78
|
+
return DONE;
|
|
79
|
+
}
|
|
80
|
+
case "stream/error": {
|
|
81
|
+
const message = (params && strField(params, "message")) ?? "indusagi-cli error";
|
|
82
|
+
const aborted = params?.["aborted"] === true;
|
|
83
|
+
sink.finishError({ message, aborted, cause: params });
|
|
84
|
+
return DONE;
|
|
85
|
+
}
|
|
86
|
+
default:
|
|
87
|
+
return CONTINUE;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function parseFrame(message: { payload: unknown }, sink: {
|
|
92
|
+
text: (delta: string) => void;
|
|
93
|
+
thinking: (delta: string) => void;
|
|
94
|
+
toolCall: (call: ToolCall) => void;
|
|
95
|
+
emit: (event: { kind: "resume"; resumeToken: string }) => void;
|
|
96
|
+
finishSuccess: (reason: "stop" | "length" | "toolUse") => void;
|
|
97
|
+
finishError: (error: { message: string; aborted: boolean; cause?: unknown }) => void;
|
|
98
|
+
}): { status: "continue" | "done" } {
|
|
99
|
+
const frame = asRecord(message.payload);
|
|
100
|
+
if (!frame) return CONTINUE;
|
|
101
|
+
const method = strField(frame, "method");
|
|
102
|
+
if (method !== undefined) {
|
|
103
|
+
return handleNotification(method, asRecord(frame["params"]), sink);
|
|
104
|
+
}
|
|
105
|
+
if ("error" in frame) {
|
|
106
|
+
const error = asRecord(frame["error"]);
|
|
107
|
+
const detail = (error && strField(error, "message")) ?? "indusagi-cli rpc error";
|
|
108
|
+
sink.finishError({ message: detail, cause: frame["error"] });
|
|
109
|
+
return DONE;
|
|
110
|
+
}
|
|
111
|
+
if ("result" in frame) {
|
|
112
|
+
return DONE;
|
|
113
|
+
}
|
|
114
|
+
return CONTINUE;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const parser = parseFrame;
|
|
118
|
+
|
|
119
|
+
function openingRequest(
|
|
120
|
+
context: Context,
|
|
121
|
+
opts: ExchangeOptions,
|
|
122
|
+
spec: ExternalRuntimeSpec,
|
|
123
|
+
): { body: unknown } {
|
|
124
|
+
return {
|
|
125
|
+
body: {
|
|
126
|
+
jsonrpc: "2.0",
|
|
127
|
+
id: opts.sessionId ?? RPC_METHOD,
|
|
128
|
+
method: RPC_METHOD,
|
|
129
|
+
params: {
|
|
130
|
+
context,
|
|
131
|
+
delegate: spec.delegate,
|
|
132
|
+
resume: opts.resume,
|
|
133
|
+
cwd: opts.cwd,
|
|
134
|
+
sessionId: opts.sessionId,
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function makeIndusagiCliBridge(spec: ExternalRuntimeSpec): RuntimeBridge {
|
|
141
|
+
return {
|
|
142
|
+
adapter: ADAPTER,
|
|
143
|
+
runExchange(model, context, opts, transport) {
|
|
144
|
+
return driveExchange(model, opts, transport, openingRequest(context, opts, spec), parser);
|
|
145
|
+
},
|
|
146
|
+
requiresCredential(s: ExternalRuntimeSpec): boolean {
|
|
147
|
+
return s.authMode === "api-key";
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export const indusagiCliBridge: RuntimeBridge = makeIndusagiCliBridge({
|
|
153
|
+
adapter: ADAPTER,
|
|
154
|
+
authMode: "external-cli",
|
|
155
|
+
});
|