Skip to content

Commit dc7c82b

Browse files
authored
Merge pull request #606 from objectstack-ai/copilot/optimize-protocol-report-again
2 parents 9c5b30d + cadc814 commit dc7c82b

13 files changed

Lines changed: 1879 additions & 37 deletions

PROTOCOL_OPTIMIZATION_REPORT.md

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ ObjectStack 协议规范展现出**卓越的架构设计**和**企业级成熟
9090
| 优先级 | 问题 | 当前状态 | 推荐方案 | 验证状态 |
9191
|--------|------|----------|----------|----------|
9292
| ~~🔴 高~~ | ~~缺少游标分页~~ | ~~query.zod.ts注释提及但未实现~~ | ~~添加cursor字段~~ |**已实现** - query.zod.ts已有keyset pagination cursor字段 |
93-
| 🟡 中 | 驱动接口过度指定 | driver.zod.ts用Zod `z.function()`验证20+方法签名 | 分离为TypeScript接口,Zod仅描述能力标志 | ⏳ 待处理 |
93+
| 🟡 中 | 驱动接口过度指定 | driver.zod.ts用Zod `z.function()`验证20+方法签名 | 分离为TypeScript接口,Zod仅描述能力标志 | **已实现** - contracts/data-driver.ts IDataDriver接口 |
9494
| 🟡 中 | 外部查找健壮性不足 | external-lookup.zod.ts有缓存策略但缺少重试 | 添加指数退避、请求转换管道、分页支持 | ⏳ 待处理 |
9595
| 🟢 低 | 命名不一致 | `externalId`(22处) vs `external_id`(2处) | 统一为camelCase `externalId` | ⏳ 待处理 |
9696

