Commit Graph

375 Commits

Author SHA1 Message Date
chiguyong b55c896794 feat(rag_platform): U3+U7 — document processing pipeline + upload security
U3: Document processing pipeline (document_processor.py)
- DocumentProcessor class wrapping parse → segment → vectorize
- parse() uses memory/document_loader.py for multi-format extraction
- segment() uses LlamaIndex SentenceSplitter
- preview() returns chunks for read-only preview (no vectorization)
- vectorize() embeds chunks and stores in pgvector (all-or-nothing)
- process() orchestrates full pipeline with status transitions:
  pending → parsing → segmenting → vectorizing → indexed | failed

U7: Upload security & content sanitization (sanitize.py)
- ALLOWED_FILE_TYPES whitelist (pdf/docx/xlsx/pptx/txt/md/csv/html)
- MAX_FILE_SIZE 50MB limit
- validate_file_type() / validate_file_size() guards
- check_zip_bomb() for ZIP-based formats (ratio > 100:1 or > 500MB)
- check_image_bomb() for pixel count > 100MP (PNG/JPEG/GIF header parsing)
- is_safe_ip() SSRF protection (loopback/RFC1918/link-local/ULA denied)
- sanitize_markdown() removes dangerous HTML tags (script/iframe/object/embed)
- sanitize_content() main entry point for text format sanitization
- parse_xml_safe() XXE protection (forbid_dtd/forbid_entities/forbid_external)

Preview API (preview.py)
- PreviewChunk / PreviewResult Pydantic models
- generate_preview() returns read-only segmentation preview

Tests: 112 tests passing (45 new + 67 existing)
- test_sanitize.py: file type/size, markdown sanitization, SSRF, zip/image bomb
- test_document_processor.py: parse/segment, preview, vectorize, failure status
2026-06-25 11:21:42 +08:00
chiguyong c1a21f57a1 feat(rag_platform): U2 — KB persistence + per-KB ACL
Add PostgreSQL-backed KB store replacing in-memory KnowledgeSourceStore:
- models.py: ORM models (KBModel, DocumentModel, KBAclModel) using
  SQLAlchemy 2 DeclarativeBase + Mapped style
- store.py: KBStore with async CRUD for KBs and documents,
  create_kb creates owner ACL in same transaction
- acl.py: filter_kb_by_user_acl(), grant_access(), revoke_access(),
  list_acl() — follows filter_kb_sources_by_department pattern

Schema: rag_platform_kbs, rag_platform_documents, rag_platform_kb_acl
with FK CASCADE on kb_id. UniqueConstraint on (kb_id, user_id).

Tests: 23 unit tests covering KB CRUD, document operations, ACL
filtering, grant/revoke. All 37 rag_platform tests pass.
2026-06-25 11:01:04 +08:00
chiguyong 27d0184392 feat(rag_platform): U1 — RAG platform skeleton + LlamaIndex integration
Create src/agentkit/rag_platform/ module with:
- models.py: Pydantic domain models (KB, Document, Chunk, QueryResult)
- indexing.py: PGVectorStore wrapper with explicit table name
  (rag_platform_kb_chunks) for schema isolation from episodic_memory
- pipeline.py: RAGPipeline wrapping LlamaIndex IngestionPipeline
  (SentenceSplitter + embedding + vector store)

Add dependencies: llama-index-core, llama-index-vector-stores-postgres,
llama-index-embeddings-openai, pgvector, jieba.

Tests: 14 unit tests covering models, indexing (URL conversion, table
name isolation, embed_dim), and pipeline (ingest, query, chunk params).
2026-06-25 10:49:35 +08:00
chiguyong 22c89763e2 docs: add long-horizon reliability fixes learning + scrub CONCEPTS.md
- New solution doc: logic-errors/long-horizon-reliability-code-review-fixes.md
  Documents 13 code-review fixes (2 P0, 5 P1, 6 P2) across U1-U7
  long-horizon reliability features (disclosure_level default, resume
  plan_id mismatch, middleware dataclass compat, state offload readback,
  checkpoint dedup, dynamic phase persistence, debate count restore,
  loop detection reset, concurrent resume lock, FAILED phase handling,
  checkpoint cleanup, offload type guard).

- CONCEPTS.md: add Expert Orchestration cluster (Disclosure Level,
  State Offloading, Pipeline Checkpoint, Debate Phase, Resume).
  Scrub Bitable entries to remove implementation specifics per
  vocabulary rules (API paths, library calls, SQL syntax, class names,
  enum values).
