docs: 添加 ag-ui 和 crewai 项目 skills 及更新文档

This commit is contained in:
qzl
2026-03-02 17:02:09 +08:00
parent 6fdbc34526
commit ca1ce3d84a
43 changed files with 56074 additions and 3 deletions
@@ -0,0 +1,255 @@
/**
* AG-UI 状态同步示例
*
* 展示 Agent 与前端的 Snapshot-Delta 状态同步模式
*
* 参考文档: modules/events.md (行 1067-1155)
*
* 状态管理模式:
* 1. StateSnapshot - 完整状态快照(初始同步/周期性刷新)
* 2. StateDelta - 增量更新(JSON Patch RFC 6902
* 3. MessagesSnapshot - 消息历史快照
*/
import {
AbstractAgent,
RunAgent,
RunAgentInput,
EventType,
BaseEvent,
} from "@ag-ui/client"
import { Observable } from "rxjs"
/**
* Agent 状态定义示例
*/
interface AgentState {
user: {
name: string
preferences: {
theme: "light" | "dark"
language: string
}
}
session: {
currentPage: number
itemsPerPage: number
totalItems: number
}
formData?: {
[key: string]: any
}
}
class StateSyncAgent extends AbstractAgent {
private state: AgentState = {
user: {
name: "Alice",
preferences: {
theme: "light",
language: "en",
},
},
session: {
currentPage: 1,
itemsPerPage: 10,
totalItems: 100,
},
}
run(input: RunAgentInput): RunAgent {
const { threadId, runId } = input
return () =>
new Observable<BaseEvent>((observer) => {
observer.next({
type: EventType.RUN_STARTED,
threadId,
runId,
})
// 1. 发送初始状态快照
observer.next({
type: EventType.STATE_SNAPSHOT,
snapshot: this.state,
})
// 2. 发送消息历史快照
observer.next({
type: EventType.MESSAGES_SNAPSHOT,
messages: [
{
id: "msg_1",
role: "user",
content: "Show me page 2",
},
{
id: "msg_2",
role: "assistant",
content: "Loading page 2...",
},
],
})
// 3. 模拟状态变化 - 分页更新
setTimeout(() => {
// 发送 Delta 更新(JSON Patch 格式)
observer.next({
type: EventType.STATE_DELTA,
delta: [
{ op: "replace", path: "/session/currentPage", value: 2 },
],
})
}, 500)
// 4. 模拟用户偏好更新
setTimeout(() => {
observer.next({
type: EventType.STATE_DELTA,
delta: [
{ op: "replace", path: "/user/preferences/theme", value: "dark" },
],
})
}, 1000)
// 5. 添加新字段(表单数据)
setTimeout(() => {
observer.next({
type: EventType.STATE_DELTA,
delta: [
{
op: "add",
path: "/formData",
value: {
searchQuery: "AG-UI tutorial",
filters: ["beginner", "typescript"],
},
},
],
})
}, 1500)
// 6. 周期性完整快照(确保状态一致性)
setTimeout(() => {
const updatedState: AgentState = {
...this.state,
session: {
...this.state.session,
currentPage: 2,
},
user: {
...this.state.user,
preferences: {
...this.state.user.preferences,
theme: "dark",
},
},
formData: {
searchQuery: "AG-UI tutorial",
filters: ["beginner", "typescript"],
},
}
observer.next({
type: EventType.STATE_SNAPSHOT,
snapshot: updatedState,
})
observer.next({
type: EventType.RUN_FINISHED,
threadId,
runId,
})
observer.complete()
}, 2000)
})
}
}
/**
* 前端状态管理示例(接收端)
*/
class StateManager {
private state: AgentState | null = null
handleEvent(event: BaseEvent) {
switch (event.type) {
case EventType.STATE_SNAPSHOT:
// 完整替换状态
this.state = (event as any).snapshot as AgentState
console.log("[State] Snapshot received:", this.state)
break
case EventType.STATE_DELTA:
// 应用 JSON Patch 增量更新
if (this.state) {
const patches = (event as any).delta
this.state = this.applyPatches(this.state, patches)
console.log("[State] Delta applied:", patches)
console.log("[State] Current state:", this.state)
}
break
case EventType.MESSAGES_SNAPSHOT:
console.log("[Messages] Snapshot:", (event as any).messages)
break
}
}
/**
* 应用 JSON Patch 操作(简化实现)
* 生产环境应使用 json-patch 库
*/
private applyPatches(state: AgentState, patches: any[]): AgentState {
const newState = JSON.parse(JSON.stringify(state))
for (const patch of patches) {
const { op, path, value } = patch
const pathParts = path.split("/").filter(Boolean)
let target: any = newState
// 导航到目标对象的父级
for (let i = 0; i < pathParts.length - 1; i++) {
target = target[pathParts[i]]
}
const lastKey = pathParts[pathParts.length - 1]
switch (op) {
case "replace":
target[lastKey] = value
break
case "add":
target[lastKey] = value
break
case "remove":
delete target[lastKey]
break
}
}
return newState
}
}
// 使用示例
const agent = new StateSyncAgent()
const stateManager = new StateManager()
agent
.runAgent({
runId: "run_state_sync",
threadId: "thread_123",
messages: [],
tools: [],
context: [],
})
.subscribe({
next: (event) => {
stateManager.handleEvent(event)
},
complete: () => console.log("\n[Complete] State sync demo finished"),
})
export { StateSyncAgent, StateManager, AgentState }