@ottocode/sdk 0.1.230 → 0.1.232

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ottocode/sdk",
3
- "version": "0.1.230",
3
+ "version": "0.1.232",
4
4
  "description": "AI agent SDK for building intelligent assistants - tree-shakable and comprehensive",
5
5
  "author": "nitishxyz",
6
6
  "license": "MIT",
@@ -35,6 +35,7 @@ const DEFAULTS: {
35
35
  guidedMode: false,
36
36
  reasoningText: true,
37
37
  reasoningLevel: 'high',
38
+ fullWidthContent: true,
38
39
  },
39
40
  providers: DEFAULT_PROVIDER_SETTINGS,
40
41
  };
@@ -115,9 +115,15 @@ export { isDebugEnabled, isTraceEnabled } from './utils/debug.ts';
115
115
  export {
116
116
  MCPClientWrapper,
117
117
  MCPServerManager,
118
+ COPILOT_MCP_SCOPE,
118
119
  convertMCPToolsToAISDK,
120
+ getCopilotMCPOAuthKey,
121
+ getStoredCopilotMCPToken,
119
122
  getMCPManager,
123
+ hasCopilotMCPScopes,
120
124
  initializeMCP,
125
+ isGitHubCopilotUrl,
126
+ isStoredCopilotMCPAuthenticated,
121
127
  shutdownMCP,
122
128
  loadMCPConfig,
123
129
  addMCPServerToConfig,
@@ -0,0 +1,104 @@
1
+ import { createHash } from 'node:crypto';
2
+ import type { MCPScope } from './types.ts';
3
+ import type { OAuthCredentialStore } from './oauth/store.ts';
4
+
5
+ export const GITHUB_COPILOT_HOSTS = [
6
+ 'api.githubcopilot.com',
7
+ 'copilot-proxy.githubusercontent.com',
8
+ ];
9
+
10
+ export const COPILOT_MCP_REQUIRED_SCOPES = [
11
+ 'repo',
12
+ 'read:org',
13
+ 'gist',
14
+ 'notifications',
15
+ 'read:project',
16
+ 'security_events',
17
+ ];
18
+
19
+ export const COPILOT_MCP_SCOPE =
20
+ 'repo read:org read:packages gist notifications read:project security_events';
21
+
22
+ /**
23
+ * Returns whether a URL points at a GitHub Copilot-backed MCP endpoint.
24
+ */
25
+ export function isGitHubCopilotUrl(url?: string): boolean {
26
+ if (!url) return false;
27
+ try {
28
+ const parsed = new URL(url);
29
+ return GITHUB_COPILOT_HOSTS.some(
30
+ (host) =>
31
+ parsed.hostname === host || parsed.hostname.endsWith(`.${host}`),
32
+ );
33
+ } catch {
34
+ return false;
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Returns whether the stored scope string satisfies the GitHub Copilot MCP requirements.
40
+ */
41
+ export function hasCopilotMCPScopes(scopes?: string): boolean {
42
+ if (!scopes) return false;
43
+ const granted = scopes.split(/[\s,]+/).filter(Boolean);
44
+ return COPILOT_MCP_REQUIRED_SCOPES.every((scope) => granted.includes(scope));
45
+ }
46
+
47
+ /**
48
+ * Builds the MCP OAuth store key for a GitHub Copilot MCP server.
49
+ */
50
+ export function getCopilotMCPOAuthKey(
51
+ serverName: string,
52
+ scope: MCPScope = 'global',
53
+ projectRoot?: string,
54
+ ): string {
55
+ if (scope === 'project' && projectRoot) {
56
+ const hash = createHash('sha256')
57
+ .update(projectRoot)
58
+ .digest('hex')
59
+ .slice(0, 8);
60
+ return `${serverName}_proj_${hash}`;
61
+ }
62
+ return serverName;
63
+ }
64
+
65
+ /**
66
+ * Loads the stored GitHub Copilot MCP bearer token for a server.
67
+ */
68
+ export async function getStoredCopilotMCPToken(
69
+ store: OAuthCredentialStore,
70
+ serverName: string,
71
+ scope: MCPScope = 'global',
72
+ projectRoot?: string,
73
+ ): Promise<{ token: string | null; needsReauth: boolean; scopes?: string }> {
74
+ const tokens = await store.loadTokens(
75
+ getCopilotMCPOAuthKey(serverName, scope, projectRoot),
76
+ );
77
+ const token = tokens?.access_token ?? null;
78
+ if (!token) {
79
+ return { token: null, needsReauth: true };
80
+ }
81
+ return {
82
+ token,
83
+ needsReauth: !hasCopilotMCPScopes(tokens?.scope),
84
+ scopes: tokens?.scope,
85
+ };
86
+ }
87
+
88
+ /**
89
+ * Returns whether the stored GitHub Copilot MCP credentials are usable.
90
+ */
91
+ export async function isStoredCopilotMCPAuthenticated(
92
+ store: OAuthCredentialStore,
93
+ serverName: string,
94
+ scope: MCPScope = 'global',
95
+ projectRoot?: string,
96
+ ): Promise<boolean> {
97
+ const { token, needsReauth } = await getStoredCopilotMCPToken(
98
+ store,
99
+ serverName,
100
+ scope,
101
+ projectRoot,
102
+ );
103
+ return !!token && !needsReauth;
104
+ }
@@ -13,6 +13,15 @@ export { MCPServerManager } from './server-manager.ts';
13
13
 
14
14
  export { convertMCPToolsToAISDK } from './tools.ts';
15
15
 
16
+ export {
17
+ COPILOT_MCP_SCOPE,
18
+ getCopilotMCPOAuthKey,
19
+ getStoredCopilotMCPToken,
20
+ hasCopilotMCPScopes,
21
+ isGitHubCopilotUrl,
22
+ isStoredCopilotMCPAuthenticated,
23
+ } from './copilot-auth.ts';
24
+
16
25
  export {
17
26
  getMCPToolBriefs,
18
27
  buildLoadMCPToolsTool,
@@ -2,66 +2,12 @@ import { MCPClientWrapper, type MCPToolInfo } from './client.ts';
2
2
  import type { MCPServerConfig, MCPServerStatus } from './types.ts';
3
3
  import { OAuthCredentialStore } from './oauth/store.ts';
4
4
  import { OttoOAuthProvider } from './oauth/provider.ts';
5
- import { createHash } from 'node:crypto';
6
- import { getAuth } from '../../../auth/src/index.ts';
7
-
8
- const GITHUB_COPILOT_HOSTS = [
9
- 'api.githubcopilot.com',
10
- 'copilot-proxy.githubusercontent.com',
11
- ];
12
-
13
- function isGitHubCopilotUrl(url?: string): boolean {
14
- if (!url) return false;
15
- try {
16
- const parsed = new URL(url);
17
- return GITHUB_COPILOT_HOSTS.some(
18
- (h) => parsed.hostname === h || parsed.hostname.endsWith(`.${h}`),
19
- );
20
- } catch {
21
- return false;
22
- }
23
- }
24
-
25
- const COPILOT_MCP_REQUIRED_SCOPES = [
26
- 'repo',
27
- 'read:org',
28
- 'gist',
29
- 'notifications',
30
- 'read:project',
31
- 'security_events',
32
- ];
33
-
34
- function hasMCPScopes(scopes?: string): boolean {
35
- if (!scopes) return false;
36
- const granted = scopes.split(/[\s,]+/).filter(Boolean);
37
- return COPILOT_MCP_REQUIRED_SCOPES.every((s) => granted.includes(s));
38
- }
39
-
40
- async function getCopilotToken(): Promise<string | null> {
41
- try {
42
- const auth = await getAuth('copilot');
43
- if (auth?.type === 'oauth' && auth.refresh) {
44
- return auth.refresh;
45
- }
46
- } catch {}
47
- return null;
48
- }
49
-
50
- async function getCopilotMCPToken(): Promise<{
51
- token: string | null;
52
- needsReauth: boolean;
53
- }> {
54
- try {
55
- const auth = await getAuth('copilot');
56
- if (auth?.type === 'oauth' && auth.refresh) {
57
- if (!hasMCPScopes(auth.scopes)) {
58
- return { token: auth.refresh, needsReauth: true };
59
- }
60
- return { token: auth.refresh, needsReauth: false };
61
- }
62
- } catch {}
63
- return { token: null, needsReauth: true };
64
- }
5
+ import {
6
+ getCopilotMCPOAuthKey,
7
+ getStoredCopilotMCPToken,
8
+ isGitHubCopilotUrl,
9
+ isStoredCopilotMCPAuthenticated,
10
+ } from './copilot-auth.ts';
65
11
 
66
12
  type IndexedTool = {
67
13
  server: string;
@@ -88,14 +34,11 @@ export class MCPServerManager {
88
34
 
89
35
  private oauthKey(serverName: string): string {
90
36
  const scope = this.serverScopes.get(serverName);
91
- if (scope === 'project' && this.projectRoot) {
92
- const hash = createHash('sha256')
93
- .update(this.projectRoot)
94
- .digest('hex')
95
- .slice(0, 8);
96
- return `${serverName}_proj_${hash}`;
97
- }
98
- return serverName;
37
+ return getCopilotMCPOAuthKey(
38
+ serverName,
39
+ scope,
40
+ this.projectRoot ?? undefined,
41
+ );
99
42
  }
100
43
 
101
44
  async startServers(configs: MCPServerConfig[]): Promise<void> {
@@ -115,7 +58,12 @@ export class MCPServerManager {
115
58
 
116
59
  if (transport !== 'stdio') {
117
60
  if (isGitHubCopilotUrl(config.url)) {
118
- const { token, needsReauth } = await getCopilotMCPToken();
61
+ const { token, needsReauth } = await getStoredCopilotMCPToken(
62
+ this.oauthStore,
63
+ config.name,
64
+ config.scope ?? 'global',
65
+ this.projectRoot ?? undefined,
66
+ );
119
67
  if (token && !needsReauth) {
120
68
  config = {
121
69
  ...config,
@@ -159,7 +107,7 @@ export class MCPServerManager {
159
107
  return;
160
108
  }
161
109
  console.error(
162
- `[mcp] GitHub Copilot MCP server "${config.name}" requires authentication. Run \`otto auth login copilot\` or \`otto mcp auth ${config.name}\`.`,
110
+ `[mcp] GitHub Copilot MCP server "${config.name}" requires authentication. Run \`otto mcp auth ${config.name}\`.`,
163
111
  );
164
112
  this.clients.set(config.name, client);
165
113
  return;
@@ -296,7 +244,12 @@ export class MCPServerManager {
296
244
  const config = client.serverConfig;
297
245
  let authenticated = false;
298
246
  if (isGitHubCopilotUrl(config.url)) {
299
- authenticated = !!(await getCopilotToken());
247
+ authenticated = await isStoredCopilotMCPAuthenticated(
248
+ this.oauthStore,
249
+ name,
250
+ config.scope ?? 'global',
251
+ this.projectRoot ?? undefined,
252
+ ).catch(() => false);
300
253
  } else {
301
254
  const key = this.oauthKey(name);
302
255
  authenticated = await this.oauthStore
@@ -334,8 +287,13 @@ export class MCPServerManager {
334
287
  if (transport === 'stdio') return null;
335
288
 
336
289
  if (isGitHubCopilotUrl(config.url)) {
337
- const token = await getCopilotToken();
338
- if (token) {
290
+ const { token, needsReauth } = await getStoredCopilotMCPToken(
291
+ this.oauthStore,
292
+ config.name,
293
+ config.scope ?? 'global',
294
+ this.projectRoot ?? undefined,
295
+ );
296
+ if (token && !needsReauth) {
339
297
  const authedConfig = {
340
298
  ...config,
341
299
  headers: {
@@ -472,8 +430,19 @@ export class MCPServerManager {
472
430
  ): Promise<{ authenticated: boolean; expiresAt?: number }> {
473
431
  const client = this.clients.get(name);
474
432
  if (client && isGitHubCopilotUrl(client.serverConfig.url)) {
475
- const token = await getCopilotToken();
476
- return { authenticated: !!token };
433
+ const key = this.oauthKey(name);
434
+ const tokens = await this.oauthStore.loadTokens(key);
435
+ return {
436
+ authenticated:
437
+ !!tokens?.access_token &&
438
+ (await isStoredCopilotMCPAuthenticated(
439
+ this.oauthStore,
440
+ name,
441
+ client.serverConfig.scope ?? 'global',
442
+ this.projectRoot ?? undefined,
443
+ )),
444
+ expiresAt: tokens?.expires_at,
445
+ };
477
446
  }
478
447
  const key = this.oauthKey(name);
479
448
  const tokens = await this.oauthStore.loadTokens(key);
package/src/index.ts CHANGED
@@ -362,9 +362,15 @@ export type { TunnelConnection, TunnelEvents } from './tunnel/index.ts';
362
362
  export {
363
363
  MCPClientWrapper,
364
364
  MCPServerManager,
365
+ COPILOT_MCP_SCOPE,
365
366
  convertMCPToolsToAISDK,
367
+ getCopilotMCPOAuthKey,
368
+ getStoredCopilotMCPToken,
366
369
  getMCPManager,
370
+ hasCopilotMCPScopes,
367
371
  initializeMCP,
372
+ isGitHubCopilotUrl,
373
+ isStoredCopilotMCPAuthenticated,
368
374
  shutdownMCP,
369
375
  loadMCPConfig,
370
376
  addMCPServerToConfig,
@@ -14,6 +14,7 @@ const OWNER_NPM: Record<ModelOwner, string> = {
14
14
  openai: '@ai-sdk/openai',
15
15
  anthropic: '@ai-sdk/anthropic',
16
16
  google: '@ai-sdk/google',
17
+ openrouter: '@openrouter/ai-sdk-provider',
17
18
  xai: '@ai-sdk/xai',
18
19
  moonshot: '@ai-sdk/openai-compatible',
19
20
  zai: '@ai-sdk/openai-compatible',
@@ -762,7 +762,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
762
762
  ownedBy: 'openai',
763
763
  label: 'GPT-5.4',
764
764
  modalities: {
765
- input: ['text', 'image'],
765
+ input: ['text', 'image', 'pdf'],
766
766
  output: ['text'],
767
767
  },
768
768
  toolCall: true,
@@ -2323,6 +2323,57 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
2323
2323
  output: 64000,
2324
2324
  },
2325
2325
  },
2326
+ {
2327
+ id: 'gemini-3.1-flash-image-preview',
2328
+ ownedBy: 'google',
2329
+ label: 'Gemini 3.1 Flash Image (Preview)',
2330
+ modalities: {
2331
+ input: ['text', 'image', 'pdf'],
2332
+ output: ['text', 'image'],
2333
+ },
2334
+ toolCall: false,
2335
+ reasoningText: true,
2336
+ attachment: true,
2337
+ temperature: true,
2338
+ knowledge: '2025-01',
2339
+ releaseDate: '2026-02-26',
2340
+ lastUpdated: '2026-02-26',
2341
+ openWeights: false,
2342
+ cost: {
2343
+ input: 0.25,
2344
+ output: 60,
2345
+ },
2346
+ limit: {
2347
+ context: 131072,
2348
+ output: 32768,
2349
+ },
2350
+ },
2351
+ {
2352
+ id: 'gemini-3.1-flash-lite-preview',
2353
+ ownedBy: 'google',
2354
+ label: 'Gemini 3.1 Flash Lite Preview',
2355
+ modalities: {
2356
+ input: ['text', 'image', 'video', 'audio', 'pdf'],
2357
+ output: ['text'],
2358
+ },
2359
+ toolCall: true,
2360
+ reasoningText: true,
2361
+ attachment: true,
2362
+ temperature: true,
2363
+ knowledge: '2025-01',
2364
+ releaseDate: '2026-03-03',
2365
+ lastUpdated: '2026-03-03',
2366
+ openWeights: false,
2367
+ cost: {
2368
+ input: 0.5,
2369
+ output: 3,
2370
+ cacheRead: 0.05,
2371
+ },
2372
+ limit: {
2373
+ context: 1048576,
2374
+ output: 65536,
2375
+ },
2376
+ },
2326
2377
  {
2327
2378
  id: 'gemini-3.1-pro-preview',
2328
2379
  ownedBy: 'google',
@@ -3940,6 +3991,78 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
3940
3991
  output: 2000,
3941
3992
  },
3942
3993
  },
3994
+ {
3995
+ id: 'inception/mercury',
3996
+ label: 'Mercury',
3997
+ modalities: {
3998
+ input: ['text'],
3999
+ output: ['text'],
4000
+ },
4001
+ toolCall: true,
4002
+ reasoningText: false,
4003
+ attachment: false,
4004
+ temperature: true,
4005
+ releaseDate: '2025-06-26',
4006
+ lastUpdated: '2025-06-26',
4007
+ openWeights: false,
4008
+ cost: {
4009
+ input: 0.25,
4010
+ output: 0.75,
4011
+ cacheRead: 0.025,
4012
+ },
4013
+ limit: {
4014
+ context: 128000,
4015
+ output: 32000,
4016
+ },
4017
+ },
4018
+ {
4019
+ id: 'inception/mercury-2',
4020
+ label: 'Mercury 2',
4021
+ modalities: {
4022
+ input: ['text'],
4023
+ output: ['text'],
4024
+ },
4025
+ toolCall: true,
4026
+ reasoningText: true,
4027
+ attachment: false,
4028
+ temperature: true,
4029
+ releaseDate: '2026-03-04',
4030
+ lastUpdated: '2026-03-04',
4031
+ openWeights: false,
4032
+ cost: {
4033
+ input: 0.25,
4034
+ output: 0.75,
4035
+ cacheRead: 0.025,
4036
+ },
4037
+ limit: {
4038
+ context: 128000,
4039
+ output: 50000,
4040
+ },
4041
+ },
4042
+ {
4043
+ id: 'inception/mercury-coder',
4044
+ label: 'Mercury Coder',
4045
+ modalities: {
4046
+ input: ['text'],
4047
+ output: ['text'],
4048
+ },
4049
+ toolCall: true,
4050
+ reasoningText: false,
4051
+ attachment: false,
4052
+ temperature: true,
4053
+ releaseDate: '2025-04-30',
4054
+ lastUpdated: '2025-04-30',
4055
+ openWeights: false,
4056
+ cost: {
4057
+ input: 0.25,
4058
+ output: 0.75,
4059
+ cacheRead: 0.025,
4060
+ },
4061
+ limit: {
4062
+ context: 128000,
4063
+ output: 32000,
4064
+ },
4065
+ },
3943
4066
  {
3944
4067
  id: 'kwaipilot/kat-coder-pro:free',
3945
4068
  label: 'Kat Coder Pro (free)',
@@ -5743,6 +5866,77 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
5743
5866
  output: 50000,
5744
5867
  },
5745
5868
  },
5869
+ {
5870
+ id: 'openrouter/free',
5871
+ label: 'Free Models Router',
5872
+ modalities: {
5873
+ input: ['text', 'image'],
5874
+ output: ['text'],
5875
+ },
5876
+ toolCall: true,
5877
+ reasoningText: true,
5878
+ attachment: true,
5879
+ temperature: true,
5880
+ releaseDate: '2026-02-01',
5881
+ lastUpdated: '2026-02-01',
5882
+ openWeights: false,
5883
+ cost: {
5884
+ input: 0,
5885
+ output: 0,
5886
+ },
5887
+ limit: {
5888
+ context: 200000,
5889
+ output: 8000,
5890
+ },
5891
+ },
5892
+ {
5893
+ id: 'openrouter/healer-alpha',
5894
+ label: 'Healer Alpha',
5895
+ modalities: {
5896
+ input: ['text', 'image', 'audio', 'pdf'],
5897
+ output: ['text'],
5898
+ },
5899
+ toolCall: true,
5900
+ reasoningText: true,
5901
+ attachment: true,
5902
+ temperature: true,
5903
+ knowledge: '2026-03-11',
5904
+ releaseDate: '2026-03-11',
5905
+ lastUpdated: '2026-03-11',
5906
+ openWeights: false,
5907
+ cost: {
5908
+ input: 0,
5909
+ output: 0,
5910
+ },
5911
+ limit: {
5912
+ context: 262144,
5913
+ output: 64000,
5914
+ },
5915
+ },
5916
+ {
5917
+ id: 'openrouter/hunter-alpha',
5918
+ label: 'Hunter Alpha',
5919
+ modalities: {
5920
+ input: ['text', 'image', 'pdf'],
5921
+ output: ['text'],
5922
+ },
5923
+ toolCall: true,
5924
+ reasoningText: true,
5925
+ attachment: true,
5926
+ temperature: true,
5927
+ knowledge: '2026-03-11',
5928
+ releaseDate: '2026-03-11',
5929
+ lastUpdated: '2026-03-11',
5930
+ openWeights: false,
5931
+ cost: {
5932
+ input: 0,
5933
+ output: 0,
5934
+ },
5935
+ limit: {
5936
+ context: 1048576,
5937
+ output: 64000,
5938
+ },
5939
+ },
5746
5940
  {
5747
5941
  id: 'openrouter/sherlock-dash-alpha',
5748
5942
  label: 'Sherlock Dash Alpha',
@@ -8199,6 +8393,31 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
8199
8393
  output: 262144,
8200
8394
  },
8201
8395
  },
8396
+ {
8397
+ id: 'mimo-v2-flash-free',
8398
+ label: 'MiMo V2 Flash Free',
8399
+ modalities: {
8400
+ input: ['text'],
8401
+ output: ['text'],
8402
+ },
8403
+ toolCall: true,
8404
+ reasoningText: true,
8405
+ attachment: false,
8406
+ temperature: true,
8407
+ knowledge: '2024-12',
8408
+ releaseDate: '2025-12-16',
8409
+ lastUpdated: '2025-12-16',
8410
+ openWeights: true,
8411
+ cost: {
8412
+ input: 0,
8413
+ output: 0,
8414
+ cacheRead: 0,
8415
+ },
8416
+ limit: {
8417
+ context: 262144,
8418
+ output: 65536,
8419
+ },
8420
+ },
8202
8421
  {
8203
8422
  id: 'minimax-m2.1',
8204
8423
  ownedBy: 'minimax',
@@ -8309,6 +8528,31 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
8309
8528
  npm: '@ai-sdk/anthropic',
8310
8529
  },
8311
8530
  },
8531
+ {
8532
+ id: 'nemotron-3-super-free',
8533
+ label: 'Nemotron 3 Super Free',
8534
+ modalities: {
8535
+ input: ['text'],
8536
+ output: ['text'],
8537
+ },
8538
+ toolCall: true,
8539
+ reasoningText: true,
8540
+ attachment: false,
8541
+ temperature: true,
8542
+ knowledge: '2026-02',
8543
+ releaseDate: '2026-03-11',
8544
+ lastUpdated: '2026-03-11',
8545
+ openWeights: true,
8546
+ cost: {
8547
+ input: 0,
8548
+ output: 0,
8549
+ cacheRead: 0,
8550
+ },
8551
+ limit: {
8552
+ context: 1000000,
8553
+ output: 128000,
8554
+ },
8555
+ },
8312
8556
  {
8313
8557
  id: 'qwen3-coder',
8314
8558
  label: 'Qwen3 Coder',
@@ -8593,7 +8837,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
8593
8837
  temperature: true,
8594
8838
  releaseDate: '2026-02-11',
8595
8839
  lastUpdated: '2026-02-11',
8596
- openWeights: false,
8840
+ openWeights: true,
8597
8841
  cost: {
8598
8842
  input: 1,
8599
8843
  output: 3.2,
@@ -8868,7 +9112,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
8868
9112
  temperature: true,
8869
9113
  releaseDate: '2026-02-11',
8870
9114
  lastUpdated: '2026-02-11',
8871
- openWeights: false,
9115
+ openWeights: true,
8872
9116
  cost: {
8873
9117
  input: 0,
8874
9118
  output: 0,
@@ -9661,7 +9905,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
9661
9905
  output: 0,
9662
9906
  },
9663
9907
  limit: {
9664
- context: 128000,
9908
+ context: 264000,
9665
9909
  output: 64000,
9666
9910
  },
9667
9911
  },
@@ -9686,7 +9930,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
9686
9930
  output: 0,
9687
9931
  },
9688
9932
  limit: {
9689
- context: 272000,
9933
+ context: 400000,
9690
9934
  output: 128000,
9691
9935
  },
9692
9936
  },
@@ -4,6 +4,7 @@ import { getModelNpmBinding } from './utils.ts';
4
4
 
5
5
  export type OpenRouterProviderConfig = {
6
6
  apiKey?: string;
7
+ baseURL?: string;
7
8
  };
8
9
 
9
10
  function isAnthropicModel(model: string): boolean {
@@ -129,6 +129,7 @@ const OWNER_TO_FAMILY: Record<ModelOwner, UnderlyingProviderKey> = {
129
129
  openai: 'openai',
130
130
  anthropic: 'anthropic',
131
131
  google: 'google',
132
+ openrouter: 'openai-compatible',
132
133
  xai: 'openai',
133
134
  moonshot: 'moonshot',
134
135
  zai: 'glm',
@@ -26,6 +26,7 @@ export type DefaultConfig = {
26
26
  reasoningText?: boolean;
27
27
  reasoningLevel?: ReasoningLevel;
28
28
  theme?: string;
29
+ fullWidthContent?: boolean;
29
30
  };
30
31
 
31
32
  export type ProviderSettings = Record<
@@ -33,6 +33,7 @@ export type ModelOwner =
33
33
  | 'openai'
34
34
  | 'anthropic'
35
35
  | 'google'
36
+ | 'openrouter'
36
37
  | 'xai'
37
38
  | 'moonshot'
38
39
  | 'zai'