@waterwx/dsh-novel-forge 1.8.0 → 1.9.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/src/routes.ts CHANGED
@@ -22,6 +22,13 @@ import {
22
22
  NOVEL_API,
23
23
  type AssetsPatch,
24
24
  type AssetsResponse,
25
+ type AddModelRequest,
26
+ type AddModelResponse,
27
+ type LlmModelsResponse,
28
+ type LlmProvidersResponse,
29
+ type LlmVendorsResponse,
30
+ type RemoveProviderRequest,
31
+ type RemoveProviderResponse,
25
32
  type AssistantFrame,
26
33
  type AssistantHistoryResponse,
27
34
  type AssistantRequest,
@@ -101,6 +108,8 @@ import {
101
108
  type StoryboardPromptsRequest,
102
109
  type ImageTestRequest,
103
110
  type ImageTestResponse,
111
+ type LlmTestRequest,
112
+ type LlmTestResponse,
104
113
  type StoryboardPromptsResponse,
105
114
  type StyleEngineRequest,
106
115
  type SummaryRequest,
@@ -170,6 +179,12 @@ import {
170
179
  generateRoleReferenceImage,
171
180
  generateMangaRoleReferenceImage,
172
181
  testImageEndpoint,
182
+ testLlmModel,
183
+ registerLlmModel,
184
+ listLlmVendors,
185
+ listLlmModels,
186
+ listLlmProviders,
187
+ removeLlmProvider,
173
188
  generateStoryboardSkeleton,
174
189
  generateStoryboardTable,
175
190
  generateStoryboardPrompts,
@@ -2438,6 +2453,117 @@ export function makeRoutes(deps: NovelRoutesDeps): WebRoute[] {
2438
2453
  },
2439
2454
  }
2440
2455
 
2456
+ // ------------------------------------------------------------- llm-test
2457
+ /** LLM 连通性测试:对选中的提供商/模型发一次最小真实调用。 */
2458
+ const llmTestRoute: WebRoute = {
2459
+ kind: 'exact',
2460
+ path: NOVEL_API.llmTest,
2461
+ handler: async (req, res) => {
2462
+ if (!guard(req, res, 'POST')) return
2463
+ const body = await readJsonBody<LlmTestRequest>(req)
2464
+ const provider = (body?.provider ?? '').trim()
2465
+ const model = (body?.model ?? '').trim()
2466
+ if (provider === '' || model === '') {
2467
+ writeJson(res, 400, { error: 'provider 与 model 必填' })
2468
+ return
2469
+ }
2470
+ const result = await testLlmModel(ctx, provider, model)
2471
+ writeJson(res, 200, result satisfies LlmTestResponse)
2472
+ },
2473
+ }
2474
+
2475
+ // ------------------------------------------------------------- llm-add
2476
+ /** 添加模型:厂商直填 API Key,或自定义 OpenAI 兼容路由(写 DSH 凭据 + router)。 */
2477
+ const addModelRoute: WebRoute = {
2478
+ kind: 'exact',
2479
+ path: NOVEL_API.addModel,
2480
+ handler: async (req, res) => {
2481
+ if (!guard(req, res, 'POST')) return
2482
+ const body = await readJsonBody<AddModelRequest>(req)
2483
+ if (body === undefined) {
2484
+ writeJson(res, 400, { error: '缺少请求体' })
2485
+ return
2486
+ }
2487
+ try {
2488
+ const result = await registerLlmModel(ctx, body)
2489
+ writeJson(res, 200, result satisfies AddModelResponse)
2490
+ } catch (error) {
2491
+ writeJson(res, 500, { error: `添加模型失败:${(error as Error).message}` })
2492
+ }
2493
+ },
2494
+ }
2495
+
2496
+ // ---------------------------------------------------------- llm-vendors
2497
+ /** 运行时厂商目录(DSH pi-ai 可配置提供方 + 内置适配器)。 */
2498
+ const llmVendorsRoute: WebRoute = {
2499
+ kind: 'exact',
2500
+ path: NOVEL_API.llmVendors,
2501
+ handler: async (req, res) => {
2502
+ if (!guard(req, res, 'GET')) return
2503
+ try {
2504
+ const result = await listLlmVendors(ctx)
2505
+ writeJson(res, 200, result satisfies LlmVendorsResponse)
2506
+ } catch (error) {
2507
+ writeJson(res, 500, { error: `读取厂商目录失败:${(error as Error).message}` })
2508
+ }
2509
+ },
2510
+ }
2511
+
2512
+ // ---------------------------------------------------------- llm-models
2513
+ /** 查询某个 provider 当前可用的模型(添加成功后可即时刷新下拉)。 */
2514
+ const llmModelsRoute: WebRoute = {
2515
+ kind: 'exact',
2516
+ path: NOVEL_API.llmModels,
2517
+ handler: async (req, res) => {
2518
+ if (!guard(req, res, 'GET')) return
2519
+ const url = new URL(req.url ?? '', 'http://localhost')
2520
+ const provider = decodeURIComponent((url.searchParams.get('provider') ?? '').trim())
2521
+ try {
2522
+ const result = await listLlmModels(ctx, provider)
2523
+ writeJson(res, 200, result satisfies LlmModelsResponse)
2524
+ } catch (error) {
2525
+ writeJson(res, 500, { error: `读取模型列表失败:${(error as Error).message}` })
2526
+ }
2527
+ },
2528
+ }
2529
+
2530
+ // ---------------------------------------------------------- llm-providers
2531
+ /** 已注册的提供方路由列表(提供方管理卡片)。 */
2532
+ const llmProvidersRoute: WebRoute = {
2533
+ kind: 'exact',
2534
+ path: NOVEL_API.llmProviders,
2535
+ handler: async (req, res) => {
2536
+ if (!guard(req, res, 'GET')) return
2537
+ try {
2538
+ const result = await listLlmProviders(ctx)
2539
+ writeJson(res, 200, result satisfies LlmProvidersResponse)
2540
+ } catch (error) {
2541
+ writeJson(res, 500, { error: `读取提供方列表失败:${(error as Error).message}` })
2542
+ }
2543
+ },
2544
+ }
2545
+
2546
+ // ------------------------------------------------------------- llm-remove
2547
+ /** 移除一个提供方(unset key + 移除 llm-pi-ai 路由)。 */
2548
+ const llmRemoveRoute: WebRoute = {
2549
+ kind: 'exact',
2550
+ path: NOVEL_API.llmRemove,
2551
+ handler: async (req, res) => {
2552
+ if (!guard(req, res, 'POST')) return
2553
+ const body = await readJsonBody<RemoveProviderRequest>(req)
2554
+ if (body === undefined) {
2555
+ writeJson(res, 400, { error: '缺少请求体' })
2556
+ return
2557
+ }
2558
+ try {
2559
+ const result = await removeLlmProvider(ctx, body)
2560
+ writeJson(res, 200, result satisfies RemoveProviderResponse)
2561
+ } catch (error) {
2562
+ writeJson(res, 500, { error: `移除提供方失败:${(error as Error).message}` })
2563
+ }
2564
+ },
2565
+ }
2566
+
2441
2567
  // ---------------------------------------------------- storyboard table
2442
2568
  /** 分镜·导演级:骨架 → 分镜表(镜头级)。 */
2443
2569
  const storyboardTableRoute: WebRoute = {
@@ -2992,6 +3118,12 @@ export function makeRoutes(deps: NovelRoutesDeps): WebRoute[] {
2992
3118
  styleImageRoute,
2993
3119
  storyboardSkeletonRoute,
2994
3120
  imageTestRoute,
3121
+ llmTestRoute,
3122
+ addModelRoute,
3123
+ llmVendorsRoute,
3124
+ llmModelsRoute,
3125
+ llmProvidersRoute,
3126
+ llmRemoveRoute,
2995
3127
  storyboardTableRoute,
2996
3128
  storyboardPromptsRoute,
2997
3129
  breakdownRoute,