Initial commit

This commit is contained in:
2026-07-10 08:31:27 +08:00
commit 2b74c30d36
134 changed files with 21801 additions and 0 deletions
+29
View File
@@ -0,0 +1,29 @@
/** worker 读取多条同 tag 时的合并策略 */
export type BlackboardInputMerge = "latest" | "concat";
export type BlackboardItem = {
id: string;
tag: string;
content: string;
source: string;
scope?: string;
createdAt: string;
updatedAt: string;
dependencies?: string[];
metadata?: Record<string, unknown>;
};
/** 总管可见:无 content */
export type BlackboardTagIndex = Pick<
BlackboardItem,
"id" | "tag" | "source" | "scope" | "updatedAt"
>;
export type BlackboardWriteInput = {
tag: string;
content: string;
source: string;
scope?: string;
dependencies?: string[];
metadata?: Record<string, unknown>;
};
+34
View File
@@ -0,0 +1,34 @@
import type { BlackboardItem } from "../types/blackboard.js";
import type { RuntimeSession } from "../types/runtime.js";
/** 磁盘上保存的 Book 绑定的 Session 快照(用于续作) */
export type PersistedBookSession = {
version: 1;
sessionId: string;
bookId: string;
orchestratorId?: string;
runtimeSession: RuntimeSession;
blackboardItems: BlackboardItem[];
messages: PersistedChatMessage[];
savedAt: string;
};
/** 与 session-manager ChatMessage 同形,独立类型避免循环依赖 */
export type PersistedChatMessage = {
id: string;
role: "system" | "user";
text: string;
createdAt: string;
kind?: string;
actor?: string;
title?: string;
body?: string;
thinking?: string;
tokenUsage?: {
totalTokens: number;
cachedTokens?: number;
cacheMissTokens?: number;
caller?: string;
model?: string;
};
};
+37
View File
@@ -0,0 +1,37 @@
export type BookProject = {
id: string;
title: string;
/** 用户选定或 agent 确认的 skill 包 */
activeSkillId?: string;
activeSkillName?: string;
preview: string;
sessionIds: string[];
/** 最近一次持久化的 sessionId,用于续作 */
activeSessionId?: string;
createdAt: string;
updatedAt: string;
/** @deprecated 旧字段,等同 activeSkillId */
orchestratorId?: string;
/** @deprecated 旧字段,等同 activeSkillName */
orchestratorName?: string;
};
export type BookSummary = Pick<
BookProject,
| "id"
| "title"
| "activeSkillId"
| "activeSkillName"
| "preview"
| "updatedAt"
| "orchestratorId"
| "orchestratorName"
>;
export type SkillPackInfo = {
id: string;
name: string;
description: string;
category: string;
bookKind?: string;
};
+26
View File
@@ -0,0 +1,26 @@
/** 启动「填空题」字段定义(来自 SKILL ## 启动询问) */
export type IntakeFieldDef = {
id: string;
label: string;
required: boolean;
};
/** 单字段展示状态 */
export type IntakeFieldStatus = {
id: string;
label: string;
required: boolean;
value?: string;
filled: boolean;
};
/** 填空进度(供 Web 展示) */
export type IntakeProgress = {
fields: IntakeFieldStatus[];
requiredTotal: number;
requiredFilled: number;
optionalTotal: number;
optionalFilled: number;
/** 全部必要项已填 */
ready: boolean;
};
+66
View File
@@ -0,0 +1,66 @@
export type PresetPromptRole = "system" | "user" | "assistant";
export type PresetPromptEntry = {
id: string;
name: string;
enabled: boolean;
role: PresetPromptRole;
content: string;
marker: boolean;
sourceIdentifier: string;
injection?: {
position?: number;
depth?: number;
order?: number;
};
};
export type PresetPromptOrderItem = {
promptId: string;
enabled: boolean;
orderIndex: number;
};
export type GenerationParameters = {
temperature?: number;
topP?: number;
topK?: number;
minP?: number;
frequencyPenalty?: number;
presencePenalty?: number;
repetitionPenalty?: number;
maxContextTokens?: number;
maxOutputTokens?: number;
stream?: boolean;
reasoningEffort?: string;
verbosity?: string;
seed?: number;
variants?: number;
};
export type UnsupportedPresetSection = {
path: string;
reason: string;
};
export type PresetPackage = {
id: string;
name: string;
source: "native" | "sillytavern";
prompts: PresetPromptEntry[];
promptOrder: PresetPromptOrderItem[];
generation: GenerationParameters;
unsupported: UnsupportedPresetSection[];
importedAt: string;
raw?: unknown;
};
export type PresetImportReport = {
preset: PresetPackage;
promptCount: number;
enabledCount: number;
unreferencedCount: number;
missingIdentifiers: string[];
generationFields: string[];
warnings: string[];
};
+56
View File
@@ -0,0 +1,56 @@
import type { BlackboardItem } from "./blackboard.js";
import type { PersistedChatMessage } from "./book-session.js";
import type { RuntimeSession } from "./runtime.js";
/** 实例化完成后的对象,或 run 中某一时刻的完整进度 */
export type SnapshotKind = "instance" | "run";
/**
* Book 快照(手动保存,可多档)
* - instance:实例化后的对象(情境、规则、角色设定等),用于复用思想实验框架、换角色重跑
* - run:运行存档,含轮次进度,读档后续玩
*/
export type RunSnapshot = {
version: 1;
id: string;
bookId: string;
label: string;
kind: SnapshotKind;
/** skill 包 id(兼容旧字段名) */
orchestratorId?: string;
runtimeSession: RuntimeSession;
blackboardItems: BlackboardItem[];
/** 保存时的对话;实例快照通常较短(到 setup 验收为止) */
messages: PersistedChatMessage[];
createdAt: string;
note?: string;
};
/** 列表展示用,不含正文 payload */
export type RunSnapshotMeta = {
id: string;
bookId: string;
label: string;
kind: SnapshotKind;
/** skill 包 id(兼容旧字段名) */
orchestratorId?: string;
createdAt: string;
note?: string;
};
export function toRunSnapshotMeta(snapshot: RunSnapshot): RunSnapshotMeta {
return {
id: snapshot.id,
bookId: snapshot.bookId,
label: snapshot.label,
kind: snapshot.kind,
orchestratorId: snapshot.orchestratorId,
createdAt: snapshot.createdAt,
note: snapshot.note,
};
}
export const SNAPSHOT_KIND_LABELS: Record<SnapshotKind, string> = {
instance: "实例",
run: "进度",
};
+257
View File
@@ -0,0 +1,257 @@
/**
* 运行阶段机类型契约。
*
* 设计原则:
* - 运行相位(RuntimePhase)只有 5 种,表示「系统在等什么」
* - 业务细节不扩 phase,而用 waitingReason、slots、artifacts 承载
* - LLM / 总管不能直接改 phase,只能通过 RuntimeEvent 驱动 applyEvent
*/
import type { IntakeFieldDef } from "./intake.js";
/** 运行相位:系统当前在等什么。只有 5 种。 */
export type RuntimePhase =
| "idle" // 会话已创建,尚未开始
| "running" // 正在推进(总管决策、worker 执行、程序验收)
| "waiting_user" // 等待用户介入
| "done" // 流程正常结束
| "error"; // 不可恢复错误
/**
* waiting_user 时的具体原因。
* 用单一 phase + reason 替代多个独立 status,避免「胖状态机」。
*/
export type WaitingReason =
| { kind: "skill_selection"; availableSkills: SkillIndexEntry[] } // 启动:选 SKILL.md
| { kind: "intake"; prompt: string } // 启动填空:必要/可选项收集
| { kind: "input"; message?: string } // 总管 ask_user / 返工说明(启动完成后)
| { kind: "approve_step"; decisionId: string } // 总管建议 run_worker,等用户确认
| { kind: "review_artifact"; artifactId: string } // worker 产物待验收
| { kind: "worker_questions"; workerId: string; questions: string[] } // worker 中途提问
| { kind: "revision"; instruction?: string }; // 产物被拒或程序验收失败
/** 与 src/skills/types 对齐的最小 skill 索引字段,避免 runtime 强依赖 skills 模块 */
export type SkillIndexEntry = {
name: string;
description: string;
category: string;
};
/**
* Book 存储形态(由 SKILL.md 选定,选 skill 后不可变更)。
* 第一版仅两种:小说线性结构 / 多轮多角色对话。
*/
export type BookKind = "novel" | "dialogue";
/** 选中的 skill 快照,写入 session.slots.activeSkill,供启动询问与后续流程使用 */
export type ActiveSkillSnapshot = {
name: string;
description: string;
category: string;
/** 选定 skill 时确定,对应 Book 最终产物结构 */
bookKind?: BookKind;
defaultFlowId?: string;
suggestedWorkers: string[];
/** 来自 SKILL.md ## 启动询问 的展示文案 */
startupPrompt: string;
/** 用户首次输入写入的 slots 键,如 book.brief */
startupTargetKey: string;
/** 启动填空字段(必要 + 可选) */
intakeFields: IntakeFieldDef[];
};
/** worker 产物验收方式 */
export type AcceptanceMode =
| "user_confirmed" // 默认:产物完成后等用户验收
| "no_confirmation" // 自动接受,直接回到总管
| "programmatic_review"; // 走程序验收规则
/**
* Worker 链推进模式(预留)。
*
* - manual:默认。每次 run_worker 可要求 approve_step;产物默认 user_confirmed。
* - semi_auto:半自动串联 worker;仅在 skill 声明的 pauseCheckpoint 处强制暂停。
*
* 第一版 Runtime 仅实现 manual;semi_auto 由 orchestrator 文档化,待后续接入。
* 见 docs/runtime-state-machine.md §10、docs/orchestrator-skill-format.md §10。
*/
export type WorkerAdvanceMode = "manual" | "semi_auto";
/**
* semi_auto 下的暂停检查点(由各 skill 在 orchestrator 中声明)。
*
* `when` 为 skill 自定义的暂停条件描述或未来可解析的表达式;
* 具体变量(轮次、token 预算、阶段界等)不由全局 enum 限定。
*/
export type AdvancePauseCheckpoint = {
id: string;
description: string;
/** 文档化条件;未来可绑定 slot / tag / 计数器,现阶段 Runtime 不解析 */
when?: string;
};
/**
* 会话级 worker 推进策略(预留)。
* 未设置或未解析时等价 `{ mode: "manual" }`。
*/
export type AdvancePolicy = {
mode: WorkerAdvanceMode;
pauseCheckpoints?: AdvancePauseCheckpoint[];
};
/** 总管(Main Agent)可执行的意图,对应 tool call 的 action 字段 */
export type MainAgentAction =
| "ask_user" // 向用户提问
| "run_worker" // 调度已有 worker
| "create_temp_worker" // 临时 worker(与 run_worker 共用阶段机分支)
| "review_blackboard" // 查看黑板后向用户说明
| "finish"; // 结束流程
/**
* 总管的一次决策。
* statePatchAllowed 必须为 false,禁止 LLM 直接 patch 会话状态。
*/
export type MainAgentDecision = {
id: string;
action: MainAgentAction;
reason: string;
workerId?: string;
/** 调度 role-decide 等时指定当前决策角色,Runtime 写入 世界.当前角色.id */
workerContext?: { roleId?: string };
/** true 时进入 waiting_user(approve_step),等用户确认后才 run_worker */
requiresApproval: boolean;
statePatchAllowed: false;
};
/** worker 产物的生命周期状态 */
export type ArtifactStatus =
| "drafted"
| "under_review"
| "accepted"
| "rejected"
| "revision_requested"
| "superseded";
/** worker 产出的一条产物记录 */
export type ArtifactRecord = {
id: string;
workerId: string;
stepId?: string;
outputTags: string[];
status: ArtifactStatus;
summary?: string;
createdAt: string;
updatedAt: string;
};
/** worker 因 ask_user 中途暂停时保存的上下文,用户回复后用于 resume_worker */
export type ResumeContext = {
workerId: string;
stepId?: string;
acceptanceMode: AcceptanceMode;
questions: string[];
};
/**
* 阶段机唯一合法的状态变更入口。
* 所有 phase 转移都必须通过 dispatch → applyEvent 处理某种 RuntimeEvent。
*/
export type RuntimeEvent =
| {
type: "session_started";
payload: { presetId: string; flowId?: string; availableSkills: SkillIndexEntry[] };
}
| { type: "skill_selected"; payload: { skill: ActiveSkillSnapshot } }
| {
type: "user_submitted_input";
payload: { text: string; intakeValues?: Record<string, string> };
}
| { type: "user_confirmed_intake"; payload: Record<string, never> }
| {
type: "main_agent_decision_created";
payload: { decision: MainAgentDecision };
}
| { type: "user_approved_next_step"; payload: { decisionId: string } }
| {
type: "user_rejected_next_step";
payload: { decisionId: string; reason?: string };
}
| {
type: "worker_started";
payload: {
workerId: string;
stepId?: string;
acceptanceMode: AcceptanceMode;
};
}
| { type: "worker_completed"; payload: { artifactId: string } }
| {
type: "worker_needs_input";
payload: { workerId: string; stepId?: string; questions: string[] };
}
| { type: "user_accepted_artifact"; payload: { artifactId: string } }
| {
type: "user_rejected_artifact";
payload: { artifactId: string; reason?: string };
}
| {
type: "user_requested_revision";
payload: { artifactId?: string; instruction: string };
}
| { type: "programmatic_review_started"; payload: { artifactId: string } }
| { type: "programmatic_review_passed"; payload: { artifactId: string } }
| {
type: "programmatic_review_failed";
payload: { artifactId: string; reason: string };
}
| { type: "flow_completed"; payload: Record<string, never> }
| { type: "runtime_failed"; payload: { reason: string } };
/** 一次会话的完整运行时快照 */
export type RuntimeSession = {
id: string;
phase: RuntimePhase;
waitingReason?: WaitingReason;
presetId: string;
flowId?: string;
/** 业务 flow 当前步骤(execution flow 层,与 phase 正交) */
currentStepId?: string;
currentWorkerId?: string;
acceptanceMode?: AcceptanceMode;
/** 推进策略(预留)。缺省 = manual,见 WorkerAdvanceMode */
advancePolicy?: AdvancePolicy;
reviewRequirements?: string[];
resumeContext?: ResumeContext;
/** 轻量槽位:activeSkill、book.brief、startupCompleted 等 */
slots: Record<string, unknown>;
artifacts: ArtifactRecord[];
/** 待用户确认的总管决策(approve_step 时有效) */
pendingDecision?: MainAgentDecision;
/** 待验收的产物 id(review_artifact 时有效) */
pendingArtifactId?: string;
/** 已应用的 RuntimeEvent 日志,便于调试与回放 */
history: RuntimeEvent[];
createdAt: string;
updatedAt: string;
};
/**
* applyEvent 返回的副作用清单。
* 纯函数 phase-machine 不执行 IO,由 phase-runtime 的 processEffects 消费。
*/
export type PhaseEffect =
| { type: "invoke_main_agent" }
| { type: "run_worker"; workerId: string; workerContext?: { roleId?: string } }
| { type: "resume_worker" }
| { type: "run_programmatic_review"; artifactId: string }
| { type: "emit_message"; message: string };
/** applyEvent 的返回值:新会话快照 + 待处理副作用 + 可选错误 */
export type ApplyEventResult = {
session: RuntimeSession;
effects: PhaseEffect[];
error?: string;
};
/** @deprecated 使用 RuntimePhase */
export type RuntimeStatus = RuntimePhase;
+61
View File
@@ -0,0 +1,61 @@
/** 总管 tool 名称 */
export type MainAgentToolName =
| "read_blackboard"
| "list_workers"
| "list_artifacts"
| "ask_user"
| "run_worker"
| "review_blackboard"
| "finish";
/** 可在 tool loop 内反复调用、不改变运行相位的 tool */
export const MAIN_AGENT_LOOP_TOOLS: MainAgentToolName[] = [
"read_blackboard",
"list_workers",
"list_artifacts",
];
/** 调用后应退出 loop、交给阶段机的终止 tool */
export const MAIN_AGENT_TERMINAL_TOOLS: MainAgentToolName[] = [
"ask_user",
"run_worker",
"review_blackboard",
"finish",
];
export function isMainAgentTerminalTool(name: string): name is MainAgentToolName {
return (MAIN_AGENT_TERMINAL_TOOLS as string[]).includes(name);
}
export function isMainAgentLoopTool(name: string): name is MainAgentToolName {
return (MAIN_AGENT_LOOP_TOOLS as string[]).includes(name);
}
export type ReadBlackboardParams = {
tags: string[];
};
export type ListWorkersParams = Record<string, never>;
export type ListArtifactsParams = Record<string, never>;
export type AskUserParams = {
reason: string;
message?: string;
};
export type RunWorkerParams = {
workerId: string;
reason: string;
requiresApproval: boolean;
roleId?: string;
};
export type ReviewBlackboardParams = {
reason: string;
summary: string;
};
export type FinishParams = {
reason: string;
};