2026-06-25 02:40:22 +08:00
chiguyong 71eaf8dc7c docs: add bitable security/reliability patterns solution doc + CONCEPTS.md
Deploy to Production / deploy (push) Has been cancelled Details
- docs/solutions/architecture-patterns/bitable-companion-service-security-reliability-patterns.md
  Knowledge-track doc capturing 10 security/reliability patterns from the
  bitable companion service (SSRF prevention, SQL injection, IDOR, atomic
  task claiming, cache invalidation, composite cursor, batch ops, async
  I/O safety, OOM prevention, internal token auth)

- CONCEPTS.md
  Seeded with 3 core domain nouns: Bitable, Field Ownership, Recalc

- AGENTS.md
  Added discoverability tips for docs/solutions/ and CONCEPTS.md
2026-06-25 01:25:06 +08:00
chiguyong bbbf9cd40a feat(bitable): add bitable companion service with full P0-P2 fixes
Bitable is a multi-dimensional table companion service that runs alongside
the main AgentKit server. It provides structured data storage with formula
fields, views, and ingestion pipelines.

Major components:
- Domain models (Pydantic v2): Table, Field, Record, View, RecalcTask
- SQLAlchemy 2 async ORM with independent bitable PostgreSQL schema
- Formula engine: AST parser, DAG, Kahn topological sort, safe eval
- RecalcWorker: atomic task claiming (FOR UPDATE SKIP LOCKED), topo-order
  processing, stale-threshold reaper for crash recovery
- REST API (/api/v1/bitable): tables, fields, records, views, files
- BitableTool: agent-facing tool with batch chunking (500/batch)
- CLI: agentkit bitable subcommands (create, list, import-excel, etc.)
- Frontend: Vue 3 + vxe-table grid with field management, views, filters
- Ingestion: Excel (openpyxl), database reflection, API collector

Security fixes (ce-code-review P0 + ce-debug P1):
- SQL injection prevention (field_id validation, parameterized queries)
- IDOR protection (_check_table_ownership on all table-level endpoints)
- SSRF prevention (URL scheme + private IP validation in parse_excel_url)
- OOM prevention (streaming file upload, batch delete, batch insert)
- Atomic recalc task claiming (FOR UPDATE SKIP LOCKED)
- Formula engine cache invalidation on field changes
- Composite cursor pagination for non-id sort orders
- Batch upsert (eliminates N+1 queries)
- Sync I/O offloaded to thread pool in async contexts
- Internal token auth (X-Internal-Token, hmac.compare_digest)
- PK unique index enforcement

Test coverage: 88 unit tests (95 skipped without Docker)
2026-06-25 01:09:59 +08:00
chiguyong 567cbc9c9b refactor: simplify code across U1-U7 (bug fix + efficiency + reuse + quality) 2026-06-24 22:35:52 +08:00
chiguyong 0847c0e086 fix(checkpoint): add TTL expiration for memory fallback mode
内存降级模式之前没有 TTL 过期机制,长期运行进程会导致内存泄漏。
现在 list_checkpoints 和 load_plan 在内存模式下会过滤/清除过期数据。

- list_checkpoints: 内存降级分支过滤过期 checkpoint
- load_plan: 内存降级分支检查 TTL 过期,过期则清除并返回 None
- 新增 _is_expired 方法检查 saved_at 是否超过 TTL
- _memory_plans 类型改为 tuple(plan_dict, timestamp) 以支持 TTL
- 新增 5 个 TTL 过期测试覆盖内存模式和 Redis 降级场景
2026-06-24 22:04:55 +08:00
chiguyong fa152e24ac feat(skills): add progressive skill loading with disclosure_level=0 (U5)
When disclosure_level=0, system prompt only injects skill name + description
(summary mode). SkillDetailTool is injected into the tool set, allowing the
LLM to load full instructions on-demand via skill_detail(query). This reduces
context window consumption when many skills are registered.
2026-06-24 21:49:00 +08:00
chiguyong dfd188b1a4 feat(orchestrator): add pipeline checkpoint and crash recovery (U7)
Add PipelineCheckpoint for stage-level crash recovery with Redis-first
+ memory fallback. TeamOrchestrator saves checkpoints after each phase
finalizes and supports resume(plan_id) to continue from the last
completed phase. New POST /api/v1/tasks/{id}/resume endpoint recreates
the team from saved plan and calls resume.
2026-06-24 21:04:18 +08:00
chiguyong 3dfda904d7 feat(core): add middleware pipeline architecture with onion model
U6: Unified middleware protocol (before/after) with MiddlewareChain
implementing onion model execution. Parallel integration (KTD1) —
middleware path controlled by presence of middleware_chain parameter,
existing ReActEngine path unchanged when None.

