gencode-ai 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -90
- package/dist/agent/agent.d.ts +1 -1
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +8 -2
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/types.d.ts +9 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/cli/components/AllModelsSelector.d.ts +11 -0
- package/dist/cli/components/AllModelsSelector.d.ts.map +1 -0
- package/dist/cli/components/AllModelsSelector.js +153 -0
- package/dist/cli/components/AllModelsSelector.js.map +1 -0
- package/dist/cli/components/App.d.ts.map +1 -1
- package/dist/cli/components/App.js +59 -25
- package/dist/cli/components/App.js.map +1 -1
- package/dist/cli/components/CommandSuggestions.d.ts.map +1 -1
- package/dist/cli/components/CommandSuggestions.js +1 -0
- package/dist/cli/components/CommandSuggestions.js.map +1 -1
- package/dist/cli/components/Messages.d.ts +15 -1
- package/dist/cli/components/Messages.d.ts.map +1 -1
- package/dist/cli/components/Messages.js +41 -15
- package/dist/cli/components/Messages.js.map +1 -1
- package/dist/cli/components/ModelSelector.d.ts +7 -7
- package/dist/cli/components/ModelSelector.d.ts.map +1 -1
- package/dist/cli/components/ModelSelector.js +116 -33
- package/dist/cli/components/ModelSelector.js.map +1 -1
- package/dist/cli/components/ProviderManager.d.ts +8 -0
- package/dist/cli/components/ProviderManager.d.ts.map +1 -0
- package/dist/cli/components/ProviderManager.js +280 -0
- package/dist/cli/components/ProviderManager.js.map +1 -0
- package/dist/cli/components/markdown.d.ts +9 -0
- package/dist/cli/components/markdown.d.ts.map +1 -0
- package/dist/cli/components/markdown.js +129 -0
- package/dist/cli/components/markdown.js.map +1 -0
- package/dist/cli/components/theme.d.ts +5 -0
- package/dist/cli/components/theme.d.ts.map +1 -1
- package/dist/cli/components/theme.js +7 -0
- package/dist/cli/components/theme.js.map +1 -1
- package/dist/cli/index.js +19 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +3 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +2 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/providers-config.d.ts +28 -0
- package/dist/config/providers-config.d.ts.map +1 -0
- package/dist/config/providers-config.js +79 -0
- package/dist/config/providers-config.js.map +1 -0
- package/dist/config/types.d.ts +31 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +1 -0
- package/dist/config/types.js.map +1 -1
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/gemini.js +14 -3
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/index.d.ts +5 -3
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +13 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/registry.d.ts +66 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +158 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/search/brave.d.ts +14 -0
- package/dist/providers/search/brave.d.ts.map +1 -0
- package/dist/providers/search/brave.js +87 -0
- package/dist/providers/search/brave.js.map +1 -0
- package/dist/providers/search/exa.d.ts +12 -0
- package/dist/providers/search/exa.d.ts.map +1 -0
- package/dist/providers/search/exa.js +158 -0
- package/dist/providers/search/exa.js.map +1 -0
- package/dist/providers/search/index.d.ts +31 -0
- package/dist/providers/search/index.d.ts.map +1 -0
- package/dist/providers/search/index.js +75 -0
- package/dist/providers/search/index.js.map +1 -0
- package/dist/providers/search/serper.d.ts +14 -0
- package/dist/providers/search/serper.d.ts.map +1 -0
- package/dist/providers/search/serper.js +87 -0
- package/dist/providers/search/serper.js.map +1 -0
- package/dist/providers/search/types.d.ts +21 -0
- package/dist/providers/search/types.d.ts.map +1 -0
- package/dist/providers/search/types.js +5 -0
- package/dist/providers/search/types.js.map +1 -0
- package/dist/providers/store.d.ts +104 -0
- package/dist/providers/store.d.ts.map +1 -0
- package/dist/providers/store.js +171 -0
- package/dist/providers/store.js.map +1 -0
- package/dist/providers/types.d.ts +7 -1
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/vertex-ai.d.ts +33 -0
- package/dist/providers/vertex-ai.d.ts.map +1 -0
- package/dist/providers/vertex-ai.js +407 -0
- package/dist/providers/vertex-ai.js.map +1 -0
- package/dist/tools/builtin/webfetch.d.ts +20 -0
- package/dist/tools/builtin/webfetch.d.ts.map +1 -0
- package/dist/tools/builtin/webfetch.js +231 -0
- package/dist/tools/builtin/webfetch.js.map +1 -0
- package/dist/tools/builtin/websearch.d.ts +17 -0
- package/dist/tools/builtin/websearch.d.ts.map +1 -0
- package/dist/tools/builtin/websearch.js +101 -0
- package/dist/tools/builtin/websearch.js.map +1 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +24 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/types.d.ts +19 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js +8 -0
- package/dist/tools/types.js.map +1 -1
- package/dist/tools/utils/ssrf.d.ts +18 -0
- package/dist/tools/utils/ssrf.d.ts.map +1 -0
- package/dist/tools/utils/ssrf.js +70 -0
- package/dist/tools/utils/ssrf.js.map +1 -0
- package/docs/README.md +5 -4
- package/docs/proposals/0001-web-fetch-tool.md +32 -2
- package/docs/proposals/0002-web-search-tool.md +59 -2
- package/docs/proposals/0041-configuration-system.md +556 -0
- package/docs/proposals/README.md +3 -2
- package/docs/providers.md +220 -0
- package/package.json +7 -2
- package/src/agent/agent.ts +9 -2
- package/src/agent/types.ts +9 -1
- package/src/cli/components/App.tsx +72 -23
- package/src/cli/components/CommandSuggestions.tsx +1 -0
- package/src/cli/components/Messages.tsx +117 -29
- package/src/cli/components/ModelSelector.tsx +169 -52
- package/src/cli/components/ProviderManager.tsx +534 -0
- package/src/cli/components/markdown.ts +157 -0
- package/src/cli/components/theme.ts +7 -0
- package/src/cli/index.tsx +22 -7
- package/src/config/index.ts +3 -2
- package/src/config/providers-config.ts +85 -0
- package/src/config/types.ts +35 -1
- package/src/providers/gemini.ts +20 -4
- package/src/providers/index.ts +18 -3
- package/src/providers/registry.ts +198 -0
- package/src/providers/search/brave.ts +132 -0
- package/src/providers/search/exa.ts +217 -0
- package/src/providers/search/index.ts +79 -0
- package/src/providers/search/serper.ts +133 -0
- package/src/providers/search/types.ts +24 -0
- package/src/providers/store.ts +216 -0
- package/src/providers/types.ts +9 -1
- package/src/providers/vertex-ai.ts +594 -0
- package/src/tools/builtin/webfetch.ts +264 -0
- package/src/tools/builtin/websearch.ts +117 -0
- package/src/tools/index.ts +24 -2
- package/src/tools/types.ts +20 -0
- package/src/tools/utils/ssrf.ts +79 -0
- package/CLAUDE.md +0 -70
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider Store - Manages provider connections and model cache
|
|
3
|
+
*
|
|
4
|
+
* Storage location: ~/.gencode/providers.json
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
import { homedir } from 'os';
|
|
9
|
+
const CONFIG_DIR = join(homedir(), '.gencode');
|
|
10
|
+
const CONFIG_FILE = join(CONFIG_DIR, 'providers.json');
|
|
11
|
+
/**
|
|
12
|
+
* Provider Store - manages connection state and model cache
|
|
13
|
+
*/
|
|
14
|
+
export class ProviderStore {
|
|
15
|
+
config;
|
|
16
|
+
constructor() {
|
|
17
|
+
this.config = this.load();
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Load configuration from disk
|
|
21
|
+
*/
|
|
22
|
+
load() {
|
|
23
|
+
try {
|
|
24
|
+
if (existsSync(CONFIG_FILE)) {
|
|
25
|
+
const data = readFileSync(CONFIG_FILE, 'utf-8');
|
|
26
|
+
return JSON.parse(data);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// Ignore parse errors, start fresh
|
|
31
|
+
}
|
|
32
|
+
return { connections: {}, models: {} };
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Save configuration to disk
|
|
36
|
+
*/
|
|
37
|
+
save() {
|
|
38
|
+
try {
|
|
39
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
40
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
41
|
+
}
|
|
42
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(this.config, null, 2));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Silently fail if we can't write
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Check if a provider is connected
|
|
50
|
+
*/
|
|
51
|
+
isConnected(providerId) {
|
|
52
|
+
return !!this.config.connections[providerId];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get connection info for a provider
|
|
56
|
+
*/
|
|
57
|
+
getConnection(providerId) {
|
|
58
|
+
return this.config.connections[providerId];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get all connected provider IDs
|
|
62
|
+
*/
|
|
63
|
+
getConnectedProviders() {
|
|
64
|
+
return Object.keys(this.config.connections);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Connect a provider
|
|
68
|
+
*/
|
|
69
|
+
connect(providerId, method) {
|
|
70
|
+
this.config.connections[providerId] = {
|
|
71
|
+
method,
|
|
72
|
+
connectedAt: new Date().toISOString(),
|
|
73
|
+
};
|
|
74
|
+
this.save();
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Disconnect a provider
|
|
78
|
+
*/
|
|
79
|
+
disconnect(providerId) {
|
|
80
|
+
delete this.config.connections[providerId];
|
|
81
|
+
delete this.config.models[providerId];
|
|
82
|
+
this.save();
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get cached models for a provider
|
|
86
|
+
*/
|
|
87
|
+
getModels(providerId) {
|
|
88
|
+
return this.config.models[providerId]?.list ?? [];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get all cached models grouped by provider
|
|
92
|
+
*/
|
|
93
|
+
getAllModels() {
|
|
94
|
+
const result = {};
|
|
95
|
+
for (const [providerId, cache] of Object.entries(this.config.models)) {
|
|
96
|
+
result[providerId] = cache.list;
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Cache models for a provider
|
|
102
|
+
*/
|
|
103
|
+
cacheModels(providerId, models) {
|
|
104
|
+
this.config.models[providerId] = {
|
|
105
|
+
cachedAt: new Date().toISOString(),
|
|
106
|
+
list: models,
|
|
107
|
+
};
|
|
108
|
+
this.save();
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get cache timestamp for a provider
|
|
112
|
+
*/
|
|
113
|
+
getCacheTime(providerId) {
|
|
114
|
+
const cache = this.config.models[providerId];
|
|
115
|
+
return cache ? new Date(cache.cachedAt) : undefined;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Check if model cache is stale (older than 24 hours)
|
|
119
|
+
*/
|
|
120
|
+
isCacheStale(providerId) {
|
|
121
|
+
const cacheTime = this.getCacheTime(providerId);
|
|
122
|
+
if (!cacheTime)
|
|
123
|
+
return true;
|
|
124
|
+
const hoursSinceCache = (Date.now() - cacheTime.getTime()) / (1000 * 60 * 60);
|
|
125
|
+
return hoursSinceCache > 24;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get total model count across all connected providers
|
|
129
|
+
*/
|
|
130
|
+
getTotalModelCount() {
|
|
131
|
+
return Object.values(this.config.models).reduce((sum, cache) => sum + cache.list.length, 0);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get model count for a specific provider
|
|
135
|
+
*/
|
|
136
|
+
getModelCount(providerId) {
|
|
137
|
+
return this.config.models[providerId]?.list.length ?? 0;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get the configured search provider
|
|
141
|
+
*/
|
|
142
|
+
getSearchProvider() {
|
|
143
|
+
return this.config.searchProvider;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Set the search provider
|
|
147
|
+
*/
|
|
148
|
+
setSearchProvider(id) {
|
|
149
|
+
this.config.searchProvider = id;
|
|
150
|
+
this.save();
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Clear the search provider (use default)
|
|
154
|
+
*/
|
|
155
|
+
clearSearchProvider() {
|
|
156
|
+
delete this.config.searchProvider;
|
|
157
|
+
this.save();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Singleton instance
|
|
161
|
+
let storeInstance = null;
|
|
162
|
+
/**
|
|
163
|
+
* Get the singleton provider store instance
|
|
164
|
+
*/
|
|
165
|
+
export function getProviderStore() {
|
|
166
|
+
if (!storeInstance) {
|
|
167
|
+
storeInstance = new ProviderStore();
|
|
168
|
+
}
|
|
169
|
+
return storeInstance;
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/providers/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ export interface ToolUseContent {
|
|
|
12
12
|
id: string;
|
|
13
13
|
name: string;
|
|
14
14
|
input: Record<string, unknown>;
|
|
15
|
+
thoughtSignature?: string;
|
|
15
16
|
}
|
|
16
17
|
export interface ToolResultContent {
|
|
17
18
|
type: 'tool_result';
|
|
@@ -121,5 +122,10 @@ export interface AnthropicConfig {
|
|
|
121
122
|
export interface GeminiConfig {
|
|
122
123
|
apiKey?: string;
|
|
123
124
|
}
|
|
124
|
-
export
|
|
125
|
+
export interface VertexAIConfig {
|
|
126
|
+
projectId?: string;
|
|
127
|
+
region?: string;
|
|
128
|
+
accessToken?: string;
|
|
129
|
+
}
|
|
130
|
+
export type ProviderConfig = OpenAIConfig | AnthropicConfig | GeminiConfig | VertexAIConfig;
|
|
125
131
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google Vertex AI Provider Implementation
|
|
3
|
+
* Supports Claude models deployed on Google Cloud Vertex AI
|
|
4
|
+
*
|
|
5
|
+
* Authentication uses Google Cloud's default credential chain:
|
|
6
|
+
* 1. GOOGLE_APPLICATION_CREDENTIALS (service account JSON)
|
|
7
|
+
* 2. gcloud auth application-default login (ADC)
|
|
8
|
+
* 3. GCE/GKE metadata service (when running on GCP)
|
|
9
|
+
*/
|
|
10
|
+
import type { LLMProvider, CompletionOptions, CompletionResponse, StreamChunk, VertexAIConfig, ModelInfo } from './types.js';
|
|
11
|
+
export declare class VertexAIProvider implements LLMProvider {
|
|
12
|
+
readonly name = "vertex-ai";
|
|
13
|
+
private projectId;
|
|
14
|
+
private region;
|
|
15
|
+
private auth;
|
|
16
|
+
private accessToken?;
|
|
17
|
+
constructor(config?: VertexAIConfig);
|
|
18
|
+
private getAccessToken;
|
|
19
|
+
private getEndpoint;
|
|
20
|
+
complete(options: CompletionOptions): Promise<CompletionResponse>;
|
|
21
|
+
stream(options: CompletionOptions): AsyncGenerator<StreamChunk, void, unknown>;
|
|
22
|
+
private buildFinalContent;
|
|
23
|
+
private convertMessages;
|
|
24
|
+
private convertToVertexContent;
|
|
25
|
+
private convertTools;
|
|
26
|
+
private convertResponse;
|
|
27
|
+
private convertContent;
|
|
28
|
+
private convertStopReason;
|
|
29
|
+
listModels(): Promise<ModelInfo[]>;
|
|
30
|
+
private formatModelName;
|
|
31
|
+
private getKnownModels;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=vertex-ai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vertex-ai.d.ts","sourceRoot":"","sources":["../../src/providers/vertex-ai.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EAKX,cAAc,EACd,SAAS,EACV,MAAM,YAAY,CAAC;AA4GpB,qBAAa,gBAAiB,YAAW,WAAW;IAClD,QAAQ,CAAC,IAAI,eAAe;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,WAAW,CAAC,CAAS;gBAEjB,MAAM,GAAE,cAAmB;YA0BzB,cAAc;IAa5B,OAAO,CAAC,WAAW;IAKb,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAkChE,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC;IAyIrF,OAAO,CAAC,iBAAiB;IAqCzB,OAAO,CAAC,eAAe;IAqBvB,OAAO,CAAC,sBAAsB;IAiC9B,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,cAAc;IAyBtB,OAAO,CAAC,iBAAiB;IAcnB,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IA0DxC,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,cAAc;CAoBvB"}
|
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google Vertex AI Provider Implementation
|
|
3
|
+
* Supports Claude models deployed on Google Cloud Vertex AI
|
|
4
|
+
*
|
|
5
|
+
* Authentication uses Google Cloud's default credential chain:
|
|
6
|
+
* 1. GOOGLE_APPLICATION_CREDENTIALS (service account JSON)
|
|
7
|
+
* 2. gcloud auth application-default login (ADC)
|
|
8
|
+
* 3. GCE/GKE metadata service (when running on GCP)
|
|
9
|
+
*/
|
|
10
|
+
import { GoogleAuth } from 'google-auth-library';
|
|
11
|
+
export class VertexAIProvider {
|
|
12
|
+
name = 'vertex-ai';
|
|
13
|
+
projectId;
|
|
14
|
+
region;
|
|
15
|
+
auth;
|
|
16
|
+
accessToken;
|
|
17
|
+
constructor(config = {}) {
|
|
18
|
+
this.projectId =
|
|
19
|
+
config.projectId ??
|
|
20
|
+
process.env.ANTHROPIC_VERTEX_PROJECT_ID ??
|
|
21
|
+
process.env.GOOGLE_CLOUD_PROJECT ??
|
|
22
|
+
'';
|
|
23
|
+
this.region =
|
|
24
|
+
config.region ??
|
|
25
|
+
process.env.ANTHROPIC_VERTEX_REGION ??
|
|
26
|
+
process.env.CLOUD_ML_REGION ??
|
|
27
|
+
'us-east5';
|
|
28
|
+
this.accessToken = config.accessToken;
|
|
29
|
+
if (!this.projectId) {
|
|
30
|
+
throw new Error('Vertex AI requires a project ID. Set ANTHROPIC_VERTEX_PROJECT_ID environment variable.');
|
|
31
|
+
}
|
|
32
|
+
this.auth = new GoogleAuth({
|
|
33
|
+
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
async getAccessToken() {
|
|
37
|
+
if (this.accessToken) {
|
|
38
|
+
return this.accessToken;
|
|
39
|
+
}
|
|
40
|
+
const client = await this.auth.getClient();
|
|
41
|
+
const tokenResponse = await client.getAccessToken();
|
|
42
|
+
if (!tokenResponse.token) {
|
|
43
|
+
throw new Error('Failed to get access token from Google Cloud');
|
|
44
|
+
}
|
|
45
|
+
return tokenResponse.token;
|
|
46
|
+
}
|
|
47
|
+
getEndpoint(model, stream = false) {
|
|
48
|
+
const method = stream ? 'streamRawPredict' : 'rawPredict';
|
|
49
|
+
return `https://${this.region}-aiplatform.googleapis.com/v1/projects/${this.projectId}/locations/${this.region}/publishers/anthropic/models/${model}:${method}`;
|
|
50
|
+
}
|
|
51
|
+
async complete(options) {
|
|
52
|
+
const messages = this.convertMessages(options.messages);
|
|
53
|
+
const tools = options.tools ? this.convertTools(options.tools) : undefined;
|
|
54
|
+
const requestBody = {
|
|
55
|
+
anthropic_version: 'vertex-2023-10-16',
|
|
56
|
+
max_tokens: options.maxTokens ?? 4096,
|
|
57
|
+
messages,
|
|
58
|
+
system: options.systemPrompt,
|
|
59
|
+
tools,
|
|
60
|
+
temperature: options.temperature,
|
|
61
|
+
};
|
|
62
|
+
const accessToken = await this.getAccessToken();
|
|
63
|
+
const endpoint = this.getEndpoint(options.model, false);
|
|
64
|
+
const response = await fetch(endpoint, {
|
|
65
|
+
method: 'POST',
|
|
66
|
+
headers: {
|
|
67
|
+
Authorization: `Bearer ${accessToken}`,
|
|
68
|
+
'Content-Type': 'application/json',
|
|
69
|
+
},
|
|
70
|
+
body: JSON.stringify(requestBody),
|
|
71
|
+
});
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
const errorText = await response.text();
|
|
74
|
+
throw new Error(`Vertex AI API error: ${response.status} ${errorText}`);
|
|
75
|
+
}
|
|
76
|
+
const data = (await response.json());
|
|
77
|
+
return this.convertResponse(data);
|
|
78
|
+
}
|
|
79
|
+
async *stream(options) {
|
|
80
|
+
const messages = this.convertMessages(options.messages);
|
|
81
|
+
const tools = options.tools ? this.convertTools(options.tools) : undefined;
|
|
82
|
+
const requestBody = {
|
|
83
|
+
anthropic_version: 'vertex-2023-10-16',
|
|
84
|
+
max_tokens: options.maxTokens ?? 4096,
|
|
85
|
+
messages,
|
|
86
|
+
system: options.systemPrompt,
|
|
87
|
+
tools,
|
|
88
|
+
temperature: options.temperature,
|
|
89
|
+
stream: true,
|
|
90
|
+
};
|
|
91
|
+
const accessToken = await this.getAccessToken();
|
|
92
|
+
const endpoint = this.getEndpoint(options.model, true);
|
|
93
|
+
const response = await fetch(endpoint, {
|
|
94
|
+
method: 'POST',
|
|
95
|
+
headers: {
|
|
96
|
+
Authorization: `Bearer ${accessToken}`,
|
|
97
|
+
'Content-Type': 'application/json',
|
|
98
|
+
},
|
|
99
|
+
body: JSON.stringify(requestBody),
|
|
100
|
+
});
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
const errorText = await response.text();
|
|
103
|
+
throw new Error(`Vertex AI API error: ${response.status} ${errorText}`);
|
|
104
|
+
}
|
|
105
|
+
if (!response.body) {
|
|
106
|
+
throw new Error('No response body from Vertex AI');
|
|
107
|
+
}
|
|
108
|
+
const toolInputBuffers = new Map();
|
|
109
|
+
const contentBlocks = new Map();
|
|
110
|
+
let inputTokens = 0;
|
|
111
|
+
let outputTokens = 0;
|
|
112
|
+
let stopReason = 'end_turn';
|
|
113
|
+
// Parse SSE stream
|
|
114
|
+
const reader = response.body.getReader();
|
|
115
|
+
const decoder = new TextDecoder();
|
|
116
|
+
let buffer = '';
|
|
117
|
+
try {
|
|
118
|
+
while (true) {
|
|
119
|
+
const { done, value } = await reader.read();
|
|
120
|
+
if (done)
|
|
121
|
+
break;
|
|
122
|
+
buffer += decoder.decode(value, { stream: true });
|
|
123
|
+
// Process complete SSE events
|
|
124
|
+
const lines = buffer.split('\n');
|
|
125
|
+
buffer = lines.pop() ?? '';
|
|
126
|
+
for (const line of lines) {
|
|
127
|
+
if (line.startsWith('data: ')) {
|
|
128
|
+
const jsonStr = line.slice(6).trim();
|
|
129
|
+
if (!jsonStr || jsonStr === '[DONE]')
|
|
130
|
+
continue;
|
|
131
|
+
try {
|
|
132
|
+
const event = JSON.parse(jsonStr);
|
|
133
|
+
if (event.type === 'message_start') {
|
|
134
|
+
inputTokens = event.message.usage.input_tokens;
|
|
135
|
+
}
|
|
136
|
+
else if (event.type === 'content_block_start') {
|
|
137
|
+
const block = event.content_block;
|
|
138
|
+
if (block.type === 'tool_use' && block.id && block.name) {
|
|
139
|
+
toolInputBuffers.set(event.index, {
|
|
140
|
+
id: block.id,
|
|
141
|
+
name: block.name,
|
|
142
|
+
input: '',
|
|
143
|
+
});
|
|
144
|
+
contentBlocks.set(event.index, {
|
|
145
|
+
type: 'tool_use',
|
|
146
|
+
id: block.id,
|
|
147
|
+
name: block.name,
|
|
148
|
+
input: '',
|
|
149
|
+
});
|
|
150
|
+
yield { type: 'tool_start', id: block.id, name: block.name };
|
|
151
|
+
}
|
|
152
|
+
else if (block.type === 'text') {
|
|
153
|
+
contentBlocks.set(event.index, { type: 'text', text: '' });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else if (event.type === 'content_block_delta') {
|
|
157
|
+
const delta = event.delta;
|
|
158
|
+
if (delta.type === 'text_delta' && delta.text) {
|
|
159
|
+
const block = contentBlocks.get(event.index);
|
|
160
|
+
if (block && block.type === 'text') {
|
|
161
|
+
block.text = (block.text ?? '') + delta.text;
|
|
162
|
+
}
|
|
163
|
+
yield { type: 'text', text: delta.text };
|
|
164
|
+
}
|
|
165
|
+
else if (delta.type === 'input_json_delta' && delta.partial_json) {
|
|
166
|
+
const toolBuffer = toolInputBuffers.get(event.index);
|
|
167
|
+
if (toolBuffer) {
|
|
168
|
+
toolBuffer.input += delta.partial_json;
|
|
169
|
+
const block = contentBlocks.get(event.index);
|
|
170
|
+
if (block && block.type === 'tool_use') {
|
|
171
|
+
block.input = toolBuffer.input;
|
|
172
|
+
}
|
|
173
|
+
yield { type: 'tool_input', id: toolBuffer.id, input: delta.partial_json };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else if (event.type === 'message_delta') {
|
|
178
|
+
stopReason = this.convertStopReason(event.delta.stop_reason);
|
|
179
|
+
outputTokens = event.usage.output_tokens;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// Skip malformed JSON
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
finally {
|
|
190
|
+
reader.releaseLock();
|
|
191
|
+
}
|
|
192
|
+
// Build final response
|
|
193
|
+
const content = this.buildFinalContent(contentBlocks, toolInputBuffers);
|
|
194
|
+
yield {
|
|
195
|
+
type: 'done',
|
|
196
|
+
response: {
|
|
197
|
+
content,
|
|
198
|
+
stopReason,
|
|
199
|
+
usage: {
|
|
200
|
+
inputTokens,
|
|
201
|
+
outputTokens,
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
buildFinalContent(contentBlocks, toolInputBuffers) {
|
|
207
|
+
const result = [];
|
|
208
|
+
const sortedIndices = Array.from(contentBlocks.keys()).sort((a, b) => a - b);
|
|
209
|
+
for (const index of sortedIndices) {
|
|
210
|
+
const block = contentBlocks.get(index);
|
|
211
|
+
if (!block)
|
|
212
|
+
continue;
|
|
213
|
+
if (block.type === 'text' && block.text) {
|
|
214
|
+
result.push({ type: 'text', text: block.text });
|
|
215
|
+
}
|
|
216
|
+
else if (block.type === 'tool_use' && block.id && block.name) {
|
|
217
|
+
const toolBuffer = toolInputBuffers.get(index);
|
|
218
|
+
let input = {};
|
|
219
|
+
try {
|
|
220
|
+
input = JSON.parse(toolBuffer?.input ?? '{}');
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// Use empty object if parsing fails
|
|
224
|
+
}
|
|
225
|
+
result.push({
|
|
226
|
+
type: 'tool_use',
|
|
227
|
+
id: block.id,
|
|
228
|
+
name: block.name,
|
|
229
|
+
input,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return result;
|
|
234
|
+
}
|
|
235
|
+
convertMessages(messages) {
|
|
236
|
+
const result = [];
|
|
237
|
+
for (const msg of messages) {
|
|
238
|
+
// Skip system messages - handled separately
|
|
239
|
+
if (msg.role === 'system') {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (msg.role === 'user') {
|
|
243
|
+
const content = this.convertToVertexContent(msg.content, 'user');
|
|
244
|
+
result.push({ role: 'user', content });
|
|
245
|
+
}
|
|
246
|
+
else if (msg.role === 'assistant') {
|
|
247
|
+
const content = this.convertToVertexContent(msg.content, 'assistant');
|
|
248
|
+
result.push({ role: 'assistant', content });
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return result;
|
|
252
|
+
}
|
|
253
|
+
convertToVertexContent(content, role) {
|
|
254
|
+
if (typeof content === 'string') {
|
|
255
|
+
return content;
|
|
256
|
+
}
|
|
257
|
+
const result = [];
|
|
258
|
+
for (const item of content) {
|
|
259
|
+
if (item.type === 'text') {
|
|
260
|
+
result.push({ type: 'text', text: item.text });
|
|
261
|
+
}
|
|
262
|
+
else if (item.type === 'tool_use' && role === 'assistant') {
|
|
263
|
+
result.push({
|
|
264
|
+
type: 'tool_use',
|
|
265
|
+
id: item.id,
|
|
266
|
+
name: item.name,
|
|
267
|
+
input: item.input,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
else if (item.type === 'tool_result' && role === 'user') {
|
|
271
|
+
result.push({
|
|
272
|
+
type: 'tool_result',
|
|
273
|
+
tool_use_id: item.toolUseId,
|
|
274
|
+
content: item.content,
|
|
275
|
+
is_error: item.isError,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return result.length > 0 ? result : '';
|
|
280
|
+
}
|
|
281
|
+
convertTools(tools) {
|
|
282
|
+
return tools.map((tool) => ({
|
|
283
|
+
name: tool.name,
|
|
284
|
+
description: tool.description,
|
|
285
|
+
input_schema: tool.parameters,
|
|
286
|
+
}));
|
|
287
|
+
}
|
|
288
|
+
convertResponse(response) {
|
|
289
|
+
return {
|
|
290
|
+
content: this.convertContent(response.content),
|
|
291
|
+
stopReason: this.convertStopReason(response.stop_reason),
|
|
292
|
+
usage: {
|
|
293
|
+
inputTokens: response.usage.input_tokens,
|
|
294
|
+
outputTokens: response.usage.output_tokens,
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
convertContent(content) {
|
|
299
|
+
return content.map((block) => {
|
|
300
|
+
if (block.type === 'text') {
|
|
301
|
+
return { type: 'text', text: block.text ?? '' };
|
|
302
|
+
}
|
|
303
|
+
else if (block.type === 'tool_use') {
|
|
304
|
+
return {
|
|
305
|
+
type: 'tool_use',
|
|
306
|
+
id: block.id ?? '',
|
|
307
|
+
name: block.name ?? '',
|
|
308
|
+
input: block.input ?? {},
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
// Fallback for unknown types
|
|
312
|
+
return { type: 'text', text: '' };
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
convertStopReason(reason) {
|
|
316
|
+
switch (reason) {
|
|
317
|
+
case 'tool_use':
|
|
318
|
+
return 'tool_use';
|
|
319
|
+
case 'max_tokens':
|
|
320
|
+
return 'max_tokens';
|
|
321
|
+
case 'stop_sequence':
|
|
322
|
+
return 'stop_sequence';
|
|
323
|
+
case 'end_turn':
|
|
324
|
+
default:
|
|
325
|
+
return 'end_turn';
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
async listModels() {
|
|
329
|
+
// Use Vertex AI Model Garden API to list Anthropic publisher models
|
|
330
|
+
// API: GET https://{region}-aiplatform.googleapis.com/v1beta1/publishers/anthropic/models
|
|
331
|
+
const accessToken = await this.getAccessToken();
|
|
332
|
+
const endpoint = `https://${this.region}-aiplatform.googleapis.com/v1beta1/publishers/anthropic/models`;
|
|
333
|
+
try {
|
|
334
|
+
const response = await fetch(endpoint, {
|
|
335
|
+
method: 'GET',
|
|
336
|
+
headers: {
|
|
337
|
+
Authorization: `Bearer ${accessToken}`,
|
|
338
|
+
'Content-Type': 'application/json',
|
|
339
|
+
},
|
|
340
|
+
});
|
|
341
|
+
if (!response.ok) {
|
|
342
|
+
// Fall back to known models if API fails
|
|
343
|
+
return this.getKnownModels();
|
|
344
|
+
}
|
|
345
|
+
const data = (await response.json());
|
|
346
|
+
if (!data.publisherModels || data.publisherModels.length === 0) {
|
|
347
|
+
return this.getKnownModels();
|
|
348
|
+
}
|
|
349
|
+
const models = [];
|
|
350
|
+
for (const model of data.publisherModels) {
|
|
351
|
+
// Extract model ID from name (e.g., "publishers/anthropic/models/claude-3-5-sonnet")
|
|
352
|
+
const modelName = model.name ?? '';
|
|
353
|
+
const modelId = modelName.split('/').pop() ?? '';
|
|
354
|
+
if (modelId && modelId.includes('claude')) {
|
|
355
|
+
// Add version suffix if available
|
|
356
|
+
const versionedId = model.versionId ? `${modelId}@${model.versionId}` : modelId;
|
|
357
|
+
models.push({
|
|
358
|
+
id: versionedId,
|
|
359
|
+
name: this.formatModelName(modelId),
|
|
360
|
+
description: `Claude model on Vertex AI`,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return models.length > 0 ? models : this.getKnownModels();
|
|
365
|
+
}
|
|
366
|
+
catch {
|
|
367
|
+
// Fall back to known models on error
|
|
368
|
+
return this.getKnownModels();
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
formatModelName(modelId) {
|
|
372
|
+
// Convert model ID to human-readable name
|
|
373
|
+
// e.g., "claude-3-5-sonnet" -> "Claude 3.5 Sonnet"
|
|
374
|
+
return modelId
|
|
375
|
+
.split('-')
|
|
376
|
+
.map((part) => {
|
|
377
|
+
if (part === 'claude')
|
|
378
|
+
return 'Claude';
|
|
379
|
+
if (/^\d+$/.test(part))
|
|
380
|
+
return part;
|
|
381
|
+
return part.charAt(0).toUpperCase() + part.slice(1);
|
|
382
|
+
})
|
|
383
|
+
.join(' ')
|
|
384
|
+
.replace(/(\d) (\d)/g, '$1.$2'); // "3 5" -> "3.5"
|
|
385
|
+
}
|
|
386
|
+
getKnownModels() {
|
|
387
|
+
// Fallback known models when API is unavailable
|
|
388
|
+
return [
|
|
389
|
+
{
|
|
390
|
+
id: 'claude-sonnet-4-5@20250929',
|
|
391
|
+
name: 'Claude Sonnet 4.5',
|
|
392
|
+
description: 'Latest Claude Sonnet model on Vertex AI',
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
id: 'claude-haiku-4-5@20251001',
|
|
396
|
+
name: 'Claude Haiku 4.5',
|
|
397
|
+
description: 'Fast and efficient Claude model',
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
id: 'claude-opus-4-1@20250805',
|
|
401
|
+
name: 'Claude Opus 4.1',
|
|
402
|
+
description: 'Most capable Claude model',
|
|
403
|
+
},
|
|
404
|
+
];
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
//# sourceMappingURL=vertex-ai.js.map
|