@@ -205,8 +205,8 @@ export const ViewSchema = z.object({
205205
| 优先级 | 问题 | 推荐方案 | 验证状态 |
206206
|--------|------|----------|----------|
207207
| ~~🔴 高~~ | ~~协议统一查询语言~~ | ~~抽象过滤器为内部规范~~ | ⚠️ **部分实现** - data/query.zod.ts已有统一DSL,降为P1完成API层适配 |
208-
| 🔴 高 | GraphQL Federation | 添加联邦指令Schema定义 | ⏳ 待处理 - 确认缺失 |
209-
| 🟡 中 | 实时协议合并 | 统一websocket + realtime为单一规范 | ⏳ 待处理 - 确认重叠 |
208+
| 🔴 高 | GraphQL Federation | 添加联邦指令Schema定义 | **已实现** - FederationGateway/Entity/Subgraph完整定义 |
209+
| 🟡 中 | 实时协议合并 | 统一websocket + realtime为单一规范 | **已实现** - realtime-shared.zod.ts已提取共享定义 |
210210
| 🟡 中 | N+1查询预防 | 添加DataLoader等价物到contract.zod.ts | ⏳ 待处理 |
211211
| 🟢 低 | OpenAPI 3.1升级 | rest-server.zod.ts添加webhooks/callbacks支持 | ⏳ 待处理 |
212212

@@ -260,7 +260,7 @@ export function toODataFilter(unified: UnifiedFilter): string {
260260
#### 改进建议
261261
| 优先级 | 问题 | 推荐方案 |
262262
|--------|------|----------|
263-
| 🔴 高 | 多智能体协调缺失 | 扩展orchestration.zod.ts添加智能体群组、角色分配、协作模式 |
263+
| 🔴 高 | 多智能体协调缺失 | 扩展orchestration.zod.ts添加智能体群组、角色分配、协作模式 |**已实现** |
264264
| 🟡 中 | 代理记忆系统 | 添加长期/短期记忆分层、反思机制、知识图谱集成 |
265265
| 🟡 中 | 结构化输出保障 | 添加JSON Schema约束、Pydantic模型绑定 |
266266
| 🟢 低 | 成本预估 | 在agent/workflow执行计划中添加token成本估算 |
@@ -353,40 +353,41 @@ export const MultiAgentOrchestrationSchema = z.object({
353353

354354
### 第二阶段 (P1 - Sprint 3-6, 1-2个月内)
355355

356-
#### Sprint 3: GraphQL Federation Schema
356+
#### Sprint 3: GraphQL Federation Schema
357357
- **任务 3.1**: 在 `api/graphql.zod.ts` 添加Federation指令Schema
358-
- 定义 `FederationDirectiveSchema` (key, external, requires, provides)
359-
- 添加 `SubgraphConfigSchema` (service URL, schema拼接策略)
360-
- 定义 `FederationGatewaySchema` (服务发现, 查询路由)
361-
- **预估工时**: 3-4天
362-
- **交付物**: graphql.zod.ts federation扩展 + 测试
363-
364-
#### Sprint 4: AI多智能体协调
365-
- **任务 4.1**: 扩展 `ai/agent.zod.ts` (当前80行 → 目标200行)
366-
- 添加自主推理循环配置 (planningStrategy, maxIterations)
367-
- 添加记忆管理 (shortTermMemory, longTermMemory, reflectionInterval)
358+
- ✅ 定义 `FederationEntityKeySchema` / `FederationExternalFieldSchema` / `FederationRequiresSchema` / `FederationProvidesSchema`
359+
- ✅ 定义 `FederationEntitySchema` (key, external, requires, provides)
360+
- ✅ 添加 `SubgraphConfigSchema` (service URL, schema拼接策略, 健康检查)
361+
- ✅ 定义 `FederationGatewaySchema` (服务发现, 查询路由, Schema组合)
362+
- ✅ 集成到 `GraphQLConfigSchema.federation`
363+
- **交付物**: graphql.zod.ts federation扩展 + 17项测试
364+
365+
#### Sprint 4: AI多智能体协调 ✅
366+
- **任务 4.1**: 扩展 `ai/agent.zod.ts`
367+
- ✅ 添加自主推理循环配置 (`planning`: react/plan_and_execute/reflexion/tree_of_thought)
368+
- ✅ 添加记忆管理 (`memory`: shortTerm/longTerm/reflectionInterval)
369+
- ✅ 添加安全护栏 (`guardrails`: maxTokens/maxExecutionTime/blockedTopics)
368370
- **任务 4.2**: 扩展 `ai/orchestration.zod.ts` 多智能体
369-
- 添加 `MultiAgentGroupSchema` (strategy, roles, communication protocol)
370-
- 定义智能体间通信 (message_passing, shared_memory, blackboard)
371-
- 添加冲突解决策略 (voting, priority, consensus)
372-
- **预估工时**: 4-5天
373-
- **交付物**: 增强的agent.zod.ts + orchestration.zod.ts + 测试
371+
- 添加 `MultiAgentGroupSchema` (5种策略: sequential/parallel/debate/hierarchical/swarm)
372+
- ✅ 定义 `AgentGroupMemberSchema` (roles, capabilities, dependencies)
373+
- ✅ 定义 `AgentCommunicationProtocolSchema` (message_passing/shared_memory/blackboard)
374+
- ✅ 添加冲突解决策略 (voting/priorityBased/consensusBased/coordinatorDecides)
375+
- **交付物**: 增强的agent.zod.ts + orchestration.zod.ts + 18项测试
374376

375-
#### Sprint 5: 驱动接口重构
377+
#### Sprint 5: 驱动接口重构
376378
- **任务 5.1**: 将 `data/driver.zod.ts` 中的 `z.function()` 签名迁移到TypeScript接口
377-
- 创建 `contracts/data-driver.ts` 纯TS接口
378-
- driver.zod.ts 仅保留 `DriverCapabilitiesSchema``DriverConfigSchema`
379-
- 保持向后兼容: 导出旧Schema作为deprecated
380-
- **预估工时**: 3-4天
381-
- **交付物**: contracts/data-driver.ts + 精简的driver.zod.ts
379+
- ✅ 创建 `contracts/data-driver.ts` 纯TS接口 (`IDataDriver`)
380+
- ✅ driver.zod.ts 保留完整 (向后兼容) — Zod Schema继续用于运行时验证
381+
- ✅ 导出到 `contracts/index.ts`
382+
- **交付物**: contracts/data-driver.ts + 3项测试
382383

383-
#### Sprint 6: API层查询DSL适配
384+
#### Sprint 6: API层查询DSL适配
384385
- **任务 6.1**: 创建 `api/query-adapter.zod.ts` 协议转换定义
385-
- 定义 REST → 统一DSL 映射规则Schema
386-
- 定义 GraphQL → 统一DSL 映射规则Schema
387-
- 定义 OData → 统一DSL 映射规则Schema
388-
- **预估工时**: 3-4天
389-
- **交付物**: query-adapter.zod.ts + 测试
386+
- 定义 REST → 统一DSL 映射规则Schema (`RestQueryAdapterSchema`)
387+
- 定义 GraphQL → 统一DSL 映射规则Schema (`GraphQLQueryAdapterSchema`)
388+
- 定义 OData → 统一DSL 映射规则Schema (`ODataQueryAdapterSchema`)
389+
- ✅ 定义 `QueryAdapterConfigSchema` 根配置 + `OperatorMappingSchema`
390+
- **交付物**: query-adapter.zod.ts + 20项测试
390391

391392
### 第三阶段 (P2 - Sprint 7-10, 3-6个月内)
392393

@@ -634,10 +635,10 @@ ObjectStack协议规范已具备**世界级企业管理软件框架**的基础
634635
4.**实时协议统一** - 合并websocket/realtime重叠 (Sprint 2, 新增)
635636

636637
### 战略性改进 (Next 3 Months) - 4 Sprints
637-
5. **GraphQL Federation** - 联邦指令Schema定义 (Sprint 3)
638-
6. **AI智能体生态** - 多智能体协调、记忆管理 (Sprint 4)
639-
7. **驱动接口重构** - 分离Zod/TS定义 (Sprint 5)
640-
8. **API查询适配** - 协议层绑定统一DSL (Sprint 6)
638+
5. **GraphQL Federation** - 联邦指令Schema定义 (Sprint 3)
639+
6. **AI智能体生态** - 多智能体协调、记忆管理 (Sprint 4)
640+
7. **驱动接口重构** - 分离Zod/TS定义 (Sprint 5)
641+
8. **API查询适配** - 协议层绑定统一DSL (Sprint 6)
641642

642643
### 长期愿景 (6+ Months) - 4 Sprints
643644
9.**灾难恢复** - 多区域容错和备份模式 (Sprint 7)

packages/spec/src/ai/agent.test.ts

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,4 +439,134 @@ Be precise, data-driven, and clear in your explanations.`,
439439
expect(result.lifecycle?.initial).toBe('idle');
440440
});
441441
});
442+
443+
describe('Autonomous Reasoning', () => {
444+
it('should accept agent with planning configuration', () => {
445+
const agent = AgentSchema.parse({
446+
name: 'planner_agent',
447+
label: 'Planning Agent',
448+
role: 'Strategic Planner',
449+
instructions: 'Plan and execute complex tasks.',
450+
planning: {
451+
strategy: 'plan_and_execute',
452+
maxIterations: 20,
453+
allowReplan: true,
454+
},
455+
});
456+
457+
expect(agent.planning?.strategy).toBe('plan_and_execute');
458+
expect(agent.planning?.maxIterations).toBe(20);
459+
expect(agent.planning?.allowReplan).toBe(true);
460+
});
461+
462+
it('should accept all planning strategies', () => {
463+
const strategies = ['react', 'plan_and_execute', 'reflexion', 'tree_of_thought'] as const;
464+
465+
strategies.forEach(strategy => {
466+
const agent = AgentSchema.parse({
467+
name: 'test_agent',
468+
label: 'Test',
469+
role: 'Test',
470+
instructions: 'Test',
471+
planning: { strategy },
472+
});
473+
expect(agent.planning?.strategy).toBe(strategy);
474+
});
475+
});
476+
477+
it('should apply default planning values', () => {
478+
const agent = AgentSchema.parse({
479+
name: 'default_agent',
480+
label: 'Default',
481+
role: 'Default',
482+
instructions: 'Test',
483+
planning: {},
484+
});
485+
486+
expect(agent.planning?.strategy).toBe('react');
487+
expect(agent.planning?.maxIterations).toBe(10);
488+
expect(agent.planning?.allowReplan).toBe(true);
489+
});
490+
491+
it('should enforce maxIterations constraints', () => {
492+
expect(() => AgentSchema.parse({
493+
name: 'test',
494+
label: 'Test',
495+
role: 'Test',
496+
instructions: 'Test',
497+
planning: { maxIterations: 0 },
498+
})).toThrow();
499+
500+
expect(() => AgentSchema.parse({
501+
name: 'test',
502+
label: 'Test',
503+
role: 'Test',
504+
instructions: 'Test',
505+
planning: { maxIterations: 101 },
506+
})).toThrow();
507+
});
508+
});
509+
510+
describe('Memory Management', () => {
511+
it('should accept agent with memory configuration', () => {
512+
const agent = AgentSchema.parse({
513+
name: 'memory_agent',
514+
label: 'Memory Agent',
515+
role: 'Persistent Assistant',
516+
instructions: 'Remember across sessions.',
517+
memory: {
518+
shortTerm: {
519+
maxMessages: 100,
520+
maxTokens: 4096,
521+
},
522+
longTerm: {
523+
enabled: true,
524+
store: 'vector',
525+
maxEntries: 10000,
526+
},
527+
reflectionInterval: 5,
528+
},
529+
});
530+
531+
expect(agent.memory?.shortTerm?.maxMessages).toBe(100);
532+
expect(agent.memory?.longTerm?.enabled).toBe(true);
533+
expect(agent.memory?.longTerm?.store).toBe('vector');
534+
expect(agent.memory?.reflectionInterval).toBe(5);
535+
});
536+
537+
it('should accept all memory store backends', () => {
538+
const stores = ['vector', 'database', 'redis'] as const;
539+
540+
stores.forEach(store => {
541+
const agent = AgentSchema.parse({
542+
name: 'test_agent',
543+
label: 'Test',
544+
role: 'Test',
545+
instructions: 'Test',
546+
memory: { longTerm: { enabled: true, store } },
547+
});
548+
expect(agent.memory?.longTerm?.store).toBe(store);
549+
});
550+
});
551+
});
552+
553+
describe('Guardrails', () => {
554+
it('should accept agent with guardrails', () => {
555+
const agent = AgentSchema.parse({
556+
name: 'safe_agent',
557+
label: 'Safe Agent',
558+
role: 'Restricted Assistant',
559+
instructions: 'Operate within guardrails.',
560+
guardrails: {
561+
maxTokensPerInvocation: 8192,
562+
maxExecutionTimeSec: 60,
563+
blockedTopics: ['financial_advice', 'medical_diagnosis'],
564+
},
565+
});
566+
567+
expect(agent.guardrails?.maxTokensPerInvocation).toBe(8192);
568+
expect(agent.guardrails?.maxExecutionTimeSec).toBe(60);
569+
expect(agent.guardrails?.blockedTopics).toContain('financial_advice');
570+
});
571+
});
442572
});

packages/spec/src/ai/agent.zod.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,57 @@ export const AgentSchema = z.object({
8181
/** Multi-tenancy & Visibility */
8282
tenantId: z.string().optional().describe('Tenant/Organization ID'),
8383
visibility: z.enum(['global', 'organization', 'private']).default('organization'),
84+
85+
/** Autonomous Reasoning */
86+
planning: z.object({
87+
/** Planning strategy for autonomous reasoning loops */
88+
strategy: z.enum(['react', 'plan_and_execute', 'reflexion', 'tree_of_thought']).default('react').describe('Autonomous reasoning strategy'),
89+
90+
/** Maximum reasoning iterations before stopping */
91+
maxIterations: z.number().int().min(1).max(100).default(10).describe('Maximum planning loop iterations'),
92+
93+
/** Whether the agent can revise its own plan mid-execution */
94+
allowReplan: z.boolean().default(true).describe('Allow dynamic re-planning based on intermediate results'),
95+
}).optional().describe('Autonomous reasoning and planning configuration'),
96+
97+
/** Memory Management */
98+
memory: z.object({
99+
/** Short-term (working) memory configuration */
100+
shortTerm: z.object({
101+
/** Maximum number of recent messages to retain */
102+
maxMessages: z.number().int().min(1).default(50).describe('Max recent messages in working memory'),
103+
104+
/** Maximum token budget for short-term context */
105+
maxTokens: z.number().int().min(100).optional().describe('Max tokens for short-term context window'),
106+
}).optional().describe('Short-term / working memory'),
107+
108+
/** Long-term (persistent) memory configuration */
109+
longTerm: z.object({
110+
/** Whether long-term memory is enabled */
111+
enabled: z.boolean().default(false).describe('Enable long-term memory persistence'),
112+
113+
/** Storage backend for long-term memory */
114+
store: z.enum(['vector', 'database', 'redis']).default('vector').describe('Long-term memory storage backend'),
115+
116+
/** Maximum number of persisted memory entries */
117+
maxEntries: z.number().int().min(1).optional().describe('Max entries in long-term memory'),
118+
}).optional().describe('Long-term / persistent memory'),
119+
120+
/** Reflection interval — how often the agent reflects on past actions */
121+
reflectionInterval: z.number().int().min(1).optional().describe('Reflect every N interactions to improve behavior'),
122+
}).optional().describe('Agent memory management'),
123+
124+
/** Guardrails */
125+
guardrails: z.object({
126+
/** Maximum tokens the agent may consume per invocation */
127+
maxTokensPerInvocation: z.number().int().min(1).optional().describe('Token budget per single invocation'),
128+
129+
/** Maximum wall-clock time per invocation in seconds */
130+
maxExecutionTimeSec: z.number().int().min(1).optional().describe('Max execution time in seconds'),
131+
132+
/** Topics or actions the agent must avoid */
133+
blockedTopics: z.array(z.string()).optional().describe('Forbidden topics or action names'),
134+
}).optional().describe('Safety guardrails for the agent'),
84135
});
85136

86137
export type Agent = z.infer<typeof AgentSchema>;

0 commit comments

Comments
 (0)