@semiont/inference 0.2.45 → 0.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/README.md CHANGED
@@ -9,10 +9,10 @@
9
9
  **AI primitives for text generation and client management.**
10
10
 
11
11
  This package provides the **core AI primitives** for the Semiont platform:
12
- - Anthropic client singleton management
12
+ - Inference client implementations (Anthropic, Ollama)
13
13
  - Simple text generation interface
14
14
  - Environment variable expansion for API keys
15
- - Provider abstraction for future extensibility
15
+ - Provider abstraction via `InferenceClient` interface
16
16
 
17
17
  For **application-specific AI logic** (entity extraction, resource generation, motivation prompts/parsers), see [@semiont/make-meaning](../make-meaning/).
18
18
 
@@ -40,6 +40,7 @@ npm install @semiont/inference
40
40
  import { generateText, getInferenceClient, getInferenceModel } from '@semiont/inference';
41
41
  import type { EnvironmentConfig } from '@semiont/core';
42
42
 
43
+ // Anthropic
43
44
  const config: EnvironmentConfig = {
44
45
  services: {
45
46
  inference: {
@@ -50,6 +51,17 @@ const config: EnvironmentConfig = {
50
51
  }
51
52
  };
52
53
 
54
+ // Ollama (no API key required)
55
+ const ollamaConfig: EnvironmentConfig = {
56
+ services: {
57
+ inference: {
58
+ type: 'ollama',
59
+ model: 'gemma2:9b',
60
+ endpoint: 'http://localhost:11434'
61
+ }
62
+ }
63
+ };
64
+
53
65
  // Generate text using the primitive
54
66
  const text = await generateText(
55
67
  'Explain quantum computing in simple terms',
@@ -77,9 +89,9 @@ Simple text generation primitive.
77
89
 
78
90
  **Returns:** `Promise<string>` - Generated text
79
91
 
80
- **Implementation** ([src/factory.ts:68-102](src/factory.ts#L68-L102)):
81
- - Uses Anthropic Messages API
82
- - Extracts text content from first text block in response
92
+ **Implementation** ([src/factory.ts](src/factory.ts)):
93
+ - Routes to provider-specific client (Anthropic Messages API or Ollama `/api/generate`)
94
+ - Extracts text content from response
83
95
  - Throws error if no text content in response
84
96
 
85
97
  **Example:**
@@ -92,28 +104,29 @@ const result = await generateText(
92
104
  );
93
105
  ```
94
106
 
95
- **`getInferenceClient(config): Promise<Anthropic>`**
107
+ **`getInferenceClient(config): Promise<InferenceClient>`**
96
108
 
97
- Get the singleton Anthropic client instance.
109
+ Get an inference client instance based on configuration.
98
110
 
99
111
  **Parameters:**
100
112
  - `config: EnvironmentConfig` - Configuration
101
113
 
102
- **Returns:** `Promise<Anthropic>` - Anthropic client
114
+ **Returns:** `Promise<InferenceClient>` - Provider-specific client implementing the `InferenceClient` interface
103
115
 
104
- **Implementation** ([src/factory.ts:17-52](src/factory.ts#L17-L52)):
105
- - Singleton pattern - creates client once, caches for reuse
106
- - Supports environment variable expansion in API keys (e.g., '${ANTHROPIC_API_KEY}')
107
- - Configurable baseURL with fallback to https://api.anthropic.com
116
+ **Implementation** ([src/factory.ts](src/factory.ts)):
117
+ - Creates `AnthropicInferenceClient` or `OllamaInferenceClient` based on `config.services.inference.type`
118
+ - Supports environment variable expansion in API keys (e.g., `'${ANTHROPIC_API_KEY}'`)
119
+ - Ollama defaults to `http://localhost:11434`, no API key required
108
120
 
109
121
  **Example:**
110
122
  ```typescript
111
123
  const client = await getInferenceClient(config);
112
- const response = await client.messages.create({
113
- model: 'claude-3-5-sonnet-20241022',
114
- max_tokens: 100,
115
- messages: [{ role: 'user', content: 'Hello' }]
116
- });
124
+ const response = await client.generateTextWithMetadata(
125
+ 'Hello',
126
+ 100,
127
+ 0.7
128
+ );
129
+ console.log(response.text);
117
130
  ```
118
131
 
119
132
  **`getInferenceModel(config): string`**
@@ -123,7 +136,7 @@ Get the configured model name.
123
136
  **Parameters:**
124
137
  - `config: EnvironmentConfig` - Configuration
125
138
 
126
- **Returns:** `string` - Model name (e.g., 'claude-3-5-sonnet-20241022')
139
+ **Returns:** `string` - Model name (e.g., `'claude-3-5-sonnet-20241022'` or `'gemma2:9b'`)
127
140
 
128
141
  **Example:**
129
142
  ```typescript
@@ -133,9 +146,10 @@ console.log(`Using model: ${model}`);
133
146
 
134
147
  ## Configuration
135
148
 
136
- From [src/factory.ts:22-48](src/factory.ts#L22-L48):
149
+ From [src/factory.ts](src/factory.ts):
137
150
 
138
151
  ```typescript
152
+ // Anthropic
139
153
  config.services.inference = {
140
154
  type: 'anthropic', // Provider type
141
155
  model: string, // Model name (e.g., 'claude-3-5-sonnet-20241022')
@@ -143,6 +157,13 @@ config.services.inference = {
143
157
  endpoint?: string, // Custom endpoint (optional)
144
158
  baseURL?: string // Fallback endpoint (optional)
145
159
  }
160
+
161
+ // Ollama
162
+ config.services.inference = {
163
+ type: 'ollama', // Provider type
164
+ model: string, // Model name (e.g., 'gemma2:9b', 'llama3.1:8b', 'mistral')
165
+ endpoint?: string, // Ollama server URL (default: http://localhost:11434)
166
+ }
146
167
  ```
147
168
 
148
169
  ### Environment Variable Expansion
@@ -224,33 +245,36 @@ const highlights = await AnnotationDetection.detectHighlights(resourceId, config
224
245
  ┌──────────────────▼──────────────────────────┐
225
246
  │ @semiont/inference │
226
247
  │ (AI primitives only) │
227
- │ - getInferenceClient()
248
+ │ - InferenceClient interface
249
+ │ - getInferenceClient() factory │
228
250
  │ - getInferenceModel() │
229
- │ - generateText() │
230
- └──────────────────┬──────────────────────────┘
231
- uses
232
- ┌──────────────────▼──────────────────────────┐
233
- @anthropic-ai/sdk
234
- │ (Anthropic Messages API)
235
- └─────────────────────────────────────────────┘
251
+ └──────────┬───────────────────┬──────────────┘
252
+ │ │
253
+ ┌──────────▼──────────┐ ┌─────▼──────────────┐
254
+ │ AnthropicInference │ │ OllamaInference │
255
+ Client │ Client │
256
+ │ (@anthropic-ai/sdk)│ │ (native HTTP API)
257
+ └─────────────────────┘ └────────────────────┘
236
258
  ```
237
259
 
238
260
  **Key Principles:**
239
261
  - **@semiont/inference**: Provider abstraction, client management, core text generation
240
262
  - **@semiont/make-meaning**: Semantic processing, prompt engineering, response parsing
241
- - **Clean separation**: Adding OpenAI support only affects @semiont/inference
263
+ - **Clean separation**: Adding a new provider only affects @semiont/inference
242
264
 
243
- ## Provider Extensibility
265
+ ## Supported Providers
244
266
 
245
- The package is designed for future provider support:
267
+ | Provider | Type | API Key | Models |
268
+ |----------|------|---------|--------|
269
+ | Anthropic | `anthropic` | Required (`ANTHROPIC_API_KEY`) | Claude family |
270
+ | Ollama | `ollama` | Not required | gemma2:9b, llama3.1:8b, mistral, etc. |
246
271
 
247
- 1. Update `getInferenceClient()` to support `config.services.inference.type`
248
- 2. Add provider-specific client initialization
249
- 3. Update `generateText()` to handle different API formats
250
- 4. Application code in `@semiont/make-meaning` remains unchanged
272
+ ### Adding a New Provider
251
273
 
252
- **Current Support:** Anthropic (Claude) via `@anthropic-ai/sdk`
253
- **Future:** OpenAI, Google Vertex AI, local models, etc.
274
+ 1. Implement `InferenceClient` interface in `src/implementations/`
275
+ 2. Add type to `InferenceClientType` union in `src/factory.ts`
276
+ 3. Add case in `createInferenceClient()` switch
277
+ 4. Application code in `@semiont/make-meaning` requires no changes
254
278
 
255
279
  ## Dependencies
256
280
 
@@ -259,6 +283,8 @@ From [package.json](package.json):
259
283
  - `@anthropic-ai/sdk` ^0.63.0 - Anthropic API client
260
284
  - `@semiont/core` * - Environment configuration
261
285
 
286
+ Ollama uses native HTTP (`fetch`) with no SDK dependency.
287
+
262
288
  **Note:** No dependency on `@semiont/api-client` - primitives have minimal dependencies
263
289
 
264
290
  ## Testing
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Logger, EnvironmentConfig } from '@semiont/core';
1
+ import { Logger, InferenceServiceConfig } from '@semiont/core';
2
2
 
3
3
  interface InferenceResponse {
4
4
  text: string;
@@ -23,7 +23,7 @@ interface InferenceClient {
23
23
  generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number): Promise<InferenceResponse>;
24
24
  }
25
25
 
26
- type InferenceClientType = 'anthropic';
26
+ type InferenceClientType = 'anthropic' | 'ollama';
27
27
  interface InferenceClientConfig {
28
28
  type: InferenceClientType;
29
29
  apiKey?: string;
@@ -32,11 +32,11 @@ interface InferenceClientConfig {
32
32
  baseURL?: string;
33
33
  }
34
34
  declare function createInferenceClient(config: InferenceClientConfig, logger?: Logger): InferenceClient;
35
- declare function getInferenceClient(config: EnvironmentConfig, logger?: Logger): Promise<InferenceClient>;
35
+ declare function getInferenceClient(inferenceConfig: InferenceServiceConfig, logger?: Logger): Promise<InferenceClient>;
36
36
  /**
37
37
  * Get the configured model name
38
38
  */
39
- declare function getInferenceModel(config: EnvironmentConfig): string;
39
+ declare function getInferenceModel(inferenceConfig: InferenceServiceConfig): string;
40
40
 
41
41
  declare class AnthropicInferenceClient implements InferenceClient {
42
42
  private client;
@@ -47,6 +47,15 @@ declare class AnthropicInferenceClient implements InferenceClient {
47
47
  generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number): Promise<InferenceResponse>;
48
48
  }
49
49
 
50
+ declare class OllamaInferenceClient implements InferenceClient {
51
+ private baseURL;
52
+ private model;
53
+ private logger?;
54
+ constructor(model: string, baseURL?: string, logger?: Logger);
55
+ generateText(prompt: string, maxTokens: number, temperature: number): Promise<string>;
56
+ generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number): Promise<InferenceResponse>;
57
+ }
58
+
50
59
  declare class MockInferenceClient implements InferenceClient {
51
60
  private responses;
52
61
  private responseIndex;
@@ -63,4 +72,4 @@ declare class MockInferenceClient implements InferenceClient {
63
72
  setResponses(responses: string[], stopReasons?: string[]): void;
64
73
  }
65
74
 
66
- export { AnthropicInferenceClient, type InferenceClient, type InferenceClientConfig, type InferenceClientType, type InferenceResponse, MockInferenceClient, createInferenceClient, getInferenceClient, getInferenceModel };
75
+ export { AnthropicInferenceClient, type InferenceClient, type InferenceClientConfig, type InferenceClientType, type InferenceResponse, MockInferenceClient, OllamaInferenceClient, createInferenceClient, getInferenceClient, getInferenceModel };
package/dist/index.js CHANGED
@@ -59,6 +59,78 @@ var AnthropicInferenceClient = class {
59
59
  }
60
60
  };
61
61
 
62
+ // src/implementations/ollama.ts
63
+ var OllamaInferenceClient = class {
64
+ baseURL;
65
+ model;
66
+ logger;
67
+ constructor(model, baseURL, logger) {
68
+ this.baseURL = (baseURL || "http://localhost:11434").replace(/\/+$/, "");
69
+ this.model = model;
70
+ this.logger = logger;
71
+ }
72
+ async generateText(prompt, maxTokens, temperature) {
73
+ const response = await this.generateTextWithMetadata(prompt, maxTokens, temperature);
74
+ return response.text;
75
+ }
76
+ async generateTextWithMetadata(prompt, maxTokens, temperature) {
77
+ this.logger?.debug("Generating text with Ollama", {
78
+ model: this.model,
79
+ promptLength: prompt.length,
80
+ maxTokens,
81
+ temperature
82
+ });
83
+ const url = `${this.baseURL}/api/generate`;
84
+ const res = await fetch(url, {
85
+ method: "POST",
86
+ headers: { "Content-Type": "application/json" },
87
+ body: JSON.stringify({
88
+ model: this.model,
89
+ prompt,
90
+ stream: false,
91
+ options: {
92
+ num_predict: maxTokens,
93
+ temperature
94
+ }
95
+ })
96
+ });
97
+ if (!res.ok) {
98
+ const body = await res.text();
99
+ this.logger?.error("Ollama API error", {
100
+ model: this.model,
101
+ status: res.status,
102
+ body
103
+ });
104
+ throw new Error(`Ollama API error (${res.status}): ${body}`);
105
+ }
106
+ const data = await res.json();
107
+ if (!data.response) {
108
+ this.logger?.error("Empty response from Ollama", { model: this.model });
109
+ throw new Error("Empty response from Ollama");
110
+ }
111
+ const stopReason = mapStopReason(data.done_reason);
112
+ this.logger?.info("Text generation completed", {
113
+ model: this.model,
114
+ textLength: data.response.length,
115
+ stopReason
116
+ });
117
+ return {
118
+ text: data.response,
119
+ stopReason
120
+ };
121
+ }
122
+ };
123
+ function mapStopReason(doneReason) {
124
+ switch (doneReason) {
125
+ case "stop":
126
+ return "end_turn";
127
+ case "length":
128
+ return "max_tokens";
129
+ default:
130
+ return doneReason || "unknown";
131
+ }
132
+ }
133
+
62
134
  // src/factory.ts
63
135
  function createInferenceClient(config, logger) {
64
136
  switch (config.type) {
@@ -73,6 +145,13 @@ function createInferenceClient(config, logger) {
73
145
  logger
74
146
  );
75
147
  }
148
+ case "ollama": {
149
+ return new OllamaInferenceClient(
150
+ config.model,
151
+ config.endpoint || config.baseURL,
152
+ logger
153
+ );
154
+ }
76
155
  default:
77
156
  throw new Error(`Unsupported inference client type: ${config.type}`);
78
157
  }
@@ -87,11 +166,7 @@ function evaluateEnvVar(value) {
87
166
  return envValue;
88
167
  });
89
168
  }
90
- async function getInferenceClient(config, logger) {
91
- const inferenceConfig = config.services.inference;
92
- if (!inferenceConfig) {
93
- throw new Error("services.inference is required in environment config");
94
- }
169
+ async function getInferenceClient(inferenceConfig, logger) {
95
170
  if (!inferenceConfig.model) {
96
171
  throw new Error("services.inference.model is required in environment config");
97
172
  }
@@ -115,9 +190,8 @@ async function getInferenceClient(config, logger) {
115
190
  });
116
191
  return client;
117
192
  }
118
- function getInferenceModel(config) {
119
- const inferenceConfig = config.services.inference;
120
- if (!inferenceConfig?.model) {
193
+ function getInferenceModel(inferenceConfig) {
194
+ if (!inferenceConfig.model) {
121
195
  throw new Error("Inference model not configured! Set it in your environment configuration.");
122
196
  }
123
197
  return inferenceConfig.model;
@@ -160,6 +234,7 @@ var MockInferenceClient = class {
160
234
  export {
161
235
  AnthropicInferenceClient,
162
236
  MockInferenceClient,
237
+ OllamaInferenceClient,
163
238
  createInferenceClient,
164
239
  getInferenceClient,
165
240
  getInferenceModel
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/implementations/anthropic.ts","../src/factory.ts","../src/implementations/mock.ts"],"sourcesContent":["// Anthropic Claude implementation of InferenceClient interface\n\nimport Anthropic from '@anthropic-ai/sdk';\nimport type { Logger } from '@semiont/core';\nimport { InferenceClient, InferenceResponse } from '../interface.js';\n\nexport class AnthropicInferenceClient implements InferenceClient {\n private client: Anthropic;\n private model: string;\n private logger?: Logger;\n\n constructor(apiKey: string, model: string, baseURL?: string, logger?: Logger) {\n this.client = new Anthropic({\n apiKey,\n baseURL: baseURL || 'https://api.anthropic.com',\n });\n this.model = model;\n this.logger = logger;\n }\n\n async generateText(prompt: string, maxTokens: number, temperature: number): Promise<string> {\n const response = await this.generateTextWithMetadata(prompt, maxTokens, temperature);\n return response.text;\n }\n\n async generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number): Promise<InferenceResponse> {\n this.logger?.debug('Generating text with inference client', {\n model: this.model,\n promptLength: prompt.length,\n maxTokens,\n temperature\n });\n\n const response = await this.client.messages.create({\n model: this.model,\n max_tokens: maxTokens,\n temperature,\n messages: [\n {\n role: 'user',\n content: prompt\n }\n ]\n });\n\n this.logger?.debug('Inference response received', {\n model: this.model,\n contentBlocks: response.content.length,\n stopReason: response.stop_reason\n });\n\n const textContent = response.content.find(c => c.type === 'text');\n\n if (!textContent || textContent.type !== 'text') {\n this.logger?.error('No text content in inference response', {\n model: this.model,\n contentTypes: response.content.map(c => c.type)\n });\n throw new Error('No text content in inference response');\n }\n\n this.logger?.info('Text generation completed', {\n model: this.model,\n textLength: textContent.text.length,\n stopReason: response.stop_reason\n });\n\n return {\n text: textContent.text,\n stopReason: response.stop_reason || 'unknown'\n };\n }\n}\n","// Factory for creating inference client instances based on configuration\n\nimport type { EnvironmentConfig, Logger } from '@semiont/core';\nimport { InferenceClient } from './interface.js';\nimport { AnthropicInferenceClient } from './implementations/anthropic.js';\n\nexport type InferenceClientType = 'anthropic';\n\nexport interface InferenceClientConfig {\n type: InferenceClientType;\n apiKey?: string;\n model: string;\n endpoint?: string;\n baseURL?: string;\n}\n\nexport function createInferenceClient(config: InferenceClientConfig, logger?: Logger): InferenceClient {\n switch (config.type) {\n case 'anthropic': {\n if (!config.apiKey || config.apiKey.trim() === '') {\n throw new Error('apiKey is required for Anthropic inference client');\n }\n return new AnthropicInferenceClient(\n config.apiKey,\n config.model,\n config.endpoint || config.baseURL,\n logger\n );\n }\n\n default:\n throw new Error(`Unsupported inference client type: ${config.type}`);\n }\n}\n\n// Helper function to evaluate environment variable placeholders\nfunction evaluateEnvVar(value: string | undefined): string | undefined {\n if (!value) return undefined;\n\n // Replace ${VAR_NAME} with actual environment variable value\n return value.replace(/\\$\\{([^}]+)\\}/g, (match, varName) => {\n const envValue = process.env[varName];\n if (!envValue) {\n throw new Error(`Environment variable ${varName} is not set. Referenced in configuration as ${match}`);\n }\n return envValue;\n });\n}\n\nexport async function getInferenceClient(config: EnvironmentConfig, logger?: Logger): Promise<InferenceClient> {\n const inferenceConfig = config.services.inference;\n if (!inferenceConfig) {\n throw new Error('services.inference is required in environment config');\n }\n\n if (!inferenceConfig.model) {\n throw new Error('services.inference.model is required in environment config');\n }\n\n const clientConfig: InferenceClientConfig = {\n type: inferenceConfig.type as InferenceClientType,\n apiKey: evaluateEnvVar(inferenceConfig.apiKey),\n model: inferenceConfig.model,\n endpoint: inferenceConfig.endpoint,\n baseURL: inferenceConfig.baseURL,\n };\n\n logger?.info('Loading inference client configuration', {\n type: clientConfig.type,\n model: clientConfig.model,\n endpoint: clientConfig.endpoint,\n hasApiKey: !!clientConfig.apiKey\n });\n\n const client = createInferenceClient(clientConfig, logger);\n\n logger?.info('Inference client initialized', {\n type: inferenceConfig.type,\n model: inferenceConfig.model\n });\n return client;\n}\n\n/**\n * Get the configured model name\n */\nexport function getInferenceModel(config: EnvironmentConfig): string {\n const inferenceConfig = config.services.inference;\n if (!inferenceConfig?.model) {\n throw new Error('Inference model not configured! Set it in your environment configuration.');\n }\n return inferenceConfig.model;\n}\n\n","// Mock implementation of InferenceClient for testing\n\nimport { InferenceClient, InferenceResponse } from '../interface.js';\n\nexport class MockInferenceClient implements InferenceClient {\n private responses: string[] = [];\n private responseIndex: number = 0;\n private stopReasons: string[] = [];\n public calls: Array<{ prompt: string; maxTokens: number; temperature: number }> = [];\n\n constructor(responses: string[] = ['Mock response'], stopReasons?: string[]) {\n this.responses = responses;\n this.stopReasons = stopReasons || responses.map(() => 'end_turn');\n }\n\n async generateText(prompt: string, maxTokens: number, temperature: number): Promise<string> {\n const response = await this.generateTextWithMetadata(prompt, maxTokens, temperature);\n return response.text;\n }\n\n async generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number): Promise<InferenceResponse> {\n this.calls.push({ prompt, maxTokens, temperature });\n\n const text = this.responses[this.responseIndex];\n const stopReason = this.stopReasons[this.responseIndex] || 'end_turn';\n\n if (this.responseIndex < this.responses.length - 1) {\n this.responseIndex++;\n }\n\n return { text, stopReason };\n }\n\n // Test helper methods\n reset(): void {\n this.calls = [];\n this.responseIndex = 0;\n }\n\n setResponses(responses: string[], stopReasons?: string[]): void {\n this.responses = responses;\n this.stopReasons = stopReasons || responses.map(() => 'end_turn');\n this.responseIndex = 0;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/implementations/anthropic.ts","../src/implementations/ollama.ts","../src/factory.ts","../src/implementations/mock.ts"],"sourcesContent":["// Anthropic Claude implementation of InferenceClient interface\n\nimport Anthropic from '@anthropic-ai/sdk';\nimport type { Logger } from '@semiont/core';\nimport { InferenceClient, InferenceResponse } from '../interface.js';\n\nexport class AnthropicInferenceClient implements InferenceClient {\n private client: Anthropic;\n private model: string;\n private logger?: Logger;\n\n constructor(apiKey: string, model: string, baseURL?: string, logger?: Logger) {\n this.client = new Anthropic({\n apiKey,\n baseURL: baseURL || 'https://api.anthropic.com',\n });\n this.model = model;\n this.logger = logger;\n }\n\n async generateText(prompt: string, maxTokens: number, temperature: number): Promise<string> {\n const response = await this.generateTextWithMetadata(prompt, maxTokens, temperature);\n return response.text;\n }\n\n async generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number): Promise<InferenceResponse> {\n this.logger?.debug('Generating text with inference client', {\n model: this.model,\n promptLength: prompt.length,\n maxTokens,\n temperature\n });\n\n const response = await this.client.messages.create({\n model: this.model,\n max_tokens: maxTokens,\n temperature,\n messages: [\n {\n role: 'user',\n content: prompt\n }\n ]\n });\n\n this.logger?.debug('Inference response received', {\n model: this.model,\n contentBlocks: response.content.length,\n stopReason: response.stop_reason\n });\n\n const textContent = response.content.find(c => c.type === 'text');\n\n if (!textContent || textContent.type !== 'text') {\n this.logger?.error('No text content in inference response', {\n model: this.model,\n contentTypes: response.content.map(c => c.type)\n });\n throw new Error('No text content in inference response');\n }\n\n this.logger?.info('Text generation completed', {\n model: this.model,\n textLength: textContent.text.length,\n stopReason: response.stop_reason\n });\n\n return {\n text: textContent.text,\n stopReason: response.stop_reason || 'unknown'\n };\n }\n}\n","// Ollama implementation of InferenceClient interface\n// Uses native Ollama HTTP API (no SDK dependency)\n\nimport type { Logger } from '@semiont/core';\nimport { InferenceClient, InferenceResponse } from '../interface.js';\n\ninterface OllamaGenerateResponse {\n response: string;\n done: boolean;\n done_reason?: string;\n}\n\nexport class OllamaInferenceClient implements InferenceClient {\n private baseURL: string;\n private model: string;\n private logger?: Logger;\n\n constructor(model: string, baseURL?: string, logger?: Logger) {\n this.baseURL = (baseURL || 'http://localhost:11434').replace(/\\/+$/, '');\n this.model = model;\n this.logger = logger;\n }\n\n async generateText(prompt: string, maxTokens: number, temperature: number): Promise<string> {\n const response = await this.generateTextWithMetadata(prompt, maxTokens, temperature);\n return response.text;\n }\n\n async generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number): Promise<InferenceResponse> {\n this.logger?.debug('Generating text with Ollama', {\n model: this.model,\n promptLength: prompt.length,\n maxTokens,\n temperature\n });\n\n const url = `${this.baseURL}/api/generate`;\n\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n model: this.model,\n prompt,\n stream: false,\n options: {\n num_predict: maxTokens,\n temperature,\n },\n }),\n });\n\n if (!res.ok) {\n const body = await res.text();\n this.logger?.error('Ollama API error', {\n model: this.model,\n status: res.status,\n body,\n });\n throw new Error(`Ollama API error (${res.status}): ${body}`);\n }\n\n const data = await res.json() as OllamaGenerateResponse;\n\n if (!data.response) {\n this.logger?.error('Empty response from Ollama', { model: this.model });\n throw new Error('Empty response from Ollama');\n }\n\n const stopReason = mapStopReason(data.done_reason);\n\n this.logger?.info('Text generation completed', {\n model: this.model,\n textLength: data.response.length,\n stopReason,\n });\n\n return {\n text: data.response,\n stopReason,\n };\n }\n}\n\nfunction mapStopReason(doneReason: string | undefined): string {\n switch (doneReason) {\n case 'stop': return 'end_turn';\n case 'length': return 'max_tokens';\n default: return doneReason || 'unknown';\n }\n}\n","// Factory for creating inference client instances based on configuration\n\nimport type { InferenceServiceConfig, Logger } from '@semiont/core';\nimport { InferenceClient } from './interface.js';\nimport { AnthropicInferenceClient } from './implementations/anthropic.js';\nimport { OllamaInferenceClient } from './implementations/ollama.js';\n\nexport type InferenceClientType = 'anthropic' | 'ollama';\n\nexport interface InferenceClientConfig {\n type: InferenceClientType;\n apiKey?: string;\n model: string;\n endpoint?: string;\n baseURL?: string;\n}\n\nexport function createInferenceClient(config: InferenceClientConfig, logger?: Logger): InferenceClient {\n switch (config.type) {\n case 'anthropic': {\n if (!config.apiKey || config.apiKey.trim() === '') {\n throw new Error('apiKey is required for Anthropic inference client');\n }\n return new AnthropicInferenceClient(\n config.apiKey,\n config.model,\n config.endpoint || config.baseURL,\n logger\n );\n }\n\n case 'ollama': {\n return new OllamaInferenceClient(\n config.model,\n config.endpoint || config.baseURL,\n logger\n );\n }\n\n default:\n throw new Error(`Unsupported inference client type: ${config.type}`);\n }\n}\n\n// Helper function to evaluate environment variable placeholders\nfunction evaluateEnvVar(value: string | undefined): string | undefined {\n if (!value) return undefined;\n\n // Replace ${VAR_NAME} with actual environment variable value\n return value.replace(/\\$\\{([^}]+)\\}/g, (match, varName) => {\n const envValue = process.env[varName];\n if (!envValue) {\n throw new Error(`Environment variable ${varName} is not set. Referenced in configuration as ${match}`);\n }\n return envValue;\n });\n}\n\nexport async function getInferenceClient(inferenceConfig: InferenceServiceConfig, logger?: Logger): Promise<InferenceClient> {\n if (!inferenceConfig.model) {\n throw new Error('services.inference.model is required in environment config');\n }\n\n const clientConfig: InferenceClientConfig = {\n type: inferenceConfig.type as InferenceClientType,\n apiKey: evaluateEnvVar(inferenceConfig.apiKey),\n model: inferenceConfig.model,\n endpoint: inferenceConfig.endpoint,\n baseURL: inferenceConfig.baseURL,\n };\n\n logger?.info('Loading inference client configuration', {\n type: clientConfig.type,\n model: clientConfig.model,\n endpoint: clientConfig.endpoint,\n hasApiKey: !!clientConfig.apiKey\n });\n\n const client = createInferenceClient(clientConfig, logger);\n\n logger?.info('Inference client initialized', {\n type: inferenceConfig.type,\n model: inferenceConfig.model\n });\n return client;\n}\n\n/**\n * Get the configured model name\n */\nexport function getInferenceModel(inferenceConfig: InferenceServiceConfig): string {\n if (!inferenceConfig.model) {\n throw new Error('Inference model not configured! Set it in your environment configuration.');\n }\n return inferenceConfig.model;\n}\n\n","// Mock implementation of InferenceClient for testing\n\nimport { InferenceClient, InferenceResponse } from '../interface.js';\n\nexport class MockInferenceClient implements InferenceClient {\n private responses: string[] = [];\n private responseIndex: number = 0;\n private stopReasons: string[] = [];\n public calls: Array<{ prompt: string; maxTokens: number; temperature: number }> = [];\n\n constructor(responses: string[] = ['Mock response'], stopReasons?: string[]) {\n this.responses = responses;\n this.stopReasons = stopReasons || responses.map(() => 'end_turn');\n }\n\n async generateText(prompt: string, maxTokens: number, temperature: number): Promise<string> {\n const response = await this.generateTextWithMetadata(prompt, maxTokens, temperature);\n return response.text;\n }\n\n async generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number): Promise<InferenceResponse> {\n this.calls.push({ prompt, maxTokens, temperature });\n\n const text = this.responses[this.responseIndex];\n const stopReason = this.stopReasons[this.responseIndex] || 'end_turn';\n\n if (this.responseIndex < this.responses.length - 1) {\n this.responseIndex++;\n }\n\n return { text, stopReason };\n }\n\n // Test helper methods\n reset(): void {\n this.calls = [];\n this.responseIndex = 0;\n }\n\n setResponses(responses: string[], stopReasons?: string[]): void {\n this.responses = responses;\n this.stopReasons = stopReasons || responses.map(() => 'end_turn');\n this.responseIndex = 0;\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semiont/inference",
3
- "version": "0.2.45",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "description": "AI inference capabilities for entity extraction, text generation, and resource creation",
6
6
  "main": "./dist/index.js",
@@ -29,10 +29,10 @@
29
29
  "@semiont/core": "*"
30
30
  },
31
31
  "devDependencies": {
32
- "@vitest/coverage-v8": "^3.0.0",
32
+ "@vitest/coverage-v8": "^4.1.0",
33
33
  "tsup": "^8.0.1",
34
34
  "typescript": "^5.6.3",
35
- "vitest": "^3.2.4"
35
+ "vitest": "^4.1.0"
36
36
  },
37
37
  "publishConfig": {
38
38
  "access": "public"
@@ -43,6 +43,7 @@
43
43
  "entity-extraction",
44
44
  "llm",
45
45
  "anthropic",
46
+ "ollama",
46
47
  "text-generation"
47
48
  ],
48
49
  "author": "The AI Alliance",