@olane/o-intelligence 0.8.3 → 0.8.4

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/README.md CHANGED
@@ -6,7 +6,7 @@ Multi-provider AI intelligence router for Olane OS that provides a unified inter
6
6
 
7
7
  ```bash
8
8
  # Installation
9
- npm install @olane/o-intelligence
9
+ pnpm install @olane/o-intelligence
10
10
  ```
11
11
 
12
12
  ```typescript
@@ -87,7 +87,7 @@ console.log(result.result.data.message);
87
87
  Configure which AI provider to use and store preferences securely.
88
88
 
89
89
  **Parameters:**
90
- - `modelProvider` (string, optional): Provider to use (`anthropic`, `openai`, `ollama`, `perplexity`, `grok`)
90
+ - `modelProvider` (string, optional): Provider to use (`anthropic`, `openai`, `ollama`, `perplexity`, `grok`, `gemini`)
91
91
  - `hostingProvider` (string, optional): Where models are hosted (`olane`, `local`)
92
92
  - `accessToken` (string, optional): Access token for hosted models
93
93
  - `address` (string, optional): Custom address for hosted models
@@ -111,18 +111,17 @@ Each provider node (`o://anthropic`, `o://openai`, etc.) exposes these tools:
111
111
 
112
112
  #### `completion` - Multi-Turn Conversation
113
113
 
114
- Generate responses with conversation history and system prompts.
114
+ Generate responses with conversation history. This is the primary method for interacting with provider nodes.
115
115
 
