@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.
package/.smartconfig.json CHANGED
@@ -11,12 +11,17 @@
11
11
  "projectDomain": "push.rocks"
12
12
  },
13
13
  "release": {
14
- "registries": [
15
- "https://verdaccio.lossless.digital",
16
- "https://registry.npmjs.org"
17
- ],
18
- "accessLevel": "public"
19
- }
14
+ "targets": {
15
+ "npm": {
16
+ "registries": [
17
+ "https://verdaccio.lossless.digital",
18
+ "https://registry.npmjs.org"
19
+ ],
20
+ "accessLevel": "public"
21
+ }
22
+ }
23
+ },
24
+ "schemaVersion": 2
20
25
  },
21
26
  "@git.zone/tsdoc": {
22
27
  "legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
@@ -24,4 +29,4 @@
24
29
  "@ship.zone/szci": {
25
30
  "npmGlobalTools": []
26
31
  }
27
- }
32
+ }
@@ -3,7 +3,7 @@
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
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxxQkFBcUI7SUFDM0IsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLDZMQUE2TDtDQUMzTSxDQUFBIn0=
@@ -1,6 +1,10 @@
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 { IOpenAiProviderOptions, IOpenAiMaxAuthCredentials, IOpenAiMaxAuthOptions, IOpenAiMaxCompleteDeviceCodeOptions, IOpenAiMaxDeviceCode, IOpenAiMaxDeviceCodePollOptions, IOpenAiMaxIdTokenInfo, IOpenAiMaxTokenData, ISmartAiModelSetup, ISmartAiOptions, TOpenAiReasoningEffort, TOpenAiTextVerbosity, TProvider, TSmartAiProviderOptions, IOllamaModelOptions, LanguageModelV3, LanguageModelV3Prompt, } from './smartai.interfaces.js';
3
3
  export { createAnthropicCachingMiddleware } from './smartai.middleware.anthropic.js';
4
+ export { applySmartAiCacheProviderOptions, applySmartAiPromptCaching, createSmartAiCachingMiddleware, getSmartAiCacheProviderOptions, getSmartAiMessageCacheProviderOptions, mergeSmartAiProviderOptions, resolveSmartAiCacheProvider, } from './smartai.cache.js';
5
+ export type { ISmartAiCacheOptions, TSmartAiCacheRetention, TSmartAiCacheSetting, TSmartAiMessageCacheProvider, } from './smartai.cache.js';
4
6
  export { createOllamaModel } from './smartai.provider.ollama.js';
7
+ export { OPENAI_MAX_AUTH_ISSUER, OPENAI_MAX_CLIENT_ID, OPENAI_MAX_CODEX_BASE_URL, OPENAI_MAX_DEFAULT_ORIGINATOR, OpenAiMaxAuthError, completeOpenAiMaxDeviceCodeLogin, createOpenAiMaxProviderSettings, ensureOpenAiMaxWorkspaceAllowed, exchangeOpenAiMaxAuthorizationCode, parseOpenAiMaxIdToken, pollOpenAiMaxDeviceCode, refreshOpenAiMaxTokenData, requestOpenAiMaxDeviceCode, } from './smartai.auth.openai.js';
8
+ export type { IOpenAiMaxAuthorizationCode } from './smartai.auth.openai.js';
5
9
  export { generateText, streamText, tool, jsonSchema } from 'ai';
6
10
  export type { ModelMessage, ToolSet, StreamTextResult } from 'ai';
package/dist_ts/index.js CHANGED
@@ -1,6 +1,8 @@
1
- export { getModel } from './smartai.classes.smartai.js';
1
+ export { getModel, getModelSetup } from './smartai.classes.smartai.js';
2
2
  export { createAnthropicCachingMiddleware } from './smartai.middleware.anthropic.js';
3
+ export { applySmartAiCacheProviderOptions, applySmartAiPromptCaching, createSmartAiCachingMiddleware, getSmartAiCacheProviderOptions, getSmartAiMessageCacheProviderOptions, mergeSmartAiProviderOptions, resolveSmartAiCacheProvider, } from './smartai.cache.js';
3
4
  export { createOllamaModel } from './smartai.provider.ollama.js';
5
+ export { OPENAI_MAX_AUTH_ISSUER, OPENAI_MAX_CLIENT_ID, OPENAI_MAX_CODEX_BASE_URL, OPENAI_MAX_DEFAULT_ORIGINATOR, OpenAiMaxAuthError, completeOpenAiMaxDeviceCodeLogin, createOpenAiMaxProviderSettings, ensureOpenAiMaxWorkspaceAllowed, exchangeOpenAiMaxAuthorizationCode, parseOpenAiMaxIdToken, pollOpenAiMaxDeviceCode, refreshOpenAiMaxTokenData, requestOpenAiMaxDeviceCode, } from './smartai.auth.openai.js';
4
6
  // Re-export commonly used ai-sdk functions for consumer convenience
