@amanm/vertex-maas 0.0.2 → 0.0.3

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/CHANGELOG.md CHANGED
@@ -2,4 +2,16 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - None.
6
+
7
+ ## 0.0.3
8
+
9
+ - Add `opencodeCompat` option to map stream finish reason to a string for OpenCode compatibility.
10
+
11
+ ## 0.0.2
12
+
13
+ - Repository metadata fix.
14
+
15
+ ## 0.0.1
16
+
5
17
  - Initial release.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @ai-sdk/vertex-maas
1
+ # @amanm/vertex-maas
2
2
 
3
3
  Vertex MaaS provider for the Vercel AI SDK.
4
4
 
@@ -33,3 +33,28 @@ const result = await generateText({
33
33
  - `project` / `location`: Used to compute the Vertex OpenAI-compatible base URL if `baseURL` is not provided.
34
34
  - `apiKey`: Optional. If set, uses a static `Authorization: Bearer <apiKey>` header (no ADC).
35
35
  - `googleAuthOptions`: Optional. Passed to `google-auth-library` `GoogleAuth`.
36
+ - `opencodeCompat`: Optional. If `true`, maps `finish.finishReason` from `{ unified, raw }` to `unified` in `doStream()` for OpenCode.
37
+
38
+ ## OpenCode
39
+
40
+ OpenCode currently expects the model stream `finishReason` to be a string.
41
+
42
+ Set `opencodeCompat: true` in your OpenCode provider options:
43
+
44
+ ```json
45
+ {
46
+ "provider": {
47
+ "vertexmaas": {
48
+ "npm": "@amanm/vertex-maas",
49
+ "options": {
50
+ "project": "common-project-by-aman",
51
+ "location": "global",
52
+ "opencodeCompat": true
53
+ },
54
+ "models": {
55
+ "glm-4.7-maas": { "id": "zai-org/glm-4.7-maas" }
56
+ }
57
+ }
58
+ }
59
+ }
60
+ ```
package/dist/index.d.mts CHANGED
@@ -51,6 +51,16 @@ interface VertexMaaSProviderSettings {
51
51
  supportsStructuredOutputs?: boolean;
52
52
  transformRequestBody?: (args: Record<string, any>) => Record<string, any>;
53
53
  metadataExtractor?: MetadataExtractor;
54
+ /**
55
+ * Compatibility mode for OpenCode.
56
+ *
57
+ * OpenCode currently expects `finishReason` in the model stream `finish` part
58
+ * to be a string. AI SDK v3 models provide `{ unified, raw }`.
59
+ *
60
+ * When enabled, we map `finish.finishReason` to `finish.finishReason.unified`
61
+ * in `doStream()`.
62
+ */
63
+ opencodeCompat?: boolean;
54
64
  }
55
65
  type VertexMaaSProvider = OpenAICompatibleProvider;
56
66
  declare function createVertexMaaS(options?: VertexMaaSProviderSettings): VertexMaaSProvider;
package/dist/index.d.ts CHANGED
@@ -51,6 +51,16 @@ interface VertexMaaSProviderSettings {
51
51
  supportsStructuredOutputs?: boolean;
52
52
  transformRequestBody?: (args: Record<string, any>) => Record<string, any>;
53
53
  metadataExtractor?: MetadataExtractor;
54
+ /**
55
+ * Compatibility mode for OpenCode.
56
+ *
57
+ * OpenCode currently expects `finishReason` in the model stream `finish` part
58
+ * to be a string. AI SDK v3 models provide `{ unified, raw }`.
59
+ *
60
+ * When enabled, we map `finish.finishReason` to `finish.finishReason.unified`
61
+ * in `doStream()`.
62
+ */
63
+ opencodeCompat?: boolean;
54
64
  }
55
65
  type VertexMaaSProvider = OpenAICompatibleProvider;
56
66
  declare function createVertexMaaS(options?: VertexMaaSProviderSettings): VertexMaaSProvider;
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ var import_openai_compatible = require("@ai-sdk/openai-compatible");
31
31
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
32
32
 
33
33
  // src/version.ts
34
- var VERSION = true ? "0.0.2" : "0.0.0-test";
34
+ var VERSION = true ? "0.0.3" : "0.0.0-test";
35
35
 
36
36
  // src/vertex-maas-auth-fetch.ts
37
37
  var import_provider_utils = require("@ai-sdk/provider-utils");
@@ -148,37 +148,77 @@ function createVertexMaaS(options = {}) {
148
148
  fetch: fetch2
149
149
  });
150
150
  const createLanguageModel = (modelId) => createChatModel(modelId);
151
- const createChatModel = (modelId) => new import_openai_compatible.OpenAICompatibleChatLanguageModel(modelId, {
152
- ...getCommonModelConfig("chat"),
153
- includeUsage: options.includeUsage,
154
- supportsStructuredOutputs: options.supportsStructuredOutputs,
155
- transformRequestBody: options.transformRequestBody,
156
- metadataExtractor: options.metadataExtractor
157
- });
158
- const createCompletionModel = (modelId) => new import_openai_compatible.OpenAICompatibleCompletionLanguageModel(modelId, {
159
- ...getCommonModelConfig("completion"),
160
- includeUsage: options.includeUsage
161
- });
151
+ const createChatModel = (modelId) => wrapModelForOpenCode(
152
+ new import_openai_compatible.OpenAICompatibleChatLanguageModel(modelId, {
153
+ ...getCommonModelConfig("chat"),
154
+ includeUsage: options.includeUsage,
155
+ supportsStructuredOutputs: options.supportsStructuredOutputs,
156
+ transformRequestBody: options.transformRequestBody,
157
+ metadataExtractor: options.metadataExtractor
158
+ })
159
+ );
160
+ const createCompletionModel = (modelId) => wrapModelForOpenCode(
161
+ new import_openai_compatible.OpenAICompatibleCompletionLanguageModel(modelId, {
162
+ ...getCommonModelConfig("completion"),
163
+ includeUsage: options.includeUsage
164
+ })
165
+ );
162
166
  const createEmbeddingModel = (modelId) => new import_openai_compatible.OpenAICompatibleEmbeddingModel(modelId, {
163
167
  ...getCommonModelConfig("embedding")
164
168
  });
165
169
  const createImageModel = (modelId) => new import_openai_compatible.OpenAICompatibleImageModel(modelId, getCommonModelConfig("image"));
166
170
  const provider = (modelId) => createLanguageModel(modelId);
167
171
  provider.specificationVersion = "v3";
168
- provider.languageModel = (modelId, config) => new import_openai_compatible.OpenAICompatibleChatLanguageModel(modelId, {
169
- ...getCommonModelConfig("chat"),
170
- includeUsage: options.includeUsage,
171
- supportsStructuredOutputs: options.supportsStructuredOutputs,
172
- transformRequestBody: options.transformRequestBody,
173
- metadataExtractor: options.metadataExtractor,
174
- ...config
175
- });
172
+ provider.languageModel = (modelId, config) => wrapModelForOpenCode(
173
+ new import_openai_compatible.OpenAICompatibleChatLanguageModel(modelId, {
174
+ ...getCommonModelConfig("chat"),
175
+ includeUsage: options.includeUsage,
176
+ supportsStructuredOutputs: options.supportsStructuredOutputs,
177
+ transformRequestBody: options.transformRequestBody,
178
+ metadataExtractor: options.metadataExtractor,
179
+ ...config
180
+ })
181
+ );
176
182
  provider.chatModel = createChatModel;
177
183
  provider.completionModel = createCompletionModel;
178
184
  provider.embeddingModel = createEmbeddingModel;
179
185
  provider.textEmbeddingModel = createEmbeddingModel;
180
186
  provider.imageModel = createImageModel;
181
187
  return provider;
188
+ function wrapModelForOpenCode(model) {
189
+ if (options.opencodeCompat !== true) {
190
+ return model;
191
+ }
192
+ const originalDoStream = model.doStream.bind(model);
193
+ return new Proxy(model, {
194
+ get(target, prop, receiver) {
195
+ if (prop !== "doStream") {
196
+ return Reflect.get(target, prop, receiver);
197
+ }
198
+ return async (callOptions) => {
199
+ const result = await originalDoStream(callOptions);
200
+ const transformedStream = result.stream.pipeThrough(
201
+ new TransformStream({
202
+ transform(part, controller) {
203
+ if ((part == null ? void 0 : part.type) === "finish" && part.finishReason != null && typeof part.finishReason === "object" && typeof part.finishReason.unified === "string") {
204
+ controller.enqueue({
205
+ ...part,
206
+ finishReason: part.finishReason.unified
207
+ });
208
+ return;
209
+ }
210
+ controller.enqueue(part);
211
+ }
212
+ })
213
+ );
214
+ return {
215
+ ...result,
216
+ stream: transformedStream
217
+ };
218
+ };
219
+ }
220
+ });
221
+ }
182
222
  }
