geminimock 0.1.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 (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +66 -0
  3. package/dist/auth/credential-store.d.ts +17 -0
  4. package/dist/auth/credential-store.js +44 -0
  5. package/dist/auth/credential-store.js.map +1 -0
  6. package/dist/auth/oauth-flow.d.ts +26 -0
  7. package/dist/auth/oauth-flow.js +87 -0
  8. package/dist/auth/oauth-flow.js.map +1 -0
  9. package/dist/auth/oauth-service.d.ts +18 -0
  10. package/dist/auth/oauth-service.js +287 -0
  11. package/dist/auth/oauth-service.js.map +1 -0
  12. package/dist/cli.d.ts +2 -0
  13. package/dist/cli.js +76 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/config/env.d.ts +11 -0
  16. package/dist/config/env.js +28 -0
  17. package/dist/config/env.js.map +1 -0
  18. package/dist/gemini/code-assist-client.d.ts +17 -0
  19. package/dist/gemini/code-assist-client.js +179 -0
  20. package/dist/gemini/code-assist-client.js.map +1 -0
  21. package/dist/gemini/model-catalog-service.d.ts +8 -0
  22. package/dist/gemini/model-catalog-service.js +31 -0
  23. package/dist/gemini/model-catalog-service.js.map +1 -0
  24. package/dist/gemini/types.d.ts +82 -0
  25. package/dist/gemini/types.js +2 -0
  26. package/dist/gemini/types.js.map +1 -0
  27. package/dist/openai/chat-service.d.ts +12 -0
  28. package/dist/openai/chat-service.js +82 -0
  29. package/dist/openai/chat-service.js.map +1 -0
  30. package/dist/openai/mapper.d.ts +7 -0
  31. package/dist/openai/mapper.js +86 -0
  32. package/dist/openai/mapper.js.map +1 -0
  33. package/dist/openai/model-resolver.d.ts +2 -0
  34. package/dist/openai/model-resolver.js +52 -0
  35. package/dist/openai/model-resolver.js.map +1 -0
  36. package/dist/openai/models-response.d.ts +10 -0
  37. package/dist/openai/models-response.js +12 -0
  38. package/dist/openai/models-response.js.map +1 -0
  39. package/dist/openai/types.d.ts +56 -0
  40. package/dist/openai/types.js +19 -0
  41. package/dist/openai/types.js.map +1 -0
  42. package/dist/server/app.d.ts +17 -0
  43. package/dist/server/app.js +91 -0
  44. package/dist/server/app.js.map +1 -0
  45. package/package.json +45 -0
package/dist/cli.js ADDED
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ import { createCredentialStore } from "./auth/credential-store.js";
3
+ import { OAuthService } from "./auth/oauth-service.js";
4
+ import { loadEnv } from "./config/env.js";
5
+ import { CodeAssistClient } from "./gemini/code-assist-client.js";
6
+ import { ModelCatalogService } from "./gemini/model-catalog-service.js";
7
+ import { createApp } from "./server/app.js";
8
+ function usage() {
9
+ process.stdout.write([
10
+ "Usage:",
11
+ " geminimock serve",
12
+ " geminimock auth login",
13
+ " geminimock auth logout",
14
+ " geminimock models list"
15
+ ].join("\n") + "\n");
16
+ }
17
+ async function runAuthLogin() {
18
+ const env = loadEnv();
19
+ const store = createCredentialStore(env.oauthPath, env.oauthFallbackPath);
20
+ const oauthService = new OAuthService(store);
21
+ const result = await oauthService.login();
22
+ process.stdout.write(`OAuth login succeeded${result.email ? `: ${result.email}` : ""}\n`);
23
+ }
24
+ async function runAuthLogout() {
25
+ const env = loadEnv();
26
+ const store = createCredentialStore(env.oauthPath, env.oauthFallbackPath);
27
+ const oauthService = new OAuthService(store);
28
+ await oauthService.logout();
29
+ process.stdout.write("OAuth credentials cleared\n");
30
+ }
31
+ async function runServe() {
32
+ const env = loadEnv();
33
+ const app = await createApp({ env });
34
+ await app.listen({ host: env.host, port: env.port });
35
+ process.stdout.write(`Server listening on http://${env.host}:${env.port}\n`);
36
+ }
37
+ async function runModelsList() {
38
+ const env = loadEnv();
39
+ const store = createCredentialStore(env.oauthPath, env.oauthFallbackPath);
40
+ const oauthService = new OAuthService(store);
41
+ const client = new CodeAssistClient(env, () => oauthService.getAccessToken());
42
+ const catalog = new ModelCatalogService(client);
43
+ const models = await catalog.listModels(true);
44
+ if (models.length === 0) {
45
+ process.stdout.write("No models available\n");
46
+ return;
47
+ }
48
+ process.stdout.write(`${models.join("\n")}\n`);
49
+ }
50
+ async function main() {
51
+ const args = process.argv.slice(2);
52
+ if (args[0] === "serve") {
53
+ await runServe();
54
+ return;
55
+ }
56
+ if (args[0] === "auth" && args[1] === "login") {
57
+ await runAuthLogin();
58
+ return;
59
+ }
60
+ if (args[0] === "auth" && args[1] === "logout") {
61
+ await runAuthLogout();
62
+ return;
63
+ }
64
+ if (args[0] === "models" && args[1] === "list") {
65
+ await runModelsList();
66
+ return;
67
+ }
68
+ usage();
69
+ process.exitCode = 1;
70
+ }
71
+ main().catch((error) => {
72
+ const message = error instanceof Error ? error.message : String(error);
73
+ process.stderr.write(`${message}\n`);
74
+ process.exit(1);
75
+ });
76
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export type AppEnv = {
2
+ host: string;
3
+ port: number;
4
+ defaultModel: string;
5
+ codeAssistEndpoint: string;
6
+ codeAssistApiVersion: string;
7
+ oauthPath: string;
8
+ oauthFallbackPath: string;
9
+ projectId?: string;
10
+ };
11
+ export declare function loadEnv(source?: NodeJS.ProcessEnv | Record<string, string | undefined>): AppEnv;
@@ -0,0 +1,28 @@
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+ import { z } from "zod";
4
+ const schema = z.object({
5
+ GEMINI_CLI_API_HOST: z.string().default("127.0.0.1"),
6
+ GEMINI_CLI_API_PORT: z.coerce.number().int().min(1).max(65535).default(8080),
7
+ GEMINI_CLI_MODEL: z.string().default("gemini-2.5-pro"),
8
+ CODE_ASSIST_ENDPOINT: z.string().url().default("https://cloudcode-pa.googleapis.com"),
9
+ CODE_ASSIST_API_VERSION: z.string().default("v1internal"),
10
+ GEMINI_CLI_API_OAUTH_PATH: z.string().default(join(homedir(), ".geminimock", "oauth_creds.json")),
11
+ GEMINI_CLI_OAUTH_FALLBACK_PATH: z.string().default(join(homedir(), ".gemini", "oauth_creds.json")),
12
+ GOOGLE_CLOUD_PROJECT: z.string().optional(),
13
+ GOOGLE_CLOUD_PROJECT_ID: z.string().optional()
14
+ });
15
+ export function loadEnv(source = process.env) {
16
+ const parsed = schema.parse(source);
17
+ return {
18
+ host: parsed.GEMINI_CLI_API_HOST,
19
+ port: parsed.GEMINI_CLI_API_PORT,
20
+ defaultModel: parsed.GEMINI_CLI_MODEL,
21
+ codeAssistEndpoint: parsed.CODE_ASSIST_ENDPOINT,
22
+ codeAssistApiVersion: parsed.CODE_ASSIST_API_VERSION,
23
+ oauthPath: parsed.GEMINI_CLI_API_OAUTH_PATH,
24
+ oauthFallbackPath: parsed.GEMINI_CLI_OAUTH_FALLBACK_PATH,
25
+ projectId: parsed.GOOGLE_CLOUD_PROJECT ?? parsed.GOOGLE_CLOUD_PROJECT_ID
26
+ };
27
+ }
28
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC;IACpD,mBAAmB,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IAC5E,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC;IACtD,oBAAoB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,qCAAqC,CAAC;IACrF,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC;IACzD,yBAAyB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,kBAAkB,CAAC,CAAC;IACjG,8BAA8B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAClG,oBAAoB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3C,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC/C,CAAC,CAAC;AAaH,MAAM,UAAU,OAAO,CAAC,SAAiE,OAAO,CAAC,GAAG;IAClG,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,mBAAmB;QAChC,IAAI,EAAE,MAAM,CAAC,mBAAmB;QAChC,YAAY,EAAE,MAAM,CAAC,gBAAgB;QACrC,kBAAkB,EAAE,MAAM,CAAC,oBAAoB;QAC/C,oBAAoB,EAAE,MAAM,CAAC,uBAAuB;QACpD,SAAS,EAAE,MAAM,CAAC,yBAAyB;QAC3C,iBAAiB,EAAE,MAAM,CAAC,8BAA8B;QACxD,SAAS,EAAE,MAAM,CAAC,oBAAoB,IAAI,MAAM,CAAC,uBAAuB;KACzE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { AppEnv } from "../config/env.js";
2
+ import type { CAGenerateContentRequest, CaGenerateContentResponse, LoadCodeAssistResponse, LongRunningOperationResponse, OnboardUserRequest, RetrieveUserQuotaResponse } from "./types.js";
3
+ export declare class CodeAssistClient {
4
+ private readonly env;
5
+ private readonly getAccessToken;
6
+ private projectCache?;
7
+ constructor(env: AppEnv, getAccessToken: () => Promise<string>);
8
+ private buildUrl;
9
+ private postJson;
10
+ loadCodeAssist(projectId?: string): Promise<LoadCodeAssistResponse>;
11
+ onboardUser(request: OnboardUserRequest): Promise<LongRunningOperationResponse>;
12
+ retrieveUserQuota(projectId: string): Promise<RetrieveUserQuotaResponse>;
13
+ getOperation(name: string): Promise<LongRunningOperationResponse>;
14
+ resolveProjectId(): Promise<string | undefined>;
15
+ generateContent(request: CAGenerateContentRequest): Promise<CaGenerateContentResponse>;
16
+ streamGenerateContent(request: CAGenerateContentRequest): AsyncGenerator<CaGenerateContentResponse>;
17
+ }
@@ -0,0 +1,179 @@
1
+ function platformToCode() {
2
+ const p = process.platform;
3
+ const a = process.arch;
4
+ if (p === "darwin" && a === "arm64")
5
+ return "DARWIN_ARM64";
6
+ if (p === "darwin")
7
+ return "DARWIN_AMD64";
8
+ if (p === "win32")
9
+ return "WINDOWS_AMD64";
10
+ if (a === "arm64")
11
+ return "LINUX_ARM64";
12
+ return "LINUX_AMD64";
13
+ }
14
+ function defaultMetadata(projectId) {
15
+ return {
16
+ ideType: "GEMINI_CLI",
17
+ platform: platformToCode(),
18
+ pluginType: "GEMINI",
19
+ duetProject: projectId
20
+ };
21
+ }
22
+ async function* parseSseStream(stream) {
23
+ const reader = stream.getReader();
24
+ const decoder = new TextDecoder();
25
+ let buffer = "";
26
+ while (true) {
27
+ const next = await reader.read();
28
+ if (next.done) {
29
+ break;
30
+ }
31
+ buffer += decoder.decode(next.value, { stream: true });
32
+ while (true) {
33
+ const separatorIndex = buffer.indexOf("\n\n");
34
+ if (separatorIndex < 0) {
35
+ break;
36
+ }
37
+ const block = buffer.slice(0, separatorIndex);
38
+ buffer = buffer.slice(separatorIndex + 2);
39
+ const dataLines = block
40
+ .split("\n")
41
+ .filter((line) => line.startsWith("data: "))
42
+ .map((line) => line.slice(6).trim())
43
+ .filter((line) => line.length > 0);
44
+ if (dataLines.length > 0) {
45
+ yield dataLines.join("\n");
46
+ }
47
+ }
48
+ }
49
+ }
50
+ export class CodeAssistClient {
51
+ env;
52
+ getAccessToken;
53
+ projectCache;
54
+ constructor(env, getAccessToken) {
55
+ this.env = env;
56
+ this.getAccessToken = getAccessToken;
57
+ }
58
+ buildUrl(method, query) {
59
+ const base = `${this.env.codeAssistEndpoint}/${this.env.codeAssistApiVersion}:${method}`;
60
+ if (!query) {
61
+ return base;
62
+ }
63
+ return `${base}?${query.toString()}`;
64
+ }
65
+ async postJson(method, body, query) {
66
+ const token = await this.getAccessToken();
67
+ const response = await fetch(this.buildUrl(method, query), {
68
+ method: "POST",
69
+ headers: {
70
+ "Content-Type": "application/json",
71
+ Authorization: `Bearer ${token}`
72
+ },
73
+ body: JSON.stringify(body)
74
+ });
75
+ if (!response.ok) {
76
+ const text = await response.text();
77
+ throw new Error(`Code Assist ${method} failed (${response.status}): ${text}`);
78
+ }
79
+ return (await response.json());
80
+ }
81
+ async loadCodeAssist(projectId) {
82
+ const request = {
83
+ cloudaicompanionProject: projectId,
84
+ metadata: defaultMetadata(projectId)
85
+ };
86
+ return this.postJson("loadCodeAssist", request);
87
+ }
88
+ async onboardUser(request) {
89
+ return this.postJson("onboardUser", request);
90
+ }
91
+ async retrieveUserQuota(projectId) {
92
+ return this.postJson("retrieveUserQuota", { project: projectId });
93
+ }
94
+ async getOperation(name) {
95
+ const token = await this.getAccessToken();
96
+ const response = await fetch(`${this.env.codeAssistEndpoint}/${this.env.codeAssistApiVersion}/${name}`, {
97
+ method: "GET",
98
+ headers: {
99
+ Authorization: `Bearer ${token}`
100
+ }
101
+ });
102
+ if (!response.ok) {
103
+ const text = await response.text();
104
+ throw new Error(`Code Assist operation failed (${response.status}): ${text}`);
105
+ }
106
+ return (await response.json());
107
+ }
108
+ async resolveProjectId() {
109
+ if (this.projectCache) {
110
+ return this.projectCache;
111
+ }
112
+ const initialProject = this.env.projectId;
113
+ const loaded = await this.loadCodeAssist(initialProject);
114
+ if (loaded.cloudaicompanionProject) {
115
+ this.projectCache = loaded.cloudaicompanionProject;
116
+ return this.projectCache;
117
+ }
118
+ if (initialProject && loaded.currentTier) {
119
+ this.projectCache = initialProject;
120
+ return this.projectCache;
121
+ }
122
+ const tier = loaded.allowedTiers?.find((item) => item.isDefault) ?? loaded.allowedTiers?.[0];
123
+ const onboard = await this.onboardUser({
124
+ tierId: tier?.id,
125
+ cloudaicompanionProject: tier?.id === "free-tier" ? undefined : initialProject,
126
+ metadata: defaultMetadata(initialProject)
127
+ });
128
+ if (onboard.done && onboard.response?.cloudaicompanionProject?.id) {
129
+ this.projectCache = onboard.response.cloudaicompanionProject.id;
130
+ return this.projectCache;
131
+ }
132
+ if (onboard.name && !onboard.done) {
133
+ let poll = onboard;
134
+ for (let i = 0; i < 12; i += 1) {
135
+ await new Promise((resolve) => setTimeout(resolve, 2000));
136
+ poll = await this.getOperation(onboard.name);
137
+ if (poll.done) {
138
+ if (poll.response?.cloudaicompanionProject?.id) {
139
+ this.projectCache = poll.response.cloudaicompanionProject.id;
140
+ return this.projectCache;
141
+ }
142
+ break;
143
+ }
144
+ }
145
+ }
146
+ if (initialProject) {
147
+ this.projectCache = initialProject;
148
+ return this.projectCache;
149
+ }
150
+ return undefined;
151
+ }
152
+ async generateContent(request) {
153
+ return this.postJson("generateContent", request);
154
+ }
155
+ async *streamGenerateContent(request) {
156
+ const token = await this.getAccessToken();
157
+ const query = new URLSearchParams({ alt: "sse" });
158
+ const response = await fetch(this.buildUrl("streamGenerateContent", query), {
159
+ method: "POST",
160
+ headers: {
161
+ "Content-Type": "application/json",
162
+ Authorization: `Bearer ${token}`
163
+ },
164
+ body: JSON.stringify(request)
165
+ });
166
+ if (!response.ok) {
167
+ const text = await response.text();
168
+ throw new Error(`Code Assist streamGenerateContent failed (${response.status}): ${text}`);
169
+ }
170
+ if (!response.body) {
171
+ throw new Error("Empty stream body");
172
+ }
173
+ for await (const chunk of parseSseStream(response.body)) {
174
+ const parsed = JSON.parse(chunk);
175
+ yield parsed;
176
+ }
177
+ }
178
+ }
179
+ //# sourceMappingURL=code-assist-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-assist-client.js","sourceRoot":"","sources":["../../src/gemini/code-assist-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { CodeAssistClient } from "./code-assist-client.js";
2
+ export declare class ModelCatalogService {
3
+ private readonly codeAssistClient;
4
+ private readonly ttlMs;
5
+ private cache?;
6
+ constructor(codeAssistClient: CodeAssistClient, ttlMs?: number);
7
+ listModels(forceRefresh?: boolean): Promise<string[]>;
8
+ }
@@ -0,0 +1,31 @@
1
+ import { normalizeModelList } from "../openai/model-resolver.js";
2
+ export class ModelCatalogService {
3
+ codeAssistClient;
4
+ ttlMs;
5
+ cache;
6
+ constructor(codeAssistClient, ttlMs = 60_000) {
7
+ this.codeAssistClient = codeAssistClient;
8
+ this.ttlMs = ttlMs;
9
+ }
10
+ async listModels(forceRefresh = false) {
11
+ const now = Date.now();
12
+ if (!forceRefresh && this.cache && this.cache.expiresAt > now) {
13
+ return this.cache.models;
14
+ }
15
+ const projectId = await this.codeAssistClient.resolveProjectId();
16
+ if (!projectId) {
17
+ return [];
18
+ }
19
+ const quota = await this.codeAssistClient.retrieveUserQuota(projectId);
20
+ const rawModels = (quota.buckets ?? [])
21
+ .map((bucket) => bucket.modelId)
22
+ .filter((model) => typeof model === "string");
23
+ const models = normalizeModelList(rawModels);
24
+ this.cache = {
25
+ expiresAt: now + this.ttlMs,
26
+ models
27
+ };
28
+ return models;
29
+ }
30
+ }
31
+ //# sourceMappingURL=model-catalog-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-catalog-service.js","sourceRoot":"","sources":["../../src/gemini/model-catalog-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,MAAM,OAAO,mBAAmB;IAOX;IACA;IAPX,KAAK,CAGX;IAEF,YACmB,gBAAkC,EAClC,QAAgB,MAAM;QADtB,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,UAAK,GAAL,KAAK,CAAiB;IACtC,CAAC;IAEJ,KAAK,CAAC,UAAU,CAAC,YAAY,GAAG,KAAK;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC;YAC9D,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAC3B,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;QACjE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACvE,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;aACpC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC;aAC/B,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC;QAEjE,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,KAAK,GAAG;YACX,SAAS,EAAE,GAAG,GAAG,IAAI,CAAC,KAAK;YAC3B,MAAM;SACP,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
@@ -0,0 +1,82 @@
1
+ export type ClientMetadata = {
2
+ ideType?: string;
3
+ platform?: string;
4
+ pluginType?: string;
5
+ duetProject?: string;
6
+ };
7
+ export type LoadCodeAssistRequest = {
8
+ cloudaicompanionProject?: string;
9
+ metadata: ClientMetadata;
10
+ };
11
+ export type GeminiUserTier = {
12
+ id: string;
13
+ name?: string;
14
+ isDefault?: boolean;
15
+ };
16
+ export type LoadCodeAssistResponse = {
17
+ currentTier?: GeminiUserTier | null;
18
+ allowedTiers?: GeminiUserTier[] | null;
19
+ cloudaicompanionProject?: string | null;
20
+ };
21
+ export type OnboardUserRequest = {
22
+ tierId: string | undefined;
23
+ cloudaicompanionProject: string | undefined;
24
+ metadata: ClientMetadata | undefined;
25
+ };
26
+ export type LongRunningOperationResponse = {
27
+ name: string;
28
+ done?: boolean;
29
+ response?: {
30
+ cloudaicompanionProject?: {
31
+ id: string;
32
+ name?: string;
33
+ };
34
+ };
35
+ };
36
+ export type RetrieveUserQuotaResponse = {
37
+ buckets?: Array<{
38
+ modelId?: string;
39
+ tokenType?: string;
40
+ remainingFraction?: number;
41
+ resetTime?: string;
42
+ }>;
43
+ };
44
+ export type VertexPart = {
45
+ text?: string;
46
+ };
47
+ export type VertexContent = {
48
+ role: "user" | "model";
49
+ parts: VertexPart[];
50
+ };
51
+ export type VertexGenerationConfig = {
52
+ temperature?: number;
53
+ topP?: number;
54
+ maxOutputTokens?: number;
55
+ stopSequences?: string[];
56
+ };
57
+ export type CAGenerateContentRequest = {
58
+ model: string;
59
+ project?: string;
60
+ request: {
61
+ contents: VertexContent[];
62
+ systemInstruction?: VertexContent;
63
+ generationConfig?: VertexGenerationConfig;
64
+ };
65
+ };
66
+ export type CaGenerateContentResponse = {
67
+ traceId?: string;
68
+ response: {
69
+ candidates?: Array<{
70
+ content?: {
71
+ role?: "model" | "user";
72
+ parts?: VertexPart[];
73
+ };
74
+ finishReason?: string;
75
+ }>;
76
+ usageMetadata?: {
77
+ promptTokenCount?: number;
78
+ candidatesTokenCount?: number;
79
+ totalTokenCount?: number;
80
+ };
81
+ };
82
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/gemini/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import type { CodeAssistClient } from "../gemini/code-assist-client.js";
2
+ import type { ModelCatalogService } from "../gemini/model-catalog-service.js";
3
+ import type { OpenAIChatCompletionChunk, OpenAIChatCompletionRequest, OpenAIChatCompletionResponse } from "./types.js";
4
+ export declare class OpenAIChatService {
5
+ private readonly defaultModel;
6
+ private readonly codeAssistClient;
7
+ private readonly modelCatalogService?;
8
+ constructor(defaultModel: string, codeAssistClient: CodeAssistClient, modelCatalogService?: ModelCatalogService | undefined);
9
+ private resolveModel;
10
+ generate(request: OpenAIChatCompletionRequest): Promise<OpenAIChatCompletionResponse>;
11
+ stream(request: OpenAIChatCompletionRequest): AsyncGenerator<OpenAIChatCompletionChunk>;
12
+ }
@@ -0,0 +1,82 @@
1
+ import { mapCodeAssistToOpenAI, mapOpenAIToCodeAssist } from "./mapper.js";
2
+ import { resolveRequestedModel } from "./model-resolver.js";
3
+ export class OpenAIChatService {
4
+ defaultModel;
5
+ codeAssistClient;
6
+ modelCatalogService;
7
+ constructor(defaultModel, codeAssistClient, modelCatalogService) {
8
+ this.defaultModel = defaultModel;
9
+ this.codeAssistClient = codeAssistClient;
10
+ this.modelCatalogService = modelCatalogService;
11
+ }
12
+ async resolveModel(requestedModel) {
13
+ const requested = requestedModel ?? this.defaultModel;
14
+ if (!this.modelCatalogService) {
15
+ return requested;
16
+ }
17
+ try {
18
+ const models = await this.modelCatalogService.listModels();
19
+ return resolveRequestedModel(requested, models);
20
+ }
21
+ catch {
22
+ return requested;
23
+ }
24
+ }
25
+ async generate(request) {
26
+ const resolvedModel = await this.resolveModel(request.model);
27
+ const projectId = await this.codeAssistClient.resolveProjectId();
28
+ const mapped = mapOpenAIToCodeAssist({
29
+ ...request,
30
+ model: resolvedModel
31
+ }, {
32
+ projectId,
33
+ defaultModel: this.defaultModel
34
+ });
35
+ const response = await this.codeAssistClient.generateContent(mapped);
36
+ return mapCodeAssistToOpenAI(response, mapped.model);
37
+ }
38
+ async *stream(request) {
39
+ const resolvedModel = await this.resolveModel(request.model);
40
+ const projectId = await this.codeAssistClient.resolveProjectId();
41
+ const mapped = mapOpenAIToCodeAssist({
42
+ ...request,
43
+ model: resolvedModel
44
+ }, {
45
+ projectId,
46
+ defaultModel: this.defaultModel
47
+ });
48
+ for await (const chunk of this.codeAssistClient.streamGenerateContent(mapped)) {
49
+ const text = chunk.response.candidates?.[0]?.content?.parts?.map((part) => part.text ?? "").join("") ?? "";
50
+ yield {
51
+ id: chunk.traceId ?? `chatcmpl-${Date.now()}`,
52
+ object: "chat.completion.chunk",
53
+ created: Math.floor(Date.now() / 1000),
54
+ model: mapped.model,
55
+ choices: [
56
+ {
57
+ index: 0,
58
+ finish_reason: null,
59
+ delta: {
60
+ role: "assistant",
61
+ content: text
62
+ }
63
+ }
64
+ ]
65
+ };
66
+ }
67
+ yield {
68
+ id: `chatcmpl-${Date.now()}`,
69
+ object: "chat.completion.chunk",
70
+ created: Math.floor(Date.now() / 1000),
71
+ model: mapped.model,
72
+ choices: [
73
+ {
74
+ index: 0,
75
+ finish_reason: "stop",
76
+ delta: {}
77
+ }
78
+ ]
79
+ };
80
+ }
81
+ }
82
+ //# sourceMappingURL=chat-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-service.js","sourceRoot":"","sources":["../../src/openai/chat-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { CAGenerateContentRequest, CaGenerateContentResponse } from "../gemini/types.js";
2
+ import type { OpenAIChatCompletionRequest, OpenAIChatCompletionResponse } from "./types.js";
3
+ export declare function mapOpenAIToCodeAssist(request: OpenAIChatCompletionRequest, context: {
4
+ projectId?: string;
5
+ defaultModel?: string;
6
+ }): CAGenerateContentRequest;
7
+ export declare function mapCodeAssistToOpenAI(response: CaGenerateContentResponse, model: string): OpenAIChatCompletionResponse;