Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
2216229
docs: add main-session decouple spec and plan
uchouT May 17, 2026
121d8dc
refactor(session): drop role/tags/metadata from SessionMeta
uchouT May 17, 2026
2d5219e
test(session): tighten meta/lifecycle tests after SessionMeta trim
uchouT May 17, 2026
9979b8f
refactor(session): merge MainStorage into SessionStorage
uchouT May 17, 2026
61a7622
refactor(session): delete MainSession interface, factory, and dedicat…
uchouT May 17, 2026
e0aaa39
test(session): drop duplicate trimRecords case and add prompt orderin…
uchouT May 17, 2026
77f044e
refactor(core): drop MAIN_SESSION_ID, unify SessionTree interface ske…
uchouT May 17, 2026
cc9b3d5
refactor(core): drop MainSessionConfig types
uchouT May 17, 2026
ea629f0
refactor(core): drop MainSessionCompatible/SessionCompatibleIntegrate…
uchouT May 17, 2026
f89a6a4
refactor(core): drop createDefaultIntegrateFn and DEFAULT_INTEGRATE_P…
uchouT May 17, 2026
bbaf24e
refactor(core): unify SessionTreeImpl under createSession with multi-…
uchouT May 17, 2026
c33dcc7
test(core): replace fork-from-main skipped tests with root-fork test
uchouT May 17, 2026
556eda7
refactor(core): remove createMainSession/integrate from StelloAgent; …
uchouT May 17, 2026
5321929
feat(core): add orchestrator-facing topology SDK on StelloAgent
uchouT May 17, 2026
c935672
feat(core): add storage injection and data-IO SDK on StelloAgent
uchouT May 17, 2026
4937898
chore(release): main-session decouple — session@0.8.0 + core@0.10.0
uchouT May 17, 2026
a105227
docs: add main-session decouple migration guide
uchouT May 17, 2026
3337f20
docs: update docs about this refactor
uchouT May 18, 2026
0968e64
feat: expose single digest read API
uchouT May 19, 2026
e3ada36
feat(core): shared memory system (#64)
uchouT May 20, 2026
ca2021c
feat: session storage compression cache (#65)
uchouT May 20, 2026
390beff
feat(core): add forkCompressFn field and DEFAULT_FORK_COMPRESS_PROMPT
uchouT May 20, 2026
c2a4e30
style(core): normalize punctuation in DEFAULT_FORK_COMPRESS_PROMPT to…
uchouT May 20, 2026
864bc39
feat(core): merge forkCompressFn through layered session config
uchouT May 20, 2026
7634b3a
feat(core): applyCompressContext prefers forkCompressFn over compressFn
uchouT May 20, 2026
3286136
refactor(core): drop summary field from SharedMemoryEntry
uchouT May 22, 2026
9bb89b6
refactor(core): InMemorySharedMemoryStore drops summary param
uchouT May 22, 2026
9088d70
refactor(core): replace renderSharedMemoryIndex with renderSharedMemo…
uchouT May 22, 2026
5611baa
refactor(core): collapse memory tools into single memoryEditTool
uchouT May 22, 2026
8d7a6f5
refactor(core): StelloAgent.upsertSharedMemoryEntry drops summary param
uchouT May 22, 2026
27324f5
refactor(core): rename sharedMemoryIndex to sharedMemoryContext in ad…
uchouT May 22, 2026
f37a4ce
refactor(core): update exports for shared memory simplification
uchouT May 22, 2026
8beb7e0
refactor(session): rename sharedMemoryIndex to sharedMemoryContext
uchouT May 22, 2026
58c3140
Feat/topology render lift (#66)
uchouT May 27, 2026
555dd60
feat(session): 支持推理模型 reasoning_content 多轮对话回传
May 28, 2026
12fd735
Merge pull request #67 from stello-agent/feat/reasoning-content-round…
Ec3o May 28, 2026
d4d215f
feat(session): attach turn metadata
May 29, 2026
94f81b5
Merge pull request #68 from stello-agent/feature/chat-turn-actions
Ec3o May 29, 2026
1ccbafa
feat: support multimodal content parts
May 31, 2026
0c021be
Merge pull request #69 from stello-agent/feature/stepfun-multimodal-c…
Ec3o May 31, 2026
81bb989
feat: builtin tools support (#70)
uchouT May 31, 2026
1d3a64f
fix lint failures
Ec3o Jun 2, 2026
dfcf386
fix default llm tests typecheck
Ec3o Jun 2, 2026
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: 2 additions & 2 deletions .agents/skills/engine-design/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Engine 不感知树结构,不知道其他 Session 的存在,**也不感知

**做**:tool call 循环、consolidate() 执行、hooks fire-and-forget、生命周期边界(enter/leave/archive/fork)、fork 编排(拓扑 + session 创建)、内置 tool 注册与执行(通过 CompositeToolRuntime 统一调度)、error 事件 emit

**不做**:调度时机判断(由 Factory hook 内联)、持有 MainSession、Session 切换检测(Orchestrator)、多 Session 管理
**不做**:调度时机判断(由 Factory hook 内联)、持有跨 Session 状态(全局反思层由应用层在 StelloAgent 之外实现)、Session 切换检测(Orchestrator)、多 Session 管理

---

Expand All @@ -41,7 +41,7 @@ fork 选项中的 `consolidateFn` 和 `compressFn` 遵循继承链:fork 时指

### Consolidation 触发内联到 Factory hook

Engine 不持有 Scheduler 或 MainSession。Consolidation 触发逻辑(如 `consolidateEveryNTurns`)由 Factory 构建闭包注入 EngineHooks。Engine 在事件点 fire-and-forget 调用 hooks,不知道背后有调度。
Engine 不持有 Scheduler,也不感知"全局反思"概念。Consolidation 触发逻辑(如 `consolidateEveryNTurns`)由 Factory 构建闭包注入 EngineHooks。Engine 在事件点 fire-and-forget 调用 hooks,不知道背后有调度。

### turn() 返回值

Expand Down
6 changes: 3 additions & 3 deletions .agents/skills/fork-design/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ sessionDefaults → parent(固化 config) → profile → forkOptions

| 场景 | 合成链贡献 |
|------|----------|
| 从 main session fork | parent 层 = undefined(main 不参与合成链) |
| 从 regular session fork | parent 层 = 该 session 的 `SerializableSessionConfig`(只有 systemPrompt/skills) |
| 从 root session fork | parent 层 = root 的 `SerializableSessionConfig`(root 是普通 session,正常参与合成链) |
| 从非 root session fork | parent 层 = 该 session 的 `SerializableSessionConfig`(只有 systemPrompt/skills) |
| 无 profile 的普通 fork | profile 层 = undefined |
| Profile + options 都提供 llm | 结果取 options 的 llm |
| Profile 提供 llm,options 不提供 | 结果取 profile 的 llm |
Expand Down Expand Up @@ -267,5 +267,5 @@ LLM 在 prepend 模式下可通过 `systemPrompt` 参数补充具体任务约束
3. **undefined 不覆盖** — 保证"某层不传"等价于"使用下层值"的直觉
4. **skills 显式 `[]` 能生效** — 与 undefined 区分,让"禁用"成为可表达的意图
5. **只固化 systemPrompt + skills** — 可序列化字段有限,其余字段每次 fork 现场合成
6. **从 main session fork 不继承 main 的配置** — main 不参与 regular session 的合成链
6. **root 是普通 session** — root 的固化 systemPrompt/skills 通过 parent 层正常进入子 session 的合成链,没有任何特殊豁免
7. **topologyParentId 与 sourceSessionId 分离** — 编排层的拓扑策略和上下文继承是两个独立维度
81 changes: 28 additions & 53 deletions .agents/skills/llm-call-sites/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,38 @@
---
name: llm-call-sites
description: Stello 框架内所有 LLM 调用位置的消息结构速查。覆盖 MainSession 对话、普通 Session 对话、compress、consolidate、integrate
description: Stello 框架内所有 LLM 调用位置的消息结构速查。覆盖 Session 对话、compress、consolidate;应用层 reflection 调用由 orchestrator 自行决定
---

# LLM 调用消息结构

Stello 里所有 LLM 调用的 `messages` 参数构成。
Stello 里所有 LLM 调用的 `messages` 参数构成。Session 同构——root 与 child 走同一套上下文组装规则,差异只在 `meta.label`。

---

## 1. MainSession 对话
## 1. Session 对话

```
[
{ role: 'system', content: systemPrompt }, // 若非空
{ role: 'system', content: synthesis }, // 若非空(始终注入)
{ role: 'system', content: compressSummary }, // 仅当触发自动压缩
...recentL3History, // user / assistant / tool
{ role: 'system', content: systemPrompt }, // 可能含 <parent_context> 块;若非空
{ role: 'system', content: <session_identity> }, // 若 meta.label 非空
{ role: 'system', content: insight }, // 若非空,消费后清除
{ role: 'system', content: compressSummary }, // 仅当触发自动压缩
...recentL3History, // user / assistant / tool
{ role: 'user', content: userInput },
]
```

`tools` 经 `llm.complete(messages, { tools })` 第二参数传入,不进 messages。

MainSession **不**注入 `<session_identity>`(只对普通 session 注入身份标签)。

---

## 2. 普通 Session 对话

```
[
{ role: 'system', content: systemPrompt }, // 可能含 <parent_context> 块
{ role: 'system', content: <session_identity> },// 若 meta.label 非空(子 session 总是非空)
{ role: 'system', content: insight }, // 若非空,消费后清除
{ role: 'system', content: compressSummary }, // 仅当触发自动压缩
...recentL3History,
{ role: 'user', content: userInput },
]
```

与 MainSession 的差异:第二槽位是 `insight`(一次性)而非 `synthesis`;此外多一条 `<session_identity>` 注入在 systemPrompt 之后。

`<session_identity>` 形态:
`<session_identity>` 形态(label 缺省则该消息不注入):

```
<session_identity>
你当前在「{meta.label}」子会话中。
</session_identity>
```

label 改名(`updateMeta({ label })`)后下次 send 自动同步,无需重写持久化的 systemPrompt。
label 改名后下次 send 自动同步,无需重写持久化的 systemPrompt。

`systemPrompt` 在 fork-compress 场景形态:

Expand All @@ -62,9 +44,11 @@ label 改名(`updateMeta({ label })`)后下次 send 自动同步,无需重
</parent_context>
```

所有 Session 同构走这套规则。Root 也是普通 Session,差异只在 `meta.label`。如需在 root 上注入"全局综合",应用层把综合结果通过 `putInsight(rootId, content)` 一次性写入即可。`memory` 槽位**不进入** send() 上下文。

---

## 3. Compress
## 2. Compress

```
[
Expand All @@ -82,7 +66,7 @@ label 改名(`updateMeta({ label })`)后下次 send 自动同步,无需重

---

## 4. Consolidate(L3→L2
## 3. Consolidate(L3 → memory

```
[
Expand All @@ -95,49 +79,40 @@ label 改名(`updateMeta({ label })`)后下次 send 自动同步,无需重
]
```

- `currentMemory` = 本 session 当前 L2
- `currentMemory` = 本 session 当前 memory 槽位
- `messages` = 本 session 全量 L3

输出:100-150 字摘要,写回本 session memory 槽位。

---

## 5. Integrate(所有子 L2 → synthesis + insights
## 4. Reflection(应用层自行实现

```
[
{ role: 'system', content: INTEGRATE_PROMPT },
{ role: 'system', content: <role_context> }, // 若传入非空 roleContext
{ role: 'user', content: [
currentSynthesis ? `当前综合:\n${currentSynthesis}` : null,
`子 Session 摘要:\n` + children.map(c =>
`- [sessionId=${c.sessionId}] ${c.label}: ${c.l2}`
).join('\n'),
].filter(Boolean).join('\n\n') },
]
```
跨 Session 的"全 memory → 综合 → 定向 insight"循环由应用层自行调用任意 LLM 完成:

- `currentSynthesis` = main 当前 synthesis
- `children` = 扁平收集所有子 session 的 `{ sessionId, label, l2 }`
- 输入:`agent.listSessionDigests({ status: 'active' })` —— `{ id, label, memory, insight }[]`
- 输出:派生 per-target `insight`,通过 `agent.putInsight(targetId, content)` 写回

输出:JSON `{ synthesis, insights: [{ sessionId, content }] }`
应用层完全掌控 prompt 形态、调用频率、LLM tier。详见 stello-agent-creation §7 与 stello-agent-usage §6.4

---

## XML Tag 注入汇总

| Tag | 调用路径 | 数据来源 | 注入位置 |
|-----|---------|---------|---------|
| `<parent_context>` | 普通 Session 对话(仅 fork-compress 场景) | 父 session 压缩摘要 | 合成进 systemPrompt 字段 |
| `<session_identity>` | 普通 Session 对话 | `SessionMeta.label`(stello 一等字段) | systemPrompt 之后 |
| `<role_context>` | Compress / Consolidate / Integrate | `DefaultFnOptions.roleContext`(应用层传入) | 任务 prompt 之后、user content 之前 |
| `<parent_context>` | Session 对话(仅 fork-compress 场景) | 父 session 压缩摘要 | 合成进 systemPrompt 字段 |
| `<session_identity>` | Session 对话 | `SessionMeta.label` | systemPrompt 之后 |
| `<role_context>` | Compress / Consolidate | `DefaultFnOptions.roleContext`(应用层传入) | 任务 prompt 之后、user content 之前 |

---

## 共性

| 维度 | 对话类(1、2) | 提炼类(3、4、5) |
|------|--------------|------------------|
| 维度 | 对话类(1) | 提炼类(2、3) |
|------|------------|--------------|
| 接口 | `llm.complete(msgs, { tools })` | `LLMCallFn(msgs)` → `string` |
| tools | 有 | 无 |
| L3 形态 | 原始 message 数组 | `${role}: ${content}` 字符串拼接进 user content |
| 返回 | 结构化(含 tool calls) | 纯文本 / JSON |
| 返回 | 结构化(含 tool calls) | 纯文本 |
| `<think>` 清洗 | 否 | 是 |
38 changes: 26 additions & 12 deletions .agents/skills/scheduler-design/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
---
name: scheduler-design
description: Consolidation 触发机制:自动触发通过 Factory 配置内联,手动触发通过 StelloAgent API。
description: Consolidation 触发机制:自动触发通过 Factory 配置内联,手动触发通过 StelloAgent API;全局 reflection 由应用层在 SDK 之上自行实现
---

# Consolidation 触发机制

## 概述

Scheduler 类已删除。Consolidation 和 integration 的触发机制简化为两条路径
Consolidation 的触发机制有两条路径

1. **自动触发**:`consolidateEveryNTurns` 配置项,由 Factory 内联处理
2. **手动触发**:`agent.consolidateSession(sessionId)` 和 `agent.integrate()`
2. **手动触发**:`agent.consolidateSession(sessionId)`

跨 Session 的 reflection 由应用层在 `agent.listSessionDigests` / `agent.putInsight` 之上自行实现,详见 skill `session-usage`。

---

## 自动 Consolidation

在 `orchestration` 配置中设置 `consolidateEveryNTurns`,每 N 轮对话后自动触发 consolidation:
在 `orchestration` 配置中设置 `consolidateEveryNTurns`,每 N 轮对话后自动触发 consolidation(fire-and-forget)

```typescript
orchestration: {
consolidateEveryNTurns: 5, // 每 5 轮自动 consolidate
consolidateEveryNTurns: 5,
}
```

Expand All @@ -30,21 +32,33 @@ orchestration: {

## 手动触发

`StelloAgent` 提供两个第一方 API:

- `agent.consolidateSession(sessionId)`:对指定 session 执行 consolidation(L3 → L2)
- `agent.integrate()`:对 Main Session 执行 integration(所有 L2 → synthesis + insights)
```typescript
await agent.consolidateSession(sessionId)
```

应用层可在任意时机调用,例如 session 结束时、定时任务、用户操作后。

---

## Integration 无框架级自动触发
## 应用层 Reflection 循环

```typescript
async function reflect() {
const digests = await agent.listSessionDigests({ status: 'active' })
// 调任意 LLM、用任意 schema 解析 ...
for (const [id, content] of Object.entries(insightsByTarget)) {
await agent.putInsight(id, content)
}
}
```

Integration 没有框架级自动触发策略。应用层负责决定何时调用 `agent.integrate()`——可在 hooks 中响应 consolidation 完成事件,也可完全独立调用
可在 `hooks.onRoundEnd` / `hooks.onSessionFork` 内 fire-and-forget 触发,或绑定到外部 cron / 用户操作。框架不假设调用频率与策略——这部分被有意外推到应用层

---

## 设计决策

去掉 Scheduler 类是有意简化:调度策略的多样性带来了复杂性,但实际上大多数应用只需要"每 N 轮"和"手动"两种模式。将复杂调度逻辑交还给应用层,框架只保留最常用的内联策略。
调度被有意压到最小:
- 自动调度只保留"每 N 轮 consolidate"——这是高频被用的唯一策略,其他策略都被应用层覆盖
- 全局 reflection 的频率 / prompt / schema / LLM tier 选择强烈与应用业务耦合,框架不假设
- reflection 由应用层在 `listSessionDigests` / `putInsight` 之上自行实现,框架不持有跨 Session 状态
6 changes: 4 additions & 2 deletions .agents/skills/server-design/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@ connectionId → { userId, spaceId, sessionId | null }

## AgentPool 默认 fn 注入

AgentPool 支持内置默认 consolidateFn / integrateFn
AgentPool 支持内置默认 consolidateFn:

- `AgentPoolOptions.llm` 提供最小 LLM 调用接口
- Space 表存 `consolidatePrompt` / `integratePrompt`
- Space 表存 `consolidatePrompt`
- 如果 buildConfig 未提供显式 fn,且 Space 有 prompt 且 llm 可用 → 自动注入默认实现
- buildConfig 提供的显式 fn 始终优先

跨 Session 的 reflection / 全局综合不由 Server 框架承担——服务端只暴露 `StelloAgent` 的 orchestrator-facing 数据 SDK(`listSessionDigests` / `putInsight` 等),应用层基于这些原语自行实现。

---

## createStelloServer 入口
Expand Down
13 changes: 7 additions & 6 deletions .agents/skills/server-storage/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ description: "@stello-ai/server 的 PG 持久化层设计决策和实现模式

---

## 4 个 Storage Adapter
## 3 个 Storage Adapter

| Adapter | 实现接口 | 职责 |
|---------|---------|------|
| PgSessionStorage | SessionStorage(@stello-ai/session) | 单个 Session 数据操作 |
| PgMainStorage | MainStorage(extends SessionStorage) | 额外:批量 L2 收集、拓扑树、全局键值 |
| PgSessionTree | SessionTree(@stello-ai/core) | 树操作:创建节点、递归树、祖先/兄弟查询 |
| PgSessionStorage | SessionStorage(@stello-ai/session) | 单个 Session 数据操作(含 root,所有 Session 同构) |
| PgSessionTree | SessionTree(@stello-ai/core) | 拓扑:createSession / listRoots / 树操作 / 固化配置 |
| PgMemoryEngine | MemoryEngine(@stello-ai/core) | 核心数据读写、递归上下文组装 |

批量 digest 收集由 `StelloAgent.listSessionDigests()` 在应用层组合 `SessionTree.listAll()` + `SessionStorage.getMemory/getInsight` 完成,存储层不需要提供专用方法。

---

## 关键实现模式
Expand All @@ -42,8 +43,8 @@ description: "@stello-ai/server 的 PG 持久化层设计决策和实现模式

### 两种 SessionMeta 投影
PG 存 sessions 表超集。不同 adapter 投影为不同类型:
- PgSessionStorage → @stello-ai/session 的 SessionMeta(有 role,无 scope/turnCount
- PgSessionTree → @stello-ai/core 的 SessionMeta( scope/turnCount,无树字段)+ TopologyNode(纯树结构)
- PgSessionStorage → @stello-ai/session 的 SessionMeta(`id / label / status / createdAt / updatedAt`
- PgSessionTree → @stello-ai/core 的 SessionMeta( scope / turnCount / lastActiveAt)+ TopologyNode(纯树结构)

### 递归 CTE
`getAncestors`、`getAllDescendantIds`、`assembleContext` 都用 `WITH RECURSIVE` 遍历树结构。
Expand Down
Loading