@push.rocks/smartai 2.0.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,97 @@
1
- import type { LanguageModelV3 } from '@ai-sdk/provider';
1
+ import type { JSONObject, JSONValue, LanguageModelV3, LanguageModelV3Prompt } from '@ai-sdk/provider';
2
+ import type { ISmartAiCacheOptions } from './smartai.cache.js';
2
3
  export type TProvider = 'anthropic' | 'openai' | 'google' | 'groq' | 'mistral' | 'xai' | 'perplexity' | 'ollama';
4
+ export type TOpenAiReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
5
+ export type TOpenAiTextVerbosity = 'low' | 'medium' | 'high';
6
+ export interface IOpenAiMaxIdTokenInfo {
7
+ email?: string;
8
+ chatgptPlanType?: string;
9
+ chatgptUserId?: string;
10
+ chatgptAccountId?: string;
11
+ chatgptAccountIsFedramp: boolean;
12
+ expiresAt?: string;
13
+ rawJwt: string;
14
+ }
15
+ export interface IOpenAiMaxAuthCredentials {
16
+ accessToken: string;
17
+ refreshToken?: string;
18
+ idToken?: string;
19
+ accountId?: string;
20
+ idTokenInfo?: IOpenAiMaxIdTokenInfo;
21
+ baseUrl?: string;
22
+ originator?: string;
23
+ }
24
+ export interface IOpenAiMaxTokenData extends IOpenAiMaxAuthCredentials {
25
+ refreshToken: string;
26
+ idToken: string;
27
+ idTokenInfo: IOpenAiMaxIdTokenInfo;
28
+ }
29
+ export interface IOpenAiMaxDeviceCode {
30
+ verificationUrl: string;
31
+ userCode: string;
32
+ deviceAuthId: string;
33
+ intervalSeconds: number;
34
+ }
35
+ export interface IOpenAiMaxAuthOptions {
36
+ issuer?: string;
37
+ clientId?: string;
38
+ fetch?: typeof fetch;
39
+ }
40
+ export interface IOpenAiMaxDeviceCodePollOptions extends IOpenAiMaxAuthOptions {
41
+ timeoutMs?: number;
42
+ sleep?: (ms: number) => Promise<void>;
43
+ }
44
+ export interface IOpenAiMaxCompleteDeviceCodeOptions extends IOpenAiMaxDeviceCodePollOptions {
45
+ forcedChatGptWorkspaceId?: string;
46
+ }
47
+ export interface IOpenAiProviderOptions extends JSONObject {
48
+ conversation?: string | null;
49
+ include?: string[] | null;
50
+ instructions?: string | null;
51
+ logitBias?: Record<string, number>;
52
+ logprobs?: boolean | number | null;
53
+ maxCompletionTokens?: number;
54
+ maxToolCalls?: number | null;
55
+ metadata?: JSONObject | null;
56
+ parallelToolCalls?: boolean | null;
57
+ previousResponseId?: string | null;
58
+ prediction?: JSONObject;
59
+ promptCacheKey?: string | null;
60
+ promptCacheRetention?: 'in_memory' | '24h' | null;
61
+ reasoningEffort?: TOpenAiReasoningEffort | null;
62
+ reasoningSummary?: string | null;
63
+ safetyIdentifier?: string | null;
64
+ serviceTier?: 'auto' | 'flex' | 'priority' | 'default' | null;
65
+ store?: boolean | null;
66
+ strictJsonSchema?: boolean | null;
67
+ systemMessageMode?: 'remove' | 'system' | 'developer';
68
+ textVerbosity?: TOpenAiTextVerbosity | null;
69
+ truncation?: 'auto' | 'disabled' | null;
70
+ user?: string | null;
71
+ forceReasoning?: boolean;
72
+ [key: string]: JSONValue | undefined;
73
+ }
74
+ export type TSmartAiProviderOptions = Record<string, JSONObject> & {
75
+ openai?: IOpenAiProviderOptions;
76
+ };
77
+ export interface ISmartAiModelSetup {
78
+ model: LanguageModelV3;
79
+ providerOptions?: TSmartAiProviderOptions;
80
+ }
3
81
  export interface ISmartAiOptions {
4
82
  provider: TProvider;
5
83
  model: string;
6
84
  apiKey?: string;
85
+ /**
86
+ * OpenAI ChatGPT/Codex subscription credentials from the device-code auth flow.
87
+ * Only used when provider === 'openai'.
88
+ */
89
+ openAiMaxAuth?: IOpenAiMaxAuthCredentials;
90
+ /**
91
+ * Provider-specific AI SDK generation options.
92
+ * Pass this to generateText()/streamText() alongside the model.
93
+ */
94
+ providerOptions?: TSmartAiProviderOptions;
7
95
  /** For Ollama: base URL of the local server. Default: http://localhost:11434 */
8
96
  baseUrl?: string;
9
97
  /**
@@ -15,7 +103,7 @@ export interface ISmartAiOptions {
15
103
  * Enable Anthropic prompt caching on system + recent messages.
16
104
  * Only used when provider === 'anthropic'. Default: true.
17
105
  */
18
- promptCaching?: boolean;
106
+ promptCaching?: boolean | ISmartAiCacheOptions;
19
107
  }
