chenchen and Claude Opus 4.8
088e3dd5a2
fix(telemetry): 补遥测后台 zh 翻译,修复中英混杂
...
遥测页/侧栏多处 key(Client Telemetry/Device ID/Error category/Error code/
Apply/Aggregate/Stack hash/Distinct users + 描述)缺 zh 翻译,回退成英文,
与中文 UI 混杂。补入 zh.json(行级插入,保留 translation 包装,JSON 校验通过)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-11 20:34:51 +08:00
chenchen
992c322858
Merge remote-tracking branch 'origin/feat/admin-telemetry-views' into deploy/test-pr69-73
2026-06-11 19:19:36 +08:00
chenchen
b36dc3fe28
Merge remote-tracking branch 'origin/feat/swarm-io-proxy-46' into deploy/test-pr69-73
2026-06-11 19:19:35 +08:00
chenchen
66947cd543
Merge remote-tracking branch 'origin/feat/swarm-model-key-injection-60' into deploy/test-pr69-73
2026-06-11 19:19:34 +08:00
chenchen
f091089365
Merge remote-tracking branch 'origin/feat/swarm-subscription-gate' into deploy/test-pr69-73
2026-06-11 19:19:32 +08:00
chenchen and Claude Opus 4.8
e7239c24b6
feat(telemetry): 管理员遥测后台只读视图(列表 + 聚合)
...
客户端错误遥测(#24 )此前只有 ingest + 留存清理,无后台查看。新增管理员只读视图
(列表 + 聚合两者),admin-gated —— device_id 可关联账号,仅管理员可读。
后端:
- model.ListTelemetryEvents(filter, startIdx, pageSize):分页列表(received_at desc),
按 user_id/client_id/platform/app_version/error_category/error_code + 时间范围过滤。
- model.AggregateTelemetryEvents(filter, dimension, limit):按白名单维度 group by 计数 +
COUNT(DISTINCT user_id),busiest first。维度白名单是 SQL 注入防线(列名只能来自 map)。
跨库安全(仅 COUNT/COUNT(DISTINCT)/GROUP BY 固定列,无 DB 特有日期函数)。
- 查询走 LOG_DB(与 ingest 同库);遥测仍隔离于计费、载荷无用户内容。
- controller AdminListTelemetryEvents / AdminAggregateTelemetryEvents;路由
GET /api/telemetry/{events,aggregate},middleware.AdminAuth() 守门。
前端(web/default):
- features/telemetry:api + types + 页面(过滤条 + 聚合面板含维度切换/条形/去重用户数 +
分页列表表)。
- 路由 /_authenticated/telemetry(ROLE.ADMIN 守门),系统设置工作区侧栏加「Client Telemetry」入口。
- routeTree.gen.ts 由 router-generator 重新生成(仅 +22 行 telemetry 路由,无重排)。
测试:model/telemetry_query_test.go 覆盖列表过滤/分页/最新在前、聚合计数 + 去重用户、
维度白名单拒绝(注入防线)。go build ./... + model/controller/router 全绿;前端 tsc 仅
resources-page 一处既有报错(与本改动无关)。
影响面:Manager ✅ (新增 admin 只读端点 + 前端页面)/ 计费 ❌ (遥测隔离)/ 密钥 ❌ /
审计 ❌ / Client ❌ / agent_swarm ❌ / 发布链路 ❌ 。隐私:沿用 #24 口径,载荷无用户内容,
device_id 账号可关联故管理员才可读。
Refs #24。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-11 19:13:38 +08:00
chenchen and Claude Opus 4.8
2c60af0216
feat(swarm): #46/#28 暴露 input/result 代理端点(I/O 闭环)
...
agent_swarm PR#41 已合并 main(契约冻结),HM 补齐客户端+swarm 双方点名需要的
两条透传端点(均设备签名,挂 /api/heicode/swarms/:id 下):
- POST /swarms/:id/input → 代理 Swarm POST …/{deployment_id}/input(追加用户输入,
注入 source=user_append;终态 run 自动 reopen,stopped 拒绝)。写路,需
SWARM_RUNTIME_ENABLED+base+token,缺一即拒不伪造受理。**指令文本仅转发,绝不落
HM 日志/审计/事件**(#40 原文不进事件流 + #46 勿落日志);审计只记发生过一次 append。
- GET /swarms/:id/result → 代理 Swarm GET …/{deployment_id}/result,返回
{summary, deliverable, artifacts[], termination_reason, status};产物按 uri 取非内联。
读路,需 base+token(与派发开关解耦);透出前 stripSensitiveKeys 递归剔除 secret_ref 等兜底。
新增:callSwarmRuntimeJSON(通用 JSON 调用 + envelope 归一,错误信息不含请求体)、
agentRuntimeSwarm{Input,Result}Path(默认 create-path 基路径,SWARM_RUNTIME_{INPUT,RESULT}_PATH 可覆盖)。
测试:swarm_io_proxy_test.go 覆盖路径构造(默认/空回退/env 覆盖)、input 转发(方法/路径/鉴权/body)、
result 解析 + deliverable/artifacts 脱敏、运行时非 2xx 报错。go build ./... + controller/router 全绿。
影响面:Manager ✅ (透传端点)/ agent_swarm ✅ (消费 PR#41 契约)/ Client ✅ (驾驶舱 I/O 闭环)/
Agent ❌ / CodeGW ❌ / 计费 ❌ / 密钥 ❌ (不经手 secret)/ 审计 ✅ (input_appended,不含原文)/ 发布链路 ❌
Refs #46 #28。Depends-on-contract: agent_swarm PR#41 (已合并 main)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-11 18:41:39 +08:00
chenchen and Claude Opus 4.8
c494e9576e
feat(swarm): #60 模型 key 注入(方案A)+ pool_terminated 吊销握手
...
对接 agent_swarm PR#43 定死的参数,实现 HM 侧的 per-user 模型 key 注入:
- A.1 粒度/命名:为认证用户 mint 一把 per-user sk-(getOrMintSwarmModelToken),
跨该用户所有 swarm run 复用;KV 密文名 swarm-model-key-<user_id>。
- A.2 KV value:JSON {"openai_api_key":"sk-..."},对齐 Swarm
orchestrator/agent_launcher._extract_model_key 解析字段。
- A.4 OPENAI_API_BASE 为 Swarm 部署常量,HM 不经 billing_context 下发。
- A.5 吊销:事件驱动。注册 swarm.pool_terminated(swarm_lifecycle 类),
回调 handleSwarmPoolTerminated 删 KV 密文 + 软删 token;user_id 优先取
payload,缺失回退 deployment 上下文。
createAgentDeploymentFromPlan 在 swarm 模式且 billing_context 未自带 secret_ref
时调 provisionSwarmModelKey,把 azkv:// 引用写进 billing_context.secret_ref 下发。
Key Vault 未配置/不可达时降级:记日志、secret_ref 留空,不阻断 create(联调前可用)。
明文 sk- 仅经 secret_ref 服务端解析,绝不入代码/日志/事件/argv。
测试:swarm_model_key_test.go 覆盖 per-user 复用、吊销重 mint、pool_terminated
回调(payload/上下文两路 user_id)、非目标事件不误吊销、事件已注册。
影响面:agent_swarm(契约消费侧)、密钥(per-user sk- mint+吊销)、计费
(走 User.Quota)、审计(回调入库+审计事件)。不影响 Client/CodeGW/发布链路。
未决依赖:A.3(Swarm 读 heicode-kv 的 RBAC,运维授权 pending)是端到端联调前置,
不阻塞本 PR。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-11 18:30:32 +08:00
chenchen and Claude Opus 4.8
c55e60b3b3
test(swarm): adapter 用例走 admin 旁路通过蜂群订阅 gate
...
PR#70 给 AgentCreateUserSwarm 加了订阅 gate 后,TestAgentUserSwarmsAdapter
CreatesScopedDeployment(普通用户、无订阅)被 POLICY_REJECTED。该用例聚焦
adapter 的用户作用域而非 gate 本身(gate 由 TestGetUserSwarmEnabled 覆盖),
故走 admin 旁路。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-11 18:28:37 +08:00
chenchen and Claude Opus 4.8
a0616eaebf
feat(swarm): 按订阅套餐控制蜂群使用权(管理员可配)
...
需求:管理员在 HM 控制台按订阅套餐控制谁能用蜂群。照搬现有 MaxAgents(#8 )模式
(per-plan、管理员设、不硬编码 tier)。
后端:
- model SubscriptionPlan 加 SwarmEnabled bool(default false;AutoMigrate 加列,跨三库)。
- model GetUserSwarmEnabled(userId):用户任一活跃套餐 SwarmEnabled=true 即放行(镜像
GetUserMaxAgents);无套餐/DB 不可用 => false(opt-in)。
- controller AgentCreateUserSwarm gate:普通用户须有开通套餐,管理员(role>=admin)绕过(测试/运维)。
- controller 套餐 admin upsert 字段映射加 swarm_enabled(create 整结构已自动带)。
前端(web/default 套餐编辑):
- plan-form schema/defaults/映射 + types 加 swarm_enabled。
- 套餐编辑抽屉加「蜂群使用权」Switch(镜像 enabled)。
- zh.json 加 "Swarm Access" → 蜂群使用权(en 用 key 兜底)。
默认关闭(opt-in)、管理员逐套餐勾选;gate 在 swarm 创建入口,与 swarm 运行时是否启用无关。
测试 TestGetUserSwarmEnabled(无套餐/开通/未开通/过期/多套餐/非法 user)。build+vet+model 测试全绿。
影响面:HM 订阅模型(加字段)+ swarm 创建鉴权 + admin UI;不涉计费扣费/密钥/swarm 契约。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-11 17:55:55 +08:00
chenchen and Claude Opus 4.8
a5419f9a15
feat(swarm): GET /swarms/:id 详情补 resource_grants/budget/audit_logs ( #66 里程碑07/08)
...
HM 自有数据,不依赖 swarm 运行时,仅 detail 带、list 不带(免膨胀):
- resource_grants:plan_json 提取,脱敏(grant_id/resource_id/resource_type/binding_scope/
target_role/permission_scope/status + has_secret);绝不下发 secret_ref 值。
- budget:max_tokens/max_cost_usd/max_duration_sec(plan.Budget 上限)。
- audit_logs:HM 控制面 deployment 级审计(脱敏 + 截断 100);run 级 trace 待 swarm /audit 代理(PR#41)。
usage/used_*/cost_by_phase 待 #60 + swarm metrics,本批不臆造。
测试:脱敏(secret_ref 值不外泄)/has_secret/budget 上限/空坏JSON。build+vet+controller 测试全绿。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-11 17:24:09 +08:00
chenchen and Claude Opus 4.8
c3f51fe479
feat: wire swarm stop to runtime + add events SSE stream (#45/#46)
...
契约已冻结(agent_swarm#14 runtime-contract v1 / #15 event-schema v1),HM 侧据此
落地两项原本 deferred 的能力,叠在读侧适配(PR #59 )之上:
- stop(#45 ):HeicodeStopSwarm 真实调用运行时冻结路径
POST /api/agent/swarm/deployments/{deployment_id}/stop,复用 agent_runtime_client
的配置/URL/信封解析;Bearer SWARM_RUNTIME_SERVICE_TOKEN + X-Idempotency-Key 幂等。
仅 SWARM_RUNTIME_ENABLED=true 且配齐 base_url+token 时发起,否则 POLICY_REJECTED,
绝不伪造 accepted;终态不抢写,由 swarm.stopped 回调写回。
- events SSE(#46 读侧):GET /api/heicode/swarms/:id/events/stream?after=,与
events?after 同源(HM 持久化回调事件,按 user_id 收口 + payload 脱敏),命中终态
(swarm.completed/failed/stopped)/客户端断开/超时(30min)收流。不调运行时。
- docs:刷新 heicode-swarm-deferred.md(登记冻结契约、读侧/stop/SSE 已落地、唯一剩余
计费缺口 #60 )与 heicode-desktop-client-api.md §5.2(SSE + stop 端点)。
影响面:Client(新增 SSE 端点 + stop 行为变化)、agent_swarm(按冻结契约调用其 stop)。
不涉及 Manager↔AM、密钥、计费扣费逻辑(计费缺口 #60 仍阻塞于 agent_swarm#16)。
测试:callSwarmRuntimeStop(httptest 校验路径/鉴权/幂等头/信封解析/错误路径/runtime
id 回退)+ swarmEventIsTerminal;go build ./... 与 controller 测试全绿。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-10 21:43:00 +08:00
Fasthei and GitHub
5470ba2c13
Merge pull request #63 from xmindlab-heicode/feat/aws-full-resource-discovery
...
feat(discovery): AWS 全量资源发现 — EC2/RDS/S3/Lambda List/Describe (#62 )
2026-06-10 21:35:03 +08:00
chenchen and Claude Opus 4.8
292504735e
feat(swarm): add goal_summary to swarm status view (#45/#28 consumer ask)
...
@Mem0ried 客户端 consumer 验收(#59 )指出 GET /swarms/:id 缺 goal_summary —— Run 列表
只能显示 deployment_id/status,体验差。补:swarmDeploymentView 增加 goal_summary,从持久化
plan_json 顶层 objective 提取,折叠空白为单行 + 截断(200 rune)+ RedactText 兜底;取不到
(无 plan / 无 objective / 坏 JSON)返回空串,不臆造。list 与 detail 同走 swarmDeploymentView,
两处都带上。
文档 docs/integration/heicode-desktop-client-api.md §5.2 状态样例补 goal_summary 字段说明。
测试 TestSwarmGoalSummary 覆盖:空/坏 JSON/无 objective→空;多行多空格折叠;误入 sk- 被脱敏;
超长截断带省略号。go build ./... 与 controller 测试全绿。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-10 21:17:32 +08:00
chenchen and Claude Opus 4.8
8529340a40
feat(discovery): AWS full-account resource discovery — EC2/RDS/S3/Lambda List/Describe ( #62 )
...
#5 的 AWS 适配器只走 Resource Groups Tagging API GetResources,仅覆盖「已打标签」资源,
不含未打标签的 EC2/RDS/S3 等(代码已据实声明,#5 全量诉求未据此关闭)。本次补齐:
- 新增服务级发现(aws_resource_discovery_services.go):EC2 DescribeInstances、
RDS DescribeDBInstances、S3 ListBuckets、Lambda ListFunctions,均复用已通过 AWS
get-vanilla 向量验证的 SigV4 签名(awsSigV4Authorization),无 AWS SDK 依赖。
- discoverAWS 改为编排:tagged + 各服务级结果按 ARN 合并去重(tagged 优先保留,标签信息更全);
原 tagged 逻辑保留为 discoverAWSTagged。
- 失败降级:单服务调用失败(如缺该服务读权限)只记日志并跳过,不让整次发现失败;仅当
tagged 报错且无任何结果时才抛原始错误,保证凭据/区域问题可见。
- 区域:EC2/RDS/Lambda 用账号配置 region;S3 ListBuckets 全局(us-east-1 签名)。跨 region
扫描不在本次范围(单 region),后续可在 #62 跟踪。
安全:沿用 applyDiscoveredResourceFields 既有约束——发现出的资源 SecretRef 恒空,绝不继承
账号 secret_ref;凭据仍走 cloud_account secret 链路,不落代码/日志。
影响面:仅 HM 内部云资源发现;不涉及 Client、AM、agent_swarm、计费、审计字段、密钥写入。
测试:parseEC2Instances/parseRDSInstances/parseS3Buckets/parseLambdaFunctions(真实响应
样本 XML/JSON)+ mergeDedupeByExternalID(去重/优先/空 id);SigV4 向量与既有发现测试不变;
go build ./... 与 controller 测试全绿。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-10 20:38:17 +08:00
chenchen and Claude Opus 4.8
56a9b02a25
feat(swarm): adopt frozen agent_swarm contract v1 (read-side) (#45/#46)
...
按 agent_swarm#14/#15 冻结契约做 HM 读侧适配(客户端 #28 消费):
- 注册 6 类新事件(event-schema v1):swarm.completed/failed/stopped、approval.approved/rejected、
handoff.created(categories + requiredFields 两表;必填先最小集,待 agent_swarm PR #28 §4 精校)。
- AgentCallbackEvent 增 Sequence(per-swarm 严格递增序号),回调入库透传 envelope.sequence;
事件视图暴露 sequence 供客户端去重/排序。游标仍用稳定 id(next_after)避免 sequence 未全量
上线时回归。
- 脱敏键补 credential_ref/signing_secret_ref(envelope 按设计透传 azkv:// 引用,客户端视图剔除)。
- artifact.created → 扁平视图 {uri,checksum,task_id,size_bytes?,created_at}(无 secret_ref;
size 未知省略不伪造)。
- 状态展示映射 §4.1:display_status(blocked→degraded;不臆造 preparing/verifying)。
测试:状态映射、artifact 视图(脱敏 + size 省略)、6 类事件注册;controller+model 全回归通过,
go build/vet 干净。文档 §5.2 更新。
未含(下一 PR):stop 真实运行时接入(写路径,复用 agentRuntimeClientConfigForMode("swarm"))。
Affects: Manager only(只读查询契约适配)。AgentCallbackEvent 加列(AutoMigrate);无计费改动。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 18:01:32 +08:00
Fasthei and GitHub
3af911257f
Merge pull request #56 from xmindlab-heicode/feat/agent-endpoint-security-scheme
...
feat(agent): return A2A endpoint security scheme/profile (#55 )
2026-06-10 16:27:34 +08:00
chenchen and Claude Opus 4.8
2500f17189
feat(agent): return A2A endpoint security scheme/profile ( #55 )
...
客户端 #25/#55:A2A 直连方需 Manager 在 agent endpoint 元数据给出安全通道信息,才能在
生产强制 HTTPS。agent 对象(列表/详情/部署/状态返回)新增 security:
- scheme: http | https(从 subdomain 推断)
- security_profile: none | tls(显式 https→tls;http 或裸主机→none)
- secure: profile != none
保守口径:无法确证 TLS 即 none,宁可客户端在生产拒绝也不回传"看似安全"的明文端点。
客户端置 HEICODE_AGENT_REQUIRE_SECURE=1 即据此强制(secure=false→拒绝)。AM 上 HTTPS/mTLS
listener(azgy)后 profile 自动变 tls,客户端无需改包。元数据不含任何 secret_ref。
纯函数 agentEndpointSecurity + 单测;文档 §5/§6 更新。Manager only,无计费/审计改动。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 15:37:28 +08:00
Fasthei and GitHub
33f60922cb
Merge branch 'main' into feat/preflight-confirm-audit-version
2026-06-10 15:36:14 +08:00
Fasthei and GitHub
88793b1066
Merge pull request #52 from xmindlab-heicode/feat/cloud-discovery-aws-gcp
...
feat(discovery): provider-agnostic cloud discovery — AWS + GCP adapters (#5 )
2026-06-10 15:33:58 +08:00
chenchen and Claude Opus 4.8
19640b44f5
fix(preflight): address #41 review — persisted confirmation, deploy ready re-check, template-aware version
...
回应 Fasthei 复审(PR #51 CHANGES_REQUESTED):
1. 持久化确认记录(强一致):新增 model.PreflightConfirmation 表 + InsertPreflightConfirmation +
PreflightConfirmationExists。confirm 时落库(默认 TTL=HEICODE_PREFLIGHT_CONFIRMATION_TTL_SECONDS
=3600s,可设 0 不过期),写失败直接报错(非 best-effort)。部署侧要求该版本存在未过期确认记录
→ 杜绝直接拿 GET version 绕过 confirm/审计。
2. 部署重新校验 Ready:verifyDeployPreflight 增加 summary.Ready 检查 —— 预算/agent_slot 等
易变项不进版本哈希,故部署时重查,防 confirm 后余额耗尽/槽位占满仍启动。
3. 版本哈希纳入模板安全面:computePreflightVersion 加 tplDigest(definition+model+name 摘要),
管理员改同一 template_key 的 definition/model 后旧确认失效。补 TestComputePreflightVersion_ChangesOnTemplateEdit。
4. 审计降为附加流:强一致确认记录作为部署门禁;审计 preflight.confirmed 互补。
测试:PreflightConfirmationExists(命中/版本不符/跨用户/过期/不过期/空参)、PreflightBindingKey、
模板变更翻转版本。TestMain + 生产迁移注册 PreflightConfirmation。controller+model 全回归通过。
文档 §4.1.1 更新。
Affects: Manager only(新增 preflight_confirmations 表 + 部署门禁强化)。无计费改动。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 15:28:07 +08:00
chenchen
64ba58357f
Merge remote-tracking branch 'origin/main' into feat/preflight-confirm-audit-version
2026-06-10 15:21:37 +08:00
chenchen and Claude Opus 4.8
df8fa80eba
fix(discovery): address #5 review — no secret inheritance, GCP URL, tagged-only scope
...
回应 Fasthei 复审(PR #52 CHANGES_REQUESTED):
1. 发现出的子资源不再继承账号 secret_ref:抽出 DB 无关的 applyDiscoveredResourceFields,
恒置 SecretRef=""(避免账号级凭据引用经 resourceToResponse / grant manifest 扩散到每个
VM/S3/DB)。加 TestApplyDiscoveredResourceFields_NoSecretInheritance。
3. GCP searchAllResources URL 修正:gcpSearchAllResourcesURL 不再 PathEscape 整个 scope
(slash 是路径模板一部分),生成 /v1/projects/<id>:searchAllResources。加 TestGCPSearchAllResourcesURL。
2. AWS 覆盖范围据实声明:Resource Groups Tagging GetResources 仅覆盖 tagged/曾 tagged 资源,
不覆盖未打标签 EC2/RDS/S3;注释明确「tagged resources only」,#5 全量发现诉求不据此关闭。
controller 全套测试通过,go build/vet 干净。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 14:29:57 +08:00
chenchen
1e28ab1100
Merge remote-tracking branch 'origin/main' into feat/cloud-discovery-aws-gcp
2026-06-10 14:25:00 +08:00
chenchen and Claude Opus 4.8
b9d9eddf7b
fix(swarm): address #45 review — payload redaction, user-scoped events, no fake stop
...
回应 Fasthei 复审(PR #53 CHANGES_REQUESTED):
1. 事件 payload 脱敏:swarmEventView 经 sanitizeSwarmPayload —— 递归剔除
secret_ref/credentials/token/api_key/private_key/access_key/password 及 plan/payload/
permission_manifest/env 大字段,再跑 RedactText 兜底。绝不下发 azkv:// secret_ref 或
sk-/Bearer(approval.requested 等 envelope 携带的凭据引用)。加 TestSanitizeSwarmPayload_*。
2. user 作用域:model.ListSwarmCallbackEventsAfter 增加 userID 参数 + WHERE user_id,
controller 传入当前用户;防 runtime_swarm_id/deployment_id 碰撞或误写导致跨用户事件泄漏。
测试补 user 隔离用例。
3. stop 不伪造成功:移除「开关打开返回 accepted:true」路径;未启用→POLICY_REJECTED,
启用也→NOT_IMPLEMENTED(未转发运行时),直到 agent_swarm#2 冻结接上真实 stop。
文档 §5.2 同步(脱敏 / user 作用域 / stop 语义)。go build/vet 干净,controller+model 全回归通过。
Affects: Manager only(只读查询脱敏 + 写端点安全语义)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 14:23:58 +08:00
chenchen and Claude Opus 4.8
59b13ba824
feat(swarm): HM-side Swarm Run read-only query — Phase1 ( #45 )
...
#45 Phase1 的只读查询(list/status/events?after/artifacts),全部基于 HM 已持久化的
运行时回调数据(Swarm → HM 带签名回调,见 agent_callback.go),**无需实时调 Swarm**,
因此不被 agent_swarm#2 契约冻结阻塞、返工风险低:
- GET /api/heicode/swarms — 列出当前用户的 swarm 运行(AgentDeployment, sub_mode=swarm 或有 runtime_swarm_id)
- GET /api/heicode/swarms/:id — 状态(:id = deployment_id/swarm_id/correlation_id 任一)
- GET /api/heicode/swarms/:id/events?after=&limit= — 事件增量拉取(id 游标 next_after,oldest-first)
新增 model.ListSwarmCallbackEventsAfter(按 deployment_id/swarm_id + id>after)
- GET /api/heicode/swarms/:id/artifacts — 从已存事件(event_type 含 artifact)派生
- POST /api/heicode/swarms/:id/stop — 唯一写操作;在 agent_swarm#2 冻结 + SWARM_RUNTIME_ENABLED=true
前默认关闭并明确提示(不臆造未冻结写接口)
字段口径对齐 agent_swarm/docs/integration/runtime-contract.md(deployment_id↔swarm_id↔
manager_deployment_id;状态机 waiting_approval→running→…)。所有查询按 user 作用域,视图脱敏
(不含 plan/payload 大字段与凭据)。
测试:TestListSwarmCallbackEventsAfter(游标/过滤/空标识);TestMain 迁移 AgentDeployment +
AgentCallbackEvent。go build/vet 干净,controller+model 全套回归通过。文档 §5.2。
Affects: Manager only(新增只读查询端点 + 一个 gated 写端点)。无计费/审计 schema 改动;
不依赖未冻结契约。stop 真实接入随 agent_swarm#2 冻结落地。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 13:24:34 +08:00
chenchen and Claude Opus 4.8
3fb07ad5fb
feat(discovery): provider-agnostic cloud discovery — AWS + GCP adapters ( #5 )
...
#5 三项 DoD 全部落地(纯 Go,无云 SDK,REST + std crypto,非 mock):
- 抽象 provider 接口(DoD #3 ):cloudDiscoveryProvider{ name, discover } + 统一
upsertDiscoveredCloudResources + 跨云一致分类 classifyCloudResourceType(vm/
database/blob/cloud_resource)。新增 dispatcher DiscoverCloudResources 按
account.Provider 路由 azure/aws/gcp。Azure 适配器复用既有 ARM 客户端,三家同抽象。
- AWS adapter(DoD #1 ):纯 Go AWS Signature V4(crypto/hmac+sha256)+ Resource
Groups Tagging API GetResources(分页)→ ARN 归一化。SigV4 实现以 AWS 官方
"get-vanilla" 测试向量验证签名正确(TestAWSSigV4_VanillaVector)。
- GCP adapter(DoD #2 ):服务账号 RS256 JWT 断言 → OAuth2 token → Cloud Asset
Inventory searchAllResources(分页)→ asset 归一化。JWT 以生成密钥 RS256 验签
roundtrip 验证(TestBuildGCPAssertion_RS256Roundtrip)。
路由:新增 POST /api/resources/:id/discover-cloud(按 provider 路由);保留既有
/:id/azure/discover 向后兼容。落库与 Azure 一致(resource_type=cloud_resource,
跨云类别入 metadata.classified_type),幂等 upsert(user+type+provider+external_id)。
测试:分类 / ARN 解析 / SigV4 官方向量 / GCP RS256 roundtrip;controller 全套通过,
go build/vet 干净。
Affects: Manager only(资源发现,新增只读发现端点 + 抽象层)。无计费/审计/部署改动;
凭据经既有 secret store 读取,不落明文。
Closes #5
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 13:07:48 +08:00
chenchen and Claude Opus 4.8
9a073e5b41
feat(preflight): confirm + audit + tamper-proof version check ( #41 )
...
完成 preflight EPIC(#29 )的最后一子项 #41 :
- POST /api/heicode/preflight/confirm:重算摘要 → 仅 ready 时可确认 → 派生防篡改
版本哈希 → 写审计事件 preflight.confirmed(谁/何时/哪个 version)→ 返回 version。
- 防篡改版本 computePreflightVersion:在**稳定安全面**(template + 资源
binding_id/type/provider/name/status/has_secret + 高危 enum + 必需缺失项)上做
sha256,刻意排除易变预算数字/agent_slot,避免版本无意义抖动。
- 部署校验:POST /api/heicode/agents 新增可选 preflight_version。默认仅在带了它时
校验(向后兼容);HEICODE_PREFLIGHT_REQUIRED=true 时强制。确认后资源/模板/高危面
漂移或被篡改 → 版本不匹配 → 部署拒绝。
- 重构:抽出 buildPreflightSummary(GET/confirm/deploy 共用);GET 现也回 version。
测试:版本确定性/稳定性(不随预算变)、资源篡改翻转版本、normalizeBindingIDs。
go build/vet 干净,controller preflight 测试全过。文档 §4.1/§4.1.1 更新。
Affects: Manager only(新增 confirm 端点 + 部署可选校验,默认向后兼容)。
无计费/审计 schema 改动(复用既有 agent_audit_events)。
Closes #41
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 12:55:40 +08:00
chenchen and Claude Opus 4.8
699fa5ef44
docs(swarm): refresh HM-side swarm docs to current agent_swarm state
...
HM 端文档里的蜂群描述还是旧的(错仓名 + 旧模型),据实更新为当前 agent_swarm:
- 仓名:`HeiCode-Swarm` → `agent_swarm`(GitHub xmindlab-heicode/agent_swarm;产品名 HeiCode Swarm)。
- 模型:旧「HM 主导编排 / 仅 /tasks」→ 当前 Master-Agent 编排(分解→派发专家并行→协作/移交→评审/重做→汇总;Orchestrator FastAPI + Redis + WebSocket + Prometheus)。
- 契约:agent_swarm 已起草正式契约 docs/integration/runtime-contract.md(对齐 heicode-am-contract),待 Manager Runtime Team 评审冻结;已实现 create/status/tasks/logs/events/metrics/workflow/diagnostics/stop/approvals(带 deployment_id)。
- issue 引用:`agent_swarm#1`(执行面缺口,已关闭)→ 活动 EPIC `agent_swarm#2`(主链路接入契约冻结);HM 侧前置 #45/#46。
文件:
- docs/integration/heicode-swarm-deferred.md:勘误抬头 + §1 模型/接入状态 + §2 归属表(仓名/契约/接口) + §4 收尾据实更新。
- heicode/docker-compose.azure-vm.yml:SWARM_RUNTIME_* 注释更正(agent_swarm,deferred,当前关闭)。
- Heicode-Manager-生产配置与账号交接清单.md §7 + Orchestrator 地址标签:加勘误 banner,保留 env 历史记录但标注为旧模型/当前关闭。
- docs/deployment/Heicode-Manager-更换部署服务配置清单.md §2.2:加勘误 banner。
HM 不实现 swarm runtime 的裁定不变;仅把"蜂群现状"事实对齐。未改 env 变量名/行为(SWARM_RUNTIME_* 仍 disabled),未动 legacy-teardown 历史记录。Docs/注释 only。
Affects: 文档/注释 only。无代码、无计费/审计/部署行为改动。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 12:15:57 +08:00
Fasthei and GitHub
c39ed6a070
Merge pull request #48 from xmindlab-heicode/feat/agent-preflight-checklist
...
feat(preflight): read-only preflight checklist + execution summary (#39 , #40 )
2026-06-10 12:08:51 +08:00
Fasthei and GitHub
a31745316b
Merge pull request #49 from xmindlab-heicode/feat/agent-usage-budget-remaining
...
feat(usage): expose budget_remaining on agent usage endpoint (#9 )
2026-06-10 12:08:23 +08:00
chenchen and Claude Opus 4.8
46cc7293e2
feat(usage): expose budget_remaining on agent usage endpoint ( #9 )
...
#9 的最后一项 DoD「预算剩余」:GET /api/heicode/agents/:id/usage 新增
budget_remaining = 用户钱包剩余额度(int64;-1 表示读取失败,不阻断用量展示)。
Agent 模型调用经隐藏 token 计费到 user.Quota(#30 ),故"本任务预算剩余"= 用户剩余额度。
与既有 quota/quota_per_unit 同口径。
#9 的①审计脱敏(PR #11 )+②deployment 维度用量(SumAgentUsage/usage 端点)此前已闭环,
本 PR 补齐 budget_remaining。文档 §5.1 随 PR #38 更新(usage 章节在该 PR)。
Affects: Manager only(usage 响应新增只读字段)。无计费/审计 schema 改动。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 11:34:24 +08:00
chenchen and Claude Opus 4.8
4502d6b5bc
feat(preflight): read-only preflight checklist + execution summary ( #39 , #40 )
...
新增 GET /api/heicode/preflight?template_id=&binding_ids=1,2,3 —— agent 启动前的统一
确认层(#29 EPIC 的 #39 缺失项检测 + #40 可读执行摘要):
- #39 缺失项检测:必需资源类别(git/sk/project_document/cloud_account)未绑定、budget
(余额≤0)、agent_slot(在跑数达 tier 上限)。ready = missing 为空。
- #40 可读执行摘要:agent 角色、脱敏资源视图、高危操作、预算(剩余额度/quota_per_unit/
tier 上限/当前在跑数)、审批策略。
- 红线:resources 只暴露 type/provider/name/status/has_secret(布尔),绝不含
secret_ref/channelId/base_url/price。
- 高危操作固定 enum:production_deploy/db_write/cloud_resource_delete/
production_secret/large_budget,由已绑资源类型推导,均 requires_approval。
判定逻辑抽为纯函数 computePreflight,单测覆盖:全缺失、就绪、槽位满、高危 enum、
敏感字段不泄露(序列化断言)。复用既有 ResourceBinding/模板/GetUserMaxAgents/部署门禁
口径,不改部署/计费逻辑。文档补 §4.1。
#41(confirm + 审计 + 防篡改版本校验)作为后续 POST /preflight/confirm 实现。
Affects: Manager only(新增只读端点)。无 Client/Swarm 代码改动,无计费/审计 schema 改动。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 11:29:34 +08:00
chenchen and Claude Opus 4.8
31bf13fc36
test(telemetry): cover retention purge deletion ( #43 )
...
#37 shipped the telemetry retention task + model.DeleteTelemetryEventsBefore but
lacked a test for the deletion itself. Add TestDeleteTelemetryEventsBefore
(strict-< cutoff, retains at/after, idempotent) and migrate TelemetryEvent in the
model TestMain so it has a table.
Closes the "测试覆盖过期清理" DoD item of #43 . Test-only; no behavior change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 10:37:44 +08:00
Fasthei and GitHub
dc75485be8
Merge pull request #37 from xmindlab-heicode/feat/telemetry-retention-and-context-whitelist
...
feat(telemetry): retention purge + context field whitelist + size caps (#32 )
2026-06-10 01:10:24 +08:00
chenchen and Claude Opus 4.8
2e37495133
feat(telemetry): retention purge + context field whitelist + size caps ( #32 )
...
Telemetry up-gating hardening (code portion of #32 ):
- Context field whitelist: telemetry `context` is filtered to a small set of
non-content diagnostic keys (route/retryable/phase/exit_code/duration_ms/
attempt) before persistence. Unknown keys — including potentially identifying
ones (email, full file path, prompt, raw IP) — are dropped, so a client
regression cannot land arbitrary JSON in the store. Empty/unparseable/no-allowed-key
context is dropped to "".
- Per-field size cap: stack_top and context are truncated to 8KiB after
redaction (backstop against unbounded blobs within batch limits).
- Retention: daily master-only task deletes telemetry rows older than
HEICODE_TELEMETRY_RETENTION_DAYS (default 30; <=0 disables).
HEICODE_TELEMETRY_RETENTION_INTERVAL_HOURS (default 24) sets cadence.
model.DeleteTelemetryEventsBefore(cutoff) + controller.StartTelemetryRetentionTask()
wired into main.go under IsMasterNode.
- GET /api/heicode/config telemetry block now surfaces retention_days for
client/admin transparency.
Tests: whitelist drop/keep, size cap, redaction-within-allowed-key. go build/vet
clean; controller telemetry tests pass.
Affects: Manager only (telemetry ingest + retention). No billing/consume-log
change (telemetry still never bills). Privacy-doc disclosure + production
enable-checklist portions of #32 tracked in heicodeDocs sync (#34 ) / desktop
client API docs (#35 ).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 00:40:23 +08:00
chenchen and Claude Opus 4.8
8fe1f5e131
fix(agent,secret): enforce CRYPTO_SECRET for agent deploy ( #31 ) and guard unscoped vault purge ( #33 )
...
#31 : HeicodeDeployAgent now refuses to deploy unless CRYPTO_SECRET is explicitly
configured, so the per-agent access_token is sealed with a key that survives a
container restart. common.CryptoSecret is never literally "" (defaults to
uuid/SessionSecret), so the sealAgentToken plaintext fallback was effectively
unreachable; the real hazard is an ephemeral random seal key making tokens
undecryptable after restart. Dev-only override: HEICODE_ALLOW_PLAINTEXT_AGENT_TOKEN_IN_DEV=true.
Verified prod container has CRYPTO_SECRET set (64 chars) -> deploy stays allowed.
#33 : StartSecretPurgeTask refuses to start a whole-vault purge when
HEICODE_SECRET_PURGE_NAME_PREFIX is empty unless HEICODE_SECRET_PURGE_VAULT_EXCLUSIVE=true,
so HM never permanently purges another tenant's soft-deleted secrets in a shared
vault. Logs the resolved purge scope at startup.
Both gates extracted into pure, unit-tested helpers (agentTokenSealKeyConfigured,
secretPurgeScopeAllowed). Affects: Manager only (Agent deploy + Secret lifecycle).
No Client/Swarm/billing/audit schema change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-10 00:33:47 +08:00
818f1412d5
feat(heicode): 客户端错误遥测上报端点(默认关闭)( #24 ) ( #27 )
...
* feat(heicode): 客户端错误遥测上报端点(默认关闭)(#24 )
按客户端 winos#23 契约 + 权威 schema 实现,结合 HM 入库逻辑:
- POST /api/heicode/telemetry/events,挂 UserOrV2DeviceAuth(设备配对鉴权)。
- 接收顶层 JSON 数组(非包裹),批量 1-20、<=256KB;校验 body client_id 等于已验签
设备(X-Heicode-Device-Id),不一致 403;无设备身份拒绝。
- 真实 4xx/5xx 码(400 非数组、413 超限、403 设备、410 关闭),让客户端"4xx 丢弃"
语义生效;2xx 返回 {accepted:n}。
- 独立表 telemetry_events,与计费完全隔离:不写 consume log、不碰 quota。
- 宽松入库(最大化采集):未知枚举 / 哨兵 app_version(0.0.0-heicode-local)/ 缺字段
原样入库;schema_version 缺省 1;stack_top/context 存 TEXT(JSON);记 user_id 作
device 到 account 关联 + 服务端 received_at。
- 默认 HEICODE_TELEMETRY_ENABLED=false 时返回 410(kill switch);隐私政策更新 +
端点下发形态确认前不开启外发。
测试用客户端仿真夹具:parseTelemetryBatch / toModel 映射与默认 / 拒绝非数组,全过。
Refs #24(上线门槛:隐私政策 §2 如实披露 + 下发形态 + 去重;见工单评论)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* feat(heicode): GET /api/heicode/config 下发 telemetry 配置/kill-switch (#24 )
按客户端 #24 拍板:选独立 config 端点(而非塞登录响应),便于 kill switch 在
会话内传导、不依赖重登录。返回 telemetry 块 {enabled, endpoint, max_batch,
flush_interval_sec};enabled 取 HEICODE_TELEMETRY_ENABLED(默认 false)。
未鉴权全局只读(同 capabilities 姿态)。
测试 heicode_config_test.go:enabled 反映 env、endpoint 与摄入路由一致、缺省 false。
Refs #24
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* fix(telemetry): 服务端二次脱敏 stack_top/context + 明确生产门槛 (#24 review)
按 Fasthei 复审意见补隐私门槛:
- 服务端纵深防御脱敏:新增导出 model.RedactText(包装已上线的 redactAuditSecrets,
#11 ),在 telemetry 入库前对 stack_top / context 再脱敏一遍(sk-/Bearer/URL
token/JSON 密钥字段),即便客户端漏脱敏也不会把明文密钥落库。
- 测试 TestTelemetryToModel_RedactsSecrets:stack_top 里的 sk-、context 里的
Bearer token 被打码,非密钥内容保留。
- 端点默认 HEICODE_TELEMETRY_ENABLED=false,关时 410;隐私政策披露完成前生产
不得开启外发(见 #24 评论记录产品/法务状态)。
go build / vet 干净;controller 测试通过。
Refs #24
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
---------
Co-authored-by: chenchen <chenchen@xinghanlab.com >
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-09 22:16:29 +08:00
Fasthei and GitHub
758e2d0342
Merge pull request #26 from xmindlab-heicode/feat/heicode-available-models
...
feat(heicode): /api/heicode/available-models 客户端模型列表收口 (#25 )
2026-06-09 16:29:35 +08:00
Fasthei and GitHub
3e0c935ad0
Merge pull request #20 from xmindlab-heicode/fix/secret-lifecycle-purge-rotate-cleanup
...
fix(secret): 闭合 #4 secret 生命周期 — 账户停用全量清理 + 30天 purge + 显式轮换
2026-06-09 16:25:51 +08:00
chenchen and Claude Opus 4.8
79e0e8b7d1
feat(heicode): 新增 /api/heicode/available-models,客户端模型列表收口 ( #25 )
...
客户端需要 Manager 下发用户可用模型作唯一来源(里程碑04 收尾)。
- GET /api/heicode/available-models(挂 UserOrV2DeviceAuth,与 /api/heicode/self 同
设备配对鉴权)。
- 服务端解析:user.Group → service.GetUserUsableGroups → model.GetGroupEnabledModels
(与 GetUserModels 同源),去重排序。
- 客户端安全形状 {model_id, display_name, default}:绝不下发 channelId/base_url/
api_key/provider_type/单价(buildAvailableModelItems 纯函数 + 测试断言不泄露)。
- default 标记取 defaultAgentModelID()。
可选字段 capabilities/context_window/cost_tier 暂不下发(HM 无可靠来源,避免臆造;
客户端按可选处理)。etag/updated_at 可作后续。
Fixes #25
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-09 15:51:21 +08:00
7d56b54324
feat(agent): 部署上限按订阅档动态化,闭合 #8 个人5/团队8 ( #21 )
...
沿用订阅体系现成先例 MaxPurchasePerUser,给 SubscriptionPlan 加 MaxAgents:
- model: SubscriptionPlan.MaxAgents(0=回退全局默认)+ GetUserMaxAgents(取用户
active 订阅档最高 MaxAgents,无则回退默认)。
- HeicodeDeployAgent: 部署上限改 model.GetUserMaxAgents(userID, 环境默认5)。
团队8=管理员把团队档配成8;个人5=默认;代码不硬编码 tier。
- subscription 控制器: Create/Update 校验 MaxAgents>=0;Update updateMap 补 max_agents。
- 前端管理端套餐表单(plan-form/types/drawer)加「Agent 部署上限」字段 + zh i18n。
测试 model/subscription_max_agents_test.go 全过(无订阅/团队档/0回退/过期/多档取最高/非法用户)。
go build、go vet、前端 tsc 干净。
Fixes #8
Co-authored-by: chenchen <chenchen@xinghanlab.com >
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-09 14:28:19 +08:00
af094dde27
feat(agent): 按部署 agent 聚合模型用量,闭合 #9 用量聚合 ( #22 )
...
#9 的审计脱敏半部已由 PR#11 完成。据评审报告(L95 usage/billing 结构完整、
L112 监控 mock metrics 属 AM)核实:HM 侧通用用量聚合并不缺,真正缺的是
agent 维度用量视图。
- model.SumAgentUsage(userId, tokenName, start, end):按 agent 铸币 token 名
'agent:<deployment_id>' 聚合 consume 日志(quota/prompt/completion/调用数),
COALESCE+COUNT/SUM 跨 SQLite/MySQL/PG。
- GET /api/heicode/agents/:deployment_id/usage:返回该 agent 用量 + quota_per_unit
(raw,调用方换算,与 /api/heicode/self 同契约),支持 ?start=&end= 时间窗。
- 测试 model/agent_usage_test.go:聚合正确、排除他人/非消费/不同 token、时间窗、空名。
go build/vet 干净;测试 PASS。
Refs #9 (审计脱敏半部 PR#11 已完成;监控 mock metrics 属 AM 侧)
Co-authored-by: chenchen <chenchen@xinghanlab.com >
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-09 14:27:48 +08:00
aa4041f604
fix(web): 钱包余额直读 /api/user/self(去 502) + 部署完成提示/动画 ( #23 )
...
两处 HM web 前端修复(此前已热部署到 VM 验证):
1. 钱包 502:wallet 不再经 /api/heicode-auth → mcp-server 读余额(那条会触发
HM GetUser 同级权限检查 → 502)。HM 本就是 new-api,直接读用户自己的
/api/user/self(GetSelf,无角色检查)。
2. 异步部署无反馈:deploy-agent-page 加快轮询(启动中 3s/稳定 30s)+ 检测
Pending→running 弹「✅ 部署完成,已就绪」(失败弹错误)+「启动中」徽章转圈脉冲。
tsc 干净。
Co-authored-by: chenchen <chenchen@xinghanlab.com >
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-09 14:27:19 +08:00
chenchen and Claude Opus 4.8
57f475b15a
fix(secret): 闭合 #4 secret 生命周期 — 账户停用全量清理 + 30天 purge + 显式轮换
...
承接 PR#13(撤销时删 KV secret)的剩余生命周期:
- 账户停用/删除全量清理:新增 revokeUserResourceSecrets(userID),撤销该用户全部
带 secret_ref 的资源绑定并 best-effort 软删 KV 凭证材料(DB 标 revoked 为权威,
KV 故障只记日志不阻塞)。接入 4 个账户路径:ManageUser disable/delete、
DeleteUser(管理员硬删)、DeleteSelf(自助删)。
- 30天 purge:新增 listDeletedSecrets(GET /deletedsecrets 分页)+ secretExpired
纯函数 + purgeExpiredVaultSecrets;StartSecretPurgeTask 每日(可配)purge 软删
≥30天(可配)的 secret,master 节点执行,KV 未配置则 no-op,purge-protection
下安全 no-op(403 容错)。env:HEICODE_SECRET_PURGE_ENABLED/RETENTION_DAYS/
INTERVAL_HOURS/NAME_PREFIX。
- 轮换显式化:UpsertResourceSecret 已有 secret 时改用 rotateSecret(同名新版本)
并审计日志,而非每次 putSecret。
测试:parseDeletedSecretsPage / secretExpired / lastPathSegment 纯函数 +
revokeUserResourceSecrets 在 KV 未配置下仍正确标记 revoked、不误伤他人/无密钥绑定。
Refs #2 (secret_store delete/rotate/purge 部分;Manager↔Swarm 契约属 Swarm 侧)
Fixes #4
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-09 00:55:09 +08:00
Fasthei and GitHub
03b9b24e45
Merge pull request #18 from xmindlab-heicode/fix/async-agent-deploy
...
fix(agent): 部署 agent 改异步,避免 Azure 网关 504 + 回滚
2026-06-08 18:08:17 +08:00
Fasthei and GitHub
206fee1f78
Merge pull request #14 from xmindlab-heicode/feat/heicode-self-quota-display-type
...
feat(heicode-self): /api/heicode/self 返回 raw quota + quota_per_unit(与网页台同源换算)
2026-06-08 17:52:46 +08:00
zsbgnw12 and GitHub
9444cdb498
fix agent deploy caps
...
approved
2026-06-08 17:49:35 +08:00
chenchen and Claude Opus 4.8
349957360d
fix(heicode-self): quota_display_type 补 CUSTOM + 统一大写 + 加 displayQuota 测试
...
按 Mem0ried 复审:
- quotaDisplayUnitLabel 补 QuotaDisplayTypeCustom 分支(原落 default→"USD",
导致自定义币种站点 display_quota 算对但 type 误报 USD、客户端配错符号)。
- tokens 标签由小写 "tokens" 改为规范常量 TOKENS,displayQuota 的判断同步用常量,
对外 quota_display_type 统一大写(与 USD/CNY/CUSTOM 一致,客户端按常量比较不再 mismatch)。
- 新增表驱动测试 heicode_self_test.go:displayQuota 四模式(USD 除 / CNY·CUSTOM 乘 /
TOKENS 原值)+ per_unit<=0 防除零;quotaDisplayUnitLabel 四模式(含 CUSTOM 回归)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-08 17:34:03 +08:00
chenchen and Claude Opus 4.8
f6da9c541e
fix(agent): 异步回填加 Pending 状态守卫,避免覆盖用户 stop/delete
...
按 Fasthei 复审意见修并发状态机边界:
- 成功/失败回填都加 WHERE deployment_id=? AND LOWER(status)='pending',
让 Pending->running / Pending->failed 成为 own-or-nothing 转换。
- 成功但 0 行(用户在 AM 启动窗口内 stop/delete/cancel):重读记录记日志,
删除 AM 刚起的 orphan runtime,绝不把记录改回 running。
- 失败仅在我方拥有 Pending->failed 转换时才 revoke model token;用户已 stop/delete
时交给对应路径(delete 已 revoke、stop 有意保留 key),避免重复/遗漏。
- 补竞态测试 StoppedDuringStart_NoResurrect:AM 启动被 hold 到记录置 stopped 后才返回,
断言记录保持 stopped、不回填 runtime_id、orphan runtime 被删除。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-08 17:17:40 +08:00