183
223
  var vertexMaaS = createVertexMaaS();
184
224
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/vertex-maas-provider.ts","../src/version.ts","../src/vertex-maas-auth-fetch.ts","../src/vertex-maas-auth-google-auth-library.ts","../src/vertex-maas-base-url.ts"],"sourcesContent":["export { createVertexMaaS, vertexMaaS } from './vertex-maas-provider';\nexport type {\n VertexMaaSProvider,\n VertexMaaSProviderSettings,\n} from './vertex-maas-provider';\nexport { VERSION } from './version';\n","import {\n MetadataExtractor,\n OpenAICompatibleProvider,\n OpenAICompatibleChatLanguageModel,\n OpenAICompatibleCompletionLanguageModel,\n OpenAICompatibleEmbeddingModel,\n OpenAICompatibleImageModel,\n} from '@ai-sdk/openai-compatible';\nimport {\n FetchFunction,\n loadSetting,\n withoutTrailingSlash,\n withUserAgentSuffix,\n} from '@ai-sdk/provider-utils';\nimport type { GoogleAuthOptions } from 'google-auth-library';\nimport { VERSION } from './version';\nimport { createVertexMaaSAuthFetch } from './vertex-maas-auth-fetch';\nimport { getVertexOpenAICompatibleBaseURL } from './vertex-maas-base-url';\nimport type {\n EmbeddingModelV3,\n ImageModelV3,\n LanguageModelV3,\n} from '@ai-sdk/provider';\n\ntype OpenAICompatibleChatConfig = ConstructorParameters<\n typeof OpenAICompatibleChatLanguageModel\n>[1];\n\nexport interface VertexMaaSProviderSettings {\n /**\n * Base URL for the API calls. If not set, it is derived from `project` and\n * `location`.\n */\n baseURL?: string;\n\n /**\n * Vertex project id. Defaults to `GOOGLE_VERTEX_PROJECT` if `baseURL` is not\n * provided.\n */\n project?: string;\n\n /**\n * Vertex location. Defaults to `GOOGLE_VERTEX_LOCATION` if `baseURL` is not\n * provided.\n */\n location?: string;\n\n /**\n * API version used when computing baseURL. Defaults to `v1beta1`.\n */\n apiVersion?: 'v1' | 'v1beta1';\n\n /**\n * Override the base host for Vertex API calls (e.g. \"https://aiplatform.googleapis.com\").\n * If not set, it is computed from location.\n */\n apiBase?: string;\n\n /**\n * Optional. Use a static bearer token instead of ADC.\n */\n apiKey?: string;\n\n /**\n * Optional. Passed to google-auth-library for ADC token generation.\n */\n googleAuthOptions?: GoogleAuthOptions;\n\n /**\n * Optional custom headers.\n */\n headers?: Record<string, string>;\n\n /**\n * Optional custom url query parameters to include in request urls.\n */\n queryParams?: Record<string, string>;\n\n /**\n * Custom fetch implementation.\n */\n fetch?: FetchFunction;\n\n includeUsage?: boolean;\n supportsStructuredOutputs?: boolean;\n transformRequestBody?: (args: Record<string, any>) => Record<string, any>;\n metadataExtractor?: MetadataExtractor;\n}\n\nexport type VertexMaaSProvider = OpenAICompatibleProvider;\n\nexport function createVertexMaaS(\n options: VertexMaaSProviderSettings = {},\n): VertexMaaSProvider {\n const providerName = 'vertexMaas';\n\n let baseURLCache: string | null = null;\n const getBaseURL = () => {\n if (baseURLCache != null) {\n return baseURLCache;\n }\n\n baseURLCache =\n withoutTrailingSlash(options.baseURL) ??\n getVertexOpenAICompatibleBaseURL({\n project: loadSetting({\n settingValue: options.project,\n settingName: 'project',\n environmentVariableName: 'GOOGLE_VERTEX_PROJECT',\n description: 'Google Vertex project',\n }),\n location: loadSetting({\n settingValue: options.location,\n settingName: 'location',\n environmentVariableName: 'GOOGLE_VERTEX_LOCATION',\n description: 'Google Vertex location',\n }),\n apiVersion: options.apiVersion ?? 'v1beta1',\n apiBase: options.apiBase,\n });\n\n return baseURLCache;\n };\n\n interface CommonModelConfig {\n provider: string;\n url: ({ path }: { path: string }) => string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n }\n\n const staticHeaders = {\n ...(options.apiKey && { Authorization: `Bearer ${options.apiKey}` }),\n ...options.headers,\n };\n\n const getHeaders = () =>\n withUserAgentSuffix(staticHeaders, `ai-sdk/vertex-maas/${VERSION}`);\n\n const fetch =\n options.apiKey != null\n ? options.fetch\n : createVertexMaaSAuthFetch({\n customFetch: options.fetch,\n googleAuthOptions: options.googleAuthOptions,\n });\n\n const getCommonModelConfig = (modelType: string): CommonModelConfig => ({\n provider: `${providerName}.${modelType}`,\n url: ({ path }) => {\n const url = new URL(`${getBaseURL()}${path}`);\n if (options.queryParams) {\n url.search = new URLSearchParams(options.queryParams).toString();\n }\n return url.toString();\n },\n headers: getHeaders,\n fetch,\n });\n\n const createLanguageModel = (modelId: string) => createChatModel(modelId);\n\n const createChatModel = (modelId: string) =>\n new OpenAICompatibleChatLanguageModel(modelId, {\n ...getCommonModelConfig('chat'),\n includeUsage: options.includeUsage,\n supportsStructuredOutputs: options.supportsStructuredOutputs,\n transformRequestBody: options.transformRequestBody,\n metadataExtractor: options.metadataExtractor,\n });\n\n const createCompletionModel = (modelId: string) =>\n new OpenAICompatibleCompletionLanguageModel(modelId, {\n ...getCommonModelConfig('completion'),\n includeUsage: options.includeUsage,\n });\n\n const createEmbeddingModel = (modelId: string) =>\n new OpenAICompatibleEmbeddingModel(modelId, {\n ...getCommonModelConfig('embedding'),\n });\n\n const createImageModel = (modelId: string) =>\n new OpenAICompatibleImageModel(modelId, getCommonModelConfig('image'));\n\n const provider = (modelId: string) => createLanguageModel(modelId);\n\n provider.specificationVersion = 'v3' as const;\n provider.languageModel = (\n modelId: string,\n config?: Partial<OpenAICompatibleChatConfig>,\n ): LanguageModelV3 =>\n new OpenAICompatibleChatLanguageModel(modelId, {\n ...getCommonModelConfig('chat'),\n includeUsage: options.includeUsage,\n supportsStructuredOutputs: options.supportsStructuredOutputs,\n transformRequestBody: options.transformRequestBody,\n metadataExtractor: options.metadataExtractor,\n ...config,\n });\n provider.chatModel = createChatModel;\n provider.completionModel = createCompletionModel;\n provider.embeddingModel = createEmbeddingModel as (\n modelId: string,\n ) => EmbeddingModelV3;\n provider.textEmbeddingModel = createEmbeddingModel as (\n modelId: string,\n ) => EmbeddingModelV3;\n provider.imageModel = createImageModel as (modelId: string) => ImageModelV3;\n\n return provider as unknown as OpenAICompatibleProvider;\n}\n\n/**\n * Default Vertex MaaS provider instance.\n */\nexport const vertexMaaS = createVertexMaaS();\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n","import { FetchFunction, normalizeHeaders } from '@ai-sdk/provider-utils';\nimport type { GoogleAuthOptions } from 'google-auth-library';\nimport { generateAuthToken } from './vertex-maas-auth-google-auth-library';\n\nexport function createVertexMaaSAuthFetch({\n customFetch,\n googleAuthOptions,\n}: {\n customFetch?: FetchFunction;\n googleAuthOptions?: GoogleAuthOptions;\n}): FetchFunction {\n return async (url, init) => {\n const existingHeaders = normalizeHeaders(init?.headers as any);\n\n // Respect caller-provided auth (including static api keys).\n if (existingHeaders.authorization != null) {\n return (customFetch ?? fetch)(url as any, init);\n }\n\n const token = await generateAuthToken(googleAuthOptions);\n if (!token) {\n throw new Error('Failed to get access token from ADC');\n }\n\n const modifiedInit: RequestInit = {\n ...init,\n headers: {\n ...existingHeaders,\n authorization: `Bearer ${token}`,\n },\n };\n\n return (customFetch ?? fetch)(url as any, modifiedInit);\n };\n}\n","import { GoogleAuth, GoogleAuthOptions } from 'google-auth-library';\n\nlet authInstance: GoogleAuth | null = null;\nlet authOptions: GoogleAuthOptions | null = null;\n\nfunction getAuth(options: GoogleAuthOptions) {\n if (!authInstance || options !== authOptions) {\n authInstance = new GoogleAuth({\n scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n ...options,\n });\n authOptions = options;\n }\n return authInstance;\n}\n\nexport async function generateAuthToken(options?: GoogleAuthOptions) {\n const auth = getAuth(options || {});\n const client = await auth.getClient();\n const token = await client.getAccessToken();\n return token?.token || null;\n}\n\n// For testing purposes only\nexport function _resetAuthInstance() {\n authInstance = null;\n}\n","import { withoutTrailingSlash } from '@ai-sdk/provider-utils';\n\nfunction getDefaultVertexApiBase(location: string): string {\n return location === 'global'\n ? 'https://aiplatform.googleapis.com'\n : `https://${location}-aiplatform.googleapis.com`;\n}\n\nexport function getVertexOpenAICompatibleBaseURL({\n project,\n location,\n apiVersion,\n apiBase,\n}: {\n project: string;\n location: string;\n apiVersion: 'v1' | 'v1beta1';\n apiBase?: string;\n}): string {\n const resolvedApiBase = withoutTrailingSlash(\n apiBase ?? getDefaultVertexApiBase(location),\n );\n\n return `${resolvedApiBase}/${apiVersion}/projects/${project}/locations/${location}/endpoints/openapi`;\n}\n"],"mappings":"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","names":["import_provider_utils","import_provider_utils","fetch"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/vertex-maas-provider.ts","../src/version.ts","../src/vertex-maas-auth-fetch.ts","../src/vertex-maas-auth-google-auth-library.ts","../src/vertex-maas-base-url.ts"],"sourcesContent":["export { createVertexMaaS, vertexMaaS } from './vertex-maas-provider';\nexport type {\n VertexMaaSProvider,\n VertexMaaSProviderSettings,\n} from './vertex-maas-provider';\nexport { VERSION } from './version';\n","import {\n MetadataExtractor,\n OpenAICompatibleProvider,\n OpenAICompatibleChatLanguageModel,\n OpenAICompatibleCompletionLanguageModel,\n OpenAICompatibleEmbeddingModel,\n OpenAICompatibleImageModel,\n} from '@ai-sdk/openai-compatible';\nimport {\n FetchFunction,\n loadSetting,\n withoutTrailingSlash,\n withUserAgentSuffix,\n} from '@ai-sdk/provider-utils';\nimport type { GoogleAuthOptions } from 'google-auth-library';\nimport { VERSION } from './version';\nimport { createVertexMaaSAuthFetch } from './vertex-maas-auth-fetch';\nimport { getVertexOpenAICompatibleBaseURL } from './vertex-maas-base-url';\nimport type {\n EmbeddingModelV3,\n ImageModelV3,\n LanguageModelV3,\n} from '@ai-sdk/provider';\n\ntype OpenAICompatibleChatConfig = ConstructorParameters<\n typeof OpenAICompatibleChatLanguageModel\n>[1];\n\nexport interface VertexMaaSProviderSettings {\n /**\n * Base URL for the API calls. If not set, it is derived from `project` and\n * `location`.\n */\n baseURL?: string;\n\n /**\n * Vertex project id. Defaults to `GOOGLE_VERTEX_PROJECT` if `baseURL` is not\n * provided.\n */\n project?: string;\n\n /**\n * Vertex location. Defaults to `GOOGLE_VERTEX_LOCATION` if `baseURL` is not\n * provided.\n */\n location?: string;\n\n /**\n * API version used when computing baseURL. Defaults to `v1beta1`.\n */\n apiVersion?: 'v1' | 'v1beta1';\n\n /**\n * Override the base host for Vertex API calls (e.g. \"https://aiplatform.googleapis.com\").\n * If not set, it is computed from location.\n */\n apiBase?: string;\n\n /**\n * Optional. Use a static bearer token instead of ADC.\n */\n apiKey?: string;\n\n /**\n * Optional. Passed to google-auth-library for ADC token generation.\n */\n googleAuthOptions?: GoogleAuthOptions;\n\n /**\n * Optional custom headers.\n */\n headers?: Record<string, string>;\n\n /**\n * Optional custom url query parameters to include in request urls.\n */\n queryParams?: Record<string, string>;\n\n /**\n * Custom fetch implementation.\n */\n fetch?: FetchFunction;\n\n includeUsage?: boolean;\n supportsStructuredOutputs?: boolean;\n transformRequestBody?: (args: Record<string, any>) => Record<string, any>;\n metadataExtractor?: MetadataExtractor;\n\n /**\n * Compatibility mode for OpenCode.\n *\n * OpenCode currently expects `finishReason` in the model stream `finish` part\n * to be a string. AI SDK v3 models provide `{ unified, raw }`.\n *\n * When enabled, we map `finish.finishReason` to `finish.finishReason.unified`\n * in `doStream()`.\n */\n opencodeCompat?: boolean;\n}\n\nexport type VertexMaaSProvider = OpenAICompatibleProvider;\n\nexport function createVertexMaaS(\n options: VertexMaaSProviderSettings = {},\n): VertexMaaSProvider {\n const providerName = 'vertexMaas';\n\n let baseURLCache: string | null = null;\n const getBaseURL = () => {\n if (baseURLCache != null) {\n return baseURLCache;\n }\n\n baseURLCache =\n withoutTrailingSlash(options.baseURL) ??\n getVertexOpenAICompatibleBaseURL({\n project: loadSetting({\n settingValue: options.project,\n settingName: 'project',\n environmentVariableName: 'GOOGLE_VERTEX_PROJECT',\n description: 'Google Vertex project',\n }),\n location: loadSetting({\n settingValue: options.location,\n settingName: 'location',\n environmentVariableName: 'GOOGLE_VERTEX_LOCATION',\n description: 'Google Vertex location',\n }),\n apiVersion: options.apiVersion ?? 'v1beta1',\n apiBase: options.apiBase,\n });\n\n return baseURLCache;\n };\n\n interface CommonModelConfig {\n provider: string;\n url: ({ path }: { path: string }) => string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n }\n\n const staticHeaders = {\n ...(options.apiKey && { Authorization: `Bearer ${options.apiKey}` }),\n ...options.headers,\n };\n\n const getHeaders = () =>\n withUserAgentSuffix(staticHeaders, `ai-sdk/vertex-maas/${VERSION}`);\n\n const fetch =\n options.apiKey != null\n ? options.fetch\n : createVertexMaaSAuthFetch({\n customFetch: options.fetch,\n googleAuthOptions: options.googleAuthOptions,\n });\n\n const getCommonModelConfig = (modelType: string): CommonModelConfig => ({\n provider: `${providerName}.${modelType}`,\n url: ({ path }) => {\n const url = new URL(`${getBaseURL()}${path}`);\n if (options.queryParams) {\n url.search = new URLSearchParams(options.queryParams).toString();\n }\n return url.toString();\n },\n headers: getHeaders,\n fetch,\n });\n\n const createLanguageModel = (modelId: string) => createChatModel(modelId);\n\n const createChatModel = (modelId: string) =>\n wrapModelForOpenCode(\n new OpenAICompatibleChatLanguageModel(modelId, {\n ...getCommonModelConfig('chat'),\n includeUsage: options.includeUsage,\n supportsStructuredOutputs: options.supportsStructuredOutputs,\n transformRequestBody: options.transformRequestBody,\n metadataExtractor: options.metadataExtractor,\n }),\n );\n\n const createCompletionModel = (modelId: string) =>\n wrapModelForOpenCode(\n new OpenAICompatibleCompletionLanguageModel(modelId, {\n ...getCommonModelConfig('completion'),\n includeUsage: options.includeUsage,\n }),\n );\n\n const createEmbeddingModel = (modelId: string) =>\n new OpenAICompatibleEmbeddingModel(modelId, {\n ...getCommonModelConfig('embedding'),\n });\n\n const createImageModel = (modelId: string) =>\n new OpenAICompatibleImageModel(modelId, getCommonModelConfig('image'));\n\n const provider = (modelId: string) => createLanguageModel(modelId);\n\n provider.specificationVersion = 'v3' as const;\n provider.languageModel = (\n modelId: string,\n config?: Partial<OpenAICompatibleChatConfig>,\n ): LanguageModelV3 =>\n wrapModelForOpenCode(\n new OpenAICompatibleChatLanguageModel(modelId, {\n ...getCommonModelConfig('chat'),\n includeUsage: options.includeUsage,\n supportsStructuredOutputs: options.supportsStructuredOutputs,\n transformRequestBody: options.transformRequestBody,\n metadataExtractor: options.metadataExtractor,\n ...config,\n }),\n );\n provider.chatModel = createChatModel;\n provider.completionModel = createCompletionModel;\n provider.embeddingModel = createEmbeddingModel as (\n modelId: string,\n ) => EmbeddingModelV3;\n provider.textEmbeddingModel = createEmbeddingModel as (\n modelId: string,\n ) => EmbeddingModelV3;\n provider.imageModel = createImageModel as (modelId: string) => ImageModelV3;\n\n return provider as unknown as OpenAICompatibleProvider;\n\n function wrapModelForOpenCode<T extends LanguageModelV3>(model: T): T {\n if (options.opencodeCompat !== true) {\n return model;\n }\n\n const originalDoStream = model.doStream.bind(model);\n\n return new Proxy(model, {\n get(target, prop, receiver) {\n if (prop !== 'doStream') {\n return Reflect.get(target, prop, receiver);\n }\n\n return async (callOptions: Parameters<T['doStream']>[0]) => {\n const result = await originalDoStream(callOptions);\n\n // Map `{ unified, raw }` -> `unified` for the finish part.\n const transformedStream = result.stream.pipeThrough(\n new TransformStream<any, any>({\n transform(part, controller) {\n if (\n part?.type === 'finish' &&\n part.finishReason != null &&\n typeof part.finishReason === 'object' &&\n typeof part.finishReason.unified === 'string'\n ) {\n controller.enqueue({\n ...part,\n finishReason: part.finishReason.unified,\n });\n return;\n }\n\n controller.enqueue(part);\n },\n }),\n );\n\n return {\n ...result,\n stream: transformedStream,\n };\n };\n },\n }) as unknown as T;\n }\n}\n\n/**\n * Default Vertex MaaS provider instance.\n */\nexport const vertexMaaS = createVertexMaaS();\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n","import { FetchFunction, normalizeHeaders } from '@ai-sdk/provider-utils';\nimport type { GoogleAuthOptions } from 'google-auth-library';\nimport { generateAuthToken } from './vertex-maas-auth-google-auth-library';\n\nexport function createVertexMaaSAuthFetch({\n customFetch,\n googleAuthOptions,\n}: {\n customFetch?: FetchFunction;\n googleAuthOptions?: GoogleAuthOptions;\n}): FetchFunction {\n return async (url, init) => {\n const existingHeaders = normalizeHeaders(init?.headers as any);\n\n // Respect caller-provided auth (including static api keys).\n if (existingHeaders.authorization != null) {\n return (customFetch ?? fetch)(url as any, init);\n }\n\n const token = await generateAuthToken(googleAuthOptions);\n if (!token) {\n throw new Error('Failed to get access token from ADC');\n }\n\n const modifiedInit: RequestInit = {\n ...init,\n headers: {\n ...existingHeaders,\n authorization: `Bearer ${token}`,\n },\n };\n\n return (customFetch ?? fetch)(url as any, modifiedInit);\n };\n}\n","import { GoogleAuth, GoogleAuthOptions } from 'google-auth-library';\n\nlet authInstance: GoogleAuth | null = null;\nlet authOptions: GoogleAuthOptions | null = null;\n\nfunction getAuth(options: GoogleAuthOptions) {\n if (!authInstance || options !== authOptions) {\n authInstance = new GoogleAuth({\n scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n ...options,\n });\n authOptions = options;\n }\n return authInstance;\n}\n\nexport async function generateAuthToken(options?: GoogleAuthOptions) {\n const auth = getAuth(options || {});\n const client = await auth.getClient();\n const token = await client.getAccessToken();\n return token?.token || null;\n}\n\n// For testing purposes only\nexport function _resetAuthInstance() {\n authInstance = null;\n}\n","import { withoutTrailingSlash } from '@ai-sdk/provider-utils';\n\nfunction getDefaultVertexApiBase(location: string): string {\n return location === 'global'\n ? 'https://aiplatform.googleapis.com'\n : `https://${location}-aiplatform.googleapis.com`;\n}\n\nexport function getVertexOpenAICompatibleBaseURL({\n project,\n location,\n apiVersion,\n apiBase,\n}: {\n project: string;\n location: string;\n apiVersion: 'v1' | 'v1beta1';\n apiBase?: string;\n}): string {\n const resolvedApiBase = withoutTrailingSlash(\n apiBase ?? getDefaultVertexApiBase(location),\n );\n\n return `${resolvedApiBase}/${apiVersion}/projects/${project}/locations/${location}/endpoints/openapi`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,+BAOO;AACP,IAAAA,yBAKO;;;ACXA,IAAM,UACX,OACI,UACA;;;ACLN,4BAAgD;;;ACAhD,iCAA8C;AAE9C,IAAI,eAAkC;AACtC,IAAI,cAAwC;AAE5C,SAAS,QAAQ,SAA4B;AAC3C,MAAI,CAAC,gBAAgB,YAAY,aAAa;AAC5C,mBAAe,IAAI,sCAAW;AAAA,MAC5B,QAAQ,CAAC,gDAAgD;AAAA,MACzD,GAAG;AAAA,IACL,CAAC;AACD,kBAAc;AAAA,EAChB;AACA,SAAO;AACT;AAEA,eAAsB,kBAAkB,SAA6B;AACnE,QAAM,OAAO,QAAQ,WAAW,CAAC,CAAC;AAClC,QAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAM,QAAQ,MAAM,OAAO,eAAe;AAC1C,UAAO,+BAAO,UAAS;AACzB;;;ADjBO,SAAS,0BAA0B;AAAA,EACxC;AAAA,EACA;AACF,GAGkB;AAChB,SAAO,OAAO,KAAK,SAAS;AAC1B,UAAM,sBAAkB,wCAAiB,6BAAM,OAAc;AAG7D,QAAI,gBAAgB,iBAAiB,MAAM;AACzC,cAAQ,oCAAe,OAAO,KAAY,IAAI;AAAA,IAChD;AAEA,UAAM,QAAQ,MAAM,kBAAkB,iBAAiB;AACvD,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AAEA,UAAM,eAA4B;AAAA,MAChC,GAAG;AAAA,MACH,SAAS;AAAA,QACP,GAAG;AAAA,QACH,eAAe,UAAU,KAAK;AAAA,MAChC;AAAA,IACF;AAEA,YAAQ,oCAAe,OAAO,KAAY,YAAY;AAAA,EACxD;AACF;;;AElCA,IAAAC,yBAAqC;AAErC,SAAS,wBAAwB,UAA0B;AACzD,SAAO,aAAa,WAChB,sCACA,WAAW,QAAQ;AACzB;AAEO,SAAS,iCAAiC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKW;AACT,QAAM,sBAAkB;AAAA,IACtB,4BAAW,wBAAwB,QAAQ;AAAA,EAC7C;AAEA,SAAO,GAAG,eAAe,IAAI,UAAU,aAAa,OAAO,cAAc,QAAQ;AACnF;;;AJ8EO,SAAS,iBACd,UAAsC,CAAC,GACnB;AACpB,QAAM,eAAe;AAErB,MAAI,eAA8B;AAClC,QAAM,aAAa,MAAM;AA5G3B;AA6GI,QAAI,gBAAgB,MAAM;AACxB,aAAO;AAAA,IACT;AAEA,oBACE,sDAAqB,QAAQ,OAAO,MAApC,YACA,iCAAiC;AAAA,MAC/B,aAAS,oCAAY;AAAA,QACnB,cAAc,QAAQ;AAAA,QACtB,aAAa;AAAA,QACb,yBAAyB;AAAA,QACzB,aAAa;AAAA,MACf,CAAC;AAAA,MACD,cAAU,oCAAY;AAAA,QACpB,cAAc,QAAQ;AAAA,QACtB,aAAa;AAAA,QACb,yBAAyB;AAAA,QACzB,aAAa;AAAA,MACf,CAAC;AAAA,MACD,aAAY,aAAQ,eAAR,YAAsB;AAAA,MAClC,SAAS,QAAQ;AAAA,IACnB,CAAC;AAEH,WAAO;AAAA,EACT;AASA,QAAM,gBAAgB;AAAA,IACpB,GAAI,QAAQ,UAAU,EAAE,eAAe,UAAU,QAAQ,MAAM,GAAG;AAAA,IAClE,GAAG,QAAQ;AAAA,EACb;AAEA,QAAM,aAAa,UACjB,4CAAoB,eAAe,sBAAsB,OAAO,EAAE;AAEpE,QAAMC,SACJ,QAAQ,UAAU,OACd,QAAQ,QACR,0BAA0B;AAAA,IACxB,aAAa,QAAQ;AAAA,IACrB,mBAAmB,QAAQ;AAAA,EAC7B,CAAC;AAEP,QAAM,uBAAuB,CAAC,eAA0C;AAAA,IACtE,UAAU,GAAG,YAAY,IAAI,SAAS;AAAA,IACtC,KAAK,CAAC,EAAE,KAAK,MAAM;AACjB,YAAM,MAAM,IAAI,IAAI,GAAG,WAAW,CAAC,GAAG,IAAI,EAAE;AAC5C,UAAI,QAAQ,aAAa;AACvB,YAAI,SAAS,IAAI,gBAAgB,QAAQ,WAAW,EAAE,SAAS;AAAA,MACjE;AACA,aAAO,IAAI,SAAS;AAAA,IACtB;AAAA,IACA,SAAS;AAAA,IACT,OAAAA;AAAA,EACF;AAEA,QAAM,sBAAsB,CAAC,YAAoB,gBAAgB,OAAO;AAExE,QAAM,kBAAkB,CAAC,YACvB;AAAA,IACE,IAAI,2DAAkC,SAAS;AAAA,MAC7C,GAAG,qBAAqB,MAAM;AAAA,MAC9B,cAAc,QAAQ;AAAA,MACtB,2BAA2B,QAAQ;AAAA,MACnC,sBAAsB,QAAQ;AAAA,MAC9B,mBAAmB,QAAQ;AAAA,IAC7B,CAAC;AAAA,EACH;AAEF,QAAM,wBAAwB,CAAC,YAC7B;AAAA,IACE,IAAI,iEAAwC,SAAS;AAAA,MACnD,GAAG,qBAAqB,YAAY;AAAA,MACpC,cAAc,QAAQ;AAAA,IACxB,CAAC;AAAA,EACH;AAEF,QAAM,uBAAuB,CAAC,YAC5B,IAAI,wDAA+B,SAAS;AAAA,IAC1C,GAAG,qBAAqB,WAAW;AAAA,EACrC,CAAC;AAEH,QAAM,mBAAmB,CAAC,YACxB,IAAI,oDAA2B,SAAS,qBAAqB,OAAO,CAAC;AAEvE,QAAM,WAAW,CAAC,YAAoB,oBAAoB,OAAO;AAEjE,WAAS,uBAAuB;AAChC,WAAS,gBAAgB,CACvB,SACA,WAEA;AAAA,IACE,IAAI,2DAAkC,SAAS;AAAA,MAC7C,GAAG,qBAAqB,MAAM;AAAA,MAC9B,cAAc,QAAQ;AAAA,MACtB,2BAA2B,QAAQ;AAAA,MACnC,sBAAsB,QAAQ;AAAA,MAC9B,mBAAmB,QAAQ;AAAA,MAC3B,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACF,WAAS,YAAY;AACrB,WAAS,kBAAkB;AAC3B,WAAS,iBAAiB;AAG1B,WAAS,qBAAqB;AAG9B,WAAS,aAAa;AAEtB,SAAO;AAEP,WAAS,qBAAgD,OAAa;AACpE,QAAI,QAAQ,mBAAmB,MAAM;AACnC,aAAO;AAAA,IACT;AAEA,UAAM,mBAAmB,MAAM,SAAS,KAAK,KAAK;AAElD,WAAO,IAAI,MAAM,OAAO;AAAA,MACtB,IAAI,QAAQ,MAAM,UAAU;AAC1B,YAAI,SAAS,YAAY;AACvB,iBAAO,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AAAA,QAC3C;AAEA,eAAO,OAAO,gBAA8C;AAC1D,gBAAM,SAAS,MAAM,iBAAiB,WAAW;AAGjD,gBAAM,oBAAoB,OAAO,OAAO;AAAA,YACtC,IAAI,gBAA0B;AAAA,cAC5B,UAAU,MAAM,YAAY;AAC1B,qBACE,6BAAM,UAAS,YACf,KAAK,gBAAgB,QACrB,OAAO,KAAK,iBAAiB,YAC7B,OAAO,KAAK,aAAa,YAAY,UACrC;AACA,6BAAW,QAAQ;AAAA,oBACjB,GAAG;AAAA,oBACH,cAAc,KAAK,aAAa;AAAA,kBAClC,CAAC;AACD;AAAA,gBACF;AAEA,2BAAW,QAAQ,IAAI;AAAA,cACzB;AAAA,YACF,CAAC;AAAA,UACH;AAEA,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAKO,IAAM,aAAa,iBAAiB;","names":["import_provider_utils","import_provider_utils","fetch"]}
package/dist/index.mjs CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  } from "@ai-sdk/provider-utils";
13
13
 
14
14
  // src/version.ts
15
- var VERSION = true ? "0.0.2" : "0.0.0-test";
15
+ var VERSION = true ? "0.0.3" : "0.0.0-test";
16
16
 
17
17
  // src/vertex-maas-auth-fetch.ts
18
18
  import { normalizeHeaders } from "@ai-sdk/provider-utils";
@@ -129,37 +129,77 @@ function createVertexMaaS(options = {}) {
129
129
  fetch: fetch2
130
130
  });