20
108
  /**
21
109
  * Ollama model runtime options passed in the request body `options` field.
@@ -38,4 +126,4 @@ export interface IOllamaModelOptions {
38
126
  */
39
127
  think?: boolean;
40
128
  }
41
- export type { LanguageModelV3 };
129
+ export type { LanguageModelV3, LanguageModelV3Prompt };
@@ -1,7 +1,8 @@
1
1
  import type { LanguageModelV3Middleware } from '@ai-sdk/provider';
2
+ import type { ISmartAiCacheOptions } from './smartai.cache.js';
2
3
  /**
3
4
  * Creates middleware that adds Anthropic prompt caching directives.
4
5
  * Marks the last system message and last user message with ephemeral cache control,
5
6
  * reducing input token cost and latency on repeated calls.
6
7
  */
7
- export declare function createAnthropicCachingMiddleware(): LanguageModelV3Middleware;
8
+ export declare function createAnthropicCachingMiddleware(options?: ISmartAiCacheOptions): LanguageModelV3Middleware;
@@ -1,36 +1,10 @@
1
+ import { createSmartAiCachingMiddleware } from './smartai.cache.js';
1
2
  /**
2
3
  * Creates middleware that adds Anthropic prompt caching directives.
3
4
  * Marks the last system message and last user message with ephemeral cache control,
4
5
  * reducing input token cost and latency on repeated calls.
5
6
  */