5
7
  export { generateText, streamText, tool, jsonSchema } from 'ai';
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFeEQsT0FBTyxFQUFFLGdDQUFnQyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDckYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFakUsb0VBQW9FO0FBQ3BFLE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxJQUFJLENBQUMifQ==
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBb0J2RSxPQUFPLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNyRixPQUFPLEVBQ0wsZ0NBQWdDLEVBQ2hDLHlCQUF5QixFQUN6Qiw4QkFBOEIsRUFDOUIsOEJBQThCLEVBQzlCLHFDQUFxQyxFQUNyQywyQkFBMkIsRUFDM0IsMkJBQTJCLEdBQzVCLE1BQU0sb0JBQW9CLENBQUM7QUFPNUIsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDakUsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixvQkFBb0IsRUFDcEIseUJBQXlCLEVBQ3pCLDZCQUE2QixFQUM3QixrQkFBa0IsRUFDbEIsZ0NBQWdDLEVBQ2hDLCtCQUErQixFQUMvQiwrQkFBK0IsRUFDL0Isa0NBQWtDLEVBQ2xDLHFCQUFxQixFQUNyQix1QkFBdUIsRUFDdkIseUJBQXlCLEVBQ3pCLDBCQUEwQixHQUMzQixNQUFNLDBCQUEwQixDQUFDO0FBR2xDLG9FQUFvRTtBQUNwRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLE1BQU0sSUFBSSxDQUFDIn0=
@@ -0,0 +1,30 @@
1
+ import type { IOpenAiMaxAuthCredentials, IOpenAiMaxAuthOptions, IOpenAiMaxCompleteDeviceCodeOptions, IOpenAiMaxDeviceCode, IOpenAiMaxDeviceCodePollOptions, IOpenAiMaxIdTokenInfo, IOpenAiMaxTokenData } from './smartai.interfaces.js';
2
+ export declare const OPENAI_MAX_AUTH_ISSUER = "https://auth.openai.com";
3
+ export declare const OPENAI_MAX_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
4
+ export declare const OPENAI_MAX_CODEX_BASE_URL = "https://chatgpt.com/backend-api/codex";
5
+ export declare const OPENAI_MAX_DEFAULT_ORIGINATOR = "smartai";
6
+ export declare class OpenAiMaxAuthError extends Error {
7
+ status?: number;
8
+ body?: string;
9
+ constructor(message: string, options?: {
10
+ status?: number;
11
+ body?: string;
12
+ });
13
+ }
14
+ export interface IOpenAiMaxAuthorizationCode {
15
+ authorizationCode: string;
16
+ codeChallenge: string;
17
+ codeVerifier: string;
18
+ }
19
+ export declare function parseOpenAiMaxIdToken(idToken: string): IOpenAiMaxIdTokenInfo;
20
+ export declare function requestOpenAiMaxDeviceCode(options?: IOpenAiMaxAuthOptions): Promise<IOpenAiMaxDeviceCode>;
21
+ export declare function pollOpenAiMaxDeviceCode(deviceCode: IOpenAiMaxDeviceCode, options?: IOpenAiMaxDeviceCodePollOptions): Promise<IOpenAiMaxAuthorizationCode>;
22
+ export declare function exchangeOpenAiMaxAuthorizationCode(authorizationCode: IOpenAiMaxAuthorizationCode, options?: IOpenAiMaxAuthOptions): Promise<IOpenAiMaxTokenData>;
23
+ export declare function ensureOpenAiMaxWorkspaceAllowed(tokenData: IOpenAiMaxTokenData, forcedChatGptWorkspaceId?: string): void;
24
+ export declare function completeOpenAiMaxDeviceCodeLogin(deviceCode: IOpenAiMaxDeviceCode, options?: IOpenAiMaxCompleteDeviceCodeOptions): Promise<IOpenAiMaxTokenData>;
25
+ export declare function refreshOpenAiMaxTokenData(tokenData: IOpenAiMaxTokenData, options?: IOpenAiMaxAuthOptions): Promise<IOpenAiMaxTokenData>;
26
+ export declare function createOpenAiMaxProviderSettings(credentials: IOpenAiMaxAuthCredentials): {
27
+ apiKey: string;
28
+ baseURL: string;
29
+ headers: Record<string, string>;
30
+ };
@@ -0,0 +1,224 @@
1
+ export const OPENAI_MAX_AUTH_ISSUER = 'https://auth.openai.com';
2
+ export const OPENAI_MAX_CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann';
3
+ export const OPENAI_MAX_CODEX_BASE_URL = 'https://chatgpt.com/backend-api/codex';
4
+ export const OPENAI_MAX_DEFAULT_ORIGINATOR = 'smartai';
5
+ const DEVICE_CODE_TIMEOUT_MS = 15 * 60 * 1000;
6
+ export class OpenAiMaxAuthError extends Error {
7
+ constructor(message, options = {}) {
8
+ super(message);
9
+ this.name = 'OpenAiMaxAuthError';
10
+ this.status = options.status;
11
+ this.body = options.body;
12
+ }
13
+ }
14
+ function getFetch(options) {
15
+ const fetchFunction = options.fetch ?? globalThis.fetch;
16
+ if (!fetchFunction) {
17
+ throw new OpenAiMaxAuthError('fetch is not available for OpenAI Max authentication.');
18
+ }
19
+ return fetchFunction;
20
+ }
21
+ function getIssuer(options) {
22
+ return (options.issuer ?? OPENAI_MAX_AUTH_ISSUER).replace(/\/+$/, '');
23
+ }
24
+ function getClientId(options) {
25
+ return options.clientId ?? OPENAI_MAX_CLIENT_ID;
26
+ }
27
+ function asString(value, name) {
28
+ if (typeof value !== 'string' || value.length === 0) {
29
+ throw new OpenAiMaxAuthError(`OpenAI Max auth response is missing ${name}.`);
30
+ }
31
+ return value;
32
+ }
33
+ function asOptionalString(value) {
34
+ return typeof value === 'string' && value.length > 0 ? value : undefined;
35
+ }
36
+ function asIntervalSeconds(value) {
37
+ const interval = typeof value === 'number' ? value : Number.parseInt(String(value ?? ''), 10);
38
+ if (!Number.isFinite(interval) || interval <= 0) {
39
+ throw new OpenAiMaxAuthError('OpenAI Max device-code response has an invalid interval.');
40
+ }
41
+ return interval;
42
+ }
43
+ async function readJson(response, context) {
44
+ const body = await response.text();
45
+ if (!response.ok) {
46
+ throw new OpenAiMaxAuthError(`${context} failed with status ${response.status}.`, {
47
+ status: response.status,
48
+ body,
49
+ });
50
+ }
51
+ try {
52
+ return body ? JSON.parse(body) : {};
53
+ }
54
+ catch (error) {
55
+ throw new OpenAiMaxAuthError(`${context} returned invalid JSON: ${error.message}`, {
56
+ status: response.status,
57
+ body,
58
+ });
59
+ }
60
+ }
61
+ async function postJson(url, body, options) {
62
+ const response = await getFetch(options)(url, {
63
+ method: 'POST',
64
+ headers: { 'Content-Type': 'application/json' },
65
+ body: JSON.stringify(body),
66
+ });
67
+ return readJson(response, `POST ${url}`);
68
+ }
69
+ async function postForm(url, body, options) {
70
+ const response = await getFetch(options)(url, {
71
+ method: 'POST',
72
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
73
+ body: body.toString(),
74
+ });
75
+ return readJson(response, `POST ${url}`);
76
+ }
77
+ function sleep(ms) {
78
+ return new Promise((resolve) => setTimeout(resolve, ms));
79
+ }
80
+ function parseJwtPayload(jwt) {
81
+ const parts = jwt.split('.');
82
+ if (parts.length !== 3 || !parts[1]) {
83
+ throw new OpenAiMaxAuthError('OpenAI Max auth returned an invalid ID token.');
84
+ }
85
+ try {
86
+ return JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf8'));
87
+ }
88
+ catch (error) {
89
+ throw new OpenAiMaxAuthError(`OpenAI Max ID token could not be parsed: ${error.message}`);
90
+ }
91
+ }
92
+ export function parseOpenAiMaxIdToken(idToken) {
93
+ const claims = parseJwtPayload(idToken);
94
+ const profile = claims['https://api.openai.com/profile'];
95
+ const auth = claims['https://api.openai.com/auth'];
96
+ const expiresAtSeconds = typeof claims.exp === 'number' ? claims.exp : undefined;
97
+ return {
98
+ email: asOptionalString(claims.email) ?? asOptionalString(profile?.email),
99
+ chatgptPlanType: asOptionalString(auth?.chatgpt_plan_type),
100
+ chatgptUserId: asOptionalString(auth?.chatgpt_user_id) ?? asOptionalString(auth?.user_id),
101
+ chatgptAccountId: asOptionalString(auth?.chatgpt_account_id),
102
+ chatgptAccountIsFedramp: auth?.chatgpt_account_is_fedramp === true,
103
+ expiresAt: expiresAtSeconds ? new Date(expiresAtSeconds * 1000).toISOString() : undefined,
104
+ rawJwt: idToken,
105
+ };
106
+ }
107
+ function createTokenData(response) {
108
+ const idToken = asString(response.id_token, 'id_token');
109
+ const accessToken = asString(response.access_token, 'access_token');
110
+ const refreshToken = asString(response.refresh_token, 'refresh_token');
111
+ const idTokenInfo = parseOpenAiMaxIdToken(idToken);
112
+ return {
113
+ idToken,
114
+ accessToken,
115
+ refreshToken,
116
+ accountId: idTokenInfo.chatgptAccountId,
117
+ idTokenInfo,
118
+ };
119
+ }
120
+ export async function requestOpenAiMaxDeviceCode(options = {}) {
121
+ const issuer = getIssuer(options);
122
+ const response = await postJson(`${issuer}/api/accounts/deviceauth/usercode`, {
123
+ client_id: getClientId(options),
124
+ }, options);
125
+ return {
126
+ verificationUrl: `${issuer}/codex/device`,
127
+ userCode: asString(response.user_code ?? response.usercode, 'user_code'),
128
+ deviceAuthId: asString(response.device_auth_id, 'device_auth_id'),
129
+ intervalSeconds: asIntervalSeconds(response.interval),
130
+ };
131
+ }
132
+ export async function pollOpenAiMaxDeviceCode(deviceCode, options = {}) {
133
+ const issuer = getIssuer(options);
134
+ const pollUrl = `${issuer}/api/accounts/deviceauth/token`;
135
+ const timeoutMs = options.timeoutMs ?? DEVICE_CODE_TIMEOUT_MS;
136
+ const sleepFunction = options.sleep ?? sleep;
137
+ const startedAt = Date.now();
138
+ while (Date.now() - startedAt < timeoutMs) {
139
+ const response = await getFetch(options)(pollUrl, {
140
+ method: 'POST',
141
+ headers: { 'Content-Type': 'application/json' },
142
+ body: JSON.stringify({
143
+ device_auth_id: deviceCode.deviceAuthId,
144
+ user_code: deviceCode.userCode,
145
+ }),
146
+ });
147
+ if (response.ok) {
148
+ const body = await readJson(response, `POST ${pollUrl}`);
149
+ return {
150
+ authorizationCode: asString(body.authorization_code, 'authorization_code'),
151
+ codeChallenge: asString(body.code_challenge, 'code_challenge'),
152
+ codeVerifier: asString(body.code_verifier, 'code_verifier'),
153
+ };
154
+ }
155
+ if (response.status !== 403 && response.status !== 404) {
156
+ const body = await response.text();
157
+ throw new OpenAiMaxAuthError(`OpenAI Max device-code polling failed with status ${response.status}.`, {
158
+ status: response.status,
159
+ body,
160
+ });
161
+ }
162
+ await response.arrayBuffer().catch(() => undefined);
163
+ const remaining = timeoutMs - (Date.now() - startedAt);
164
+ await sleepFunction(Math.min(deviceCode.intervalSeconds * 1000, Math.max(remaining, 0)));
165
+ }
166
+ throw new OpenAiMaxAuthError('OpenAI Max device-code login timed out.');
167
+ }
168
+ export async function exchangeOpenAiMaxAuthorizationCode(authorizationCode, options = {}) {
169
+ const issuer = getIssuer(options);
170
+ const response = await postForm(`${issuer}/oauth/token`, new URLSearchParams({
171
+ grant_type: 'authorization_code',
172
+ code: authorizationCode.authorizationCode,
173
+ redirect_uri: `${issuer}/deviceauth/callback`,
174
+ client_id: getClientId(options),
175
+ code_verifier: authorizationCode.codeVerifier,
176
+ }), options);
177
+ return createTokenData(response);
178
+ }
179
+ export function ensureOpenAiMaxWorkspaceAllowed(tokenData, forcedChatGptWorkspaceId) {
180
+ if (!forcedChatGptWorkspaceId) {
181
+ return;
182
+ }
183
+ if (tokenData.idTokenInfo.chatgptAccountId !== forcedChatGptWorkspaceId) {
184
+ throw new OpenAiMaxAuthError(`OpenAI Max login is restricted to workspace ${forcedChatGptWorkspaceId}.`);
185
+ }
186
+ }
187
+ export async function completeOpenAiMaxDeviceCodeLogin(deviceCode, options = {}) {
188
+ const authorizationCode = await pollOpenAiMaxDeviceCode(deviceCode, options);
189
+ const tokenData = await exchangeOpenAiMaxAuthorizationCode(authorizationCode, options);
190
+ ensureOpenAiMaxWorkspaceAllowed(tokenData, options.forcedChatGptWorkspaceId);
191
+ return tokenData;
192
+ }
193
+ export async function refreshOpenAiMaxTokenData(tokenData, options = {}) {
194
+ const issuer = getIssuer(options);
195
+ const response = await postJson(`${issuer}/oauth/token`, {
196
+ client_id: getClientId(options),
197
+ grant_type: 'refresh_token',
198
+ refresh_token: tokenData.refreshToken,
199
+ }, options);
200
+ return createTokenData({
201
+ id_token: response.id_token ?? tokenData.idToken,
202
+ access_token: response.access_token ?? tokenData.accessToken,
203
+ refresh_token: response.refresh_token ?? tokenData.refreshToken,
204
+ });
205
+ }
206
+ export function createOpenAiMaxProviderSettings(credentials) {
207
+ const accountId = credentials.accountId ?? credentials.idTokenInfo?.chatgptAccountId;
208
+ const isFedrampAccount = credentials.idTokenInfo?.chatgptAccountIsFedramp === true;
209
+ const headers = {
210
+ originator: credentials.originator ?? OPENAI_MAX_DEFAULT_ORIGINATOR,
211
+ };
212
+ if (accountId) {
213
+ headers['ChatGPT-Account-ID'] = accountId;
214
+ }
215
+ if (isFedrampAccount) {
216
+ headers['X-OpenAI-Fedramp'] = 'true';
217
+ }
218
+ return {
219
+ apiKey: credentials.accessToken,
220
+ baseURL: credentials.baseUrl ?? OPENAI_MAX_CODEX_BASE_URL,
221
+ headers,
222
+ };
223
+ }
224
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhaS5hdXRoLm9wZW5haS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0YWkuYXV0aC5vcGVuYWkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBVUEsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcseUJBQXlCLENBQUM7QUFDaEUsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsOEJBQThCLENBQUM7QUFDbkUsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQUcsdUNBQXVDLENBQUM7QUFDakYsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQUcsU0FBUyxDQUFDO0FBRXZELE1BQU0sc0JBQXNCLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFFOUMsTUFBTSxPQUFPLGtCQUFtQixTQUFRLEtBQUs7SUFJM0MsWUFBWSxPQUFlLEVBQUUsVUFBOEMsRUFBRTtRQUMzRSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDZixJQUFJLENBQUMsSUFBSSxHQUFHLG9CQUFvQixDQUFDO1FBQ2pDLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUM3QixJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7SUFDM0IsQ0FBQztDQUNGO0FBY0QsU0FBUyxRQUFRLENBQUMsT0FBOEI7SUFDOUMsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLEtBQUssSUFBSSxVQUFVLENBQUMsS0FBSyxDQUFDO0lBQ3hELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNuQixNQUFNLElBQUksa0JBQWtCLENBQUMsdURBQXVELENBQUMsQ0FBQztJQUN4RixDQUFDO0lBQ0QsT0FBTyxhQUFhLENBQUM7QUFDdkIsQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLE9BQThCO0lBQy9DLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxJQUFJLHNCQUFzQixDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFB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
@@ -0,0 +1,31 @@
1
+ import type { LanguageModelV3Middleware, LanguageModelV3Prompt } from '@ai-sdk/provider';
2
+ import type { TSmartAiProviderOptions } from './smartai.interfaces.js';
3
+ export type TSmartAiMessageCacheProvider = 'anthropic' | 'openrouter' | 'bedrock' | 'openaiCompatible' | 'copilot' | 'alibaba';
4
+ export type TSmartAiCacheRetention = 'ephemeral' | '1h' | 'in_memory' | '24h';
5
+ export interface ISmartAiCacheOptions {
6
+ /** Provider-specific message cache marker namespace. Usually inferred from the model. */
7
+ provider?: TSmartAiMessageCacheProvider;
8
+ /** Stable session/request key for providers that support request-level prompt cache affinity. */
9
+ key?: string;
10
+ /** Short retention is the default; longer retention is opt-in. */
11
+ retention?: TSmartAiCacheRetention;
12
+ }
13
+ export type TSmartAiCacheSetting = boolean | 'auto' | ISmartAiCacheOptions;
14
+ export declare function mergeSmartAiProviderOptions(defaults?: TSmartAiProviderOptions, overrides?: TSmartAiProviderOptions): TSmartAiProviderOptions | undefined;
15
+ export declare function resolveSmartAiCacheProvider(provider?: string, modelId?: string): TSmartAiMessageCacheProvider | undefined;
16
+ export declare function getSmartAiMessageCacheProviderOptions(provider: TSmartAiMessageCacheProvider, options?: ISmartAiCacheOptions): TSmartAiProviderOptions;
17
+ export declare function applySmartAiPromptCaching(prompt: LanguageModelV3Prompt, options?: ISmartAiCacheOptions): LanguageModelV3Prompt;
18
+ export declare function createSmartAiCachingMiddleware(options?: ISmartAiCacheOptions): LanguageModelV3Middleware;
19
+ export declare function getSmartAiCacheProviderOptions(input: {
20
+ provider?: string;
21
+ modelId?: string;
22
+ cache?: TSmartAiCacheSetting;
23
+ sessionId?: string;
24
+ }): TSmartAiProviderOptions | undefined;
25
+ export declare function applySmartAiCacheProviderOptions(input: {
26
+ provider?: string;
27
+ modelId?: string;
28
+ providerOptions?: TSmartAiProviderOptions;
29
+ cache?: TSmartAiCacheSetting;
30
+ sessionId?: string;
31
+ }): TSmartAiProviderOptions | undefined;
@@ -0,0 +1,179 @@
1
+ function isObject(input) {
2
+ return typeof input === 'object' && input !== null && !Array.isArray(input);
3
+ }
4
+ function mergeJsonDefaults(defaults, overrides) {
5
+ const result = { ...defaults };
6
+ if (!overrides)
7
+ return result;
8
+ for (const [key, value] of Object.entries(overrides)) {
9
+ const existing = result[key];
10
+ if (isObject(existing) && isObject(value)) {
11
+ result[key] = mergeJsonDefaults(existing, value);
12
+ continue;
13
+ }
14
+ result[key] = value;
15
+ }
16
+ return result;
17
+ }
18
+ export function mergeSmartAiProviderOptions(defaults, overrides) {
19
+ if (!defaults)
20
+ return overrides;
21
+ if (!overrides)
22
+ return defaults;
23
+ return mergeJsonDefaults(defaults, overrides);
24
+ }
25
+ function cacheOptionsFromSetting(cache) {
26
+ if (cache === false)
27
+ return undefined;
28
+ if (cache === undefined || cache === true || cache === 'auto')
29
+ return {};
30
+ return cache;
31
+ }
32
+ export function resolveSmartAiCacheProvider(provider, modelId) {
33
+ const providerLower = provider?.toLowerCase() ?? '';
34
+ const modelLower = modelId?.toLowerCase() ?? '';
35
+ if (providerLower.includes('openrouter'))
36
+ return 'openrouter';
37
+ if (providerLower.includes('bedrock'))
38
+ return 'bedrock';
39
+ if (providerLower.includes('copilot'))
40
+ return 'copilot';
41
+ if (providerLower.includes('alibaba'))
42
+ return 'alibaba';
43
+ if (providerLower.includes('openai-compatible') || providerLower.includes('openaicompatible')) {
44
+ return 'openaiCompatible';
45
+ }
46
+ if (providerLower.includes('anthropic'))
47
+ return 'anthropic';
48
+ if (modelLower.includes('claude') || modelLower.includes('anthropic'))
49
+ return 'anthropic';
50
+ return undefined;
51
+ }
52
+ export function getSmartAiMessageCacheProviderOptions(provider, options = {}) {
53
+ const anthropicCacheControl = {
54
+ type: 'ephemeral',
55
+ ...(options.retention === '1h' ? { ttl: '1h' } : {}),
56
+ };
57
+ const providerOptions = {
58
+ anthropic: {
59
+ anthropic: {
60
+ cacheControl: anthropicCacheControl,
61
+ },
62
+ },
63
+ openrouter: {
64
+ openrouter: {
65
+ cacheControl: { type: 'ephemeral' },
66
+ },
67
+ },
68
+ bedrock: {
69
+ bedrock: {
70
+ cachePoint: { type: 'default' },
71
+ },
72
+ },
73
+ openaiCompatible: {
74
+ openaiCompatible: {
75
+ cache_control: { type: 'ephemeral' },
76
+ },
77
+ },
78
+ copilot: {
79
+ copilot: {
80
+ copilot_cache_control: { type: 'ephemeral' },
81
+ },
82
+ },
83
+ alibaba: {
84
+ alibaba: {
85
+ cacheControl: { type: 'ephemeral' },
86
+ },
87
+ },
88
+ };
89
+ return providerOptions[provider];
90
+ }
91
+ function shouldUseMessageLevelOptions(provider) {
92
+ return provider === 'anthropic' || provider === 'bedrock';
93
+ }
94
+ function applyProviderOptionsDefaults(item, defaults) {
95
+ return {
96
+ ...item,
97
+ providerOptions: mergeSmartAiProviderOptions(defaults, item.providerOptions),
98
+ };
99
+ }
100
+ function isToolApprovalPart(part) {
101
+ if (!isObject(part))
102
+ return false;
103
+ return part.type === 'tool-approval-request' || part.type === 'tool-approval-response';
104
+ }
105
+ function applyCacheToMessage(message, provider, options) {
106
+ const providerOptions = getSmartAiMessageCacheProviderOptions(provider, options);
107
+ const content = message.content;
108
+ if (!shouldUseMessageLevelOptions(provider) && Array.isArray(content) && content.length > 0) {
109
+ const lastIndex = content.length - 1;
110
+ const lastPart = content[lastIndex];
111
+ if (!isToolApprovalPart(lastPart)) {
112
+ const messageWithArrayContent = message;
113
+ return {
114
+ ...messageWithArrayContent,
115
+ content: content.map((part, index) => index === lastIndex ? applyProviderOptionsDefaults(part, providerOptions) : part),
116
+ };
117
+ }
118
+ }
119
+ return applyProviderOptionsDefaults(message, providerOptions);
120
+ }
121
+ export function applySmartAiPromptCaching(prompt, options = {}) {
122
+ const provider = options.provider ?? 'anthropic';
123
+ const targetIndexes = new Set();
124
+ const nonSystemIndexes = [];
125
+ let systemCount = 0;
126
+ for (let i = 0; i < prompt.length; i++) {
127
+ const message = prompt[i];
128
+ if (message.role === 'system') {
129
+ if (systemCount < 2)
130
+ targetIndexes.add(i);
131
+ systemCount++;
132
+ continue;
133
+ }
134
+ nonSystemIndexes.push(i);
135
+ }
136
+ for (const index of nonSystemIndexes.slice(-2)) {
137
+ targetIndexes.add(index);
138
+ }
139
+ if (targetIndexes.size === 0)
140
+ return prompt;
141
+ return prompt.map((message, index) => targetIndexes.has(index) ? applyCacheToMessage(message, provider, options) : message);
142
+ }
143
+ export function createSmartAiCachingMiddleware(options = {}) {
144
+ return {
145
+ specificationVersion: 'v3',
146
+ transformParams: async ({ params }) => ({
147
+ ...params,
148
+ prompt: applySmartAiPromptCaching(params.prompt, options),
149
+ }),
150
+ };
151
+ }
152
+ function isOpenAiProvider(provider) {
153
+ const providerLower = provider?.toLowerCase() ?? '';
154
+ return providerLower === 'openai' || providerLower.startsWith('openai.') || providerLower.includes('@ai-sdk/openai');
155
+ }
156
+ export function getSmartAiCacheProviderOptions(input) {
157
+ const cacheOptions = cacheOptionsFromSetting(input.cache);
158
+ if (!cacheOptions)
159
+ return undefined;
160
+ if (isOpenAiProvider(input.provider)) {
161
+ const key = cacheOptions.key ?? input.sessionId;
162
+ return {
163
+ openai: {
164
+ store: false,
165
+ ...(key ? { promptCacheKey: key } : {}),
166
+ ...(cacheOptions.retention === '24h' || cacheOptions.retention === 'in_memory'
167
+ ? { promptCacheRetention: cacheOptions.retention }
168
+ : key
169
+ ? { promptCacheRetention: 'in_memory' }
170
+ : {}),
171
+ },
172
+ };
173
+ }
174
+ return undefined;
175
+ }
176
+ export function applySmartAiCacheProviderOptions(input) {
177
+ return mergeSmartAiProviderOptions(getSmartAiCacheProviderOptions(input), input.providerOptions);
178
+ }
179
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhaS5jYWNoZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0YWkuY2FjaGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBd0JBLFNBQVMsUUFBUSxDQUFDLEtBQWM7SUFDOUIsT0FBTyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDOUUsQ0FBQztBQUVELFNBQVMsaUJBQWlCLENBQUMsUUFBb0IsRUFBRSxTQUFzQjtJQUNyRSxNQUFNLE1BQU0sR0FBZSxFQUFFLEdBQUcsUUFBUSxFQUFFLENBQUM7SUFFM0MsSUFBSSxDQUFDLFNBQVM7UUFBRSxPQUFPLE1BQU0sQ0FBQztJQUU5QixLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ3JELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM3QixJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMxQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsaUJBQWlCLENBQUMsUUFBc0IsRUFBRSxLQUFtQixDQUFDLENBQUM7WUFDN0UsU0FBUztRQUNYLENBQUM7UUFDRCxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBa0IsQ0FBQztJQUNuQyxDQUFDO0lBRUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELE1BQU0sVUFBVSwyQkFBMkIsQ0FDekMsUUFBa0MsRUFDbEMsU0FBbUM7SUFFbkMsSUFBSSxDQUFDLFFBQVE7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUNoQyxJQUFJLENBQUMsU0FBUztRQUFFLE9BQU8sUUFBUSxDQUFDO0lBQ2hDLE9BQU8saUJBQWlCLENBQUMsUUFB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
@@ -1,7 +1,11 @@
1
- import type { ISmartAiOptions, LanguageModelV3 } from './smartai.interfaces.js';
1
+ import type { ISmartAiModelSetup, ISmartAiOptions, LanguageModelV3 } from './smartai.interfaces.js';
2
2
  /**
3
3
  * Returns a LanguageModelV3 for the given provider and model.
4
4
  * This is the primary API — consumers use the returned model with AI SDK's
5
5
  * generateText(), streamText(), etc.
6
6
  */
