@ottocode/sdk 0.1.247 → 0.1.248

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.247",
3
+ "version": "0.1.248",
4
4
  "description": "AI agent SDK for building intelligent assistants - tree-shakable and comprehensive",
5
5
  "author": "nitishxyz",
6
6
  "license": "MIT",
package/src/index.ts CHANGED
@@ -40,6 +40,18 @@ export type {
40
40
  // Providers (from internal providers module)
41
41
  // =======================
42
42
  export { catalog } from './providers/src/index.ts';
43
+ export {
44
+ DEFAULT_REMOTE_MODEL_CATALOG_URL,
45
+ getModelCatalogCachePath,
46
+ mergeCachedModelCatalog,
47
+ normalizeModelCatalogPayload,
48
+ readCachedModelCatalog,
49
+ writeCachedModelCatalog,
50
+ } from './providers/src/index.ts';
51
+ export type {
52
+ CachedModelCatalog,
53
+ CachedProviderCatalogEntry,
54
+ } from './providers/src/index.ts';
43
55
  export {
44
56
  isProviderId,
45
57
  providerIds,
@@ -1,5 +1,17 @@
1
1
  export { isProviderAuthorized, ensureProviderEnv } from './authorization.ts';
2
2
  export { catalog } from './catalog-merged.ts';
3
+ export {
4
+ DEFAULT_REMOTE_MODEL_CATALOG_URL,
5
+ getModelCatalogCachePath,
6
+ mergeCachedModelCatalog,
7
+ normalizeModelCatalogPayload,
8
+ readCachedModelCatalog,
9
+ writeCachedModelCatalog,
10
+ } from './model-catalog-cache.ts';
11
+ export type {
12
+ CachedModelCatalog,
13
+ CachedProviderCatalogEntry,
14
+ } from './model-catalog-cache.ts';
3
15
  export type {
4
16
  BuiltInProviderId,
5
17
  ProviderId,
@@ -0,0 +1,107 @@
1
+ import { getGlobalConfigDir, joinPath } from '../../config/src/paths.ts';
2
+ import type { ModelInfo, ProviderId } from '../../types/src/index.ts';
3
+
4
+ export type CachedProviderCatalogEntry = {
5
+ id: ProviderId;
6
+ label?: string;
7
+ models: ModelInfo[];
8
+ };
9
+
10
+ export type CachedModelCatalog = {
11
+ version: 1;
12
+ updatedAt: string;
13
+ providers: Record<string, CachedProviderCatalogEntry>;
14
+ };
15
+
16
+ export const DEFAULT_REMOTE_MODEL_CATALOG_URL =
17
+ 'https://ottocode.io/catalog/models.json';
18
+
19
+ export function getModelCatalogCachePath(): string {
20
+ return joinPath(getGlobalConfigDir(), 'models-catalog.json');
21
+ }
22
+
23
+ function isRecord(value: unknown): value is Record<string, unknown> {
24
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
25
+ }
26
+
27
+ function normalizeProviderEntry(
28
+ id: string,
29
+ value: unknown,
30
+ ): CachedProviderCatalogEntry | null {
31
+ if (!isRecord(value)) return null;
32
+ const models = Array.isArray(value.models)
33
+ ? value.models.filter(
34
+ (model): model is ModelInfo =>
35
+ isRecord(model) && typeof model.id === 'string',
36
+ )
37
+ : [];
38
+ return {
39
+ id: (typeof value.id === 'string' ? value.id : id) as ProviderId,
40
+ label: typeof value.label === 'string' ? value.label : undefined,
41
+ models,
42
+ };
43
+ }
44
+
45
+ export function normalizeModelCatalogPayload(
46
+ payload: unknown,
47
+ ): Record<string, CachedProviderCatalogEntry> {
48
+ if (!isRecord(payload)) return {};
49
+ const source = isRecord(payload.providers) ? payload.providers : payload;
50
+ const providers: Record<string, CachedProviderCatalogEntry> = {};
51
+ for (const [id, value] of Object.entries(source)) {
52
+ const entry = normalizeProviderEntry(id, value);
53
+ if (entry) providers[id] = entry;
54
+ }
55
+ return providers;
56
+ }
57
+
58
+ export async function readCachedModelCatalog(): Promise<CachedModelCatalog | null> {
59
+ try {
60
+ const file = Bun.file(getModelCatalogCachePath());
61
+ if (!(await file.exists())) return null;
62
+ const payload = await file.json();
63
+ const providers = normalizeModelCatalogPayload(payload);
64
+ return {
65
+ version: 1,
66
+ updatedAt:
67
+ isRecord(payload) && typeof payload.updatedAt === 'string'
68
+ ? payload.updatedAt
69
+ : new Date(0).toISOString(),
70
+ providers,
71
+ };
72
+ } catch {
73
+ return null;
74
+ }
75
+ }
76
+
77
+ export async function writeCachedModelCatalog(
78
+ providers: Record<string, CachedProviderCatalogEntry>,
79
+ ): Promise<void> {
80
+ const path = getModelCatalogCachePath();
81
+ const dir = path.slice(0, path.lastIndexOf('/'));
82
+ await import('node:fs/promises').then((fs) =>
83
+ fs.mkdir(dir, { recursive: true }),
84
+ );
85
+ await Bun.write(
86
+ path,
87
+ JSON.stringify(
88
+ {
89
+ version: 1,
90
+ updatedAt: new Date().toISOString(),
91
+ providers,
92
+ },
93
+ null,
94
+ 2,
95
+ ),
96
+ );
97
+ }
98
+
99
+ export async function mergeCachedModelCatalog(
100
+ providers: Record<string, CachedProviderCatalogEntry>,
101
+ ): Promise<void> {
102
+ const existing = await readCachedModelCatalog();
103
+ await writeCachedModelCatalog({
104
+ ...(existing?.providers ?? {}),
105
+ ...providers,
106
+ });
107
+ }
@@ -133,7 +133,7 @@ export function getProviderDefinition(
133
133
  source: 'built-in',
134
134
  compatibility: BUILTIN_COMPATIBILITY[provider],
135
135
  family: BUILTIN_FAMILY[provider],
136
- baseURL: normalizeOptionalText(settings?.baseURL),
136
+ baseURL: normalizeOptionalText(settings?.baseURL) ?? entry.api,
137
137
  apiKey: normalizeOptionalText(settings?.apiKey),
138
138
  apiKeyEnv:
139
139
  normalizeOptionalText(settings?.apiKeyEnv) ?? providerEnvVar(provider),