6
- export function createAnthropicCachingMiddleware() {
7
- return {
8
- specificationVersion: 'v3',
9
- transformParams: async ({ params }) => {
10
- const messages = [...params.prompt];
11
- // Find the last system message and last user message
12
- let lastSystemIdx = -1;
13
- let lastUserIdx = -1;
14
- for (let i = 0; i < messages.length; i++) {
15
- if (messages[i].role === 'system')
16
- lastSystemIdx = i;
17
- if (messages[i].role === 'user')
18
- lastUserIdx = i;
19
- }
20
- const targets = [lastSystemIdx, lastUserIdx].filter(i => i >= 0);
21
- for (const idx of targets) {
22
- const msg = { ...messages[idx] };
23
- msg.providerOptions = {
24
- ...(msg.providerOptions || {}),
25
- anthropic: {
26
- ...(msg.providerOptions?.anthropic || {}),
27
- cacheControl: { type: 'ephemeral' },
28
- },
29
- };
30
- messages[idx] = msg;
31
- }
32
- return { ...params, prompt: messages };
33
- },
34
- };
7
+ export function createAnthropicCachingMiddleware(options = {}) {
8
+ return createSmartAiCachingMiddleware({ ...options, provider: 'anthropic' });
35
9
  }
36
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhaS5taWRkbGV3YXJlLmFudGhyb3BpYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0YWkubWlkZGxld2FyZS5hbnRocm9waWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUE7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxnQ0FBZ0M7SUFDOUMsT0FBTztRQUNMLG9CQUFvQixFQUFFLElBQUk7UUFDMUIsZUFBZSxFQUFFLEtBQUssRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUU7WUFDcEMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQW1DLENBQUM7WUFFdEUscURBQXFEO1lBQ3JELElBQUksYUFBYSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3ZCLElBQUksV0FBVyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3JCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ3pDLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxRQUFRO29CQUFFLGFBQWEsR0FBRyxDQUFDLENBQUM7Z0JBQ3JELElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxNQUFNO29CQUFFLFdBQVcsR0FBRyxDQUFDLENBQUM7WUFDbkQsQ0FBQztZQUVELE1BQU0sT0FBTyxHQUFHLENBQUMsYUFBYSxFQUFFLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNqRSxLQUFLLE1BQU0sR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUMxQixNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2pDLEdBQUcsQ0FBQyxlQUFlLEdBQUc7b0JBQ3BCLEdBQUcsQ0FBQyxHQUFHLENBQUMsZUFBMEMsSUFBSSxFQUFFLENBQUM7b0JBQ3pELFNBQVMsRUFBRTt3QkFDVCxHQUFHLENBQUUsR0FBRyxDQUFDLGVBQTJDLEVBQUUsU0FBb0MsSUFBSSxFQUFFLENBQUM7d0JBQ2pHLFlBQVksRUFBRSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUU7cUJBQ3BDO2lCQUNGLENBQUM7Z0JBQ0YsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztZQUN0QixDQUFDO1lBRUQsT0FBTyxFQUFFLEdBQUcsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUE0QyxFQUFFLENBQUM7UUFDN0UsQ0FBQztLQUNGLENBQUM7QUFDSixDQUFDIn0=
10
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhaS5taWRkbGV3YXJlLmFudGhyb3BpYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0YWkubWlkZGxld2FyZS5hbnRocm9waWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFHcEU7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxnQ0FBZ0MsQ0FBQyxVQUFnQyxFQUFFO0lBQ2pGLE9BQU8sOEJBQThCLENBQUMsRUFBRSxHQUFHLE9BQU8sRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztBQUMvRSxDQUFDIn0=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@push.rocks/smartai",
3
- "version": "2.0.1",
3
+ "version": "2.3.0",
4
4
  "private": false,
5
5
  "description": "Provider registry and capability utilities for ai-sdk (Vercel AI SDK). Core export returns LanguageModel; subpath exports provide vision, audio, image, document and research capabilities.",
6
6
  "main": "dist_ts/index.js",
@@ -34,37 +34,31 @@
34
34
  },
35
35
  "author": "Task Venture Capital GmbH",
36
36
  "license": "MIT",
37
- "scripts": {
38
- "test": "(tstest test/ --verbose --logfile)",
39
- "typecheck": "tsbuild check",
40
- "build": "(tsbuild tsfolders)",
41
- "buildDocs": "(tsdoc)"
42
- },
43
37
  "devDependencies": {
44
- "@git.zone/tsbuild": "^4.4.0",
45
- "@git.zone/tsrun": "^2.0.2",
46
- "@git.zone/tstest": "^3.6.3",
47
- "@push.rocks/qenv": "^6.1.3",
38
+ "@git.zone/tsbuild": "^4.4.1",
39
+ "@git.zone/tsrun": "^2.0.4",
40
+ "@git.zone/tstest": "^3.6.6",
41
+ "@push.rocks/qenv": "^6.1.4",
48
42
  "@types/json-schema": "^7.0.15",
49
43
  "@types/lodash.clonedeep": "^4.5.9",
50
- "@types/node": "^25.6.0",
44
+ "@types/node": "^25.7.0",
51
45
  "@types/pngjs": "^6.0.5",
52
46
  "typescript": "^6.0.3",
53
- "undici-types": "^8.1.0"
47
+ "undici-types": "^8.2.0"
54
48
  },
