@olane/o-intelligence 0.7.59 → 0.7.61
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/src/base-intelligence-router.tool.d.ts +135 -0
- package/dist/src/base-intelligence-router.tool.d.ts.map +1 -0
- package/dist/src/base-intelligence-router.tool.js +338 -0
- package/dist/src/base-intelligence.tool.d.ts +140 -0
- package/dist/src/base-intelligence.tool.d.ts.map +1 -0
- package/dist/src/base-intelligence.tool.js +153 -0
- package/dist/src/gemini-intelligence.tool.d.ts +15 -3
- package/dist/src/gemini-intelligence.tool.d.ts.map +1 -1
- package/dist/src/gemini-intelligence.tool.js +279 -11
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/interfaces/provider-types.d.ts +421 -0
- package/dist/src/interfaces/provider-types.d.ts.map +1 -0
- package/dist/src/interfaces/provider-types.js +8 -0
- package/dist/src/methods/llm.methods.d.ts.map +1 -1
- package/dist/src/methods/llm.methods.js +84 -0
- package/dist/src/o-intelligence.tool.d.ts +1 -0
- package/dist/src/o-intelligence.tool.d.ts.map +1 -1
- package/dist/src/o-intelligence.tool.js +5 -2
- package/dist/src/openai-intelligence.tool.d.ts +4 -0
- package/dist/src/openai-intelligence.tool.d.ts.map +1 -1
- package/dist/src/openai-intelligence.tool.js +83 -0
- package/package.json +7 -7
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BaseIntelligenceRouter - Abstract base class for intelligence routing tools
|
|
3
|
+
*
|
|
4
|
+
* This base class extracts common patterns from intelligence routers:
|
|
5
|
+
* - Secure storage access (getSecureValue)
|
|
6
|
+
* - Provider selection logic (getModelProvider, getProviderApiKey)
|
|
7
|
+
* - Request routing (chooseIntelligence)
|
|
8
|
+
* - Configuration management (_tool_configure)
|
|
9
|
+
* - Prompt execution (_tool_prompt)
|
|
10
|
+
*
|
|
11
|
+
* Subclasses implement:
|
|
12
|
+
* - createChildTools(): Returns array of provider tools to register
|
|
13
|
+
*
|
|
14
|
+
* This allows o-braintrust to extend with Braintrust-instrumented children
|
|
15
|
+
* while reusing all routing, API key management, and configuration logic.
|
|
16
|
+
*/
|
|
17
|
+
import { oAddress } from '@olane/o-core';
|
|
18
|
+
import { oLaneTool } from '@olane/o-lane';
|
|
19
|
+
import { oNodeToolConfig } from '@olane/o-node';
|
|
20
|
+
import { ToolResult } from '@olane/o-tool';
|
|
21
|
+
import { LLMProviders } from './enums/llm-providers.enum.js';
|
|
22
|
+
export interface BaseIntelligenceRouterConfig extends oNodeToolConfig {
|
|
23
|
+
description?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface PromptRequest {
|
|
26
|
+
params: {
|
|
27
|
+
userMessage?: string;
|
|
28
|
+
prompt: string;
|
|
29
|
+
_isStreaming?: boolean;
|
|
30
|
+
};
|
|
31
|
+
stream?: any;
|
|
32
|
+
}
|
|
33
|
+
export interface ConfigureRequest {
|
|
34
|
+
params: {
|
|
35
|
+
modelProvider?: LLMProviders;
|
|
36
|
+
hostingProvider?: string;
|
|
37
|
+
accessToken?: string;
|
|
38
|
+
address?: string;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Abstract base router for intelligence tools
|
|
43
|
+
*
|
|
44
|
+
* Usage (subclass example):
|
|
45
|
+
* ```typescript
|
|
46
|
+
* export class IntelligenceTool extends BaseIntelligenceRouter {
|
|
47
|
+
* constructor(config: oNodeToolConfig) {
|
|
48
|
+
* super({
|
|
49
|
+
* ...config,
|
|
50
|
+
* address: new oAddress('o://intelligence'),
|
|
51
|
+
* methods: INTELLIGENCE_PARAMS,
|
|
52
|
+
* description: 'Intelligence router',
|
|
53
|
+
* });
|
|
54
|
+
* }
|
|
55
|
+
*
|
|
56
|
+
* protected createChildTools(): oLaneTool[] {
|
|
57
|
+
* return [
|
|
58
|
+
* new AnthropicIntelligenceTool({ parent: this.address, leader: this.leader }),
|
|
59
|
+
* new OpenAIIntelligenceTool({ parent: this.address, leader: this.leader }),
|
|
60
|
+
* // ... other providers
|
|
61
|
+
* ];
|
|
62
|
+
* }
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare abstract class BaseIntelligenceRouter extends oLaneTool {
|
|
67
|
+
protected roundRobinIndex: number;
|
|
68
|
+
constructor(config: BaseIntelligenceRouterConfig & {
|
|
69
|
+
address: oAddress;
|
|
70
|
+
methods: any;
|
|
71
|
+
});
|
|
72
|
+
/**
|
|
73
|
+
* Abstract method: Create child provider tools
|
|
74
|
+
* Subclasses implement to return appropriate provider tools
|
|
75
|
+
* (standard HTTP-based or Braintrust-instrumented)
|
|
76
|
+
*/
|
|
77
|
+
protected abstract createChildTools(): oLaneTool[];
|
|
78
|
+
/**
|
|
79
|
+
* Get secure value from vault
|
|
80
|
+
* ✅ Shared secure storage access
|
|
81
|
+
*/
|
|
82
|
+
getSecureValue(key: string): Promise<string | null>;
|
|
83
|
+
/**
|
|
84
|
+
* Get model provider preference
|
|
85
|
+
* ✅ Shared provider selection logic
|
|
86
|
+
*
|
|
87
|
+
* Priority:
|
|
88
|
+
* 1. Environment variable MODEL_PROVIDER_CHOICE
|
|
89
|
+
* 2. Secure storage preference
|
|
90
|
+
* 3. Ask user (if o://human available)
|
|
91
|
+
* 4. Default to anthropic
|
|
92
|
+
*/
|
|
93
|
+
getModelProvider(): Promise<{
|
|
94
|
+
provider: LLMProviders;
|
|
95
|
+
}>;
|
|
96
|
+
/**
|
|
97
|
+
* Get provider API key
|
|
98
|
+
* ✅ Shared API key retrieval logic
|
|
99
|
+
*
|
|
100
|
+
* Priority:
|
|
101
|
+
* 1. Environment variable (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.)
|
|
102
|
+
* 2. Secure storage
|
|
103
|
+
* 3. Ask user (if o://human available)
|
|
104
|
+
*/
|
|
105
|
+
getProviderApiKey(provider: LLMProviders): Promise<{
|
|
106
|
+
apiKey: string;
|
|
107
|
+
}>;
|
|
108
|
+
/**
|
|
109
|
+
* Choose intelligence provider and get configuration
|
|
110
|
+
* ✅ Shared routing logic
|
|
111
|
+
*/
|
|
112
|
+
chooseIntelligence(request: PromptRequest): Promise<{
|
|
113
|
+
choice: oAddress;
|
|
114
|
+
apiKey: string;
|
|
115
|
+
options: any;
|
|
116
|
+
}>;
|
|
117
|
+
/**
|
|
118
|
+
* Configure intelligence preferences
|
|
119
|
+
* ✅ Shared configuration management
|
|
120
|
+
*/
|
|
121
|
+
_tool_configure(request: ConfigureRequest): Promise<ToolResult>;
|
|
122
|
+
/**
|
|
123
|
+
* Main prompt method - routes to appropriate provider
|
|
124
|
+
* ✅ Shared routing and streaming logic
|
|
125
|
+
*
|
|
126
|
+
* We cannot wrap this tool use in a plan because it is a core dependency in all planning
|
|
127
|
+
*/
|
|
128
|
+
_tool_prompt(request: PromptRequest): Promise<ToolResult>;
|
|
129
|
+
/**
|
|
130
|
+
* Initialize router and register child provider tools
|
|
131
|
+
* ✅ Calls abstract createChildTools() for subclass customization
|
|
132
|
+
*/
|
|
133
|
+
initialize(): Promise<void>;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=base-intelligence-router.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-intelligence-router.tool.d.ts","sourceRoot":"","sources":["../../src/base-intelligence-router.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,QAAQ,EAAwB,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,MAAM,WAAW,4BAA6B,SAAQ,eAAe;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE;QACN,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,CAAC;IACF,MAAM,CAAC,EAAE,GAAG,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE;QACN,aAAa,CAAC,EAAE,YAAY,CAAC;QAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,8BAAsB,sBAAuB,SAAQ,SAAS;IAC5D,SAAS,CAAC,eAAe,SAAK;gBAElB,MAAM,EAAE,4BAA4B,GAAG;QAAE,OAAO,EAAE,QAAQ,CAAC;QAAC,OAAO,EAAE,GAAG,CAAA;KAAE;IAqBtF;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,gBAAgB,IAAI,SAAS,EAAE;IAElD;;;OAGG;IACG,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAmBzD;;;;;;;;;OASG;IACG,gBAAgB,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;IA+D7D;;;;;;;;OAQG;IACG,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IA0E5E;;;OAGG;IACG,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC;QACxD,MAAM,EAAE,QAAQ,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,GAAG,CAAC;KACd,CAAC;IAYF;;;OAGG;IACG,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IAkDrE;;;;;OAKG;IACG,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC;IA4C/D;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAYlC"}
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BaseIntelligenceRouter - Abstract base class for intelligence routing tools
|
|
3
|
+
*
|
|
4
|
+
* This base class extracts common patterns from intelligence routers:
|
|
5
|
+
* - Secure storage access (getSecureValue)
|
|
6
|
+
* - Provider selection logic (getModelProvider, getProviderApiKey)
|
|
7
|
+
* - Request routing (chooseIntelligence)
|
|
8
|
+
* - Configuration management (_tool_configure)
|
|
9
|
+
* - Prompt execution (_tool_prompt)
|
|
10
|
+
*
|
|
11
|
+
* Subclasses implement:
|
|
12
|
+
* - createChildTools(): Returns array of provider tools to register
|
|
13
|
+
*
|
|
14
|
+
* This allows o-braintrust to extend with Braintrust-instrumented children
|
|
15
|
+
* while reusing all routing, API key management, and configuration logic.
|
|
16
|
+
*/
|
|
17
|
+
import { oAddress, oResponse, CoreUtils } from '@olane/o-core';
|
|
18
|
+
import { oLaneTool } from '@olane/o-lane';
|
|
19
|
+
import { IntelligenceStorageKeys } from './enums/intelligence-storage-keys.enum.js';
|
|
20
|
+
import { LLMProviders } from './enums/llm-providers.enum.js';
|
|
21
|
+
/**
|
|
22
|
+
* Abstract base router for intelligence tools
|
|
23
|
+
*
|
|
24
|
+
* Usage (subclass example):
|
|
25
|
+
* ```typescript
|
|
26
|
+
* export class IntelligenceTool extends BaseIntelligenceRouter {
|
|
27
|
+
* constructor(config: oNodeToolConfig) {
|
|
28
|
+
* super({
|
|
29
|
+
* ...config,
|
|
30
|
+
* address: new oAddress('o://intelligence'),
|
|
31
|
+
* methods: INTELLIGENCE_PARAMS,
|
|
32
|
+
* description: 'Intelligence router',
|
|
33
|
+
* });
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* protected createChildTools(): oLaneTool[] {
|
|
37
|
+
* return [
|
|
38
|
+
* new AnthropicIntelligenceTool({ parent: this.address, leader: this.leader }),
|
|
39
|
+
* new OpenAIIntelligenceTool({ parent: this.address, leader: this.leader }),
|
|
40
|
+
* // ... other providers
|
|
41
|
+
* ];
|
|
42
|
+
* }
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export class BaseIntelligenceRouter extends oLaneTool {
|
|
47
|
+
constructor(config) {
|
|
48
|
+
super({
|
|
49
|
+
...config,
|
|
50
|
+
description: config.description ||
|
|
51
|
+
'Tool to help route LLM requests to the best intelligence tool',
|
|
52
|
+
dependencies: config.dependencies || [
|
|
53
|
+
{
|
|
54
|
+
address: 'o://setup',
|
|
55
|
+
parameters: [
|
|
56
|
+
{
|
|
57
|
+
name: 'intelligence',
|
|
58
|
+
type: 'string',
|
|
59
|
+
description: 'The intelligence tool to use',
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
});
|
|
65
|
+
this.roundRobinIndex = 0;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get secure value from vault
|
|
69
|
+
* ✅ Shared secure storage access
|
|
70
|
+
*/
|
|
71
|
+
async getSecureValue(key) {
|
|
72
|
+
try {
|
|
73
|
+
const response = await this.use(new oAddress('o://secure'), {
|
|
74
|
+
method: 'get',
|
|
75
|
+
params: {
|
|
76
|
+
key: key,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
const payload = response.result.data;
|
|
80
|
+
if (payload && payload.value) {
|
|
81
|
+
return payload.value;
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
this.logger.error('Error getting secure value: ', error);
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get model provider preference
|
|
92
|
+
* ✅ Shared provider selection logic
|
|
93
|
+
*
|
|
94
|
+
* Priority:
|
|
95
|
+
* 1. Environment variable MODEL_PROVIDER_CHOICE
|
|
96
|
+
* 2. Secure storage preference
|
|
97
|
+
* 3. Ask user (if o://human available)
|
|
98
|
+
* 4. Default to anthropic
|
|
99
|
+
*/
|
|
100
|
+
async getModelProvider() {
|
|
101
|
+
// Check ENV vars for override
|
|
102
|
+
if (process.env.MODEL_PROVIDER_CHOICE) {
|
|
103
|
+
if (Object.values(LLMProviders).includes(process.env.MODEL_PROVIDER_CHOICE)) {
|
|
104
|
+
return {
|
|
105
|
+
provider: process.env.MODEL_PROVIDER_CHOICE,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
throw new Error('Invalid model provider choice, please set the MODEL_PROVIDER_CHOICE environment variable to a valid model provider');
|
|
109
|
+
}
|
|
110
|
+
let model = LLMProviders.ANTHROPIC;
|
|
111
|
+
// Check secure storage for preference
|
|
112
|
+
const modelProviderStored = await this.getSecureValue(IntelligenceStorageKeys.MODEL_PROVIDER_PREFERENCE);
|
|
113
|
+
if (modelProviderStored) {
|
|
114
|
+
model = modelProviderStored;
|
|
115
|
+
return {
|
|
116
|
+
provider: model,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// No preference found, ask the human
|
|
120
|
+
this.logger.info('Asking human for model selection...');
|
|
121
|
+
try {
|
|
122
|
+
const modelResponse = await this.use(new oAddress('o://human'), {
|
|
123
|
+
method: 'question',
|
|
124
|
+
params: {
|
|
125
|
+
question: 'Which AI model do you want to use? (anthropic, openai, ollama, perplexity, grok)',
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
// Process the human response
|
|
129
|
+
const { answer: modelHuman } = modelResponse.result.data;
|
|
130
|
+
model = modelHuman.toLowerCase();
|
|
131
|
+
await this.use(new oAddress('o://secure'), {
|
|
132
|
+
method: 'put',
|
|
133
|
+
params: {
|
|
134
|
+
key: IntelligenceStorageKeys.MODEL_PROVIDER_PREFERENCE,
|
|
135
|
+
value: model,
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
this.logger.warn('Defaulting to anthropic');
|
|
141
|
+
model = LLMProviders.ANTHROPIC;
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
provider: model,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get provider API key
|
|
149
|
+
* ✅ Shared API key retrieval logic
|
|
150
|
+
*
|
|
151
|
+
* Priority:
|
|
152
|
+
* 1. Environment variable (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.)
|
|
153
|
+
* 2. Secure storage
|
|
154
|
+
* 3. Ask user (if o://human available)
|
|
155
|
+
*/
|
|
156
|
+
async getProviderApiKey(provider) {
|
|
157
|
+
// Leverage the ENV vars first
|
|
158
|
+
const ENV_KEYS = [
|
|
159
|
+
{
|
|
160
|
+
key: process.env.ANTHROPIC_API_KEY,
|
|
161
|
+
address: 'o://anthropic',
|
|
162
|
+
name: 'anthropic',
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
key: process.env.OPENAI_API_KEY,
|
|
166
|
+
address: 'o://openai',
|
|
167
|
+
name: 'openai',
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
key: process.env.SONAR_API_KEY,
|
|
171
|
+
address: 'o://sonar',
|
|
172
|
+
name: 'sonar',
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
key: process.env.GEMINI_API_KEY,
|
|
176
|
+
address: 'o://gemini',
|
|
177
|
+
name: 'gemini',
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
key: process.env.GROK_API_KEY,
|
|
181
|
+
address: 'o://grok',
|
|
182
|
+
name: 'grok',
|
|
183
|
+
},
|
|
184
|
+
];
|
|
185
|
+
const modelEnvConfig = ENV_KEYS.find((key) => key.name === provider);
|
|
186
|
+
if (modelEnvConfig && !!modelEnvConfig.key) {
|
|
187
|
+
return {
|
|
188
|
+
apiKey: modelEnvConfig.key,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
let apiKey = '';
|
|
192
|
+
// Check secure storage 2nd
|
|
193
|
+
const apiKeyStored = await this.getSecureValue(`${provider}-${IntelligenceStorageKeys.API_KEY_SUFFIX}`);
|
|
194
|
+
if (apiKeyStored) {
|
|
195
|
+
return {
|
|
196
|
+
apiKey: apiKeyStored,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
// No preference found, ask the human
|
|
200
|
+
this.logger.info('Asking human for API key...');
|
|
201
|
+
const keyResponse = await this.use(new oAddress('o://human'), {
|
|
202
|
+
method: 'question',
|
|
203
|
+
params: {
|
|
204
|
+
question: `What is the API key for the ${provider} model?`,
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
// Process the human response
|
|
208
|
+
const { answer: key } = keyResponse.result.data;
|
|
209
|
+
apiKey = key;
|
|
210
|
+
await this.use(new oAddress('o://secure'), {
|
|
211
|
+
method: 'put',
|
|
212
|
+
params: {
|
|
213
|
+
key: `${provider}-${IntelligenceStorageKeys.API_KEY_SUFFIX}`,
|
|
214
|
+
value: key,
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
return {
|
|
218
|
+
apiKey: apiKey,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Choose intelligence provider and get configuration
|
|
223
|
+
* ✅ Shared routing logic
|
|
224
|
+
*/
|
|
225
|
+
async chooseIntelligence(request) {
|
|
226
|
+
// Check to see if provider key is in vault
|
|
227
|
+
const { provider } = await this.getModelProvider();
|
|
228
|
+
const { apiKey } = await this.getProviderApiKey(provider);
|
|
229
|
+
return {
|
|
230
|
+
choice: new oAddress(`o://${provider}`),
|
|
231
|
+
apiKey,
|
|
232
|
+
options: {},
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Configure intelligence preferences
|
|
237
|
+
* ✅ Shared configuration management
|
|
238
|
+
*/
|
|
239
|
+
async _tool_configure(request) {
|
|
240
|
+
const { modelProvider, hostingProvider, accessToken, address } = request.params;
|
|
241
|
+
if (hostingProvider) {
|
|
242
|
+
await this.use(new oAddress('o://secure'), {
|
|
243
|
+
method: 'put',
|
|
244
|
+
params: {
|
|
245
|
+
key: `${IntelligenceStorageKeys.HOSTING_PROVIDER_PREFERENCE}`,
|
|
246
|
+
value: hostingProvider,
|
|
247
|
+
},
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
if (accessToken) {
|
|
251
|
+
await this.use(new oAddress('o://secure'), {
|
|
252
|
+
method: 'put',
|
|
253
|
+
params: {
|
|
254
|
+
key: `${IntelligenceStorageKeys.ACCESS_TOKEN}`,
|
|
255
|
+
value: accessToken,
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
if (address) {
|
|
260
|
+
await this.use(new oAddress('o://secure'), {
|
|
261
|
+
method: 'put',
|
|
262
|
+
params: {
|
|
263
|
+
key: `${IntelligenceStorageKeys.OLANE_ADDRESS}`,
|
|
264
|
+
value: address,
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
if (modelProvider) {
|
|
269
|
+
await this.use(new oAddress('o://secure'), {
|
|
270
|
+
method: 'put',
|
|
271
|
+
params: {
|
|
272
|
+
key: `${IntelligenceStorageKeys.MODEL_PROVIDER_PREFERENCE}`,
|
|
273
|
+
value: modelProvider,
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
// ✅ Return raw data (not wrapped)
|
|
278
|
+
return {
|
|
279
|
+
success: true,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Main prompt method - routes to appropriate provider
|
|
284
|
+
* ✅ Shared routing and streaming logic
|
|
285
|
+
*
|
|
286
|
+
* We cannot wrap this tool use in a plan because it is a core dependency in all planning
|
|
287
|
+
*/
|
|
288
|
+
async _tool_prompt(request) {
|
|
289
|
+
const { userMessage, prompt, _isStreaming = false } = request.params;
|
|
290
|
+
const stream = request.stream;
|
|
291
|
+
const intelligence = await this.chooseIntelligence(request);
|
|
292
|
+
const child = this.hierarchyManager.getChild(intelligence.choice);
|
|
293
|
+
const response = await this.useChild(child || intelligence.choice, {
|
|
294
|
+
method: 'completion',
|
|
295
|
+
params: {
|
|
296
|
+
_isStreaming: _isStreaming,
|
|
297
|
+
apiKey: intelligence.apiKey,
|
|
298
|
+
messages: !!userMessage
|
|
299
|
+
? [
|
|
300
|
+
{
|
|
301
|
+
role: 'assistant',
|
|
302
|
+
content: prompt,
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
role: 'user',
|
|
306
|
+
content: userMessage,
|
|
307
|
+
},
|
|
308
|
+
]
|
|
309
|
+
: [
|
|
310
|
+
{
|
|
311
|
+
role: 'user',
|
|
312
|
+
content: prompt,
|
|
313
|
+
},
|
|
314
|
+
],
|
|
315
|
+
},
|
|
316
|
+
}, {
|
|
317
|
+
isStream: _isStreaming || false,
|
|
318
|
+
onChunk: async (chunk) => {
|
|
319
|
+
await CoreUtils.sendResponse(oResponse.fromJSON(chunk), stream);
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
return response.result.data;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Initialize router and register child provider tools
|
|
326
|
+
* ✅ Calls abstract createChildTools() for subclass customization
|
|
327
|
+
*/
|
|
328
|
+
async initialize() {
|
|
329
|
+
await super.initialize();
|
|
330
|
+
const tools = this.createChildTools();
|
|
331
|
+
for (const tool of tools) {
|
|
332
|
+
tool.onInitFinished(() => {
|
|
333
|
+
this.addChildNode(tool);
|
|
334
|
+
});
|
|
335
|
+
await tool.start();
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BaseIntelligenceTool - Abstract base class for LLM provider tools
|
|
3
|
+
*
|
|
4
|
+
* This base class extracts common patterns from all provider intelligence tools:
|
|
5
|
+
* - Validation (API keys, messages, prompts)
|
|
6
|
+
* - Error handling (throw errors, no error returns)
|
|
7
|
+
* - Streaming vs non-streaming patterns
|
|
8
|
+
* - Tool method templates (_tool_completion, _tool_generate, etc.)
|
|
9
|
+
*
|
|
10
|
+
* Provider-specific implementations extend this class and implement:
|
|
11
|
+
* - getApiKeyEnvVar(): Returns the environment variable name for the API key
|
|
12
|
+
* - callCompletion(params): Makes the actual API call for completion
|
|
13
|
+
* - streamCompletion(params): Handles streaming completion
|
|
14
|
+
* - callGenerate(params): Makes the actual API call for generation
|
|
15
|
+
* - streamGenerate(params): Handles streaming generation
|
|
16
|
+
*
|
|
17
|
+
* Subclasses can use either HTTP fetch() or official SDKs with Braintrust instrumentation.
|
|
18
|
+
*/
|
|
19
|
+
import { oLaneTool } from '@olane/o-lane';
|
|
20
|
+
import { oNodeToolConfig, oStreamRequest } from '@olane/o-node';
|
|
21
|
+
import { oAddress, oRequest } from '@olane/o-core';
|
|
22
|
+
import { ToolResult } from '@olane/o-tool';
|
|
23
|
+
export interface BaseIntelligenceConfig extends oNodeToolConfig {
|
|
24
|
+
apiKey?: string;
|
|
25
|
+
defaultModel?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Abstract base class for intelligence provider tools
|
|
29
|
+
*
|
|
30
|
+
* Usage (subclass example):
|
|
31
|
+
* ```typescript
|
|
32
|
+
* export class AnthropicIntelligenceTool extends BaseIntelligenceTool {
|
|
33
|
+
* constructor(config: oNodeToolConfig) {
|
|
34
|
+
* super({
|
|
35
|
+
* ...config,
|
|
36
|
+
* address: new oAddress('o://anthropic'),
|
|
37
|
+
* description: 'Anthropic LLM provider',
|
|
38
|
+
* defaultModel: 'claude-sonnet-4-5-20250929',
|
|
39
|
+
* });
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* protected getApiKeyEnvVar(): string {
|
|
43
|
+
* return 'ANTHROPIC_API_KEY';
|
|
44
|
+
* }
|
|
45
|
+
*
|
|
46
|
+
* protected async callCompletion(params: any): Promise<ToolResult> {
|
|
47
|
+
* // Anthropic-specific HTTP implementation or SDK call
|
|
48
|
+
* }
|
|
49
|
+
*
|
|
50
|
+
* protected async *streamCompletion(params: any): AsyncGenerator<ToolResult> {
|
|
51
|
+
* // Anthropic-specific streaming implementation
|
|
52
|
+
* }
|
|
53
|
+
* }
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare abstract class BaseIntelligenceTool extends oLaneTool {
|
|
57
|
+
protected defaultModel: string;
|
|
58
|
+
protected apiKey: string;
|
|
59
|
+
constructor(config: BaseIntelligenceConfig & {
|
|
60
|
+
address: oAddress;
|
|
61
|
+
description: string;
|
|
62
|
+
methods: any;
|
|
63
|
+
});
|
|
64
|
+
/**
|
|
65
|
+
* Abstract method: Get the environment variable name for the provider's API key
|
|
66
|
+
* Subclasses must implement this
|
|
67
|
+
*/
|
|
68
|
+
protected abstract getApiKeyEnvVar(): string;
|
|
69
|
+
/**
|
|
70
|
+
* Abstract method: Call completion API (non-streaming)
|
|
71
|
+
* Subclasses implement with HTTP fetch() or SDK
|
|
72
|
+
*
|
|
73
|
+
* Must throw errors for validation failures
|
|
74
|
+
* Must return raw data (not wrapped in success object)
|
|
75
|
+
*/
|
|
76
|
+
protected abstract callCompletion(params: any): Promise<ToolResult>;
|
|
77
|
+
/**
|
|
78
|
+
* Abstract method: Stream completion API
|
|
79
|
+
* Subclasses implement with HTTP fetch() or SDK streaming
|
|
80
|
+
*
|
|
81
|
+
* Must yield errors by throwing (generator will catch and wrap)
|
|
82
|
+
* Must yield raw data chunks
|
|
83
|
+
*/
|
|
84
|
+
protected abstract streamCompletion(params: any): AsyncGenerator<ToolResult>;
|
|
85
|
+
/**
|
|
86
|
+
* Abstract method: Call generate API (non-streaming)
|
|
87
|
+
* Optional - some providers may not implement this
|
|
88
|
+
*/
|
|
89
|
+
protected abstract callGenerate(params: any): Promise<ToolResult>;
|
|
90
|
+
/**
|
|
91
|
+
* Abstract method: Stream generate API
|
|
92
|
+
* Optional - some providers may not implement this
|
|
93
|
+
*/
|
|
94
|
+
protected abstract streamGenerate(params: any): AsyncGenerator<ToolResult>;
|
|
95
|
+
/**
|
|
96
|
+
* Shared validation: API key
|
|
97
|
+
* ✅ Throws error for validation failure
|
|
98
|
+
*/
|
|
99
|
+
protected validateApiKey(apiKey: string | undefined): void;
|
|
100
|
+
/**
|
|
101
|
+
* Shared validation: Messages array
|
|
102
|
+
* ✅ Throws error for validation failure
|
|
103
|
+
*/
|
|
104
|
+
protected validateMessages(messages: any): void;
|
|
105
|
+
/**
|
|
106
|
+
* Shared validation: Prompt string
|
|
107
|
+
* ✅ Throws error for validation failure
|
|
108
|
+
*/
|
|
109
|
+
protected validatePrompt(prompt: any): void;
|
|
110
|
+
/**
|
|
111
|
+
* Tool method: Chat completion
|
|
112
|
+
* ✅ Template method pattern - delegates to subclass
|
|
113
|
+
* ✅ Handles streaming vs non-streaming
|
|
114
|
+
* ✅ Throws errors (base class wraps them)
|
|
115
|
+
*/
|
|
116
|
+
_tool_completion(request: oStreamRequest): Promise<ToolResult>;
|
|
117
|
+
/**
|
|
118
|
+
* Tool method: Text generation
|
|
119
|
+
* ✅ Template method pattern - delegates to subclass
|
|
120
|
+
* ✅ Handles streaming vs non-streaming
|
|
121
|
+
* ✅ Throws errors (base class wraps them)
|
|
122
|
+
*/
|
|
123
|
+
_tool_generate(request: oStreamRequest): Promise<ToolResult>;
|
|
124
|
+
/**
|
|
125
|
+
* Tool method: List models
|
|
126
|
+
* Default implementation - subclasses can override
|
|
127
|
+
*/
|
|
128
|
+
_tool_list_models(request: oRequest): Promise<ToolResult>;
|
|
129
|
+
/**
|
|
130
|
+
* Tool method: Get model info
|
|
131
|
+
* Default implementation - subclasses can override
|
|
132
|
+
*/
|
|
133
|
+
_tool_model_info(request: oRequest): Promise<ToolResult>;
|
|
134
|
+
/**
|
|
135
|
+
* Tool method: Check API status
|
|
136
|
+
* Default implementation - subclasses can override
|
|
137
|
+
*/
|
|
138
|
+
_tool_status(request: oRequest): Promise<ToolResult>;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=base-intelligence.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-intelligence.tool.d.ts","sourceRoot":"","sources":["../../src/base-intelligence.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAe,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,WAAW,sBAAuB,SAAQ,eAAe;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,8BAAsB,oBAAqB,SAAQ,SAAS;IAC1D,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC;IAC/B,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEb,MAAM,EAAE,sBAAsB,GAAG;QAAE,OAAO,EAAE,QAAQ,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,GAAG,CAAA;KAAE;IAUrG;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,eAAe,IAAI,MAAM;IAE5C;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC;IAEnE;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,GAAG,cAAc,CAAC,UAAU,CAAC;IAE5E;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC;IAEjE;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,GAAG,cAAc,CAAC,UAAU,CAAC;IAE1E;;;OAGG;IACH,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAM1D;;;OAGG;IACH,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI;IAS/C;;;OAGG;IACH,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI;IAS3C;;;;;OAKG;IACG,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAiBpE;;;;;OAKG;IACG,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAmBlE;;;OAGG;IACG,iBAAiB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAI/D;;;OAGG;IACG,gBAAgB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAI9D;;;OAGG;IACG,YAAY,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;CAG3D"}
|