Skip to content

Commit ddb2b11

Browse files
Add CopilotAPI service for a future Claude agent (#313553)
* Add CopilotAPI service & plan for Claude This service can be used to send requests to CAPI which we will need as we shim requests from agents to CAPI. * Add CopilotAPI service & plan for Claude This service can be used to send requests to CAPI which we will need as we shim requests from agents to CAPI. * Clarify signal propagation behavior in ICopilotApiServiceRequestOptions documentation
1 parent dc2572a commit ddb2b11

9 files changed

Lines changed: 3411 additions & 1 deletion

File tree

eslint.config.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1067,7 +1067,7 @@ export default tseslint.config(
10671067
'local/code-no-static-node-module-import': [
10681068
'error',
10691069
// Files that run in separate processes, not on the electron-main startup path
1070-
'src/vs/platform/agentHost/node/copilot/**/*.ts',
1070+
'src/vs/platform/agentHost/node/**/*.ts',
10711071
'src/vs/platform/files/node/watcher/**/*.ts',
10721072
'src/vs/platform/terminal/node/**/*.ts',
10731073
// Files that use small, safe modules
@@ -1620,6 +1620,21 @@ export default tseslint.config(
16201620
'vs/editor/common/diff/**', // diffing logic used by the agent host
16211621
]
16221622
},
1623+
{
1624+
'target': 'src/vs/platform/agentHost/~',
1625+
'restrictions': [
1626+
'vs/base/~',
1627+
'vs/base/parts/*/~',
1628+
'vs/platform/*/~',
1629+
'tas-client', // node module allowed even in /common/
1630+
'@microsoft/1ds-core-js', // node module allowed even in /common/
1631+
'@microsoft/1ds-post-js', // node module allowed even in /common/
1632+
'@xterm/headless', // node module allowed even in /common/
1633+
'@vscode/tree-sitter-wasm', // used by agentHost for command auto-approval
1634+
'@vscode/copilot-api', // used by agentHost for Copilot API requests
1635+
'@anthropic-ai/sdk' // used by agentHost for Anthropic API requests
1636+
]
1637+
},
16231638
{
16241639
'target': 'src/vs/platform/*/~',
16251640
'restrictions': [

package-lock.json

Lines changed: 56 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
},
9191
"dependencies": {
9292
"@anthropic-ai/sandbox-runtime": "0.0.49",
93+
"@anthropic-ai/sdk": "^0.82.0",
9394
"@github/copilot": "1.0.39",
9495
"@github/copilot-sdk": "^0.3.0",
9596
"@microsoft/1ds-core-js": "^3.2.13",
@@ -102,6 +103,7 @@
102103
"@parcel/watcher": "^2.5.6",
103104
"@types/semver": "^7.5.8",
104105
"@vscode/codicons": "^0.0.46-6",
106+
"@vscode/copilot-api": "^0.3.0",
105107
"@vscode/deviceid": "^0.1.1",
106108
"@vscode/iconv-lite-umd": "0.7.1",
107109
"@vscode/native-watchdog": "^1.4.6",

src/typings/copilot-api.d.ts

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
/**
7+
* Ambient type declarations for @vscode/copilot-api.
8+
*
9+
* The package's .d.ts files use extensionless relative imports which are
10+
* incompatible with `moduleResolution: "nodenext"`. This file provides
11+
* the subset of types used by the agent host until the package is fixed.
12+
*/
13+
declare module '@vscode/copilot-api' {
14+
15+
export interface IAbortSignal {
16+
readonly aborted: boolean;
17+
addEventListener(type: 'abort', listener: (this: AbortSignal) => void): void;
18+
removeEventListener(type: 'abort', listener: (this: AbortSignal) => void): void;
19+
}
20+
21+
export interface FetchOptions {
22+
callSite: string;
23+
headers?: { [name: string]: string };
24+
body?: BodyInit;
25+
timeout?: number;
26+
json?: unknown;
27+
method?: 'GET' | 'POST' | 'PUT';
28+
signal?: IAbortSignal;
29+
suppressIntegrationId?: boolean;
30+
}
31+
32+
export type MakeRequestOptions = Omit<FetchOptions, 'callSite'> & {
33+
callSite?: string;
34+
};
35+
36+
export interface IFetcherService {
37+
fetch(url: string, options: FetchOptions): Promise<unknown>;
38+
}
39+
40+
export interface IExtensionInformation {
41+
name: string;
42+
sessionId: string;
43+
machineId: string;
44+
deviceId: string;
45+
vscodeVersion: string;
46+
version: string;
47+
buildType: 'dev' | 'prod';
48+
}
49+
50+
export interface CopilotToken {
51+
endpoints: {
52+
api?: string;
53+
telemetry?: string;
54+
proxy?: string;
55+
'origin-tracker'?: string;
56+
};
57+
sku: string;
58+
}
59+
60+
export enum RequestType {
61+
CopilotToken = 'CopilotToken',
62+
ChatCompletions = 'ChatCompletions',
63+
ChatResponses = 'ChatResponses',
64+
ChatMessages = 'ChatMessages',
65+
Models = 'Models',
66+
}
67+
68+
export type RequestMetadata =
69+
| { type: RequestType.CopilotToken }
70+
| { type: RequestType.ChatCompletions | RequestType.ChatResponses | RequestType.ChatMessages | RequestType.Models; isModelLab?: boolean };
71+
72+
export interface IDomainChangeResponse {
73+
capiUrlChanged: boolean;
74+
telemetryUrlChanged: boolean;
75+
dotcomUrlChanged: boolean;
76+
proxyUrlChanged: boolean;
77+
}
78+
79+
export class CAPIClient {
80+
constructor(
81+
extensionInfo: IExtensionInformation,
82+
license: string | undefined,
83+
fetcherService?: IFetcherService,
84+
hmacSecret?: string,
85+
integrationId?: string,
86+
);
87+
updateDomains(copilotToken: CopilotToken | undefined, enterpriseUrlConfig: string | undefined): IDomainChangeResponse;
88+
makeRequest<T>(requestOptions: MakeRequestOptions, requestMetadata: RequestMetadata): Promise<T>;
89+
}
90+
91+
interface CCAModelBilling {
92+
is_premium: boolean;
93+
multiplier: number;
94+
restricted_to: string[];
95+
}
96+
97+
interface CCAModelVisionLimits {
98+
max_prompt_image_size: number;
99+
max_prompt_images: number;
100+
supported_media_types: string[];
101+
}
102+
103+
interface CCAModelLimits {
104+
max_context_window_tokens: number;
105+
max_output_tokens: number;
106+
max_prompt_tokens: number;
107+
vision?: CCAModelVisionLimits;
108+
}
109+
110+
interface CCAModelSupports {
111+
max_thinking_budget?: number;
112+
min_thinking_budget?: number;
113+
parallel_tool_calls: boolean;
114+
streaming: boolean;
115+
tool_calls: boolean;
116+
vision: boolean;
117+
}
118+
119+
interface CCAModelCapabilities {
120+
family: string;
121+
limits: CCAModelLimits;
122+
object: string;
123+
supports: CCAModelSupports;
124+
tokenizer: string;
125+
type: string;
126+
}
127+
128+
interface CCAModelPolicy {
129+
state: string;
130+
terms: string;
131+
}
132+
133+
export interface CCAModel {
134+
billing: CCAModelBilling;
135+
capabilities: CCAModelCapabilities;
136+
id: string;
137+
is_chat_default: boolean;
138+
is_chat_fallback: boolean;
139+
model_picker_category: string;
140+
model_picker_enabled: boolean;
141+
name: string;
142+
object: string;
143+
policy: CCAModelPolicy;
144+
preview: boolean;
145+
/**
146+
* API endpoints the model supports (e.g. `'/v1/messages'`, `'/chat/completions'`).
147+
* Anthropic-format models use `'/v1/messages'`.
148+
*/
149+
supported_endpoints: string[] | undefined;
150+
vendor: string;
151+
version: string;
152+
}
153+
}

src/vs/platform/agentHost/node/agentHostMain.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { AgentService } from './agentService.js';
2020
import { IAgentConfigurationService } from './agentConfigurationService.js';
2121
import { IAgentHostTerminalManager } from './agentHostTerminalManager.js';
2222
import { CopilotAgent } from './copilot/copilotAgent.js';
23+
import { CopilotApiService, ICopilotApiService } from './shared/copilotApiService.js';
2324
import { ProtocolServerHandler } from './protocolServerHandler.js';
2425
import { WebSocketProtocolServer } from './webSocketTransport.js';
2526
import { INativeEnvironmentService } from '../../environment/common/environment.js';
@@ -100,9 +101,12 @@ function startAgentHost(): void {
100101
diServices.set(ILogService, logService);
101102
diServices.set(IFileService, fileService);
102103
diServices.set(ISessionDataService, sessionDataService);
104+
diServices.set(IProductService, productService);
103105
const instantiationService = new InstantiationService(diServices);
104106
const gitService = instantiationService.createInstance(AgentHostGitService);
105107
diServices.set(IAgentHostGitService, gitService);
108+
const copilotApiService = instantiationService.createInstance(CopilotApiService, undefined);
109+
diServices.set(ICopilotApiService, copilotApiService);
106110
agentService = new AgentService(logService, fileService, sessionDataService, productService, gitService, rootConfigResource);
107111
const pluginManager = new AgentPluginManager(URI.file(environmentService.userDataPath), fileService, logService);
108112
diServices.set(IAgentPluginManager, pluginManager);

0 commit comments

Comments
 (0)