55
49
  "dependencies": {
56
- "@ai-sdk/anthropic": "^3.0.72",
57
- "@ai-sdk/google": "^3.0.65",
58
- "@ai-sdk/groq": "^3.0.36",
59
- "@ai-sdk/mistral": "^3.0.31",
60
- "@ai-sdk/openai": "^3.0.54",
61
- "@ai-sdk/perplexity": "^3.0.30",
62
- "@ai-sdk/provider": "^3.0.9",
63
- "@ai-sdk/xai": "^3.0.84",
64
- "@anthropic-ai/sdk": "0.91.0",
50
+ "@ai-sdk/anthropic": "^3.0.77",
51
+ "@ai-sdk/google": "^3.0.73",
52
+ "@ai-sdk/groq": "^3.0.39",
53
+ "@ai-sdk/mistral": "^3.0.36",
54
+ "@ai-sdk/openai": "^3.0.63",
55
+ "@ai-sdk/perplexity": "^3.0.33",
56
+ "@ai-sdk/provider": "^3.0.10",
57
+ "@ai-sdk/xai": "^3.0.89",
58
+ "@anthropic-ai/sdk": "0.95.2",
65
59
  "@push.rocks/smartpdf": "^4.2.2",
66
- "ai": "^6.0.170",
67
- "openai": "^6.35.0"
60
+ "ai": "^6.0.180",
61
+ "openai": "^6.37.0"
68
62
  },
69
63
  "repository": {
70
64
  "type": "git",
@@ -115,11 +109,10 @@
115
109
  "AI toolkit",
116
110
  "provider switching"
117
111
  ],
118
- "pnpm": {
119
- "onlyBuiltDependencies": [
120
- "esbuild",
121
- "puppeteer"
122
- ]
123
- },
124
- "packageManager": "pnpm@10.28.2"
125
- }
112
+ "scripts": {
113
+ "test": "(tstest test/ --verbose --logfile)",
114
+ "typecheck": "tsbuild check",
115
+ "build": "(tsbuild tsfolders)",
116
+ "buildDocs": "(tsdoc)"
117
+ }
118
+ }
package/readme.hints.md CHANGED
@@ -6,9 +6,11 @@ The package is a **provider registry** built on the Vercel AI SDK (`ai` v6). The
6
6
 
7
7
  ### Core Entry (`ts/`)
8
8
  - `getModel(options)` → returns `LanguageModelV3` for any supported provider
9
+ - `getModelSetup(options)` → returns `{ model, providerOptions }` for request-time AI SDK provider options
9
10
  - Providers: anthropic, openai, google, groq, mistral, xai, perplexity, ollama
10
11
  - Anthropic prompt caching via `wrapLanguageModel` middleware (enabled by default)
11
12
  - Custom Ollama provider implementing `LanguageModelV3` directly (for think, num_ctx support)
13
+ - OpenAI ChatGPT/Max device-code auth in `smartai.auth.openai.ts`; `openAiMaxAuth` routes OpenAI models to the ChatGPT Codex backend
12
14
 
13
15
  ### Subpath Exports
14
16
  - `@push.rocks/smartai/vision` — `analyzeImage()` using `generateText` with image content
@@ -19,11 +21,11 @@ The package is a **provider registry** built on the Vercel AI SDK (`ai` v6). The
19
21
 
20
22
  ## Dependencies
21
23
 
22
- - `ai` ^6.0.116 — Vercel AI SDK core
24
+ - `ai` ^6.0.175 — Vercel AI SDK core
23
25
  - `@ai-sdk/*` — Provider packages (anthropic, openai, google, groq, mistral, xai, perplexity)
24
- - `@ai-sdk/provider` ^3.0.8 — LanguageModelV3 types
25
- - `@anthropic-ai/sdk` ^0.78.0 — Direct SDK for research (web search tool)
26
- - `openai` ^6.25.0 — Direct SDK for audio TTS and image generation/editing
26
+ - `@ai-sdk/provider` ^3.0.10 — LanguageModelV3 types
27
+ - `@anthropic-ai/sdk` ^0.95.0 — Direct SDK for research (web search tool)
28
+ - `openai` ^6.36.0 — Direct SDK for audio TTS and image generation/editing
27
29
  - `@push.rocks/smartpdf` ^4.1.3 — PDF to PNG conversion for document analysis
28
30
 
29
31
  ## Build
@@ -40,6 +42,9 @@ The package is a **provider registry** built on the Vercel AI SDK (`ai` v6). The
40
42
  - Ollama `think` param goes at request body top level, not inside `options`
