@meetopenbot/openbot 0.1.1 → 0.1.3
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/dist/credits-auth.d.ts +16 -0
- package/dist/credits-auth.js +39 -0
- package/dist/model.d.ts +5 -1
- package/dist/model.js +26 -5
- package/dist/runtime.js +27 -7
- package/package.json +1 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { OpenbotAuthMode } from './cloud-mode.js';
|
|
2
|
+
export declare const INTEGRATIONS_TOKEN_HEADER = "x-openbot-integrations-token";
|
|
3
|
+
export declare const CREDITS_API_KEY_PLACEHOLDER = "openbot-credits";
|
|
4
|
+
export interface CreditsAuthConfig {
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
token: string;
|
|
7
|
+
}
|
|
8
|
+
export type CreditsProviderId = 'openai' | 'anthropic';
|
|
9
|
+
/** Cloud host injects these when routing LLM calls through OpenBot Credits. */
|
|
10
|
+
export declare function resolveCreditsAuthConfig(): CreditsAuthConfig | undefined;
|
|
11
|
+
export declare function creditsProviderBaseUrl(config: CreditsAuthConfig, provider: CreditsProviderId): string;
|
|
12
|
+
export declare function shouldUseCreditsAuth(options?: {
|
|
13
|
+
authMode?: OpenbotAuthMode;
|
|
14
|
+
}): boolean;
|
|
15
|
+
export declare function isCreditsErrorMessage(message: string): boolean;
|
|
16
|
+
export declare function isAuthErrorMessage(message: string): boolean;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { isCloudMode } from './cloud-mode.js';
|
|
2
|
+
export const INTEGRATIONS_TOKEN_HEADER = 'x-openbot-integrations-token';
|
|
3
|
+
export const CREDITS_API_KEY_PLACEHOLDER = 'openbot-credits';
|
|
4
|
+
const CREDITS_PROVIDER_PATHS = {
|
|
5
|
+
openai: 'openai/v1',
|
|
6
|
+
anthropic: 'anthropic/v1',
|
|
7
|
+
};
|
|
8
|
+
/** Cloud host injects these when routing LLM calls through OpenBot Credits. */
|
|
9
|
+
export function resolveCreditsAuthConfig() {
|
|
10
|
+
const baseUrl = process.env.OPENBOT_INTEGRATIONS_BASE_URL?.trim();
|
|
11
|
+
const token = process.env.OPENBOT_INTEGRATIONS_TOKEN?.trim();
|
|
12
|
+
if (!baseUrl || !token)
|
|
13
|
+
return undefined;
|
|
14
|
+
return { baseUrl: baseUrl.replace(/\/$/, ''), token };
|
|
15
|
+
}
|
|
16
|
+
export function creditsProviderBaseUrl(config, provider) {
|
|
17
|
+
return `${config.baseUrl}/${CREDITS_PROVIDER_PATHS[provider]}`;
|
|
18
|
+
}
|
|
19
|
+
export function shouldUseCreditsAuth(options) {
|
|
20
|
+
if (options?.authMode === 'byok')
|
|
21
|
+
return false;
|
|
22
|
+
if (options?.authMode === 'credits')
|
|
23
|
+
return true;
|
|
24
|
+
// Cloud host injected integrations credentials — route through proxy even if authMode unset.
|
|
25
|
+
return isCloudMode() && resolveCreditsAuthConfig() !== undefined;
|
|
26
|
+
}
|
|
27
|
+
export function isCreditsErrorMessage(message) {
|
|
28
|
+
const lower = message.toLowerCase();
|
|
29
|
+
return (lower.includes('insufficient_credits') ||
|
|
30
|
+
lower.includes('insufficient credits') ||
|
|
31
|
+
lower.includes('402'));
|
|
32
|
+
}
|
|
33
|
+
export function isAuthErrorMessage(message) {
|
|
34
|
+
const lower = message.toLowerCase();
|
|
35
|
+
return (lower.includes('api key') ||
|
|
36
|
+
lower.includes('401') ||
|
|
37
|
+
lower.includes('unauthorized') ||
|
|
38
|
+
lower.includes('authentication'));
|
|
39
|
+
}
|
package/dist/model.d.ts
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
import type { LanguageModel } from 'ai';
|
|
2
|
-
|
|
2
|
+
import type { OpenbotAuthMode } from './cloud-mode.js';
|
|
3
|
+
export interface ResolveModelOptions {
|
|
4
|
+
authMode?: OpenbotAuthMode;
|
|
5
|
+
}
|
|
6
|
+
export declare function resolveModel(modelString: string, options?: ResolveModelOptions): LanguageModel;
|
package/dist/model.js
CHANGED
|
@@ -1,18 +1,39 @@
|
|
|
1
|
-
import { openai as defaultOpenai } from '@ai-sdk/openai';
|
|
2
|
-
import { anthropic } from '@ai-sdk/anthropic';
|
|
1
|
+
import { createOpenAI, openai as defaultOpenai } from '@ai-sdk/openai';
|
|
2
|
+
import { createAnthropic, anthropic } from '@ai-sdk/anthropic';
|
|
3
3
|
import { google } from '@ai-sdk/google';
|
|
4
|
-
|
|
4
|
+
import { CREDITS_API_KEY_PLACEHOLDER, INTEGRATIONS_TOKEN_HEADER, creditsProviderBaseUrl, resolveCreditsAuthConfig, shouldUseCreditsAuth, } from './credits-auth.js';
|
|
5
|
+
function resolveCreditsProvider(provider, modelId) {
|
|
6
|
+
const config = resolveCreditsAuthConfig();
|
|
7
|
+
if (!config) {
|
|
8
|
+
throw new Error('OpenBot Credits is not configured. The cloud host must set OPENBOT_INTEGRATIONS_BASE_URL and OPENBOT_INTEGRATIONS_TOKEN.');
|
|
9
|
+
}
|
|
10
|
+
const baseURL = creditsProviderBaseUrl(config, provider);
|
|
11
|
+
const headers = { [INTEGRATIONS_TOKEN_HEADER]: config.token };
|
|
12
|
+
// Any non-empty key satisfies the SDK; the integrations gateway authenticates via header.
|
|
13
|
+
const apiKey = config.token || CREDITS_API_KEY_PLACEHOLDER;
|
|
14
|
+
switch (provider) {
|
|
15
|
+
case 'openai':
|
|
16
|
+
return createOpenAI({ baseURL, apiKey, headers })(modelId);
|
|
17
|
+
case 'anthropic':
|
|
18
|
+
return createAnthropic({ baseURL, apiKey, headers })(modelId);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function resolveModel(modelString, options) {
|
|
5
22
|
const [provider, ...rest] = modelString.split('/');
|
|
6
23
|
const modelId = rest.join('/');
|
|
7
24
|
if (!modelId) {
|
|
8
25
|
throw new Error(`Invalid model string: "${modelString}". Expected "provider/model-id".`);
|
|
9
26
|
}
|
|
27
|
+
const useCredits = shouldUseCreditsAuth(options);
|
|
10
28
|
switch (provider) {
|
|
11
29
|
case 'openai':
|
|
12
|
-
return defaultOpenai(modelId);
|
|
30
|
+
return useCredits ? resolveCreditsProvider('openai', modelId) : defaultOpenai(modelId);
|
|
13
31
|
case 'anthropic':
|
|
14
|
-
return anthropic(modelId);
|
|
32
|
+
return useCredits ? resolveCreditsProvider('anthropic', modelId) : anthropic(modelId);
|
|
15
33
|
case 'google':
|
|
34
|
+
if (useCredits) {
|
|
35
|
+
throw new Error('Google models are not available via OpenBot Credits. Switch to an OpenAI or Anthropic model, or use BYOK mode.');
|
|
36
|
+
}
|
|
16
37
|
return google(modelId);
|
|
17
38
|
default:
|
|
18
39
|
throw new Error(`Unsupported AI provider: "${provider}"`);
|
package/dist/runtime.js
CHANGED
|
@@ -2,6 +2,7 @@ import { generateText } from 'ai';
|
|
|
2
2
|
import { eventsToModelMessages } from './history.js';
|
|
3
3
|
import { buildContext } from './context.js';
|
|
4
4
|
import { OPENBOT_SYSTEM_PROMPT } from './system-prompt.js';
|
|
5
|
+
import { isAuthErrorMessage, isCreditsErrorMessage } from './credits-auth.js';
|
|
5
6
|
import { resolveModel } from './model.js';
|
|
6
7
|
async function buildSystemPrompt(state, storage) {
|
|
7
8
|
const context = await buildContext(state, storage);
|
|
@@ -68,7 +69,8 @@ function createToolBatchTracker(state, storage, channelId, threadId) {
|
|
|
68
69
|
export const openbotRuntime = (options) => (builder) => {
|
|
69
70
|
const { model: modelString = 'openai/gpt-4o-mini', authMode = 'byok', agentId, storage, toolDefinitions = {}, abortSignal, host, } = options;
|
|
70
71
|
let currentModelString = modelString;
|
|
71
|
-
|
|
72
|
+
const resolveCurrentModel = () => resolveModel(currentModelString, { authMode });
|
|
73
|
+
let model = resolveCurrentModel();
|
|
72
74
|
const isCreditsCloudAgent = (id) => host.isCloudSystemAgent(id ?? '') && authMode === 'credits';
|
|
73
75
|
const runLLM = async function* (context, threadId, trigger) {
|
|
74
76
|
if (!storage)
|
|
@@ -162,11 +164,29 @@ export const openbotRuntime = (options) => (builder) => {
|
|
|
162
164
|
if (abortSignal?.aborted)
|
|
163
165
|
return;
|
|
164
166
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
165
|
-
|
|
166
|
-
errorMessage
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
167
|
+
if (isCreditsCloudAgent(context.state.agentId)) {
|
|
168
|
+
if (isCreditsErrorMessage(errorMessage)) {
|
|
169
|
+
yield {
|
|
170
|
+
type: 'agent:output',
|
|
171
|
+
data: {
|
|
172
|
+
content: 'Insufficient workspace credits. Add credits in workspace settings or switch this agent to BYOK mode.',
|
|
173
|
+
},
|
|
174
|
+
meta: { agentId: context.state.agentId, threadId },
|
|
175
|
+
};
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (isAuthErrorMessage(errorMessage)) {
|
|
179
|
+
yield {
|
|
180
|
+
type: 'agent:output',
|
|
181
|
+
data: {
|
|
182
|
+
content: 'Could not authenticate via OpenBot Credits. Check your workspace credit balance in settings, or switch this agent to BYOK mode.',
|
|
183
|
+
},
|
|
184
|
+
meta: { agentId: context.state.agentId, threadId },
|
|
185
|
+
};
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (isAuthErrorMessage(errorMessage) && !isCreditsCloudAgent(context.state.agentId)) {
|
|
170
190
|
const registry = await host.resolveModelRegistry();
|
|
171
191
|
const providerActions = host.listApiKeyProvidersFromRegistry(registry).map((provider) => ({
|
|
172
192
|
id: provider.id,
|
|
@@ -340,7 +360,7 @@ export const openbotRuntime = (options) => (builder) => {
|
|
|
340
360
|
await storage.createVariable({ key: envVar, value: apiKey, secret: true });
|
|
341
361
|
process.env[envVar] = apiKey;
|
|
342
362
|
currentModelString = newModelString;
|
|
343
|
-
model =
|
|
363
|
+
model = resolveCurrentModel();
|
|
344
364
|
try {
|
|
345
365
|
host.saveConfig({ model: currentModelString });
|
|
346
366
|
const details = await storage.getAgentDetails({ agentId: context.state.agentId });
|