@musnows/scriverse 1.0.1 → 1.0.3

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/dist/app.js CHANGED
@@ -504,6 +504,7 @@ const modelSchema = z.object({
504
504
  });
505
505
  const aiPromptSchema = z.object({
506
506
  systemPrompt: z.string().max(100_000).optional(),
507
+ systemPromptOverride: z.boolean().optional(),
507
508
  imageToolModelId: identifier.nullable().optional(),
508
509
  streamIdleTimeoutSeconds: z.number().int().min(MIN_AI_STREAM_IDLE_TIMEOUT_SECONDS).max(MAX_AI_STREAM_IDLE_TIMEOUT_SECONDS).optional()
509
510
  });
@@ -639,6 +640,7 @@ const aiProcessStepSchema = z.discriminatedUnion("type", [
639
640
  ]);
640
641
  const workAiSettingsSchema = z.object({
641
642
  systemPrompt: z.string().max(100_000).optional(),
643
+ systemPromptOverride: z.boolean().optional(),
642
644
  dailyTokenQuota: z.number().int().min(1, "Token 额度必须设置大于 0").max(2_000_000_000).nullable().optional(),
643
645
  monthlyTokenQuota: z.number().int().min(1, "Token 额度必须设置大于 0").max(2_000_000_000).nullable().optional(),
644
646
  autoRunEnabled: z.boolean().optional(),
@@ -3566,7 +3568,7 @@ export function createRuntime(options) {
3566
3568
  app.get("/api/works/:workId/ai/questions/:questionId", (request, response) => {
3567
3569
  data(response, aiWritePlanManager.getQuestion(request.params.questionId, request.params.workId, planViewer()));
3568
3570
  });
3569
- const resumeQuestionWorkflow = async (questionId, workId, viewer) => {
3571
+ const resumeQuestionWorkflow = async (questionId, workId, viewer, stream = {}) => {
3570
3572
  const continuation = aiWritePlanManager.claimQuestionContinuation(questionId, workId, viewer);
3571
3573
  if (!continuation)
3572
3574
  return;
@@ -3597,26 +3599,88 @@ export function createRuntime(options) {
3597
3599
  : {}),
3598
3600
  ...(typeof continuation.round === "number" ? { round: continuation.round } : {}),
3599
3601
  ...(Array.isArray(continuation.toolMessages) ? { toolMessages: continuation.toolMessages } : {})
3600
- });
3602
+ }, stream);
3601
3603
  aiWritePlanManager.finishQuestionContinuation(questionId, { callId: resumed.callId ?? null, completed: true });
3604
+ return resumed;
3602
3605
  }
3603
3606
  catch (error) {
3604
3607
  aiWritePlanManager.finishQuestionContinuation(questionId, { message: error instanceof Error ? error.message : "恢复失败" }, true);
3605
3608
  throw error;
3606
3609
  }
3607
3610
  };
3611
+ const respondWithQuestionContinuation = async (request, response, viewer) => {
3612
+ const { questionId, workId } = request.params;
3613
+ if (!request.get("Accept")?.includes("text/event-stream")) {
3614
+ await resumeQuestionWorkflow(questionId, workId, viewer);
3615
+ data(response, aiWritePlanManager.getQuestion(questionId, workId, viewer));
3616
+ return;
3617
+ }
3618
+ const controller = new AbortController();
3619
+ response.status(200);
3620
+ response.setHeader("Content-Type", "text/event-stream; charset=utf-8");
3621
+ response.setHeader("Cache-Control", "no-cache, no-transform");
3622
+ response.setHeader("Connection", "keep-alive");
3623
+ response.setHeader("X-Accel-Buffering", "no");
3624
+ response.flushHeaders();
3625
+ const sendEvent = (event, payload) => {
3626
+ if (!response.writableEnded && !response.destroyed)
3627
+ response.write(`event: ${event}\ndata: ${JSON.stringify(payload)}\n\n`);
3628
+ };
3629
+ const heartbeat = setInterval(() => {
3630
+ if (!response.writableEnded && !response.destroyed)
3631
+ response.write(": heartbeat\n\n");
3632
+ }, aiStreamHeartbeatIntervalMs);
3633
+ heartbeat.unref();
3634
+ response.on("close", () => {
3635
+ clearInterval(heartbeat);
3636
+ if (!response.writableEnded)
3637
+ controller.abort(new Error("浏览器已中断流式请求"));
3638
+ });
3639
+ try {
3640
+ const resumed = await resumeQuestionWorkflow(questionId, workId, viewer, {
3641
+ signal: controller.signal,
3642
+ onStart: (message) => sendEvent("continuation", message),
3643
+ onDelta: (delta) => sendEvent("delta", { delta }),
3644
+ onToolCall: (toolCall, round) => sendEvent("tool_call", { ...toolCall, round }),
3645
+ onProcessStep: (step) => sendEvent("process_step", step),
3646
+ onContextCompacted: (event) => sendEvent("context_compacted", event)
3647
+ });
3648
+ const message = resumed?.conversationMessage;
3649
+ const metadata = message?.metadata;
3650
+ sendEvent("complete", {
3651
+ warningOnly: !resumed,
3652
+ model: resumed?.model,
3653
+ outputTokens: metadata?.outputTokens ?? resumed?.outputTokens,
3654
+ cacheHitPercent: metadata?.cacheHitPercent ?? resumed?.cacheHitPercent,
3655
+ processDurationMs: metadata?.processDurationMs ?? resumed?.processDurationMs,
3656
+ toolCalls: metadata?.toolCalls ?? resumed?.toolCalls,
3657
+ processSteps: metadata?.processSteps ?? resumed?.processSteps,
3658
+ contextUsage: resumed?.contextUsage,
3659
+ messageId: message?.id,
3660
+ messageCreatedAt: message?.createdAt,
3661
+ question: aiWritePlanManager.getQuestion(questionId, workId, viewer)
3662
+ });
3663
+ }
3664
+ catch (error) {
3665
+ if (!controller.signal.aborted)
3666
+ sendEvent("error", publicAiStreamError(error));
3667
+ }
3668
+ finally {
3669
+ clearInterval(heartbeat);
3670
+ if (!response.writableEnded && !response.destroyed)
3671
+ response.end();
3672
+ }
3673
+ };
3608
3674
  app.post("/api/works/:workId/ai/questions/:questionId/answer", async (request, response) => {
3609
3675
  const input = parse(answerAiUserQuestionSchema, request.body ?? {});
3610
3676
  const viewer = planViewer();
3611
3677
  aiWritePlanManager.answerQuestion(request.params.questionId, request.params.workId, viewer, input);
3612
- await resumeQuestionWorkflow(request.params.questionId, request.params.workId, viewer);
3613
- data(response, aiWritePlanManager.getQuestion(request.params.questionId, request.params.workId, viewer));
3678
+ await respondWithQuestionContinuation(request, response, viewer);
3614
3679
  });
3615
3680
  app.post("/api/works/:workId/ai/questions/:questionId/reject", async (request, response) => {
3616
3681
  const viewer = planViewer();
3617
3682
  aiWritePlanManager.rejectQuestion(request.params.questionId, request.params.workId, viewer);
3618
- await resumeQuestionWorkflow(request.params.questionId, request.params.workId, viewer);
3619
- data(response, aiWritePlanManager.getQuestion(request.params.questionId, request.params.workId, viewer));
3683
+ await respondWithQuestionContinuation(request, response, viewer);
3620
3684
  });
3621
3685
  app.get("/api/works/:workId/providers", (request, response) => {
3622
3686
  store.getWork(request.params.workId);