41
43
  - Qwen models get default temperature 0.55 in the custom Ollama provider
42
44
  - `qenv.getEnvVarOnDemand()` returns a Promise — must be awaited in tests
45
+ - OpenAI reasoning options belong in AI SDK `providerOptions`, not model construction options
46
+ - SmartAI accepts OpenAI model IDs as plain strings, including `gpt-5.5`
47
+ - ChatGPT-authenticated OpenAI model calls use `https://chatgpt.com/backend-api/codex` plus bearer access token and `ChatGPT-Account-ID`, not `https://api.openai.com/v1`
43
48
 
44
49
  ## Testing
45
50
 
package/readme.md CHANGED
@@ -17,7 +17,7 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
17
17
  - **🔌 One function, eight providers** — `getModel()` returns a standard `LanguageModelV3`. Switch providers by changing a string.
18
18
  - **🧱 Built on Vercel AI SDK** — Uses `ai` v6 under the hood. Your model works with `generateText()`, `streamText()`, tool calling, structured output, and everything else in the AI SDK ecosystem.
19
19
  - **🏠 Custom Ollama provider** — A full `LanguageModelV3` implementation for Ollama with support for `think` mode, `num_ctx`, auto-tuned temperature for Qwen models, and native tool calling.
20
- - **💰 Anthropic prompt caching** — Automatic `cacheControl` middleware reduces cost and latency on repeated calls. Enabled by default, opt out with `promptCaching: false`.
20
+ - **💰 Prompt caching** — Anthropic cache-control middleware is enabled by default; provider cache helpers are available for agent/session integrations.
21
21
  - **📦 Modular subpath exports** — Vision, audio, image, document, and research capabilities ship as separate imports. Only import what you need.
22
22
  - **⚡ Zero lock-in** — Your code uses standard AI SDK types. Swap providers without touching application logic.
23
23
 
@@ -70,11 +70,67 @@ const options: ISmartAiOptions = {
70
70
  baseUrl: 'http://localhost:11434',
71
71
  // Ollama-only: model runtime options
72
72
  ollamaOptions: { think: true, num_ctx: 4096 },
73
+ // OpenAI request-time options for generateText()/streamText()
74
+ providerOptions: { openai: { reasoningEffort: 'xhigh' } },
73
75
  };
74
76
 
75
77
  const model = getModel(options);
