@getpaseo/server 0.1.99 → 0.1.100
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/dist/server/server/agent/provider-registry.js +1 -0
- package/dist/server/server/agent/providers/acp-agent.d.ts +19 -1
- package/dist/server/server/agent/providers/acp-agent.js +117 -0
- package/dist/server/server/agent/providers/claude/agent.js +36 -52
- package/dist/server/server/agent/providers/copilot-acp-agent.d.ts +2 -1
- package/dist/server/server/agent/providers/copilot-acp-agent.js +10 -0
- package/dist/server/server/agent/providers/opencode/server-manager.d.ts +14 -11
- package/dist/server/server/agent/providers/opencode/server-manager.js +149 -91
- package/dist/server/server/agent/providers/opencode/test-server-manager.d.ts +6 -5
- package/dist/server/server/agent/providers/opencode/test-server-manager.js +13 -3
- package/dist/server/server/agent/providers/opencode/test-utils/{test-opencode-runtime.d.ts → test-opencode-harness.d.ts} +11 -11
- package/dist/server/server/agent/providers/opencode/test-utils/{test-opencode-runtime.js → test-opencode-harness.js} +23 -10
- package/dist/server/server/agent/providers/opencode-agent.d.ts +9 -3
- package/dist/server/server/agent/providers/opencode-agent.js +26 -38
- package/dist/server/server/agent/providers/pi/agent.d.ts +2 -1
- package/dist/server/server/agent/providers/pi/agent.js +5 -3
- package/dist/server/server/agent/providers/pi/cli-runtime.d.ts +3 -0
- package/dist/server/server/agent/providers/pi/cli-runtime.js +6 -3
- package/dist/server/server/agent/providers/pi/rpc-types.d.ts +2 -1
- package/package.json +5 -5
- package/dist/server/server/agent/providers/opencode/runtime.d.ts +0 -28
- package/dist/server/server/agent/providers/opencode/runtime.js +0 -5
|
@@ -51,6 +51,7 @@ const PROVIDER_CLIENT_FACTORIES = {
|
|
|
51
51
|
providerParams: options?.providerParams ?? {
|
|
52
52
|
sessionDir: "~/.omp/agent/sessions",
|
|
53
53
|
},
|
|
54
|
+
commandsRpcType: "get_available_commands",
|
|
54
55
|
}),
|
|
55
56
|
mock: (logger) => new MockLoadTestAgentClient(logger),
|
|
56
57
|
"mock-slow": () => new MockSlowProviderClient(),
|
|
@@ -3,7 +3,7 @@ import type { ProcessTerminator } from "../../../utils/tree-kill.js";
|
|
|
3
3
|
import type { ReadableStream as NodeReadableStream, WritableStream as NodeWritableStream } from "node:stream/web";
|
|
4
4
|
import { ClientSideConnection, type Client as ACPClient, type CreateTerminalRequest, type InitializeResponse, type KillTerminalRequest, type LoadSessionResponse, type NewSessionResponse, type ReadTextFileRequest, type RequestPermissionRequest, type RequestPermissionResponse, type ResumeSessionResponse, type SessionConfigOption, type SessionMode, type SessionModelState, type SessionNotification, type TerminalOutputRequest, type TerminalOutputResponse, type ToolCallContent, type ToolCallLocation, type ToolCallStatus, type ToolKind, type Usage, type WaitForTerminalExitRequest, type WriteTextFileRequest, type Stream as ACPStream } from "@agentclientprotocol/sdk";
|
|
5
5
|
import type { Logger } from "pino";
|
|
6
|
-
import { type AgentCapabilityFlags, type AgentClient, type AgentLaunchContext, type AgentMode, type AgentModelDefinition, type AgentPermissionRequest, type AgentPermissionResponse, type AgentPersistenceHandle, type AgentPromptInput, type AgentRunOptions, type AgentRunResult, type AgentRuntimeInfo, type AgentSession, type AgentSessionConfig, type AgentSlashCommand, type AgentStreamEvent, type AgentUsage, type FetchCatalogOptions, type ImportableProviderSession, type ImportProviderSessionContext, type ImportProviderSessionInput, type ListImportableSessionsOptions, type ProviderCatalog } from "../agent-sdk-types.js";
|
|
6
|
+
import { type AgentCapabilityFlags, type AgentClient, type AgentFeature, type AgentLaunchContext, type AgentMode, type AgentModelDefinition, type AgentPermissionRequest, type AgentPermissionResponse, type AgentPersistenceHandle, type AgentPromptInput, type AgentRunOptions, type AgentRunResult, type AgentRuntimeInfo, type AgentSession, type AgentSessionConfig, type AgentSlashCommand, type AgentStreamEvent, type AgentUsage, type FetchCatalogOptions, type ImportableProviderSession, type ImportProviderSessionContext, type ImportProviderSessionInput, type ListImportableSessionsOptions, type ProviderCatalog } from "../agent-sdk-types.js";
|
|
7
7
|
import { type ProviderRuntimeSettings } from "../provider-launch-config.js";
|
|
8
8
|
export declare function summarizeACPRequestError(error: unknown): {
|
|
9
9
|
message: string;
|
|
@@ -24,6 +24,7 @@ interface ACPAgentClientOptions {
|
|
|
24
24
|
modelTransformer?: (models: AgentModelDefinition[]) => AgentModelDefinition[];
|
|
25
25
|
sessionResponseTransformer?: (response: SessionStateResponse) => SessionStateResponse;
|
|
26
26
|
configOptionsTransformer?: (configOptions: SessionConfigOption[]) => SessionConfigOption[];
|
|
27
|
+
configFeatureOptions?: ACPConfigFeatureOption[];
|
|
27
28
|
modeIdTransformer?: (modeId: string) => string | null;
|
|
28
29
|
toolSnapshotTransformer?: (snapshot: ACPToolSnapshot) => ACPToolSnapshot;
|
|
29
30
|
providerModeWriter?: (context: ACPProviderModeWriterContext) => Promise<ACPProviderModeWriteResult>;
|
|
@@ -43,6 +44,7 @@ interface ACPAgentSessionOptions {
|
|
|
43
44
|
modelTransformer?: (models: AgentModelDefinition[]) => AgentModelDefinition[];
|
|
44
45
|
sessionResponseTransformer?: (response: SessionStateResponse) => SessionStateResponse;
|
|
45
46
|
configOptionsTransformer?: (configOptions: SessionConfigOption[]) => SessionConfigOption[];
|
|
47
|
+
configFeatureOptions?: ACPConfigFeatureOption[];
|
|
46
48
|
modeIdTransformer?: (modeId: string) => string | null;
|
|
47
49
|
toolSnapshotTransformer?: (snapshot: ACPToolSnapshot) => ACPToolSnapshot;
|
|
48
50
|
providerModeWriter?: (context: ACPProviderModeWriterContext) => Promise<ACPProviderModeWriteResult>;
|
|
@@ -76,6 +78,16 @@ interface TerminalExit {
|
|
|
76
78
|
exitCode?: number | null;
|
|
77
79
|
signal?: string | null;
|
|
78
80
|
}
|
|
81
|
+
export interface ACPConfigFeatureOption {
|
|
82
|
+
id: string;
|
|
83
|
+
configId: string;
|
|
84
|
+
category: string;
|
|
85
|
+
label: string;
|
|
86
|
+
description?: string;
|
|
87
|
+
tooltip?: string;
|
|
88
|
+
icon?: string;
|
|
89
|
+
emptyOptionLabel?: string;
|
|
90
|
+
}
|
|
79
91
|
type SelectConfigOption = Extract<SessionConfigOption, {
|
|
80
92
|
type: "select";
|
|
81
93
|
}>;
|
|
@@ -134,6 +146,7 @@ export declare function deriveModesFromACP(fallbackModes: AgentMode[], modeState
|
|
|
134
146
|
currentModeId: string | null;
|
|
135
147
|
};
|
|
136
148
|
export declare function deriveModelDefinitionsFromACP(provider: string, models: SessionModelState | null | undefined, configOptions?: SessionConfigOption[] | null): AgentModelDefinition[];
|
|
149
|
+
export declare function deriveFeaturesFromACP(configOptions: SessionConfigOption[] | null | undefined, featureOptions: ACPConfigFeatureOption[]): AgentFeature[];
|
|
137
150
|
export declare class ACPAgentClient implements AgentClient {
|
|
138
151
|
readonly provider: string;
|
|
139
152
|
readonly capabilities: AgentCapabilityFlags;
|
|
@@ -144,6 +157,7 @@ export declare class ACPAgentClient implements AgentClient {
|
|
|
144
157
|
private readonly modelTransformer?;
|
|
145
158
|
private readonly sessionResponseTransformer?;
|
|
146
159
|
private readonly configOptionsTransformer?;
|
|
160
|
+
private readonly configFeatureOptions;
|
|
147
161
|
private readonly modeIdTransformer?;
|
|
148
162
|
private readonly toolSnapshotTransformer?;
|
|
149
163
|
private readonly providerModeWriter?;
|
|
@@ -156,6 +170,7 @@ export declare class ACPAgentClient implements AgentClient {
|
|
|
156
170
|
createSession(config: AgentSessionConfig, launchContext?: AgentLaunchContext): Promise<AgentSession>;
|
|
157
171
|
resumeSession(handle: AgentPersistenceHandle, overrides?: Partial<AgentSessionConfig>, launchContext?: AgentLaunchContext): Promise<AgentSession>;
|
|
158
172
|
fetchCatalog(options: FetchCatalogOptions): Promise<ProviderCatalog>;
|
|
173
|
+
listFeatures(config: AgentSessionConfig): Promise<AgentFeature[]>;
|
|
159
174
|
listImportableSessions(options?: ListImportableSessionsOptions): Promise<ImportableProviderSession[]>;
|
|
160
175
|
importSession(input: ImportProviderSessionInput, context: ImportProviderSessionContext): Promise<import("../agent-sdk-types.js").ImportedProviderSession>;
|
|
161
176
|
isAvailable(): Promise<boolean>;
|
|
@@ -182,6 +197,7 @@ export declare class ACPAgentSession implements AgentSession, ACPClient {
|
|
|
182
197
|
protected readonly modelTransformer?: (models: AgentModelDefinition[]) => AgentModelDefinition[];
|
|
183
198
|
private readonly sessionResponseTransformer?;
|
|
184
199
|
private readonly configOptionsTransformer?;
|
|
200
|
+
private readonly configFeatureOptions;
|
|
185
201
|
private readonly modeIdTransformer?;
|
|
186
202
|
private readonly toolSnapshotTransformer?;
|
|
187
203
|
private readonly providerModeWriter?;
|
|
@@ -236,6 +252,7 @@ export declare class ACPAgentSession implements AgentSession, ACPClient {
|
|
|
236
252
|
getRuntimeInfo(): Promise<AgentRuntimeInfo>;
|
|
237
253
|
getAvailableModes(): Promise<AgentMode[]>;
|
|
238
254
|
getCurrentMode(): Promise<string | null>;
|
|
255
|
+
get features(): AgentFeature[];
|
|
239
256
|
private ensureCommandsReadyDeferred;
|
|
240
257
|
private settleCommandsReady;
|
|
241
258
|
private waitForCommandsReady;
|
|
@@ -246,6 +263,7 @@ export declare class ACPAgentSession implements AgentSession, ACPClient {
|
|
|
246
263
|
setModel(modelId: string | null): Promise<void>;
|
|
247
264
|
private setModelWithSelection;
|
|
248
265
|
setThinkingOption(thinkingOptionId: string | null): Promise<void>;
|
|
266
|
+
setFeature(featureId: string, value: unknown): Promise<void>;
|
|
249
267
|
private applyConfigOptionResponse;
|
|
250
268
|
getPendingPermissions(): AgentPermissionRequest[];
|
|
251
269
|
respondToPermission(requestId: string, response: AgentPermissionResponse): Promise<void>;
|
|
@@ -257,6 +257,26 @@ export function deriveModelDefinitionsFromACP(provider, models, configOptions) {
|
|
|
257
257
|
metadata: option.metadata,
|
|
258
258
|
}));
|
|
259
259
|
}
|
|
260
|
+
export function deriveFeaturesFromACP(configOptions, featureOptions) {
|
|
261
|
+
return featureOptions.flatMap((featureOption) => {
|
|
262
|
+
const option = findSelectConfigFeatureOption(configOptions, featureOption);
|
|
263
|
+
if (!option) {
|
|
264
|
+
return [];
|
|
265
|
+
}
|
|
266
|
+
return [
|
|
267
|
+
{
|
|
268
|
+
type: "select",
|
|
269
|
+
id: featureOption.id,
|
|
270
|
+
label: featureOption.label,
|
|
271
|
+
description: featureOption.description,
|
|
272
|
+
tooltip: featureOption.tooltip,
|
|
273
|
+
icon: featureOption.icon,
|
|
274
|
+
value: option.currentValue ?? null,
|
|
275
|
+
options: deriveConfigFeatureSelectOptions(option, featureOption),
|
|
276
|
+
},
|
|
277
|
+
];
|
|
278
|
+
});
|
|
279
|
+
}
|
|
260
280
|
export class ACPAgentClient {
|
|
261
281
|
constructor(options) {
|
|
262
282
|
this.provider = options.provider;
|
|
@@ -272,6 +292,7 @@ export class ACPAgentClient {
|
|
|
272
292
|
this.modelTransformer = options.modelTransformer;
|
|
273
293
|
this.sessionResponseTransformer = options.sessionResponseTransformer;
|
|
274
294
|
this.configOptionsTransformer = options.configOptionsTransformer;
|
|
295
|
+
this.configFeatureOptions = options.configFeatureOptions ?? [];
|
|
275
296
|
this.modeIdTransformer = options.modeIdTransformer;
|
|
276
297
|
this.toolSnapshotTransformer = options.toolSnapshotTransformer;
|
|
277
298
|
this.providerModeWriter = options.providerModeWriter;
|
|
@@ -291,6 +312,7 @@ export class ACPAgentClient {
|
|
|
291
312
|
modelTransformer: this.modelTransformer,
|
|
292
313
|
sessionResponseTransformer: this.sessionResponseTransformer,
|
|
293
314
|
configOptionsTransformer: this.configOptionsTransformer,
|
|
315
|
+
configFeatureOptions: this.configFeatureOptions,
|
|
294
316
|
modeIdTransformer: this.modeIdTransformer,
|
|
295
317
|
toolSnapshotTransformer: this.toolSnapshotTransformer,
|
|
296
318
|
providerModeWriter: this.providerModeWriter,
|
|
@@ -329,6 +351,7 @@ export class ACPAgentClient {
|
|
|
329
351
|
modelTransformer: this.modelTransformer,
|
|
330
352
|
sessionResponseTransformer: this.sessionResponseTransformer,
|
|
331
353
|
configOptionsTransformer: this.configOptionsTransformer,
|
|
354
|
+
configFeatureOptions: this.configFeatureOptions,
|
|
332
355
|
modeIdTransformer: this.modeIdTransformer,
|
|
333
356
|
toolSnapshotTransformer: this.toolSnapshotTransformer,
|
|
334
357
|
providerModeWriter: this.providerModeWriter,
|
|
@@ -364,6 +387,24 @@ export class ACPAgentClient {
|
|
|
364
387
|
await this.closeProbe(probe);
|
|
365
388
|
}
|
|
366
389
|
}
|
|
390
|
+
async listFeatures(config) {
|
|
391
|
+
if (this.configFeatureOptions.length === 0) {
|
|
392
|
+
return [];
|
|
393
|
+
}
|
|
394
|
+
this.assertProvider(config);
|
|
395
|
+
const probe = await this.spawnProcess(PROBE_ENV);
|
|
396
|
+
try {
|
|
397
|
+
const response = await this.runACPRequest(() => probe.connection.newSession({
|
|
398
|
+
cwd: config.cwd,
|
|
399
|
+
mcpServers: [],
|
|
400
|
+
}));
|
|
401
|
+
const transformed = this.transformSessionResponse(response);
|
|
402
|
+
return deriveFeaturesFromACP(transformed.configOptions, this.configFeatureOptions);
|
|
403
|
+
}
|
|
404
|
+
finally {
|
|
405
|
+
await this.closeProbe(probe);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
367
408
|
async listImportableSessions(options) {
|
|
368
409
|
const probe = await this.spawnProcess(PROBE_ENV);
|
|
369
410
|
try {
|
|
@@ -582,6 +623,7 @@ export class ACPAgentSession {
|
|
|
582
623
|
this.modelTransformer = options.modelTransformer;
|
|
583
624
|
this.sessionResponseTransformer = options.sessionResponseTransformer;
|
|
584
625
|
this.configOptionsTransformer = options.configOptionsTransformer;
|
|
626
|
+
this.configFeatureOptions = options.configFeatureOptions ?? [];
|
|
585
627
|
this.modeIdTransformer = options.modeIdTransformer;
|
|
586
628
|
this.toolSnapshotTransformer = options.toolSnapshotTransformer;
|
|
587
629
|
this.providerModeWriter = options.providerModeWriter;
|
|
@@ -739,6 +781,9 @@ export class ACPAgentSession {
|
|
|
739
781
|
async getCurrentMode() {
|
|
740
782
|
return this.currentMode;
|
|
741
783
|
}
|
|
784
|
+
get features() {
|
|
785
|
+
return deriveFeaturesFromACP(this.configOptions, this.configFeatureOptions);
|
|
786
|
+
}
|
|
742
787
|
ensureCommandsReadyDeferred() {
|
|
743
788
|
if (this.commandsReadyDeferred || this.commandsReadySettled || this.cachedCommands.length > 0) {
|
|
744
789
|
return;
|
|
@@ -1015,6 +1060,37 @@ export class ACPAgentSession {
|
|
|
1015
1060
|
thinkingOptionId: this.thinkingOptionId,
|
|
1016
1061
|
});
|
|
1017
1062
|
}
|
|
1063
|
+
async setFeature(featureId, value) {
|
|
1064
|
+
if (!this.connection || !this.sessionId) {
|
|
1065
|
+
throw new Error("ACP session not initialized");
|
|
1066
|
+
}
|
|
1067
|
+
const featureOption = this.configFeatureOptions.find((option) => option.id === featureId);
|
|
1068
|
+
if (!featureOption) {
|
|
1069
|
+
throw new Error(`Unknown ${this.provider} feature: ${featureId}`);
|
|
1070
|
+
}
|
|
1071
|
+
const option = findSelectConfigFeatureOption(this.configOptions, featureOption);
|
|
1072
|
+
if (!option) {
|
|
1073
|
+
throw new Error(`${this.provider} does not expose ACP feature '${featureId}'`);
|
|
1074
|
+
}
|
|
1075
|
+
const requestedValue = normalizeConfigFeatureValue(value);
|
|
1076
|
+
const choice = findSelectConfigChoice({ option, value: requestedValue });
|
|
1077
|
+
if (!choice) {
|
|
1078
|
+
throw new Error(`${this.provider} feature '${featureId}' does not include option '${requestedValue}'`);
|
|
1079
|
+
}
|
|
1080
|
+
const response = await this.connection.setSessionConfigOption({
|
|
1081
|
+
sessionId: this.sessionId,
|
|
1082
|
+
configId: option.id,
|
|
1083
|
+
value: requestedValue,
|
|
1084
|
+
});
|
|
1085
|
+
const currentValue = this.applyConfigOptionResponse({
|
|
1086
|
+
response,
|
|
1087
|
+
configId: option.id,
|
|
1088
|
+
category: featureOption.category,
|
|
1089
|
+
requestedValue,
|
|
1090
|
+
label: featureOption.label,
|
|
1091
|
+
});
|
|
1092
|
+
this.config.featureValues = { ...this.config.featureValues, [featureId]: currentValue };
|
|
1093
|
+
}
|
|
1018
1094
|
applyConfigOptionResponse({ response, configId, category, requestedValue, label, }) {
|
|
1019
1095
|
this.configOptions = this.transformConfigOptions(response.configOptions);
|
|
1020
1096
|
const responseOption = findSelectConfigOption({
|
|
@@ -1386,6 +1462,13 @@ export class ACPAgentSession {
|
|
|
1386
1462
|
if (this.config.thinkingOptionId && this.config.thinkingOptionId !== this.thinkingOptionId) {
|
|
1387
1463
|
await this.setThinkingOption(this.config.thinkingOptionId);
|
|
1388
1464
|
}
|
|
1465
|
+
const configuredFeatureValues = this.config.featureValues ?? {};
|
|
1466
|
+
for (const featureOption of this.configFeatureOptions) {
|
|
1467
|
+
if (!Object.prototype.hasOwnProperty.call(configuredFeatureValues, featureOption.id)) {
|
|
1468
|
+
continue;
|
|
1469
|
+
}
|
|
1470
|
+
await this.setFeature(featureOption.id, configuredFeatureValues[featureOption.id]);
|
|
1471
|
+
}
|
|
1389
1472
|
}
|
|
1390
1473
|
warnInvalidSelection(value, message) {
|
|
1391
1474
|
this.logger.warn({ value }, message);
|
|
@@ -1671,6 +1754,12 @@ function findSelectConfigOption({ configOptions, category, id, }) {
|
|
|
1671
1754
|
const option = configOptions?.find((entry) => entry.type === "select" && entry.category === category && (!id || entry.id === id));
|
|
1672
1755
|
return option ?? null;
|
|
1673
1756
|
}
|
|
1757
|
+
function findSelectConfigFeatureOption(configOptions, featureOption) {
|
|
1758
|
+
const option = configOptions?.find((entry) => entry.type === "select" &&
|
|
1759
|
+
entry.id === featureOption.configId &&
|
|
1760
|
+
entry.category === featureOption.category);
|
|
1761
|
+
return option ?? null;
|
|
1762
|
+
}
|
|
1674
1763
|
function findSelectConfigChoice({ option, value, }) {
|
|
1675
1764
|
if (!option) {
|
|
1676
1765
|
return null;
|
|
@@ -1690,6 +1779,34 @@ function flattenSelectOptions(options) {
|
|
|
1690
1779
|
}
|
|
1691
1780
|
return flattened;
|
|
1692
1781
|
}
|
|
1782
|
+
function deriveConfigFeatureSelectOptions(option, featureOption) {
|
|
1783
|
+
return flattenSelectOptions(option.options).map((choice) => ({
|
|
1784
|
+
id: choice.value,
|
|
1785
|
+
label: normalizeConfigFeatureOptionLabel(choice, featureOption),
|
|
1786
|
+
description: choice.description ?? undefined,
|
|
1787
|
+
isDefault: choice.value === option.currentValue,
|
|
1788
|
+
metadata: choice.group ? { group: choice.group } : undefined,
|
|
1789
|
+
}));
|
|
1790
|
+
}
|
|
1791
|
+
function normalizeConfigFeatureOptionLabel(choice, featureOption) {
|
|
1792
|
+
const name = choice.name.trim();
|
|
1793
|
+
if (name) {
|
|
1794
|
+
return name;
|
|
1795
|
+
}
|
|
1796
|
+
if (choice.value === "" && featureOption.emptyOptionLabel) {
|
|
1797
|
+
return featureOption.emptyOptionLabel;
|
|
1798
|
+
}
|
|
1799
|
+
return choice.value;
|
|
1800
|
+
}
|
|
1801
|
+
function normalizeConfigFeatureValue(value) {
|
|
1802
|
+
if (typeof value === "string") {
|
|
1803
|
+
return value;
|
|
1804
|
+
}
|
|
1805
|
+
if (value === null) {
|
|
1806
|
+
return "";
|
|
1807
|
+
}
|
|
1808
|
+
throw new Error(`ACP feature value must be a string`);
|
|
1809
|
+
}
|
|
1693
1810
|
function deriveSelectorOptions(configOptions, category) {
|
|
1694
1811
|
const option = findSelectConfigOption({ configOptions, category });
|
|
1695
1812
|
if (!option) {
|
|
@@ -1252,23 +1252,6 @@ function readLegacyResultUsageTokens(usage) {
|
|
|
1252
1252
|
const usageRecord = toObjectRecord(usage);
|
|
1253
1253
|
return usageRecord ? readUsageTokenTotal(usageRecord) : undefined;
|
|
1254
1254
|
}
|
|
1255
|
-
function readCurrentContextUsage(value) {
|
|
1256
|
-
const record = toObjectRecord(value);
|
|
1257
|
-
if (!record) {
|
|
1258
|
-
return undefined;
|
|
1259
|
-
}
|
|
1260
|
-
const totalTokens = record.totalTokens;
|
|
1261
|
-
if (typeof totalTokens !== "number" || !Number.isFinite(totalTokens) || totalTokens < 0) {
|
|
1262
|
-
return undefined;
|
|
1263
|
-
}
|
|
1264
|
-
const maxTokens = record.maxTokens;
|
|
1265
|
-
return {
|
|
1266
|
-
totalTokens,
|
|
1267
|
-
...(typeof maxTokens === "number" && Number.isFinite(maxTokens) && maxTokens > 0
|
|
1268
|
-
? { maxTokens }
|
|
1269
|
-
: {}),
|
|
1270
|
-
};
|
|
1271
|
-
}
|
|
1272
1255
|
function isClaudeSubagentToolName(name) {
|
|
1273
1256
|
return name === "Task" || name === "Agent";
|
|
1274
1257
|
}
|
|
@@ -1280,6 +1263,7 @@ class ClaudeContextUsageState {
|
|
|
1280
1263
|
beginTurn() {
|
|
1281
1264
|
this.streamRequestInputTokens = undefined;
|
|
1282
1265
|
this.streamRequestOutputTokens = undefined;
|
|
1266
|
+
this.compactedContextWindowUsedTokens = undefined;
|
|
1283
1267
|
}
|
|
1284
1268
|
setInitialContextWindowMaxTokens(contextWindowMaxTokens) {
|
|
1285
1269
|
this.contextWindowMaxTokens = contextWindowMaxTokens;
|
|
@@ -1291,11 +1275,6 @@ class ClaudeContextUsageState {
|
|
|
1291
1275
|
}
|
|
1292
1276
|
return this.contextWindowMaxTokens;
|
|
1293
1277
|
}
|
|
1294
|
-
recordCurrentContextUsage(usage) {
|
|
1295
|
-
if (usage?.maxTokens !== undefined) {
|
|
1296
|
-
this.contextWindowMaxTokens = usage.maxTokens;
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
1278
|
buildStreamUsageEvent(event) {
|
|
1300
1279
|
const streamEvent = toObjectRecord(event);
|
|
1301
1280
|
if (!streamEvent) {
|
|
@@ -1326,7 +1305,7 @@ class ClaudeContextUsageState {
|
|
|
1326
1305
|
}
|
|
1327
1306
|
return this.createUsageUpdatedEvent(usedTokens);
|
|
1328
1307
|
}
|
|
1329
|
-
buildResultUsage(message, modelUsage
|
|
1308
|
+
buildResultUsage(message, modelUsage) {
|
|
1330
1309
|
try {
|
|
1331
1310
|
if (!message.usage) {
|
|
1332
1311
|
return undefined;
|
|
@@ -1338,7 +1317,6 @@ class ClaudeContextUsageState {
|
|
|
1338
1317
|
totalCostUsd: message.total_cost_usd,
|
|
1339
1318
|
};
|
|
1340
1319
|
const modelContextWindowMaxTokens = this.recordModelUsage(modelUsage ?? message.modelUsage);
|
|
1341
|
-
this.recordCurrentContextUsage(currentContextUsage);
|
|
1342
1320
|
if (this.contextWindowMaxTokens !== undefined) {
|
|
1343
1321
|
usage.contextWindowMaxTokens = this.contextWindowMaxTokens;
|
|
1344
1322
|
}
|
|
@@ -1347,13 +1325,14 @@ class ClaudeContextUsageState {
|
|
|
1347
1325
|
}
|
|
1348
1326
|
const activeResultUsageTokens = readActiveUsageTokens(message.usage) ??
|
|
1349
1327
|
(this.completedResultTurns === 0 ? readLegacyResultUsageTokens(message.usage) : undefined);
|
|
1350
|
-
const usedTokens =
|
|
1328
|
+
const usedTokens = this.streamUsedTokens() ?? activeResultUsageTokens ?? this.compactedContextWindowUsedTokens;
|
|
1351
1329
|
if (usedTokens !== undefined) {
|
|
1352
1330
|
usage.contextWindowUsedTokens = usedTokens;
|
|
1353
1331
|
}
|
|
1354
1332
|
return usage;
|
|
1355
1333
|
}
|
|
1356
1334
|
finally {
|
|
1335
|
+
this.compactedContextWindowUsedTokens = undefined;
|
|
1357
1336
|
this.completedResultTurns += 1;
|
|
1358
1337
|
}
|
|
1359
1338
|
}
|
|
@@ -1362,7 +1341,8 @@ class ClaudeContextUsageState {
|
|
|
1362
1341
|
typeof this.streamRequestOutputTokens !== "number") {
|
|
1363
1342
|
return undefined;
|
|
1364
1343
|
}
|
|
1365
|
-
|
|
1344
|
+
const usedTokens = this.streamRequestInputTokens + this.streamRequestOutputTokens;
|
|
1345
|
+
return usedTokens > 0 ? usedTokens : undefined;
|
|
1366
1346
|
}
|
|
1367
1347
|
createUsageUpdatedEvent(contextWindowUsedTokens) {
|
|
1368
1348
|
const usage = {
|
|
@@ -1377,6 +1357,23 @@ class ClaudeContextUsageState {
|
|
|
1377
1357
|
usage,
|
|
1378
1358
|
};
|
|
1379
1359
|
}
|
|
1360
|
+
buildCompactionUsageEvent(postTokens) {
|
|
1361
|
+
this.streamRequestInputTokens = undefined;
|
|
1362
|
+
this.streamRequestOutputTokens = undefined;
|
|
1363
|
+
this.compactedContextWindowUsedTokens = postTokens;
|
|
1364
|
+
const usage = {};
|
|
1365
|
+
if (this.contextWindowMaxTokens !== undefined) {
|
|
1366
|
+
usage.contextWindowMaxTokens = this.contextWindowMaxTokens;
|
|
1367
|
+
}
|
|
1368
|
+
if (postTokens !== undefined) {
|
|
1369
|
+
usage.contextWindowUsedTokens = postTokens;
|
|
1370
|
+
}
|
|
1371
|
+
return {
|
|
1372
|
+
type: "usage_updated",
|
|
1373
|
+
provider: "claude",
|
|
1374
|
+
usage,
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1380
1377
|
}
|
|
1381
1378
|
class ClaudeAgentSession {
|
|
1382
1379
|
constructor(config, options) {
|
|
@@ -2659,7 +2656,7 @@ class ClaudeAgentSession {
|
|
|
2659
2656
|
if (await this.handleMissingResumedConversation(message, activeQuery)) {
|
|
2660
2657
|
return true;
|
|
2661
2658
|
}
|
|
2662
|
-
await this.routeSdkMessageFromPump(message
|
|
2659
|
+
await this.routeSdkMessageFromPump(message);
|
|
2663
2660
|
return false;
|
|
2664
2661
|
};
|
|
2665
2662
|
const drainActiveQuery = async () => {
|
|
@@ -2727,7 +2724,7 @@ class ClaudeAgentSession {
|
|
|
2727
2724
|
message.type === "tool_progress" ||
|
|
2728
2725
|
(message.type === "system" && message.subtype === "task_notification"));
|
|
2729
2726
|
}
|
|
2730
|
-
async routeSdkMessageFromPump(message
|
|
2727
|
+
async routeSdkMessageFromPump(message) {
|
|
2731
2728
|
if (this.shouldSuppressStaleResult(message)) {
|
|
2732
2729
|
return;
|
|
2733
2730
|
}
|
|
@@ -2750,7 +2747,7 @@ class ClaudeAgentSession {
|
|
|
2750
2747
|
identifiers,
|
|
2751
2748
|
rawEvent: message,
|
|
2752
2749
|
}, "provider.claude.parsed_event");
|
|
2753
|
-
const events = await this.buildPumpedMessageEvents(message,
|
|
2750
|
+
const events = await this.buildPumpedMessageEvents(message, identifiers.messageId, turnId);
|
|
2754
2751
|
if (events.length === 0) {
|
|
2755
2752
|
return;
|
|
2756
2753
|
}
|
|
@@ -2773,14 +2770,10 @@ class ClaudeAgentSession {
|
|
|
2773
2770
|
}
|
|
2774
2771
|
this.dispatchEvents(events);
|
|
2775
2772
|
}
|
|
2776
|
-
async buildPumpedMessageEvents(message,
|
|
2777
|
-
const currentContextUsage = message.type === "result" && message.subtype === "success"
|
|
2778
|
-
? await this.queryCurrentContextUsage(activeQuery)
|
|
2779
|
-
: undefined;
|
|
2773
|
+
async buildPumpedMessageEvents(message, messageIdHint, turnId) {
|
|
2780
2774
|
const messageEvents = this.translateMessageToEvents(message, {
|
|
2781
2775
|
suppressAssistantText: true,
|
|
2782
2776
|
suppressReasoning: true,
|
|
2783
|
-
currentContextUsage,
|
|
2784
2777
|
});
|
|
2785
2778
|
const assistantTimelineEvents = this.timelineAssembler
|
|
2786
2779
|
.consume({
|
|
@@ -2795,16 +2788,6 @@ class ClaudeAgentSession {
|
|
|
2795
2788
|
}));
|
|
2796
2789
|
return [...messageEvents, ...assistantTimelineEvents];
|
|
2797
2790
|
}
|
|
2798
|
-
async queryCurrentContextUsage(activeQuery) {
|
|
2799
|
-
try {
|
|
2800
|
-
const usage = await withTimeout(activeQuery.getContextUsage(), 3000, "timeout");
|
|
2801
|
-
return readCurrentContextUsage(usage);
|
|
2802
|
-
}
|
|
2803
|
-
catch (error) {
|
|
2804
|
-
this.logger.debug({ err: error }, "Claude context usage query failed");
|
|
2805
|
-
return undefined;
|
|
2806
|
-
}
|
|
2807
|
-
}
|
|
2808
2791
|
async handleMissingResumedConversation(message, activeQuery) {
|
|
2809
2792
|
const staleResumeError = this.readMissingResumedConversationError(message);
|
|
2810
2793
|
if (!staleResumeError) {
|
|
@@ -2895,9 +2878,7 @@ class ClaudeAgentSession {
|
|
|
2895
2878
|
this.appendStreamEventEvents(message, events, options);
|
|
2896
2879
|
break;
|
|
2897
2880
|
case "result":
|
|
2898
|
-
this.appendResultEvents(message, events
|
|
2899
|
-
currentContextUsage: options?.currentContextUsage,
|
|
2900
|
-
});
|
|
2881
|
+
this.appendResultEvents(message, events);
|
|
2901
2882
|
break;
|
|
2902
2883
|
default:
|
|
2903
2884
|
break;
|
|
@@ -2963,6 +2944,7 @@ class ClaudeAgentSession {
|
|
|
2963
2944
|
},
|
|
2964
2945
|
provider: "claude",
|
|
2965
2946
|
});
|
|
2947
|
+
events.push(this.contextUsage.buildCompactionUsageEvent(compactMetadata?.postTokens));
|
|
2966
2948
|
return;
|
|
2967
2949
|
}
|
|
2968
2950
|
if (message.subtype === "task_notification") {
|
|
@@ -3067,8 +3049,8 @@ class ClaudeAgentSession {
|
|
|
3067
3049
|
events.push({ type: "timeline", item, provider: "claude" });
|
|
3068
3050
|
}
|
|
3069
3051
|
}
|
|
3070
|
-
appendResultEvents(message, events
|
|
3071
|
-
const usage = this.convertUsage(message, message.modelUsage
|
|
3052
|
+
appendResultEvents(message, events) {
|
|
3053
|
+
const usage = this.convertUsage(message, message.modelUsage);
|
|
3072
3054
|
if (message.subtype === "success") {
|
|
3073
3055
|
// Built-in slash commands (e.g. /voice, /usage, "Unknown command: …")
|
|
3074
3056
|
// run client-side in the Claude CLI with no model turn — output_tokens
|
|
@@ -3212,8 +3194,8 @@ class ClaudeAgentSession {
|
|
|
3212
3194
|
}
|
|
3213
3195
|
return null;
|
|
3214
3196
|
}
|
|
3215
|
-
convertUsage(message, modelUsage
|
|
3216
|
-
return this.contextUsage.buildResultUsage(message, modelUsage
|
|
3197
|
+
convertUsage(message, modelUsage) {
|
|
3198
|
+
return this.contextUsage.buildResultUsage(message, modelUsage);
|
|
3217
3199
|
}
|
|
3218
3200
|
enqueueTimeline(item) {
|
|
3219
3201
|
this.pushEvent({ type: "timeline", item, provider: "claude" });
|
|
@@ -3899,7 +3881,9 @@ function readCompactionMetadata(source) {
|
|
|
3899
3881
|
const trigger = typeof metadata.trigger === "string" ? metadata.trigger : undefined;
|
|
3900
3882
|
const preTokensRaw = metadata.preTokens ?? metadata.pre_tokens;
|
|
3901
3883
|
const preTokens = typeof preTokensRaw === "number" ? preTokensRaw : undefined;
|
|
3902
|
-
|
|
3884
|
+
const postTokensRaw = metadata.postTokens ?? metadata.post_tokens;
|
|
3885
|
+
const postTokens = typeof postTokensRaw === "number" ? postTokensRaw : undefined;
|
|
3886
|
+
return { trigger, preTokens, postTokens };
|
|
3903
3887
|
}
|
|
3904
3888
|
return null;
|
|
3905
3889
|
}
|
|
@@ -2,8 +2,9 @@ import type { Logger } from "pino";
|
|
|
2
2
|
import type { SessionConfigOption } from "@agentclientprotocol/sdk";
|
|
3
3
|
import type { AgentMode } from "../agent-sdk-types.js";
|
|
4
4
|
import { type ProviderRuntimeSettings } from "../provider-launch-config.js";
|
|
5
|
-
import { ACPAgentClient, type ACPBeforeModeWriteResult, type ACPProviderModeWriteResult, type ACPProviderModeWriterContext, type SessionStateResponse } from "./acp-agent.js";
|
|
5
|
+
import { ACPAgentClient, type ACPConfigFeatureOption, type ACPBeforeModeWriteResult, type ACPProviderModeWriteResult, type ACPProviderModeWriterContext, type SessionStateResponse } from "./acp-agent.js";
|
|
6
6
|
export declare const COPILOT_ALLOW_ALL_MODE_ID = "allow-all";
|
|
7
|
+
export declare const COPILOT_AGENT_FEATURE_OPTION: ACPConfigFeatureOption;
|
|
7
8
|
export declare const COPILOT_MODES: AgentMode[];
|
|
8
9
|
interface CopilotACPAgentClientOptions {
|
|
9
10
|
logger: Logger;
|
|
@@ -20,6 +20,15 @@ export const COPILOT_ALLOW_ALL_MODE_ID = "allow-all";
|
|
|
20
20
|
const COPILOT_ALLOW_ALL_CONFIG_ID = "allow_all";
|
|
21
21
|
const COPILOT_ALLOW_ALL_ON = "on";
|
|
22
22
|
const COPILOT_ALLOW_ALL_OFF = "off";
|
|
23
|
+
export const COPILOT_AGENT_FEATURE_OPTION = {
|
|
24
|
+
id: "agent",
|
|
25
|
+
configId: "agent",
|
|
26
|
+
category: "_agent",
|
|
27
|
+
label: "Agent",
|
|
28
|
+
description: "Use a Copilot custom agent profile",
|
|
29
|
+
tooltip: "Select Copilot agent",
|
|
30
|
+
emptyOptionLabel: "Default",
|
|
31
|
+
};
|
|
23
32
|
export const COPILOT_MODES = [
|
|
24
33
|
{
|
|
25
34
|
id: COPILOT_AGENT_MODE_ID,
|
|
@@ -47,6 +56,7 @@ export class CopilotACPAgentClient extends ACPAgentClient {
|
|
|
47
56
|
defaultModes: COPILOT_MODES,
|
|
48
57
|
sessionResponseTransformer: transformCopilotSessionResponse,
|
|
49
58
|
configOptionsTransformer: transformCopilotConfigOptions,
|
|
59
|
+
configFeatureOptions: [COPILOT_AGENT_FEATURE_OPTION],
|
|
50
60
|
modeIdTransformer: transformCopilotModeId,
|
|
51
61
|
providerModeWriter: writeCopilotProviderMode,
|
|
52
62
|
beforeModeWriter: beforeCopilotModeWriter,
|
|
@@ -16,10 +16,10 @@ export interface OpenCodeServerManagerLike {
|
|
|
16
16
|
port: number;
|
|
17
17
|
url: string;
|
|
18
18
|
}>;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
acquireCurrent(): Promise<OpenCodeServerAcquisition>;
|
|
20
|
+
acquireNew(): Promise<OpenCodeServerAcquisition>;
|
|
21
|
+
acquireDedicated(env: Record<string, string>): Promise<OpenCodeServerAcquisition>;
|
|
22
|
+
shutdown(): Promise<void>;
|
|
23
23
|
}
|
|
24
24
|
export interface OpenCodeServerGeneration {
|
|
25
25
|
process: ChildProcess;
|
|
@@ -27,7 +27,11 @@ export interface OpenCodeServerGeneration {
|
|
|
27
27
|
url: string;
|
|
28
28
|
refCount: number;
|
|
29
29
|
retired: boolean;
|
|
30
|
+
ready: Promise<void>;
|
|
30
31
|
managedProcessId?: string;
|
|
32
|
+
managedProcessRecord?: Promise<{
|
|
33
|
+
id: string;
|
|
34
|
+
} | null>;
|
|
31
35
|
}
|
|
32
36
|
export type OpenCodePortAllocator = () => Promise<number>;
|
|
33
37
|
export type OpenCodeCommandPrefixResolver = () => Promise<{
|
|
@@ -50,7 +54,7 @@ export declare class OpenCodeServerManager implements OpenCodeServerManagerLike
|
|
|
50
54
|
private currentServer;
|
|
51
55
|
private retiredServers;
|
|
52
56
|
private startPromise;
|
|
53
|
-
private
|
|
57
|
+
private newServerPromise;
|
|
54
58
|
private readonly logger;
|
|
55
59
|
private readonly runtimeSettings?;
|
|
56
60
|
private readonly runtimeSettingsKey;
|
|
@@ -66,21 +70,20 @@ export declare class OpenCodeServerManager implements OpenCodeServerManagerLike
|
|
|
66
70
|
port: number;
|
|
67
71
|
url: string;
|
|
68
72
|
}>;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}): Promise<OpenCodeServerAcquisition>;
|
|
73
|
+
acquireCurrent(): Promise<OpenCodeServerAcquisition>;
|
|
74
|
+
acquireNew(): Promise<OpenCodeServerAcquisition>;
|
|
75
|
+
acquireDedicated(env: Record<string, string>): Promise<OpenCodeServerAcquisition>;
|
|
73
76
|
private acquireServer;
|
|
74
|
-
private
|
|
77
|
+
private getNewServer;
|
|
75
78
|
private getCurrentServer;
|
|
76
79
|
private rotateCurrentServer;
|
|
77
|
-
private startDedicatedServer;
|
|
78
80
|
private startServer;
|
|
79
81
|
shutdown(): Promise<void>;
|
|
80
82
|
private cleanupRetiredServers;
|
|
81
83
|
private killServer;
|
|
82
84
|
private recordManagedServerProcess;
|
|
83
85
|
private removeManagedProcessRecordWhenResolved;
|
|
86
|
+
private removeManagedServerRecord;
|
|
84
87
|
private removeManagedProcessId;
|
|
85
88
|
}
|
|
86
89
|
//# sourceMappingURL=server-manager.d.ts.map
|