131
131
  const createLanguageModel = (modelId) => createChatModel(modelId);
132
- const createChatModel = (modelId) => new OpenAICompatibleChatLanguageModel(modelId, {
133
- ...getCommonModelConfig("chat"),
134
- includeUsage: options.includeUsage,
135
- supportsStructuredOutputs: options.supportsStructuredOutputs,
136
- transformRequestBody: options.transformRequestBody,
137
- metadataExtractor: options.metadataExtractor
138
- });
139
- const createCompletionModel = (modelId) => new OpenAICompatibleCompletionLanguageModel(modelId, {
140
- ...getCommonModelConfig("completion"),
141
- includeUsage: options.includeUsage
142
- });
132
+ const createChatModel = (modelId) => wrapModelForOpenCode(
133
+ new OpenAICompatibleChatLanguageModel(modelId, {
134
+ ...getCommonModelConfig("chat"),
135
+ includeUsage: options.includeUsage,
136
+ supportsStructuredOutputs: options.supportsStructuredOutputs,
137
+ transformRequestBody: options.transformRequestBody,
138
+ metadataExtractor: options.metadataExtractor
139
+ })
140
+ );
141
+ const createCompletionModel = (modelId) => wrapModelForOpenCode(
142
+ new OpenAICompatibleCompletionLanguageModel(modelId, {
143
+ ...getCommonModelConfig("completion"),
144
+ includeUsage: options.includeUsage
145
+ })
146
+ );
143
147
  const createEmbeddingModel = (modelId) => new OpenAICompatibleEmbeddingModel(modelId, {
144
148
  ...getCommonModelConfig("embedding")
145
149
  });
