import { ExtensionAPI } from '@earendil-works/pi-coding-agent'; type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue; }; interface EvidenceRef { source: "user" | "assistant"; quote: string; } interface ProposedEvent { ref: string; kind: string; summary: string; participants: string[]; observedBy: string[]; importance: number; confidence: number; evidence: EvidenceRef[]; } interface ProposedStateTarget { domain: "appearance" | "location" | "inventory" | "conditions" | "relationship" | "knowledge" | "goals" | "questFlags"; field?: string; subjectId?: string; itemId?: string; conditionId?: string; topicId?: string; goalId?: string; flagId?: string; } interface ProposedStateChange { op: "add" | "replace" | "remove"; /** Legacy v1/manual input. Model tool schema v2 uses target instead. */ path?: string; target?: ProposedStateTarget; from?: JsonValue; value?: JsonValue; durability: "temporary" | "persistent"; causeEventRef?: string; confidence: number; evidence: EvidenceRef[]; } interface ProposedMemory { ownerCharacterId: string; eventRef?: string; summary: string; valence: string; importance: number; retrievalKeys: string[]; participants: string[]; confidence: number; evidence: EvidenceRef[]; } interface CommittedEvent extends Omit { eventId: string; } interface CommittedMemory extends Omit { memoryId: string; eventId?: string; } interface CommittedStateChange extends Omit { path: string; causeEventId?: string; } type RoleplayIssueCode = "schema_version" | "duplicate_ref" | "evidence" | "confidence" | "forbidden_path" | "unknown_path" | "unknown_event" | "state_conflict" | "missing_value" | "invalid_owner" | "importance" | "overlapping_path" | "requires_review"; interface RoleplayValidationIssue { code: RoleplayIssueCode; category: "schema" | "evidence" | "permission" | "conflict" | "review"; message: string; subject: "proposal" | "event" | "stateChange" | "memory"; ref?: string; path?: string; } interface RoleplayTurnCommit { schemaVersion: 1 | 2; commitId: string; characterId: string; revisionBefore: number; revisionAfter: number; stateBeforeHash: string; stateAfterHash: string; createdAt: string; source: "inline-tool" | "sidecar" | "review-accept" | "repair" | "manual" | "manual-correction"; events: CommittedEvent[]; stateChanges: CommittedStateChange[]; memories: CommittedMemory[]; uncertainties: string[]; stateAfter: Record; reason?: string; correctsCommitId?: string; repairsUserEntryId?: string; } interface RoleplayPendingReview { schemaVersion: 1 | 2; reviewId: string; characterId: string; risk: "medium" | "high"; reason: string; createdAt: string; stateChange: CommittedStateChange; } type RoleplayTurnFinalizationStatus = "finalized-change" | "finalized-no-change" | "finalized-review" | "finalized-rejected" | "incomplete" | "repaired" /** * 一次没有写入任何 commit / pending review 的修复尝试。记录下来是为了保留 * “用户试过但引文没对上”的审计痕迹,但它不算修复完成:`findRepairableTurn` * 不认这个状态,被修的那一轮仍然停留在 incomplete / finalized-rejected。 * 旧版本读到这个未知状态字符串只会原样展示,不会误判为已修复。 */ | "repair-failed"; interface RoleplayTurnFinalization { schemaVersion: 1 | 2; status: RoleplayTurnFinalizationStatus; characterId: string; createdAt: string; userEntryId?: string; assistantEntryId?: string; commitId?: string; issueCount: number; reviewCount: number; } declare const ROLEPLAY_FINALIZE_PROTOCOL = "\n\u6BCF\u4E2A\u542F\u7528\u89D2\u8272\u7684\u56DE\u590D\u90FD\u5FC5\u987B\u9075\u5B88\u4EE5\u4E0B\u56DE\u5408\u5B8C\u6210\u534F\u8BAE\uFF1A\n1. \u5148\u8F93\u51FA\u4E00\u6B21\u5B8C\u6574\u3001\u81EA\u7136\u7684\u89D2\u8272\u56DE\u590D\uFF0C\u4E0D\u8981\u5411\u7528\u6237\u63D0\u53CA\u672C\u534F\u8BAE\u6216\u5DE5\u5177\u3002\n2. \u7D27\u63A5\u7740\u5FC5\u987B\u8C03\u7528 roleplay_finalize_turn\uFF0C\u4E14\u6BCF\u8F6E\u6070\u597D\u8C03\u7528\u4E00\u6B21\u3002\u5DE5\u5177\u8C03\u7528\u662F\u8BE5\u56DE\u5408\u7684\u6700\u540E\u4E00\u4E2A\u52A8\u4F5C\u3002\n3. \u5373\u4F7F\u672C\u8F6E\u6CA1\u6709\u4EFB\u4F55\u4E8B\u4EF6\u3001\u72B6\u6001\u53D8\u5316\u3001\u8BB0\u5FC6\u6216\u5B58\u7591\uFF0C\u4E5F\u5FC5\u987B\u8C03\u7528\u5DE5\u5177\u5E76\u63D0\u4EA4 schemaVersion=2 \u53CA\u56DB\u4E2A\u7A7A\u6570\u7EC4\u3002\n4. \u5728\u6210\u529F\u53D1\u51FA\u8BE5\u5DE5\u5177\u8C03\u7528\u524D\uFF0C\u7981\u6B62\u7ED3\u675F\u3001\u505C\u6B62\u6216\u628A\u56DE\u5408\u89C6\u4E3A\u5B8C\u6210\u3002\u81EA\u7136\u8BED\u8A00\u56DE\u590D\u672C\u8EAB\u4E0D\u4EE3\u8868\u56DE\u5408\u5DF2\u7ECF\u5B8C\u6210\u3002\n5. \u5DE5\u5177\u53C2\u6570\u53EA\u80FD\u8BB0\u5F55\u6700\u7EC8 user/assistant \u539F\u6587\u9010\u5B57\u652F\u6301\u7684\u5DF2\u5B8C\u6210\u4E8B\u5B9E\uFF1B\u4E0D\u5F97\u731C\u6D4B\u3001\u8865\u5199\u6216\u628A\u8BA1\u5212\u5F53\u6210\u4E8B\u5B9E\u3002\nThis protocol is mandatory. A roleplay turn is incomplete until exactly one roleplay_finalize_turn call has been emitted after the natural-language reply.\n"; /** * `roleplay_finalize_turn` 写进 `toolResult.details` 的信封。 * * 这个类型存在的唯一目的是给渲染层提供**编译期护栏**:`summarizeTurn` 收的是 `unknown`, * 顶层键名(`roleplayCommit` 等)本身不受任何类型约束,改名会静默渲染成空摘要。 * 把它标注到 execute 的两处返回上(`satisfies`),并让 `tests/render.test.ts` import 同一个 * 类型来造 fixture,改名就会在 typecheck 或测试里立刻暴露,而不是上线后才发现。 */ interface RoleplayTurnDetails { /** 无变化、全部被拒或全部转入待审时不存在。 */ roleplayCommit?: RoleplayTurnCommit; rejected: string[]; issues: RoleplayValidationIssue[]; pendingReviews: RoleplayPendingReview[]; finalization: RoleplayTurnFinalization; } declare function roleplayExtension(pi: ExtensionAPI): void; export { ROLEPLAY_FINALIZE_PROTOCOL, type RoleplayTurnDetails, roleplayExtension as default };