condukt 0.25.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/runtimes/claude/bridge-cache.d.ts +58 -0
  2. package/dist/runtimes/claude/bridge-cache.d.ts.map +1 -0
  3. package/dist/runtimes/claude/bridge-cache.js +257 -0
  4. package/dist/runtimes/claude/bridge-cache.js.map +1 -0
  5. package/dist/runtimes/claude/claude-runtime.d.ts +30 -0
  6. package/dist/runtimes/claude/claude-runtime.d.ts.map +1 -0
  7. package/dist/runtimes/claude/claude-runtime.js +88 -0
  8. package/dist/runtimes/claude/claude-runtime.js.map +1 -0
  9. package/dist/runtimes/claude/claude-session.d.ts +154 -0
  10. package/dist/runtimes/claude/claude-session.d.ts.map +1 -0
  11. package/dist/runtimes/claude/claude-session.js +851 -0
  12. package/dist/runtimes/claude/claude-session.js.map +1 -0
  13. package/dist/runtimes/claude/config-mapper.d.ts +69 -0
  14. package/dist/runtimes/claude/config-mapper.d.ts.map +1 -0
  15. package/dist/runtimes/claude/config-mapper.js +458 -0
  16. package/dist/runtimes/claude/config-mapper.js.map +1 -0
  17. package/dist/runtimes/claude/epoch-store.d.ts +28 -0
  18. package/dist/runtimes/claude/epoch-store.d.ts.map +1 -0
  19. package/dist/runtimes/claude/epoch-store.js +199 -0
  20. package/dist/runtimes/claude/epoch-store.js.map +1 -0
  21. package/dist/runtimes/claude/fallback-runtime.d.ts +14 -0
  22. package/dist/runtimes/claude/fallback-runtime.d.ts.map +1 -0
  23. package/dist/runtimes/claude/fallback-runtime.js +64 -0
  24. package/dist/runtimes/claude/fallback-runtime.js.map +1 -0
  25. package/dist/runtimes/claude/index.d.ts +24 -0
  26. package/dist/runtimes/claude/index.d.ts.map +1 -0
  27. package/dist/runtimes/claude/index.js +61 -0
  28. package/dist/runtimes/claude/index.js.map +1 -0
  29. package/dist/runtimes/claude/message-mapper.d.ts +135 -0
  30. package/dist/runtimes/claude/message-mapper.d.ts.map +1 -0
  31. package/dist/runtimes/claude/message-mapper.js +504 -0
  32. package/dist/runtimes/claude/message-mapper.js.map +1 -0
  33. package/dist/runtimes/claude/one-shot.d.ts +48 -0
  34. package/dist/runtimes/claude/one-shot.d.ts.map +1 -0
  35. package/dist/runtimes/claude/one-shot.js +186 -0
  36. package/dist/runtimes/claude/one-shot.js.map +1 -0
  37. package/dist/runtimes/claude/protocol-bridge.d.ts +138 -0
  38. package/dist/runtimes/claude/protocol-bridge.d.ts.map +1 -0
  39. package/dist/runtimes/claude/protocol-bridge.js +1170 -0
  40. package/dist/runtimes/claude/protocol-bridge.js.map +1 -0
  41. package/dist/runtimes/claude/protocol-router.d.ts +113 -0
  42. package/dist/runtimes/claude/protocol-router.d.ts.map +1 -0
  43. package/dist/runtimes/claude/protocol-router.js +514 -0
  44. package/dist/runtimes/claude/protocol-router.js.map +1 -0
  45. package/dist/runtimes/claude/session-epoch.d.ts +156 -0
  46. package/dist/runtimes/claude/session-epoch.d.ts.map +1 -0
  47. package/dist/runtimes/claude/session-epoch.js +365 -0
  48. package/dist/runtimes/claude/session-epoch.js.map +1 -0
  49. package/dist/runtimes/claude/session-recovery.d.ts +78 -0
  50. package/dist/runtimes/claude/session-recovery.d.ts.map +1 -0
  51. package/dist/runtimes/claude/session-recovery.js +259 -0
  52. package/dist/runtimes/claude/session-recovery.js.map +1 -0
  53. package/dist/runtimes/claude/sse.d.ts +16 -0
  54. package/dist/runtimes/claude/sse.d.ts.map +1 -0
  55. package/dist/runtimes/claude/sse.js +46 -0
  56. package/dist/runtimes/claude/sse.js.map +1 -0
  57. package/dist/runtimes/claude/translate-chat.d.ts +106 -0
  58. package/dist/runtimes/claude/translate-chat.d.ts.map +1 -0
  59. package/dist/runtimes/claude/translate-chat.js +857 -0
  60. package/dist/runtimes/claude/translate-chat.js.map +1 -0
  61. package/dist/runtimes/claude/translate-responses.d.ts +76 -0
  62. package/dist/runtimes/claude/translate-responses.d.ts.map +1 -0
  63. package/dist/runtimes/claude/translate-responses.js +625 -0
  64. package/dist/runtimes/claude/translate-responses.js.map +1 -0
  65. package/dist/runtimes/claude/usage-ledger.d.ts +108 -0
  66. package/dist/runtimes/claude/usage-ledger.d.ts.map +1 -0
  67. package/dist/runtimes/claude/usage-ledger.js +189 -0
  68. package/dist/runtimes/claude/usage-ledger.js.map +1 -0
  69. package/dist/runtimes/copilot/copilot-backend.d.ts +8 -0
  70. package/dist/runtimes/copilot/copilot-backend.d.ts.map +1 -1
  71. package/dist/runtimes/copilot/sdk-backend.d.ts.map +1 -1
  72. package/dist/runtimes/copilot/sdk-backend.js +314 -135
  73. package/dist/runtimes/copilot/sdk-backend.js.map +1 -1
  74. package/dist/runtimes/mcp-env.d.ts +24 -0
  75. package/dist/runtimes/mcp-env.d.ts.map +1 -0
  76. package/dist/runtimes/mcp-env.js +81 -0
  77. package/dist/runtimes/mcp-env.js.map +1 -0
  78. package/dist/runtimes/mock/mock-runtime.d.ts +2 -2
  79. package/dist/runtimes/mock/mock-runtime.d.ts.map +1 -1
  80. package/dist/runtimes/mock/mock-runtime.js +38 -1
  81. package/dist/runtimes/mock/mock-runtime.js.map +1 -1
  82. package/dist/src/agent.d.ts.map +1 -1
  83. package/dist/src/agent.js +171 -3
  84. package/dist/src/agent.js.map +1 -1
  85. package/dist/src/index.d.ts +1 -1
  86. package/dist/src/index.d.ts.map +1 -1
  87. package/dist/src/index.js.map +1 -1
  88. package/dist/src/session-recovery-policy.d.ts +19 -0
  89. package/dist/src/session-recovery-policy.d.ts.map +1 -0
  90. package/dist/src/session-recovery-policy.js +43 -0
  91. package/dist/src/session-recovery-policy.js.map +1 -0
  92. package/dist/src/types.d.ts +118 -1
  93. package/dist/src/types.d.ts.map +1 -1
  94. package/dist/src/types.js +11 -1
  95. package/dist/src/types.js.map +1 -1
  96. package/package.json +20 -4
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.INTERNAL_MCP_TOOL_NAMES = exports.CONDUKT_MCP_SERVER_NAME = void 0;
4
+ exports.runOneShot = runOneShot;
5
+ exports.buildAdvisorStandInServer = buildAdvisorStandInServer;
6
+ const claude_agent_sdk_1 = require("@anthropic-ai/claude-agent-sdk");
7
+ const zod_1 = require("zod");
8
+ const config_mapper_1 = require("./config-mapper");
9
+ /**
10
+ * A single, isolated query: advisor, stand-in voter, or handoff summary.
11
+ *
12
+ * Isolation is deliberate and mirrors the Copilot one-shot session: no
13
+ * built-in tools, no MCP servers, no host settings discovery (`settingSources:
14
+ * []`), and `dontAsk` so nothing can prompt. `env` carries the protocol
15
+ * bridge's `ANTHROPIC_BASE_URL`/credentials; without it the CLI would call
16
+ * `api.anthropic.com` directly.
17
+ */
18
+ async function runOneShot(opts) {
19
+ if (opts.signal?.aborted === true) {
20
+ return { text: '', usages: [], model: opts.model };
21
+ }
22
+ const abortController = new AbortController();
23
+ if (opts.signal !== undefined) {
24
+ opts.signal.addEventListener('abort', () => abortController.abort(), { once: true });
25
+ }
26
+ const config = {
27
+ model: opts.model,
28
+ cwd: opts.cwd,
29
+ addDirs: [],
30
+ timeout: 0,
31
+ heartbeatTimeout: 0,
32
+ ...(opts.system !== undefined ? { systemMessage: opts.system } : {}),
33
+ };
34
+ const mapped = (0, config_mapper_1.mapConfig)(config, {
35
+ oneShot: true,
36
+ ...(opts.env !== undefined ? { env: opts.env } : {}),
37
+ });
38
+ const options = {
39
+ ...mapped.options,
40
+ permissionMode: 'dontAsk',
41
+ allowDangerouslySkipPermissions: false,
42
+ abortController,
43
+ };
44
+ let text = '';
45
+ let usages = [];
46
+ const q = (0, claude_agent_sdk_1.query)({ prompt: opts.prompt, options });
47
+ try {
48
+ for await (const msg of q) {
49
+ if (msg.type === 'assistant') {
50
+ for (const block of msg.message.content) {
51
+ if (block.type === 'text')
52
+ text += block.text;
53
+ }
54
+ }
55
+ else if (msg.type === 'result') {
56
+ // A one-shot session is fresh, so its cumulative snapshot is this
57
+ // call's usage.
58
+ usages = usageRecords(msg.modelUsage, msg.duration_ms);
59
+ if (msg.subtype === 'success' && text.length === 0 && msg.result.length > 0) {
60
+ text = msg.result;
61
+ }
62
+ }
63
+ }
64
+ }
65
+ finally {
66
+ try {
67
+ q.close();
68
+ }
69
+ catch { /* already closed */ }
70
+ }
71
+ return { text, usages, model: opts.model };
72
+ }
73
+ function count(value) {
74
+ return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : 0;
75
+ }
76
+ function usageRecords(modelUsage, durationMs) {
77
+ const records = [];
78
+ for (const [model, usage] of Object.entries(modelUsage ?? {})) {
79
+ const cacheReadTokens = count(usage.cacheReadInputTokens);
80
+ const cacheWriteTokens = count(usage.cacheCreationInputTokens);
81
+ const inputTokens = count(usage.inputTokens) + cacheReadTokens + cacheWriteTokens;
82
+ const outputTokens = count(usage.outputTokens);
83
+ if (inputTokens === 0 && outputTokens === 0)
84
+ continue;
85
+ records.push({
86
+ inputTokens,
87
+ outputTokens,
88
+ totalTokens: inputTokens + outputTokens,
89
+ cacheReadTokens,
90
+ cacheWriteTokens,
91
+ model,
92
+ ...(durationMs !== undefined ? { duration: durationMs } : {}),
93
+ });
94
+ }
95
+ return records;
96
+ }
97
+ const CONSULT_SCHEMA = { question: zod_1.z.string(), transcript: zod_1.z.string().optional() };
98
+ /** Name the session registers the internal advisor/stand-in server under. */
99
+ exports.CONDUKT_MCP_SERVER_NAME = 'condukt';
100
+ /**
101
+ * Qualified names of the internal tools. Under `dontAsk` only tools listed in
102
+ * `allowedTools` may run, and this server is added after `mapConfig`, so the
103
+ * session must add these itself or the model is denied its own advisor.
104
+ */
105
+ exports.INTERNAL_MCP_TOOL_NAMES = [
106
+ `mcp__${exports.CONDUKT_MCP_SERVER_NAME}__advisor`,
107
+ `mcp__${exports.CONDUKT_MCP_SERVER_NAME}__stand_in`,
108
+ ];
109
+ function buildAdvisorStandInServer(opts) {
110
+ const advisorModel = opts.config.advisor?.model;
111
+ const standInCfg = opts.config.standIn;
112
+ const tools = [];
113
+ const env = {
114
+ ...(opts.env !== undefined ? { env: opts.env } : {}),
115
+ ...(opts.signal !== undefined ? { signal: opts.signal } : {}),
116
+ };
117
+ if (advisorModel) {
118
+ tools.push((0, claude_agent_sdk_1.tool)('advisor', opts.config.advisor?.description ?? 'Consult a stronger reviewer model.', CONSULT_SCHEMA, async (args) => {
119
+ const prompt = [
120
+ opts.config.advisor?.system ?? '',
121
+ 'Question: ' + args.question,
122
+ args.transcript ? 'Transcript:\n' + args.transcript : '',
123
+ ].filter(Boolean).join('\n\n');
124
+ const res = await runOneShot({ model: advisorModel, prompt, cwd: opts.cwd, ...env });
125
+ opts.onToolUsage({
126
+ tool: 'advisor',
127
+ model: res.model,
128
+ usages: res.usages,
129
+ sectionSizes: {
130
+ focusChars: (opts.config.advisor?.system ?? '').length,
131
+ contextChars: 0,
132
+ transcriptChars: (args.transcript ?? '').length,
133
+ promptChars: prompt.length,
134
+ },
135
+ });
136
+ return { content: [{ type: 'text', text: res.text }] };
137
+ }));
138
+ }
139
+ if (standInCfg) {
140
+ // StandInConfig shape: `members` (explicit models) and/or `memberCount`.
141
+ // Claude cannot auto-select from the copilot model catalogue, so a bare
142
+ // memberCount (without members) disables stand_in here.
143
+ const hasMembers = Array.isArray(standInCfg.members) && standInCfg.members.length > 0;
144
+ const hasBoth = hasMembers && standInCfg.memberCount !== undefined;
145
+ if (hasBoth) {
146
+ // eslint-disable-next-line no-console
147
+ console.warn('[condukt] standIn: configure members or memberCount, not both; disabling stand_in');
148
+ }
149
+ else if (hasMembers) {
150
+ const models = [...(standInCfg.members ?? [])];
151
+ const memberCount = standInCfg.memberCount ?? models.length;
152
+ if (models.length > 0) {
153
+ tools.push((0, claude_agent_sdk_1.tool)('stand_in', standInCfg.description ?? 'Consult multiple reviewer models for a cross-lab verdict.', CONSULT_SCHEMA, async (args) => {
154
+ const prompt = ['Question: ' + args.question, args.transcript ? 'Transcript:\n' + args.transcript : ''].filter(Boolean).join('\n\n');
155
+ const voters = models.slice(0, memberCount);
156
+ const results = await Promise.all(voters.map((m) => runOneShot({ model: m, prompt, cwd: opts.cwd, ...env })));
157
+ const ballots = results.map((r) => r.text).join('\n---\n');
158
+ opts.onToolUsage({
159
+ tool: 'stand_in',
160
+ model: voters.join(','),
161
+ usages: results.flatMap((r) => r.usages),
162
+ sectionSizes: {
163
+ focusChars: 0,
164
+ contextChars: 0,
165
+ transcriptChars: (args.transcript ?? '').length,
166
+ promptChars: prompt.length,
167
+ },
168
+ });
169
+ return { content: [{ type: 'text', text: ballots }] };
170
+ }));
171
+ }
172
+ }
173
+ }
174
+ if (tools.length === 0)
175
+ return null;
176
+ // `SdkMcpToolDefinition`'s handler parameter is contravariant, so the
177
+ // erased `SdkMcpToolDefinition<any>[]` element type rejects a concretely
178
+ // typed definition even though the runtime shapes are identical. Assert at
179
+ // this one boundary; every handler below is schema-checked by `tool()`.
180
+ return (0, claude_agent_sdk_1.createSdkMcpServer)({
181
+ name: exports.CONDUKT_MCP_SERVER_NAME,
182
+ version: '1.0.0',
183
+ tools: tools,
184
+ });
185
+ }
186
+ //# sourceMappingURL=one-shot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"one-shot.js","sourceRoot":"","sources":["../../../runtimes/claude/one-shot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Self-contained in-process protocol bridge.
3
+ *
4
+ * Exposes an Anthropic-compatible HTTP surface (for Claude SDK via
5
+ * ANTHROPIC_BASE_URL) and translates to any of the three OpenCode Go /
6
+ * Zen upstream protocols, applying cache instrumentation:
7
+ *
8
+ * - anthropic → raw pass-through (cache_control preserved)
9
+ * - openai → chat/completions translation (request + SSE)
10
+ * - responses → OpenAI Responses translation (request + SSE)
11
+ *
12
+ * Routing is model-driven (see protocol-router.ts), session-stickiness
13
+ * uses the `x-opencode-session` header, and prompt-cache keys are stamped
14
+ * on chat/completions with a 400-downgrade fallback. Requests to OpenCode
15
+ * hosts present the OpenCode client identity the Console expects (client
16
+ * User-Agent, `x-opencode-client`, client-shaped session id). Binds 127.0.0.1.
17
+ */
18
+ import { type SessionEpochConstants } from './session-epoch';
19
+ import { type ProtocolId } from './protocol-router';
20
+ export interface BridgeConfig {
21
+ readonly port: number;
22
+ /** Upstream base URL (opencode base, /v1 base, or host base). */
23
+ readonly upstreamBaseUrl: string;
24
+ readonly upstreamApiKey?: string;
25
+ readonly sessionId: string;
26
+ readonly modelAliasMap?: Readonly<Record<string, string>>;
27
+ /** Force a single upstream protocol for every model. */
28
+ readonly protocol?: ProtocolId;
29
+ /** Explicit per-model protocol overrides (win over docs tables). */
30
+ readonly protocolMap?: Readonly<Record<string, ProtocolId>>;
31
+ /** Explicit per-protocol endpoint overrides (win over derivation). */
32
+ readonly endpoints?: Partial<Record<ProtocolId, string>>;
33
+ /** Optional Console (Zen) base URL for gap-fill of Zen-only models. */
34
+ readonly zenBaseUrl?: string;
35
+ /** Explicit per-protocol Zen endpoint overrides (win over derivation). */
36
+ readonly zenEndpoints?: Partial<Record<ProtocolId, string>>;
37
+ readonly bridgeSecret?: string;
38
+ readonly stateFile?: string;
39
+ readonly maxBodyBytes?: number;
40
+ readonly userAgent?: string;
41
+ readonly maxAttempts?: number;
42
+ readonly requestTimeoutMs?: number;
43
+ readonly keepAliveMs?: number;
44
+ readonly idleTimeoutMs?: number;
45
+ /** Kill-switch for prompt-cache stamping (default on). */
46
+ readonly cacheKeyEnabled?: boolean;
47
+ /** Kill-switch for session compaction epochs (-eN / -rM, default on). */
48
+ readonly epochEnabled?: boolean;
49
+ /** Kill-switch for stagnation rotation (-rM, requires epochs, default on). */
50
+ readonly epochRotateEnabled?: boolean;
51
+ /** Epoch sidecar path, or false to disable persistence. */
52
+ readonly epochStateFile?: string | false;
53
+ /** Threshold overrides for the epoch/rotation triggers (tests). */
54
+ readonly epochConstants?: Partial<SessionEpochConstants>;
55
+ }
56
+ export interface BridgeMetrics {
57
+ readonly requestCount: number;
58
+ readonly downgradeCount: number;
59
+ readonly cacheStampedCount: number;
60
+ readonly errorCount: number;
61
+ /** Exact/heuristic compaction bumps observed (eras advanced). */
62
+ readonly epochBumps: number;
63
+ /** Stagnation rotations observed (-rM advances). */
64
+ readonly epochRotations: number;
65
+ /** Prompt-cache read tokens summed over measured turns. */
66
+ readonly cacheReadTokens: number;
67
+ /** Prompt-cache creation tokens summed over measured turns. */
68
+ readonly cacheWriteTokens: number;
69
+ readonly protocolCounts: Readonly<Record<ProtocolId, number>>;
70
+ }
71
+ export interface BridgeHandle {
72
+ readonly port: number;
73
+ readonly baseUrl: string;
74
+ readonly endpoints: Readonly<Record<ProtocolId, string>>;
75
+ readonly zenEndpoints: Readonly<Record<ProtocolId, string>>;
76
+ readonly metrics: BridgeMetrics;
77
+ /**
78
+ * Exact compaction notification (the Claude SDK emits a compact
79
+ * boundary): advances the session era immediately so the first
80
+ * post-compaction request already carries the fresh identity.
81
+ */
82
+ notifyCompaction(): void;
83
+ close(): Promise<void>;
84
+ }
85
+ /**
86
+ * Per-session bridge configuration: everything from BridgeConfig except
87
+ * the port (0 = ephemeral) and session id (fresh per session by default,
88
+ * so prompt-cache keys stay isolated between sessions).
89
+ */
90
+ export interface BridgeRuntimeConfig extends Omit<BridgeConfig, 'port' | 'sessionId'> {
91
+ readonly port?: number;
92
+ /** Force a fixed session id (tests / deliberate cache clustering). */
93
+ readonly sessionId?: string;
94
+ }
95
+ /**
96
+ * Environment for pointing the Claude CLI at the in-process bridge.
97
+ * The reference deployments use a fake key on both variables; the bridge
98
+ * itself authenticates upstream with `upstreamApiKey`.
99
+ */
100
+ export declare function buildBridgeEnv(handle: BridgeHandle, opts?: {
101
+ readonly bridgeSecret?: string;
102
+ readonly apiKey?: string;
103
+ }): Record<string, string>;
104
+ /**
105
+ * OpenCode 2.x client User-Agent shape (`opencode/<channel>/<version>/<name>`,
106
+ * packages/core/src/app.ts). The Console reads it to recognise the client, so
107
+ * bridge requests to OpenCode hosts present it by default; `config.userAgent`
108
+ * still overrides.
109
+ */
110
+ export declare const OPENCODE_CLIENT_USER_AGENT = "opencode/latest/2.0.32/cli";
111
+ /**
112
+ * Abort signal that fires after `ms`, optionally chained to a parent
113
+ * signal. `clear()` releases the timer so long fetches do not leak.
114
+ */
115
+ export declare function timeoutSignal(ms: number, parent?: AbortSignal): {
116
+ signal: AbortSignal;
117
+ clear: () => void;
118
+ };
119
+ /** Anthropic error type names an SDK client may branch on. */
120
+ type AnthropicErrorType = 'invalid_request_error' | 'authentication_error' | 'permission_error' | 'not_found_error' | 'request_too_large' | 'rate_limit_error' | 'api_error' | 'overloaded_error';
121
+ /**
122
+ * The Anthropic client branches on `error.type`, not on the HTTP status.
123
+ * Collapsing every 4xx into `invalid_request_error` makes a 401 look like a
124
+ * malformed request, and a client that would re-authenticate instead keeps
125
+ * resending the same rejected credential.
126
+ */
127
+ export declare function anthropicErrorTypeForStatus(status: number): AnthropicErrorType;
128
+ /**
129
+ * Epoch sidecar resolution: explicit config → `CONDUKT_EPOCH_PATH` →
130
+ * sibling of `stateFile` → default user path. `false` disables
131
+ * persistence. The home default is skipped under test runners
132
+ * (NODE_ENV=test / VITEST) so unit tests never write to a developer's
133
+ * home directory.
134
+ */
135
+ export declare function resolveEpochStateFile(config: BridgeConfig): string | null;
136
+ export declare function createBridge(config: BridgeConfig): Promise<BridgeHandle>;
137
+ export {};
138
+ //# sourceMappingURL=protocol-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol-bridge.d.ts","sourceRoot":"","sources":["../../../runtimes/claude/protocol-bridge.ts"],"names":[],"mappings":"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"}