@actalk/inkos-core 1.6.3 → 1.7.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.
Files changed (163) hide show
  1. package/dist/agent/agent-session.d.ts.map +1 -1
  2. package/dist/agent/agent-session.js +21 -11
  3. package/dist/agent/agent-session.js.map +1 -1
  4. package/dist/agent/agent-system-prompt.d.ts.map +1 -1
  5. package/dist/agent/agent-system-prompt.js +14 -8
  6. package/dist/agent/agent-system-prompt.js.map +1 -1
  7. package/dist/agent/agent-tools.d.ts +34 -2
  8. package/dist/agent/agent-tools.d.ts.map +1 -1
  9. package/dist/agent/agent-tools.js +236 -54
  10. package/dist/agent/agent-tools.js.map +1 -1
  11. package/dist/agent/chapter-import-source.d.ts +15 -0
  12. package/dist/agent/chapter-import-source.d.ts.map +1 -0
  13. package/dist/agent/chapter-import-source.js +41 -0
  14. package/dist/agent/chapter-import-source.js.map +1 -0
  15. package/dist/agent/film-authoring-tools.d.ts +5 -3
  16. package/dist/agent/film-authoring-tools.d.ts.map +1 -1
  17. package/dist/agent/film-authoring-tools.js +34 -19
  18. package/dist/agent/film-authoring-tools.js.map +1 -1
  19. package/dist/agent/index.d.ts +1 -1
  20. package/dist/agent/index.d.ts.map +1 -1
  21. package/dist/agent/index.js +1 -1
  22. package/dist/agent/index.js.map +1 -1
  23. package/dist/agents/base.d.ts +1 -0
  24. package/dist/agents/base.d.ts.map +1 -1
  25. package/dist/agents/base.js +2 -0
  26. package/dist/agents/base.js.map +1 -1
  27. package/dist/agents/script-storyboard.d.ts +3 -0
  28. package/dist/agents/script-storyboard.d.ts.map +1 -1
  29. package/dist/agents/script-storyboard.js +221 -14
  30. package/dist/agents/script-storyboard.js.map +1 -1
  31. package/dist/agents/short-fiction.d.ts +13 -2
  32. package/dist/agents/short-fiction.d.ts.map +1 -1
  33. package/dist/agents/short-fiction.js +77 -43
  34. package/dist/agents/short-fiction.js.map +1 -1
  35. package/dist/index.d.ts +8 -5
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +10 -8
  38. package/dist/index.js.map +1 -1
  39. package/dist/interaction/action-envelope.d.ts +53 -1
  40. package/dist/interaction/action-envelope.d.ts.map +1 -1
  41. package/dist/interaction/action-envelope.js +9 -0
  42. package/dist/interaction/action-envelope.js.map +1 -1
  43. package/dist/interaction/intents.d.ts +2 -2
  44. package/dist/interaction/project-control.d.ts +1 -1
  45. package/dist/interactive-film/generate.d.ts +1 -0
  46. package/dist/interactive-film/generate.d.ts.map +1 -1
  47. package/dist/interactive-film/generate.js +15 -5
  48. package/dist/interactive-film/generate.js.map +1 -1
  49. package/dist/llm/provider.d.ts +1 -0
  50. package/dist/llm/provider.d.ts.map +1 -1
  51. package/dist/llm/provider.js +64 -18
  52. package/dist/llm/provider.js.map +1 -1
  53. package/dist/llm/providers/endpoints/openrouter.d.ts.map +1 -1
  54. package/dist/llm/providers/endpoints/openrouter.js +3 -2
  55. package/dist/llm/providers/endpoints/openrouter.js.map +1 -1
  56. package/dist/llm/think-tag-stripper.d.ts +15 -0
  57. package/dist/llm/think-tag-stripper.d.ts.map +1 -0
  58. package/dist/llm/think-tag-stripper.js +60 -0
  59. package/dist/llm/think-tag-stripper.js.map +1 -0
  60. package/dist/materials/ingest.d.ts.map +1 -1
  61. package/dist/materials/ingest.js +4 -3
  62. package/dist/materials/ingest.js.map +1 -1
  63. package/dist/materials/retrieve.d.ts.map +1 -1
  64. package/dist/materials/retrieve.js +3 -1
  65. package/dist/materials/retrieve.js.map +1 -1
  66. package/dist/models/book.d.ts +28 -0
  67. package/dist/models/book.d.ts.map +1 -1
  68. package/dist/models/book.js +22 -0
  69. package/dist/models/book.js.map +1 -1
  70. package/dist/models/project.d.ts +40 -0
  71. package/dist/models/project.d.ts.map +1 -1
  72. package/dist/models/project.js +5 -0
  73. package/dist/models/project.js.map +1 -1
  74. package/dist/notify/dispatcher.d.ts.map +1 -1
  75. package/dist/notify/dispatcher.js +8 -5
  76. package/dist/notify/dispatcher.js.map +1 -1
  77. package/dist/notify/feishu.d.ts +2 -1
  78. package/dist/notify/feishu.d.ts.map +1 -1
  79. package/dist/notify/feishu.js +12 -6
  80. package/dist/notify/feishu.js.map +1 -1
  81. package/dist/notify/format.d.ts +12 -0
  82. package/dist/notify/format.d.ts.map +1 -0
  83. package/dist/notify/format.js +11 -0
  84. package/dist/notify/format.js.map +1 -0
  85. package/dist/notify/telegram.d.ts +2 -1
  86. package/dist/notify/telegram.d.ts.map +1 -1
  87. package/dist/notify/telegram.js +3 -2
  88. package/dist/notify/telegram.js.map +1 -1
  89. package/dist/notify/wechat-work.d.ts +2 -1
  90. package/dist/notify/wechat-work.d.ts.map +1 -1
  91. package/dist/notify/wechat-work.js +5 -5
  92. package/dist/notify/wechat-work.js.map +1 -1
  93. package/dist/pipeline/runner.d.ts +13 -1
  94. package/dist/pipeline/runner.d.ts.map +1 -1
  95. package/dist/pipeline/runner.js +41 -7
  96. package/dist/pipeline/runner.js.map +1 -1
  97. package/dist/pipeline/script-storyboard-runner.d.ts +3 -0
  98. package/dist/pipeline/script-storyboard-runner.d.ts.map +1 -1
  99. package/dist/pipeline/script-storyboard-runner.js +86 -43
  100. package/dist/pipeline/script-storyboard-runner.js.map +1 -1
  101. package/dist/pipeline/short-fiction-runner.d.ts +3 -1
  102. package/dist/pipeline/short-fiction-runner.d.ts.map +1 -1
  103. package/dist/pipeline/short-fiction-runner.js +80 -33
  104. package/dist/pipeline/short-fiction-runner.js.map +1 -1
  105. package/dist/play/play-runner.d.ts +8 -0
  106. package/dist/play/play-runner.d.ts.map +1 -1
  107. package/dist/play/play-runner.js +14 -0
  108. package/dist/play/play-runner.js.map +1 -1
  109. package/dist/prompts/short-fiction.d.ts +14 -13
  110. package/dist/prompts/short-fiction.d.ts.map +1 -1
  111. package/dist/prompts/short-fiction.js +253 -14
  112. package/dist/prompts/short-fiction.js.map +1 -1
  113. package/dist/state/manager.d.ts +16 -2
  114. package/dist/state/manager.d.ts.map +1 -1
  115. package/dist/state/manager.js +218 -31
  116. package/dist/state/manager.js.map +1 -1
  117. package/dist/translation/epub.d.ts +10 -0
  118. package/dist/translation/epub.d.ts.map +1 -0
  119. package/dist/translation/epub.js +86 -0
  120. package/dist/translation/epub.js.map +1 -0
  121. package/dist/translation/export.d.ts +6 -0
  122. package/dist/translation/export.d.ts.map +1 -0
  123. package/dist/translation/export.js +68 -0
  124. package/dist/translation/export.js.map +1 -0
  125. package/dist/translation/index.d.ts +9 -0
  126. package/dist/translation/index.d.ts.map +1 -0
  127. package/dist/translation/index.js +9 -0
  128. package/dist/translation/index.js.map +1 -0
  129. package/dist/translation/llm-model.d.ts +8 -0
  130. package/dist/translation/llm-model.d.ts.map +1 -0
  131. package/dist/translation/llm-model.js +134 -0
  132. package/dist/translation/llm-model.js.map +1 -0
  133. package/dist/translation/project.d.ts +3 -0
  134. package/dist/translation/project.d.ts.map +1 -0
  135. package/dist/translation/project.js +76 -0
  136. package/dist/translation/project.js.map +1 -0
  137. package/dist/translation/run-store.d.ts +11 -0
  138. package/dist/translation/run-store.d.ts.map +1 -0
  139. package/dist/translation/run-store.js +53 -0
  140. package/dist/translation/run-store.js.map +1 -0
  141. package/dist/translation/runner.d.ts +6 -0
  142. package/dist/translation/runner.d.ts.map +1 -0
  143. package/dist/translation/runner.js +88 -0
  144. package/dist/translation/runner.js.map +1 -0
  145. package/dist/translation/source.d.ts +12 -0
  146. package/dist/translation/source.d.ts.map +1 -0
  147. package/dist/translation/source.js +66 -0
  148. package/dist/translation/source.js.map +1 -0
  149. package/dist/translation/text.d.ts +10 -0
  150. package/dist/translation/text.d.ts.map +1 -0
  151. package/dist/translation/text.js +77 -0
  152. package/dist/translation/text.js.map +1 -0
  153. package/dist/translation/types.d.ts +96 -0
  154. package/dist/translation/types.d.ts.map +1 -0
  155. package/dist/translation/types.js +2 -0
  156. package/dist/translation/types.js.map +1 -0
  157. package/dist/utils/effective-llm-config.js +19 -1
  158. package/dist/utils/effective-llm-config.js.map +1 -1
  159. package/dist/utils/posix-path.d.ts +2 -0
  160. package/dist/utils/posix-path.d.ts.map +1 -0
  161. package/dist/utils/posix-path.js +7 -0
  162. package/dist/utils/posix-path.js.map +1 -0
  163. package/package.json +4 -3
