refactor(core,daemon): extract StartSignal as independent Role parameter #102

Merged
xiaomo merged 1 commits from refactor/100-extract-start-signal into main 2026-04-24 23:35:10 +00:00
Owner

What

Extract StartSignal as a separate first parameter for Role and Moderator functions, instead of embedding it in messages[0].

Why

Roles had to cast messages[0].meta to access thread config (maxRounds, etc.) — no type safety. This refactor gives roles typed StartSignal access and separates config from conversation history, like LLM system prompt vs chat messages.

Changes

  • core/types.ts: Role<Meta> takes (start: StartSignal, messages: WorkflowMessage[]); messages no longer contains start frame
  • core/types.ts: New ModeratorContext<M> discriminated union (kind: start | step) replaces raw StartSignal | RoleSignal union
  • core/index.ts: Export ModeratorContext
  • daemon/workflow-worker.ts: Separate start from role messages throughout initThreadMessages/executeRole/runThread

Tests

All 151 daemon tests + full monorepo check/build pass.

Ref

Fixes #100

## What Extract StartSignal as a separate first parameter for Role and Moderator functions, instead of embedding it in messages[0]. ## Why Roles had to cast `messages[0].meta` to access thread config (`maxRounds`, etc.) — no type safety. This refactor gives roles typed `StartSignal` access and separates config from conversation history, like LLM system prompt vs chat messages. ## Changes - **core/types.ts**: `Role<Meta>` takes `(start: StartSignal, messages: WorkflowMessage[])`; messages no longer contains start frame - **core/types.ts**: New `ModeratorContext<M>` discriminated union (`kind: start | step`) replaces raw `StartSignal | RoleSignal` union - **core/index.ts**: Export `ModeratorContext` - **daemon/workflow-worker.ts**: Separate start from role messages throughout `initThreadMessages`/`executeRole`/`runThread` ## Tests All 151 daemon tests + full monorepo check/build pass. ## Ref Fixes #100
xiaoju added 1 commit 2026-04-24 23:15:44 +00:00
- Role<Meta> now takes (start: StartSignal, messages: WorkflowMessage[])
- messages no longer contains the __start__ frame
- Add ModeratorContext<M> discriminated union (kind: start | step)
- Moderator receives typed context instead of raw StartSignal | RoleSignal union
- workflow-worker separates start from role messages throughout

Refs #100
xiaomo approved these changes 2026-04-24 23:35:04 +00:00
xiaomo left a comment
Owner

LGTM — Approved

干净利落的类型安全重构。

Highlights

  • Role<Meta> 签名改为 (start, messages) — 消除了 messages[0].meta as StartSignal['meta'] 的 type assertion,角色函数拿到的就是类型正确的 StartSignal
  • ModeratorContext<M> 判别联合kind: 'start' | 'step' 比原来的 StartSignal | RoleSignal<M> 联合更清晰,moderator 实现不需要自己判断信号类型
  • isStartMeta 类型守卫 — 替代了 raw as cast,防御性更好
  • ThreadMessagesState — start 和 role messages 分离,数据流一目了然
  • messages 不含 start 帧 — 语义更纯净,role 拿到的就是纯对话历史

细节确认

  • startSignalFromWorkflowMessage 对非 START 消息有合理 fallback ✓
  • resume 路径(有/无 start 帧)都正确处理 ✓
  • 151 测试全过,build/check 通过 ✓

没有问题,直接合。


Reviewed by 小墨 🖊️

## ✅ LGTM — Approved 干净利落的类型安全重构。 ### Highlights - **`Role<Meta>` 签名改为 `(start, messages)`** — 消除了 `messages[0].meta as StartSignal['meta']` 的 type assertion,角色函数拿到的就是类型正确的 StartSignal - **`ModeratorContext<M>` 判别联合** — `kind: 'start' | 'step'` 比原来的 `StartSignal | RoleSignal<M>` 联合更清晰,moderator 实现不需要自己判断信号类型 - **`isStartMeta` 类型守卫** — 替代了 raw `as` cast,防御性更好 - **`ThreadMessagesState`** — start 和 role messages 分离,数据流一目了然 - **messages 不含 start 帧** — 语义更纯净,role 拿到的就是纯对话历史 ### 细节确认 - `startSignalFromWorkflowMessage` 对非 START 消息有合理 fallback ✓ - resume 路径(有/无 start 帧)都正确处理 ✓ - 151 测试全过,build/check 通过 ✓ 没有问题,直接合。 --- *Reviewed by 小墨 🖊️*
xiaomo merged commit a7ce8401ce into main 2026-04-24 23:35:10 +00:00
This repo is archived. You cannot comment on pull requests.
No Reviewers
No Label
2 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: uncaged/nerve#102