7
7
  export declare function getModel(options: ISmartAiOptions): LanguageModelV3;
8
+ /**
9
+ * Returns the model plus request-time providerOptions for AI SDK calls.
10
+ */
11
+ export declare function getModelSetup(options: ISmartAiOptions): ISmartAiModelSetup;
@@ -1,6 +1,7 @@
1
1
  import * as plugins from './plugins.js';
2
2
  import { createOllamaModel } from './smartai.provider.ollama.js';
3
3
  import { createAnthropicCachingMiddleware } from './smartai.middleware.anthropic.js';
4
+ import { createOpenAiMaxProviderSettings } from './smartai.auth.openai.js';
4
5
  /**
5
6
  * Returns a LanguageModelV3 for the given provider and model.
6
7
  * This is the primary API — consumers use the returned model with AI SDK's
@@ -15,11 +16,13 @@ export function getModel(options) {
15
16
  return base;
16
17
  return plugins.wrapLanguageModel({
17
18
  model: base,
18
- middleware: createAnthropicCachingMiddleware(),
19
+ middleware: createAnthropicCachingMiddleware(typeof options.promptCaching === 'object' ? options.promptCaching : undefined),
19
20
  });
20
21
  }
21
22
  case 'openai': {
22
- const p = plugins.createOpenAI({ apiKey: options.apiKey });
23
+ const p = plugins.createOpenAI(options.openAiMaxAuth
24
+ ? createOpenAiMaxProviderSettings(options.openAiMaxAuth)
25
+ : { apiKey: options.apiKey });
23
26
  return p(options.model);
24
27
  }
25
28
  case 'google': {
@@ -48,4 +51,11 @@ export function getModel(options) {
48
51
  throw new Error(`Unknown provider: ${options.provider}`);
49
52
  }
50
53
  }
51
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhaS5jbGFzc2VzLnNtYXJ0YWkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFpLmNsYXNzZXMuc21hcnRhaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUVyRjs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLFFBQVEsQ0FBQyxPQUF3QjtJQUMvQyxRQUFRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN6QixLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUM7WUFDakIsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUM5RCxNQUFNLElBQUksR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBb0IsQ0FBQztZQUNqRCxJQUFJLE9BQU8sQ0FBQyxhQUFhLEtBQUssS0FBSztnQkFBRSxPQUFPLElBQUksQ0FBQztZQUNqRCxPQUFPLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQztnQkFDL0IsS0FBSyxFQUFFLElBQUk7Z0JBQ1gsVUFBVSxFQUFFLGdDQUFnQyxFQUFFO2FBQy9DLENBQStCLENBQUM7UUFDbkMsQ0FBQztRQUNELEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQztZQUNkLE1BQU0sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDM0QsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBb0IsQ0FBQztRQUM3QyxDQUFDO1FBQ0QsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQ2QsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLHdCQUF3QixDQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZFLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQW9CLENBQUM7UUFDN0MsQ0FBQztRQUNELEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNaLE1BQU0sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDekQsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBb0IsQ0FBQztRQUM3QyxDQUFDO1FBQ0QsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ2YsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUM1RCxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFvQixDQUFDO1FBQzdDLENBQUM7UUFDRCxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDWCxNQUFNLENBQUMsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQ3hELE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQW9CLENBQUM7UUFDN0MsQ0FBQztRQUNELEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQztZQUNsQixNQUFNLENBQUMsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDL0QsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBb0IsQ0FBQztRQUM3QyxDQUFDO1FBQ0QsS0FBSyxRQUFRO1lBQ1gsT0FBTyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNwQztZQUNFLE1BQU0sSUFBSSxLQUFLLENBQUMscUJBQXNCLE9BQTJCLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUNsRixDQUFDO0FBQ0gsQ0FBQyJ9
54
+ /**
55
+ * Returns the model plus request-time providerOptions for AI SDK calls.
56
+ */
57
+ export function getModelSetup(options) {
58
+ const model = getModel(options);
59
+ return options.providerOptions ? { model, providerOptions: options.providerOptions } : { model };
60
+ }
61
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhaS5jbGFzc2VzLnNtYXJ0YWkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFpLmNsYXNzZXMuc21hcnRhaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNyRixPQUFPLEVBQUUsK0JBQStCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUUzRTs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLFFBQVEsQ0FBQyxPQUF3QjtJQUMvQyxRQUFRLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN6QixLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUM7WUFDakIsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUM5RCxNQUFNLElBQUksR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBb0IsQ0FBQztZQUNqRCxJQUFJLE9BQU8sQ0FBQyxhQUFhLEtBQUssS0FBSztnQkFBRSxPQUFPLElBQUksQ0FBQztZQUNqRCxPQUFPLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQztnQkFDL0IsS0FBSyxFQUFFLElBQUk7Z0JBQ1gsVUFBVSxFQUFFLGdDQUFnQyxDQUMxQyxPQUFPLE9BQU8sQ0FBQyxhQUFhLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQzlFO2FBQ0YsQ0FBK0IsQ0FBQztRQUNuQyxDQUFDO1FBQ0QsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQ2QsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FDNUIsT0FBTyxDQUFDLGFBQWE7Z0JBQ25CLENBQUMsQ0FBQywrQkFBK0IsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDO2dCQUN4RCxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUMvQixDQUFDO1lBQ0YsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBb0IsQ0FBQztRQUM3QyxDQUFDO1FBQ0QsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQ2QsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLHdCQUF3QixDQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZFLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQW9CLENBQUM7UUFDN0MsQ0FBQztRQUNELEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNaLE1BQU0sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDekQsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBb0IsQ0FBQztRQUM3QyxDQUFDO1FBQ0QsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ2YsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUM1RCxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFvQixDQUFDO1FBQzdDLENBQUM7UUFDRCxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDWCxNQUFNLENBQUMsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQ3hELE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQW9CLENBQUM7UUFDN0MsQ0FBQztRQUNELEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQztZQUNsQixNQUFNLENBQUMsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDL0QsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBb0IsQ0FBQztRQUM3QyxDQUFDO1FBQ0QsS0FBSyxRQUFRO1lBQ1gsT0FBTyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNwQztZQUNFLE1BQU0sSUFBSSxLQUFLLENBQUMscUJBQXNCLE9BQTJCLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUNsRixDQUFDO0FBQ0gsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxPQUF3QjtJQUNwRCxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDaEMsT0FBTyxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsT0FBTyxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDO0FBQ25HLENBQUMifQ==