@@ -1,3 +1,4 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
1
2
  import { chatCompletion, createLLMClient } from "../llm/provider.js";
2
3
  import { ArchitectAgent } from "../agents/architect.js";
3
4
  import { FoundationReviewerAgent } from "../agents/foundation-reviewer.js";
@@ -174,15 +175,35 @@ export function buildImportFoundationSource(chapters, language, options = {}) {
174
175
  anchorText,
175
176
  ].join("\n");
176
177
  }
178
+ /** Human-readable description of each manual-revision gate, surfaced in revisionDiagnostics. */
179
+ const REVISION_GATE_STANDARDS = {
180
+ strict: "A revision is applied only when blocking, critical, and AI-tell counts do not worsen, and at least blocking or AI-tell issues improve.",
181
+ lenient: "A revision is applied whenever blocking, critical, and AI-tell counts do not worsen; no improvement is required (lenient gate).",
182
+ always: "Manual revisions are always applied; audit counts are recorded for reference only (always gate).",
183
+ };
177
184
  export class PipelineRunner {
178
185
  state;
179
186
  config;
180
187
  agentClients = new Map();
188
+ operationContext = new AsyncLocalStorage();
181
189
  memoryIndexFallbackWarned = false;
182
190
  constructor(config) {
183
191
  this.config = config;
184
192
  this.state = new StateManager(config.projectRoot);
185
193
  }
194
+ async runWithAbortSignal(signal, task) {
195
+ signal?.throwIfAborted();
196
+ return this.operationContext.run({ signal }, async () => {
197
+ signal?.throwIfAborted();
198
+ return task();
199
+ });
200
+ }
201
+ currentAbortSignal() {
202
+ return this.operationContext.getStore()?.signal;
203
+ }
204
+ throwIfOperationAborted() {
205
+ this.currentAbortSignal()?.throwIfAborted();
206
+ }
186
207
  localize(language, messages) {
187
208
  return language === "en" ? messages.en : messages.zh;
188
209
  }
@@ -361,6 +382,7 @@ export class PipelineRunner {
361
382
  bookId,
362
383
  logger: this.config.logger?.child(agent),
363
384
  onStreamProgress: this.config.onStreamProgress,
385
+ signal: this.currentAbortSignal(),
364
386
  };
365
387
  }
