forked from bai/curriculum-project-hub
feat(hub): 事件去重(A-4) + 审计写入路径(A-8)
A-4 FeishuEventReceipt: - 新增 FeishuEventReceipt 表(eventId @unique),lark ws 至少一次投递的幂等兜底 - MessageReceiveEvent 加 header.event_id 字段 - trigger 入口查重:已存在的 event_id → 跳过(不建第二次 run) - resetDb 加入 FeishuEventReceipt A-8 审计写入: - AuditEntry 加 projectId(权限拒绝/slash 命令等无 run 的审计点可定位) - 新建 src/audit.ts:writeAudit(prisma, entry) best-effort 写入(吞错,不阻断 trigger) - trigger 五个审计点:trigger.denied / trigger.role_denied / run.created / run.lock_race / run.finished / run.failed - 新增 audit unit 测试(3) + trigger 集成测试(去重 + 审计,2) 59 tests 全过。
This commit is contained in:
@@ -36,9 +36,12 @@ Per-run model selection (the run carries its model) is the switching point.
|
||||
|
||||
- Switching model mid-project = new session; the new run seeds from project
|
||||
memory/anchors (ADR-0003), not the prior session's live context.
|
||||
- The agent layer is provider-agnostic: the agent loop is ours; model calls go
|
||||
through an OpenAI-compatible client. No hard dependency on a single-vendor
|
||||
agent SDK.
|
||||
- The agent layer is provider-agnostic: model calls go through an
|
||||
OpenAI-compatible client, and the tool-calling loop is delegated to the
|
||||
Vercel AI SDK (`generateText` + `tool`). The provider seam is the SDK's
|
||||
`LanguageModel` interface, not a hand-rolled loop; swapping provider is
|
||||
swapping the `createOpenAICompatible` factory, not rewriting the loop. No
|
||||
hard dependency on a single-vendor agent SDK.
|
||||
- Role-based model routing (different run kinds default to different models) is
|
||||
a product/admin configuration concern, not a spec invariant.
|
||||
- "AgentSession reused by many runs" (ADR-0002) holds *within* one
|
||||
|
||||
Reference in New Issue
Block a user