76
78
  ```
77
79
 
80
+ ### `getModelSetup(options): { model, providerOptions }`
81
+
82
+ Use this when a provider needs request-time AI SDK `providerOptions`, such as GPT-5 reasoning settings for OpenAI. `getModel()` remains available for existing consumers; `getModelSetup()` returns the same model plus provider options to pass into `generateText()` or `streamText()`.
83
+
84
+ ```typescript
85
+ import { getModelSetup, generateText } from '@push.rocks/smartai';
86
+
87
+ const setup = getModelSetup({
88
+ provider: 'openai',
89
+ apiKey: process.env.OPENAI_API_KEY,
90
+ model: 'gpt-5.5',
91
+ providerOptions: {
92
+ openai: {
93
+ reasoningEffort: 'xhigh',
94
+ textVerbosity: 'high',
95
+ },
96
+ },
97
+ });
98
+
99
+ const result = await generateText({
100
+ model: setup.model,
101
+ prompt: 'Draft a careful migration plan.',
102
+ providerOptions: setup.providerOptions,
103
+ });
104
+
105
+ console.log(result.text);
106
+ ```
107
+
108
+ OpenAI `reasoningEffort` supports `'none'`, `'minimal'`, `'low'`, `'medium'`, `'high'`, and `'xhigh'`. Model IDs are accepted as strings, so new IDs like `'gpt-5.5'` can be used before upstream model unions are updated.
109
+
110
+ ### OpenAI Max / ChatGPT Auth
111
+
112
+ SmartAI can request ChatGPT subscription-backed Codex credentials with OpenAI's device-code flow. The returned credentials are passed to `getModel()` through `openAiMaxAuth`; SmartAI then routes OpenAI model calls through the ChatGPT Codex backend with the required account headers.
113
+
114
+ ```typescript
115
+ import {
116
+ completeOpenAiMaxDeviceCodeLogin,
117
+ getModel,
118
+ requestOpenAiMaxDeviceCode,
119
+ } from '@push.rocks/smartai';
120
+
121
+ const deviceCode = await requestOpenAiMaxDeviceCode();
122
+ console.log(`Open ${deviceCode.verificationUrl} and enter ${deviceCode.userCode}`);
123
+
124
+ const openAiMaxAuth = await completeOpenAiMaxDeviceCodeLogin(deviceCode);
125
+ const model = getModel({
126
+ provider: 'openai',
127
+ model: 'gpt-5.5',
128
+ openAiMaxAuth,
129
+ });
130
+ ```
131
+
132
+ Use `refreshOpenAiMaxTokenData(openAiMaxAuth)` before stored credentials expire, or after receiving an unauthorized response.
133
+
78
134
  ### Re-exported AI SDK Functions
79
135
 
80
136
  SmartAI re-exports the most commonly used functions from `ai` for convenience:
@@ -101,7 +157,7 @@ import type {
101
157
  | Provider | Package | Example Models |
102
158
  |----------|---------|----------------|
103
159
  | **Anthropic** | `@ai-sdk/anthropic` | `claude-sonnet-4-5-20250929`, `claude-opus-4-5-20250929` |
104
- | **OpenAI** | `@ai-sdk/openai` | `gpt-4o`, `gpt-4o-mini`, `o3-mini` |
160
+ | **OpenAI** | `@ai-sdk/openai` | `gpt-5.5`, `gpt-5`, `gpt-4o`, `o3-mini` |
105
161
  | **Google** | `@ai-sdk/google` | `gemini-2.0-flash`, `gemini-2.5-pro` |
106
162
  | **Groq** | `@ai-sdk/groq` | `llama-3.3-70b-versatile`, `mixtral-8x7b-32768` |
107
163
  | **Mistral** | `@ai-sdk/mistral` | `mistral-large-latest`, `mistral-small-latest` |
@@ -218,9 +274,9 @@ console.log(result.text);
218
274
  - **Streaming with reasoning** — `doStream()` emits proper `reasoning-start`, `reasoning-delta`, `reasoning-end` parts alongside text.
219
275
  - **All Ollama options** — `num_ctx`, `top_k`, `top_p`, `repeat_penalty`, `num_predict`, `stop`, `seed`.
220
276
 
221
- ## 💰 Anthropic Prompt Caching
277
+ ## 💰 Prompt Caching
222
278
 
223
- When using the Anthropic provider, SmartAI automatically wraps the model with caching middleware that adds `cacheControl: { type: 'ephemeral' }` to the last system message and last user message. This can significantly reduce cost and latency for repeated calls with the same system prompt.
279
+ When using the Anthropic provider, SmartAI automatically wraps the model with caching middleware. The middleware follows the same breakpoint strategy used by opencode: cache the first two system messages and the two most recent non-system messages. This can significantly reduce cost and latency for repeated agent calls with stable system/tool context.
224
280
 
225
281
  ```typescript
226
282
  // Caching enabled by default
@@ -239,6 +295,17 @@ const modelNoCaching = getModel({
239
295
  });
240
296
  ```
241
297
 
298
+ Longer Anthropic cache TTL is opt-in:
299
+
300
+ ```typescript
301
+ const modelWithOneHourCache = getModel({
302
+ provider: 'anthropic',
303
+ model: 'claude-sonnet-4-5-20250929',
304
+ apiKey: process.env.ANTHROPIC_TOKEN,
305
+ promptCaching: { retention: '1h' },
306
+ });
307
+ ```
308
+
242
309
  You can also use the middleware directly:
243
310
 
244
311
  ```typescript
@@ -249,6 +316,23 @@ const middleware = createAnthropicCachingMiddleware();
249
316
  const cachedModel = wrapLanguageModel({ model: baseModel, middleware });