- New core/middleware.py: RequestContext, Middleware protocol,
  MiddlewareChain (onion model: before outer→inner, after inner→outer)
- 3 example middlewares: SummarizationMiddleware (U3 headroom compression),
  TokenUsageMiddleware, LoopDetectionMiddleware (request-level audit)
- ReActEngine.__init__ accepts middleware_chain parameter
- execute() branches: middleware path when chain present, existing path otherwise
- 22 tests covering ordering, error handling, state passing, backward compat
2026-06-24 20:52:15 +08:00
chiguyong ef84e3fd53 feat(experts): add SharedWorkspace state offloading for long-horizon runs
U4: ExpertTeam accepts redis_client, passes to SharedWorkspace. After phase
completion, full result is written to workspace and in-memory phase.result
is replaced with a 500-char summary + _ref_key. Dependency output reading
resolves offloaded content from workspace on demand, with graceful fallback
to summary on read failure.

Tests: 8 scenarios (offload creation, short content, dependency resolution,
workspace failure fallback, non-offloaded passthrough, redis_client wiring,
memory dict fallback, pipeline integration) — all pass.
2026-06-24 20:32:10 +08:00
chiguyong 122173ec2c feat(core): add headroom-based compression trigger
U3: ContextCompressor now accepts model_context_limit, headroom_threshold,
and min_tokens. should_compress() triggers when token ratio exceeds 0.8 of
model limit OR exceeds min_tokens (8000 fallback). ReActEngine._should_compress
delegates to compressor when available, checks is_available() first.

Tests: 6 scenarios (headroom trigger, min_tokens guard, small model,
unavailable compressor, delegation, fallback) — all pass.
2026-06-24 20:28:14 +08:00
chiguyong 717aad1303 feat(experts): add concurrency limit to TeamOrchestrator parallel phases
U2: Add asyncio.Semaphore to bound concurrent phase execution and debate
argument generation. Default limit=3, configurable via max_concurrent_phases.
Prevents LLM rate-limit spikes when many phases run in the same layer.

Tests: 5 scenarios (happy path, 5-phase edge case, serial mode, failure
release, debate integration) — all pass.
2026-06-24 20:23:30 +08:00
chiguyong 018b342d96 feat(react): add loop detection to prevent repeated identical tool calls
U1: Sliding window hash detection in ReAct loop. When the same tool is
called with identical arguments >= threshold times (default 2), injects
a correction message first, then raises LoopDetectedError if the LLM
doesn't change strategy. Covers both _execute_loop and execute_stream.
2026-06-24 20:12:35 +08:00
chiguyong a312e584ae Merge branch 'feat/expert-team-pm-collaboration' — PM 协同模式 + 代码审查全量修复
Deploy to Production / deploy (push) Waiting to run Details
# Conflicts:
#	src/agentkit/server/frontend/components.d.ts
2026-06-24 18:57:37 +08:00
chiguyong 20a4c55d5b feat(skills): SkillHarness 前置条件 + 风险守卫学习增强
- cli/skill.py: skill learn 子命令增强
- evolution/risk_guard_learner.py: 风险守卫学习改进
- memory/models.py: 记忆模型扩展
- skills/base.py + loader.py: SkillHarness 前置条件支持
- 对应测试更新
2026-06-24 18:56:51 +08:00
chiguyong 574db8458f fix(experts): PM 协同代码审查全量修复
P0: 跨阶段契约状态同步 — _notify_collaborators 更新接收方契约状态为 received
P0: 4 个 PM 事件加入 _VALID_TEAM_EVENT_TYPES 白名单

P1: 验收 fail-open 改标注降级原因
P1: 返工失败抛 RuntimeError 而非返回 dict
P1: 验收 prompt injection 防护 — 专家输出用 XML 标签包裹
P1: 契约字段校验 _EXPERT_NAME_RE
P1: bool("false") 修复 — 显式比较避免字符串真值陷阱
P1: _parse_risk_flags(None) 防御

