@jungtz/chat-kit 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../.build/models/types.js","../../.build/models/protocol.js","../../.build/models/model-spec.js","../../.build/models/key-ring.js","../../.build/models/quirks.js","../../.build/models/create-model.js","../../.build/models/stream-peek.js","../../.build/models/routed-model.js","../../.build/models/fallback-model.js","../../.build/models/from-config.js","../../.build/models/list-models.js"],"names":["consoleLogger","warn","m","console","info","DEFAULT_PROTOCOL","PROTOCOLS","PROTOCOL_ALIASES","chat","responses","messages","normalizeProtocol","name","includes","Object","prototype","hasOwnProperty","call","resolveProtocol","providerDef","modelName","logger","sdk","rule","perModel","undefined","flavorName","flavor","path","normalized","String","join","parseModelSpec","spec","providerKey","slashIdx","indexOf","substring","normalizeModelConfig","cfg","reasoningEffort","backup","primary","model","DEFAULT_COOLDOWN_MS","MAX_COOLDOWN_MS","createKeyRing","options","strategy","defaultCooldownMs","Number","isFinite","now","Date","random","Math","rings","Map","getRing","baseURL","id","replace","toLowerCase","ringKeyOf","ring","get","cursor","cooldowns","knownKeys","Set","set","pick","keys","list","filter","k","length","add","t","available","reduce","best","floor","picked","MAX_SAFE_INTEGER","markExhausted","key","cooldownMs","ms","min","maskApiKey","round","status","out","total","size","active","values","ts","coolingDown","push","nextRecoveryMs","reset","clear","defaultKeyRing","expandEnvRefs","value","env","_","normalizeApiKeyList","process","raw","Array","isArray","item","expanded","trim","resolveProviderApiKeys","toArray","v","apiKey","apiKeys","slice","unwrapErrors","err","current","depth","e","lastError","cause","isQuotaError","x","statusCode","response","message","error","test","retryAfterMsFromError","headers","responseHeaders","read","h","hit","find","retryAfterMs","parseFloat","retryAfter","seconds","dateMs","parse","delta","normalizeBaseURL","endsWith","OPENCODE_HOST","isOpenCodeEndpoint","host","URL","hostname","hostOf","openCodeHeaders","identity","userAgent","sessionId","reasoningProviderOptions","protocol","effort","isGroq","isAgnes","chat_template_kwargs","enable_thinking","forceReasoning","systemMessageMode","DEFAULT_ANTHROPIC_MAX_OUTPUT_TOKENS","providerOptionsName","async","importOrExplain","specifier","loader","code","Error","createLanguageModel","target","rawApiKey","settings","fetch","createOpenAICompatible","includeUsage","chatModel","createOpenAI","createAnthropic","languageModel","peekStream","stream","isCommitPoint","reader","getReader","buffered","done","next","part","type","some","cancel","catch","kind","ReadableStream","start","controller","p","enqueue","close","pull","reason","isTextDelta","isTextOrReasoningDelta","CHAT_KIT_OPTIONS_KEY","reasoningOptions","translateCallOptions","chatKitRaw","otherProviderOptions","providerOptions","chatKit","fragment","namespace","translated","maxOutputTokens","createRoutedModel","keyRing","factory","createModel","modelsByKey","modelFor","delete","withKeyRotation","attempt","tried","i","max","candidates","has","specificationVersion","provider","modelId","supportedUrls","doGenerate","callOptions","Promise","resolve","doStream","result","peeked","describe","errorMessage","createFallbackModel","models","run","onFallback","from","to","index","resolveModelTarget","providers","def","defaultModel","requireApiKey","resolveModelChain","rawConfig","isNormalized","primaryKey","defaultProviderKey","effortFor","defaultReasoningEffort","base","primaryEffort","chain","backupKey","backupEffort","createModelFromConfig","targets","map","routed","fallback","ListModelsHttpError","constructor","detail","super","this","forEach","listModels","doFetch","globalThis","url","extraHeaders","res","method","Authorization","signal","ok","text","body","json","data"],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * API 金鑰環:多金鑰輪替 + 配額耗盡冷卻。移植自 stock-viewer `server/services/api-key-ring.js`。
3
+ *
4
+ * 與原版的差異只有一個:狀態由 `createKeyRing()` 建立的**實例**持有,不再是模組層全域。
5
+ * 這是 chat-kit「import 時零副作用」的要求,也讓測試不必互相清狀態。
6
+ * 同一個行程內要共享冷卻狀態,就共用同一個實例(`createRoutedModel` 預設共用 `defaultKeyRing`)。
7
+ *
8
+ * 保留的語意:
9
+ * - 冷卻以「金鑰 × 端點」計:同一把金鑰在不同 baseURL 各自冷卻,配額綁在兩者的組合上。
10
+ * - 全部冷卻中時挑「最快解除」那把送出,讓上層的 provider 備援去接手,而不是在此直接判死。
11
+ * - 冷卻狀態是行程內記憶體,重啟即清空(配額窗口多為小時/日級,不值得為它持久化)。
12
+ */
13
+ import type { Logger } from './types.js';
14
+ /** 429 之後預設冷卻時間;provider 有回 `Retry-After` 時以它為準 */
15
+ export declare const DEFAULT_COOLDOWN_MS: number;
16
+ /** 冷卻上限,避免離譜的 `Retry-After` 把金鑰鎖死 */
17
+ export declare const MAX_COOLDOWN_MS: number;
18
+ export type KeyStrategy = 'round-robin' | 'random';
19
+ export interface KeyRingOptions {
20
+ strategy?: KeyStrategy;
21
+ defaultCooldownMs?: number;
22
+ logger?: Logger;
23
+ /** 測試用:注入時間來源 */
24
+ now?: () => number;
25
+ /** 測試用:注入亂數來源(random 策略) */
26
+ random?: () => number;
27
+ }
28
+ export interface KeyRingStatus {
29
+ baseURL: string;
30
+ /** 走過這個環的金鑰總數;0 代表還沒有任何請求走過,不等於健康 */
31
+ total: number;
32
+ /** 冷卻中的金鑰數;單金鑰端點恆為 0(單把時冷卻是 no-op,回報它只會產生假警報) */
33
+ coolingDown: number;
34
+ nextRecoveryMs: number | null;
35
+ }
36
+ export interface KeyRing {
37
+ pick(baseURL: string, keys: readonly string[]): string;
38
+ markExhausted(baseURL: string, key: string, cooldownMs?: number | null): void;
39
+ status(): KeyRingStatus[];
40
+ reset(): void;
41
+ }
42
+ export declare function createKeyRing(options?: KeyRingOptions): KeyRing;
43
+ /** 行程層共用的預設環。由呼叫端第一次使用時才產生狀態,import 本身不做任何事。 */
44
+ export declare const defaultKeyRing: KeyRing;
45
+ type Env = Record<string, string | undefined>;
46
+ /** 正規化為字串陣列:展開 `${ENV}`、去重、濾空 */
47
+ export declare function normalizeApiKeyList(value: unknown, env?: Env): string[];
48
+ /**
49
+ * 從 provider 設定取出金鑰清單。`apiKey` 與 `apiKeys` 並存時**合併**(`apiKey` 排前)——
50
+ * 擇一會靜默丟棄另一邊的金鑰,那種錯只有配額用完那天才會現形。
51
+ */
52
+ export declare function resolveProviderApiKeys(providerDef: {
53
+ apiKey?: string | string[];
54
+ apiKeys?: string[];
55
+ } | null | undefined, env?: Env): string[];
56
+ /** 遮罩金鑰供日誌使用——完整金鑰永遠不進日誌 */
57
+ export declare function maskApiKey(key: unknown): string;
58
+ /**
59
+ * 是否為「配額耗盡/限流」——只有這一類值得換金鑰。
60
+ *
61
+ * 認 HTTP 429(AI SDK 的 `APICallError.statusCode`、openai SDK 的 `status`),也認訊息特徵:
62
+ * 部分中介層會把 429 包成 500,只在訊息裡留下 quota / rate limit 字樣。
63
+ */
64
+ export declare function isQuotaError(err: unknown): boolean;
65
+ /**
66
+ * 從錯誤取出建議等待時間(毫秒)。讀 `retry-after-ms` 或 `retry-after`(秒數或 HTTP date)。
67
+ * 標頭來源:AI SDK 的 `responseHeaders`(純物件)或 openai SDK 的 `headers`(Headers)。
68
+ */
69
+ export declare function retryAfterMsFromError(err: unknown, now?: () => number): number | null;
70
+ export {};
@@ -0,0 +1,30 @@
1
+ /**
2
+ * 列出 provider 的可用模型(`GET {baseURL}/models`,OpenAI 相容端點)。
3
+ *
4
+ * 用途是**健康檢查**:金鑰撞到 429 時會換下一把重試。若不輪替,單一把金鑰配額用完就會讓整個
5
+ * provider 被判定不健康而掉出 pool,其餘金鑰明明還能用卻永遠沒機會被試到。
6
+ * 輪替規則與 `createRoutedModel` 一致:配額類錯誤才換、其他錯誤原樣拋出。
7
+ */
8
+ import type { FetchFunction } from './create-model.js';
9
+ import type { KeyRing } from './key-ring.js';
10
+ import type { ClientIdentity } from './quirks.js';
11
+ import type { Logger } from './types.js';
12
+ export interface ListedModel {
13
+ id: string;
14
+ /** 目前與 `id` 相同(OpenAI 相容端點只提供 id) */
15
+ name: string;
16
+ }
17
+ export interface ListModelsOptions {
18
+ signal?: AbortSignal;
19
+ keyRing?: KeyRing;
20
+ /** opencode 閘門需要的呼叫端身分;只會送給 opencode 端點 */
21
+ identity?: ClientIdentity;
22
+ /** 測試或代理用 */
23
+ fetch?: FetchFunction;
24
+ logger?: Logger;
25
+ }
26
+ /**
27
+ * @param apiKeys 單把金鑰、金鑰清單,或空(無需金鑰的端點,如本機 Ollama)
28
+ * @throws HTTP 非 2xx(配額類錯誤在所有金鑰都試過之後才拋)、回應格式不符、或被 `signal` 中止
29
+ */
30
+ export declare function listModels(baseURL: string, apiKeys: string | readonly string[] | null | undefined, options?: ListModelsOptions): Promise<ListedModel[]>;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * model 規格字串解析。移植自 stock-viewer `server/services/model-spec.js`。
3
+ *
4
+ * - `"opencode-go"` → 只指定 provider,模型走該 provider 的 defaultModel
5
+ * - `"opencode-go/mimo-v2.5"` → 同時指定 provider 與模型(以第一個 `/` 切分)
6
+ *
7
+ * 報告管線的分階段路由(`routing`)不在這裡:那是 stock-viewer 報告專屬的設定,P7 遷移
8
+ * 報告管線時再評估要不要搬。
9
+ */
10
+ import type { ReasoningEffort } from './types.js';
11
+ export interface ModelSpec {
12
+ providerKey: string | null;
13
+ modelName: string | null;
14
+ }
15
+ export declare function parseModelSpec(spec: unknown): ModelSpec;
16
+ export interface ModelConfig extends ModelSpec {
17
+ reasoningEffort: ReasoningEffort | undefined;
18
+ backup: string | undefined;
19
+ }
20
+ /** 設定區段的原始形狀(例如 stock-viewer 的 `premium.chat`) */
21
+ export type RawModelConfig = string | {
22
+ model?: string;
23
+ /** 舊格式:primary 為 provider、model 為純模型名 */
24
+ primary?: string;
25
+ reasoningEffort?: ReasoningEffort;
26
+ backup?: string;
27
+ } | null | undefined;
28
+ /**
29
+ * 正規化模型設定區段。支援三種寫法:
30
+ * - 字串 `"provider"` | `"provider/model"`
31
+ * - 物件(現行)`{ model: "provider" | "provider/model", reasoningEffort?, backup? }`
32
+ * - 物件(舊)`{ primary, model: <純模型名>, reasoningEffort?, backup? }`
33
+ */
34
+ export declare function normalizeModelConfig(cfg: RawModelConfig): ModelConfig;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * API 協定判別:從 provider 的 `sdk` 欄位解出某個模型該走哪種協定。
3
+ *
4
+ * 移植自 stock-viewer `server/services/api-flavor.js` 的 `resolveApiFlavor`,語意不變:
5
+ *
6
+ * - 同一個 provider 的不同模型可能走完全不同的協定。2026-08-24 對 opencode-go 實測,
7
+ * `muse-spark-*` 只在 `/responses` 上供應,打 `/chat/completions` 一律 500。
8
+ * - 不能用嗅探法判斷:`chat` 與 `messages` 都用 `messages` 欄位,而且認證標頭不同
9
+ * (`messages` 要 `x-api-key`),所以必須由設定明確宣告。
10
+ * - **只登記「走 `"*"` 預設會失敗」的模型**,每多一個逐模型例外就多一處要跟上游同步。
11
+ *
12
+ * 與原版唯一的差異:**不支援 `{ flavor, path }` 的自訂路徑**。AI SDK 的 provider 固定
13
+ * 以 `baseURL + 協定路徑` 組 URL,而現行設定沒有任何 provider 用到自訂路徑;遇到時
14
+ * 警告並忽略路徑,不靜默吞掉。
15
+ */
16
+ import type { Logger, Protocol, ProviderDef } from './types.js';
17
+ export declare const DEFAULT_PROTOCOL: Protocol;
18
+ /**
19
+ * 舊值域別名(stock-viewer 第一版依端點命名)。保留是為了讓既有設定不會靜默改走預設協定。
20
+ */
21
+ export declare const PROTOCOL_ALIASES: Readonly<Record<string, Protocol>>;
22
+ /**
23
+ * 正規化協定名稱(吃得下舊別名)。
24
+ * @returns 不認得時回 null
25
+ */
26
+ export declare function normalizeProtocol(name: unknown): Protocol | null;
27
+ /**
28
+ * 解出某模型的協定。
29
+ *
30
+ * 未知的協定名稱**退回預設並警告**,不拋錯:設定打錯字不該讓整條管線掛掉,但也不能無聲
31
+ * 吞掉——muse 走 Chat Completions 是 500,靜默退回的症狀跟沒設定一模一樣。
32
+ */
33
+ export declare function resolveProtocol(providerDef: Pick<ProviderDef, 'sdk'> | null | undefined, modelName: string | null | undefined, logger?: Logger): Protocol;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Provider 特例:baseURL 正規化、opencode 閘門標頭、推理強度的逐 provider 轉譯。
3
+ *
4
+ * 全部移植自 stock-viewer `server/services/ai-client.js`,判斷條件不變。集中在這裡是為了讓
5
+ * 「哪個 provider 吃哪種參數」只有一份真相——散落到呼叫端的特例必然分歧。
6
+ */
7
+ import type { Protocol, ReasoningEffort } from './types.js';
8
+ /** 補上 `/v1`(ollama.com 等端點的 baseURL 慣例不帶) */
9
+ export declare function normalizeBaseURL(baseURL: string): string;
10
+ /** 以 host 判斷,不用字串包含:`?next=https://opencode.ai` 這類參數不該算命中 */
11
+ export declare function isOpenCodeEndpoint(baseURL: string): boolean;
12
+ /** 呼叫端身分,供 opencode Go 閘門使用 */
13
+ export interface ClientIdentity {
14
+ /** 例:`stock-viewer/1.4.2`。Go 要求 client 自報家門,不能是通用 SDK 的預設 UA */
15
+ userAgent: string;
16
+ /** 行程級穩定 ID;Go 用它做路由與 prompt caching,缺了回 `MissingSessionID` */
17
+ sessionId: string;
18
+ }
19
+ /**
20
+ * opencode Go 閘門標頭。**只送給 opencode 端點**:對其他 provider 覆寫 UA、送出可關聯
21
+ * 所有請求的穩定 ID,既無必要也不妥。
22
+ *
23
+ * ⚠️ AI SDK 會在 UA 後面附加自己的後綴(`stock-viewer/x ai-sdk/openai-compatible/y`),
24
+ * 舊實作送的是純 `stock-viewer/x`。閘門目前只要求「不是通用 SDK 預設 UA」,此差異需以實打驗證。
25
+ */
26
+ export declare function openCodeHeaders(baseURL: string, identity: ClientIdentity | undefined): Record<string, string>;
27
+ /**
28
+ * 把推理強度轉成該 provider 認得的 providerOptions 片段(放在 provider 自己的命名空間下)。
29
+ *
30
+ * | 條件 | 送出 |
31
+ * | :-- | :-- |
32
+ * | 未指定 | 不帶任何參數(模型自身預設) |
33
+ * | openai-compatible × Groq | 不帶(非 reasoning model 收到會報錯) |
34
+ * | openai-compatible × Agnes | `chat_template_kwargs.enable_thinking`(high→開,其餘→關) |
35
+ * | openai-compatible × 其他 | `reasoning_effort`,`'none'` 照實送出 |
36
+ * | openai(/responses) | `reasoning.effort`;另帶 `forceReasoning` 與 `systemMessageMode: 'system'` |
37
+ * | anthropic | 不帶(`thinking` 是 token 預算語意,與強度沒有可靠對應) |
38
+ *
39
+ * `/responses` 那列的兩個附加旗標:AI SDK 只對它認得的模型(o 系列、gpt-5+)送 reasoning,
40
+ * muse 這類不在名單內的模型會被**靜默丟掉** effort(只留一條 warning)。`forceReasoning`
41
+ * 把它送出去;但它同時會把 system 角色改成 `developer`,舊實作送的是 `system`,故再明確釘回。
42
+ */
43
+ export declare function reasoningProviderOptions(protocol: Protocol, baseURL: string, effort: ReasoningEffort | null | undefined): Record<string, unknown>;
44
+ /** Anthropic 協定 `max_tokens` 必填;未指定時的預設值(與舊實作相同) */
45
+ export declare const DEFAULT_ANTHROPIC_MAX_OUTPUT_TOKENS = 8192;
46
+ /**
47
+ * `@ai-sdk/openai-compatible` 的 providerOptions 命名空間。
48
+ *
49
+ * 該套件把 provider 名稱「在第一個 `.` 截斷」才拿去找 providerOptions
50
+ * (`name: 'opencode.ai'` → 命名空間是 `opencode`)。providerKey 若含點(例如拿主機名稱當 key),
51
+ * 建立 model 與轉譯推理強度兩處用原字串就會對不上,**推理強度被靜默丟掉**,連一條 warning 都沒有。
52
+ * 所以兩處一律經過這個函式,保證同一個值、且不含點。
53
+ */
54
+ export declare function providerOptionsName(providerKey: string): string;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * 路由模型:把一個 `ModelTarget`(可能有多把金鑰)包成單一 AI SDK `LanguageModelV3`。
3
+ *
4
+ * 引擎與呼叫端看到的只是一個普通的 model;以下三件事都收在這一層:
5
+ *
6
+ * 1. **金鑰輪替**:撞到 429 就冷卻該金鑰、換下一把重試。非配額類錯誤(模型不存在、
7
+ * baseURL 打錯、逾時)原樣拋出——換金鑰對它們沒幫助,只會把一次失敗放大成 N 次。
8
+ * 2. **推理強度轉譯**:呼叫端一律用 `reasoningOptions(effort)` 表達意圖,這裡依協定與
9
+ * provider 轉成實際參數(見 `quirks.ts`)。協定差異不外漏到呼叫端。
10
+ * 3. **provider 特例**:opencode 閘門標頭、Anthropic 必填的輸出上限。
11
+ *
12
+ * ⚠️ 使用 `streamText` / `generateText` 時請設 `maxRetries: 0`。輪替已在這裡處理,
13
+ * AI SDK 預設的重試會在外層再疊一次,把一次 429 放大、還多等指數退避。
14
+ */
15
+ import type { LanguageModelV3, SharedV3ProviderOptions } from '@ai-sdk/provider';
16
+ import type { Logger, ModelTarget, ReasoningEffort } from './types.js';
17
+ import type { FetchFunction, ModelFactory } from './create-model.js';
18
+ import type { KeyRing } from './key-ring.js';
19
+ import type { ClientIdentity } from './quirks.js';
20
+ /** chat-kit 自己的 providerOptions 命名空間;只在這一層解讀,不會送到 provider */
21
+ export declare const CHAT_KIT_OPTIONS_KEY = "chatKit";
22
+ export interface ChatKitCallOptions {
23
+ /**
24
+ * 本次呼叫的推理強度。省略=沿用 target 的預設;`null`=本次明確不帶參數。
25
+ */
26
+ reasoningEffort?: ReasoningEffort | null;
27
+ }
28
+ /**
29
+ * 產生要放進 `streamText({ providerOptions })` 的推理強度設定。
30
+ * @example streamText({ model, messages, providerOptions: reasoningOptions('low') })
31
+ */
32
+ export declare function reasoningOptions(effort: ReasoningEffort | null): SharedV3ProviderOptions;
33
+ export interface RoutedModelOptions {
34
+ keyRing?: KeyRing;
35
+ /** opencode 閘門需要的呼叫端身分;未給則不送閘門標頭 */
36
+ identity?: ClientIdentity;
37
+ /** 測試或代理用 */
38
+ fetch?: FetchFunction;
39
+ logger?: Logger;
40
+ /** 測試用:替換單一金鑰模型的建立方式 */
41
+ createModel?: ModelFactory;
42
+ }
43
+ export declare function createRoutedModel(target: ModelTarget, options?: RoutedModelOptions): LanguageModelV3;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * 串流「探頭」:讀到第一個有意義的內容之前,先把串流握在手上。
3
+ *
4
+ * 金鑰輪替與 provider 備援共用同一條硬規則:**已經吐出內容就不再換手**。使用者眼前已經
5
+ * 看到半截回覆時換手,第二段會接在第一段後面,產出兩個模型拼接的破碎答案,比報錯更糟。
6
+ *
7
+ * 但有些 provider 先回 HTTP 200,再於串流的第一個事件送錯誤——那時其實還沒有任何內容,
8
+ * 可以換手。所以不能只看 `doStream()` 有沒有拋錯,要讀到第一個「算數」的 part 才能決定。
9
+ */
10
+ import type { LanguageModelV3StreamPart } from '@ai-sdk/provider';
11
+ export type PeekResult =
12
+ /** 在任何內容之前就遇到錯誤;`error` 是 part 裡的錯誤物件 */
13
+ {
14
+ kind: 'early-error';
15
+ error: unknown;
16
+ }
17
+ /** 已確認可以交出;`stream` 會從頭重播已讀過的 part */
18
+ | {
19
+ kind: 'ok';
20
+ stream: ReadableStream<LanguageModelV3StreamPart>;
21
+ };
22
+ /**
23
+ * @param isCommitPoint 讀到哪一種 part 就視為「已吐出內容、不能再換手」
24
+ */
25
+ export declare function peekStream(stream: ReadableStream<LanguageModelV3StreamPart>, isCommitPoint: (part: LanguageModelV3StreamPart) => boolean): Promise<PeekResult>;
26
+ export declare const isTextDelta: (p: LanguageModelV3StreamPart) => boolean;
27
+ export declare const isTextOrReasoningDelta: (p: LanguageModelV3StreamPart) => boolean;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * models/ 層的共用型別。
3
+ *
4
+ * `ProviderDef` 刻意貼齊 stock-viewer `config.json` 的 `providers[key]` 形狀——那是目前
5
+ * 唯一的設定來源。chat-kit 的引擎本身不認得這個形狀(只認 AI SDK 的 LanguageModel),
6
+ * 這一層只是「把這種設定轉成 model」的可選輔助。
7
+ */
8
+ /** API 協定家族,值域對齊 opencode 官方文件的 SDK 詞彙 */
9
+ export type Protocol = 'openai-compatible' | 'openai' | 'anthropic';
10
+ /**
11
+ * 推理強度。`'none'` 是**明確關閉思考**並照實送出,與「不設定(不帶參數,模型自身預設)」
12
+ * 是兩回事——opencode-go/deepseek 不帶參數時預設是開思考。
13
+ */
14
+ export type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
15
+ /** `sdk` 欄位:整個 provider 一種,或逐模型(`"*"` 為預設) */
16
+ export type SdkRule = string | {
17
+ flavor?: string;
18
+ path?: string;
19
+ } | null | undefined;
20
+ export type SdkSetting = string | Record<string, SdkRule> | null | undefined;
21
+ export interface ProviderDef {
22
+ baseURL?: string;
23
+ apiKey?: string | string[];
24
+ apiKeys?: string[];
25
+ defaultModel?: string;
26
+ sdk?: SdkSetting;
27
+ reasoningEffort?: ReasoningEffort;
28
+ description?: string;
29
+ type?: string;
30
+ }
31
+ export type ProviderMap = Record<string, ProviderDef>;
32
+ /**
33
+ * 解析後的單一呼叫目標。四個端點欄位(baseURL / apiKeys / model / protocol)一律整包流動,
34
+ * 不拆開傳——stock-viewer 曾因 `apiFlavor` 被逐欄拆開而連續漏傳七次(見其 ai-client.js)。
35
+ */
36
+ export interface ModelTarget {
37
+ providerKey: string;
38
+ baseURL: string;
39
+ /** 已展開 `${ENV}`、去重、濾空;空陣列代表此端點不需要金鑰(如本機 Ollama) */
40
+ apiKeys: string[];
41
+ model: string;
42
+ protocol: Protocol;
43
+ /** 此目標的預設推理強度;呼叫端可用 `reasoningOptions()` 逐次覆寫 */
44
+ reasoningEffort?: ReasoningEffort;
45
+ }
46
+ /** 注入式日誌介面;預設使用 console,測試可換成收集器 */
47
+ export interface Logger {
48
+ warn(message: string): void;
49
+ info?(message: string): void;
50
+ }
51
+ export declare const consoleLogger: Logger;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * 提示詞組裝:Domain 片段 + 上下文區塊 → system 字串與最後一則使用者訊息。
3
+ *
4
+ * 兩個刻意的設計:
5
+ * - **拼接順序完全由 `order` / `key` 決定**,與區塊產生的先後無關。stock-viewer 舊實作讓
6
+ * 各資料源並行 `content +=`,誰先回來誰在前,同一組輸入每次組出的提示詞都不同——
7
+ * 既無法重現,也讓 prompt cache 失效。
8
+ * - **未展開的佔位符直接拋錯**:殘留的 `{{ENTITY_ID}}` 送到模型那邊不會報錯,只會讓回覆
9
+ * 莫名其妙,這種錯必須在組裝時就炸。
10
+ */
11
+ import type { ContextBlock, PromptSpec } from './types.js';
12
+ export interface AssembleInput {
13
+ spec: PromptSpec;
14
+ channel: string;
15
+ blocks: readonly ContextBlock[];
16
+ /**
17
+ * 呼叫端自帶的 system 內容(接在 Domain 片段之後、區塊之前)。
18
+ * **原樣帶入,不展開也不檢查佔位符**:它是已經組好的資料(例如前端把報告全文填進提示詞),
19
+ * 裡面剛好出現 `{{x}}` 不該被當成模板,更不該因此讓整輪失敗。
20
+ */
21
+ extraSystem?: readonly string[];
22
+ /** 最後一則使用者訊息的原文 */
23
+ userMessage: string;
24
+ }
25
+ export interface AssembledPrompt {
26
+ system: string;
27
+ userMessage: string;
28
+ /** 實際注入的區塊 key(依拼接順序),供日誌與回歸比對 */
29
+ injectedKeys: string[];
30
+ }
31
+ /**
32
+ * 展開模板裡的 `{{NAME}}`。**只掃一次、只檢查模板本身**:佔位符的「值」是資料(例如整份報告),
33
+ * 值裡剛好出現 `{{x}}` 既不會被再展開,也不會算成殘留而讓整輪失敗。
34
+ */
35
+ export declare function expandPlaceholders(text: string, values?: Readonly<Record<string, string>>): string;
36
+ /** 依 order、再依 key 排序;空內容略過。key 重複直接拋錯(多半是 Domain 寫錯) */
37
+ export declare function orderBlocks(blocks: readonly ContextBlock[]): ContextBlock[];
38
+ export declare function renderBlock(block: ContextBlock): string;
39
+ export declare function assemblePrompt(input: AssembleInput): AssembledPrompt;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * 信任標記:區塊在提示詞裡的邊界記號。
3
+ *
4
+ * 這組記號是**整個系統唯一的一份真相**。三處都從這裡推導,不得各自再寫一份:
5
+ * 1. 組提示詞時包住區塊(`openMarker` / `closeMarker`)
6
+ * 2. 輸入閘門中和使用者訊息裡的偽造標記(`markerPattern`)
7
+ * 3. 輸出閘門清掉模型吐出來的標記(同上)
8
+ *
9
+ * 動機(owlnest Redmine #9285):使用者若在訊息裡打出 `[END REFERENCE]` 或整段偽造的
10
+ * 權威區塊,模型分不出哪段是系統注入的、哪段是使用者寫的,就會照著偽造的「最高優先指令」做。
11
+ */
12
+ import type { Trust } from './types.js';
13
+ export declare const TRUST_LABELS: Readonly<Record<Trust, string>>;
14
+ export declare function openMarker(trust: Trust, title: string): string;
15
+ export declare function closeMarker(trust: Trust): string;
16
+ /**
17
+ * 比對本系統使用的標記(開頭與結尾兩種),不分大小寫、容許空白變體。
18
+ * 第 1 組擷取括號內的文字,供「換括號、保留內容」使用。
19
+ */
20
+ export declare function markerPattern(): RegExp;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * 提示詞組裝的型別。
3
+ */
4
+ /** 通道。不限定值域:各專案自己決定有哪些通道(web / line / api …) */
5
+ export type Channel = string;
6
+ /**
7
+ * 信任等級,決定區塊在提示詞裡被標記成什麼:
8
+ * - `authoritative`:系統或業主確認過、模型應優先採信的資料
9
+ * - `reference`:檢索或外部取得的參考資料,可能過期或不完整
10
+ * - `realtime`:當下即時取得的資料(報價、狀態),時間敏感
11
+ */
12
+ export type Trust = 'authoritative' | 'reference' | 'realtime';
13
+ /**
14
+ * 一段要注入提示詞的上下文。由 Domain 的 `buildContext` 產出。
15
+ */
16
+ export interface ContextBlock {
17
+ /** 識別用(除錯與回歸比對),同一輪內不可重複 */
18
+ key: string;
19
+ /** 拼接順序,小的在前;同 order 依 key 字典序,保證可重現 */
20
+ order: number;
21
+ trust: Trust;
22
+ /**
23
+ * 放在 system 還是附在最後一則使用者訊息前。
24
+ * 參考資料放 user 訊息是 owlnest 的做法(較不易被當成指令);
25
+ * 既有系統若一直放 system,改動前必須先做行為驗證。
26
+ */
27
+ placement: 'system' | 'user';
28
+ title: string;
29
+ /** 空字串代表本輪無資料,整塊略過(不輸出空標題) */
30
+ content: string;
31
+ /**
32
+ * `marked`(預設):以信任標記包住,例如 `[REFERENCE: 標題] … [END REFERENCE]`
33
+ * `raw`:原樣輸出 content(content 自帶標題時用,例如既有系統的 markdown 區塊)
34
+ */
35
+ format?: 'marked' | 'raw';
36
+ }
37
+ /**
38
+ * Domain 的提示詞規格。片段是**已載入的文字**:讀檔、快取、熱重載都是 Domain 的事,
39
+ * chat-kit 不碰檔案系統。
40
+ */
41
+ export interface PromptSpec {
42
+ /** 依序拼接的 system 片段 */
43
+ parts: readonly string[];
44
+ /** 各通道額外附加的片段(接在 parts 之後) */
45
+ channelParts?: Readonly<Record<Channel, readonly string[]>>;
46
+ /** 佔位符 `{{NAME}}` 的值;組完仍有未展開的佔位符會直接拋錯 */
47
+ placeholders?: Readonly<Record<string, string>>;
48
+ /**
49
+ * 把 user 區塊與使用者原文組成最後一則訊息。預設:區塊在前、原文在後,以空行分隔。
50
+ */
51
+ composeUserMessage?: (args: {
52
+ blocks: string;
53
+ message: string;
54
+ }) => string;
55
+ }