146
150
  const createImageModel = (modelId) => new OpenAICompatibleImageModel(modelId, getCommonModelConfig("image"));
147
151
  const provider = (modelId) => createLanguageModel(modelId);
148
152
  provider.specificationVersion = "v3";
149
- provider.languageModel = (modelId, config) => new OpenAICompatibleChatLanguageModel(modelId, {
150
- ...getCommonModelConfig("chat"),
151
- includeUsage: options.includeUsage,
152
- supportsStructuredOutputs: options.supportsStructuredOutputs,
153
- transformRequestBody: options.transformRequestBody,
154
- metadataExtractor: options.metadataExtractor,
155
- ...config
156
- });
153
+ provider.languageModel = (modelId, config) => wrapModelForOpenCode(
154
+ new OpenAICompatibleChatLanguageModel(modelId, {
155
+ ...getCommonModelConfig("chat"),
156
+ includeUsage: options.includeUsage,
157
+ supportsStructuredOutputs: options.supportsStructuredOutputs,
158
+ transformRequestBody: options.transformRequestBody,
159
+ metadataExtractor: options.metadataExtractor,
160
+ ...config
161
+ })
162
+ );
157
163
  provider.chatModel = createChatModel;
158
164
  provider.completionModel = createCompletionModel;
159
165
  provider.embeddingModel = createEmbeddingModel;