P2: _notify_collaborators 移到验收通过后
P2: SharedWorkspace 写入移到验收通过后
P2: 验收贪婪正则修复
P2: 风险标记数量上限 MAX_RISK_FLAGS=10
P2: 返工 feedback 截断
P2: 前端会话隔离 — 切换会话时清除/恢复 collaborationState
P2: 前端契约状态更新 — collaboration_notice 时标记 delivered
P2: CLI 死代码标注 + 异常改 debug 日志
P2: 模块级 _RISK_FLAG_RE 预编译
2026-06-24 18:56:27 +08:00
chiguyong 6016c087fe feat(cli): U6 CLI 协同事件 Rich 渲染
- chat.py 新增 _render_collaboration_contracts 和 _render_pm_collaboration_event
- 4 种 PM 协同事件渲染:
  collaboration_contract_defined (cyan Panel)
  collaboration_notice (蓝→品红 文本)
  review_result (passed=green / failed=red Panel)
  risk_flagged (yellow Panel)
- plan_update 中提取 collaboration_contracts 并渲染
- _print_help 更新项目经理模式说明
- 优雅降级:字段缺失回退到 ?,空契约不输出,整体 try/except 不中断编排
- 新增 11 个测试(TestPMCollaborationRendering 9 + TestPrintHelpPMMode 2)
- ruff 通过,pytest 23 passed
2026-06-24 14:57:49 +08:00
chiguyong 34a4164430 feat(frontend): U5 前端协作关系图 + 验收/风险卡片
- types.ts 新增 ICollaborationContract/ICollaborationNotice/IReviewResult/IRiskFlag 等接口
- chat.ts 新增 collaborationState ref,处理 4 种协同事件
  (collaboration_contract_defined/collaboration_notice/review_result/risk_flagged)
  并在 plan_update 中提取 contracts,team_formed/dissolved 清理状态
- CollaborationGraphCard.vue SVG 协作关系图:
  圆形布局节点(专家首字),实线=契约,虚线动画=数据流向
  节点颜色编码验收状态(绿=通过,红=返工/失败),橙色!标记风险
- ReviewResultCard.vue 验收结果卡片(passed/failed + feedback)
- RiskFlagCard.vue 风险标记卡片(专家 + 风险描述)
- useMessageRenderer.ts 新增 3 个视图类型和渲染规格
- index.ts 导出 3 个新组件
- 遵循 U5 辩论可视化 BoardState 模式
- typecheck 通过
2026-06-24 14:42:00 +08:00
chiguyong 5487cca199 feat(experts): U4 专家风险标记 + risk_flagged 事件
- orchestrator 新增 _parse_risk_flags 静态方法,正则解析 [RISK: ...] 标记
- _execute_execution_phase 在协作通知后、验收前解析风险标记
- 风险标记通过 risk_flagged 事件广播,供前端/CLI 渲染
- 无风险标记时行为不变,向后兼容
- 新增 TestRiskFlagging 7 个测试(单/多/无/格式错误/事件发出/内容/兼容)
2026-06-24 14:17:58 +08:00
chiguyong 62fcbc0feb feat(experts): U3 Lead 验收环节 + 返工机制
- PlanPhase 添加 rework_count 和 review_feedback 字段
- 添加 _review_phase_output 方法,Lead 用 LLM 验收阶段输出
- _execute_execution_phase 重构为返工循环(MAX_REWORKS=2)
- 验收通过/返工/失败三种路径,发出 review_result 事件
- LLM 不可用时优雅降级直接通过
- 6 个新测试,全套 449 passed 无回归
2026-06-24 14:09:18 +08:00
chiguyong fef7ecea39 feat(skills): SkillHarness 激活前置条件 + 风险守卫学习
基于 SkillHarness 论文(arXiv:2606.20636)与 Agent Skills 综述
(arXiv:2602.12430)引入激活前置条件(preconditions)与来源标记
(provenance),并新增从失败轨迹学习风险守卫建议的能力。

变更内容:
- U1: SkillConfig 新增 v7 preconditions/provenance 字段(base.py)
- U2: build_skill_system_prompt 注入 preconditions 软检查段落
- U3: SkillLoader 三路径记录 provenance + entry_points 危险能力告警
- U4: 10 个业务 Skill YAML 补充 preconditions(2-4 条中文短句)
- U5: RiskGuardLearner 从失败轨迹学习风险守卫建议(人工审查,不自动应用)
- U6: CLI 命令 agentkit skill learn-risk-guards