366
388
  createAgentContext(agent, bookId) {
@@ -991,10 +1013,13 @@ export class PipelineRunner {
991
1013
  const blockingDidNotWorsen = effectivePostRevision.blockingCount <= preRevision.blockingCount;
992
1014
  const criticalDidNotWorsen = effectivePostRevision.criticalCount <= preRevision.criticalCount;
993
1015
  const aiDidNotWorsen = effectivePostRevision.aiTellCount <= preRevision.aiTellCount;
994
- const shouldApplyRevision = blockingDidNotWorsen
995
- && criticalDidNotWorsen
996
- && aiDidNotWorsen
997
- && (improvedBlocking || improvedAITells);
1016
+ const didNotWorsen = blockingDidNotWorsen && criticalDidNotWorsen && aiDidNotWorsen;
1017
+ const revisionGate = this.config.revisionGate ?? "strict";
1018
+ const shouldApplyRevision = revisionGate === "always"
1019
+ ? true
1020
+ : revisionGate === "lenient"
1021
+ ? didNotWorsen
1022
+ : didNotWorsen && (improvedBlocking || improvedAITells);
998
1023
  if (!shouldApplyRevision) {
999
1024
  const remainingIssues = effectivePostRevision.revisionBlockingIssues
1000
1025
  .filter((issue) => issue.severity === "warning" || issue.severity === "critical")
@@ -1013,7 +1038,7 @@ export class PipelineRunner {
1013
1038
  status: "unchanged",
1014
1039
  skippedReason: `Manual revision kept original chapter: before blocking=${preRevision.blockingCount}, critical=${preRevision.criticalCount}, aiTell=${preRevision.aiTellCount}; after blocking=${effectivePostRevision.blockingCount}, critical=${effectivePostRevision.criticalCount}, aiTell=${effectivePostRevision.aiTellCount}.`,
1015
1040
  revisionDiagnostics: {
1016
- standard: "A revision is applied only when blocking, critical, and AI-tell counts do not worsen, and at least blocking or AI-tell issues improve.",
1041
+ standard: REVISION_GATE_STANDARDS[revisionGate],
1017
1042
  before: {
1018
1043
  blockingCount: preRevision.blockingCount,
1019
1044
  criticalCount: preRevision.criticalCount,
@@ -1157,6 +1182,7 @@ export class PipelineRunner {
1157
1182
  // Full pipeline (convenience — runs draft + audit + revise in one shot)
1158
1183
  // ---------------------------------------------------------------------------
1159
1184
  async writeNextChapter(bookId, wordCount, temperatureOverride) {
1185
+ this.throwIfOperationAborted();
1160
1186
  const releaseLock = await this.state.acquireBookLock(bookId);
1161
1187
  try {
1162
1188
  return await this._writeNextChapterLocked(bookId, wordCount, temperatureOverride, this.config.externalContext);
@@ -1184,6 +1210,7 @@ export class PipelineRunner {
1184
1210
  }
1185
1211
  }
1186
1212
  async _writeNextChapterLocked(bookId, wordCount, temperatureOverride, externalContext) {
1213
+ this.throwIfOperationAborted();
1187
1214
  await this.state.ensureControlDocuments(bookId);
1188
1215
  const book = await this.state.loadBookConfig(bookId);
1189
1216
  const bookDir = this.state.bookDir(bookId);
@@ -1220,6 +1247,7 @@ export class PipelineRunner {
1220
1247
  ...(wordCount ? { wordCountOverride: wordCount } : {}),
1221
1248
  ...(temperatureOverride ? { temperatureOverride } : {}),
1222
1249
  });
1250
+ this.throwIfOperationAborted();
1223
1251
  const writerCount = countChapterLength(output.content, lengthSpec.countingMode);
1224
1252
  // Token usage accumulator
1225
1253
  let totalUsage = output.tokenUsage ?? { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
@@ -1303,6 +1331,7 @@ export class PipelineRunner {
1303
1331
  normalizeApplied = reviewResult.normalizeApplied;
1304
1332
  preAuditNormalizedWordCount = reviewResult.preAuditNormalizedWordCount;
1305
1333
  }
1334
+ this.throwIfOperationAborted();
1306
1335
  // 3b. Lightweight per-chapter promotion pass — check if any hooks should
1307
1336
  // be promoted based on advanced_count derived from chapter_summaries.
1308
1337
  // Runs BEFORE persistence so the reviewer of the NEXT chapter sees the
@@ -1326,6 +1355,7 @@ export class PipelineRunner {
1326
1355
  }
1327
1356
  }
1328
1357
  }
1358
+ this.throwIfOperationAborted();
1329
1359
  // 4. Save the final chapter and truth files from a single persistence source
1330
1360
  this.logStage(stageLanguage, { zh: "落盘最终章节", en: "persisting final chapter" });
1331
1361
  this.logStage(stageLanguage, { zh: "生成最终真相文件", en: "rebuilding final truth files" });
@@ -1848,7 +1878,7 @@ Base the analysis on the text's actual features, not generalities. Support each
1848
1878
  const response = await chatCompletion(this.config.client, this.config.model, [
1849
1879
  { role: "system", content: styleSystemPrompt },
1850
1880
  { role: "user", content: styleUserPrompt },
1851
- ], { temperature: 0.3 });
1881
+ ], { temperature: 0.3, signal: this.currentAbortSignal() });
1852
1882
  qualitativeGuide = response.content.trim()
1853
1883
  ? response.content
1854
1884
  : this.buildDeterministicStyleGuide(profile, {
@@ -2036,7 +2066,7 @@ ${emotions}
2036
2066
  ## 正传角色矩阵
2037
2067
  ${matrix}`,
2038
2068
  },
2039
- ], { temperature: 0.3 });
2069
+ ], { temperature: 0.3, signal: this.currentAbortSignal() });
2040
2070
  // Append deterministic meta block (LLM may hallucinate timestamps)
2041
2071
  const metaBlock = [
2042
2072
  "",
@@ -2089,6 +2119,7 @@ ${matrix}`,
2089
2119
  * Step 2: Sequentially replay each chapter through ChapterAnalyzer to build truth files.
2090
2120
  */
2091
2121
  async importChapters(input) {
2122
+ this.throwIfOperationAborted();
2092
2123
  const releaseLock = await this.state.acquireBookLock(input.bookId);
2093
2124
  try {
2094
2125
  const book = await this.state.loadBookConfig(input.bookId);
@@ -2116,6 +2147,7 @@ ${matrix}`,
2116
2147
  targetChapters: book.targetChapters,
2117
2148
  })
2118
2149
  : await architect.generateFoundationFromImport(book, foundationSource);
2150
+ this.throwIfOperationAborted();
2119
2151
  await architect.writeFoundationFiles(bookDir, foundation, gp.numericalSystem, resolvedLanguage);
2120
2152
  await this.resetImportReplayTruthFiles(bookDir, resolvedLanguage);
2121
2153
  await this.state.saveChapterIndex(input.bookId, [], { allowEmptyWithChapterFiles: true });
@@ -2144,6 +2176,7 @@ ${matrix}`,
2144
2176
  let totalWords = 0;
2145
2177
  let importedCount = 0;
2146
2178
  for (let i = startFrom - 1; i < input.chapters.length; i++) {
2179
+ this.throwIfOperationAborted();
2147
2180
  const ch = input.chapters[i];
2148
2181
  const chapterNumber = i + 1;
2149
2182
  const governedInput = await this.prepareWriteInput(book, bookDir, chapterNumber);
@@ -2162,6 +2195,7 @@ ${matrix}`,
2162
2195
  contextPackage: governedInput.contextPackage,
2163
2196
  ruleStack: governedInput.ruleStack,
2164
2197
  });
2198
+ this.throwIfOperationAborted();
2165
2199
  const chapterWordCount = countChapterLength(ch.content, countingMode);
2166
2200
  const persistedOutput = {
2167
2201
  ...output,