160
166
  provider.textEmbeddingModel = createEmbeddingModel;
161
167
  provider.imageModel = createImageModel;
162
168
  return provider;
169
+ function wrapModelForOpenCode(model) {
170
+ if (options.opencodeCompat !== true) {
171
+ return model;
172
+ }
173
+ const originalDoStream = model.doStream.bind(model);
174
+ return new Proxy(model, {
175
+ get(target, prop, receiver) {
176
+ if (prop !== "doStream") {
177
+ return Reflect.get(target, prop, receiver);
178
+ }
179
+ return async (callOptions) => {
180
+ const result = await originalDoStream(callOptions);
181
+ const transformedStream = result.stream.pipeThrough(
182
+ new TransformStream({
183
+ transform(part, controller) {
184
+ if ((part == null ? void 0 : part.type) === "finish" && part.finishReason != null && typeof part.finishReason === "object" && typeof part.finishReason.unified === "string") {
185
+ controller.enqueue({
186
+ ...part,
187
+ finishReason: part.finishReason.unified
188
+ });
189
+ return;
190
+ }
191
+ controller.enqueue(part);
192
+ }
193
+ })
194
+ );
195
+ return {
196
+ ...result,
197
+ stream: transformedStream
198
+ };
199
+ };
200
+ }
201
+ });
202
+ }
163
203
  }
164
204
  var vertexMaaS = createVertexMaaS();
