Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ go run ./cmd/neocode
- **`internal/provider/catalog`** — 模型发现、catalog 缓存与后台刷新
- **`internal/provider/selection`** — provider/model 选择与配置同步
- **`internal/provider/builtin`** — 内建 driver 注册
- **`internal/runtime`** — ReAct 主循环、事件流、会话管理
- **`internal/runtime`** — ReAct 主循环与事件流编排(不直接承载会话存储实现;不再导出会话模型与存储类型)
- **`internal/session`** — 会话模型、会话存储抽象与 JSON 持久化实现(统一对外暴露 `Session` / `Summary` / `Store`)
- **`internal/tools`** — 工具注册表与具体工具实现
- **`internal/tui`** — 终端 UI、交互体验、事件桥接
- **`internal/app`** — 应用装配与依赖注入
Expand All @@ -116,6 +117,7 @@ go run ./cmd/neocode
│ │ ├── catalog # 模型发现与缓存
│ │ └── selection # provider/model 选择服务
│ ├── runtime # ReAct 循环与事件流
│ ├── session # 会话模型与持久化
│ ├── tools # 工具系统
│ └── tui # 终端 UI
└── README.md
Expand Down
16 changes: 13 additions & 3 deletions docs/session-persistence-design.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
# Session 持久化设计

## 模块职责与收口边界
- `internal/session`:承载会话领域模型、存储抽象与 JSON 持久化实现,是唯一的会话持久化实现归属层
- `internal/runtime`:只依赖 `internal/session` 提供的抽象与模型,负责会话保存时机与主循环编排,不再维护会话存储实现细节
- `internal/tui`:仅消费 runtime 暴露的会话数据,不直接执行会话持久化

## 存储策略
NeoCode 在 MVP 阶段使用 JSON 文件持久化 Session,以保持本地优先、易于调试和跨平台可移植。

## 数据模型
- `Session`:完整消息历史以及 `id`、`title`、`updated_at` 等元信息
- `SessionSummary`:用于侧边栏的轻量摘要结构
- `Summary`:用于侧边栏的轻量摘要结构(原 `SessionSummary` 命名已统一收口为 `Summary`)

## 加载策略
- `ListSummaries` 只读取渲染侧边栏所需的基础信息
- `Load` 仅在用户真正进入某个会话时读取完整消息历史
- `Save` 通过临时文件原子写入完整 Session

## 命名策略
- 新会话默认展示为 `Draft`
- 新会话默认展示为 `New Session`
- 一旦持久化,runtime 会根据首轮用户消息生成简短标题

## 并发约束
- SessionStore 实现必须自行保护共享访问
- `internal/session` 中的 Store 实现必须自行保护共享访问
- 真正的保存时机由 runtime 决定,TUI 不负责直接触发磁盘写入

## 兼容性与演进说明
- 会话持久化能力已从 runtime 侧实现中彻底收口到 `internal/session`
- 新增会话存储实现时,应优先在 `internal/session` 内扩展并通过接口注入 runtime,避免跨层实现
50 changes: 0 additions & 50 deletions docs/tool-execution-toctou.md

This file was deleted.

3 changes: 2 additions & 1 deletion internal/app/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
providercatalog "neo-code/internal/provider/catalog"
agentruntime "neo-code/internal/runtime"
"neo-code/internal/security"
agentsession "neo-code/internal/session"
"neo-code/internal/tools"
"neo-code/internal/tools/bash"
"neo-code/internal/tools/filesystem"
Expand Down Expand Up @@ -62,7 +63,7 @@ func NewProgram(ctx context.Context) (*tea.Program, error) {
return nil, err
}

sessionStore := agentruntime.NewSessionStore(loader.BaseDir())
sessionStore := agentsession.NewStore(loader.BaseDir())
runtimeSvc := agentruntime.NewWithFactory(
manager,
toolManager,
Expand Down
4 changes: 2 additions & 2 deletions internal/context/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package context
import (
"context"

"neo-code/internal/provider"
providertypes "neo-code/internal/provider/types"
)

// DefaultBuilder preserves the current runtime context-building behavior.
Expand Down Expand Up @@ -59,7 +59,7 @@ func (b *DefaultBuilder) Build(ctx context.Context, input BuildInput) (BuildResu
}

// applyReadTimeContextProjection 负责在 provider 请求前按开关应用只读上下文投影,避免改写原始会话消息。
func applyReadTimeContextProjection(messages []provider.Message, options CompactOptions, policies MicroCompactPolicySource) []provider.Message {
func applyReadTimeContextProjection(messages []providertypes.Message, options CompactOptions, policies MicroCompactPolicySource) []providertypes.Message {
if options.DisableMicroCompact {
return cloneContextMessages(messages)
}
Expand Down
Loading
Loading