@caeliq/llms 1.0.67 → 1.0.69
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 +7 -5
- package/dist/cjs/server.cjs +226 -222
- package/dist/cjs/server.cjs.map +4 -4
- package/dist/cursor-sdk/events-to-sse.d.ts +3 -3
- package/dist/cursor-sdk/lifecycle-planner.d.ts +5 -0
- package/dist/cursor-sdk/session.d.ts +21 -0
- package/dist/cursor-sdk/shared.d.ts +7 -0
- package/dist/cursor-sdk/usage.d.ts +14 -7
- package/dist/esm/server.mjs +222 -218
- package/dist/esm/server.mjs.map +4 -4
- package/dist/routing/fim-pipeline.d.ts +6 -0
- package/dist/routing/protocol-endpoints.d.ts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/session-registry.d.ts +36 -0
- package/dist/tests/cursor-sdk.shared.d.ts +1 -0
- package/dist/tests/cursor-sdk.tool-id-alias.d.ts +1 -0
- package/dist/tests/fim.endpoint.d.ts +1 -0
- package/dist/tests/fim.transformers.d.ts +1 -0
- package/dist/tests/gpt6.astra-hardening.d.ts +1 -0
- package/dist/tests/session-registry.d.ts +1 -0
- package/dist/transformer/fim/fim.deepseek.transformer.d.ts +15 -0
- package/dist/transformer/fim/fim.mistral.transformer.d.ts +14 -0
- package/dist/transformer/fim/fim.qwen.transformer.d.ts +15 -0
- package/dist/transformer/fim/fim.transformer.d.ts +22 -0
- package/dist/transformer/fim/index.d.ts +4 -0
- package/dist/transformer/index.d.ts +5 -0
- package/dist/transformer/openai.transformer.d.ts +5 -0
- package/dist/transformer/opencode-headers.transformer.d.ts +1 -2
- package/dist/utils/fim/encode.d.ts +14 -0
- package/dist/utils/fim/inbound.d.ts +9 -0
- package/dist/utils/fim/index.d.ts +7 -0
- package/dist/utils/fim/kinds.d.ts +16 -0
- package/dist/utils/fim/response.d.ts +17 -0
- package/dist/utils/fim/types.d.ts +41 -0
- package/dist/utils/fim/url.d.ts +13 -0
- package/dist/utils/message-debug.d.ts +20 -2
- package/dist/utils/reasoning-effort.d.ts +23 -0
- package/dist/utils/router.d.ts +2 -1
- package/package.json +5 -5
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
|
2
|
+
import type { Transformer } from "../types/transformer";
|
|
3
|
+
/**
|
|
4
|
+
* Dedicated FIM pipeline — does not call prepareInboundRequest / chat Unified.
|
|
5
|
+
*/
|
|
6
|
+
export declare function handleFimEndpoint(req: FastifyRequest, reply: FastifyReply, fastify: FastifyInstance, _ownerTransformer: Transformer, routePath: string): Promise<undefined>;
|
|
@@ -4,7 +4,7 @@ import type { ResponsesCallIdMap } from "../utils/openai.responses.util";
|
|
|
4
4
|
/**
|
|
5
5
|
* Inbound client protocols supported by CCR's gateway lifecycle.
|
|
6
6
|
*/
|
|
7
|
-
export type ClientProtocol = "anthropic_messages" | "openai_chat_completions" | "openai_responses";
|
|
7
|
+
export type ClientProtocol = "anthropic_messages" | "openai_chat_completions" | "openai_responses" | "openai_fim_completions";
|
|
8
8
|
export interface AnthropicSourceRequestFields {
|
|
9
9
|
metadata?: Record<string, unknown>;
|
|
10
10
|
thinking?: Record<string, unknown>;
|
package/dist/server.d.ts
CHANGED
|
@@ -59,7 +59,7 @@ export { pluginManager, tokenSpeedPlugin, getTokenSpeedStats, getGlobalTokenSpee
|
|
|
59
59
|
export { SSEParserTransform, SSESerializerTransform, rewriteStream } from "./utils/sse";
|
|
60
60
|
export { isClientAbortError } from "./utils/retry";
|
|
61
61
|
export { sanitizeHeadersForLog, diffHeadersForLog, sanitizeBodyForLog, DEFAULT_LOG_BODY_MAX_BYTES, } from "./utils/redact";
|
|
62
|
-
export { logMessageBody, bodyToLogString,
|
|
62
|
+
export { logMessageBody, bodyToLogString, shouldLogSSEEvents, resolveLogBodyMaxBytes, resolveLogBodySelection, isTruthyConfigFlag, type MessageDebugDirection, } from "./utils/message-debug";
|
|
63
63
|
export { tapUpstreamSSEDebug, tapClientSSEDebug, } from "./utils/sse-debug-tap";
|
|
64
64
|
export { exchangeAuthorizationCode, fetchUserEmail, resolveProjectId, saveTokens, loadTokens, getValidAccessToken, getValidAccessToken as getAntigravityAccessToken, ANTIGRAVITY_CLIENT_ID, ANTIGRAVITY_CLIENT_SECRET, ANTIGRAVITY_REDIRECT_URI, ANTIGRAVITY_SCOPES, type AntigravityTokens, } from "./utils/antigravity-auth";
|
|
65
65
|
export { getValidAccessToken as getClaudeAccessToken } from "./utils/claude-auth";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent registry for every session identity CCR mints.
|
|
3
|
+
*
|
|
4
|
+
* Two families, one mechanism — the stable lookup key already exists in each
|
|
5
|
+
* case (Zen conversation id, cursor buildSessionKey hash); only the minted
|
|
6
|
+
* value used to live in process memory and died on restart:
|
|
7
|
+
*
|
|
8
|
+
* - "zen": conversationKey -> x-opencode-session (ses_…)
|
|
9
|
+
* - "cursor": sessionKey -> { agentId, workspaceDir, model }
|
|
10
|
+
*
|
|
11
|
+
* The file lives under CCR_HOME (the mounted ~/.claude-code-router volume),
|
|
12
|
+
* so bindings survive both restarts and image rebuilds. Plain JSON: values
|
|
13
|
+
* are short strings, not blobs (unlike cursor-opencode-provider's pb.gz,
|
|
14
|
+
* which persists raw Cursor protocol state we never see — the SDK owns that).
|
|
15
|
+
*
|
|
16
|
+
* Synchronous API, tiny file (capped entries), persistence on mint/delete
|
|
17
|
+
* only — never on the hot read path.
|
|
18
|
+
*/
|
|
19
|
+
export type PersistedSession = {
|
|
20
|
+
/** The fixed CCR-minted id (ses_… for zen; SDK agentId for cursor). */
|
|
21
|
+
sessionId: string;
|
|
22
|
+
workspaceDir?: string;
|
|
23
|
+
model?: string;
|
|
24
|
+
updatedAt: number;
|
|
25
|
+
};
|
|
26
|
+
export declare const SESSION_REGISTRY_TTL_MS: number;
|
|
27
|
+
/** Fixed id previously minted for this family+key, or undefined. */
|
|
28
|
+
export declare function getPersistedSession(family: string, key: string, now?: number): PersistedSession | undefined;
|
|
29
|
+
/** Record a newly minted fixed id. Overwrites any prior binding. */
|
|
30
|
+
export declare function putPersistedSession(family: string, key: string, value: Omit<PersistedSession, "updatedAt">, now?: number): PersistedSession;
|
|
31
|
+
/** Forget a binding (session retire, Zen bucket re-roll). */
|
|
32
|
+
export declare function deletePersistedSession(family: string, key: string): void;
|
|
33
|
+
/** Drop expired bindings; returns the number pruned. */
|
|
34
|
+
export declare function pruneSessionRegistry(now?: number): number;
|
|
35
|
+
/** Test hook: drop in-memory state (the file itself is keyed by env dir). */
|
|
36
|
+
export declare function resetSessionRegistryForTests(): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { LLMProvider } from "../../types/llm";
|
|
2
|
+
import type { Transformer, TransformerContext } from "../../types/transformer";
|
|
3
|
+
import { type UnifiedFimRequest } from "../../utils/fim";
|
|
4
|
+
/**
|
|
5
|
+
* DeepSeek beta completions FIM outbound.
|
|
6
|
+
* Same-kind (future deepseek inbound): auth + URL only.
|
|
7
|
+
* Cross-family from Codestral Unified: prompt+suffix + 4K clamp + non-thinking.
|
|
8
|
+
*/
|
|
9
|
+
export declare class FimDeepseekTransformer implements Transformer {
|
|
10
|
+
static TransformerName: string;
|
|
11
|
+
name: string;
|
|
12
|
+
logger?: any;
|
|
13
|
+
transformRequestIn(request: UnifiedFimRequest | any, provider: LLMProvider, context: TransformerContext): Promise<Record<string, any>>;
|
|
14
|
+
transformResponseOut(response: Response): Promise<Response>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { LLMProvider } from "../../types/llm";
|
|
2
|
+
import type { Transformer, TransformerContext } from "../../types/transformer";
|
|
3
|
+
import { type UnifiedFimRequest } from "../../utils/fim";
|
|
4
|
+
/**
|
|
5
|
+
* Codestral / Mistral native FIM outbound.
|
|
6
|
+
* Same-kind (mistral inbound): body passthrough — auth + URL only.
|
|
7
|
+
*/
|
|
8
|
+
export declare class FimMistralTransformer implements Transformer {
|
|
9
|
+
static TransformerName: string;
|
|
10
|
+
name: string;
|
|
11
|
+
logger?: any;
|
|
12
|
+
transformRequestIn(request: UnifiedFimRequest | any, provider: LLMProvider, context: TransformerContext): Promise<Record<string, any>>;
|
|
13
|
+
transformResponseOut(response: Response): Promise<Response>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { LLMProvider } from "../../types/llm";
|
|
2
|
+
import type { Transformer, TransformerContext } from "../../types/transformer";
|
|
3
|
+
import { type UnifiedFimRequest } from "../../utils/fim";
|
|
4
|
+
/**
|
|
5
|
+
* Qwen Completions FIM (LM Studio + DashScope).
|
|
6
|
+
* Same-kind (future qwen inbound): auth + URL only — do not re-template.
|
|
7
|
+
* Cross-family from Codestral Unified: HF tokens in prompt, no suffix field.
|
|
8
|
+
*/
|
|
9
|
+
export declare class FimQwenTransformer implements Transformer {
|
|
10
|
+
static TransformerName: string;
|
|
11
|
+
name: string;
|
|
12
|
+
logger?: any;
|
|
13
|
+
transformRequestIn(request: UnifiedFimRequest | any, provider: LLMProvider, context: TransformerContext): Promise<Record<string, any>>;
|
|
14
|
+
transformResponseOut(response: Response): Promise<Response>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { LLMProvider } from "../../types/llm";
|
|
2
|
+
import type { Transformer, TransformerContext } from "../../types/transformer";
|
|
3
|
+
import { type UnifiedFimRequest } from "../../utils/fim";
|
|
4
|
+
/**
|
|
5
|
+
* Protocol owner for POST /v1/fim/completions.
|
|
6
|
+
* Validates Codestral-shaped inbound → Unified FIM (v1).
|
|
7
|
+
* Client response framing: same-kind passthrough, else encode to inbound wire.
|
|
8
|
+
*/
|
|
9
|
+
export declare class FimTransformer implements Transformer {
|
|
10
|
+
static TransformerName: string;
|
|
11
|
+
name: string;
|
|
12
|
+
endPoint: string;
|
|
13
|
+
logger?: any;
|
|
14
|
+
transformRequestOut(request: any, context: TransformerContext): Promise<any>;
|
|
15
|
+
/**
|
|
16
|
+
* Owner does not perform provider outbound; fim.* transformers do.
|
|
17
|
+
* transformResponseIn is a no-op identity for pipeline compatibility.
|
|
18
|
+
*/
|
|
19
|
+
transformResponseIn(response: Response): Promise<Response>;
|
|
20
|
+
}
|
|
21
|
+
/** Type helper — FIM provider transformers accept UnifiedFimRequest. */
|
|
22
|
+
export type FimProviderTransformIn = (request: UnifiedFimRequest, provider: LLMProvider, context: TransformerContext) => Promise<Record<string, any>>;
|
|
@@ -30,6 +30,7 @@ import { ClaudeAuthTransformer } from "./claude-auth.transformer";
|
|
|
30
30
|
import { CursorSdkTransformer } from "./cursor-sdk.transformer";
|
|
31
31
|
import { AntigravityAuthTransformer } from "./antigravity-auth.transformer";
|
|
32
32
|
import { XaiAuthTransformer } from "./xai-auth.transformer";
|
|
33
|
+
import { FimTransformer, FimMistralTransformer, FimDeepseekTransformer, FimQwenTransformer } from "./fim";
|
|
33
34
|
declare const _default: {
|
|
34
35
|
AnthropicTransformer: typeof AnthropicTransformer;
|
|
35
36
|
GeminiTransformer: typeof GeminiTransformer;
|
|
@@ -63,5 +64,9 @@ declare const _default: {
|
|
|
63
64
|
CursorSdkTransformer: typeof CursorSdkTransformer;
|
|
64
65
|
AntigravityAuthTransformer: typeof AntigravityAuthTransformer;
|
|
65
66
|
XaiAuthTransformer: typeof XaiAuthTransformer;
|
|
67
|
+
FimTransformer: typeof FimTransformer;
|
|
68
|
+
FimMistralTransformer: typeof FimMistralTransformer;
|
|
69
|
+
FimDeepseekTransformer: typeof FimDeepseekTransformer;
|
|
70
|
+
FimQwenTransformer: typeof FimQwenTransformer;
|
|
66
71
|
};
|
|
67
72
|
export default _default;
|
|
@@ -10,6 +10,8 @@ import { UnifiedChatRequest } from "../types/llm";
|
|
|
10
10
|
*
|
|
11
11
|
* ## Full request pipeline (for context)
|
|
12
12
|
*
|
|
13
|
+
* Chat protocols share one lifecycle; the Anthropic inbound example:
|
|
14
|
+
*
|
|
13
15
|
* Client → POST /v1/messages
|
|
14
16
|
* → AnthropicTransformer.transformRequestOut() // Anthropic → Unified (OpenAI)
|
|
15
17
|
* → provider.transformer.use[].transformRequestIn() // provider middleware
|
|
@@ -24,6 +26,9 @@ import { UnifiedChatRequest } from "../types/llm";
|
|
|
24
26
|
* → OpenAITransformer.transformRequestOut() // validate → Unified
|
|
25
27
|
* → provider.transformer.use[].transformRequestIn()
|
|
26
28
|
* → … → OpenAITransformer.transformResponseIn() // reasoning_content; strip Unified thinking
|
|
29
|
+
*
|
|
30
|
+
* Responses and FIM use their own owners (`openai-responses`, `Fim`). FIM is a
|
|
31
|
+
* separate pipeline from chat Unified.
|
|
27
32
|
*/
|
|
28
33
|
export declare class OpenAITransformer implements Transformer {
|
|
29
34
|
name: string;
|
|
@@ -3,8 +3,6 @@ export declare class OpencodeHeadersTransformer implements Transformer {
|
|
|
3
3
|
name: string;
|
|
4
4
|
ownsTransport: boolean;
|
|
5
5
|
requestPhase: "transport";
|
|
6
|
-
private sessionCache;
|
|
7
|
-
private readonly MAX_SESSIONS;
|
|
8
6
|
private lastTimestamp;
|
|
9
7
|
private counter;
|
|
10
8
|
transformRequestIn(request: any, provider: any, context: any): Promise<Record<string, any>>;
|
|
@@ -33,6 +31,7 @@ export declare class OpencodeHeadersTransformer implements Transformer {
|
|
|
33
31
|
private exponentialRetryDelayMs;
|
|
34
32
|
private retryAfterHeaders;
|
|
35
33
|
private ensurePromptCacheKey;
|
|
34
|
+
private ensurePromptCacheRetention;
|
|
36
35
|
private fingerprintConversation;
|
|
37
36
|
private getOrCreateSessionId;
|
|
38
37
|
private invalidateSession;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { UnifiedFimRequest } from "./types";
|
|
2
|
+
declare const DEEPSEEK_FIM_MAX_TOKENS = 4096;
|
|
3
|
+
/** Qwen / HF FIM markers for completions prompt. */
|
|
4
|
+
export declare function buildQwenFimPrompt(prompt: string, suffix?: string): string;
|
|
5
|
+
/** Sampling fields shared across FIM outbound bodies. */
|
|
6
|
+
export declare function pickFimSamplingFields(unified: UnifiedFimRequest): Record<string, unknown>;
|
|
7
|
+
/** Native prompt+suffix body (Mistral / DeepSeek field shape). */
|
|
8
|
+
export declare function encodePromptSuffixBody(unified: UnifiedFimRequest, options?: {
|
|
9
|
+
clampMaxTokens?: number;
|
|
10
|
+
disableThinking?: boolean;
|
|
11
|
+
}): Record<string, unknown>;
|
|
12
|
+
export declare function encodeDeepseekFimBody(unified: UnifiedFimRequest): Record<string, unknown>;
|
|
13
|
+
export declare function encodeQwenFimBody(unified: UnifiedFimRequest): Record<string, unknown>;
|
|
14
|
+
export { DEEPSEEK_FIM_MAX_TOKENS };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FimInboundKind } from "./kinds";
|
|
2
|
+
import type { UnifiedFimRequest } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Inbound → Unified FIM seam.
|
|
5
|
+
* v1: only Codestral/Mistral kind. Future: inboundKind selects an adapter.
|
|
6
|
+
*/
|
|
7
|
+
export declare function inboundToUnifiedFim(body: unknown, inboundKind?: FimInboundKind): UnifiedFimRequest;
|
|
8
|
+
/** Clone client body for same-kind passthrough (preserve unknown fields). */
|
|
9
|
+
export declare function cloneFimClientBody(body: unknown, modelName: string): Record<string, unknown>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { UnifiedFimRequest, UnifiedFimResponse, UnifiedFimChoice, } from "./types";
|
|
2
|
+
export type { FimInboundKind, FimOutboundFamily } from "./kinds";
|
|
3
|
+
export { V1_FIM_INBOUND_KIND, isFimProviderTransformerName, outboundFamilyFromTransformerName, shouldFimPassthrough, } from "./kinds";
|
|
4
|
+
export { inboundToUnifiedFim, cloneFimClientBody, } from "./inbound";
|
|
5
|
+
export { resolveFimMistralUrl, resolveFimDeepseekUrl, resolveFimQwenCompletionsUrl, bearerAuthHeaders, } from "./url";
|
|
6
|
+
export { buildQwenFimPrompt, pickFimSamplingFields, encodePromptSuffixBody, encodeDeepseekFimBody, encodeQwenFimBody, DEEPSEEK_FIM_MAX_TOKENS, } from "./encode";
|
|
7
|
+
export { encodeFimResponseForInbound, normalizeToFimClientJson, normalizeFimSseDataPayload, } from "./response";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FIM inbound/outbound family kinds. v1 only implements mistral/codestral
|
|
3
|
+
* inbound; deepseek/qwen inbound adapters are reserved for later.
|
|
4
|
+
*/
|
|
5
|
+
export type FimInboundKind = "mistral" | "deepseek" | "qwen";
|
|
6
|
+
export type FimOutboundFamily = "mistral" | "deepseek" | "qwen";
|
|
7
|
+
/** v1 hard-wired inbound kind (Codestral/Mistral-shaped client wire). */
|
|
8
|
+
export declare const V1_FIM_INBOUND_KIND: FimInboundKind;
|
|
9
|
+
export declare function isFimProviderTransformerName(name: string | undefined): boolean;
|
|
10
|
+
export declare function outboundFamilyFromTransformerName(name: string | undefined): FimOutboundFamily | null;
|
|
11
|
+
/**
|
|
12
|
+
* Same-kind passthrough: no request or response shape translation —
|
|
13
|
+
* auth/URL only. Kept generic so future DeepSeek→DeepSeek / Qwen→Qwen
|
|
14
|
+
* inbound works the same.
|
|
15
|
+
*/
|
|
16
|
+
export declare function shouldFimPassthrough(inboundKind: FimInboundKind, outboundFamily: FimOutboundFamily): boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encode upstream FIM responses to the **inbound** client wire.
|
|
3
|
+
* Client response shape follows inbound kind (not outbound provider).
|
|
4
|
+
* v1 inbound is mistral/Codestral; deepseek/qwen inbound reserved for later.
|
|
5
|
+
*/
|
|
6
|
+
import type { FimInboundKind } from "./kinds";
|
|
7
|
+
/**
|
|
8
|
+
* Normalize upstream JSON to the inbound client wire.
|
|
9
|
+
* @param inboundKind — must match the kind used for inboundToUnifiedFim
|
|
10
|
+
*/
|
|
11
|
+
export declare function encodeFimResponseForInbound(payload: any, inboundKind?: FimInboundKind): Record<string, any>;
|
|
12
|
+
/** @deprecated Prefer encodeFimResponseForInbound(payload, inboundKind) */
|
|
13
|
+
export declare function normalizeToFimClientJson(payload: any, inboundKind?: FimInboundKind): Record<string, any>;
|
|
14
|
+
/**
|
|
15
|
+
* Map one SSE data payload to the inbound client wire.
|
|
16
|
+
*/
|
|
17
|
+
export declare function normalizeFimSseDataPayload(dataStr: string, inboundKind?: FimInboundKind): string;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified FIM intermediate (prompt + optional suffix + sampling).
|
|
3
|
+
* Types live next to FIM utils — not a separate types/fim package.
|
|
4
|
+
*
|
|
5
|
+
* Client response wire follows **inbound** kind (see encodeFimResponseForInbound).
|
|
6
|
+
* v1 inbound is mistral/Codestral chat.completion; other kinds reserved.
|
|
7
|
+
*/
|
|
8
|
+
export interface UnifiedFimRequest {
|
|
9
|
+
model: string;
|
|
10
|
+
prompt: string;
|
|
11
|
+
suffix?: string;
|
|
12
|
+
max_tokens?: number;
|
|
13
|
+
temperature?: number;
|
|
14
|
+
top_p?: number;
|
|
15
|
+
stop?: string | string[];
|
|
16
|
+
stream?: boolean;
|
|
17
|
+
min_tokens?: number;
|
|
18
|
+
random_seed?: number;
|
|
19
|
+
}
|
|
20
|
+
/** Choice on mistral/Codestral inbound client wire. */
|
|
21
|
+
export interface UnifiedFimChoice {
|
|
22
|
+
index: number;
|
|
23
|
+
message: {
|
|
24
|
+
role: string;
|
|
25
|
+
content: string;
|
|
26
|
+
};
|
|
27
|
+
finish_reason: string;
|
|
28
|
+
}
|
|
29
|
+
export interface UnifiedFimResponse {
|
|
30
|
+
id: string;
|
|
31
|
+
object: "chat.completion";
|
|
32
|
+
model: string;
|
|
33
|
+
created: number;
|
|
34
|
+
choices: UnifiedFimChoice[];
|
|
35
|
+
usage: {
|
|
36
|
+
prompt_tokens: number;
|
|
37
|
+
completion_tokens: number;
|
|
38
|
+
total_tokens: number;
|
|
39
|
+
};
|
|
40
|
+
[key: string]: unknown;
|
|
41
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Resolve Codestral/Mistral native FIM URL from provider base. */
|
|
2
|
+
export declare function resolveFimMistralUrl(baseUrl: string): URL;
|
|
3
|
+
/**
|
|
4
|
+
* DeepSeek hosted FIM uses beta completions.
|
|
5
|
+
* Prefer explicit …/beta/completions; otherwise derive from host.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveFimDeepseekUrl(baseUrl: string): URL;
|
|
8
|
+
/**
|
|
9
|
+
* Qwen / LM Studio / DashScope: OpenAI legacy completions.
|
|
10
|
+
* Trust api_base_url when it already ends with /completions.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveFimQwenCompletionsUrl(baseUrl: string): URL;
|
|
13
|
+
export declare function bearerAuthHeaders(apiKey: string | undefined): Record<string, string>;
|
|
@@ -4,9 +4,18 @@ export declare function isTruthyConfigFlag(value: unknown): boolean;
|
|
|
4
4
|
export declare function resolveLogBodyMaxBytes(configService: {
|
|
5
5
|
get?: (key: string) => unknown;
|
|
6
6
|
} | null | undefined): number;
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Body capture selector (`LOG_REQUEST_BODY_PARTS`): comma-separated top-level
|
|
9
|
+
* body fields (`system,tools`), or `full` for the whole body. Unset/empty
|
|
10
|
+
* disables capture. Unknown names are kept and reported as not-found at write
|
|
11
|
+
* time so typos stay visible.
|
|
12
|
+
*/
|
|
13
|
+
export type LogBodySelection = "full" | string[];
|
|
14
|
+
export declare function resolveLogBodySelection(configService: {
|
|
8
15
|
get?: (key: string) => unknown;
|
|
9
|
-
} | null | undefined):
|
|
16
|
+
} | null | undefined): LogBodySelection | undefined;
|
|
17
|
+
/** Capture files live next to the rotated server logs. */
|
|
18
|
+
export declare function defaultLogBodyDir(): string;
|
|
10
19
|
export declare function shouldLogSSEEvents(configService: {
|
|
11
20
|
get?: (key: string) => unknown;
|
|
12
21
|
} | null | undefined): boolean;
|
|
@@ -27,6 +36,15 @@ export type MessageBodyLogOptions = {
|
|
|
27
36
|
maxBytes?: number;
|
|
28
37
|
/** Override the historical `type` field when needed. */
|
|
29
38
|
type?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Resolved `LOG_REQUEST_BODY_PARTS` (see resolveLogBodySelection).
|
|
41
|
+
* `"full"` stores the whole body; a list stores one file per named
|
|
42
|
+
* top-level field. The log carries one manifest line per part (with sha256)
|
|
43
|
+
* instead of the body. Undefined keeps the legacy inline whole-body dump.
|
|
44
|
+
*/
|
|
45
|
+
selection?: LogBodySelection | undefined;
|
|
46
|
+
/** Code-level directory override (tests); defaults to the logs folder. */
|
|
47
|
+
bodiesDir?: string;
|
|
30
48
|
};
|
|
31
49
|
/**
|
|
32
50
|
* Compact keep-wire snapshot for debug logs. Full transcripts stay behind
|
|
@@ -32,4 +32,27 @@ export declare function canonicalReasoning(effortValue: unknown, enabledWhenEffo
|
|
|
32
32
|
export declare function applyOpenAIChatReasoning(request: UnifiedChatRequest): UnifiedChatRequest;
|
|
33
33
|
/** Anthropic accepts low..max, while CCR/OpenAI may additionally emit minimal/ultra/none. */
|
|
34
34
|
export declare function toAnthropicReasoningEffort(effortValue: unknown): Exclude<ThinkLevel, "none" | "minimal" | "ultra"> | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* GPT-6 family slugs (`gpt-6`, `gpt-6-astra`, `openai/gpt-6-astra`,
|
|
37
|
+
* `codex,gpt-6-astra`). Anchored so `gpt-60` / `gpt-5.6` do not match.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isGpt6FamilyModel(model: unknown): boolean;
|
|
40
|
+
/** Astra rejects `none` / `minimal`; OpenAI's migration floor is `low`. */
|
|
41
|
+
export declare function coerceGpt6ReasoningEffort(model: unknown, effort: ThinkLevel | undefined): ThinkLevel | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Remap unsupported GPT-6 efforts on a Responses/Unified request in place.
|
|
44
|
+
* Covers convert (`openai-responses`) and same-protocol wire-keep (`codex`).
|
|
45
|
+
*/
|
|
46
|
+
export declare function applyGpt6ReasoningEffortCoercion(request: {
|
|
47
|
+
model?: unknown;
|
|
48
|
+
reasoning?: {
|
|
49
|
+
effort?: unknown;
|
|
50
|
+
enabled?: boolean;
|
|
51
|
+
} | null;
|
|
52
|
+
}): void;
|
|
53
|
+
/**
|
|
54
|
+
* GPT-6 Astra rejects temperature / top_p / logprobs on Responses. Strip in
|
|
55
|
+
* place when the model is in the gpt-6 family.
|
|
56
|
+
*/
|
|
57
|
+
export declare function stripGpt6UnsupportedSampling(request: Record<string, any>): void;
|
|
35
58
|
export {};
|
package/dist/utils/router.d.ts
CHANGED
|
@@ -35,7 +35,7 @@ export interface RouterContext {
|
|
|
35
35
|
tokenizerService?: TokenizerService;
|
|
36
36
|
event?: any;
|
|
37
37
|
}
|
|
38
|
-
export type RouterScenarioType = 'default' | 'background' | 'think' | 'longContext' | 'webSearch' | 'subagent';
|
|
38
|
+
export type RouterScenarioType = 'default' | 'background' | 'think' | 'longContext' | 'webSearch' | 'subagent' | 'fim';
|
|
39
39
|
export interface RouterFallbackConfig {
|
|
40
40
|
default?: string[];
|
|
41
41
|
background?: string[];
|
|
@@ -43,6 +43,7 @@ export interface RouterFallbackConfig {
|
|
|
43
43
|
longContext?: string[];
|
|
44
44
|
webSearch?: string[];
|
|
45
45
|
subagent?: string[];
|
|
46
|
+
fim?: string[];
|
|
46
47
|
}
|
|
47
48
|
export declare const router: (req: any, _res: any, context: RouterContext) => Promise<void>;
|
|
48
49
|
export declare const searchProjectBySession: (sessionId: string, logger?: any) => Promise<string | null>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caeliq/llms",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.69",
|
|
4
4
|
"description": "A universal LLM API transformation server",
|
|
5
5
|
"main": "dist/cjs/server.cjs",
|
|
6
6
|
"module": "dist/esm/server.mjs",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@anthropic-ai/sdk": "^0.120.0",
|
|
33
|
-
"@caeliq/ccr-shared": "^2.1.
|
|
33
|
+
"@caeliq/ccr-shared": "^2.1.11",
|
|
34
34
|
"@cursor/sdk": "^1.0.30",
|
|
35
35
|
"@fastify/cors": "^11.3.0",
|
|
36
36
|
"@fastify/rate-limit": "^11.2.0",
|
|
@@ -46,13 +46,13 @@
|
|
|
46
46
|
"lru-cache": "^11.5.2",
|
|
47
47
|
"openai": "^7.5.0",
|
|
48
48
|
"tiktoken": "^1.0.22",
|
|
49
|
-
"undici": "^8.10.
|
|
49
|
+
"undici": "^8.10.1",
|
|
50
50
|
"uuid": "^14.0.2"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@types/node": "^26.4.
|
|
53
|
+
"@types/node": "^26.4.1",
|
|
54
54
|
"esbuild": "^0.28.2",
|
|
55
|
-
"tsx": "^4.23.
|
|
55
|
+
"tsx": "^4.23.13",
|
|
56
56
|
"typescript": "^6.0.3"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|