165
205
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/vertex-maas-provider.ts","../src/version.ts","../src/vertex-maas-auth-fetch.ts","../src/vertex-maas-auth-google-auth-library.ts","../src/vertex-maas-base-url.ts"],"sourcesContent":["import {\n MetadataExtractor,\n OpenAICompatibleProvider,\n OpenAICompatibleChatLanguageModel,\n OpenAICompatibleCompletionLanguageModel,\n OpenAICompatibleEmbeddingModel,\n OpenAICompatibleImageModel,\n} from '@ai-sdk/openai-compatible';\nimport {\n FetchFunction,\n loadSetting,\n withoutTrailingSlash,\n withUserAgentSuffix,\n} from '@ai-sdk/provider-utils';\nimport type { GoogleAuthOptions } from 'google-auth-library';\nimport { VERSION } from './version';\nimport { createVertexMaaSAuthFetch } from './vertex-maas-auth-fetch';\nimport { getVertexOpenAICompatibleBaseURL } from './vertex-maas-base-url';\nimport type {\n EmbeddingModelV3,\n ImageModelV3,\n LanguageModelV3,\n} from '@ai-sdk/provider';\n\ntype OpenAICompatibleChatConfig = ConstructorParameters<\n typeof OpenAICompatibleChatLanguageModel\n>[1];\n\nexport interface VertexMaaSProviderSettings {\n /**\n * Base URL for the API calls. If not set, it is derived from `project` and\n * `location`.\n */\n baseURL?: string;\n\n /**\n * Vertex project id. Defaults to `GOOGLE_VERTEX_PROJECT` if `baseURL` is not\n * provided.\n */\n project?: string;\n\n /**\n * Vertex location. Defaults to `GOOGLE_VERTEX_LOCATION` if `baseURL` is not\n * provided.\n */\n location?: string;\n\n /**\n * API version used when computing baseURL. Defaults to `v1beta1`.\n */\n apiVersion?: 'v1' | 'v1beta1';\n\n /**\n * Override the base host for Vertex API calls (e.g. \"https://aiplatform.googleapis.com\").\n * If not set, it is computed from location.\n */\n apiBase?: string;\n\n /**\n * Optional. Use a static bearer token instead of ADC.\n */\n apiKey?: string;\n\n /**\n * Optional. Passed to google-auth-library for ADC token generation.\n */\n googleAuthOptions?: GoogleAuthOptions;\n\n /**\n * Optional custom headers.\n */\n headers?: Record<string, string>;\n\n /**\n * Optional custom url query parameters to include in request urls.\n */\n queryParams?: Record<string, string>;\n\n /**\n * Custom fetch implementation.\n */\n fetch?: FetchFunction;\n\n includeUsage?: boolean;\n supportsStructuredOutputs?: boolean;\n transformRequestBody?: (args: Record<string, any>) => Record<string, any>;\n metadataExtractor?: MetadataExtractor;\n}\n\nexport type VertexMaaSProvider = OpenAICompatibleProvider;\n\nexport function createVertexMaaS(\n options: VertexMaaSProviderSettings = {},\n): VertexMaaSProvider {\n const providerName = 'vertexMaas';\n\n let baseURLCache: string | null = null;\n const getBaseURL = () => {\n if (baseURLCache != null) {\n return baseURLCache;\n }\n\n baseURLCache =\n withoutTrailingSlash(options.baseURL) ??\n getVertexOpenAICompatibleBaseURL({\n project: loadSetting({\n settingValue: options.project,\n settingName: 'project',\n environmentVariableName: 'GOOGLE_VERTEX_PROJECT',\n description: 'Google Vertex project',\n }),\n location: loadSetting({\n settingValue: options.location,\n settingName: 'location',\n environmentVariableName: 'GOOGLE_VERTEX_LOCATION',\n description: 'Google Vertex location',\n }),\n apiVersion: options.apiVersion ?? 'v1beta1',\n apiBase: options.apiBase,\n });\n\n return baseURLCache;\n };\n\n interface CommonModelConfig {\n provider: string;\n url: ({ path }: { path: string }) => string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n }\n\n const staticHeaders = {\n ...(options.apiKey && { Authorization: `Bearer ${options.apiKey}` }),\n ...options.headers,\n };\n\n const getHeaders = () =>\n withUserAgentSuffix(staticHeaders, `ai-sdk/vertex-maas/${VERSION}`);\n\n const fetch =\n options.apiKey != null\n ? options.fetch\n : createVertexMaaSAuthFetch({\n customFetch: options.fetch,\n googleAuthOptions: options.googleAuthOptions,\n });\n\n const getCommonModelConfig = (modelType: string): CommonModelConfig => ({\n provider: `${providerName}.${modelType}`,\n url: ({ path }) => {\n const url = new URL(`${getBaseURL()}${path}`);\n if (options.queryParams) {\n url.search = new URLSearchParams(options.queryParams).toString();\n }\n return url.toString();\n },\n headers: getHeaders,\n fetch,\n });\n\n const createLanguageModel = (modelId: string) => createChatModel(modelId);\n\n const createChatModel = (modelId: string) =>\n new OpenAICompatibleChatLanguageModel(modelId, {\n ...getCommonModelConfig('chat'),\n includeUsage: options.includeUsage,\n supportsStructuredOutputs: options.supportsStructuredOutputs,\n transformRequestBody: options.transformRequestBody,\n metadataExtractor: options.metadataExtractor,\n });\n\n const createCompletionModel = (modelId: string) =>\n new OpenAICompatibleCompletionLanguageModel(modelId, {\n ...getCommonModelConfig('completion'),\n includeUsage: options.includeUsage,\n });\n\n const createEmbeddingModel = (modelId: string) =>\n new OpenAICompatibleEmbeddingModel(modelId, {\n ...getCommonModelConfig('embedding'),\n });\n\n const createImageModel = (modelId: string) =>\n new OpenAICompatibleImageModel(modelId, getCommonModelConfig('image'));\n\n const provider = (modelId: string) => createLanguageModel(modelId);\n\n provider.specificationVersion = 'v3' as const;\n provider.languageModel = (\n modelId: string,\n config?: Partial<OpenAICompatibleChatConfig>,\n ): LanguageModelV3 =>\n new OpenAICompatibleChatLanguageModel(modelId, {\n ...getCommonModelConfig('chat'),\n includeUsage: options.includeUsage,\n supportsStructuredOutputs: options.supportsStructuredOutputs,\n transformRequestBody: options.transformRequestBody,\n metadataExtractor: options.metadataExtractor,\n ...config,\n });\n provider.chatModel = createChatModel;\n provider.completionModel = createCompletionModel;\n provider.embeddingModel = createEmbeddingModel as (\n modelId: string,\n ) => EmbeddingModelV3;\n provider.textEmbeddingModel = createEmbeddingModel as (\n modelId: string,\n ) => EmbeddingModelV3;\n provider.imageModel = createImageModel as (modelId: string) => ImageModelV3;\n\n return provider as unknown as OpenAICompatibleProvider;\n}\n\n/**\n * Default Vertex MaaS provider instance.\n */\nexport const vertexMaaS = createVertexMaaS();\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n","import { FetchFunction, normalizeHeaders } from '@ai-sdk/provider-utils';\nimport type { GoogleAuthOptions } from 'google-auth-library';\nimport { generateAuthToken } from './vertex-maas-auth-google-auth-library';\n\nexport function createVertexMaaSAuthFetch({\n customFetch,\n googleAuthOptions,\n}: {\n customFetch?: FetchFunction;\n googleAuthOptions?: GoogleAuthOptions;\n}): FetchFunction {\n return async (url, init) => {\n const existingHeaders = normalizeHeaders(init?.headers as any);\n\n // Respect caller-provided auth (including static api keys).\n if (existingHeaders.authorization != null) {\n return (customFetch ?? fetch)(url as any, init);\n }\n\n const token = await generateAuthToken(googleAuthOptions);\n if (!token) {\n throw new Error('Failed to get access token from ADC');\n }\n\n const modifiedInit: RequestInit = {\n ...init,\n headers: {\n ...existingHeaders,\n authorization: `Bearer ${token}`,\n },\n };\n\n return (customFetch ?? fetch)(url as any, modifiedInit);\n };\n}\n","import { GoogleAuth, GoogleAuthOptions } from 'google-auth-library';\n\nlet authInstance: GoogleAuth | null = null;\nlet authOptions: GoogleAuthOptions | null = null;\n\nfunction getAuth(options: GoogleAuthOptions) {\n if (!authInstance || options !== authOptions) {\n authInstance = new GoogleAuth({\n scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n ...options,\n });\n authOptions = options;\n }\n return authInstance;\n}\n\nexport async function generateAuthToken(options?: GoogleAuthOptions) {\n const auth = getAuth(options || {});\n const client = await auth.getClient();\n const token = await client.getAccessToken();\n return token?.token || null;\n}\n\n// For testing purposes only\nexport function _resetAuthInstance() {\n authInstance = null;\n}\n","import { withoutTrailingSlash } from '@ai-sdk/provider-utils';\n\nfunction getDefaultVertexApiBase(location: string): string {\n return location === 'global'\n ? 'https://aiplatform.googleapis.com'\n : `https://${location}-aiplatform.googleapis.com`;\n}\n\nexport function getVertexOpenAICompatibleBaseURL({\n project,\n location,\n apiVersion,\n apiBase,\n}: {\n project: string;\n location: string;\n apiVersion: 'v1' | 'v1beta1';\n apiBase?: string;\n}): string {\n const resolvedApiBase = withoutTrailingSlash(\n apiBase ?? getDefaultVertexApiBase(location),\n );\n\n return `${resolvedApiBase}/${apiVersion}/projects/${project}/locations/${location}/endpoints/openapi`;\n}\n"],"mappings":"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","names":["withoutTrailingSlash","withoutTrailingSlash","fetch"]}
1
+ {"version":3,"sources":["../src/vertex-maas-provider.ts","../src/version.ts","../src/vertex-maas-auth-fetch.ts","../src/vertex-maas-auth-google-auth-library.ts","../src/vertex-maas-base-url.ts"],"sourcesContent":["import {\n MetadataExtractor,\n OpenAICompatibleProvider,\n OpenAICompatibleChatLanguageModel,\n OpenAICompatibleCompletionLanguageModel,\n OpenAICompatibleEmbeddingModel,\n OpenAICompatibleImageModel,\n} from '@ai-sdk/openai-compatible';\nimport {\n FetchFunction,\n loadSetting,\n withoutTrailingSlash,\n withUserAgentSuffix,\n} from '@ai-sdk/provider-utils';\nimport type { GoogleAuthOptions } from 'google-auth-library';\nimport { VERSION } from './version';\nimport { createVertexMaaSAuthFetch } from './vertex-maas-auth-fetch';\nimport { getVertexOpenAICompatibleBaseURL } from './vertex-maas-base-url';\nimport type {\n EmbeddingModelV3,\n ImageModelV3,\n LanguageModelV3,\n} from '@ai-sdk/provider';\n\ntype OpenAICompatibleChatConfig = ConstructorParameters<\n typeof OpenAICompatibleChatLanguageModel\n>[1];\n\nexport interface VertexMaaSProviderSettings {\n /**\n * Base URL for the API calls. If not set, it is derived from `project` and\n * `location`.\n */\n baseURL?: string;\n\n /**\n * Vertex project id. Defaults to `GOOGLE_VERTEX_PROJECT` if `baseURL` is not\n * provided.\n */\n project?: string;\n\n /**\n * Vertex location. Defaults to `GOOGLE_VERTEX_LOCATION` if `baseURL` is not\n * provided.\n */\n location?: string;\n\n /**\n * API version used when computing baseURL. Defaults to `v1beta1`.\n */\n apiVersion?: 'v1' | 'v1beta1';\n\n /**\n * Override the base host for Vertex API calls (e.g. \"https://aiplatform.googleapis.com\").\n * If not set, it is computed from location.\n */\n apiBase?: string;\n\n /**\n * Optional. Use a static bearer token instead of ADC.\n */\n apiKey?: string;\n\n /**\n * Optional. Passed to google-auth-library for ADC token generation.\n */\n googleAuthOptions?: GoogleAuthOptions;\n\n /**\n * Optional custom headers.\n */\n headers?: Record<string, string>;\n\n /**\n * Optional custom url query parameters to include in request urls.\n */\n queryParams?: Record<string, string>;\n\n /**\n * Custom fetch implementation.\n */\n fetch?: FetchFunction;\n\n includeUsage?: boolean;\n supportsStructuredOutputs?: boolean;\n transformRequestBody?: (args: Record<string, any>) => Record<string, any>;\n metadataExtractor?: MetadataExtractor;\n\n /**\n * Compatibility mode for OpenCode.\n *\n * OpenCode currently expects `finishReason` in the model stream `finish` part\n * to be a string. AI SDK v3 models provide `{ unified, raw }`.\n *\n * When enabled, we map `finish.finishReason` to `finish.finishReason.unified`\n * in `doStream()`.\n */\n opencodeCompat?: boolean;\n}\n\nexport type VertexMaaSProvider = OpenAICompatibleProvider;\n\nexport function createVertexMaaS(\n options: VertexMaaSProviderSettings = {},\n): VertexMaaSProvider {\n const providerName = 'vertexMaas';\n\n let baseURLCache: string | null = null;\n const getBaseURL = () => {\n if (baseURLCache != null) {\n return baseURLCache;\n }\n\n baseURLCache =\n withoutTrailingSlash(options.baseURL) ??\n getVertexOpenAICompatibleBaseURL({\n project: loadSetting({\n settingValue: options.project,\n settingName: 'project',\n environmentVariableName: 'GOOGLE_VERTEX_PROJECT',\n description: 'Google Vertex project',\n }),\n location: loadSetting({\n settingValue: options.location,\n settingName: 'location',\n environmentVariableName: 'GOOGLE_VERTEX_LOCATION',\n description: 'Google Vertex location',\n }),\n apiVersion: options.apiVersion ?? 'v1beta1',\n apiBase: options.apiBase,\n });\n\n return baseURLCache;\n };\n\n interface CommonModelConfig {\n provider: string;\n url: ({ path }: { path: string }) => string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n }\n\n const staticHeaders = {\n ...(options.apiKey && { Authorization: `Bearer ${options.apiKey}` }),\n ...options.headers,\n };\n\n const getHeaders = () =>\n withUserAgentSuffix(staticHeaders, `ai-sdk/vertex-maas/${VERSION}`);\n\n const fetch =\n options.apiKey != null\n ? options.fetch\n : createVertexMaaSAuthFetch({\n customFetch: options.fetch,\n googleAuthOptions: options.googleAuthOptions,\n });\n\n const getCommonModelConfig = (modelType: string): CommonModelConfig => ({\n provider: `${providerName}.${modelType}`,\n url: ({ path }) => {\n const url = new URL(`${getBaseURL()}${path}`);\n if (options.queryParams) {\n url.search = new URLSearchParams(options.queryParams).toString();\n }\n return url.toString();\n },\n headers: getHeaders,\n fetch,\n });\n\n const createLanguageModel = (modelId: string) => createChatModel(modelId);\n\n const createChatModel = (modelId: string) =>\n wrapModelForOpenCode(\n new OpenAICompatibleChatLanguageModel(modelId, {\n ...getCommonModelConfig('chat'),\n includeUsage: options.includeUsage,\n supportsStructuredOutputs: options.supportsStructuredOutputs,\n transformRequestBody: options.transformRequestBody,\n metadataExtractor: options.metadataExtractor,\n }),\n );\n\n const createCompletionModel = (modelId: string) =>\n wrapModelForOpenCode(\n new OpenAICompatibleCompletionLanguageModel(modelId, {\n ...getCommonModelConfig('completion'),\n includeUsage: options.includeUsage,\n }),\n );\n\n const createEmbeddingModel = (modelId: string) =>\n new OpenAICompatibleEmbeddingModel(modelId, {\n ...getCommonModelConfig('embedding'),\n });\n\n const createImageModel = (modelId: string) =>\n new OpenAICompatibleImageModel(modelId, getCommonModelConfig('image'));\n\n const provider = (modelId: string) => createLanguageModel(modelId);\n\n provider.specificationVersion = 'v3' as const;\n provider.languageModel = (\n modelId: string,\n config?: Partial<OpenAICompatibleChatConfig>,\n ): LanguageModelV3 =>\n wrapModelForOpenCode(\n new OpenAICompatibleChatLanguageModel(modelId, {\n ...getCommonModelConfig('chat'),\n includeUsage: options.includeUsage,\n supportsStructuredOutputs: options.supportsStructuredOutputs,\n transformRequestBody: options.transformRequestBody,\n metadataExtractor: options.metadataExtractor,\n ...config,\n }),\n );\n provider.chatModel = createChatModel;\n provider.completionModel = createCompletionModel;\n provider.embeddingModel = createEmbeddingModel as (\n modelId: string,\n ) => EmbeddingModelV3;\n provider.textEmbeddingModel = createEmbeddingModel as (\n modelId: string,\n ) => EmbeddingModelV3;\n provider.imageModel = createImageModel as (modelId: string) => ImageModelV3;\n\n return provider as unknown as OpenAICompatibleProvider;\n\n function wrapModelForOpenCode<T extends LanguageModelV3>(model: T): T {\n if (options.opencodeCompat !== true) {\n return model;\n }\n\n const originalDoStream = model.doStream.bind(model);\n\n return new Proxy(model, {\n get(target, prop, receiver) {\n if (prop !== 'doStream') {\n return Reflect.get(target, prop, receiver);\n }\n\n return async (callOptions: Parameters<T['doStream']>[0]) => {\n const result = await originalDoStream(callOptions);\n\n // Map `{ unified, raw }` -> `unified` for the finish part.\n const transformedStream = result.stream.pipeThrough(\n new TransformStream<any, any>({\n transform(part, controller) {\n if (\n part?.type === 'finish' &&\n part.finishReason != null &&\n typeof part.finishReason === 'object' &&\n typeof part.finishReason.unified === 'string'\n ) {\n controller.enqueue({\n ...part,\n finishReason: part.finishReason.unified,\n });\n return;\n }\n\n controller.enqueue(part);\n },\n }),\n );\n\n return {\n ...result,\n stream: transformedStream,\n };\n };\n },\n }) as unknown as T;\n }\n}\n\n/**\n * Default Vertex MaaS provider instance.\n */\nexport const vertexMaaS = createVertexMaaS();\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n","import { FetchFunction, normalizeHeaders } from '@ai-sdk/provider-utils';\nimport type { GoogleAuthOptions } from 'google-auth-library';\nimport { generateAuthToken } from './vertex-maas-auth-google-auth-library';\n\nexport function createVertexMaaSAuthFetch({\n customFetch,\n googleAuthOptions,\n}: {\n customFetch?: FetchFunction;\n googleAuthOptions?: GoogleAuthOptions;\n}): FetchFunction {\n return async (url, init) => {\n const existingHeaders = normalizeHeaders(init?.headers as any);\n\n // Respect caller-provided auth (including static api keys).\n if (existingHeaders.authorization != null) {\n return (customFetch ?? fetch)(url as any, init);\n }\n\n const token = await generateAuthToken(googleAuthOptions);\n if (!token) {\n throw new Error('Failed to get access token from ADC');\n }\n\n const modifiedInit: RequestInit = {\n ...init,\n headers: {\n ...existingHeaders,\n authorization: `Bearer ${token}`,\n },\n };\n\n return (customFetch ?? fetch)(url as any, modifiedInit);\n };\n}\n","import { GoogleAuth, GoogleAuthOptions } from 'google-auth-library';\n\nlet authInstance: GoogleAuth | null = null;\nlet authOptions: GoogleAuthOptions | null = null;\n\nfunction getAuth(options: GoogleAuthOptions) {\n if (!authInstance || options !== authOptions) {\n authInstance = new GoogleAuth({\n scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n ...options,\n });\n authOptions = options;\n }\n return authInstance;\n}\n\nexport async function generateAuthToken(options?: GoogleAuthOptions) {\n const auth = getAuth(options || {});\n const client = await auth.getClient();\n const token = await client.getAccessToken();\n return token?.token || null;\n}\n\n// For testing purposes only\nexport function _resetAuthInstance() {\n authInstance = null;\n}\n","import { withoutTrailingSlash } from '@ai-sdk/provider-utils';\n\nfunction getDefaultVertexApiBase(location: string): string {\n return location === 'global'\n ? 'https://aiplatform.googleapis.com'\n : `https://${location}-aiplatform.googleapis.com`;\n}\n\nexport function getVertexOpenAICompatibleBaseURL({\n project,\n location,\n apiVersion,\n apiBase,\n}: {\n project: string;\n location: string;\n apiVersion: 'v1' | 'v1beta1';\n apiBase?: string;\n}): string {\n const resolvedApiBase = withoutTrailingSlash(\n apiBase ?? getDefaultVertexApiBase(location),\n );\n\n return `${resolvedApiBase}/${apiVersion}/projects/${project}/locations/${location}/endpoints/openapi`;\n}\n"],"mappings":"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","names":["withoutTrailingSlash","withoutTrailingSlash","fetch"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amanm/vertex-maas",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -85,6 +85,17 @@ export interface VertexMaaSProviderSettings {
85
85
  supportsStructuredOutputs?: boolean;
86
86
  transformRequestBody?: (args: Record<string, any>) => Record<string, any>;
87
87
  metadataExtractor?: MetadataExtractor;
88
+
89
+ /**
90
+ * Compatibility mode for OpenCode.
91
+ *
92
+ * OpenCode currently expects `finishReason` in the model stream `finish` part
93
+ * to be a string. AI SDK v3 models provide `{ unified, raw }`.
94
+ *
95
+ * When enabled, we map `finish.finishReason` to `finish.finishReason.unified`
96
+ * in `doStream()`.
97
+ */
98
+ opencodeCompat?: boolean;
88
99
  }
89
100
 
90
101
  export type VertexMaaSProvider = OpenAICompatibleProvider;
@@ -161,19 +172,23 @@ export function createVertexMaaS(
161
172
  const createLanguageModel = (modelId: string) => createChatModel(modelId);
162
173
 
163
174
  const createChatModel = (modelId: string) =>
164
- new OpenAICompatibleChatLanguageModel(modelId, {
165
- ...getCommonModelConfig('chat'),
166
- includeUsage: options.includeUsage,
167
- supportsStructuredOutputs: options.supportsStructuredOutputs,
168
- transformRequestBody: options.transformRequestBody,
169
- metadataExtractor: options.metadataExtractor,
170
- });
175
+ wrapModelForOpenCode(
176
+ new OpenAICompatibleChatLanguageModel(modelId, {
177
+ ...getCommonModelConfig('chat'),
178
+ includeUsage: options.includeUsage,
179
+ supportsStructuredOutputs: options.supportsStructuredOutputs,
180
+ transformRequestBody: options.transformRequestBody,
181
+ metadataExtractor: options.metadataExtractor,
182
+ }),
183
+ );
171
184
 
172
185
  const createCompletionModel = (modelId: string) =>
173
- new OpenAICompatibleCompletionLanguageModel(modelId, {
174
- ...getCommonModelConfig('completion'),
175
- includeUsage: options.includeUsage,
176
- });
186
+ wrapModelForOpenCode(
187
+ new OpenAICompatibleCompletionLanguageModel(modelId, {
188
+ ...getCommonModelConfig('completion'),
189
+ includeUsage: options.includeUsage,
190
+ }),
191
+ );
177
192
 
178
193
  const createEmbeddingModel = (modelId: string) =>
179
194
  new OpenAICompatibleEmbeddingModel(modelId, {
@@ -190,14 +205,16 @@ export function createVertexMaaS(
190
205
  modelId: string,
191
206
  config?: Partial<OpenAICompatibleChatConfig>,
192
207
  ): LanguageModelV3 =>
193
- new OpenAICompatibleChatLanguageModel(modelId, {
194
- ...getCommonModelConfig('chat'),
195
- includeUsage: options.includeUsage,
196
- supportsStructuredOutputs: options.supportsStructuredOutputs,
197
- transformRequestBody: options.transformRequestBody,
198
- metadataExtractor: options.metadataExtractor,
199
- ...config,
200
- });
208
+ wrapModelForOpenCode(
209
+ new OpenAICompatibleChatLanguageModel(modelId, {
210
+ ...getCommonModelConfig('chat'),
211
+ includeUsage: options.includeUsage,
212
+ supportsStructuredOutputs: options.supportsStructuredOutputs,
213
+ transformRequestBody: options.transformRequestBody,
214
+ metadataExtractor: options.metadataExtractor,
215
+ ...config,
216
+ }),
217
+ );
201
218
  provider.chatModel = createChatModel;
202
219
  provider.completionModel = createCompletionModel;
203
220
  provider.embeddingModel = createEmbeddingModel as (
@@ -209,6 +226,53 @@ export function createVertexMaaS(
209
226
  provider.imageModel = createImageModel as (modelId: string) => ImageModelV3;
210
227
 
211
228
  return provider as unknown as OpenAICompatibleProvider;
229
+
230
+ function wrapModelForOpenCode<T extends LanguageModelV3>(model: T): T {
231
+ if (options.opencodeCompat !== true) {
232
+ return model;
233
+ }
234
+
235
+ const originalDoStream = model.doStream.bind(model);
236
+
237
+ return new Proxy(model, {
238
+ get(target, prop, receiver) {
239
+ if (prop !== 'doStream') {
240
+ return Reflect.get(target, prop, receiver);
241
+ }
242
+
243
+ return async (callOptions: Parameters<T['doStream']>[0]) => {
244
+ const result = await originalDoStream(callOptions);
245
+
246
+ // Map `{ unified, raw }` -> `unified` for the finish part.
247
+ const transformedStream = result.stream.pipeThrough(
248
+ new TransformStream<any, any>({
249
+ transform(part, controller) {
250
+ if (
251
+ part?.type === 'finish' &&
252
+ part.finishReason != null &&
253
+ typeof part.finishReason === 'object' &&
254
+ typeof part.finishReason.unified === 'string'
255
+ ) {
256
+ controller.enqueue({
257
+ ...part,
258
+ finishReason: part.finishReason.unified,
259
+ });
260
+ return;
261
+ }
262
+
263
+ controller.enqueue(part);
264
+ },
265
+ }),
266
+ );
267
+
268
+ return {
269
+ ...result,
270
+ stream: transformedStream,
271
+ };
272
+ };
273
+ },
274
+ }) as unknown as T;
275
+ }
212
276
  }
213
277
 
214
278
  /**