关键决策:
- KTD1: preconditions 通过 system_prompt 注入(软检查),不做硬 LLM 调用
- KTD2: RiskGuardLearner 不自动应用,需人工审查(论文显示 75% 自动学习不安全)
- KTD3: provenance 为轻量字符串,不加 hash/签名(无合规需求)

测试:39 个新增单元测试全部通过,ruff 检查通过。
2026-06-24 13:56:37 +08:00
chiguyong c46cf06f6d feat(experts): U2 协作契约执行 — 专家可见 + 主动通知
- _execute_execution_phase 按协作契约读取相关专家输出(可见性)
- 添加 _notify_collaborators 方法,完成后通知相关专家(可协助)
- 发出 collaboration_notice 事件,契约状态更新为 delivered
- 7 个新测试,全套 443 passed 无回归
2026-06-24 13:54:38 +08:00
chiguyong f219c5f016 feat(experts): U1 协作契约数据模型 + Lead 生成契约
- PlanPhase 添加 collaboration_contracts 字段(CollaborationContract dataclass)
- 修改 _decompose_task prompt,要求 Lead 分解任务时定义协作契约
- 修改 _parse_phases 解析 LLM 返回的协作契约信息
- plan_update 事件自动包含协作契约(通过 to_dict 序列化)
- 71 + 9 = 80 个新测试,全套 436 passed 无回归
2026-06-24 13:44:50 +08:00
chiguyong 0957afb0a2 Merge branch 'test/calendar-e2e' into main
Deploy to Production / deploy (push) Waiting to run Details
Calendar E2E testing: 5-layer test plan + 8 Playwright e2e tests + config fixes.

- Layer 2: Wire calendar router into app.py (was missing)
- Layer 3: 7 integration tests (lifecycle, recurrence, tags, types, invitations, permissions, ICS)
- Layer 4: 8 Playwright e2e tests (E1-E8, all passing)
- Config: JWT secret + rate_limit fix for e2e test environment
2026-06-24 13:22:11 +08:00
chiguyong 59e47c5871 test(calendar): 8 Playwright e2e tests + config fixes (JWT secret, rate limit)
E2E tests (calendar.spec.ts):
- E1: panel loads, shows empty state
- E2: create event via UI, verify in panel
- E3: switch between calendar/card/list views
- E4: edit event title via UI
- E5: delete event via API, verify removal from UI
- E6: create event with tag via UI (keyboard.type for Ant Select)
- E7: recurring event displays multiple occurrences
- E8: invitation manager button accessible

Config fixes (playwright.config.ts):
- Set AGENTKIT_JWT_SECRET so AuthMiddleware can verify login tokens
  (without it, get_jwt_secret() returns None → 401 on all API calls)
- Call create_app(rate_limit=10000) explicitly instead of uvicorn
  factory=True — factory mode lets server_config.rate_limit (60, from
  agentkit.yaml) override the env var, causing 429 rate limiting
- Use .venv/bin/python instead of system python3 (missing deps)

All 8 tests pass (47s).
2026-06-24 13:17:53 +08:00
chiguyong b86100a0a1 feat(cli): U6 CLI 多 Agent 入口 + 辩论 Rich 渲染
- 新增 _execute_team_cli() 处理 @team 前缀,运行 ExpertTeam 流水线
- Rich 事件渲染:team_formed/plan_update/phase_*/debate_*/team_synthesis
- 干预循环使用 select.select() 非阻塞轮询 stdin(Unix-only,ponytail 标注)
- 支持 /debate 手动触发辩论、/stop 终止团队、纯文本作为上下文注入
- 扩展 _print_help() 增加 Multi-Agent 与 Interventions 说明
- 新增 12 个单元测试覆盖路由、帮助文档、函数返回值、干预基础设施
2026-06-24 13:03:57 +08:00
chiguyong 49b483b933 feat(frontend): U5 前端辩论可视化
前端展示辩论过程,专家交锋有独立气泡样式,裁决结果清晰可见。

类型 (api/types.ts):
- WsServerMessage 新增 5 个辩论事件:debate_started / expert_argument /
  debate_round_summary / debate_resolved / team_intervention_ack
- IChatMessage.message_type 新增 4 个辩论消息类型
- IChatMessage 新增 7 个可选辩论字段(topic/round/decision 等)
- 新增 4 个数据接口

