@lynn123411/dsh-a6api 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ interface A6ApiSidebarCardProps {
3
+ /** 宿主注入:侧边栏是否宽布局(false = 56px rail) */
4
+ wide: boolean;
5
+ /** 宿主注入:会话列表快照钩子(取 current 即当前会话 ID) */
6
+ useSessions?: (selector: (s: any) => any) => any;
7
+ /** apply 注入:modelDirectories 服务访问器(与 composer 模型选择器同源) */
8
+ getModelDirectories?: () => any;
9
+ }
10
+ /**
11
+ * 侧边栏左下角「A6api」按钮 + 向上弹出当前会话 A6api 模型的 MerchantCard 浮层。
12
+ * 与设置页共享 A6ApiStore 单例:探测/轮询/操作结果实时同步。
13
+ *
14
+ * useSessions 是 React hook,不能条件调用:由外层按「壳是否注入」分派到两个固定
15
+ * 分支(内层恒调用 / 无钩子分支恒不调用),规避 Rules of Hooks 风险。
16
+ */
17
+ export declare const A6ApiSidebarCard: React.FC<A6ApiSidebarCardProps>;
18
+ export {};
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ /**
3
+ * 模型目录页(「可用模型」右侧 tab):
4
+ * - 「从 A6API 获取市场模型」:翻页拉取 A6API 市场全部模型 ID 入目录(参数初始为空)
5
+ * - 「从 OpenRouter 一键查询」:对全部模型查 OpenRouter 并填充参数(name 仅用户手动填写);
6
+ * 每行也可单独查询
7
+ * - 筛选:可用模型(当前令牌白名单,与「可用模型」页同源)/ 参数状态(已填/未填)
8
+ * - 行内编辑 settings.yaml 原生模型字段;保存后若该模型已在 DSH 启用,
9
+ * 服务端立即重写 settings.yaml 对应条目(参数即时生效)
10
+ */
11
+ export declare const ModelCatalogPanel: React.FC;
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import type { PriceFluctuationState } from '../../types.js';
3
+ /**
4
+ * 价格波动胶囊(设置页头部与侧边栏浮层共用):
5
+ * 未配置令牌显示 `--`(禁用),无变动置灰(禁用),有待处理时点击跳官网处理。
6
+ * compact 为浮层内的紧凑缩窄版。
7
+ */
8
+ export declare const PricePill: React.FC<{
9
+ pf: PriceFluctuationState;
10
+ hasToken: boolean;
11
+ compact?: boolean;
12
+ }>;
@@ -1,4 +1,4 @@
1
- import type { A6ApiConfig, BalanceInfo, ModelCardData, ApiRoutingLogItem, PriceFluctuationState } from '../types.js';
1
+ import type { A6ApiConfig, BalanceInfo, CatalogModelEntry, ModelCardData, ApiRoutingLogItem, PriceFluctuationState, MarketplacePin } from '../types.js';
2
2
  export interface StoreState {
3
3
  loading: boolean;
4
4
  config: A6ApiConfig;
@@ -7,6 +7,20 @@ export interface StoreState {
7
7
  dshConfiguredModels: string[];
8
8
  recentLogs: ApiRoutingLogItem[];
9
9
  probingModelNames: Set<string>;
10
+ /** 正在执行固定/取消固定/禁用/恢复操作的模型 */
11
+ actionBusyModels: Set<string>;
12
+ /** 全量探测是否进行中(store 驱动 UI:进度、取消按钮、重入防护) */
13
+ probeAllActive: boolean;
14
+ /** 全量探测总模型数(入队时快照) */
15
+ probeAllTotal: number;
16
+ /** 全量探测已完成数(与 state.models 解耦,/state 刷新不丢) */
17
+ probeAllDoneCount: number;
18
+ /** 平台固定记录(卡片状态跟随官网) */
19
+ pins: MarketplacePin[];
20
+ /** 模型目录(运行时 JSON,字段 = settings.yaml 原生模型字段 + brand) */
21
+ catalog: CatalogModelEntry[];
22
+ /** 目录操作进行中(获取市场模型 / OpenRouter 查询) */
23
+ catalogBusy: 'fetch' | 'query' | null;
10
24
  error: string | null;
11
25
  priceFluctuation: PriceFluctuationState;
12
26
  }
@@ -15,7 +29,16 @@ declare class A6ApiStore {
15
29
  private state;
16
30
  private listeners;
17
31
  private autoRefreshTimer;
18
- private pricePollTimer;
32
+ /** 启动预热已触发(幂等):插件随 DSH 启动即后台拉一次完整状态 */
33
+ private warmedUp;
34
+ /** 全量探测取消标志:置位后不再从队列取新任务,在途探测正常完成 */
35
+ private probeCancelled;
36
+ /** 本轮全量探测的模型名快照(null = 未在运行),用于进度计数与 /state 刷新后重挂状态 */
37
+ private probeAllSnapshot;
38
+ /** 本轮已完成探测的模型(幂等集合,驱动 probeAllDoneCount) */
39
+ private probeAllDone;
40
+ /** 入队前各模型的 probeError 暂存,取消时恢复历史错误提示 */
41
+ private probeQueuedPrevError;
19
42
  constructor();
20
43
  subscribe(listener: Listener): () => void;
21
44
  private notify;
@@ -23,10 +46,77 @@ declare class A6ApiStore {
23
46
  fetchState(): Promise<void>;
24
47
  saveConfig(config: Partial<A6ApiConfig>): Promise<boolean>;
25
48
  refreshBalance(): Promise<void>;
49
+ fetchCatalog(): Promise<void>;
50
+ /** 从 A6API 市场拉取全部模型 ID 并入目录(仅新增/补品牌,不动已有参数) */
51
+ fetchMarketModels(): Promise<{
52
+ ok: boolean;
53
+ total?: number;
54
+ added?: number;
55
+ failedPages?: number;
56
+ error?: string;
57
+ }>;
58
+ /** 对全部(或指定)目录模型查 OpenRouter 并填充参数 */
59
+ queryOpenRouter(modelIds?: string[]): Promise<{
60
+ ok: boolean;
61
+ updated?: number;
62
+ notFound?: string[];
63
+ error?: string;
64
+ }>;
65
+ /** 修改目录条目参数;已启用模型由服务端即时重写 settings.yaml */
66
+ updateCatalogEntry(id: string, patch: Partial<CatalogModelEntry>): Promise<{
67
+ ok: boolean;
68
+ error?: string;
69
+ }>;
70
+ /** 清空模型目录(随后可重新从 A6API 拉取 / OpenRouter 填充) */
71
+ clearCatalog(): Promise<{
72
+ ok: boolean;
73
+ error?: string;
74
+ }>;
26
75
  fetchPriceFluctuation(): Promise<void>;
76
+ /** 单次探测请求(不修改状态,供限流重试循环复用) */
77
+ private probeOnce;
78
+ private isRateLimitedOutcome;
79
+ /** 把一次探测结果应用到卡片(按结果类型走原有映射逻辑) */
80
+ private applyProbeResult;
27
81
  probeModel(modelName: string): Promise<void>;
28
82
  probeAll(): Promise<void>;
83
+ /** 把仍处于 queued 的模型复位为 idle 并恢复入队前的错误文案 */
84
+ private restoreQueuedModels;
85
+ /** 取消全量探测:立即复位排队模型,不再取新任务,已在途的探测正常完成并回填卡片 */
86
+ cancelProbeAll(): void;
29
87
  toggleDshModel(modelName: string): Promise<void>;
88
+ /**
89
+ * 固定 / 取消固定 / 禁用 / 恢复 的统一执行器。
90
+ * 成功后会刷新 /state(服务端会把平台固定记录叠加回卡片,跟随官网状态)。
91
+ */
92
+ private runMarketplaceAction;
93
+ /** 固定卡片当前商家到该模型 */
94
+ pinModel(modelName: string): Promise<{
95
+ ok: boolean;
96
+ error?: string;
97
+ }>;
98
+ /** 取消该模型的固定 */
99
+ unpinModel(modelName: string): Promise<{
100
+ ok: boolean;
101
+ error?: string;
102
+ }>;
103
+ /** 禁用卡片当前商家对该模型的服务 */
104
+ disableModel(modelName: string): Promise<{
105
+ ok: boolean;
106
+ error?: string;
107
+ }>;
108
+ /** 恢复被禁用的商家 */
109
+ restoreModel(modelName: string): Promise<{
110
+ ok: boolean;
111
+ error?: string;
112
+ }>;
113
+ /**
114
+ * 启动预热:插件随 DSH 启动即后台拉取一次完整状态。
115
+ * 侧边栏按钮在应用启动时就已挂载,预热让用户打开浮层/设置页时数据早已就绪 → 秒开无 spinner。
116
+ * 未配置凭据时 /state 返回默认回退数据,无害;后续保存配置/轮询会持续刷新。
117
+ * 目录一并预热(模型目录 tab 徽标/首屏不等待首次进入)。
118
+ */
119
+ warmUp(): void;
30
120
  private startAutoRefresh;
31
121
  stopAutoRefresh(): void;
32
122
  initPricePolling(): void;
@@ -1,7 +1,7 @@
1
1
  export declare const name = "@lynn123411/dsh-a6api";
2
2
  export declare const inject: string[];
3
- export { fetchBalance, fetchTokenModels, fetchRecentLogs, fetchChannelDetails, } from './server/a6api-client.js';
3
+ export { fetchBalance, fetchTokenModels, fetchRecentLogs, fetchChannelDetails, fetchMarketplacePins, } from './server/a6api-client.js';
4
4
  export { probeSingleModel, getKnownMerchantsFromLogs } from './server/probe.js';
5
- export { resolveModelMeta, A6API_CATALOG } from './server/catalog.js';
6
- export { readPluginConfig, savePluginConfig, syncToDshSettings } from './server/sync.js';
5
+ export { resolveModelMeta, inferBrand, getCatalog, getCatalogEntry, clearCatalog, queryOpenRouter, fetchMarketplaceModels, updateCatalogEntry, } from './server/catalog.js';
6
+ export { createConfigAccess, A6API_CRED_REF, A6API_TOKEN_REF, A6API_USER_REF } from './server/sync.js';
7
7
  export declare function apply(ctx: any): void;
@@ -1,24 +1,50 @@
1
- import type { BalanceInfo, MerchantChannelInfo, ApiRoutingLogItem } from '../types.js';
1
+ import type { BalanceInfo, MerchantChannelInfo, ApiRoutingLogItem, MarketplacePin, A6ApiTokenItem } from '../types.js';
2
2
  /** Normalize Base URL removing trailing slashes */
3
3
  export declare function cleanBaseUrl(url: string): string;
4
4
  /** Format relative time */
5
5
  export declare function formatRelativeTime(timestampSec: number): string;
6
6
  /** Format CNY Price */
7
7
  export declare function formatCnyPrice(micros: number, exchangeRate?: number): string;
8
- export declare function buildWebHeaders(userId?: string, sessionCookie?: string): Record<string, string>;
8
+ export declare function buildWebHeaders(userId?: string, accessToken?: string): Record<string, string>;
9
9
  /** Fetch User Balance (Real Account Balance Only) */
10
- export declare function fetchBalance(baseURL: string, apiKey: string, userId?: string, sessionCookie?: string): Promise<BalanceInfo | null>;
10
+ export declare function fetchBalance(baseURL: string, apiKey: string, userId?: string, accessToken?: string): Promise<BalanceInfo | null>;
11
11
  /** Fetch Token Allowed Models */
12
12
  export declare function fetchTokenModels(baseURL: string, apiKey: string): Promise<string[]>;
13
13
  /** Fetch Recent User Routing Logs */
14
- export declare function fetchRecentLogs(userId?: string, sessionCookie?: string, limit?: number): Promise<ApiRoutingLogItem[]>;
14
+ export declare function fetchRecentLogs(userId?: string, accessToken?: string, limit?: number): Promise<ApiRoutingLogItem[]>;
15
15
  /** Fetch Channel Card details from A6API Marketplace */
16
- export declare function fetchChannelDetails(channelId: number, userId?: string, sessionCookie?: string, targetModelName?: string, logSnapshot?: any): Promise<MerchantChannelInfo | null>;
16
+ export declare function fetchChannelDetails(channelId: number, userId?: string, accessToken?: string, targetModelName?: string, logSnapshot?: any): Promise<MerchantChannelInfo | null>;
17
17
  /** 轻量拉取价格波动条数(仅 pending/unseen) */
18
- export declare function fetchPriceFluctuation(userId?: string, sessionCookie?: string, accessToken?: string): Promise<{
18
+ export declare function fetchPriceFluctuation(userId?: string, accessToken?: string): Promise<{
19
19
  pendingCount: number;
20
20
  unseenCount: number;
21
21
  totalCount: number;
22
22
  notices?: any[];
23
23
  authError?: boolean;
24
24
  }>;
25
+ interface MarketplaceActionResult {
26
+ ok: boolean;
27
+ message?: string;
28
+ data?: any;
29
+ }
30
+ /** GET /api/marketplace/pins — 当前账号全部固定记录(卡片状态跟随官网的真相源) */
31
+ export declare function fetchMarketplacePins(userId?: string, accessToken?: string): Promise<MarketplacePin[]>;
32
+ /** GET /api/token/?p=1&size=100 — 令牌列表(用于把 API Key 解析为 token_id) */
33
+ export declare function fetchTokens(userId?: string, accessToken?: string): Promise<A6ApiTokenItem[]>;
34
+ /** POST /api/marketplace/pin — 把某模型的流量固定到指定渠道(绑定令牌) */
35
+ export declare function marketplacePin(userId: string | undefined, accessToken: string | undefined, payload: {
36
+ token_id: number;
37
+ channel_id: number;
38
+ model_name: string;
39
+ fallback_to_smart_routing: boolean;
40
+ }): Promise<MarketplaceActionResult>;
41
+ /** POST /api/marketplace/unpin — 取消某模型的固定 */
42
+ export declare function marketplaceUnpin(userId: string | undefined, accessToken: string | undefined, payload: {
43
+ token_id: number;
44
+ model_name: string;
45
+ }): Promise<MarketplaceActionResult>;
46
+ /** POST /api/marketplace/channels/:id/disable?model= — 禁用某渠道对该模型的服务 */
47
+ export declare function marketplaceDisableChannel(userId: string | undefined, accessToken: string | undefined, channelId: number, model: string): Promise<MarketplaceActionResult>;
48
+ /** POST /api/marketplace/channels/:id/restore?model= — 恢复被禁用的渠道 */
49
+ export declare function marketplaceRestoreChannel(userId: string | undefined, accessToken: string | undefined, channelId: number, model: string): Promise<MarketplaceActionResult>;
50
+ export {};
@@ -1,6 +1,45 @@
1
- import type { A6ApiModelMeta } from '../types.js';
2
- export declare const A6API_CATALOG: Record<string, A6ApiModelMeta>;
3
- /** Infer Brand from model name if not in catalog. */
1
+ import type { A6ApiModelMeta, CatalogModelEntry } from '../types.js';
2
+ export declare function catalogFile(): string;
3
+ export declare function getCatalog(): CatalogModelEntry[];
4
+ export declare function getCatalogEntry(id: string): CatalogModelEntry | undefined;
5
+ /** 合并新增条目(不覆盖已有条目的既有字段;仅补缺失字段,参数以用户已保存/查询到的为准)。
6
+ * undefined 字段不参与合并(避免覆盖已有值);按小写 id 去重(保留首个 casing,避免大小写幽灵重复)。 */
7
+ export declare function upsertCatalogEntries(entries: CatalogModelEntry[]): Promise<void>;
8
+ /** 清空目录(重新从 A6API 拉取/OpenRouter 填充前使用)。settings.yaml 已启用条目不受影响 */
9
+ export declare function clearCatalog(): Promise<void>;
10
+ /** 全量替换式更新单个条目(模型目录页保存修改用);patch 中值为 null 的字段 = 删除该字段。返回更新后的条目 */
11
+ export declare function updateCatalogEntry(id: string, patch: Partial<Omit<CatalogModelEntry, 'id'>>): Promise<CatalogModelEntry | null>;
12
+ /** 从 A6API 模型名推断品牌(目录无数据时的展示兜底,与旧行为一致) */
4
13
  export declare function inferBrand(modelId: string): string;
5
- /** Resolve metadata for any model ID, falling back to safe defaults. */
14
+ /**
15
+ * 默认推理档位:DSH llm-pi-ai 支持的全部思考档位(THINKING_LEVELS),
16
+ * wire 值取档位名本身(identity),`off` 无 wire 值(null = 发送时不带思考参数)。
17
+ * 新获取的市场模型默认声明全部档位,用户可自行修改。
18
+ */
19
+ export declare const DEFAULT_REASONING_EFFORTS: Record<string, string | null>;
20
+ /**
21
+ * 解析模型元信息(同步):目录数据优先,缺失时返回展示兜底值。
22
+ * 注意:写 settings.yaml 时不要用此函数的兜底值——缺字段应省略(见 buildA6apiBlock)。
23
+ */
6
24
  export declare function resolveModelMeta(modelId: string): A6ApiModelMeta;
25
+ /**
26
+ * 拉取 A6API 市场支持的全部模型 ID(含品牌)。
27
+ * 不排除任何模型(图像生成等一并收录,参数由 OpenRouter 查询决定能否填充)。
28
+ */
29
+ export declare function fetchMarketplaceModels(userId?: string, accessToken?: string): Promise<{
30
+ models: {
31
+ id: string;
32
+ brand?: string;
33
+ reasoningEfforts: Record<string, string | null>;
34
+ }[];
35
+ failedPages: number;
36
+ }>;
37
+ export interface OrQueryResult {
38
+ updated: CatalogModelEntry[];
39
+ notFound: string[];
40
+ }
41
+ /**
42
+ * 对一批模型 ID 查询 OpenRouter 并填充目录(能查到的填充,查不到的保持空参数字段)。
43
+ * 返回更新统计:updated 为本次填充/变更的条目,notFound 为查无的 ID。
44
+ */
45
+ export declare function queryOpenRouter(ids: string[]): Promise<OrQueryResult>;
@@ -4,6 +4,8 @@ export interface ProbeResult {
4
4
  success: boolean;
5
5
  channelId?: number;
6
6
  channelName?: string;
7
+ /** 该次请求实际使用的令牌 ID(用于固定/禁用按令牌绑定) */
8
+ tokenId?: number;
7
9
  merchant?: MerchantChannelInfo | null;
8
10
  error?: string;
9
11
  durationMs?: number;
@@ -1,14 +1,33 @@
1
1
  import type { A6ApiConfig } from '../types.js';
2
+ /**
3
+ * DSH 原生配置整合(消除插件独立配置文件 dsh-a6api-config.json):
4
+ * - 凭据(API Key / 系统访问令牌 / userId)→ ~/.dsh/.credentials.yaml(refs,0600)
5
+ * - 非机密状态(baseURL / 模型列表)→ ~/.dsh/settings.yaml 的 llm-pi-ai.providers.a6api 块
6
+ * - 读写优先走 DSH 原生缝 ctx.credentials / ctx.settings(env 优先语义、串行写队列、schema 校验、
7
+ * 热发布);原生服务缺失或写入失败时回退到直接读写两个文件(格式与 DSH 原生一致)。
8
+ * - 旧版独立配置文件在启动时自动迁移(只填空不覆盖)并归档为 dsh-a6api-config.json.bak。
9
+ */
2
10
  export declare const A6API_CRED_REF = "A6API_API_KEY";
3
- /** Read plugin dedicated config */
4
- export declare function readPluginConfig(): Promise<A6ApiConfig>;
5
- /** Save plugin dedicated config(密钥单一真相源在 ~/.dsh/.credentials.yaml,配置 JSON 不再冗余明文) */
6
- export declare function savePluginConfig(config: A6ApiConfig): Promise<void>;
11
+ export declare const A6API_TOKEN_REF = "A6API_ACCESS_TOKEN";
12
+ export declare const A6API_USER_REF = "A6API_USER_ID";
7
13
  /** Read a key from .credentials.yaml */
8
14
  export declare function readCredentialKey(refKey: string): Promise<string | null>;
9
- /** Write/update a key in .credentials.yaml */
15
+ /**
16
+ * Write/update a key in .credentials.yaml。
17
+ * DSH credentials-local 对空 ref 值整体拒收文档(parseRefs 抛错),因此
18
+ * 空串/undefined = 删除该键行(与原生 unset 语义一致),绝不写入空值。
19
+ */
10
20
  export declare function writeCredentialKey(refKey: string, value: string): Promise<void>;
11
- /** Sync active models to DSH settings.yaml under llm-pi-ai.providers.a6api */
12
- export declare function syncToDshSettings(baseURL: string, modelIds: string[]): Promise<void>;
13
- /** Get currently configured model IDs in DSH settings for a6api */
14
- export declare function getDshConfiguredModels(): Promise<string[]>;
21
+ export interface ConfigAccess {
22
+ /** 触发(并等待)旧配置文件的自动迁移;幂等,进程内只执行一次,失败不阻塞 */
23
+ ensureMigrated(): Promise<void>;
24
+ /** 读取当前配置:原生缝优先,逐级兜底到旧文件 */
25
+ readConfig(): Promise<A6ApiConfig>;
26
+ /** 写入凭据字段(空串 = 清除,走 unset);settings 同步请用 syncModels */
27
+ writeConfig(parts: Partial<Pick<A6ApiConfig, 'apiKey' | 'accessToken' | 'userId'>>): Promise<void>;
28
+ /** 把模型列表(与 baseURL)同步进 DSH settings.yaml 的 llm-pi-ai.providers.a6api 块 */
29
+ syncModels(baseURL: string, modelIds: string[]): Promise<void>;
30
+ /** 当前 DSH 已配置的 a6api 模型 ID 列表 */
31
+ getDshConfiguredModels(): Promise<string[]>;
32
+ }
33
+ export declare function createConfigAccess(ctx: any): ConfigAccess;
@@ -4,15 +4,44 @@ export interface A6ApiConfig {
4
4
  accessToken?: string;
5
5
  userId?: string;
6
6
  activeModels: string[];
7
- lastSelectedBaseUrl?: string;
8
- customBaseURL?: string;
9
- /** backward compatibility */
10
- sessionCookie?: string;
11
7
  /** 服务端脱敏下发:是否已配置 API Key(真实密钥绝不回传客户端) */
12
8
  hasApiKey?: boolean;
13
9
  /** 服务端脱敏下发:是否已配置系统访问令牌 */
14
10
  hasToken?: boolean;
15
11
  }
12
+ /**
13
+ * 模型目录条目(settings.yaml 的 llm-pi-ai 原生模型字段 + 内部 brand)。
14
+ * 可选字段缺省 = 参数未获取/未填写,写 settings.yaml 时省略该字段(llm-pi-ai 默认值兜底)。
15
+ */
16
+ export interface CatalogModelEntry {
17
+ id: string;
18
+ name?: string;
19
+ contextWindow?: number;
20
+ maxTokens?: number;
21
+ input?: ('text' | 'image')[];
22
+ /** false = 明确非推理模型;dict = 档位 → wire 值(值可为 null,同 llm-pi-ai 语义) */
23
+ reasoningEfforts?: Record<string, string | null> | false;
24
+ /** 仅插件内部使用:品牌来自 A6API 市场渠道,不写入 settings.yaml */
25
+ brand?: string;
26
+ /** 最近一次 OpenRouter 查询/人工修改时间 */
27
+ updatedAt?: number;
28
+ }
29
+ /** DSH llm-pi-ai 支持的完整思考档位(THINKING_LEVELS,与 dsh-llm-pi-ai 源码一致) */
30
+ export declare const THINKING_LEVEL_KEYS: readonly ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
31
+ export type ReasoningEffortsValue = Record<string, string | null> | false;
32
+ /**
33
+ * 校验 reasoningEfforts(DSH llm-pi-ai 语义,服务端与客户端共用):
34
+ * - false = 非推理模型,合法
35
+ * - 键必须 ∈ THINKING_LEVEL_KEYS;值必须非空字符串,仅 off 允许 null
36
+ * - 空字典、仅 off 无其他档位均非法
37
+ */
38
+ export declare function validateReasoningEfforts(value: unknown): {
39
+ ok: true;
40
+ value: ReasoningEffortsValue;
41
+ } | {
42
+ ok: false;
43
+ error: string;
44
+ };
16
45
  export interface A6ApiModelMeta {
17
46
  id: string;
18
47
  name: string;
@@ -103,10 +132,35 @@ export interface MerchantChannelInfo {
103
132
  authenticity_guaranteed: boolean;
104
133
  authenticity_badge?: string;
105
134
  is_pinned?: boolean;
135
+ /** 官方渠道搜索返回的固定状态:pin_here / pin_elsewhere / undefined */
136
+ pin_status?: string;
106
137
  user_channel_disabled?: boolean;
107
138
  supplier_channel_disabled?: boolean;
108
139
  raw?: any;
109
140
  }
141
+ /** 平台侧固定记录(GET /api/marketplace/pins) */
142
+ export interface MarketplacePin {
143
+ id?: number;
144
+ token_id: number;
145
+ token_name?: string;
146
+ model_name: string;
147
+ channel_id?: number;
148
+ channel_name?: string;
149
+ supplier_name?: string;
150
+ supplier_nickname?: string;
151
+ /** 异常时是否自动切换智能优选(false = 严格固定) */
152
+ fallback_to_smart_routing?: boolean;
153
+ created_at?: number;
154
+ raw?: any;
155
+ }
156
+ /** 令牌列表条目(GET /api/token/,用于把 API Key 解析为 token_id) */
157
+ export interface A6ApiTokenItem {
158
+ id: number;
159
+ name?: string;
160
+ key?: string;
161
+ status?: number;
162
+ raw?: any;
163
+ }
110
164
  export interface ModelCardData {
111
165
  model_name: string;
112
166
  brand: string;
@@ -116,7 +170,7 @@ export interface ModelCardData {
116
170
  hasReasoning: boolean;
117
171
  inDsh: boolean;
118
172
  merchant?: MerchantChannelInfo;
119
- probeStatus: 'idle' | 'probing' | 'success' | 'error';
173
+ probeStatus: 'idle' | 'queued' | 'probing' | 'success' | 'error';
120
174
  probeError?: string;
121
175
  probeLatencyMs?: number;
122
176
  lastProbedAt?: number;
@@ -124,6 +178,14 @@ export interface ModelCardData {
124
178
  lastRoutedAt?: number;
125
179
  /** 服务端算好的相对时间文案(如「3 小时前」),无记录时客户端显示「从未路由」 */
126
180
  lastRoutedText?: string;
181
+ /** 平台固定状态(按当前 API Key 令牌):固定到卡片商家 / 固定到其他商家 / 未固定 */
182
+ pinStatus?: 'pin_here' | 'pin_elsewhere';
183
+ /** 固定的渠道 ID(pin_elsewhere 时用于展示固定到了哪家) */
184
+ pinnedChannelId?: number;
185
+ pinnedSupplierName?: string;
186
+ pinnedFallback?: boolean;
187
+ /** 该模型对应的固定记录是否属于当前 API Key 令牌(false 时仅作参考展示) */
188
+ pinTokenMatched?: boolean;
127
189
  }
128
190
  export interface BalanceInfo {
129
191
  hasAccountAuth: boolean;
@@ -144,6 +206,8 @@ export interface ApiRoutingLogItem {
144
206
  model_name: string;
145
207
  channel?: number | string;
146
208
  channel_name?: string;
209
+ /** 发起该请求的令牌 ID(用于把 API Key 解析为固定/禁用所需的 token_id) */
210
+ token_id?: number;
147
211
  prompt_tokens?: number;
148
212
  completion_tokens?: number;
149
213
  use_time?: number;
@@ -161,6 +225,8 @@ export interface A6ApiStateResponse {
161
225
  models: ModelCardData[];
162
226
  dshConfiguredModels: string[];
163
227
  recentLogs?: ApiRoutingLogItem[];
228
+ /** 平台固定记录列表(用于卡片状态跟随官网) */
229
+ pins?: MarketplacePin[];
164
230
  }
165
231
  export interface PriceFluctuationState {
166
232
  pendingCount: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynn123411/dsh-a6api",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "A6API 多模型聚合站接入插件:原生 LLM 提供商注册、账户实时余额与价格波动监控、Token 白名单同步、商户线路探测与全景指标卡片",
5
5
  "license": "MIT",
6
6
  "author": "lynn123411",