@ai-sdk/harness-opencode 1.0.92 → 1.0.94

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.
@@ -1,10 +1,12 @@
1
1
  import type {
2
+ HarnessV1Authentication,
2
3
  HarnessV1RequestTransformation,
3
4
  HarnessV1RequestTransformationSources,
4
5
  } from '@ai-sdk/harness';
5
6
  import {
6
7
  createCredentialRequestTransformation,
7
8
  getAiGatewayAuthFromEnv,
9
+ isHarnessAuthenticationEnvironment,
8
10
  } from '@ai-sdk/harness/utils';
9
11
 
10
12
  export const OPENCODE_CREDENTIAL_ENVIRONMENT_VARIABLES = [
@@ -108,40 +110,9 @@ export type OpenCodeResolvedAuthenticationMode =
108
110
  | 'openai'
109
111
  | 'ai-gateway';
110
112
 
111
- export type OpenCodeAuthenticationMode =
112
- | OpenCodeResolvedAuthenticationMode
113
- | 'auto';
114
-
115
- /**
116
- * @deprecated Passing an object to auth options is deprecated. Use an `OpenCodeAuthenticationMode` string value ("auto" | "anthropic" | "openai" | "ai-gateway") instead, and pass credentials via environment variables.
117
- */
118
- export type LegacyOpenCodeAuthOptions = {
119
- readonly gateway?: {
120
- readonly apiKey?: string;
121
- readonly baseUrl?: string;
122
- };
123
- readonly anthropic?: {
124
- readonly apiKey?: string;
125
- readonly authToken?: string;
126
- readonly baseUrl?: string;
127
- };
128
- readonly openai?: {
129
- readonly apiKey?: string;
130
- readonly baseUrl?: string;
131
- readonly organization?: string;
132
- readonly project?: string;
133
- };
134
- readonly openaiCompatible?: {
135
- readonly apiKey?: string;
136
- readonly baseUrl?: string;
137
- readonly name?: string;
138
- readonly queryParams?: Record<string, string>;
139
- };
140
- };
141
-
142
- export type OpenCodeAuthOptions =
143
- | OpenCodeAuthenticationMode
144
- | LegacyOpenCodeAuthOptions;
113
+ export type OpenCodeAuthenticationMode = HarnessV1Authentication<
114
+ 'anthropic' | 'openai'
115
+ >;
145
116
 
146
117
  export function resolveOpenCodeProvider({
147
118
  model,
@@ -188,37 +159,30 @@ export function resolveOpenCodeEnv({
188
159
  provider,
189
160
  processEnv = process.env,
190
161
  }: {
191
- auth: OpenCodeAuthOptions | undefined;
162
+ auth: OpenCodeAuthenticationMode | undefined;
192
163
  model?: string;
193
164
  provider?: string;
194
165
  processEnv?: Record<string, string | undefined>;
195
166
  }): Record<string, string> {
196
- const normalizedAuth = normalizeOpenCodeAuthToLegacyAuth(auth);
167
+ const suppliedEnvironment = isHarnessAuthenticationEnvironment(auth);
168
+ const authenticationEnvironment = suppliedEnvironment ? auth : processEnv;
197
169
  const selectedProvider = resolveOpenCodeProvider({ model, provider });
198
- if (normalizedAuth?.openaiCompatible) {
199
- return pickOpenAICompatible(normalizedAuth.openaiCompatible, processEnv);
170
+ if (selectedProvider === 'openai' && auth === 'openai') {
171
+ return pickOpenAI({ processEnv: authenticationEnvironment });
200
172
  }
201
- if (selectedProvider === 'openai') {
202
- if (normalizedAuth?.openai) {
203
- return pickOpenAI({ explicit: normalizedAuth.openai, processEnv });
204
- }
205
- } else if (normalizedAuth?.anthropic) {
206
- return pickAnthropic({ explicit: normalizedAuth.anthropic, processEnv });
173
+ if (selectedProvider === 'anthropic' && auth === 'anthropic') {
174
+ return pickAnthropic({ processEnv: authenticationEnvironment });
207
175
  }
208
176
 
209
- const gatewayAuthFromEnv = getAiGatewayAuthFromEnv({ env: processEnv });
210
- if (normalizedAuth?.gateway) {
211
- return pickGateway({
212
- explicit: normalizedAuth.gateway,
213
- gatewayAuthFromEnv,
214
- });
215
- }
216
- if (gatewayAuthFromEnv.apiKey) {
217
- return pickGateway({ explicit: {}, gatewayAuthFromEnv });
177
+ const gatewayAuthFromEnv = getAiGatewayAuthFromEnv({
178
+ env: authenticationEnvironment,
179
+ });
180
+ if (auth === 'ai-gateway' || gatewayAuthFromEnv.apiKey) {
181
+ return pickGateway({ gatewayAuthFromEnv });
218
182
  }
219
183
  return selectedProvider === 'openai'
220
- ? pickOpenAI({ processEnv })
221
- : pickAnthropic({ processEnv });
184
+ ? pickOpenAI({ processEnv: authenticationEnvironment })
185
+ : pickAnthropic({ processEnv: authenticationEnvironment });
222
186
  }
223
187
 
224
188
  export function resolveOpenCodeAuthenticationMode({
@@ -227,29 +191,24 @@ export function resolveOpenCodeAuthenticationMode({
227
191
  provider,
228
192
  processEnv = process.env,
229
193
  }: {
230
- auth: OpenCodeAuthOptions | undefined;
194
+ auth: OpenCodeAuthenticationMode | undefined;
231
195
  model?: string;
232
196
  provider?: string;
233
197
  processEnv?: Record<string, string | undefined>;
234
198
  }): OpenCodeResolvedAuthenticationMode {
235
- if (typeof auth !== 'string' && auth?.openaiCompatible) {
236
- return 'openai';
199
+ if (isHarnessAuthenticationEnvironment(auth)) {
200
+ return getAiGatewayAuthFromEnv({ env: auth }).apiKey
201
+ ? 'ai-gateway'
202
+ : resolveOpenCodeProvider({ model, provider });
237
203
  }
238
-
239
204
  const selectedProvider = resolveOpenCodeProvider({ model, provider });
240
- if (
241
- selectedProvider === 'openai' &&
242
- (auth === 'openai' || (typeof auth !== 'string' && auth?.openai))
243
- ) {
205
+ if (selectedProvider === 'openai' && auth === 'openai') {
244
206
  return 'openai';
245
207
  }
246
- if (
247
- selectedProvider === 'anthropic' &&
248
- (auth === 'anthropic' || (typeof auth !== 'string' && auth?.anthropic))
249
- ) {
208
+ if (selectedProvider === 'anthropic' && auth === 'anthropic') {
250
209
  return 'anthropic';
251
210
  }
252
- if (auth === 'ai-gateway' || (typeof auth !== 'string' && auth?.gateway)) {
211
+ if (auth === 'ai-gateway') {
253
212
  return 'ai-gateway';
254
213
  }
255
214
  if (getAiGatewayAuthFromEnv({ env: processEnv }).apiKey) {
@@ -258,99 +217,47 @@ export function resolveOpenCodeAuthenticationMode({
258
217
  return selectedProvider;
259
218
  }
260
219
 
261
- function normalizeOpenCodeAuthToLegacyAuth(
262
- auth: OpenCodeAuthOptions | undefined,
263
- ): LegacyOpenCodeAuthOptions | undefined {
264
- if (auth == null || auth === 'auto') {
265
- return undefined;
266
- }
267
- if (typeof auth === 'string') {
268
- switch (auth) {
269
- case 'anthropic':
270
- return { anthropic: {} };
271
- case 'openai':
272
- return { openai: {} };
273
- case 'ai-gateway':
274
- return { gateway: {} };
275
- default:
276
- return undefined;
277
- }
278
- }
279
-
280
- console.warn(
281
- '[opencode] Passing an object to auth options is deprecated. Use a string mode ("auto" | "anthropic" | "openai" | "ai-gateway") instead, and pass credentials via environment variables.',
282
- );
283
- return auth;
284
- }
285
-
286
- function pickOpenAICompatible(
287
- explicit: NonNullable<LegacyOpenCodeAuthOptions['openaiCompatible']>,
288
- processEnv: Record<string, string | undefined>,
289
- ): Record<string, string> {
290
- const env: Record<string, string> = {};
291
- const apiKey = explicit.apiKey ?? processEnv.OPENAI_API_KEY;
292
- if (apiKey) env.OPENAI_API_KEY = apiKey;
293
- const baseUrl = explicit.baseUrl ?? processEnv.OPENAI_BASE_URL;
294
- if (baseUrl) env.OPENAI_BASE_URL = baseUrl;
295
- const name = explicit.name ?? processEnv.OPENAI_NAME;
296
- if (name) env.OPENAI_NAME = name;
297
- if (explicit.queryParams && Object.keys(explicit.queryParams).length > 0) {
298
- env.OPENAI_QUERY_PARAMS_JSON = JSON.stringify(explicit.queryParams);
299
- } else if (processEnv.OPENAI_QUERY_PARAMS_JSON) {
300
- env.OPENAI_QUERY_PARAMS_JSON = processEnv.OPENAI_QUERY_PARAMS_JSON;
301
- }
302
- return env;
303
- }
304
-
305
220
  function pickOpenAI({
306
- explicit,
307
221
  processEnv,
308
222
  }: {
309
- explicit?: NonNullable<LegacyOpenCodeAuthOptions['openai']>;
310
223
  processEnv: Record<string, string | undefined>;
311
224
  }): Record<string, string> {
312
225
  const env: Record<string, string> = {};
313
- const apiKey = explicit?.apiKey ?? processEnv.OPENAI_API_KEY;
226
+ const apiKey = processEnv.OPENAI_API_KEY;
314
227
  if (apiKey) env.OPENAI_API_KEY = apiKey;
315
- const baseUrl = explicit?.baseUrl ?? processEnv.OPENAI_BASE_URL;
228
+ const baseUrl = processEnv.OPENAI_BASE_URL;
316
229
  if (baseUrl) env.OPENAI_BASE_URL = baseUrl;
317
- const organization = explicit?.organization ?? processEnv.OPENAI_ORGANIZATION;
230
+ const organization = processEnv.OPENAI_ORGANIZATION;
318
231
  if (organization) env.OPENAI_ORGANIZATION = organization;
319
- const project = explicit?.project ?? processEnv.OPENAI_PROJECT;
232
+ const project = processEnv.OPENAI_PROJECT;
320
233
  if (project) env.OPENAI_PROJECT = project;
321
234
  return env;
322
235
  }
323
236
 
324
237
  function pickAnthropic({
325
- explicit,
326
238
  processEnv,
327
239
  }: {
328
- explicit?: NonNullable<LegacyOpenCodeAuthOptions['anthropic']>;
329
240
  processEnv: Record<string, string | undefined>;
330
241
  }): Record<string, string> {
331
242
  const env: Record<string, string> = {};
332
- const apiKey = explicit?.apiKey ?? processEnv.ANTHROPIC_API_KEY;
243
+ const apiKey = processEnv.ANTHROPIC_API_KEY;
333
244
  if (apiKey) env.ANTHROPIC_API_KEY = apiKey;
334
- const authToken = explicit?.authToken ?? processEnv.ANTHROPIC_AUTH_TOKEN;
245
+ const authToken = processEnv.ANTHROPIC_AUTH_TOKEN;
335
246
  if (authToken) env.ANTHROPIC_AUTH_TOKEN = authToken;
336
- const baseUrl = explicit?.baseUrl ?? processEnv.ANTHROPIC_BASE_URL;
247
+ const baseUrl = processEnv.ANTHROPIC_BASE_URL;
337
248
  if (baseUrl) env.ANTHROPIC_BASE_URL = baseUrl;
338
249
  return env;
339
250
  }
340
251
 
341
252
  function pickGateway({
342
- explicit,
343
253
  gatewayAuthFromEnv,
344
254
  }: {
345
- explicit: NonNullable<LegacyOpenCodeAuthOptions['gateway']>;
346
255
  gatewayAuthFromEnv: ReturnType<typeof getAiGatewayAuthFromEnv>;
347
256
  }): Record<string, string> {
348
257
  const env: Record<string, string> = {};
349
- const apiKey = explicit.apiKey ?? gatewayAuthFromEnv.apiKey;
258
+ const apiKey = gatewayAuthFromEnv.apiKey;
350
259
  if (apiKey) env.AI_GATEWAY_API_KEY = apiKey;
351
- const baseUrl = toOpenCodeGatewayBaseUrl(
352
- explicit.baseUrl ?? gatewayAuthFromEnv.baseUrl,
353
- );
260
+ const baseUrl = toOpenCodeGatewayBaseUrl(gatewayAuthFromEnv.baseUrl);
354
261
  env.AI_GATEWAY_BASE_URL = baseUrl;
355
262
  return env;
356
263
  }
@@ -57,7 +57,7 @@ import {
57
57
  resolveOpenCodeAuthenticationMode,
58
58
  resolveOpenCodeEnv,
59
59
  splitOpenCodeModel,
60
- type OpenCodeAuthOptions,
60
+ type OpenCodeAuthenticationMode,
61
61
  } from './opencode-auth';
62
62
  import {
63
63
  outboundMessageSchema,
@@ -79,7 +79,7 @@ type WriteSkillsResult = {
79
79
  const OPENCODE_CLIENT_APP = `ai-sdk/harness-opencode/${VERSION}`;
80
80
 
81
81
  export type OpenCodeHarnessSettings = {
82
- readonly auth?: OpenCodeAuthOptions;
82
+ readonly auth?: OpenCodeAuthenticationMode;
83
83
  /**
84
84
  * Customizes each credential value before it is forwarded into a sandbox
85
85
  * process. This does not restrict which credentials the harness adapter can