Chat Store (stores/chat.ts):
- 新增 debateState ref(topic/participants/round/status)
- WS switch 新增 5 个 case,复用 appendMessage/appendStep 模式
- 辩论结束 1s 后清空 debateState(与 board_concluded 一致)

渲染器 (useMessageRenderer.ts):
- MessageViewType + resolveMessageType 新增 4 个辩论视图类型
- useMessageRenderer 新增 4 个 render spec

新组件 (messages/):
- DebateBannerCard.vue — 辩论开始横幅(主题 + 参与专家 + 开场白)
- DebateArgumentCard.vue — 专家论点卡片(专家色边框 + 轮次标签)
- DebateSummaryCard.vue — 主持人轮次小结
- DebateConclusionCard.vue — 裁决卡片(按 decision 着色)

输入框 (ChatInput.vue):
- 团队模式下显示「辩论」按钮,点击弹出 prompt 输入主题
- 发送 /debate <topic> 命令(U4 WS 干预通道处理)

npm run typecheck 通过。
2026-06-24 12:37:37 +08:00
chiguyong c831e925b6 feat(experts): U4 用户干预通道 + 手动辩论触发
建立 @team 执行期间的用户干预通道,支持 /stop、/debate <topic>、
普通文本追加上下文。

ExpertTeam (src/agentkit/experts/team.py):
- 新增 _interventions: asyncio.Queue (maxsize=64) 干预队列
- add_user_intervention(msg): 广播 + 入队
- consume_user_interventions(): 排空并返回待处理干预
- broadcast_user_message 现在同时入队干预队列

TeamOrchestrator (src/agentkit/experts/orchestrator.py):
- 新增 _user_context: list[str] 累积普通文本干预
- 新增 _process_interventions(lead, plan) 在每层执行前调用:
  * /stop → 终止执行,广播 plan_update(stopped_by_user)
  * /debate <topic> → 动态插入 DEBATE phase(受 MAX_DEBATES 限制)
  * 普通文本 → 累积到 _user_context
- _synthesize_results 将 _user_context 追加到 synthesis prompt

WS 路由 (src/agentkit/server/routes/chat.py):
- 模块级 _active_teams dict 跟踪每个 session 的活跃团队
- _execute_team_collab 执行前注册、finally 注销
- WS 消息循环:若 session 有活跃团队,message 路由为干预而非新任务
- 新增 team_intervention_ack 确认消息

测试:tests/unit/experts/test_team_intervention.py(20 测试),
覆盖队列基础、/stop、/debate、普通文本、混合消息、synthesis 影响。
同步更新 test_orchestrator_debate.py 的干预通道兼容性测试
(U4 已实现 consume_user_interventions)。