116
- **Parameters:**
116
+ **Parameters (from `LLM_PARAMS`):**
117
+ - `model` (string, optional): Specific model to use (defaults to provider's default model)
117
118
  - `messages` (array, required): Conversation history
118
119
  - `role` (string): `user` or `assistant`
119
120
  - `content` (string | array): Message content
120
- - `model` (string, optional): Specific model to use
121
- - `system` (string, optional): System message for behavior control
122
- - `max_tokens` (number, optional): Maximum tokens to generate (default: 1000)
123
- - `temperature` (number, optional): Randomness control (0-1)
124
- - `top_p` (number, optional): Nucleus sampling (0-1)
125
- - `apiKey` (string, optional): Override API key
121
+ - `options` (object, optional): Provider-specific generation options (e.g., `temperature`, `max_tokens`, `top_p`, `system`). See note on two-tier architecture below.
122
+ - `stream` (boolean, optional): Whether to stream the response
123
+
124
+ > **Note**: Parameters like `system`, `max_tokens`, `temperature`, `apiKey` are not defined in the `LLM_PARAMS` method definition. However, providers destructure additional parameters from `request.params` at runtime. Pass provider-specific options via the `options` object or as top-level params depending on the provider. See [Two-Tier Architecture](#two-tier-architecture) for details.
126
125
 
127
126
  **Returns:** Response with message, model info, and token usage
128
127
 
@@ -154,13 +153,11 @@ console.log(response.result.data);
154
153
 
155
154
  Generate text from a single prompt (simpler than completion).
156
155
 
157
- **Parameters:**
158
- - `prompt` (string, required): Input prompt
159
- - `model` (string, optional): Model to use
160
- - `system` (string, optional): System message
161
- - `max_tokens` (number, optional): Token limit
162
- - `temperature` (number, optional): Randomness
163
- - `apiKey` (string, optional): Override API key
156
+ **Parameters (from `LLM_PARAMS`):**
157
+ - `model` (string, required): The model to use for generation
158
+ - `stream` (boolean, optional): Whether to stream the response
159
+
160
+ > **Note**: The `LLM_PARAMS` method definition only specifies `model` and `stream`. However, provider implementations accept additional runtime parameters like `prompt`, `system`, `max_tokens`, and `apiKey` via `request.params`. See [Two-Tier Architecture](#two-tier-architecture) for details.
164
161
 
165
162
  **Returns:** Generated text response
166
163
 
@@ -171,6 +168,7 @@ const result = await intelligence.use(new oAddress('o://openai'), {
171
168
  params: {
172
169
  apiKey: process.env.OPENAI_API_KEY,
173
170
  prompt: 'Explain REST APIs in one paragraph',
171
+ model: 'gpt-4-turbo-preview',
174
172
  max_tokens: 200
175
173
  }
176
174
  });
@@ -252,6 +250,242 @@ console.log(status.result.data);
252
250
  // { success: true, status: 'ok', response: 'Anthropic API is accessible' }
253
251
  ```
254
252
 
253
+ #### `pull_model` - Pull Model (Ollama)
254
+
255
+ Download a model from the Ollama library to the local machine.
256
+
257
+ **Parameters:**
258
+ - `model` (string, required): The model name to pull (e.g., `llama2`, `codellama`)
259
+ - `insecure` (boolean, optional): Whether to allow insecure connections
260
+
261
+ **Returns:** Success confirmation with pull details
262
+
263
+ **Example:**
264
+ ```typescript
265
+ const result = await intelligence.use(new oAddress('o://ollama'), {
266
+ method: 'pull_model',
267
+ params: {
268
+ model: 'llama3.2:latest'
269
+ }
270
+ });
271
+
272
+ console.log(result.result.data);
273
+ // { success: true, message: 'Model llama3.2:latest pulled successfully', details: '...' }
274
+ ```
275
+
276
+ > **Note**: This method is only available on the Ollama provider (`o://ollama`).
277
+
278
+ ---
279
+
280
+ #### `delete_model` - Delete Model (Ollama)
281
+
282
+ Remove a model from the local Ollama installation.
283
+
284
+ **Parameters:**
285
+ - `model` (string, required): The model name to delete
286
+
287
+ **Returns:** Success confirmation
288
+
289
+ **Example:**
290
+ ```typescript
291
+ const result = await intelligence.use(new oAddress('o://ollama'), {
292
+ method: 'delete_model',
293
+ params: {
294
+ model: 'llama2'
295
+ }
296
+ });
297
+
298
+ console.log(result.result.data);
299
+ // { success: true, message: 'Model llama2 deleted successfully' }
300
+ ```
301
+
302
+ > **Note**: This method is only available on the Ollama provider (`o://ollama`).
303
+
304
+ ---
305
+
306
+ #### `embed_documents` - Generate Document Embeddings
307
+
308
+ Generate vector embeddings for multiple text documents. Useful for semantic search and RAG applications.
309
+
310
+ **Parameters:**
311
+ - `input` (array, required): Array of text strings to embed
312
+ - `model` (string, optional): The embedding model to use
313
+ - `apiKey` (string, optional): API key (falls back to environment variable)
314
+ - `dimensions` (number, optional): Number of embedding dimensions (only for text-embedding-3 models)
315
+
316
+ **Returns:** Array of embedding vectors
317
+
318
+ **Example:**
319
+ ```typescript
320
+ const result = await intelligence.use(new oAddress('o://openai'), {
321
+ method: 'embed_documents',
322
+ params: {
323
+ input: ['First document text', 'Second document text'],
324
+ model: 'text-embedding-3-small',
325
+ apiKey: process.env.OPENAI_API_KEY
326
+ }
327
+ });
328
+
329
+ console.log(result.result.data);
330
+ ```
331
+
332
+ > **Note**: Available on providers that support embeddings (OpenAI, Gemini, Ollama).
333
+
334
+ ---
335
+
336
+ #### `embed_query` - Generate Query Embedding
337
+
338
+ Generate a vector embedding for a single query string. Optimized for search queries.
339
+
340
+ **Parameters:**
341
+ - `input` (string, required): Text string to embed
342
+ - `model` (string, optional): The embedding model to use
343
+ - `apiKey` (string, optional): API key (falls back to environment variable)
344
+ - `dimensions` (number, optional): Number of embedding dimensions (only for text-embedding-3 models)
345
+
346
+ **Returns:** Embedding vector
347
+
348
+ **Example:**
349
+ ```typescript
350
+ const result = await intelligence.use(new oAddress('o://openai'), {
351
+ method: 'embed_query',
352
+ params: {
353
+ input: 'What is machine learning?',
354
+ model: 'text-embedding-3-small',
355
+ apiKey: process.env.OPENAI_API_KEY
356
+ }
357
+ });
358
+
359
+ console.log(result.result.data);
360
+ ```
361
+
362
+ > **Note**: Available on providers that support embeddings (OpenAI, Gemini, Ollama).
363
+
364
+ ---
365
+
366
+ #### `generate_image` - Generate Images (Gemini)
367
+
368
+ Generate images from text prompts using Gemini image models.
369
+
370
+ **Parameters:**
371
+ - `prompt` (string, required): Text description of the desired image
372
+ - `model` (string, optional): Model to use (`gemini-2.5-flash-image` (default) or `gemini-3-pro-image-preview`)
373
+ - `aspectRatio` (string, optional): Aspect ratio (e.g., `1:1`, `16:9`, `9:16`). Default: `1:1`
374
+ - `imageSize` (string, optional): Size (`1K`, `2K` (default), `4K`)
375
+ - `negativePrompt` (string, optional): Description of what to avoid in the image
376
+
377
+ **Returns:** Generated image data
378
+
379
+ **Example:**
380
+ ```typescript
381
+ const result = await intelligence.use(new oAddress('o://gemini'), {
382
+ method: 'generate_image',
383
+ params: {
384
+ prompt: 'A serene mountain landscape at sunset',
385
+ aspectRatio: '16:9',
386
+ imageSize: '2K'
387
+ }
388
+ });
389
+
390
+ console.log(result.result.data);
391
+ ```
392
+
393
+ > **Note**: This method is only available on the Gemini provider (`o://gemini`).
394
+
395
+ ---
396
+
397
+ #### `edit_image` - Edit Images (Gemini)
398
+
399
+ Edit or transform an existing image using Gemini image models.
400
+
401
+ **Parameters:**
402
+ - `prompt` (string, required): Instructions for how to edit the image
403
+ - `image` (string, required): Base64-encoded image data or file path (JPEG, PNG)
404
+ - `model` (string, optional): Model to use (`gemini-2.5-flash-image` (default) or `gemini-3-pro-image-preview`)
405
+ - `aspectRatio` (string, optional): Aspect ratio for the edited image
406
+ - `imageSize` (string, optional): Size of the edited image (`1K`, `2K` (default), `4K`)
407
+
408
+ **Returns:** Edited image data
409
+
410
+ **Example:**
411
+ ```typescript
412
+ const result = await intelligence.use(new oAddress('o://gemini'), {
413
+ method: 'edit_image',
414
+ params: {
415
+ prompt: 'Remove the background and replace with a white backdrop',
416
+ image: '/path/to/image.png',
417
+ imageSize: '2K'
418
+ }
419
+ });
420
+
421
+ console.log(result.result.data);
422
+ ```
423
+
424
+ > **Note**: This method is only available on the Gemini provider (`o://gemini`).
425
+
426
+ ---
427
+
428
+ ## Two-Tier Architecture {#two-tier-architecture}
429
+
430
+ `o-intelligence` uses a two-tier method parameter architecture:
431
+
432
+ ### `INTELLIGENCE_PARAMS` (Router Level)
433
+
434
+ Defined in `intelligence.methods.ts`, these are the methods exposed by the `o://intelligence` router node:
435
+ - `configure` - Set provider preferences (`modelProvider`, `hostingProvider`)
436
+ - `prompt` - Simple AI prompting (`prompt`, `userMessage`, `stream`)
437
+
438
+ These are high-level orchestration methods that handle provider selection and routing.
439
+
440
+ ### `LLM_PARAMS` (Provider Level)
441
+
442
+ Defined in `llm.methods.ts`, these are the methods exposed by each provider child node (`o://anthropic`, `o://openai`, etc.):
443
+ - `completion` - Multi-turn conversation (`model`, `messages`, `options`, `stream`)
444
+ - `generate` - Simple text generation (`model`, `stream`)
445
+ - `list_models` - List available models
446
+ - `pull_model` - Pull model (Ollama-specific)
447
+ - `delete_model` - Delete model (Ollama-specific)
448
+ - `model_info` - Get model details (`model`)
449
+ - `status` - Check provider health
450
+ - `embed_documents` - Generate document embeddings
451
+ - `embed_query` - Generate query embedding
452
+ - `generate_image` - Generate images (Gemini-specific)
453
+ - `edit_image` - Edit images (Gemini-specific)
454
+
455
+ **Important**: The `LLM_PARAMS` definitions specify the formal parameter schema for AI discovery. However, individual provider implementations accept additional runtime parameters (like `apiKey`, `system`, `max_tokens`, `temperature`) that are destructured directly from `request.params`. This means you can pass these extra parameters when calling providers, even though they are not declared in the method schema.
456
+
457
+ ## Response Structure {#response-structure}
458
+
459
+ When calling provider methods via `node.use()`, responses follow the standard Olane response pattern:
460
+
461
+ ```typescript
462
+ const response = await intelligence.use(new oAddress('o://anthropic'), {
463
+ method: 'completion',
464
+ params: { messages: [...], model: 'claude-sonnet-4-5-20250929' }
465
+ });
466
+
467
+ // Always check success first
468
+ if (response.result.success) {
469
+ const data = response.result.data;
470
+ console.log(data.message); // The generated text
471
+ console.log(data.model); // Model used
472
+ console.log(data.usage); // Token usage info
473
+ } else {
474
+ console.error(response.result.error); // Error message string
475
+ }
476
+
477
+ // Full response shape:
478
+ // {
479
+ // jsonrpc: "2.0",
480
+ // id: "request-id",
481
+ // result: {
482
+ // success: boolean,
483
+ // data: any, // Present on success
484
+ // error?: string // Present on failure
485
+ // }
486
+ // }
487
+ ```
488
+
255
489
  ## Configuration {#configuration}
256
490
 
257
491
  ### Environment Variables
@@ -267,7 +501,7 @@ export GROK_API_KEY="..."
267
501
  export SONAR_API_KEY="..." # Perplexity
268
502
 
269
503
  # Provider Selection
270
- export MODEL_PROVIDER_CHOICE="anthropic" # anthropic, openai, ollama, perplexity, grok
504
+ export MODEL_PROVIDER_CHOICE="anthropic" # anthropic, openai, ollama, perplexity, grok, gemini
271
505
  ```
272
506
 
273
507
  ### Secure Storage
@@ -292,7 +526,7 @@ If no configuration is found, users will be prompted:
292
526
 
293
527
  ```bash
294
528
  # Terminal output when no provider is configured:
295
- ? Which AI model do you want to use? (anthropic, openai, ollama, perplexity, grok)
529
+ ? Which AI model do you want to use? (anthropic, openai, ollama, perplexity, grok, gemini)
296
530
  > anthropic
297
531
 
298
532
  ? What is the API key for the anthropic model?
@@ -384,7 +618,7 @@ async function generateWithFallback(prompt: string) {
384
618
  }
385
619
  });
386
620
 
387
- if (response.result.data.success !== false) {
621
+ if (response.result.success) {
388
622
  return response.result.data;
389
623
  }
390
624
  } catch (error) {
@@ -585,6 +819,8 @@ enum LLMProviders {
585
819
  }
586
820
  ```
587
821
 
822
+ > **Note**: Gemini is supported as a provider (`o://gemini`) with `GeminiIntelligenceTool`, but is not currently listed in the `LLMProviders` enum. It can be used by directly addressing `o://gemini` when the provider is initialized.
823
+
588
824
  ### HostModelProvider
589
825
 
590
826
  Where AI models are hosted.
@@ -680,7 +916,7 @@ await intelligence.use(new oAddress('o://intelligence'), {
680
916
 
681
917
  **Solution:** Use a valid provider:
682
918
  ```bash
683
- export MODEL_PROVIDER_CHOICE="anthropic" # anthropic, openai, ollama, perplexity, grok
919
+ export MODEL_PROVIDER_CHOICE="anthropic" # anthropic, openai, ollama, perplexity, grok, gemini
684
920
  ```
685
921
 
686
922
  ---
@@ -1,5 +1,6 @@
1
1
  export declare enum IntelligenceStorageKeys {
2
2
  MODEL_PROVIDER_PREFERENCE = "model-provider-preference",
3
+ MODEL_CHOICE = "model-choice",
3
4
  API_KEY_SUFFIX = "api-key",
4
5
  HOSTING_PROVIDER_PREFERENCE = "hosting-provider-preference",
5
6
  ACCESS_TOKEN = "access-token",
@@ -1 +1 @@
1
- {"version":3,"file":"intelligence-storage-keys.enum.d.ts","sourceRoot":"","sources":["../../../src/enums/intelligence-storage-keys.enum.ts"],"names":[],"mappings":"AAAA,oBAAY,uBAAuB;IACjC,yBAAyB,8BAA8B;IACvD,cAAc,YAAY;IAC1B,2BAA2B,gCAAgC;IAC3D,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;CAChC"}
1
+ {"version":3,"file":"intelligence-storage-keys.enum.d.ts","sourceRoot":"","sources":["../../../src/enums/intelligence-storage-keys.enum.ts"],"names":[],"mappings":"AAAA,oBAAY,uBAAuB;IACjC,yBAAyB,8BAA8B;IACvD,YAAY,iBAAiB;IAC7B,cAAc,YAAY;IAC1B,2BAA2B,gCAAgC;IAC3D,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;CAChC"}
@@ -1,6 +1,7 @@
1
1
  export var IntelligenceStorageKeys;
2
2
  (function (IntelligenceStorageKeys) {
3
3
  IntelligenceStorageKeys["MODEL_PROVIDER_PREFERENCE"] = "model-provider-preference";
4
+ IntelligenceStorageKeys["MODEL_CHOICE"] = "model-choice";
4
5
  IntelligenceStorageKeys["API_KEY_SUFFIX"] = "api-key";
5
6
  IntelligenceStorageKeys["HOSTING_PROVIDER_PREFERENCE"] = "hosting-provider-preference";
6
7
  IntelligenceStorageKeys["ACCESS_TOKEN"] = "access-token";
@@ -8,6 +8,7 @@ export interface ConfigureRequest extends oRequest {
8
8
  hostingProvider: HostModelProvider;
9
9
  accessToken: string;
10
10
  address: string;
11
+ model: string;
11
12
  };
12
13
  }
13
14
  //# sourceMappingURL=configure.request.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"configure.request.d.ts","sourceRoot":"","sources":["../../../src/interfaces/configure.request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,MAAM,WAAW,gBAAiB,SAAQ,QAAQ;IAChD,MAAM,EAAE,aAAa,GAAG;QACtB,aAAa,EAAE,YAAY,CAAC;QAC5B,eAAe,EAAE,iBAAiB,CAAC;QACnC,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH"}
1
+ {"version":3,"file":"configure.request.d.ts","sourceRoot":"","sources":["../../../src/interfaces/configure.request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,MAAM,WAAW,gBAAiB,SAAQ,QAAQ;IAChD,MAAM,EAAE,aAAa,GAAG;QACtB,aAAa,EAAE,YAAY,CAAC;QAC5B,eAAe,EAAE,iBAAiB,CAAC;QACnC,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH"}
@@ -1,8 +1,11 @@
1
1
  import { oStreamRequest } from '@olane/o-node';
2
2
  import { RequestParams } from '@olane/o-protocol';
3
+ import { LLMProviders } from '../enums/llm-providers.enum';
3
4
  export interface PromptRequest extends oStreamRequest {
4
5
  params: RequestParams & {
5
6
  prompt: string;
7
+ model?: string;
8
+ provider?: LLMProviders;
6
9
  };
7
10
  }
8
11
  //# sourceMappingURL=prompt.request.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.request.d.ts","sourceRoot":"","sources":["../../../src/interfaces/prompt.request.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,MAAM,EAAE,aAAa,GAAG;QACtB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH"}
1
+ {"version":3,"file":"prompt.request.d.ts","sourceRoot":"","sources":["../../../src/interfaces/prompt.request.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,MAAM,EAAE,aAAa,GAAG;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,YAAY,CAAC;KACzB,CAAC;CACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"intelligence.methods.d.ts","sourceRoot":"","sources":["../../../src/methods/intelligence.methods.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,eAAO,MAAM,mBAAmB,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAiDzD,CAAC"}
1
+ {"version":3,"file":"intelligence.methods.d.ts","sourceRoot":"","sources":["../../../src/methods/intelligence.methods.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,eAAO,MAAM,mBAAmB,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAyEzD,CAAC"}
@@ -18,6 +18,13 @@ export const INTELLIGENCE_PARAMS = {
18
18
  description: 'The hosting provider to use (olane, local)',
19
19
  required: false,
20
20
  },
21
+ {
22
+ name: 'model',
23
+ type: 'string',
24
+ value: 'string',
25
+ description: 'Persistent model preference (e.g., claude-opus-4-20250514, gpt-4o). Stored in secure storage for future requests.',
26
+ required: false,
27
+ },
21
28
  ],
22
29
  },
23
30
  prompt: {
@@ -44,6 +51,20 @@ export const INTELLIGENCE_PARAMS = {
44
51
  description: 'Whether to stream the response',
45
52
  required: false,
46
53
  },
54
+ {
55
+ name: 'model',
56
+ type: 'string',
57
+ value: 'string',
58
+ description: 'Per-request model override (e.g., claude-opus-4-20250514, gpt-4o). Takes priority over configured model.',
59
+ required: false,
60
+ },
61
+ {
62
+ name: 'provider',
63
+ type: 'string',
64
+ value: 'string',
65
+ description: 'Per-request provider override (anthropic, openai, ollama, perplexity, grok, olane). Takes priority over configured provider.',
66
+ required: false,
67
+ },
47
68
  ],
48
69
  },
49
70
  };
@@ -15,10 +15,12 @@ export declare class IntelligenceTool extends oLaneTool {
15
15
  getProviderApiKey(provider: LLMProviders): Promise<{
16
16
  apiKey: string;
17
17
  }>;
18
+ getModelChoice(): Promise<string | undefined>;
18
19
  chooseIntelligence(request: PromptRequest): Promise<{
19
20
  choice: oAddress;
20
21
  apiKey: string;
21
22
  options: any;
23
+ model: string | undefined;
22
24
  }>;
23
25
  _tool_configure(request: ConfigureRequest): Promise<ToolResult>;
24
26
  _tool_prompt(request: PromptRequest): Promise<ToolResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"o-intelligence.tool.d.ts","sourceRoot":"","sources":["../../src/o-intelligence.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,QAAQ,EAAa,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAQ3C,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,qBAAa,gBAAiB,SAAQ,SAAS;IAC7C,OAAO,CAAC,eAAe,CAAK;gBAChB,MAAM,EAAE,eAAe;IAuB7B,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAmBnD,gBAAgB,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;IA6DvD,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAsEtE,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;IAWI,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IA6C/D,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC;IA0CzD,mBAAmB;IAsCnB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAIlC"}
1
+ {"version":3,"file":"o-intelligence.tool.d.ts","sourceRoot":"","sources":["../../src/o-intelligence.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,QAAQ,EAAa,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAQ3C,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,qBAAa,gBAAiB,SAAQ,SAAS;IAC7C,OAAO,CAAC,eAAe,CAAK;gBAChB,MAAM,EAAE,eAAe;IAuB7B,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAmBnD,gBAAgB,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;IA6DvD,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAsEtE,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAa7C,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC;QACxD,MAAM,EAAE,QAAQ,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,GAAG,CAAC;QACb,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;KAC3B,CAAC;IA6BI,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IAsD/D,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC;IAyDzD,mBAAmB;IAsCnB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAIlC"}
@@ -162,18 +162,42 @@ export class IntelligenceTool extends oLaneTool {
162
162
  apiKey: apiKey,
163
163
  };
164
164
  }
165
+ async getModelChoice() {
166
+ if (process.env.MODEL_CHOICE) {
167
+ return process.env.MODEL_CHOICE;
168
+ }
169
+ const modelStored = await this.getSecureValue(IntelligenceStorageKeys.MODEL_CHOICE);
170
+ if (modelStored) {
171
+ return modelStored;
172
+ }
173
+ return undefined;
174
+ }
165
175
  async chooseIntelligence(request) {
166
- // check to see if anthropic key is in vault
167
- const { provider } = await this.getModelProvider();
176
+ const { provider: providerParam, model: modelParam } = request.params;
177
+ // Resolve provider: per-request param > env/storage/human flow
178
+ let provider;
179
+ if (providerParam) {
180
+ if (!Object.values(LLMProviders).includes(providerParam)) {
181
+ throw new Error(`Invalid provider '${providerParam}'. Must be one of: ${Object.values(LLMProviders).join(', ')}`);
182
+ }
183
+ provider = providerParam;
184
+ }
185
+ else {
186
+ const result = await this.getModelProvider();
187
+ provider = result.provider;
188
+ }
189
+ // Resolve model: per-request param > env/storage > undefined (child default)
190
+ const model = modelParam || (await this.getModelChoice());
168
191
  const { apiKey } = await this.getProviderApiKey(provider);
169
192
  return {
170
193
  choice: new oAddress(`o://${provider}`),
171
194
  apiKey,
172
195
  options: {},
196
+ model,
173
197
  };
174
198
  }
175
199
  async _tool_configure(request) {
176
- const { modelProvider, hostingProvider, accessToken, address } = request.params;
200
+ const { modelProvider, hostingProvider, accessToken, address, model } = request.params;
177
201
  if (hostingProvider) {
178
202
  await this.use(new oAddress('o://secure'), {
179
203
  method: 'put',
@@ -210,21 +234,36 @@ export class IntelligenceTool extends oLaneTool {
210
234
  },
211
235
  });
212
236
  }
237
+ if (model) {
238
+ await this.use(new oAddress('o://secure'), {
239
+ method: 'put',
240
+ params: {
241
+ key: `${IntelligenceStorageKeys.MODEL_CHOICE}`,
242
+ value: model,
243
+ },
244
+ });
245
+ }
213
246
  return {
214
247
  success: true,
215
248
  };
216
249
  }
217
250
  // we cannot wrap this tool use in a plan because it is a core dependency in all planning
218
251
  async _tool_prompt(request) {
219
- const { userMessage, prompt, _isStreaming = false } = request.params;
252
+ const { userMessage, prompt, _isStreaming = false, model, provider, } = request.params;
220
253
  const stream = request.stream;
254
+ const providerAddress = provider ? new oAddress(`o://${provider}`) : null;
221
255
  const intelligence = await this.chooseIntelligence(request);
222
- const child = this.hierarchyManager.getChild(intelligence.choice);
256
+ const child = this.hierarchyManager.getChild(providerAddress || intelligence.choice);
223
257
  const response = await this.useChild(child || intelligence.choice, {
224
258
  method: 'completion',
225
259
  params: {
226
260
  _isStreaming: _isStreaming,
227
261
  apiKey: intelligence.apiKey,
262
+ ...(model
263
+ ? { model }
264
+ : intelligence.model
265
+ ? { model: intelligence.model }
266
+ : {}),
228
267
  messages: !!userMessage
229
268
  ? [
230
269
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olane/o-intelligence",
3
- "version": "0.8.3",
3
+ "version": "0.8.4",
4
4
  "type": "module",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -54,13 +54,13 @@
54
54
  "typescript": "5.4.5"
55
55
  },
56
56
  "dependencies": {
57
- "@olane/o-config": "0.8.3",
58
- "@olane/o-core": "0.8.3",
59
- "@olane/o-lane": "0.8.3",
60
- "@olane/o-protocol": "0.8.3",
61
- "@olane/o-tool": "0.8.3",
57
+ "@olane/o-config": "0.8.4",
58
+ "@olane/o-core": "0.8.4",
59
+ "@olane/o-lane": "0.8.4",
60
+ "@olane/o-protocol": "0.8.4",
61
+ "@olane/o-tool": "0.8.4",
62
62
  "debug": "^4.4.1",
63
63
  "dotenv": "^16.5.0"
64
64
  },
65
- "gitHead": "189c0cf7b6dd9d5d961f5424af21d37978092d9e"
65
+ "gitHead": "b53623b1ad4365133911722f80d5597a72b65bf2"
66
66
  }