@loonylabs/llm-middleware 2.29.2 β 2.30.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/.env.example +6 -0
- package/README.md +2 -1
- package/dist/middleware/services/llm/llm.service.d.ts.map +1 -1
- package/dist/middleware/services/llm/llm.service.js +2 -0
- package/dist/middleware/services/llm/llm.service.js.map +1 -1
- package/dist/middleware/services/llm/providers/inceptron-provider.d.ts +49 -0
- package/dist/middleware/services/llm/providers/inceptron-provider.d.ts.map +1 -0
- package/dist/middleware/services/llm/providers/inceptron-provider.js +310 -0
- package/dist/middleware/services/llm/providers/inceptron-provider.js.map +1 -0
- package/dist/middleware/services/llm/providers/index.d.ts +1 -0
- package/dist/middleware/services/llm/providers/index.d.ts.map +1 -1
- package/dist/middleware/services/llm/providers/index.js +1 -0
- package/dist/middleware/services/llm/providers/index.js.map +1 -1
- package/dist/middleware/services/llm/types/common.types.d.ts +3 -1
- package/dist/middleware/services/llm/types/common.types.d.ts.map +1 -1
- package/dist/middleware/services/llm/types/common.types.js +2 -0
- package/dist/middleware/services/llm/types/common.types.js.map +1 -1
- package/dist/middleware/services/llm/types/inceptron.types.d.ts +112 -0
- package/dist/middleware/services/llm/types/inceptron.types.d.ts.map +1 -0
- package/dist/middleware/services/llm/types/inceptron.types.js +3 -0
- package/dist/middleware/services/llm/types/inceptron.types.js.map +1 -0
- package/dist/middleware/services/llm/types/index.d.ts +1 -0
- package/dist/middleware/services/llm/types/index.d.ts.map +1 -1
- package/dist/middleware/services/llm/types/index.js +1 -0
- package/dist/middleware/services/llm/types/index.js.map +1 -1
- package/package.json +7 -2
package/.env.example
CHANGED
|
@@ -44,6 +44,12 @@ AZURE_OPENAI_ENDPOINT=https://<resource>.openai.azure.com # Your resource endpo
|
|
|
44
44
|
AZURE_OPENAI_DEPLOYMENT=o4-mini # Your deployment name (= 'model' field in the request body)
|
|
45
45
|
AZURE_OPENAI_API_VERSION= # Optional: empty = v1 route (/openai/v1/); '2024-05-01-preview' = MaaS route (/models/)
|
|
46
46
|
|
|
47
|
+
# Inceptron Configuration (Optional - Bearer token auth, OpenAI-compatible, serverless; HQ: Inceptron AB, Lund/Sweden)
|
|
48
|
+
# EU data residency is PER-MODEL: e.g. GLM-5.1 is marked "Residency: EU". DPA & SCCs available on request (support@inceptron.io).
|
|
49
|
+
INCEPTRON_API_KEY=your_inceptron_api_key_here # Inceptron API key (Bearer token in the Authorization header)
|
|
50
|
+
INCEPTRON_BASE_URL=https://openrouter.inceptron.io/v1 # Base URL from the dashboard quickstart (public docs show api.inceptron.io/v1)
|
|
51
|
+
INCEPTRON_MODEL=zai-org/GLM-5.1-FP8 # Default model ID (EU-resident; verify exact ID in your dashboard)
|
|
52
|
+
|
|
47
53
|
# Test Configuration (Optional)
|
|
48
54
|
TEST_LLM_MODEL=vertex/gemini-2.0-flash-lite # Model for general LLM tests
|
|
49
55
|
# Reasoning models:
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# π LLM Middleware
|
|
4
4
|
|
|
5
|
-
*A comprehensive TypeScript middleware library for building robust multi-provider LLM backends. Currently supports Ollama, Anthropic Claude, Google Gemini (Direct API & Vertex AI), Requesty.AI (300+ models), AWS Bedrock,
|
|
5
|
+
*A comprehensive TypeScript middleware library for building robust multi-provider LLM backends. Currently supports Ollama, Anthropic Claude, Google Gemini (Direct API & Vertex AI), Requesty.AI (300+ models), AWS Bedrock, Azure OpenAI / Foundry, and Inceptron. Features EU data residency via Vertex AI / Bedrock / Azure data zones, reasoning control, advanced JSON cleaning, logging, error handling, cost tracking, and more.*
|
|
6
6
|
|
|
7
7
|
<!-- Horizontal Badge Navigation Bar -->
|
|
8
8
|
[](https://www.npmjs.com/package/@loonylabs/llm-middleware)
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
- β
**Requesty.AI**: 300+ models via unified API, built-in cost tracking
|
|
48
48
|
- β
**AWS Bedrock**: Converse API via Bearer-token auth (no AWS SDK); Claude, Nova, Qwen, GLM, Kimi, DeepSeek, gpt-oss β with central `reasoningEffort` control β **v2.28.0**
|
|
49
49
|
- β
**Azure OpenAI / Foundry**: OpenAI-compatible v1 route with `api-key` auth; o-series/GPT-5 reasoning vs. gpt-4o standard auto-handled; EU data-zone residency β **v2.29.0**
|
|
50
|
+
- β
**Inceptron**: OpenAI-compatible Bearer-token auth (Inceptron AB, Sweden); curated open-weight models (GLM-5.1, Kimi, DeepSeek, gpt-oss); `reasoning`βthinking mapping; per-model EU residency β **v2.30.0**
|
|
50
51
|
- π **Pluggable**: Easy to add custom providers - see [LLM Providers Guide](docs/LLM_PROVIDERS.md)
|
|
51
52
|
- ποΈ **Vision / Multimodal Input**: Send images alongside text to LLM providers
|
|
52
53
|
- β¨ **v2.22.0**: Provider-agnostic `MultimodalContent` type (`string | ContentPart[]`)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.service.d.ts","sourceRoot":"","sources":["../../../../src/middleware/services/llm/llm.service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAKhE,OAAO,EAAoB,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"llm.service.d.ts","sourceRoot":"","sources":["../../../../src/middleware/services/llm/llm.service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAKhE,OAAO,EAAoB,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAI9E,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,cAAc,CAAC,EAAE,sBAAsB,CAAC;CACzC;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,eAAe,CAAmC;gBAE9C,OAAO,CAAC,EAAE,iBAAiB;IAavC;;OAEG;IACI,WAAW,CAAC,QAAQ,EAAE,WAAW,GAAG,eAAe;IAQ1D;;;;;;;;;;;;;;;;;;OAkBG;IACI,gBAAgB,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI;IAI/E;;OAEG;IACI,kBAAkB,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI;IAOtD;;OAEG;IACI,kBAAkB,IAAI,WAAW;IAIxC;;;OAGG;IACU,qBAAqB,CAChC,UAAU,EAAE,iBAAiB,EAC7B,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,gBAAgB,GAAG;QAAE,QAAQ,CAAC,EAAE,WAAW,CAAA;KAAO,GAC1D,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAMpC;;;OAGG;IACU,IAAI,CACf,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,gBAAgB,GAAG;QAAE,QAAQ,CAAC,EAAE,WAAW,CAAA;KAAO,GAC1D,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAMpC;;OAEG;IACI,qBAAqB,IAAI,WAAW,EAAE;CAG9C;AAGD,eAAO,MAAM,UAAU,YAAmB,CAAC"}
|
|
@@ -12,6 +12,7 @@ const requesty_provider_1 = require("./providers/requesty-provider");
|
|
|
12
12
|
const gemini_1 = require("./providers/gemini");
|
|
13
13
|
const bedrock_provider_1 = require("./providers/bedrock-provider");
|
|
14
14
|
const azure_openai_provider_1 = require("./providers/azure-openai-provider");
|
|
15
|
+
const inceptron_provider_1 = require("./providers/inceptron-provider");
|
|
15
16
|
const types_1 = require("./types");
|
|
16
17
|
class LLMService {
|
|
17
18
|
constructor(options) {
|
|
@@ -25,6 +26,7 @@ class LLMService {
|
|
|
25
26
|
this.providers.set(types_1.LLMProvider.VERTEX_AI, new gemini_1.VertexAIProvider(options?.vertexAIConfig));
|
|
26
27
|
this.providers.set(types_1.LLMProvider.BEDROCK, new bedrock_provider_1.BedrockProvider());
|
|
27
28
|
this.providers.set(types_1.LLMProvider.AZURE_OPENAI, new azure_openai_provider_1.AzureOpenAIProvider());
|
|
29
|
+
this.providers.set(types_1.LLMProvider.INCEPTRON, new inceptron_provider_1.InceptronProvider());
|
|
28
30
|
}
|
|
29
31
|
/**
|
|
30
32
|
* Get a specific provider instance
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.service.js","sourceRoot":"","sources":["../../../../src/middleware/services/llm/llm.service.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,iEAA6D;AAC7D,uEAAmE;AACnE,iEAA6D;AAC7D,qEAAiE;AACjE,+CAA8E;AAC9E,mEAA+D;AAC/D,6EAAwE;AACxE,mCAA2E;AAQ3E,MAAa,UAAU;IAIrB,YAAY,OAA2B;QAF/B,oBAAe,GAAgB,mBAAW,CAAC,MAAM,CAAC;QAGxD,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;QAC3B,iCAAiC;QACjC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAW,CAAC,MAAM,EAAE,IAAI,gCAAc,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAW,CAAC,SAAS,EAAE,IAAI,sCAAiB,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAW,CAAC,MAAM,EAAE,IAAI,gCAAc,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAW,CAAC,QAAQ,EAAE,IAAI,oCAAgB,EAAE,CAAC,CAAC;QACjE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAW,CAAC,SAAS,EAAE,IAAI,yBAAgB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;QACzF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAW,CAAC,OAAO,EAAE,IAAI,kCAAe,EAAE,CAAC,CAAC;QAC/D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAW,CAAC,YAAY,EAAE,IAAI,2CAAmB,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"llm.service.js","sourceRoot":"","sources":["../../../../src/middleware/services/llm/llm.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { BaseLLMProvider } from './base-llm-provider';
|
|
2
|
+
import { CommonLLMResponse } from '../types';
|
|
3
|
+
import { InceptronRequestOptions } from '../types/inceptron.types';
|
|
4
|
+
import { MultimodalContent } from '../types/multimodal.types';
|
|
5
|
+
/**
|
|
6
|
+
* Inceptron provider using the OpenAI-compatible Chat Completions API.
|
|
7
|
+
*
|
|
8
|
+
* Inceptron (Inceptron AB, Lund/Sweden) serves curated open-weight models
|
|
9
|
+
* (GLM-5.1, Kimi, DeepSeek, gpt-oss, MiniMax, Llama, β¦) on a compiler-accelerated
|
|
10
|
+
* inference stack. The wire format mirrors the Requesty provider β only two
|
|
11
|
+
* behaviours are Inceptron-specific (both live-verified):
|
|
12
|
+
*
|
|
13
|
+
* 1. Reasoning text arrives in `message.reasoning` (OpenRouter style), which we
|
|
14
|
+
* map to the provider-agnostic `message.thinking`.
|
|
15
|
+
* 2. `message.content` can be `null`; we treat it as an empty string and warn
|
|
16
|
+
* when it is empty while reasoning is present.
|
|
17
|
+
*
|
|
18
|
+
* `usage` carries no `reasoning_tokens` (reasoning is folded into
|
|
19
|
+
* `completion_tokens`, like Ollama) and no `cost`.
|
|
20
|
+
*
|
|
21
|
+
* Auth: Authorization: Bearer <INCEPTRON_API_KEY>
|
|
22
|
+
* Endpoint: {INCEPTRON_BASE_URL}/chat/completions (default openrouter.inceptron.io/v1)
|
|
23
|
+
* Residency: per-model β e.g. GLM-5.1 is marked EU-resident. DPA/SCCs on request.
|
|
24
|
+
* @see docs/INCEPTRON.md
|
|
25
|
+
*/
|
|
26
|
+
export declare class InceptronProvider extends BaseLLMProvider {
|
|
27
|
+
private dataFlowLogger;
|
|
28
|
+
private readonly DEFAULT_BASE_URL;
|
|
29
|
+
private readonly DEFAULT_MODEL;
|
|
30
|
+
private readonly DEFAULT_TIMEOUT;
|
|
31
|
+
constructor();
|
|
32
|
+
/**
|
|
33
|
+
* Build the user message content: multimodal (text + image_url) or plain string.
|
|
34
|
+
* Uses the OpenAI image_url/data-URI format, identical to Requesty/Azure.
|
|
35
|
+
*/
|
|
36
|
+
private buildUserContent;
|
|
37
|
+
/**
|
|
38
|
+
* Call the Inceptron Chat Completions API with a custom system message.
|
|
39
|
+
* @param userPrompt - The user's prompt (text or multimodal content)
|
|
40
|
+
* @param systemMessage - The system message defining AI behavior
|
|
41
|
+
* @param options - Options for the API call
|
|
42
|
+
* @returns The API response or null on error
|
|
43
|
+
*/
|
|
44
|
+
callWithSystemMessage(userPrompt: MultimodalContent, systemMessage: string, options?: InceptronRequestOptions): Promise<CommonLLMResponse | null>;
|
|
45
|
+
}
|
|
46
|
+
export declare const inceptronProvider: InceptronProvider;
|
|
47
|
+
export { InceptronProvider as InceptronService };
|
|
48
|
+
export { inceptronProvider as inceptronService };
|
|
49
|
+
//# sourceMappingURL=inceptron-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inceptron-provider.d.ts","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/providers/inceptron-provider.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAe,iBAAiB,EAA+B,MAAM,UAAU,CAAC;AACvF,OAAO,EACL,uBAAuB,EAKxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAkB9D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,iBAAkB,SAAQ,eAAe;IACpD,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAwC;IACzE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IACvD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAU;;IAO1C;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAsBxB;;;;;;OAMG;IACU,qBAAqB,CAChC,UAAU,EAAE,iBAAiB,EAC7B,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;CAsSrC;AAGD,eAAO,MAAM,iBAAiB,mBAA0B,CAAC;AAGzD,OAAO,EAAE,iBAAiB,IAAI,gBAAgB,EAAE,CAAC;AACjD,OAAO,EAAE,iBAAiB,IAAI,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.inceptronService = exports.InceptronService = exports.inceptronProvider = exports.InceptronProvider = void 0;
|
|
7
|
+
// NEW FILE: inceptron-provider.ts
|
|
8
|
+
const axios_1 = __importDefault(require("axios"));
|
|
9
|
+
const uuid_1 = require("uuid");
|
|
10
|
+
const logging_utils_1 = require("../../../shared/utils/logging.utils");
|
|
11
|
+
const base_llm_provider_1 = require("./base-llm-provider");
|
|
12
|
+
const types_1 = require("../types");
|
|
13
|
+
const debug_llm_utils_1 = require("../utils/debug-llm.utils");
|
|
14
|
+
const data_flow_logger_1 = require("../../data-flow-logger");
|
|
15
|
+
const retry_utils_1 = require("../utils/retry.utils");
|
|
16
|
+
const multimodal_utils_1 = require("../utils/multimodal.utils");
|
|
17
|
+
/**
|
|
18
|
+
* Default reasoning effort sent when the caller does not specify one.
|
|
19
|
+
*
|
|
20
|
+
* Live verification against zai-org/GLM-5.1-FP8 showed that omitting
|
|
21
|
+
* reasoning_effort makes `content` non-deterministic (sometimes empty, with the
|
|
22
|
+
* whole answer in `reasoning`). Sending an explicit value β even 'none' β
|
|
23
|
+
* reliably populates `content`. 'none' is chosen as the safe default: clean,
|
|
24
|
+
* fast, deterministic content with no reasoning-token overhead. Callers opt into
|
|
25
|
+
* reasoning explicitly via `reasoningEffort`.
|
|
26
|
+
*/
|
|
27
|
+
const DEFAULT_REASONING_EFFORT = 'none';
|
|
28
|
+
/**
|
|
29
|
+
* Inceptron provider using the OpenAI-compatible Chat Completions API.
|
|
30
|
+
*
|
|
31
|
+
* Inceptron (Inceptron AB, Lund/Sweden) serves curated open-weight models
|
|
32
|
+
* (GLM-5.1, Kimi, DeepSeek, gpt-oss, MiniMax, Llama, β¦) on a compiler-accelerated
|
|
33
|
+
* inference stack. The wire format mirrors the Requesty provider β only two
|
|
34
|
+
* behaviours are Inceptron-specific (both live-verified):
|
|
35
|
+
*
|
|
36
|
+
* 1. Reasoning text arrives in `message.reasoning` (OpenRouter style), which we
|
|
37
|
+
* map to the provider-agnostic `message.thinking`.
|
|
38
|
+
* 2. `message.content` can be `null`; we treat it as an empty string and warn
|
|
39
|
+
* when it is empty while reasoning is present.
|
|
40
|
+
*
|
|
41
|
+
* `usage` carries no `reasoning_tokens` (reasoning is folded into
|
|
42
|
+
* `completion_tokens`, like Ollama) and no `cost`.
|
|
43
|
+
*
|
|
44
|
+
* Auth: Authorization: Bearer <INCEPTRON_API_KEY>
|
|
45
|
+
* Endpoint: {INCEPTRON_BASE_URL}/chat/completions (default openrouter.inceptron.io/v1)
|
|
46
|
+
* Residency: per-model β e.g. GLM-5.1 is marked EU-resident. DPA/SCCs on request.
|
|
47
|
+
* @see docs/INCEPTRON.md
|
|
48
|
+
*/
|
|
49
|
+
class InceptronProvider extends base_llm_provider_1.BaseLLMProvider {
|
|
50
|
+
constructor() {
|
|
51
|
+
super(types_1.LLMProvider.INCEPTRON);
|
|
52
|
+
this.DEFAULT_BASE_URL = 'https://openrouter.inceptron.io/v1';
|
|
53
|
+
this.DEFAULT_MODEL = 'zai-org/GLM-5.1-FP8';
|
|
54
|
+
this.DEFAULT_TIMEOUT = 180000;
|
|
55
|
+
this.dataFlowLogger = data_flow_logger_1.DataFlowLoggerService.getInstance();
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build the user message content: multimodal (text + image_url) or plain string.
|
|
59
|
+
* Uses the OpenAI image_url/data-URI format, identical to Requesty/Azure.
|
|
60
|
+
*/
|
|
61
|
+
buildUserContent(userPrompt) {
|
|
62
|
+
if (!(0, multimodal_utils_1.hasImages)(userPrompt)) {
|
|
63
|
+
return typeof userPrompt === 'string'
|
|
64
|
+
? userPrompt
|
|
65
|
+
: (0, multimodal_utils_1.normalizeContent)(userPrompt)
|
|
66
|
+
.map(p => p.text)
|
|
67
|
+
.join('\n');
|
|
68
|
+
}
|
|
69
|
+
return (0, multimodal_utils_1.normalizeContent)(userPrompt).map(part => {
|
|
70
|
+
if (part.type === 'text') {
|
|
71
|
+
return { type: 'text', text: part.text };
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
type: 'image_url',
|
|
75
|
+
image_url: {
|
|
76
|
+
url: `data:${part.mimeType};base64,${part.data}`,
|
|
77
|
+
...(part.detail && { detail: part.detail })
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Call the Inceptron Chat Completions API with a custom system message.
|
|
84
|
+
* @param userPrompt - The user's prompt (text or multimodal content)
|
|
85
|
+
* @param systemMessage - The system message defining AI behavior
|
|
86
|
+
* @param options - Options for the API call
|
|
87
|
+
* @returns The API response or null on error
|
|
88
|
+
*/
|
|
89
|
+
async callWithSystemMessage(userPrompt, systemMessage, options = {}) {
|
|
90
|
+
const { authToken = process.env.INCEPTRON_API_KEY, model = process.env.INCEPTRON_MODEL || this.DEFAULT_MODEL, baseUrl = process.env.INCEPTRON_BASE_URL || this.DEFAULT_BASE_URL, temperature = 0.7, maxTokens = 4096, timeout = this.DEFAULT_TIMEOUT, httpReferer, xTitle, debugContext, sessionId = (0, uuid_1.v4)(), chapterNumber, pageNumber, pageName, reasoningEffort } = options;
|
|
91
|
+
// Validate API key
|
|
92
|
+
if (!authToken) {
|
|
93
|
+
throw new Error('Inceptron API key is required but not provided. ' +
|
|
94
|
+
'Please set INCEPTRON_API_KEY in your .env file or pass authToken in options.');
|
|
95
|
+
}
|
|
96
|
+
// Validate model
|
|
97
|
+
if (!model) {
|
|
98
|
+
throw new Error('Model name is required but not provided. ' +
|
|
99
|
+
'Please set INCEPTRON_MODEL in your .env file or pass model in options.');
|
|
100
|
+
}
|
|
101
|
+
// Always send a reasoning_effort to keep `content` deterministic (see DEFAULT_REASONING_EFFORT).
|
|
102
|
+
const effectiveEffort = reasoningEffort ?? DEFAULT_REASONING_EFFORT;
|
|
103
|
+
const base = baseUrl.replace(/\/+$/, '');
|
|
104
|
+
const url = `${base}/chat/completions`;
|
|
105
|
+
// Build headers
|
|
106
|
+
const headers = {
|
|
107
|
+
'Content-Type': 'application/json',
|
|
108
|
+
'Accept': 'application/json',
|
|
109
|
+
'Authorization': `Bearer ${authToken}`
|
|
110
|
+
};
|
|
111
|
+
if (httpReferer)
|
|
112
|
+
headers['HTTP-Referer'] = httpReferer;
|
|
113
|
+
if (xTitle)
|
|
114
|
+
headers['X-Title'] = xTitle;
|
|
115
|
+
// Build request payload (OpenAI format)
|
|
116
|
+
const requestPayload = {
|
|
117
|
+
model,
|
|
118
|
+
messages: [
|
|
119
|
+
...(systemMessage ? [{ role: 'system', content: systemMessage }] : []),
|
|
120
|
+
{ role: 'user', content: this.buildUserContent(userPrompt) }
|
|
121
|
+
],
|
|
122
|
+
max_tokens: maxTokens,
|
|
123
|
+
temperature,
|
|
124
|
+
reasoning_effort: effectiveEffort
|
|
125
|
+
};
|
|
126
|
+
// Use debug string to avoid base64 blobs in logs
|
|
127
|
+
const userMessageDebug = (0, multimodal_utils_1.contentToDebugString)(userPrompt);
|
|
128
|
+
const debugInfo = {
|
|
129
|
+
timestamp: new Date(),
|
|
130
|
+
provider: this.providerName,
|
|
131
|
+
model,
|
|
132
|
+
baseUrl: url,
|
|
133
|
+
systemMessage,
|
|
134
|
+
userMessage: userMessageDebug,
|
|
135
|
+
requestData: requestPayload,
|
|
136
|
+
useCase: debugContext,
|
|
137
|
+
sessionId,
|
|
138
|
+
chapterNumber,
|
|
139
|
+
pageNumber,
|
|
140
|
+
pageName,
|
|
141
|
+
temperature,
|
|
142
|
+
reasoningEffort: effectiveEffort
|
|
143
|
+
};
|
|
144
|
+
await debug_llm_utils_1.LLMDebugger.logRequest(debugInfo);
|
|
145
|
+
const contextForLogger = {
|
|
146
|
+
currentChapterNr: chapterNumber,
|
|
147
|
+
currentPage: pageNumber,
|
|
148
|
+
debugContext
|
|
149
|
+
};
|
|
150
|
+
const requestId = this.dataFlowLogger.startRequest(debugContext || 'inceptron', contextForLogger);
|
|
151
|
+
this.dataFlowLogger.logLLMRequest({
|
|
152
|
+
stage: debugContext || 'inceptron',
|
|
153
|
+
prompt: userMessageDebug,
|
|
154
|
+
systemMessage,
|
|
155
|
+
modelName: model,
|
|
156
|
+
temperature,
|
|
157
|
+
contextInfo: { sessionId, chapterNumber, pageNumber, pageName }
|
|
158
|
+
}, contextForLogger, requestId);
|
|
159
|
+
const requestStartTime = Date.now();
|
|
160
|
+
try {
|
|
161
|
+
logging_utils_1.logger.info('Sending request to Inceptron API', {
|
|
162
|
+
context: 'InceptronProvider',
|
|
163
|
+
metadata: {
|
|
164
|
+
url,
|
|
165
|
+
model,
|
|
166
|
+
reasoningEffort: effectiveEffort,
|
|
167
|
+
promptLength: (0, multimodal_utils_1.contentLength)(userPrompt),
|
|
168
|
+
maxTokens
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
const response = await (0, retry_utils_1.retryWithBackoff)(() => axios_1.default.post(url, requestPayload, { headers, timeout }), this.constructor.name, options.retry);
|
|
172
|
+
const requestDuration = Date.now() - requestStartTime;
|
|
173
|
+
if (response && response.status === 200) {
|
|
174
|
+
const apiResponse = response.data;
|
|
175
|
+
const choice = apiResponse.choices[0];
|
|
176
|
+
// `content` can be null (see InceptronAPIResponse); treat as empty string.
|
|
177
|
+
const responseText = choice?.message?.content ?? '';
|
|
178
|
+
// Reasoning arrives in `message.reasoning` (OpenRouter style) -> map to thinking.
|
|
179
|
+
const thinking = choice?.message?.reasoning || undefined;
|
|
180
|
+
// GLM-5.1 occasionally returns empty content with all text in `reasoning`.
|
|
181
|
+
// Surface it so the consumer understands an empty answer, rather than silently
|
|
182
|
+
// returning "". (Does not happen with the default reasoning_effort='none'.)
|
|
183
|
+
if (!responseText && thinking) {
|
|
184
|
+
logging_utils_1.logger.warn('Inceptron returned empty content while reasoning text was present. ' +
|
|
185
|
+
'The model kept its answer in the reasoning channel. ' +
|
|
186
|
+
"Consider setting reasoningEffort='none' or raising maxTokens.", { context: 'InceptronProvider', metadata: { model, reasoningEffort: effectiveEffort } });
|
|
187
|
+
}
|
|
188
|
+
// Normalize token usage. No reasoning_tokens / cost are returned; reasoning
|
|
189
|
+
// is folded into completion_tokens (like Ollama). cached_tokens may appear
|
|
190
|
+
// on cache hits.
|
|
191
|
+
const usage = apiResponse.usage;
|
|
192
|
+
const cachedTokens = usage?.prompt_tokens_details?.cached_tokens;
|
|
193
|
+
const tokenUsage = {
|
|
194
|
+
inputTokens: usage?.prompt_tokens ?? 0,
|
|
195
|
+
outputTokens: usage?.completion_tokens ?? 0,
|
|
196
|
+
totalTokens: usage?.total_tokens ?? 0,
|
|
197
|
+
...(cachedTokens ? { cacheMetadata: { cacheReadTokens: cachedTokens } } : {})
|
|
198
|
+
};
|
|
199
|
+
const normalizedResponse = {
|
|
200
|
+
message: {
|
|
201
|
+
content: responseText,
|
|
202
|
+
...(thinking && { thinking })
|
|
203
|
+
},
|
|
204
|
+
sessionId,
|
|
205
|
+
metadata: {
|
|
206
|
+
provider: this.providerName,
|
|
207
|
+
model: apiResponse.model || model,
|
|
208
|
+
tokensUsed: tokenUsage.totalTokens,
|
|
209
|
+
processingTime: requestDuration
|
|
210
|
+
},
|
|
211
|
+
usage: tokenUsage,
|
|
212
|
+
id: apiResponse.id,
|
|
213
|
+
finish_reason: choice?.finish_reason || undefined
|
|
214
|
+
};
|
|
215
|
+
debugInfo.responseTimestamp = new Date();
|
|
216
|
+
debugInfo.response = responseText;
|
|
217
|
+
debugInfo.rawResponseData = apiResponse;
|
|
218
|
+
if (thinking) {
|
|
219
|
+
debugInfo.thinking = thinking;
|
|
220
|
+
}
|
|
221
|
+
await debug_llm_utils_1.LLMDebugger.logResponse(debugInfo);
|
|
222
|
+
this.dataFlowLogger.logLLMResponse(debugContext || 'inceptron', { rawResponse: responseText, processingTime: requestDuration }, contextForLogger, requestId);
|
|
223
|
+
return normalizedResponse;
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
const error = new Error(`Status ${response?.status || 'unknown'}`);
|
|
227
|
+
logging_utils_1.logger.error('Error calling Inceptron API', {
|
|
228
|
+
context: this.constructor.name,
|
|
229
|
+
error: error.message,
|
|
230
|
+
metadata: response?.data || {}
|
|
231
|
+
});
|
|
232
|
+
this.dataFlowLogger.logLLMResponse(debugContext || 'inceptron', { rawResponse: '', processingTime: Date.now() - requestStartTime, error }, contextForLogger, requestId);
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
let errorMessage = 'Unknown error';
|
|
238
|
+
let errorDetails = {};
|
|
239
|
+
if (error instanceof Error) {
|
|
240
|
+
errorMessage = error.message;
|
|
241
|
+
}
|
|
242
|
+
// Handle Axios errors
|
|
243
|
+
if (error &&
|
|
244
|
+
typeof error === 'object' &&
|
|
245
|
+
'isAxiosError' in error &&
|
|
246
|
+
error.isAxiosError === true) {
|
|
247
|
+
const axiosError = error;
|
|
248
|
+
if (axiosError.response) {
|
|
249
|
+
errorDetails = {
|
|
250
|
+
statusCode: axiosError.response.status,
|
|
251
|
+
statusText: axiosError.response.statusText,
|
|
252
|
+
data: axiosError.response.data
|
|
253
|
+
};
|
|
254
|
+
if (axiosError.response.status === 401) {
|
|
255
|
+
logging_utils_1.logger.error('Authentication error with Inceptron API', {
|
|
256
|
+
context: this.constructor.name,
|
|
257
|
+
error: 'Invalid API key (sent as Authorization: Bearer)',
|
|
258
|
+
metadata: { statusCode: 401, message: axiosError.response.data?.error?.message }
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
else if (axiosError.response.status === 404) {
|
|
262
|
+
logging_utils_1.logger.error('Inceptron model or route not found', {
|
|
263
|
+
context: this.constructor.name,
|
|
264
|
+
error: 'Model ID not found, or base URL/route incorrect',
|
|
265
|
+
metadata: {
|
|
266
|
+
statusCode: 404,
|
|
267
|
+
model,
|
|
268
|
+
hint: 'Verify the model ID and INCEPTRON_BASE_URL (dashboard quickstart shows openrouter.inceptron.io/v1).'
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
else if (axiosError.response.status === 429) {
|
|
273
|
+
logging_utils_1.logger.error('Rate limit exceeded on Inceptron API', {
|
|
274
|
+
context: this.constructor.name,
|
|
275
|
+
error: 'Too many requests',
|
|
276
|
+
metadata: { statusCode: 429, retryAfter: axiosError.response.headers?.['retry-after'] }
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
else if (axiosError.response.status === 400) {
|
|
280
|
+
logging_utils_1.logger.error('Bad request to Inceptron API', {
|
|
281
|
+
context: this.constructor.name,
|
|
282
|
+
error: axiosError.response.data?.error?.message || 'Invalid request',
|
|
283
|
+
metadata: { model, details: axiosError.response.data?.error }
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
logging_utils_1.logger.error('Error in Inceptron API request', {
|
|
289
|
+
context: this.constructor.name,
|
|
290
|
+
error: errorMessage,
|
|
291
|
+
metadata: { ...errorDetails, requestModel: model, sessionId }
|
|
292
|
+
});
|
|
293
|
+
this.dataFlowLogger.logLLMResponse(debugContext || 'inceptron', {
|
|
294
|
+
rawResponse: '',
|
|
295
|
+
processingTime: Date.now() - requestStartTime,
|
|
296
|
+
error: error instanceof Error ? error : new Error(errorMessage)
|
|
297
|
+
}, contextForLogger, requestId);
|
|
298
|
+
debugInfo.responseTimestamp = new Date();
|
|
299
|
+
debugInfo.error = { message: errorMessage, details: errorDetails };
|
|
300
|
+
await debug_llm_utils_1.LLMDebugger.logError(debugInfo);
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
exports.InceptronProvider = InceptronProvider;
|
|
306
|
+
exports.InceptronService = InceptronProvider;
|
|
307
|
+
// Export singleton instance
|
|
308
|
+
exports.inceptronProvider = new InceptronProvider();
|
|
309
|
+
exports.inceptronService = exports.inceptronProvider;
|
|
310
|
+
//# sourceMappingURL=inceptron-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inceptron-provider.js","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/providers/inceptron-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/providers/index.ts"],"names":[],"mappings":"AACA,cAAc,qBAAqB,CAAC;AAGpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/providers/index.ts"],"names":[],"mappings":"AACA,cAAc,qBAAqB,CAAC;AAGpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC"}
|
|
@@ -24,6 +24,7 @@ __exportStar(require("./requesty-provider"), exports);
|
|
|
24
24
|
__exportStar(require("./bedrock-provider"), exports);
|
|
25
25
|
__exportStar(require("./azure-openai-provider"), exports);
|
|
26
26
|
__exportStar(require("./azure-openai-capabilities"), exports);
|
|
27
|
+
__exportStar(require("./inceptron-provider"), exports);
|
|
27
28
|
// Future providers will be added here:
|
|
28
29
|
// export * from './openai-provider';
|
|
29
30
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/providers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gBAAgB;AAChB,sDAAoC;AAEpC,qBAAqB;AACrB,oDAAkC;AAClC,uDAAqC;AACrC,oDAAkC;AAClC,sDAAoC;AACpC,qDAAmC;AACnC,0DAAwC;AACxC,8DAA4C;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/providers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gBAAgB;AAChB,sDAAoC;AAEpC,qBAAqB;AACrB,oDAAkC;AAClC,uDAAqC;AACrC,oDAAkC;AAClC,sDAAoC;AACpC,qDAAmC;AACnC,0DAAwC;AACxC,8DAA4C;AAC5C,uDAAqC;AAErC,uCAAuC;AACvC,qCAAqC"}
|
|
@@ -147,7 +147,9 @@ export declare enum LLMProvider {
|
|
|
147
147
|
/** AWS Bedrock - Bearer token (API key) auth via Converse API, EU hosting support */
|
|
148
148
|
BEDROCK = "bedrock",
|
|
149
149
|
/** Azure OpenAI / Microsoft Foundry - api-key auth via OpenAI-compatible v1 route, EU data-zone support */
|
|
150
|
-
AZURE_OPENAI = "azure_openai"
|
|
150
|
+
AZURE_OPENAI = "azure_openai",
|
|
151
|
+
/** Inceptron (Inceptron AB, Sweden) - Bearer token auth via OpenAI-compatible API, per-model EU residency */
|
|
152
|
+
INCEPTRON = "inceptron"
|
|
151
153
|
}
|
|
152
154
|
/**
|
|
153
155
|
* Debug information interface (provider-agnostic)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.types.d.ts","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/types/common.types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"common.types.d.ts","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/types/common.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,5 +20,7 @@ var LLMProvider;
|
|
|
20
20
|
LLMProvider["BEDROCK"] = "bedrock";
|
|
21
21
|
/** Azure OpenAI / Microsoft Foundry - api-key auth via OpenAI-compatible v1 route, EU data-zone support */
|
|
22
22
|
LLMProvider["AZURE_OPENAI"] = "azure_openai";
|
|
23
|
+
/** Inceptron (Inceptron AB, Sweden) - Bearer token auth via OpenAI-compatible API, per-model EU residency */
|
|
24
|
+
LLMProvider["INCEPTRON"] = "inceptron";
|
|
23
25
|
})(LLMProvider || (exports.LLMProvider = LLMProvider = {}));
|
|
24
26
|
//# sourceMappingURL=common.types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.types.js","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/types/common.types.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AA6JH;;GAEG;AACH,IAAY,
|
|
1
|
+
{"version":3,"file":"common.types.js","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/types/common.types.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AA6JH;;GAEG;AACH,IAAY,WAcX;AAdD,WAAY,WAAW;IACrB,gCAAiB,CAAA;IACjB,gCAAiB,CAAA;IACjB,sCAAuB,CAAA;IACvB,gCAAiB,CAAA;IACjB,oCAAqB,CAAA;IACrB,kEAAkE;IAClE,sCAAuB,CAAA;IACvB,qFAAqF;IACrF,kCAAmB,CAAA;IACnB,2GAA2G;IAC3G,4CAA6B,CAAA;IAC7B,6GAA6G;IAC7G,sCAAuB,CAAA;AACzB,CAAC,EAdW,WAAW,2BAAX,WAAW,QActB"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { CommonLLMOptions, CommonLLMResponse, ReasoningEffort } from './common.types';
|
|
2
|
+
/**
|
|
3
|
+
* Inceptron-specific request options.
|
|
4
|
+
*
|
|
5
|
+
* Inceptron (Inceptron AB, Lund/Sweden) serves curated open-weight models
|
|
6
|
+
* (GLM-5.1, Kimi, DeepSeek, gpt-oss, β¦) via an OpenAI-compatible Chat
|
|
7
|
+
* Completions API. The wire format matches the Requesty provider; the only
|
|
8
|
+
* Inceptron-specific behaviours are documented on the response type below.
|
|
9
|
+
*
|
|
10
|
+
* Auth, endpoint and model fall back to the common options, then to the
|
|
11
|
+
* INCEPTRON_API_KEY / INCEPTRON_BASE_URL / INCEPTRON_MODEL env vars.
|
|
12
|
+
*/
|
|
13
|
+
export interface InceptronRequestOptions extends CommonLLMOptions {
|
|
14
|
+
/** Optional analytics header: your site URL (HTTP-Referer). */
|
|
15
|
+
httpReferer?: string;
|
|
16
|
+
/** Optional analytics header: your app name (X-Title). */
|
|
17
|
+
xTitle?: string;
|
|
18
|
+
/** Request timeout in milliseconds (default: 180000). */
|
|
19
|
+
timeout?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Reasoning-effort values accepted by Inceptron's reasoning models.
|
|
23
|
+
*
|
|
24
|
+
* Live-verified against zai-org/GLM-5.1-FP8: 'none', 'low', 'medium' and 'high'
|
|
25
|
+
* are all accepted (no HTTP 400), so the provider-agnostic ReasoningEffort maps
|
|
26
|
+
* 1:1. 'none' is the only mode that reliably suppresses the reasoning text and
|
|
27
|
+
* returns a clean `content` (see InceptronAPIResponse for the caveats).
|
|
28
|
+
*/
|
|
29
|
+
export type InceptronReasoningEffort = ReasoningEffort;
|
|
30
|
+
/**
|
|
31
|
+
* OpenAI-compatible content part for multimodal messages (image_url / data-URI),
|
|
32
|
+
* identical to the Requesty/Azure providers.
|
|
33
|
+
*/
|
|
34
|
+
export type InceptronContentPart = {
|
|
35
|
+
type: 'text';
|
|
36
|
+
text: string;
|
|
37
|
+
} | {
|
|
38
|
+
type: 'image_url';
|
|
39
|
+
image_url: {
|
|
40
|
+
url: string;
|
|
41
|
+
detail?: 'low' | 'high' | 'auto';
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* OpenAI-compatible request format for the Inceptron API.
|
|
46
|
+
*/
|
|
47
|
+
export interface InceptronAPIRequest {
|
|
48
|
+
/** Model ID, e.g. "zai-org/GLM-5.1-FP8" (format: provider/model-name[-quant]). */
|
|
49
|
+
model: string;
|
|
50
|
+
messages: Array<{
|
|
51
|
+
role: 'system' | 'user' | 'assistant';
|
|
52
|
+
content: string | InceptronContentPart[];
|
|
53
|
+
}>;
|
|
54
|
+
temperature?: number;
|
|
55
|
+
max_tokens?: number;
|
|
56
|
+
top_p?: number;
|
|
57
|
+
stream?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Reasoning effort. Live-verified to stabilise the response: when set (even to
|
|
60
|
+
* 'none'), `content` was reliably populated; when omitted, `content` was
|
|
61
|
+
* non-deterministic (sometimes empty with all text in `reasoning`). The
|
|
62
|
+
* provider therefore always sends this field, defaulting to 'none'.
|
|
63
|
+
*/
|
|
64
|
+
reasoning_effort?: InceptronReasoningEffort;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* OpenAI-compatible response from the Inceptron API.
|
|
68
|
+
*
|
|
69
|
+
* Two behaviours differ from a textbook OpenAI response (both live-verified
|
|
70
|
+
* against zai-org/GLM-5.1-FP8 on https://openrouter.inceptron.io/v1):
|
|
71
|
+
* 1. Reasoning text is returned in `message.reasoning` (OpenRouter style),
|
|
72
|
+
* NOT `reasoning_content` or `thinking`.
|
|
73
|
+
* 2. `message.content` can be `null` (e.g. when the whole answer leaked into
|
|
74
|
+
* `reasoning`, or when max_tokens was exhausted by reasoning).
|
|
75
|
+
*
|
|
76
|
+
* `usage` carries no `reasoning_tokens` and no `cost`; reasoning tokens are
|
|
77
|
+
* included in `completion_tokens` (so reasoningTokens cannot be tracked here).
|
|
78
|
+
*/
|
|
79
|
+
export interface InceptronAPIResponse {
|
|
80
|
+
id: string;
|
|
81
|
+
object: 'chat.completion';
|
|
82
|
+
created: number;
|
|
83
|
+
model: string;
|
|
84
|
+
choices: Array<{
|
|
85
|
+
index: number;
|
|
86
|
+
message: {
|
|
87
|
+
role: 'assistant';
|
|
88
|
+
/** Can be null β handle defensively. */
|
|
89
|
+
content: string | null;
|
|
90
|
+
/** Reasoning/thinking text (present unless reasoning_effort='none'). */
|
|
91
|
+
reasoning?: string | null;
|
|
92
|
+
};
|
|
93
|
+
finish_reason: 'stop' | 'length' | 'content_filter' | null;
|
|
94
|
+
}>;
|
|
95
|
+
usage: {
|
|
96
|
+
prompt_tokens: number;
|
|
97
|
+
completion_tokens: number;
|
|
98
|
+
total_tokens: number;
|
|
99
|
+
/** Reserved by the API but observed as null; may carry cached_tokens on cache hits. */
|
|
100
|
+
prompt_tokens_details?: {
|
|
101
|
+
cached_tokens?: number;
|
|
102
|
+
} | null;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Normalized Inceptron response (extends CommonLLMResponse).
|
|
107
|
+
*/
|
|
108
|
+
export interface InceptronResponse extends CommonLLMResponse {
|
|
109
|
+
id?: string;
|
|
110
|
+
finish_reason?: string;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=inceptron.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inceptron.types.d.ts","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/types/inceptron.types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtF;;;;;;;;;;GAUG;AACH,MAAM,WAAW,uBAAwB,SAAQ,gBAAgB;IAC/D,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,wBAAwB,GAAG,eAAe,CAAC;AAEvD;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAExF;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;QACtC,OAAO,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAAC;KAC1C,CAAC,CAAC;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,wBAAwB,CAAC;CAC7C;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,KAAK,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE;YACP,IAAI,EAAE,WAAW,CAAC;YAClB,wCAAwC;YACxC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;YACvB,wEAAwE;YACxE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;SAC3B,CAAC;QACF,aAAa,EAAE,MAAM,GAAG,QAAQ,GAAG,gBAAgB,GAAG,IAAI,CAAC;KAC5D,CAAC,CAAC;IACH,KAAK,EAAE;QACL,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;QACrB,uFAAuF;QACvF,qBAAqB,CAAC,EAAE;YAAE,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;KAC3D,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inceptron.types.js","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/types/inceptron.types.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/types/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC;AAG/B,cAAc,oBAAoB,CAAC;AAGnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/types/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC;AAG/B,cAAc,oBAAoB,CAAC;AAGnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC"}
|
|
@@ -26,4 +26,5 @@ __exportStar(require("./requesty.types"), exports);
|
|
|
26
26
|
__exportStar(require("./vertex-ai.types"), exports);
|
|
27
27
|
__exportStar(require("./bedrock.types"), exports);
|
|
28
28
|
__exportStar(require("./azure-openai.types"), exports);
|
|
29
|
+
__exportStar(require("./inceptron.types"), exports);
|
|
29
30
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,eAAe;AACf,iDAA+B;AAE/B,wCAAwC;AACxC,qDAAmC;AAEnC,0BAA0B;AAC1B,iDAA+B;AAC/B,oDAAkC;AAClC,iDAA+B;AAC/B,mDAAiC;AACjC,oDAAkC;AAClC,kDAAgC;AAChC,uDAAqC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/middleware/services/llm/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,eAAe;AACf,iDAA+B;AAE/B,wCAAwC;AACxC,qDAAmC;AAEnC,0BAA0B;AAC1B,iDAA+B;AAC/B,oDAAkC;AAClC,iDAA+B;AAC/B,mDAAiC;AACjC,oDAAkC;AAClC,kDAAgC;AAChC,uDAAqC;AACrC,oDAAkC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loonylabs/llm-middleware",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Complete middleware infrastructure for LLM-based backends with multi-provider support (Ollama, Anthropic, OpenAI,
|
|
3
|
+
"version": "2.30.0",
|
|
4
|
+
"description": "Complete middleware infrastructure for LLM-based backends with multi-provider support (Ollama, Anthropic, Google Gemini & Vertex AI, Requesty, AWS Bedrock, Azure OpenAI / Foundry, Inceptron)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"test:provider:vertex": "ts-node tests/manual/vertex-ai-smoke-test.ts",
|
|
29
29
|
"test:provider:bedrock": "TEST_PROVIDER=bedrock ts-node tests/manual/provider-smoke-test.ts",
|
|
30
30
|
"test:provider:azure": "TEST_PROVIDER=azure ts-node tests/manual/provider-smoke-test.ts",
|
|
31
|
+
"test:provider:inceptron": "TEST_PROVIDER=inceptron ts-node tests/manual/provider-smoke-test.ts",
|
|
31
32
|
"test:vertex:smoke": "ts-node tests/manual/vertex-ai-smoke-test.ts",
|
|
32
33
|
"test:integration:reasoning": "LLM_INTEGRATION_TESTS=true jest tests/integration/reasoning-control.integration.test.ts --testTimeout=120000",
|
|
33
34
|
"test:live": "LLM_INTEGRATION_TESTS=true jest tests/integration/*.integration.test.ts --testTimeout=120000",
|
|
@@ -50,6 +51,10 @@
|
|
|
50
51
|
"google",
|
|
51
52
|
"vertex-ai",
|
|
52
53
|
"gemini",
|
|
54
|
+
"requesty",
|
|
55
|
+
"bedrock",
|
|
56
|
+
"azure-openai",
|
|
57
|
+
"inceptron",
|
|
53
58
|
"multi-provider",
|
|
54
59
|
"backend",
|
|
55
60
|
"typescript",
|