@code-yeongyu/senpi 2026.8.3-3 → 2026.8.4
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/CHANGELOG.md +27 -0
- package/dist/core/agent-session.d.ts +2 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +64 -26
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +2 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +126 -26
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +12 -7
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/per-turn-cap.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/per-turn-cap.js +4 -1
- package/dist/core/extensions/builtin/compaction/per-turn-cap.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/retained-message-safety.d.ts +4 -0
- package/dist/core/extensions/builtin/compaction/retained-message-safety.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/retained-message-safety.js +155 -0
- package/dist/core/extensions/builtin/compaction/retained-message-safety.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +21 -13
- package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
- package/dist/core/extensions/builtin/goal/cache-warm-renderer.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/cache-warm-renderer.js +9 -14
- package/dist/core/extensions/builtin/goal/cache-warm-renderer.js.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts +1 -0
- package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation-recovery.js +7 -0
- package/dist/core/extensions/builtin/goal/continuation-recovery.js.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation.d.ts +1 -1
- package/dist/core/extensions/builtin/goal/continuation.js +1 -1
- package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
- package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/index.js +12 -10
- package/dist/core/extensions/builtin/goal/index.js.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts +7 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +14 -2
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/extension.d.ts.map +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/extension.js +14 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/extension.js.map +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/types.d.ts +1 -0
- package/dist/core/extensions/builtin/gpt-apply-patch/types.d.ts.map +1 -1
- package/dist/core/extensions/builtin/gpt-apply-patch/types.js.map +1 -1
- package/dist/core/extensions/builtin/loop-guard/renderer.d.ts.map +1 -1
- package/dist/core/extensions/builtin/loop-guard/renderer.js +4 -12
- package/dist/core/extensions/builtin/loop-guard/renderer.js.map +1 -1
- package/dist/core/extensions/builtin/rule-activation/index.d.ts +6 -0
- package/dist/core/extensions/builtin/rule-activation/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rule-activation/index.js +10 -0
- package/dist/core/extensions/builtin/rule-activation/index.js.map +1 -0
- package/dist/core/extensions/builtin/rule-activation/renderer.d.ts +3 -0
- package/dist/core/extensions/builtin/rule-activation/renderer.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rule-activation/renderer.js +37 -0
- package/dist/core/extensions/builtin/rule-activation/renderer.js.map +1 -0
- package/dist/core/extensions/builtin/rule-activation/types.d.ts +15 -0
- package/dist/core/extensions/builtin/rule-activation/types.d.ts.map +1 -0
- package/dist/core/extensions/builtin/rule-activation/types.js +45 -0
- package/dist/core/extensions/builtin/rule-activation/types.js.map +1 -0
- package/dist/core/extensions/builtin/rules/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/rules/index.js +9 -1
- package/dist/core/extensions/builtin/rules/index.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.d.ts +22 -0
- package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.d.ts.map +1 -0
- package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.js +93 -0
- package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.js.map +1 -0
- package/dist/core/extensions/builtin/ttsr/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/index.js +60 -21
- package/dist/core/extensions/builtin/ttsr/index.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/prompts.d.ts +1 -0
- package/dist/core/extensions/builtin/ttsr/prompts.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/prompts.js +5 -0
- package/dist/core/extensions/builtin/ttsr/prompts.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/repetitive-turns-lane.d.ts +23 -0
- package/dist/core/extensions/builtin/ttsr/repetitive-turns-lane.d.ts.map +1 -0
- package/dist/core/extensions/builtin/ttsr/repetitive-turns-lane.js +101 -0
- package/dist/core/extensions/builtin/ttsr/repetitive-turns-lane.js.map +1 -0
- package/dist/core/extensions/builtin/ttsr/stream-remediation.d.ts +15 -0
- package/dist/core/extensions/builtin/ttsr/stream-remediation.d.ts.map +1 -0
- package/dist/core/extensions/builtin/ttsr/stream-remediation.js +22 -0
- package/dist/core/extensions/builtin/ttsr/stream-remediation.js.map +1 -0
- package/dist/core/extensions/builtin/ttsr/types.d.ts +1 -1
- package/dist/core/extensions/builtin/ttsr/types.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/types.js.map +1 -1
- package/dist/core/extensions/notice/adapters.d.ts +15 -0
- package/dist/core/extensions/notice/adapters.d.ts.map +1 -0
- package/dist/core/extensions/notice/adapters.js +22 -0
- package/dist/core/extensions/notice/adapters.js.map +1 -0
- package/dist/core/extensions/notice/box.d.ts +8 -0
- package/dist/core/extensions/notice/box.d.ts.map +1 -0
- package/dist/core/extensions/notice/box.js +17 -0
- package/dist/core/extensions/notice/box.js.map +1 -0
- package/dist/core/extensions/notice/index.d.ts +4 -0
- package/dist/core/extensions/notice/index.d.ts.map +1 -0
- package/dist/core/extensions/notice/index.js +3 -0
- package/dist/core/extensions/notice/index.js.map +1 -0
- package/dist/core/extensions/notice/spec.d.ts +23 -0
- package/dist/core/extensions/notice/spec.d.ts.map +1 -0
- package/dist/core/extensions/notice/spec.js +2 -0
- package/dist/core/extensions/notice/spec.js.map +1 -0
- package/dist/core/retry-fallback/settings.d.ts.map +1 -1
- package/dist/core/retry-fallback/settings.js +16 -1
- package/dist/core/retry-fallback/settings.js.map +1 -1
- package/dist/core/retry-fallback/validate.d.ts.map +1 -1
- package/dist/core/retry-fallback/validate.js +15 -2
- package/dist/core/retry-fallback/validate.js.map +1 -1
- package/dist/core/settings-manager.d.ts +7 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +13 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +42 -7
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/interactive-stderr-guard.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-stderr-guard.js +37 -0
- package/dist/modes/interactive/interactive-stderr-guard.js.map +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +16 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +13 -3
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/eval-status.ts +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +6 -6
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-runtime.ts +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +2 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-snapshot.ts +2 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-request.ts +20 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +17 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +18 -7
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +19 -5
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/alibaba-token-plan.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan-cn.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { getKeybindings } from \"@earendil-works/pi-tui\";\n\nimport type { ExtensionAPI, ExtensionContext, MessageUpdateEvent } from \"../../types.ts\";\nimport { BUILTIN_TTSR_RULES } from \"./builtin-rules.ts\";\nimport { registerTtsrCommands, type TtsrPublicState } from \"./commands.ts\";\nimport { claimAbort, createGenerationState, markUserCancelled } from \"./coordinator.ts\";\nimport { discoverTtsrRulesSync } from \"./discovery.ts\";\nimport { TtsrManager } from \"./manager.ts\";\nimport { COLLAPSE_RULE_CONTENT } from \"./prompts.ts\";\nimport {\n\tbuildErrorShellReplacement,\n\tbuildNudgeMessage,\n\tbuildTruncateReplacement,\n\ttype TruncatableAssistantMessage,\n\ttype TtsrNudgeMessage,\n} from \"./remediation.ts\";\nimport { compileRuleCondition } from \"./rule-condition.ts\";\nimport {\n\tDEFAULT_TTSR_SETTINGS,\n\ttype DetectionResolution,\n\ttype GenerationDetectionState,\n\tTTSR_INJECTION_CUSTOM_TYPE,\n\ttype TtsrRule,\n} from \"./types.ts\";\nimport { StreamWatcher } from \"./watch.ts\";\n\ninterface PendingRemediation {\n\treadonly resolution: DetectionResolution;\n\treadonly streamKind: \"text\" | \"thinking\";\n}\n\ninterface PendingRuleNudge {\n\treadonly rule: TtsrRule;\n}\n\nconst INTERRUPT_KEYBINDING = \"app.interrupt\";\n\nfunction isInterruptKey(data: string): boolean {\n\ttry {\n\t\treturn getKeybindings().matches(data, INTERRUPT_KEYBINDING);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction parseDisabledRules(raw: boolean | string | undefined): string[] {\n\treturn typeof raw === \"string\" && raw.length > 0\n\t\t? raw\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((name) => name.trim())\n\t\t\t\t.filter((name) => name.length > 0)\n\t\t: [];\n}\n\nexport default function ttsrExtension(pi: ExtensionAPI): void {\n\tpi.registerFlag(\"ttsr-disabled\", {\n\t\ttype: \"boolean\",\n\t\tdefault: false,\n\t\tdescription: \"Disable TTSR stream-rule detection.\",\n\t});\n\tpi.registerFlag(\"ttsr-rules-disabled\", {\n\t\ttype: \"string\",\n\t\tdefault: \"\",\n\t\tdescription: \"Comma-separated TTSR rule names to disable.\",\n\t});\n\n\tlet manager: TtsrManager | null = null;\n\tlet watcher: StreamWatcher | null = null;\n\tlet genState: GenerationDetectionState = createGenerationState();\n\tlet generation = 0;\n\tlet pendingRemediation: PendingRemediation | null = null;\n\tlet pendingRuleNudge: PendingRuleNudge | null = null;\n\tlet pendingNudge: TtsrNudgeMessage | null = null;\n\tlet disabled = false;\n\n\tfunction cancelRemediation(): void {\n\t\tif (pendingRemediation !== null || pendingNudge !== null || pendingRuleNudge !== null) {\n\t\t\tmarkUserCancelled(genState);\n\t\t\tpendingRemediation = null;\n\t\t\tpendingRuleNudge = null;\n\t\t\tpendingNudge = null;\n\t\t}\n\t}\n\n\tfunction recordInjection(owner: string, observed: readonly string[], retryMode: string): void {\n\t\tpi.appendEntry(TTSR_INJECTION_CUSTOM_TYPE, {\n\t\t\trules: observed,\n\t\t\towner,\n\t\t\tremediation: retryMode,\n\t\t\tat: Date.now(),\n\t\t});\n\t}\n\n\tfunction notify(ctx: ExtensionContext, owner: string): void {\n\t\tif (ctx.mode !== \"tui\") return;\n\t\ttry {\n\t\t\tctx.ui.notify(`Stream rule triggered: ${owner}`, \"warning\");\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\t}\n\n\tfunction ensureInitialized(ctx: ExtensionContext): void {\n\t\tif (manager !== null) return;\n\t\tdisabled = pi.getFlag(\"ttsr-disabled\") === true;\n\t\tconst disabledRules = parseDisabledRules(pi.getFlag(\"ttsr-rules-disabled\"));\n\t\tconst settings = { ...DEFAULT_TTSR_SETTINGS, enabled: !disabled, disabledRules };\n\t\tmanager = new TtsrManager(settings, (pattern) => compileRuleCondition(pattern).regex);\n\t\tconst injectedNames = ctx.sessionManager\n\t\t\t.getEntries()\n\t\t\t.filter((entry) => entry.type === \"custom\" && entry.customType === TTSR_INJECTION_CUSTOM_TYPE)\n\t\t\t.flatMap((entry) => {\n\t\t\t\tconst data = entry.type === \"custom\" ? entry.data : undefined;\n\t\t\t\tif (typeof data !== \"object\" || data === null || !(\"rules\" in data)) return [];\n\t\t\t\tconst rules = (data as { rules?: unknown }).rules;\n\t\t\t\treturn Array.isArray(rules) ? rules.filter((rule): rule is string => typeof rule === \"string\") : [];\n\t\t\t});\n\t\tmanager.restoreInjected(injectedNames);\n\t\tfor (const rule of BUILTIN_TTSR_RULES) {\n\t\t\tmanager.addRule(rule);\n\t\t}\n\t\tconst discovered = discoverTtsrRulesSync(ctx.cwd);\n\t\tfor (const rule of discovered.rules) {\n\t\t\tmanager.addRule(rule);\n\t\t}\n\t\twatcher = new StreamWatcher(manager, disabledRules);\n\t\tif (ctx.mode === \"tui\") {\n\t\t\ttry {\n\t\t\t\tctx.ui.onTerminalInput((data) => {\n\t\t\t\t\tif (isInterruptKey(data)) cancelRemediation();\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction publicState(): TtsrPublicState {\n\t\treturn {\n\t\t\trules: manager?.getRules() ?? [],\n\t\t\tinjectedRuleNames: manager?.getInjectedRuleNames() ?? [],\n\t\t\tdisabled,\n\t\t};\n\t}\n\n\tregisterTtsrCommands(pi, publicState);\n\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tensureInitialized(ctx);\n\t});\n\n\tpi.on(\"session_abort\", () => {\n\t\tcancelRemediation();\n\t});\n\n\tpi.on(\"input\", () => {\n\t\tcancelRemediation();\n\t});\n\n\tpi.on(\"turn_start\", (_event, ctx) => {\n\t\tensureInitialized(ctx);\n\t\tgeneration += 1;\n\t\tgenState = createGenerationState();\n\t\tpendingRemediation = null;\n\t\tpendingRuleNudge = null;\n\t\twatcher?.reset();\n\t});\n\n\tpi.on(\"turn_end\", () => {\n\t\tmanager?.incrementMessageCount();\n\t});\n\n\tpi.on(\"message_update\", (event: MessageUpdateEvent, ctx) => {\n\t\tensureInitialized(ctx);\n\t\tif (disabled || manager === null || watcher === null) return;\n\t\tconst deltaEvent = event.assistantMessageEvent;\n\t\tif (deltaEvent.type !== \"text_delta\" && deltaEvent.type !== \"thinking_delta\") return;\n\t\tconst source = deltaEvent.type === \"text_delta\" ? \"text\" : \"thinking\";\n\t\tconst streamKey = `${source}:${String(deltaEvent.contentIndex)}`;\n\t\tconst outcome = watcher.handleDelta(source, streamKey, deltaEvent.delta, generation);\n\t\tif (outcome.resolution !== null && claimAbort(genState, outcome.resolution)) {\n\t\t\tpendingRemediation = { resolution: outcome.resolution, streamKind: source };\n\t\t\tnotify(ctx, outcome.resolution.owner);\n\t\t\tctx.abort();\n\t\t\treturn;\n\t\t}\n\t\tconst interrupting = outcome.ruleMatches.filter((rule) => rule.interruptMode === \"always\");\n\t\tconst rule = interrupting[0];\n\t\tif (rule !== undefined && pendingRuleNudge === null && !genState.abortClaimed) {\n\t\t\tgenState.abortClaimed = true;\n\t\t\tgenState.abortOwner = \"collapse-repetition\";\n\t\t\tgenState.selfAbortAt = Date.now();\n\t\t\tpendingRuleNudge = { rule };\n\t\t\tnotify(ctx, rule.name);\n\t\t\tctx.abort();\n\t\t}\n\t});\n\n\tpi.on(\"message_end\", (event) => {\n\t\tif (genState.userCancelled) return undefined;\n\t\tif (event.message.role !== \"assistant\") return undefined;\n\t\tif (pendingRuleNudge !== null) {\n\t\t\tconst pending = pendingRuleNudge;\n\t\t\tpendingRuleNudge = null;\n\t\t\tmanager?.markInjectedByNames([pending.rule.name]);\n\t\t\trecordInjection(pending.rule.name, [pending.rule.name], \"nudge\");\n\t\t\tpendingNudge = buildNudgeMessage(pending.rule.name, pending.rule.content);\n\t\t\treturn undefined;\n\t\t}\n\t\tif (pendingRemediation === null) return undefined;\n\t\tconst pending = pendingRemediation;\n\t\tpendingRemediation = null;\n\t\ttry {\n\t\t\tif (pending.resolution.remediation.corruptionScope === \"generation\") {\n\t\t\t\trecordInjection(pending.resolution.owner, pending.resolution.observedRules, \"provider-error\");\n\t\t\t\treturn { message: { ...event.message, ...buildErrorShellReplacement() } };\n\t\t\t}\n\t\t\tconst replaced = buildTruncateReplacement(\n\t\t\t\tevent.message as unknown as TruncatableAssistantMessage,\n\t\t\t\tpending.resolution.match.garbageStartOffset,\n\t\t\t\tpending.streamKind,\n\t\t\t);\n\t\t\trecordInjection(pending.resolution.owner, pending.resolution.observedRules, \"nudge\");\n\t\t\tpendingNudge = buildNudgeMessage(pending.resolution.owner, COLLAPSE_RULE_CONTENT);\n\t\t\treturn { message: replaced as unknown as typeof event.message };\n\t\t} catch (error) {\n\t\t\tpi.appendEntry(\"ttsr-remediation-error\", {\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\tat: Date.now(),\n\t\t\t});\n\t\t\treturn undefined;\n\t\t}\n\t});\n\n\tpi.on(\"agent_settled\", () => {\n\t\tif (pendingNudge === null || genState.userCancelled) {\n\t\t\tpendingNudge = null;\n\t\t\treturn;\n\t\t}\n\t\tconst nudge = pendingNudge;\n\t\tpendingNudge = null;\n\t\tpi.sendMessage(nudge, { triggerTurn: true });\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { getKeybindings } from \"@earendil-works/pi-tui\";\n\nimport type { ExtensionAPI, ExtensionContext, MessageUpdateEvent } from \"../../types.ts\";\nimport { appendRuleActivation, registerRuleActivationRenderer } from \"../rule-activation/index.ts\";\nimport { BUILTIN_TTSR_RULES } from \"./builtin-rules.ts\";\nimport { registerTtsrCommands, type TtsrPublicState } from \"./commands.ts\";\nimport { claimAbort, createGenerationState, markUserCancelled } from \"./coordinator.ts\";\nimport { REPETITIVE_TURNS_RULE_NAME } from \"./detectors/repetitive-turns.ts\";\nimport { discoverTtsrRulesSync } from \"./discovery.ts\";\nimport { TtsrManager } from \"./manager.ts\";\nimport { REPETITIVE_TURNS_RULE_CONTENT } from \"./prompts.ts\";\nimport { buildNudgeMessage, type TtsrNudgeMessage } from \"./remediation.ts\";\nimport { collectAssistantText, RepetitiveTurnsLane, readPersistedAssistantTexts } from \"./repetitive-turns-lane.ts\";\nimport { compileRuleCondition } from \"./rule-condition.ts\";\nimport { buildStreamRemediation } from \"./stream-remediation.ts\";\nimport {\n\tDEFAULT_TTSR_SETTINGS,\n\ttype DetectionResolution,\n\ttype GenerationDetectionState,\n\tTTSR_INJECTION_CUSTOM_TYPE,\n\ttype TtsrRule,\n} from \"./types.ts\";\nimport { StreamWatcher } from \"./watch.ts\";\n\ninterface PendingRemediation {\n\treadonly resolution: DetectionResolution;\n\treadonly streamKind: \"text\" | \"thinking\";\n}\n\ninterface PendingRuleNudge {\n\treadonly rule: TtsrRule;\n}\n\nconst INTERRUPT_KEYBINDING = \"app.interrupt\";\n\nfunction isInterruptKey(data: string): boolean {\n\ttry {\n\t\treturn getKeybindings().matches(data, INTERRUPT_KEYBINDING);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction parseDisabledRules(raw: boolean | string | undefined): string[] {\n\treturn typeof raw === \"string\" && raw.length > 0\n\t\t? raw\n\t\t\t\t.split(\",\")\n\t\t\t\t.map((name) => name.trim())\n\t\t\t\t.filter((name) => name.length > 0)\n\t\t: [];\n}\n\nexport default function ttsrExtension(pi: ExtensionAPI): void {\n\tregisterRuleActivationRenderer(pi);\n\tpi.registerFlag(\"ttsr-disabled\", {\n\t\ttype: \"boolean\",\n\t\tdefault: false,\n\t\tdescription: \"Disable TTSR stream-rule detection.\",\n\t});\n\tpi.registerFlag(\"ttsr-rules-disabled\", {\n\t\ttype: \"string\",\n\t\tdefault: \"\",\n\t\tdescription: \"Comma-separated TTSR rule names to disable.\",\n\t});\n\n\tlet manager: TtsrManager | null = null;\n\tlet watcher: StreamWatcher | null = null;\n\tlet genState: GenerationDetectionState = createGenerationState();\n\tlet generation = 0;\n\tlet pendingRemediation: PendingRemediation | null = null;\n\tlet pendingRuleNudge: PendingRuleNudge | null = null;\n\tlet pendingNudge: TtsrNudgeMessage | null = null;\n\tlet disabled = false;\n\tconst repetitiveTurns = new RepetitiveTurnsLane();\n\n\tfunction cancelRemediation(): void {\n\t\tif (pendingRemediation !== null || pendingNudge !== null || pendingRuleNudge !== null) {\n\t\t\tmarkUserCancelled(genState);\n\t\t\tpendingRemediation = null;\n\t\t\tpendingRuleNudge = null;\n\t\t\tpendingNudge = null;\n\t\t\trepetitiveTurns.disarm();\n\t\t}\n\t}\n\n\tfunction recordInjection(owner: string, observed: readonly string[], retryMode: \"nudge\" | \"provider-error\"): void {\n\t\tpi.appendEntry(TTSR_INJECTION_CUSTOM_TYPE, {\n\t\t\trules: observed,\n\t\t\towner,\n\t\t\tremediation: retryMode,\n\t\t\tat: Date.now(),\n\t\t});\n\t\tappendRuleActivation(pi, {\n\t\t\tkind: \"ttsr\",\n\t\t\towner,\n\t\t\trules: observed,\n\t\t\tremediation: retryMode,\n\t\t});\n\t}\n\n\tfunction notify(ctx: ExtensionContext, owner: string): void {\n\t\tif (ctx.mode !== \"tui\") return;\n\t\ttry {\n\t\t\tctx.ui.notify(`Stream rule triggered: ${owner}`, \"warning\");\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\t}\n\n\tfunction ensureInitialized(ctx: ExtensionContext): void {\n\t\tif (manager !== null) return;\n\t\tdisabled = pi.getFlag(\"ttsr-disabled\") === true;\n\t\tconst disabledRules = parseDisabledRules(pi.getFlag(\"ttsr-rules-disabled\"));\n\t\trepetitiveTurns.configure(new Set(disabledRules));\n\t\tconst settings = { ...DEFAULT_TTSR_SETTINGS, enabled: !disabled, disabledRules };\n\t\tmanager = new TtsrManager(settings, (pattern) => compileRuleCondition(pattern).regex);\n\t\tconst injectedNames = ctx.sessionManager\n\t\t\t.getEntries()\n\t\t\t.filter((entry) => entry.type === \"custom\" && entry.customType === TTSR_INJECTION_CUSTOM_TYPE)\n\t\t\t.flatMap((entry) => {\n\t\t\t\tconst data = entry.type === \"custom\" ? entry.data : undefined;\n\t\t\t\tif (typeof data !== \"object\" || data === null || !(\"rules\" in data)) return [];\n\t\t\t\tconst rules = (data as { rules?: unknown }).rules;\n\t\t\t\treturn Array.isArray(rules) ? rules.filter((rule): rule is string => typeof rule === \"string\") : [];\n\t\t\t});\n\t\tmanager.restoreInjected(injectedNames);\n\t\tfor (const rule of BUILTIN_TTSR_RULES) {\n\t\t\tmanager.addRule(rule);\n\t\t}\n\t\tconst discovered = discoverTtsrRulesSync(ctx.cwd);\n\t\tfor (const rule of discovered.rules) {\n\t\t\tmanager.addRule(rule);\n\t\t}\n\t\twatcher = new StreamWatcher(manager, disabledRules);\n\t\trepetitiveTurns.restoreFromHistory(readPersistedAssistantTexts(ctx));\n\t\tif (ctx.mode === \"tui\") {\n\t\t\ttry {\n\t\t\t\tctx.ui.onTerminalInput((data) => {\n\t\t\t\t\tif (isInterruptKey(data)) cancelRemediation();\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction publicState(): TtsrPublicState {\n\t\treturn {\n\t\t\trules: manager?.getRules() ?? [],\n\t\t\tinjectedRuleNames: manager?.getInjectedRuleNames() ?? [],\n\t\t\tdisabled,\n\t\t};\n\t}\n\n\tregisterTtsrCommands(pi, publicState);\n\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tensureInitialized(ctx);\n\t});\n\n\tpi.on(\"session_abort\", () => {\n\t\tcancelRemediation();\n\t});\n\n\tpi.on(\"input\", () => {\n\t\tcancelRemediation();\n\t});\n\n\tpi.on(\"turn_start\", (_event, ctx) => {\n\t\tensureInitialized(ctx);\n\t\tgeneration += 1;\n\t\tgenState = createGenerationState();\n\t\tpendingRemediation = null;\n\t\tpendingRuleNudge = null;\n\t\trepetitiveTurns.resetTurn();\n\t\twatcher?.reset();\n\t});\n\n\tpi.on(\"turn_end\", () => {\n\t\tmanager?.incrementMessageCount();\n\t});\n\n\tpi.on(\"message_update\", (event: MessageUpdateEvent, ctx) => {\n\t\tensureInitialized(ctx);\n\t\tif (disabled || manager === null || watcher === null) return;\n\t\tconst deltaEvent = event.assistantMessageEvent;\n\t\tif (deltaEvent.type !== \"text_delta\" && deltaEvent.type !== \"thinking_delta\") return;\n\t\tconst source = deltaEvent.type === \"text_delta\" ? \"text\" : \"thinking\";\n\t\tconst streamKey = `${source}:${String(deltaEvent.contentIndex)}`;\n\t\tconst outcome = watcher.handleDelta(source, streamKey, deltaEvent.delta, generation);\n\t\tif (outcome.resolution !== null && claimAbort(genState, outcome.resolution)) {\n\t\t\tpendingRemediation = { resolution: outcome.resolution, streamKind: source };\n\t\t\tnotify(ctx, outcome.resolution.owner);\n\t\t\tctx.abort();\n\t\t\treturn;\n\t\t}\n\t\tif (source === \"text\") {\n\t\t\tconst canArm = pendingRuleNudge === null && !genState.abortClaimed;\n\t\t\tif (repetitiveTurns.observeTextDelta(deltaEvent.delta, canArm) && !genState.abortClaimed) {\n\t\t\t\tgenState.abortClaimed = true;\n\t\t\t\tgenState.abortOwner = \"collapse-repetition\";\n\t\t\t\tgenState.selfAbortAt = Date.now();\n\t\t\t\tnotify(ctx, REPETITIVE_TURNS_RULE_NAME);\n\t\t\t\tctx.abort();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tconst interrupting = outcome.ruleMatches.filter((rule) => rule.interruptMode === \"always\");\n\t\tconst rule = interrupting[0];\n\t\tif (rule !== undefined && pendingRuleNudge === null && !genState.abortClaimed) {\n\t\t\tgenState.abortClaimed = true;\n\t\t\tgenState.abortOwner = \"collapse-repetition\";\n\t\t\tgenState.selfAbortAt = Date.now();\n\t\t\tpendingRuleNudge = { rule };\n\t\t\tnotify(ctx, rule.name);\n\t\t\tctx.abort();\n\t\t}\n\t});\n\n\tpi.on(\"message_end\", (event) => {\n\t\tif (genState.userCancelled) return undefined;\n\t\tif (event.message.role !== \"assistant\") return undefined;\n\t\tconst turnText = collectAssistantText(event.message);\n\t\tif (repetitiveTurns.armed) {\n\t\t\trepetitiveTurns.commitArmedTurn(turnText);\n\t\t\tmanager?.markInjectedByNames([REPETITIVE_TURNS_RULE_NAME]);\n\t\t\trecordInjection(REPETITIVE_TURNS_RULE_NAME, [REPETITIVE_TURNS_RULE_NAME], \"nudge\");\n\t\t\tpendingNudge = buildNudgeMessage(REPETITIVE_TURNS_RULE_NAME, REPETITIVE_TURNS_RULE_CONTENT);\n\t\t\treturn undefined;\n\t\t}\n\t\tif (pendingRuleNudge !== null) {\n\t\t\tconst pending = pendingRuleNudge;\n\t\t\tpendingRuleNudge = null;\n\t\t\tmanager?.markInjectedByNames([pending.rule.name]);\n\t\t\trecordInjection(pending.rule.name, [pending.rule.name], \"nudge\");\n\t\t\tpendingNudge = buildNudgeMessage(pending.rule.name, pending.rule.content);\n\t\t\treturn undefined;\n\t\t}\n\t\tif (pendingRemediation !== null) {\n\t\t\tif (turnText !== null) repetitiveTurns.recordCompletedTurn(turnText);\n\t\t\tconst pending = pendingRemediation;\n\t\t\tpendingRemediation = null;\n\t\t\ttry {\n\t\t\t\tconst outcome = buildStreamRemediation(pending, event.message);\n\t\t\t\trecordInjection(outcome.owner, outcome.observedRules, outcome.retryMode);\n\t\t\t\tif (outcome.nudge !== null) {\n\t\t\t\t\tpendingNudge = outcome.nudge;\n\t\t\t\t}\n\t\t\t\tconst merged = { ...event.message, ...outcome.replacement };\n\t\t\t\treturn { message: merged as unknown as typeof event.message };\n\t\t\t} catch (error) {\n\t\t\t\tpi.appendEntry(\"ttsr-remediation-error\", {\n\t\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\t\tat: Date.now(),\n\t\t\t\t});\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\t\tif (turnText !== null) repetitiveTurns.recordCompletedTurn(turnText);\n\t\treturn undefined;\n\t});\n\n\tpi.on(\"agent_settled\", () => {\n\t\tif (pendingNudge === null || genState.userCancelled) {\n\t\t\tpendingNudge = null;\n\t\t\treturn;\n\t\t}\n\t\tconst nudge = pendingNudge;\n\t\tpendingNudge = null;\n\t\tpi.sendMessage(nudge, { triggerTurn: true });\n\t});\n}\n"]}
|
|
@@ -3,4 +3,5 @@ export declare const COLLAPSE_RULE_CONTENT: string;
|
|
|
3
3
|
export declare const LEAK_ERROR_MESSAGE = "Degeneration guard: control-token leakage; treating as internal error, resampling";
|
|
4
4
|
export declare const COLLAPSE_RULE_NAME = "collapse-repetition";
|
|
5
5
|
export declare const CONTROL_LEAK_RULE_NAME = "control-token-leak";
|
|
6
|
+
export declare const REPETITIVE_TURNS_RULE_CONTENT: string;
|
|
6
7
|
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/prompts.ts"],"names":[],"mappings":"AAAA,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAU/E;AAED,eAAO,MAAM,qBAAqB,QAKtB,CAAC;AAEb,eAAO,MAAM,kBAAkB,sFAAsF,CAAC;AAEtH,eAAO,MAAM,kBAAkB,wBAAwB,CAAC;AACxD,eAAO,MAAM,sBAAsB,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/prompts.ts"],"names":[],"mappings":"AAAA,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAU/E;AAED,eAAO,MAAM,qBAAqB,QAKtB,CAAC;AAEb,eAAO,MAAM,kBAAkB,sFAAsF,CAAC;AAEtH,eAAO,MAAM,kBAAkB,wBAAwB,CAAC;AACxD,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AAE3D,eAAO,MAAM,6BAA6B,QAI9B,CAAC"}
|
|
@@ -18,4 +18,9 @@ export const COLLAPSE_RULE_CONTENT = [
|
|
|
18
18
|
export const LEAK_ERROR_MESSAGE = "Degeneration guard: control-token leakage; treating as internal error, resampling";
|
|
19
19
|
export const COLLAPSE_RULE_NAME = "collapse-repetition";
|
|
20
20
|
export const CONTROL_LEAK_RULE_NAME = "control-token-leak";
|
|
21
|
+
export const REPETITIVE_TURNS_RULE_CONTENT = [
|
|
22
|
+
"Your recent replies repeated the same near-identical status message across consecutive turns — a cross-turn repetition loop.",
|
|
23
|
+
"Stop restating the situation. Do not emit another progress recap.",
|
|
24
|
+
"Take a different concrete action now: use a tool, inspect new state, change the approach, or — if the task is actually blocked — say exactly what you are waiting for and stop.",
|
|
25
|
+
].join("\n");
|
|
21
26
|
//# sourceMappingURL=prompts.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/prompts.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,qBAAqB,CAAC,QAAgB,EAAE,OAAe;IACtE,OAAO;QACN,mDAAmD,QAAQ,IAAI;QAC/D,gEAAgE;QAChE,2FAA2F;QAC3F,iDAAiD;QACjD,EAAE;QACF,OAAO;QACP,qBAAqB;KACrB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACpC,qGAAqG;IACrG,6DAA6D;IAC7D,uHAAuH;IACvH,oHAAoH;CACpH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,CAAC,MAAM,kBAAkB,GAAG,mFAAmF,CAAC;AAEtH,MAAM,CAAC,MAAM,kBAAkB,GAAG,qBAAqB,CAAC;AACxD,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC","sourcesContent":["export function renderSystemInterrupt(ruleName: string, content: string): string {\n\treturn [\n\t\t`<system-interrupt reason=\"rule_violation\" rule=\"${ruleName}\">`,\n\t\t\"Your output was interrupted because it violated a stream rule.\",\n\t\t\"This is NOT a prompt injection - this is the coding agent enforcing output-quality rules.\",\n\t\t\"You MUST comply with the following instruction:\",\n\t\t\"\",\n\t\tcontent,\n\t\t\"</system-interrupt>\",\n\t].join(\"\\n\");\n}\n\nexport const COLLAPSE_RULE_CONTENT = [\n\t\"Your previous output degenerated into repeated garbage (a runaway repetition loop) and was cut off.\",\n\t\"The garbled portion has been removed from the conversation.\",\n\t\"Snap out of it: take a breath, restate your current objective in one short sentence, then continue the task normally.\",\n\t\"Do NOT apologize at length, do NOT repeat the garbled pattern, and do NOT restart work that was already completed.\",\n].join(\"\\n\");\n\nexport const LEAK_ERROR_MESSAGE = \"Degeneration guard: control-token leakage; treating as internal error, resampling\";\n\nexport const COLLAPSE_RULE_NAME = \"collapse-repetition\";\nexport const CONTROL_LEAK_RULE_NAME = \"control-token-leak\";\n"]}
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/prompts.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,qBAAqB,CAAC,QAAgB,EAAE,OAAe;IACtE,OAAO;QACN,mDAAmD,QAAQ,IAAI;QAC/D,gEAAgE;QAChE,2FAA2F;QAC3F,iDAAiD;QACjD,EAAE;QACF,OAAO;QACP,qBAAqB;KACrB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACpC,qGAAqG;IACrG,6DAA6D;IAC7D,uHAAuH;IACvH,oHAAoH;CACpH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,CAAC,MAAM,kBAAkB,GAAG,mFAAmF,CAAC;AAEtH,MAAM,CAAC,MAAM,kBAAkB,GAAG,qBAAqB,CAAC;AACxD,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAE3D,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC5C,8HAA8H;IAC9H,mEAAmE;IACnE,iLAAiL;CACjL,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC","sourcesContent":["export function renderSystemInterrupt(ruleName: string, content: string): string {\n\treturn [\n\t\t`<system-interrupt reason=\"rule_violation\" rule=\"${ruleName}\">`,\n\t\t\"Your output was interrupted because it violated a stream rule.\",\n\t\t\"This is NOT a prompt injection - this is the coding agent enforcing output-quality rules.\",\n\t\t\"You MUST comply with the following instruction:\",\n\t\t\"\",\n\t\tcontent,\n\t\t\"</system-interrupt>\",\n\t].join(\"\\n\");\n}\n\nexport const COLLAPSE_RULE_CONTENT = [\n\t\"Your previous output degenerated into repeated garbage (a runaway repetition loop) and was cut off.\",\n\t\"The garbled portion has been removed from the conversation.\",\n\t\"Snap out of it: take a breath, restate your current objective in one short sentence, then continue the task normally.\",\n\t\"Do NOT apologize at length, do NOT repeat the garbled pattern, and do NOT restart work that was already completed.\",\n].join(\"\\n\");\n\nexport const LEAK_ERROR_MESSAGE = \"Degeneration guard: control-token leakage; treating as internal error, resampling\";\n\nexport const COLLAPSE_RULE_NAME = \"collapse-repetition\";\nexport const CONTROL_LEAK_RULE_NAME = \"control-token-leak\";\n\nexport const REPETITIVE_TURNS_RULE_CONTENT = [\n\t\"Your recent replies repeated the same near-identical status message across consecutive turns — a cross-turn repetition loop.\",\n\t\"Stop restating the situation. Do not emit another progress recap.\",\n\t\"Take a different concrete action now: use a tool, inspect new state, change the approach, or — if the task is actually blocked — say exactly what you are waiting for and stop.\",\n].join(\"\\n\");\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare function collectAssistantText(message: {
|
|
2
|
+
readonly content: unknown;
|
|
3
|
+
}): string | null;
|
|
4
|
+
interface SessionEntrySource {
|
|
5
|
+
readonly sessionManager: {
|
|
6
|
+
getEntries(): readonly unknown[];
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export declare function readPersistedAssistantTexts(ctx: SessionEntrySource): string[];
|
|
10
|
+
export declare class RepetitiveTurnsLane {
|
|
11
|
+
#private;
|
|
12
|
+
configure(disabledRules: ReadonlySet<string>): void;
|
|
13
|
+
resetSession(): void;
|
|
14
|
+
restoreFromHistory(assistantTexts: readonly string[]): void;
|
|
15
|
+
resetTurn(): void;
|
|
16
|
+
disarm(): void;
|
|
17
|
+
get armed(): boolean;
|
|
18
|
+
observeTextDelta(delta: string, canArm: boolean): boolean;
|
|
19
|
+
commitArmedTurn(turnText: string | null): void;
|
|
20
|
+
recordCompletedTurn(turnText: string): void;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=repetitive-turns-lane.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repetitive-turns-lane.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/repetitive-turns-lane.ts"],"names":[],"mappings":"AAUA,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CAU1F;AAID,UAAU,kBAAkB;IAC3B,QAAQ,CAAC,cAAc,EAAE;QAAE,UAAU,IAAI,SAAS,OAAO,EAAE,CAAA;KAAE,CAAC;CAC9D;AAED,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,EAAE,CAY7E;AAED,qBAAa,mBAAmB;;IAQ/B,SAAS,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAElD;IAED,YAAY,IAAI,IAAI,CAMnB;IAED,kBAAkB,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAK1D;IAED,SAAS,IAAI,IAAI,CAGhB;IAED,MAAM,IAAI,IAAI,CAEb;IAED,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAYxD;IAED,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAM7C;IAED,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAU1C;CACD"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { createRepetitiveTurnsState, isNearDuplicateOfPreviousTurn, normalizeTurnText, REPETITIVE_TURNS_MIN_NORMALIZED_CHARS, REPETITIVE_TURNS_RULE_NAME, recordTurnText, } from "./detectors/repetitive-turns.js";
|
|
2
|
+
export function collectAssistantText(message) {
|
|
3
|
+
if (!Array.isArray(message.content))
|
|
4
|
+
return null;
|
|
5
|
+
let combined = "";
|
|
6
|
+
for (const block of message.content) {
|
|
7
|
+
if (typeof block !== "object" || block === null)
|
|
8
|
+
continue;
|
|
9
|
+
if (!("type" in block) || block.type !== "text")
|
|
10
|
+
continue;
|
|
11
|
+
const value = Reflect.get(block, "text");
|
|
12
|
+
if (typeof value === "string")
|
|
13
|
+
combined += value;
|
|
14
|
+
}
|
|
15
|
+
return combined.length > 0 ? combined : null;
|
|
16
|
+
}
|
|
17
|
+
const RESTORED_TURN_LIMIT = 8;
|
|
18
|
+
export function readPersistedAssistantTexts(ctx) {
|
|
19
|
+
const texts = [];
|
|
20
|
+
for (const entry of ctx.sessionManager.getEntries()) {
|
|
21
|
+
if (typeof entry !== "object" || entry === null)
|
|
22
|
+
continue;
|
|
23
|
+
if (!("type" in entry) || entry.type !== "message")
|
|
24
|
+
continue;
|
|
25
|
+
const message = Reflect.get(entry, "message");
|
|
26
|
+
if (typeof message !== "object" || message === null)
|
|
27
|
+
continue;
|
|
28
|
+
if (Reflect.get(message, "role") !== "assistant")
|
|
29
|
+
continue;
|
|
30
|
+
const text = collectAssistantText({ content: Reflect.get(message, "content") });
|
|
31
|
+
if (text !== null)
|
|
32
|
+
texts.push(text);
|
|
33
|
+
}
|
|
34
|
+
return texts.slice(-RESTORED_TURN_LIMIT);
|
|
35
|
+
}
|
|
36
|
+
export class RepetitiveTurnsLane {
|
|
37
|
+
#state = createRepetitiveTurnsState();
|
|
38
|
+
#armed = false;
|
|
39
|
+
#recovering = false;
|
|
40
|
+
#currentTurnText = "";
|
|
41
|
+
#lastCompletedTurnText = null;
|
|
42
|
+
#enabled = true;
|
|
43
|
+
configure(disabledRules) {
|
|
44
|
+
this.#enabled = !disabledRules.has(REPETITIVE_TURNS_RULE_NAME);
|
|
45
|
+
}
|
|
46
|
+
resetSession() {
|
|
47
|
+
this.#state = createRepetitiveTurnsState();
|
|
48
|
+
this.#armed = false;
|
|
49
|
+
this.#recovering = false;
|
|
50
|
+
this.#currentTurnText = "";
|
|
51
|
+
this.#lastCompletedTurnText = null;
|
|
52
|
+
}
|
|
53
|
+
restoreFromHistory(assistantTexts) {
|
|
54
|
+
for (const text of assistantTexts) {
|
|
55
|
+
this.recordCompletedTurn(text);
|
|
56
|
+
}
|
|
57
|
+
this.#armed = false;
|
|
58
|
+
}
|
|
59
|
+
resetTurn() {
|
|
60
|
+
this.#armed = false;
|
|
61
|
+
this.#currentTurnText = "";
|
|
62
|
+
}
|
|
63
|
+
disarm() {
|
|
64
|
+
this.#armed = false;
|
|
65
|
+
}
|
|
66
|
+
get armed() {
|
|
67
|
+
return this.#armed;
|
|
68
|
+
}
|
|
69
|
+
observeTextDelta(delta, canArm) {
|
|
70
|
+
if (this.#enabled && !this.#armed && !this.#recovering && canArm && this.#lastCompletedTurnText !== null) {
|
|
71
|
+
const candidate = normalizeTurnText(this.#currentTurnText + delta);
|
|
72
|
+
if (candidate.length >= REPETITIVE_TURNS_MIN_NORMALIZED_CHARS &&
|
|
73
|
+
isNearDuplicateOfPreviousTurn(candidate, this.#lastCompletedTurnText)) {
|
|
74
|
+
this.#armed = true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
this.#currentTurnText += delta;
|
|
78
|
+
return this.#armed;
|
|
79
|
+
}
|
|
80
|
+
commitArmedTurn(turnText) {
|
|
81
|
+
this.#armed = false;
|
|
82
|
+
this.#recovering = true;
|
|
83
|
+
if (turnText !== null) {
|
|
84
|
+
this.#lastCompletedTurnText = normalizeTurnText(turnText);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
recordCompletedTurn(turnText) {
|
|
88
|
+
const normalized = normalizeTurnText(turnText);
|
|
89
|
+
this.#lastCompletedTurnText = normalized;
|
|
90
|
+
if (!this.#enabled)
|
|
91
|
+
return;
|
|
92
|
+
const match = recordTurnText(this.#state, turnText);
|
|
93
|
+
if (match === null) {
|
|
94
|
+
if (this.#recovering)
|
|
95
|
+
this.#recovering = false;
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
this.#armed = true;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=repetitive-turns-lane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repetitive-turns-lane.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/repetitive-turns-lane.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tcreateRepetitiveTurnsState,\n\tisNearDuplicateOfPreviousTurn,\n\tnormalizeTurnText,\n\tREPETITIVE_TURNS_MIN_NORMALIZED_CHARS,\n\tREPETITIVE_TURNS_RULE_NAME,\n\ttype RepetitiveTurnsState,\n\trecordTurnText,\n} from \"./detectors/repetitive-turns.ts\";\n\nexport function collectAssistantText(message: { readonly content: unknown }): string | null {\n\tif (!Array.isArray(message.content)) return null;\n\tlet combined = \"\";\n\tfor (const block of message.content) {\n\t\tif (typeof block !== \"object\" || block === null) continue;\n\t\tif (!(\"type\" in block) || block.type !== \"text\") continue;\n\t\tconst value: unknown = Reflect.get(block, \"text\");\n\t\tif (typeof value === \"string\") combined += value;\n\t}\n\treturn combined.length > 0 ? combined : null;\n}\n\nconst RESTORED_TURN_LIMIT = 8;\n\ninterface SessionEntrySource {\n\treadonly sessionManager: { getEntries(): readonly unknown[] };\n}\n\nexport function readPersistedAssistantTexts(ctx: SessionEntrySource): string[] {\n\tconst texts: string[] = [];\n\tfor (const entry of ctx.sessionManager.getEntries()) {\n\t\tif (typeof entry !== \"object\" || entry === null) continue;\n\t\tif (!(\"type\" in entry) || entry.type !== \"message\") continue;\n\t\tconst message: unknown = Reflect.get(entry, \"message\");\n\t\tif (typeof message !== \"object\" || message === null) continue;\n\t\tif (Reflect.get(message, \"role\") !== \"assistant\") continue;\n\t\tconst text = collectAssistantText({ content: Reflect.get(message, \"content\") });\n\t\tif (text !== null) texts.push(text);\n\t}\n\treturn texts.slice(-RESTORED_TURN_LIMIT);\n}\n\nexport class RepetitiveTurnsLane {\n\t#state: RepetitiveTurnsState = createRepetitiveTurnsState();\n\t#armed = false;\n\t#recovering = false;\n\t#currentTurnText = \"\";\n\t#lastCompletedTurnText: string | null = null;\n\t#enabled = true;\n\n\tconfigure(disabledRules: ReadonlySet<string>): void {\n\t\tthis.#enabled = !disabledRules.has(REPETITIVE_TURNS_RULE_NAME);\n\t}\n\n\tresetSession(): void {\n\t\tthis.#state = createRepetitiveTurnsState();\n\t\tthis.#armed = false;\n\t\tthis.#recovering = false;\n\t\tthis.#currentTurnText = \"\";\n\t\tthis.#lastCompletedTurnText = null;\n\t}\n\n\trestoreFromHistory(assistantTexts: readonly string[]): void {\n\t\tfor (const text of assistantTexts) {\n\t\t\tthis.recordCompletedTurn(text);\n\t\t}\n\t\tthis.#armed = false;\n\t}\n\n\tresetTurn(): void {\n\t\tthis.#armed = false;\n\t\tthis.#currentTurnText = \"\";\n\t}\n\n\tdisarm(): void {\n\t\tthis.#armed = false;\n\t}\n\n\tget armed(): boolean {\n\t\treturn this.#armed;\n\t}\n\n\tobserveTextDelta(delta: string, canArm: boolean): boolean {\n\t\tif (this.#enabled && !this.#armed && !this.#recovering && canArm && this.#lastCompletedTurnText !== null) {\n\t\t\tconst candidate = normalizeTurnText(this.#currentTurnText + delta);\n\t\t\tif (\n\t\t\t\tcandidate.length >= REPETITIVE_TURNS_MIN_NORMALIZED_CHARS &&\n\t\t\t\tisNearDuplicateOfPreviousTurn(candidate, this.#lastCompletedTurnText)\n\t\t\t) {\n\t\t\t\tthis.#armed = true;\n\t\t\t}\n\t\t}\n\t\tthis.#currentTurnText += delta;\n\t\treturn this.#armed;\n\t}\n\n\tcommitArmedTurn(turnText: string | null): void {\n\t\tthis.#armed = false;\n\t\tthis.#recovering = true;\n\t\tif (turnText !== null) {\n\t\t\tthis.#lastCompletedTurnText = normalizeTurnText(turnText);\n\t\t}\n\t}\n\n\trecordCompletedTurn(turnText: string): void {\n\t\tconst normalized = normalizeTurnText(turnText);\n\t\tthis.#lastCompletedTurnText = normalized;\n\t\tif (!this.#enabled) return;\n\t\tconst match = recordTurnText(this.#state, turnText);\n\t\tif (match === null) {\n\t\t\tif (this.#recovering) this.#recovering = false;\n\t\t\treturn;\n\t\t}\n\t\tthis.#armed = true;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ErrorShellReplacement, type TruncatableAssistantMessage, type TtsrNudgeMessage } from "./remediation.ts";
|
|
2
|
+
import type { DetectionResolution } from "./types.ts";
|
|
3
|
+
export interface StreamRemediationInput {
|
|
4
|
+
readonly resolution: DetectionResolution;
|
|
5
|
+
readonly streamKind: "text" | "thinking";
|
|
6
|
+
}
|
|
7
|
+
export interface StreamRemediationOutcome {
|
|
8
|
+
readonly replacement: ErrorShellReplacement | TruncatableAssistantMessage;
|
|
9
|
+
readonly nudge: TtsrNudgeMessage | null;
|
|
10
|
+
readonly owner: string;
|
|
11
|
+
readonly observedRules: readonly string[];
|
|
12
|
+
readonly retryMode: "nudge" | "provider-error";
|
|
13
|
+
}
|
|
14
|
+
export declare function buildStreamRemediation(pending: StreamRemediationInput, message: unknown): StreamRemediationOutcome;
|
|
15
|
+
//# sourceMappingURL=stream-remediation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-remediation.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/stream-remediation.ts"],"names":[],"mappings":"AACA,OAAO,EAIN,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,gBAAgB,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAAC;CACzC;AAED,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,WAAW,EAAE,qBAAqB,GAAG,2BAA2B,CAAC;IAC1E,QAAQ,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,gBAAgB,CAAC;CAC/C;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,OAAO,GAAG,wBAAwB,CAsBlH"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { COLLAPSE_RULE_CONTENT } from "./prompts.js";
|
|
2
|
+
import { buildErrorShellReplacement, buildNudgeMessage, buildTruncateReplacement, } from "./remediation.js";
|
|
3
|
+
export function buildStreamRemediation(pending, message) {
|
|
4
|
+
if (pending.resolution.remediation.corruptionScope === "generation") {
|
|
5
|
+
return {
|
|
6
|
+
replacement: buildErrorShellReplacement(),
|
|
7
|
+
nudge: null,
|
|
8
|
+
owner: pending.resolution.owner,
|
|
9
|
+
observedRules: pending.resolution.observedRules,
|
|
10
|
+
retryMode: "provider-error",
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
const replaced = buildTruncateReplacement(message, pending.resolution.match.garbageStartOffset, pending.streamKind);
|
|
14
|
+
return {
|
|
15
|
+
replacement: replaced,
|
|
16
|
+
nudge: buildNudgeMessage(pending.resolution.owner, COLLAPSE_RULE_CONTENT),
|
|
17
|
+
owner: pending.resolution.owner,
|
|
18
|
+
observedRules: pending.resolution.observedRules,
|
|
19
|
+
retryMode: "nudge",
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=stream-remediation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-remediation.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/stream-remediation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EACN,0BAA0B,EAC1B,iBAAiB,EACjB,wBAAwB,GAIxB,MAAM,kBAAkB,CAAC;AAgB1B,MAAM,UAAU,sBAAsB,CAAC,OAA+B,EAAE,OAAgB;IACvF,IAAI,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,eAAe,KAAK,YAAY,EAAE,CAAC;QACrE,OAAO;YACN,WAAW,EAAE,0BAA0B,EAAE;YACzC,KAAK,EAAE,IAAI;YACX,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK;YAC/B,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,aAAa;YAC/C,SAAS,EAAE,gBAAgB;SAC3B,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,wBAAwB,CACxC,OAAsC,EACtC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,kBAAkB,EAC3C,OAAO,CAAC,UAAU,CAClB,CAAC;IACF,OAAO;QACN,WAAW,EAAE,QAAQ;QACrB,KAAK,EAAE,iBAAiB,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,qBAAqB,CAAC;QACzE,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK;QAC/B,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,aAAa;QAC/C,SAAS,EAAE,OAAO;KAClB,CAAC;AACH,CAAC","sourcesContent":["import { COLLAPSE_RULE_CONTENT } from \"./prompts.ts\";\nimport {\n\tbuildErrorShellReplacement,\n\tbuildNudgeMessage,\n\tbuildTruncateReplacement,\n\ttype ErrorShellReplacement,\n\ttype TruncatableAssistantMessage,\n\ttype TtsrNudgeMessage,\n} from \"./remediation.ts\";\nimport type { DetectionResolution } from \"./types.ts\";\n\nexport interface StreamRemediationInput {\n\treadonly resolution: DetectionResolution;\n\treadonly streamKind: \"text\" | \"thinking\";\n}\n\nexport interface StreamRemediationOutcome {\n\treadonly replacement: ErrorShellReplacement | TruncatableAssistantMessage;\n\treadonly nudge: TtsrNudgeMessage | null;\n\treadonly owner: string;\n\treadonly observedRules: readonly string[];\n\treadonly retryMode: \"nudge\" | \"provider-error\";\n}\n\nexport function buildStreamRemediation(pending: StreamRemediationInput, message: unknown): StreamRemediationOutcome {\n\tif (pending.resolution.remediation.corruptionScope === \"generation\") {\n\t\treturn {\n\t\t\treplacement: buildErrorShellReplacement(),\n\t\t\tnudge: null,\n\t\t\towner: pending.resolution.owner,\n\t\t\tobservedRules: pending.resolution.observedRules,\n\t\t\tretryMode: \"provider-error\",\n\t\t};\n\t}\n\tconst replaced = buildTruncateReplacement(\n\t\tmessage as TruncatableAssistantMessage,\n\t\tpending.resolution.match.garbageStartOffset,\n\t\tpending.streamKind,\n\t);\n\treturn {\n\t\treplacement: replaced,\n\t\tnudge: buildNudgeMessage(pending.resolution.owner, COLLAPSE_RULE_CONTENT),\n\t\towner: pending.resolution.owner,\n\t\tobservedRules: pending.resolution.observedRules,\n\t\tretryMode: \"nudge\",\n\t};\n}\n"]}
|
|
@@ -33,7 +33,7 @@ export interface DetectorContext {
|
|
|
33
33
|
readonly generation: number;
|
|
34
34
|
}
|
|
35
35
|
export interface DetectorMatch {
|
|
36
|
-
readonly rule: "collapse-repetition" | "control-token-leak";
|
|
36
|
+
readonly rule: "collapse-repetition" | "control-token-leak" | "repetitive-turns";
|
|
37
37
|
readonly reason: string;
|
|
38
38
|
readonly anomalyStartOffset: number;
|
|
39
39
|
readonly garbageStartOffset: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;AAE5D,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;CAC9C;AAED,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEnD,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;CAClD;AAED,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED,eAAO,MAAM,qBAAqB,EAAE,YAKnC,CAAC;AAEF,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,IAAI,EAAE,qBAAqB,GAAG,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/types.ts"],"names":[],"mappings":"AAkCA,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IAClD,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,EAAE;IACb,aAAa,EAAE,EAAE;CACjB,CAAC;AAsCF,MAAM,CAAC,MAAM,oBAAoB,GAAoB;IACpD,SAAS,EAAE,OAAO;IAClB,WAAW,EAAE,UAAU;IACvB,eAAe,EAAE,eAAe;IAChC,QAAQ,EAAE,qBAAqB;CAC/B,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAoB;IACxD,SAAS,EAAE,gBAAgB;IAC3B,WAAW,EAAE,SAAS;IACtB,eAAe,EAAE,YAAY;IAC7B,SAAS,EAAE,oBAAoB;CAC/B,CAAC;AAuBF,MAAM,CAAC,MAAM,0BAA0B,GAAG,gBAAgB,CAAC","sourcesContent":["export type TtsrStreamSource = \"text\" | \"thinking\" | \"tool\";\n\nexport interface TtsrToolScope {\n\treadonly toolName: string;\n\treadonly pathGlob?: string;\n}\n\nexport interface TtsrScope {\n\treadonly allowText: boolean;\n\treadonly allowThinking: boolean;\n\treadonly toolScopes: readonly TtsrToolScope[];\n}\n\nexport type TtsrInterruptMode = \"always\" | \"never\";\n\nexport interface TtsrRule {\n\treadonly name: string;\n\treadonly path?: string;\n\treadonly content: string;\n\treadonly description?: string;\n\treadonly globs?: readonly string[];\n\treadonly condition: readonly string[];\n\treadonly scope: TtsrScope;\n\treadonly interruptMode: TtsrInterruptMode;\n\treadonly source: \"builtin\" | \"project\" | \"global\";\n}\n\nexport interface TtsrSettings {\n\treadonly enabled: boolean;\n\treadonly repeatMode: \"once\" | \"after-gap\";\n\treadonly repeatGap: number;\n\treadonly disabledRules: readonly string[];\n}\n\nexport const DEFAULT_TTSR_SETTINGS: TtsrSettings = {\n\tenabled: true,\n\trepeatMode: \"once\",\n\trepeatGap: 10,\n\tdisabledRules: [],\n};\n\nexport interface DetectorContext {\n\treadonly source: Exclude<TtsrStreamSource, \"tool\">;\n\treadonly streamKey: string;\n\treadonly generation: number;\n}\n\nexport interface DetectorMatch {\n\treadonly rule: \"collapse-repetition\" | \"control-token-leak\";\n\treadonly reason: string;\n\treadonly anomalyStartOffset: number;\n\treadonly garbageStartOffset: number;\n\treadonly detail: Readonly<Record<string, string | number | boolean>>;\n}\n\nexport interface StreamDetector<State> {\n\tcreateState(): State;\n\tcheckDelta(state: State, delta: string, ctx: DetectorContext): DetectorMatch | null;\n\tflush?(state: State, ctx: DetectorContext): DetectorMatch | null;\n}\n\nexport type TtsrContextMode = \"keep\" | \"truncate\" | \"discard\";\n\nexport type RuleRemediation =\n\t| {\n\t\t\treadonly retryMode: \"nudge\";\n\t\t\treadonly contextMode: TtsrContextMode;\n\t\t\treadonly corruptionScope: \"output-region\";\n\t\t\treadonly nudgeKey: string;\n\t }\n\t| {\n\t\t\treadonly retryMode: \"provider-error\";\n\t\t\treadonly contextMode: \"discard\";\n\t\t\treadonly corruptionScope: \"generation\";\n\t\t\treadonly errorKind: \"control-token-leak\";\n\t };\n\nexport const COLLAPSE_REMEDIATION: RuleRemediation = {\n\tretryMode: \"nudge\",\n\tcontextMode: \"truncate\",\n\tcorruptionScope: \"output-region\",\n\tnudgeKey: \"collapse-repetition\",\n};\n\nexport const CONTROL_LEAK_REMEDIATION: RuleRemediation = {\n\tretryMode: \"provider-error\",\n\tcontextMode: \"discard\",\n\tcorruptionScope: \"generation\",\n\terrorKind: \"control-token-leak\",\n};\n\nexport interface DetectionResolution {\n\treadonly owner: \"collapse-repetition\" | \"control-token-leak\";\n\treadonly observedRules: readonly (\"collapse-repetition\" | \"control-token-leak\")[];\n\treadonly match: DetectorMatch;\n\treadonly remediation: RuleRemediation;\n}\n\nexport interface GenerationDetectionState {\n\tabortClaimed: boolean;\n\tabortOwner?: DetectionResolution[\"owner\"];\n\tselfAbortAt?: number;\n\tuserCancelled: boolean;\n}\n\nexport interface TtsrInjectionRecord {\n\treadonly rules: readonly string[];\n\treadonly owner: DetectionResolution[\"owner\"];\n\treadonly remediation: RuleRemediation[\"retryMode\"];\n\treadonly at: number;\n}\n\nexport const TTSR_INJECTION_CUSTOM_TYPE = \"ttsr-injection\";\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/ttsr/types.ts"],"names":[],"mappings":"AAkCA,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IAClD,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,EAAE;IACb,aAAa,EAAE,EAAE;CACjB,CAAC;AAsCF,MAAM,CAAC,MAAM,oBAAoB,GAAoB;IACpD,SAAS,EAAE,OAAO;IAClB,WAAW,EAAE,UAAU;IACvB,eAAe,EAAE,eAAe;IAChC,QAAQ,EAAE,qBAAqB;CAC/B,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAoB;IACxD,SAAS,EAAE,gBAAgB;IAC3B,WAAW,EAAE,SAAS;IACtB,eAAe,EAAE,YAAY;IAC7B,SAAS,EAAE,oBAAoB;CAC/B,CAAC;AAuBF,MAAM,CAAC,MAAM,0BAA0B,GAAG,gBAAgB,CAAC","sourcesContent":["export type TtsrStreamSource = \"text\" | \"thinking\" | \"tool\";\n\nexport interface TtsrToolScope {\n\treadonly toolName: string;\n\treadonly pathGlob?: string;\n}\n\nexport interface TtsrScope {\n\treadonly allowText: boolean;\n\treadonly allowThinking: boolean;\n\treadonly toolScopes: readonly TtsrToolScope[];\n}\n\nexport type TtsrInterruptMode = \"always\" | \"never\";\n\nexport interface TtsrRule {\n\treadonly name: string;\n\treadonly path?: string;\n\treadonly content: string;\n\treadonly description?: string;\n\treadonly globs?: readonly string[];\n\treadonly condition: readonly string[];\n\treadonly scope: TtsrScope;\n\treadonly interruptMode: TtsrInterruptMode;\n\treadonly source: \"builtin\" | \"project\" | \"global\";\n}\n\nexport interface TtsrSettings {\n\treadonly enabled: boolean;\n\treadonly repeatMode: \"once\" | \"after-gap\";\n\treadonly repeatGap: number;\n\treadonly disabledRules: readonly string[];\n}\n\nexport const DEFAULT_TTSR_SETTINGS: TtsrSettings = {\n\tenabled: true,\n\trepeatMode: \"once\",\n\trepeatGap: 10,\n\tdisabledRules: [],\n};\n\nexport interface DetectorContext {\n\treadonly source: Exclude<TtsrStreamSource, \"tool\">;\n\treadonly streamKey: string;\n\treadonly generation: number;\n}\n\nexport interface DetectorMatch {\n\treadonly rule: \"collapse-repetition\" | \"control-token-leak\" | \"repetitive-turns\";\n\treadonly reason: string;\n\treadonly anomalyStartOffset: number;\n\treadonly garbageStartOffset: number;\n\treadonly detail: Readonly<Record<string, string | number | boolean>>;\n}\n\nexport interface StreamDetector<State> {\n\tcreateState(): State;\n\tcheckDelta(state: State, delta: string, ctx: DetectorContext): DetectorMatch | null;\n\tflush?(state: State, ctx: DetectorContext): DetectorMatch | null;\n}\n\nexport type TtsrContextMode = \"keep\" | \"truncate\" | \"discard\";\n\nexport type RuleRemediation =\n\t| {\n\t\t\treadonly retryMode: \"nudge\";\n\t\t\treadonly contextMode: TtsrContextMode;\n\t\t\treadonly corruptionScope: \"output-region\";\n\t\t\treadonly nudgeKey: string;\n\t }\n\t| {\n\t\t\treadonly retryMode: \"provider-error\";\n\t\t\treadonly contextMode: \"discard\";\n\t\t\treadonly corruptionScope: \"generation\";\n\t\t\treadonly errorKind: \"control-token-leak\";\n\t };\n\nexport const COLLAPSE_REMEDIATION: RuleRemediation = {\n\tretryMode: \"nudge\",\n\tcontextMode: \"truncate\",\n\tcorruptionScope: \"output-region\",\n\tnudgeKey: \"collapse-repetition\",\n};\n\nexport const CONTROL_LEAK_REMEDIATION: RuleRemediation = {\n\tretryMode: \"provider-error\",\n\tcontextMode: \"discard\",\n\tcorruptionScope: \"generation\",\n\terrorKind: \"control-token-leak\",\n};\n\nexport interface DetectionResolution {\n\treadonly owner: \"collapse-repetition\" | \"control-token-leak\";\n\treadonly observedRules: readonly (\"collapse-repetition\" | \"control-token-leak\")[];\n\treadonly match: DetectorMatch;\n\treadonly remediation: RuleRemediation;\n}\n\nexport interface GenerationDetectionState {\n\tabortClaimed: boolean;\n\tabortOwner?: DetectionResolution[\"owner\"];\n\tselfAbortAt?: number;\n\tuserCancelled: boolean;\n}\n\nexport interface TtsrInjectionRecord {\n\treadonly rules: readonly string[];\n\treadonly owner: DetectionResolution[\"owner\"];\n\treadonly remediation: RuleRemediation[\"retryMode\"];\n\treadonly at: number;\n}\n\nexport const TTSR_INJECTION_CUSTOM_TYPE = \"ttsr-injection\";\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CustomMessage } from "../../messages.ts";
|
|
2
|
+
import type { CustomEntry } from "../../session-manager.ts";
|
|
3
|
+
import type { EntryRenderer, MessageRenderer } from "../types.ts";
|
|
4
|
+
import type { NoticeSpec } from "./spec.ts";
|
|
5
|
+
/**
|
|
6
|
+
* Adapt a NoticeSpec mapper into a MessageRenderer for custom messages
|
|
7
|
+
* (model-facing notices such as loop-guard detections).
|
|
8
|
+
*/
|
|
9
|
+
export declare function noticeMessageRenderer<T>(map: (message: CustomMessage<T>) => NoticeSpec | undefined): MessageRenderer<T>;
|
|
10
|
+
/**
|
|
11
|
+
* Adapt a NoticeSpec mapper into an EntryRenderer for durable custom entries
|
|
12
|
+
* (display-only records such as ttsr injections; entries never reach the LLM).
|
|
13
|
+
*/
|
|
14
|
+
export declare function noticeEntryRenderer<T>(map: (entry: CustomEntry<T>) => NoticeSpec | undefined): EntryRenderer<T>;
|
|
15
|
+
//# sourceMappingURL=adapters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/notice/adapters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACtC,GAAG,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,UAAU,GAAG,SAAS,GACxD,eAAe,CAAC,CAAC,CAAC,CAKpB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,UAAU,GAAG,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,CAK/G"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { buildNoticeBox } from "./box.js";
|
|
2
|
+
/**
|
|
3
|
+
* Adapt a NoticeSpec mapper into a MessageRenderer for custom messages
|
|
4
|
+
* (model-facing notices such as loop-guard detections).
|
|
5
|
+
*/
|
|
6
|
+
export function noticeMessageRenderer(map) {
|
|
7
|
+
return (message, options, theme) => {
|
|
8
|
+
const spec = map(message);
|
|
9
|
+
return spec === undefined ? undefined : buildNoticeBox(spec, options, theme);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Adapt a NoticeSpec mapper into an EntryRenderer for durable custom entries
|
|
14
|
+
* (display-only records such as ttsr injections; entries never reach the LLM).
|
|
15
|
+
*/
|
|
16
|
+
export function noticeEntryRenderer(map) {
|
|
17
|
+
return (entry, options, theme) => {
|
|
18
|
+
const spec = map(entry);
|
|
19
|
+
return spec === undefined ? undefined : buildNoticeBox(spec, options, theme);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=adapters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.js","sourceRoot":"","sources":["../../../../src/core/extensions/notice/adapters.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACpC,GAA0D;IAE1D,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAClC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1B,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAC9E,CAAC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAI,GAAsD;IAC5F,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAChC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC;QACxB,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAC9E,CAAC,CAAC;AACH,CAAC","sourcesContent":["import type { CustomMessage } from \"../../messages.ts\";\nimport type { CustomEntry } from \"../../session-manager.ts\";\nimport type { EntryRenderer, MessageRenderer } from \"../types.ts\";\nimport { buildNoticeBox } from \"./box.ts\";\nimport type { NoticeSpec } from \"./spec.ts\";\n\n/**\n * Adapt a NoticeSpec mapper into a MessageRenderer for custom messages\n * (model-facing notices such as loop-guard detections).\n */\nexport function noticeMessageRenderer<T>(\n\tmap: (message: CustomMessage<T>) => NoticeSpec | undefined,\n): MessageRenderer<T> {\n\treturn (message, options, theme) => {\n\t\tconst spec = map(message);\n\t\treturn spec === undefined ? undefined : buildNoticeBox(spec, options, theme);\n\t};\n}\n\n/**\n * Adapt a NoticeSpec mapper into an EntryRenderer for durable custom entries\n * (display-only records such as ttsr injections; entries never reach the LLM).\n */\nexport function noticeEntryRenderer<T>(map: (entry: CustomEntry<T>) => NoticeSpec | undefined): EntryRenderer<T> {\n\treturn (entry, options, theme) => {\n\t\tconst spec = map(entry);\n\t\treturn spec === undefined ? undefined : buildNoticeBox(spec, options, theme);\n\t};\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Component } from "@earendil-works/pi-tui";
|
|
2
|
+
import type { Theme } from "../../../modes/interactive/theme/theme.ts";
|
|
3
|
+
import type { NoticeSpec } from "./spec.ts";
|
|
4
|
+
/** Render a NoticeSpec as the shared transcript notice box (loop-guard visual family). */
|
|
5
|
+
export declare function buildNoticeBox(spec: NoticeSpec, options: {
|
|
6
|
+
readonly expanded: boolean;
|
|
7
|
+
}, theme: Theme): Component;
|
|
8
|
+
//# sourceMappingURL=box.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/notice/box.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,SAAS,EAAQ,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAK5C,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE;IAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,CAWjH"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Box, Text } from "@earendil-works/pi-tui";
|
|
2
|
+
const BOLD = "[1m";
|
|
3
|
+
const BOLD_OFF = "[22m";
|
|
4
|
+
/** Render a NoticeSpec as the shared transcript notice box (loop-guard visual family). */
|
|
5
|
+
export function buildNoticeBox(spec, options, theme) {
|
|
6
|
+
const box = new Box(1, 1, (text) => theme.bg("customMessageBg", text));
|
|
7
|
+
box.addChild(new Text(theme.fg(spec.tone ?? "accent", `${BOLD}${spec.title}${BOLD_OFF}`), 0, 0));
|
|
8
|
+
box.addChild(new Text(theme.fg("dim", spec.why), 0, 0));
|
|
9
|
+
for (const line of spec.extra ?? []) {
|
|
10
|
+
box.addChild(new Text(theme.fg(line.tone ?? "dim", line.text), 0, 0));
|
|
11
|
+
}
|
|
12
|
+
if (options.expanded && spec.expandedLine !== undefined) {
|
|
13
|
+
box.addChild(new Text(theme.fg("dim", spec.expandedLine), 0, 0));
|
|
14
|
+
}
|
|
15
|
+
return box;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=box.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"box.js","sourceRoot":"","sources":["../../../../src/core/extensions/notice/box.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAkB,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAInE,MAAM,IAAI,GAAG,MAAM,CAAC;AACpB,MAAM,QAAQ,GAAG,OAAO,CAAC;AAEzB,0FAA0F;AAC1F,MAAM,UAAU,cAAc,CAAC,IAAgB,EAAE,OAAuC,EAAE,KAAY;IACrG,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC,CAAC;IACvE,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,QAAQ,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACjG,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACxD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;QACrC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACzD,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC","sourcesContent":["import { Box, type Component, Text } from \"@earendil-works/pi-tui\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport type { NoticeSpec } from \"./spec.ts\";\n\nconst BOLD = \"\u001b[1m\";\nconst BOLD_OFF = \"\u001b[22m\";\n\n/** Render a NoticeSpec as the shared transcript notice box (loop-guard visual family). */\nexport function buildNoticeBox(spec: NoticeSpec, options: { readonly expanded: boolean }, theme: Theme): Component {\n\tconst box = new Box(1, 1, (text) => theme.bg(\"customMessageBg\", text));\n\tbox.addChild(new Text(theme.fg(spec.tone ?? \"accent\", `${BOLD}${spec.title}${BOLD_OFF}`), 0, 0));\n\tbox.addChild(new Text(theme.fg(\"dim\", spec.why), 0, 0));\n\tfor (const line of spec.extra ?? []) {\n\t\tbox.addChild(new Text(theme.fg(line.tone ?? \"dim\", line.text), 0, 0));\n\t}\n\tif (options.expanded && spec.expandedLine !== undefined) {\n\t\tbox.addChild(new Text(theme.fg(\"dim\", spec.expandedLine), 0, 0));\n\t}\n\treturn box;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/notice/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/extensions/notice/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC","sourcesContent":["export { noticeEntryRenderer, noticeMessageRenderer } from \"./adapters.ts\";\nexport { buildNoticeBox } from \"./box.ts\";\nexport type { NoticeLine, NoticeSpec, NoticeTone } from \"./spec.ts\";\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visual contract for a transcript notice box: the shared widget used by
|
|
3
|
+
* loop-guard detections, ttsr stream-rule interventions, goal cache-warm
|
|
4
|
+
* entries, and interactive fallback transitions.
|
|
5
|
+
*/
|
|
6
|
+
export type NoticeTone = "accent" | "warning" | "error" | "success" | "dim";
|
|
7
|
+
export interface NoticeLine {
|
|
8
|
+
readonly text: string;
|
|
9
|
+
/** Line tone; defaults to "dim". */
|
|
10
|
+
readonly tone?: NoticeTone;
|
|
11
|
+
}
|
|
12
|
+
export interface NoticeSpec {
|
|
13
|
+
readonly title: string;
|
|
14
|
+
/** Title tone; defaults to "accent". */
|
|
15
|
+
readonly tone?: NoticeTone;
|
|
16
|
+
/** Secondary line explaining what happened, rendered dim. */
|
|
17
|
+
readonly why: string;
|
|
18
|
+
/** Optional extra lines between the why line and the expanded detail. */
|
|
19
|
+
readonly extra?: readonly NoticeLine[];
|
|
20
|
+
/** Detail line shown only when the transcript is expanded. */
|
|
21
|
+
readonly expandedLine?: string;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/notice/spec.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,KAAK,CAAC;AAE5E,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;IAC3B,6DAA6D;IAC7D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,8DAA8D;IAC9D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAC/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../../../src/core/extensions/notice/spec.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Visual contract for a transcript notice box: the shared widget used by\n * loop-guard detections, ttsr stream-rule interventions, goal cache-warm\n * entries, and interactive fallback transitions.\n */\nexport type NoticeTone = \"accent\" | \"warning\" | \"error\" | \"success\" | \"dim\";\n\nexport interface NoticeLine {\n\treadonly text: string;\n\t/** Line tone; defaults to \"dim\". */\n\treadonly tone?: NoticeTone;\n}\n\nexport interface NoticeSpec {\n\treadonly title: string;\n\t/** Title tone; defaults to \"accent\". */\n\treadonly tone?: NoticeTone;\n\t/** Secondary line explaining what happened, rendered dim. */\n\treadonly why: string;\n\t/** Optional extra lines between the why line and the expanded detail. */\n\treadonly extra?: readonly NoticeLine[];\n\t/** Detail line shown only when the transcript is expanded. */\n\treadonly expandedLine?: string;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/core/retry-fallback/settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,WAAW,qBAAqB;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1C,oBAAoB,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC;IACnD,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,6BAA6B;IAC7C,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,cAAc,CAAC;IACvB,YAAY,EAAE,iBAAiB,GAAG,OAAO,CAAC;CAC1C;AAED,eAAO,MAAM,uBAAuB,EAAE,cAMrC,CAAC;
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/core/retry-fallback/settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,WAAW,qBAAqB;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1C,oBAAoB,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC;IACnD,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,6BAA6B;IAC7C,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,cAAc,CAAC;IACvB,YAAY,EAAE,iBAAiB,GAAG,OAAO,CAAC;CAC1C;AAED,eAAO,MAAM,uBAAuB,EAAE,cAMrC,CAAC;AA6CF,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,aAAa,GAAG,SAAS,GAAG,6BAA6B,CAM/G;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAE3F;AAED,eAAO,MAAM,0BAA0B,SAAU,CAAC;AAClD,eAAO,MAAM,yBAAyB,UAAY,CAAC;AAEnD,MAAM,WAAW,0BAA0B;IAC1C,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,aAAa,GAAG,SAAS,GAAG,0BAA0B,CAezG"}
|
|
@@ -18,15 +18,30 @@ function isPlainObject(value) {
|
|
|
18
18
|
function isStringArray(value) {
|
|
19
19
|
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* User chains layer over the shipped defaults per key instead of replacing the
|
|
23
|
+
* whole map. Configuring an unrelated model must not silently delete a default
|
|
24
|
+
* chain: that left the defaulted model with no client chain at all, which in
|
|
25
|
+
* turn disabled the server-fallback abort and handed model choice back to the
|
|
26
|
+
* provider. A same-named key still replaces that default outright (never a
|
|
27
|
+
* union), and an explicit empty array removes a default the user does not want.
|
|
28
|
+
*
|
|
29
|
+
* Cross-scope replacement (global vs project) stays wholesale and is handled by
|
|
30
|
+
* `deepMergeSettings`; this only resolves defaults against the merged result.
|
|
31
|
+
*/
|
|
21
32
|
function resolveFallbackChains(value) {
|
|
22
33
|
if (value === undefined)
|
|
23
34
|
return cloneDefaultFallbackChains();
|
|
24
35
|
if (!isPlainObject(value))
|
|
25
36
|
return cloneDefaultFallbackChains();
|
|
26
|
-
const chains =
|
|
37
|
+
const chains = cloneDefaultFallbackChains();
|
|
27
38
|
for (const [key, entries] of Object.entries(value)) {
|
|
28
39
|
if (!isStringArray(entries))
|
|
29
40
|
return cloneDefaultFallbackChains();
|
|
41
|
+
if (entries.length === 0) {
|
|
42
|
+
delete chains[key];
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
30
45
|
chains[key] = [...entries];
|
|
31
46
|
}
|
|
32
47
|
return chains;
|