全部 418 experts 测试 + 325 server 测试通过。
2026-06-24 12:17:09 +08:00
chiguyong 5b5bd44ac4 test(calendar): 7 integration flow tests (lifecycle, recurrence, tags, types, invitations, authz, ICS) 2026-06-24 12:04:42 +08:00
chiguyong d4bc79e409 test(calendar): wire calendar router into app.py + test plan
- Register calendar router in create_app() so /api/v1/calendar/* is reachable
- Initialize CalendarService + ReminderScheduler in lifespan
- Register CalendarTool into tool registry for ReAct integration
- Lazy-import ICSProvider in routes to break circular import
- Add test plan document (5 layers: unit/integration/e2e)
2026-06-24 11:51:31 +08:00
chiguyong 91352d910e Merge feat/calendar-schedule: calendar & schedule feature (U1-U12 + code review fixes)
Deploy to Production / deploy (push) Waiting to run Details
12 implementation units, 104 tests, 23 code review fixes (2 critical, 15 major, 6 minor).
See docs/plans/2026-06-23-003-feat-calendar-schedule-plan.md for details.
2026-06-24 11:36:30 +08:00
chiguyong 460cf6e926 docs(calendar): add implementation history with code review summary 2026-06-24 11:36:10 +08:00
chiguyong 3fdee65979 fix(calendar): code review fixes - 23 issues (2 critical, 15 major, 6 minor) 2026-06-24 11:29:23 +08:00
chiguyong ac26d417b3 feat(experts): U3 分歧检测 + 方案评审辩论自动触发
在 TeamOrchestrator 中新增 4 个方法实现自动辩论触发:

- _maybe_add_plan_review_debate: 任务分解后可选插入方案评审 DEBATE
  phase(phases > 2 且 LLM 判断需要时),所有执行阶段依赖它
- _detect_divergence: 每层执行后用 LLM 判断已完成阶段产出是否与其他
  阶段存在分歧,偏好 false negative
- _insert_debate_phase: 动态插入 DEBATE phase 并重 wiring 依赖
  (原依赖 trigger 的 phase 现在依赖 DEBATE)
- _check_divergence_and_insert_debates: 每层完成后的协调入口,
  受 MAX_DEBATES=3 上限保护

主循环从 `for layer in layers` 改为 `while True` + 重新计算
topological_sort(),以支持动态插入 DEBATE phase 后的依赖分层。

测试:tests/unit/experts/test_divergence_detection.py(21 测试),
覆盖 happy path / 边界 / 错误路径 / 集成分层。同步修复
test_team_orchestrator.py 的 mock gateway 以适配 U3 的额外 LLM 调用。

全部 398 测试通过。
2026-06-24 11:09:53 +08:00
chiguyong fbe08cb1e2 feat(experts): add debate phase executor to TeamOrchestrator (U2)
Implement _execute_debate_phase() with Lead-facilitated structured debate:
- Lead opens with divergence point + dependency context
- Experts argue in parallel per round (asyncio.gather)
- Lead summarizes each round, then adjudicates final verdict
- Verdict produces decision (adopt/compromise/shelve/inconclusive) + conclusion
- Conclusion written to SharedWorkspace for downstream phases

Escape hatches:
- debate_config.skip=true short-circuits with template text
- MAX_DEBATE_ROUNDS=4 hard cap on rounds
- User /stop intervention ends debate early (U4-compatible via getattr fallback)
- LLM unavailable falls back to template verdict, no crash

New events: debate_started, expert_argument, debate_round_summary,
debate_resolved (plus existing phase_completed for consistency).

Phase dispatcher (_execute_phase) routes by phase_type:
EXECUTION to _execute_execution_phase, DEBATE to _execute_debate_phase.

36 new tests in test_orchestrator_debate.py covering happy path (2 rounds,
2 experts), max_rounds=1 boundary, empty participants, user stop, skip
escape hatch, LLM unavailable, SharedWorkspace integration, event
broadcasting, intervention channel compatibility, and helper methods.
All 377 expert tests pass.

Also includes planning artifacts (brainstorm requirements + implementation
plan with 6 units U1-U6).
2026-06-24 10:54:51 +08:00
chiguyong e539122314 feat(experts): add PhaseType enum and debate_config to PlanPhase
U1: Data model foundation for structured debate collaboration.
- Add PhaseType enum (EXECUTION | DEBATE)
- Add phase_type and debate_config fields to PlanPhase
- Update to_dict/from_dict for serialization with backward compatibility
- Add tests for PhaseType, debate phase creation, serialization, and
  mixed EXECUTION+DEBATE topological sort
2026-06-24 10:42:11 +08:00
chiguyong 4ea7801bcf fix(router): keyword match tiebreaker should preserve list order, not alphabetical 2026-06-24 10:11:42 +08:00
chiguyong d1250cf32b docs(calendar): mark plan as completed — all 12 units implemented 2026-06-24 05:04:39 +08:00
chiguyong 394d734d42 feat(calendar): U12 reminder config and external sync settings UI 2026-06-24 05:02:29 +08:00
chiguyong 3131769aed feat(calendar): U11 event editor, invitation manager and batch operations 2026-06-24 05:02:12 +08:00
chiguyong 8350b02d75 feat(calendar): U10 frontend calendar views with 3 view modes and drawer 2026-06-23 23:50:28 +08:00
chiguyong 8d4145ddf9 feat(calendar): U7 Outlook sync via Microsoft Graph API
OutlookSyncProvider implementing AbstractSyncProvider for
bidirectional Outlook Calendar sync. Uses Graph API delta query
for incremental pull, auto-refreshes OAuth tokens on 401, and
converts Outlook recurrence patterns to RRULE. Same conflict
resolution as CalDAV (last-write-wins + WS notification).

- src/agentkit/calendar/sync/outlook_provider.py — OutlookSyncProvider
- tests/unit/calendar/test_sync_outlook.py — 8 tests
2026-06-23 23:49:24 +08:00
chiguyong 40bc27822f feat(calendar): U9 frontend store, API client and types
CalendarApiClient with 20 methods covering all backend endpoints
(listEvents, createEvent, importIcs, searchUsers, syncNow, etc.).
useCalendarStore Pinia store with events/eventTypes/tags state,
view mode switching, and handleWsEvent dispatch for 4 calendar WS
message types. WsServerMessage union extended with calendar variants.

- src/agentkit/server/frontend/src/api/calendar.ts — API client + types
- src/agentkit/server/frontend/src/stores/calendar.ts — Pinia store
- src/agentkit/server/frontend/src/api/types.ts — WS message types
2026-06-23 22:52:40 +08:00
chiguyong 40d326cd3f feat(calendar): U6 CalDAV sync provider and SyncManager
AbstractSyncProvider interface with CalDAVSyncProvider implementation
for bidirectional Apple Calendar sync. SyncManager orchestrates all
providers (G8) — sync_all/sync_provider/resolve_conflict with
last-write-wins + WS notification on conflicts (G4). caldav library
calls wrapped in asyncio.to_thread for non-blocking operation.

- src/agentkit/calendar/sync/base.py — AbstractSyncProvider ABC
- src/agentkit/calendar/sync/caldav_provider.py — CalDAVSyncProvider
- src/agentkit/calendar/sync/manager.py — SyncManager (G8)
- pyproject.toml — added caldav>=1.3 dependency
- tests — 12 tests (9 CalDAV + 3 SyncManager)
2026-06-23 22:52:29 +08:00
chiguyong ffb184acc7 feat(calendar): U8 iCal/ICS import and export
ICSProvider parses .ics files (icalendar library) and creates local
CalendarEvents, skipping duplicate UIDs. Export builds an iCalendar
from events in a date range, deduplicating recurring event
occurrences back to a single VEVENT with RRULE. REST endpoints:
POST /import-ics (multipart upload), GET /export-ics (download).

- src/agentkit/calendar/sync/__init__.py — sync subpackage init
- src/agentkit/calendar/sync/ics_provider.py — ICSProvider (import/export)
- src/agentkit/calendar/db.py — added get_event_by_external_id() for dedup
- src/agentkit/server/routes/calendar.py — import-ics and export-ics endpoints
- pyproject.toml — added icalendar>=5.0 dependency
- tests/unit/calendar/test_ics_provider.py — 8 tests
2026-06-23 22:20:07 +08:00
chiguyong 26efbb51db feat(calendar): U5 reminder subsystem with scheduler and multi-channel dispatch
ReminderScheduler scans upcoming events every 60s, matches reminder
rules, and dispatches via client (WS), email (SMTP), or webhook
channels. Idempotent delivery (no duplicates on re-scan), retry with
exponential backoff (up to 3 attempts). Follows task_store.py
start/stop asyncio loop pattern (KTD-2 — conscious deviation from
APScheduler).

- src/agentkit/calendar/scheduler.py — ReminderScheduler (start/stop/scan_once)
- src/agentkit/calendar/reminders.py — ReminderDispatcher (strategy per channel)
- src/agentkit/calendar/db.py — added list_all_events_in_time_range() for scheduler
- tests/unit/calendar/test_scheduler.py — 8 tests
- tests/unit/calendar/test_reminders.py — 9 tests
2026-06-23 22:19:57 +08:00
chiguyong ddcedb57b2 feat(calendar): U4 post-processing extractor with keyword gating
Adds PostProcessingExtractor — a zero-LLM keyword gate (Chinese +
English time words) followed by LLM extraction for ambiguous cases.
Events created from extraction carry source="post_extract" so the UI
can style them distinctly (R33). LLM gateway is optional to keep the
constructor testable without a live provider.

- src/agentkit/calendar/extraction.py — PostProcessingExtractor
- tests/unit/calendar/test_extraction.py — 13 tests with MockLLMGateway
2026-06-23 21:56:20 +08:00
chiguyong 42fe7bcbc9 feat(calendar): U3 agent calendar tool for ReAct integration
Adds CalendarTool implementing the Tool ABC so the ReAct engine can
create, query, update, and delete events autonomously. Resolves
event_type_name and tag_names (look up or create), sets
source="agent" to distinguish agent-created events from manual ones.

- src/agentkit/tools/calendar_tool.py — CalendarTool(Tool)
- tests/unit/tools/test_calendar_tool.py — 13 tests covering all actions
2026-06-23 21:56:08 +08:00