250
317
  ```
251
318
 
319
+ For agent frameworks, SmartAI exports lower-level helpers:
320
+
321
+ ```typescript
322
+ import {
323
+ applySmartAiCacheProviderOptions,
324
+ createSmartAiCachingMiddleware,
325
+ } from '@push.rocks/smartai';
326
+
327
+ const providerOptions = applySmartAiCacheProviderOptions({
328
+ provider: 'openai',
329
+ sessionId: 'stable-session-id',
330
+ cache: 'auto',
331
+ });
332
+ ```
333
+
334
+ OpenAI request-level cache affinity is only added when a stable `sessionId` or explicit cache `key` is provided. Extended OpenAI retention (`'24h'`) is opt-in.
335
+
252
336
  ## 📦 Subpath Exports
253
337
 
254
338
  SmartAI provides specialized capabilities as separate subpath imports. Each one is a focused utility that takes a model (or API key) and does one thing well.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartai',
6
- version: '2.0.1',
6
+ version: '2.3.0',
7
7
  description: 'Provider registry and capability utilities for ai-sdk (Vercel AI SDK). Core export returns LanguageModel; subpath exports provide vision, audio, image, document and research capabilities.'
8
8
  }
package/ts/index.ts CHANGED
@@ -1,7 +1,56 @@
1
- export { getModel } from './smartai.classes.smartai.js';
2
- export type { ISmartAiOptions, TProvider, IOllamaModelOptions, LanguageModelV3 } from './smartai.interfaces.js';
1
+ export { getModel, getModelSetup } from './smartai.classes.smartai.js';
2
+ export type {
3
+ IOpenAiProviderOptions,
4
+ IOpenAiMaxAuthCredentials,
5
+ IOpenAiMaxAuthOptions,
6
+ IOpenAiMaxCompleteDeviceCodeOptions,
7
+ IOpenAiMaxDeviceCode,
8
+ IOpenAiMaxDeviceCodePollOptions,
9
+ IOpenAiMaxIdTokenInfo,
10
+ IOpenAiMaxTokenData,
11
+ ISmartAiModelSetup,
12
+ ISmartAiOptions,
13
+ TOpenAiReasoningEffort,
14
+ TOpenAiTextVerbosity,
15
+ TProvider,
16
+ TSmartAiProviderOptions,
17
+ IOllamaModelOptions,
18
+ LanguageModelV3,
19
+ LanguageModelV3Prompt,
20
+ } from './smartai.interfaces.js';
3
21
  export { createAnthropicCachingMiddleware } from './smartai.middleware.anthropic.js';
22
+ export {
23
+ applySmartAiCacheProviderOptions,
24
+ applySmartAiPromptCaching,
25
+ createSmartAiCachingMiddleware,
26
+ getSmartAiCacheProviderOptions,
27
+ getSmartAiMessageCacheProviderOptions,
28
+ mergeSmartAiProviderOptions,
29
+ resolveSmartAiCacheProvider,
30
+ } from './smartai.cache.js';
31
+ export type {
32
+ ISmartAiCacheOptions,
33
+ TSmartAiCacheRetention,
34
+ TSmartAiCacheSetting,
35
+ TSmartAiMessageCacheProvider,
36
+ } from './smartai.cache.js';
4
37
  export { createOllamaModel } from './smartai.provider.ollama.js';
38
+ export {
39
+ OPENAI_MAX_AUTH_ISSUER,
40
+ OPENAI_MAX_CLIENT_ID,
41
+ OPENAI_MAX_CODEX_BASE_URL,
42
+ OPENAI_MAX_DEFAULT_ORIGINATOR,
43
+ OpenAiMaxAuthError,
44
+ completeOpenAiMaxDeviceCodeLogin,
45
+ createOpenAiMaxProviderSettings,
46
+ ensureOpenAiMaxWorkspaceAllowed,
47
+ exchangeOpenAiMaxAuthorizationCode,
48
+ parseOpenAiMaxIdToken,
49
+ pollOpenAiMaxDeviceCode,
50
+ refreshOpenAiMaxTokenData,
51
+ requestOpenAiMaxDeviceCode,
52
+ } from './smartai.auth.openai.js';
53
+ export type { IOpenAiMaxAuthorizationCode } from './smartai.auth.openai.js';
5
54
 
6
55
  // Re-export commonly used ai-sdk functions for consumer convenience
7
56
  export { generateText, streamText, tool, jsonSchema } from 'ai';