feat: 实现日历提醒完整功能(操作执行、通知服务重构、归档)
- 新增 ReminderActionExecutor 处理取消/稍后提醒操作 - 新增 ReminderOutboxStore 本地存储待处理操作 - 重构 LocalNotificationService 支持聚合提醒和交互操作 - 新增 event_color_resolver 工具类统一颜色解析 - 新增 CalendarService.archiveEvent 归档方法 - 增强 ModelTracking 支持缓存命中、推理token和成本追踪 - 添加 qwen3.5-35b-a3b 模型配置 - 更新 AndroidManifest 全屏intent权限 - 补充相关单元测试和文档
This commit is contained in:
@@ -76,6 +76,7 @@ Base URL: `/api/v1/agent`
|
||||
- `200 OK`
|
||||
- `Content-Type: text/event-stream`
|
||||
- 事件类型与字段见 `docs/protocols/agent/sse-events.md`
|
||||
- usage 审计与成本回退策略见 `docs/protocols/agent/sse-events.md`(5) Usage 审计协议)
|
||||
- 空闲时会发送 keep-alive 注释行 `: keep-alive`
|
||||
|
||||
### 错误码
|
||||
|
||||
@@ -197,7 +197,107 @@ data: <json>
|
||||
|
||||
`inputTokens`、`outputTokens`、`cost`、`latencyMs`、`model` 属于后端内部统计字段,不在 SSE 对外协议中暴露。
|
||||
|
||||
### 3.5 快照事件
|
||||
---
|
||||
|
||||
## 5) Usage 审计协议(后端内部)
|
||||
|
||||
本节描述后端对 LLM usage 的内部审计与计费策略。该协议用于数据库持久化、成本统计与运行观测,不对 SSE 外部协议直接暴露。
|
||||
|
||||
### 5.1 当前厂商范围
|
||||
|
||||
- DashScope(Qwen)
|
||||
- DeepSeek
|
||||
|
||||
当前实现仅针对上述两家做深度适配。
|
||||
|
||||
### 5.2 原始字段采集(Provider -> Runtime)
|
||||
|
||||
`TrackingChatModel` 会优先读取 provider 直接字段,读取不到时再从 metadata 补齐。
|
||||
|
||||
优先级如下:
|
||||
|
||||
1. 直接字段(优先)
|
||||
- `usage.input_tokens`
|
||||
- `usage.output_tokens`
|
||||
- `usage.total_tokens`
|
||||
- `usage.time`(秒)
|
||||
- `usage.cost`(若存在)
|
||||
2. metadata 字段(补齐)
|
||||
- `metadata.prompt_tokens`
|
||||
- `metadata.completion_tokens`
|
||||
- `metadata.total_tokens`
|
||||
- `metadata.prompt_tokens_details.cached_tokens`
|
||||
- `metadata.prompt_cache_hit_tokens`
|
||||
- `metadata.prompt_cache_miss_tokens`
|
||||
- `metadata.completion_tokens_details.reasoning_tokens`
|
||||
- `metadata.cost` / `metadata.total_cost`(若存在)
|
||||
|
||||
### 5.3 归一化后的内部 usage_summary 字段
|
||||
|
||||
`TrackingChatModel.usage_summary()` 当前输出:
|
||||
|
||||
- `input_tokens`
|
||||
- `output_tokens`
|
||||
- `total_tokens`
|
||||
- `latency_ms`(由 `usage.time * 1000` 转换)
|
||||
- `cached_prompt_tokens`
|
||||
- `prompt_cache_hit_tokens`
|
||||
- `prompt_cache_miss_tokens`
|
||||
- `reasoning_tokens`
|
||||
- `direct_cost`
|
||||
- `direct_cost_observed`(0/1)
|
||||
- `direct_cost_complete`(0/1)
|
||||
- `model_call_records`
|
||||
- `usage_records`
|
||||
- `direct_cost_records`
|
||||
- `cost_source`(`provider` | `catalog_fallback`)
|
||||
|
||||
### 5.4 成本计算策略(严谨优先)
|
||||
|
||||
核心原则:**能直接用 provider 返回就直接用;缺失才 fallback。**
|
||||
|
||||
`LiteLLMService.build_usage_metadata()` 执行规则:
|
||||
|
||||
1. 仅当以下条件同时满足时使用 provider 直出成本:
|
||||
- `usageComplete == true`(`model_call_records == usage_records`)
|
||||
- `direct_cost_observed == 1`
|
||||
- `direct_cost_complete == 1`
|
||||
- `direct_cost` 为有效非负数
|
||||
2. 否则使用 catalog 价格回退计算(`calculate_cost`)
|
||||
|
||||
### 5.5 Fallback 计费细节
|
||||
|
||||
- 档位选择:按 `prompt_tokens` 命中 `pricing_tiers.max_prompt_tokens`
|
||||
- 公式:
|
||||
|
||||
```text
|
||||
cost = uncached_prompt_tokens * input_cost_per_token
|
||||
+ cached_prompt_tokens * cached_token_rate
|
||||
+ completion_tokens * output_cost_per_token
|
||||
```
|
||||
|
||||
- `cached_token_rate` 规则:
|
||||
- 若 tier 配置了 `cache_hit_cost_per_token` 且 > 0,使用该值
|
||||
- 否则回退为 `input_cost_per_token`
|
||||
|
||||
### 5.6 内部 costSource 语义
|
||||
|
||||
- `provider`: 使用 provider 直接成本
|
||||
- `catalog_fallback`: 正常使用价格表回退
|
||||
- `catalog_fallback_incomplete_provider_cost`: provider 返回了部分 direct cost,但不完整,回退价格表
|
||||
- `incomplete_usage_fallback`: usage 本身不完整,回退价格表
|
||||
|
||||
### 5.7 DeepSeek / DashScope 当前观测到的返回特征
|
||||
|
||||
根据当前线上探针与运行结果:
|
||||
|
||||
- 两家都稳定返回:`input_tokens`、`output_tokens`、`time`
|
||||
- `usage.total_tokens` 顶层可能为空,但 `metadata.total_tokens` 可用
|
||||
- DeepSeek 常见 `prompt_tokens_details.cached_tokens`、`prompt_cache_hit_tokens`、`prompt_cache_miss_tokens`
|
||||
- DashScope 常见 `completion_tokens_details.reasoning_tokens`(可能为 `null`)
|
||||
- 两家当前都未稳定提供直接 `cost` 字段,因此多数场景为 catalog fallback
|
||||
|
||||
## 6) 快照事件
|
||||
|
||||
编码器支持以下 AG-UI 类型映射:
|
||||
|
||||
@@ -208,7 +308,7 @@ data: <json>
|
||||
|
||||
---
|
||||
|
||||
## 4) 字段命名约定
|
||||
## 7) 字段命名约定
|
||||
|
||||
- 事件顶层通用字段使用 AG-UI 风格:`type`、`threadId`、`runId`
|
||||
- 部分业务字段沿运行时模型历史命名保留下划线:
|
||||
|
||||
Reference in New Issue
Block a user