feat(runtime): document 内容类型与持久化(design/24 S2)
- model 新增 ContentTypeDocument + Content 的四字段 + DocumentMessage 构造器 + ValidateDocumentParts(文档部件只允许 RoleUser,非 user ⇒ ErrDocumentOnNonUser,fail-loud)。 - 两个编码器入口(buildMessages / buildAnthropicMessages)对文档部件报 ErrBadRequest: 本期 document 永不抵达编码器,且绝不静默丢块。 - history:拆出 types.go(Message 增 Document 列),新增 document.go(DocumentRef 同时是 落库 JSON 与 DTO 形状,6 字段含 status ⇒ §4.4 的「读不到要可见」;坏列回 unreadable 不静默)。 - chat_messages 加 document 列(迁移 0015 + NewStore 幂等前滚);historyMessage.Document DTO; session_persist 的 messageTextImage → messageTextImageDocument(保留窄视图以免牵连 steer 配对)。 - 只落「引用 + 统计」,绝不落抽取正文(TestPersistedDocumentHoldsNoBody 把全部列拼起来扫正文)。 验收(主会话独立复跑,非自报):隔离 worktree(HEAD + 本切片)go build/vet 绿、 全树 58 包 0 FAIL、linux/amd64 + darwin/arm64 交叉编译绿、18 条 Document* 测试 PASS。 变异独立复现:ValidateDocumentParts 开头 return nil ⇒ 非 user 负例红。
This commit is contained in:
1 parent
407c934a05
commit
6b2b07cbef
15 files changed
+895
-101
No files matched your search
@@ -128,7 +128,13 @@ func (a *OpenAIChatAdapter) buildRequest(req Request, stream bool) ([]byte, erro
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
// buildMessages 把归一化消息列表逐条渲染成 OpenAI 线格式,并在入口拒绝
|
||||
// 挂在非用户回合上的文档部件(design/24 §2.3-③):文档本期永不抵达编码器,
|
||||
// 漏网即编程错误,绝不静默丢块。
|
||||
func buildMessages(msgs []Message) ([]openAIMessage, error) {
|
||||
if err := ValidateDocumentParts(msgs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]openAIMessage, 0, len(msgs))
|
||||
for _, m := range msgs {
|
||||
wire, err := encodeOpenAIMessage(m)
|
||||
@@ -196,6 +202,10 @@ func encodeToolCalls(parts []Content) []openAIToolCall {
|
||||
return calls
|
||||
}
|
||||
|
||||
// encodeContent 把归一化内容片段转成 OpenAI 的内容字段(纯文本、或
|
||||
// 文本/图片片段数组)。文档片段不走这里:本期不向提供商发任何文档块
|
||||
// (design/24 §2.3-②:形状不对就是 400),因此它落到 default 分支被
|
||||
// 拒绝 —— fail-loud,绝不静默丢块。
|
||||
func encodeContent(parts []Content) (any, error) {
|
||||
if len(parts) == 0 {
|
||||
return "", nil
|
||||
|
||||
Reference in new issue
Block a user