Skip to content

feat(agentresource): 支持新版 agent 资源分发#653

Open
twursc wants to merge 11 commits into
mainfrom
feat-custom-agents-2
Open

feat(agentresource): 支持新版 agent 资源分发#653
twursc wants to merge 11 commits into
mainfrom
feat-custom-agents-2

Conversation

@twursc
Copy link
Copy Markdown
Collaborator

@twursc twursc commented Jun 7, 2026

支持向前端展示管理员在后台配置的 Skill 和 插件,并通过 S3 Presigned URL 向 Agent 按需分发,去除对原来手动维护的模板仓库的依赖。

xmv97 added 11 commits June 7, 2026 09:19
Mirror the 9 agent_* tables from mcai-backend as read-only ent schemas
on the mcai-gh/backend side (shared Postgres consumer). Skill/plugin
version tables keep s3_key; rule_versions intentionally omits s3_key /
s3_synced_at (rule content is DB-authoritative, no S3 mirror).

- ent/schema: agent_rule(+version), agent_skill_repo, agent_plugin_repo,
  agent_skill(+version), agent_plugin(+version), agent_sync_job
- ent/types/agent_resources.go: SkillParsedMeta, PluginParsedMeta,
  PluginManualEntries, SyncJobErrors, SyncJobResultSummary jsonb GoTypes
- migration/000011_agent_resources.{up,down}.sql: full schema with
  CHECK constraints + reverse FKs (rule_versions has no s3 columns)
Mirror the mcai-backend agentresource package onto the gh backend so the
task dispatch path and the public skill/plugin pickers can read shared
agent resources without depending on admin BFF mutations.

- repo: two-step queries over agent_rule/skill/plugin + their active
  version rows. Rules read content straight from DB; skills/plugins
  surface s3_key + parsed_meta for downstream materialization.
- resolver: pulls each skill/plugin zip via a minimal ObjectStore
  interface (pkg/oss.Client satisfies it implicitly) and unzips in
  memory with zip-bomb / zip-slip guards. Per-asset fetch/unzip errors
  are logged and skipped so one bad asset can't break dispatch.
- tests: sqlite-backed ent tests for the repo (union, orphan, deleted,
  no-active-version) plus fake-driven resolver tests covering rules,
  unzip safety, and user/force union forwarding.
…/api/v1/skills + /api/v1/plugins

- task usecase: getCodingConfigs 改签名为 (ctx, cli, m, skillIDs, pluginIDs),
  接入 agentresource.ResolverInterface,按 spec §6.3 注入 rule(三 CLI)/ skill
  (三 CLI、resolver 并集 force_delivery)/ plugin(仅 OpenCode、注入 opencode.json
  plugin 数组);resolver==nil 时 nil-safe 跳过供单元测试
- 删除老 /app/skills 文件系统 walk + consts.SkillBaseDir 常量
- 新增 /api/v1/skills(biz/skill)和 /api/v1/plugins(biz/plugin)handler,
  从 agentresource.Repo.ListSkillsForListing / ListPluginsForListing 读 DB
- 新增 domain.SkillListItem / PluginListItem DTO
- biz/agentresource/register.go 落 DI(Repo / *oss.Client / ResolverInterface),
  ObjectStorage 关闭时降级到 noopObjectStore;object_storage 未启用时
  回退到 aliyun.public_oss 配置块
- biz/register.go 接线 agentresource / skill / plugin Provide+Invoke
- task handler: 非 uuid 的 skill/plugin id 记日志后跳过,不再整任务 reject
- 单元测试适配新签名(ctx + pluginIDs),resolver nil-safe 路径无需 fake
…roto

Skill/plugin zips were being downloaded server-side, unzipped in memory, then
re-shipped as per-file ConfigFile entries through the taskflow gRPC PushTasks
call. With ~64 files in scope this blew past the 4MiB gRPC message limit.

Switch the dispatch path to hand the codingmatrix agent presigned GET URLs
instead — the agent already had DownloadAndExtractAssets wired up for
AgentResources.AssetRef, the publisher side was just unhooked since the
slim port.

Changes:
- pkg/oss.PresignGet: new helper that presigns a GET URL against a full S3
  key (existing Presign uses prefix+filename for uploads)
- biz/agentresource: SkillRef / PluginRef types + Resolver.SkillRefs /
  Resolver.PluginRefs that call ObjectStore.PresignGet; resolved log
  includes zip_url for diagnosability
- biz/task/usecase: forward AgentResources.{Skills,Plugins} on
  TaskExecutionConfig instead of inlining ConfigFile bytes
- single-line JSON dump of ConfigFile slice kept for debug visibility
AWS-SDK-v2's SigV4 signer is incompatible with Aliyun OSS:
  - SignatureDoesNotMatch (OSS uses its own OSS4-HMAC-SHA256 / V1 sigs)
  - With ForcePathStyle and a virtual-host endpoint (oss.foo.com style),
    the bucket gets prefixed in the path → bucket.oss.foo.com/bucket/key
    instead of bucket.oss.foo.com/key

Adds pkg/oss.AliyunClient backed by aliyun-oss-go-sdk that implements just
GetObject + PresignGet (enough for agentresource.Resolver). The existing
*pkg/oss.Client stays untouched — avatar / repo / spec / temp uploads keep
going through the AWS SDK path when object_storage is enabled.

agentresource/register.go now picks the client by config block:
  - object_storage.enabled = true → existing AWS-SDK client
  - aliyun.public_oss.bucket set  → new aliyun-oss-go-sdk client
  - neither                       → noopObjectStore (skip-and-log)
Mixed commit: regenerated swagger.json alongside unrelated small edits in
adjacent packages (team_dashboard / asr / clickhouse / speech / doubao /
config). Preserved as-is because splitting would require touching the
generated swagger blob.
Mixed commit: regenerated swagger.json alongside unrelated small edits in
adjacent packages (team_dashboard / asr / clickhouse / speech / doubao /
config). Preserved as-is because splitting would require touching the
generated swagger blob.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant