be93feb063
MUL-6792: perf(server): batch skill-file loads in LoadAgentSkills ( #7689 )
...
* perf(server): batch skill-file loads in LoadAgentSkills
LoadAgentSkills issued one ListSkillFiles query per skill inside a loop,
so an agent with N skills cost N+1 round trips on the task-claim hot
path (three callers in daemon.go). Each query also pulls full file
bodies, so the fixed per-query overhead (pool acquire, RTT, parse) was
paid N times.
Add ListSkillFilesBySkillIDs (skill_id = ANY(...), ordered by skill_id,
path — backed by idx_skill_file_skill) and load all files in one query,
grouping by skill_id in a single linear pass. N+1 becomes 2. Output
order is preserved by assembling in ListAgentSkills order. Total bytes
transferred are unchanged; this removes round trips and pool acquires,
not payload. The per-skill ListSkillFiles is retained for the single-
skill handler callers that legitimately need it.
Co-Authored-By: Claude Fable 5 <[email protected] >
* fix(server): fail closed when the agent skill read fails
Batching the per-skill ListSkillFiles loop into one query changed what a
swallowed read error means. Before, one failed query dropped one skill's
supporting files. Now a single failure drops the files of EVERY skill --
and the `files, _ :=` discard let claim and resolve carry on as if that
were the agent's real skill set.
Nothing downstream can catch it. BuildAgentSkillBundles hashes whatever
loaded, so the refs sent at claim and the bundle served at resolve agree
with each other; the daemon's validateSkillBundle compares a bundle
against a ref derived from that same bundle, accepts it, and writes it to
the on-disk cache. The agent then starts on skills whose rules are
missing, and the next dispatch reuses the cached truncated copy. The same
was true of the ListAgentSkills error above it, which could silently
strip every workspace skill from an agent.
LoadAgentSkills and LoadAgentSkillBundles now return the error, and the
three call sites settle it:
- claim (both the slim skill-refs path and the legacy inline-skills
path) refuses with 500 via rejectClaimSkillLoad and leaves the task
dispatched, so the stale-dispatched reclaim redelivers it -- the same
treatment rejectClaimSourceLoad gives a transient source read.
- ResolveTaskSkillBundles returns 500, which the daemon's existing
resolve retry schedule already treats as transient, instead of serving
a bundle built from a failed read.
Tests: service-level coverage for both read failures, for
LoadAgentSkillBundles failing closed rather than returning built-ins
only, and for the batch grouping itself -- the fixture puts the two
result sets in deliberately different orders (skills by name, files by
skill_id) so a positional zip would hand each skill another skill's
files, and asserts the per-skill query is no longer issued. Handler-level
coverage asserts the 500s and that a refused claim leaves the task
dispatched and unstarted.
Co-Authored-By: J <[email protected] >
Co-authored-by: multica-agent <[email protected] >
---------
Co-authored-by: Claude Fable 5 <[email protected] >
Co-authored-by: J <[email protected] >
Co-authored-by: multica-agent <[email protected] >
2026-08-31 14:52:00 +08:00
..
2026-08-19 14:06:59 +08:00
2026-08-19 14:06:59 +08:00
2026-08-18 03:00:21 +08:00
2026-08-13 15:34:17 +08:00
2026-07-15 03:09:56 +08:00
2026-07-15 03:09:56 +08:00
2026-08-14 18:56:40 +08:00
2026-08-19 16:33:48 +08:00
2026-08-26 15:55:26 +08:00
2026-07-29 15:39:18 +08:00
2026-08-25 18:28:01 +08:00
2026-08-26 19:01:01 +08:00
2026-07-03 14:18:43 +08:00
2026-08-12 16:09:16 +08:00
2026-08-26 19:01:01 +08:00
2026-07-29 14:01:09 +08:00
2026-08-20 13:42:44 +08:00
2026-07-03 14:18:43 +08:00
2026-08-18 03:00:21 +08:00
2026-06-13 15:33:28 +08:00
2026-08-03 12:39:27 +08:00
2026-07-22 15:38:38 +08:00
2026-07-29 15:39:18 +08:00
2026-07-29 14:28:44 +08:00
2026-08-13 16:42:47 +08:00
2026-07-29 12:47:14 +08:00
2026-08-26 16:34:10 +08:00
2026-08-26 19:01:01 +08:00
2026-08-19 16:33:48 +08:00
2026-08-12 15:02:03 +08:00
2026-08-12 15:02:03 +08:00
2026-07-29 18:25:14 +08:00
2026-07-15 03:09:56 +08:00
2026-04-21 14:42:52 +08:00
2026-08-16 15:46:00 +08:00
2026-07-15 03:09:56 +08:00
2026-07-17 16:44:31 +08:00
2026-07-17 16:44:31 +08:00
2026-08-26 01:28:35 +08:00
2026-08-21 14:12:36 +08:00
2026-06-30 12:29:11 +08:00
2026-07-15 03:09:56 +08:00
2026-08-19 15:51:26 +08:00
2026-08-24 18:49:54 +08:00
2026-08-20 16:48:03 +08:00
2026-07-15 03:09:56 +08:00
2026-08-18 03:00:21 +08:00
2026-08-18 03:00:21 +08:00
2026-08-20 13:42:44 +08:00
2026-08-27 14:23:09 +08:00
2026-07-29 15:39:18 +08:00
2026-07-29 15:39:18 +08:00
2026-08-19 03:09:59 +08:00
2026-08-25 18:28:01 +08:00
2026-08-25 18:28:01 +08:00
2026-08-25 18:28:01 +08:00
2026-08-20 01:30:58 +08:00
2026-08-25 18:28:01 +08:00
2026-08-25 18:28:01 +08:00
2026-08-11 13:46:48 +08:00
2026-07-15 00:52:27 +08:00
2026-08-03 12:39:27 +08:00
2026-08-22 11:27:39 +08:00
2026-08-22 11:27:39 +08:00
2026-08-25 18:28:01 +08:00
2026-08-05 15:06:42 +08:00
2026-07-08 21:58:16 +08:00
2026-08-25 18:28:01 +08:00
2026-08-05 15:06:42 +08:00
2026-08-25 18:28:01 +08:00
2026-08-25 18:28:01 +08:00
2026-08-21 13:56:18 +08:00
2026-08-28 12:49:08 +08:00
2026-08-22 11:18:02 +08:00
2026-07-22 16:52:34 +08:00
2026-07-22 16:52:34 +08:00
2026-08-27 14:23:09 +08:00
2026-08-27 14:23:09 +08:00
2026-05-27 14:52:03 +08:00
2026-05-27 14:52:03 +08:00
2026-07-31 14:40:16 +08:00
2026-07-14 19:56:17 +08:00
2026-07-15 03:09:56 +08:00
2026-08-18 03:00:21 +08:00
2026-06-24 09:52:18 +08:00
2026-07-31 14:40:16 +08:00
2026-07-27 14:26:23 +08:00
2026-08-19 03:09:59 +08:00
2026-08-03 13:35:04 +08:00
2026-07-10 16:15:10 +08:00
2026-08-18 03:00:21 +08:00
2026-08-19 16:08:40 +08:00
2026-07-15 03:09:56 +08:00
2026-08-19 16:08:40 +08:00
2026-08-21 14:12:36 +08:00
2026-08-26 19:01:01 +08:00
2026-08-26 19:01:01 +08:00
2026-08-18 03:00:21 +08:00
2026-06-03 16:39:06 +08:00
2026-08-21 14:12:36 +08:00
2026-07-14 11:53:42 +08:00
2026-08-16 04:54:32 +08:00
2026-07-27 15:44:39 +08:00
2026-08-19 12:40:04 +08:00
2026-08-20 01:30:58 +08:00
2026-08-25 18:28:01 +08:00
2026-07-27 13:12:06 +08:00
2026-08-21 17:40:27 +08:00
2026-08-14 19:49:37 +08:00
2026-08-19 16:08:40 +08:00
2026-07-10 13:43:45 +08:00
2026-08-05 15:41:15 +08:00
2026-07-14 11:53:42 +08:00
2026-07-14 11:53:42 +08:00
2026-08-26 15:55:05 +08:00
2026-08-31 14:52:00 +08:00
2026-08-26 16:34:10 +08:00
2026-07-14 11:56:30 +08:00
2026-07-14 11:56:30 +08:00
2026-08-31 14:52:00 +08:00
2026-07-29 13:08:48 +08:00
2026-08-19 03:09:59 +08:00
2026-08-06 20:59:32 +08:00
2026-08-18 15:36:10 +08:00
2026-08-21 14:26:48 +08:00
2026-08-21 14:26:48 +08:00
2026-08-20 18:12:30 +08:00
2026-08-24 19:02:47 +08:00
2026-08-12 11:55:53 +08:00
2026-08-12 11:55:53 +08:00
2026-08-27 16:55:03 +08:00
2026-08-25 12:00:49 +08:00
2026-08-21 15:36:33 +08:00
2026-08-21 15:36:33 +08:00
2026-08-19 03:09:59 +08:00
2026-07-07 14:43:19 +08:00
2026-08-27 14:23:09 +08:00
2026-05-07 15:50:27 +08:00
2026-05-07 15:50:27 +08:00
2026-05-06 14:31:33 +08:00
2026-08-24 16:27:42 +08:00
2026-08-27 14:23:09 +08:00
2026-07-13 16:42:46 +08:00
2026-07-03 16:10:19 +08:00
2026-08-26 12:42:42 +08:00
2026-08-26 12:42:42 +08:00
2026-08-26 12:42:42 +08:00
2026-08-18 03:00:21 +08:00
2026-07-15 03:09:56 +08:00
2026-07-02 14:11:10 +08:00
2026-08-25 18:44:39 +08:00
2026-08-26 15:55:26 +08:00
2026-07-10 09:11:29 +08:00
2026-07-13 16:15:58 +08:00
2026-08-07 15:35:59 +08:00
2026-08-18 02:38:18 +08:00
2026-08-20 01:30:58 +08:00
2026-08-20 13:42:44 +08:00
2026-07-22 22:43:34 +08:00
2026-08-19 14:06:59 +08:00
2026-07-16 13:31:06 +08:00
2026-05-28 14:20:20 +08:00
2026-07-13 13:08:04 +08:00
2026-05-19 10:37:38 +08:00
2026-08-19 16:08:40 +08:00
2026-06-02 17:17:41 +08:00
2026-08-27 14:23:09 +08:00
2026-05-21 16:35:45 +08:00
2026-08-19 14:06:59 +08:00
2026-07-23 15:58:25 +08:00
2026-08-19 14:06:59 +08:00
2026-08-19 16:08:40 +08:00
2026-08-19 14:06:59 +08:00
2026-07-06 19:11:47 +08:00
2026-08-19 16:08:40 +08:00
2026-07-13 13:08:04 +08:00
2026-08-19 16:08:40 +08:00
2026-08-23 12:36:10 +08:00
2026-08-18 18:52:11 +08:00
2026-08-28 14:24:32 +08:00
2026-08-28 14:24:32 +08:00
2026-08-28 15:56:34 +08:00
2026-07-17 19:21:27 +08:00
2026-08-18 18:52:11 +08:00
2026-08-19 16:08:40 +08:00
2026-08-27 14:23:09 +08:00
2026-08-27 14:23:09 +08:00
2026-08-20 23:53:49 +08:00
2026-07-31 13:04:42 +08:00
2026-08-20 16:03:51 +08:00
2026-08-04 17:53:03 +08:00
2026-08-14 13:57:09 +08:00
2026-08-11 14:43:45 +08:00
2026-06-16 12:26:44 +08:00
2026-08-10 11:55:05 +08:00
2026-08-10 11:55:05 +08:00
2026-08-18 03:00:21 +08:00
2026-08-10 11:55:05 +08:00
2026-08-28 14:24:32 +08:00
2026-07-31 14:41:05 +08:00
2026-08-19 14:06:59 +08:00
2026-07-08 16:19:41 +08:00
2026-07-08 16:19:41 +08:00
2026-07-03 14:18:43 +08:00
2026-08-03 17:43:03 +08:00
2026-07-15 03:09:56 +08:00
2026-08-06 14:21:02 +08:00
2026-08-25 18:28:01 +08:00
2026-08-07 18:48:07 +08:00
2026-08-07 18:48:07 +08:00
2026-08-07 18:48:07 +08:00
2026-08-07 18:48:07 +08:00
2026-08-07 18:48:07 +08:00
2026-08-25 18:28:01 +08:00
2026-08-06 14:17:19 +08:00
2026-08-06 14:17:19 +08:00
2026-08-27 14:23:09 +08:00
2026-07-23 01:57:44 +08:00
2026-08-06 14:21:02 +08:00
2026-05-21 15:33:47 +08:00
2026-05-27 22:22:26 +08:00
2026-05-27 22:22:26 +08:00
2026-08-10 11:55:05 +08:00
2026-08-23 22:47:37 +08:00
2026-08-27 14:23:09 +08:00
2026-08-20 02:35:29 +08:00
2026-08-23 22:47:37 +08:00
2026-08-23 17:15:46 +08:00
2026-08-23 22:47:37 +08:00
2026-08-23 22:47:37 +08:00
2026-08-21 16:03:44 +08:00
2026-08-20 02:35:29 +08:00
2026-08-21 16:03:44 +08:00
2026-08-23 13:47:06 +08:00
2026-08-23 13:47:06 +08:00
2026-08-21 16:03:44 +08:00
2026-08-23 13:47:06 +08:00
2026-08-23 13:47:06 +08:00
2026-08-23 17:37:21 +08:00
2026-08-23 17:37:21 +08:00
2026-07-13 13:22:02 +08:00
2026-08-18 18:49:01 +08:00
2026-08-22 11:18:02 +08:00
2026-06-21 23:54:58 +08:00
2026-08-18 18:49:01 +08:00
2026-08-28 15:56:34 +08:00
2026-08-28 15:56:34 +08:00
2026-07-30 21:01:48 +08:00
2026-07-30 21:01:48 +08:00
2026-08-20 13:42:44 +08:00
2026-08-27 16:55:03 +08:00
2026-08-19 14:06:59 +08:00
2026-08-06 15:36:02 +08:00
2026-08-11 02:23:11 +08:00
2026-07-02 18:31:45 +08:00
2026-07-08 16:00:17 +08:00
2026-05-06 14:31:33 +08:00
2026-05-06 14:31:33 +08:00
2026-06-11 13:00:56 +08:00
2026-08-19 14:37:08 +08:00
2026-08-19 14:37:08 +08:00
2026-08-26 01:48:44 +08:00
2026-08-26 01:48:44 +08:00
2026-07-30 20:34:01 +08:00
2026-07-29 16:03:26 +08:00
2026-07-30 20:34:01 +08:00
2026-07-30 20:34:01 +08:00
2026-07-30 20:34:01 +08:00
2026-08-19 14:37:08 +08:00
2026-08-19 14:37:08 +08:00
2026-05-03 11:13:34 +08:00
2026-08-26 01:48:44 +08:00
2026-08-28 12:49:08 +08:00
2026-08-28 12:49:08 +08:00
2026-07-02 14:38:05 +08:00
2026-08-03 12:39:27 +08:00
2026-08-28 12:49:08 +08:00
2026-08-28 12:49:08 +08:00
2026-08-03 12:39:27 +08:00
2026-08-20 13:42:44 +08:00
2026-08-26 01:48:44 +08:00
2026-08-03 13:35:04 +08:00
2026-08-19 14:37:08 +08:00
2026-08-19 14:37:08 +08:00
2026-07-16 13:54:01 +08:00
2026-08-26 01:48:44 +08:00
2026-08-26 01:48:44 +08:00
2026-08-28 12:49:08 +08:00
2026-08-07 12:33:47 +08:00
2026-08-27 14:23:09 +08:00
2026-07-06 12:34:51 +08:00
2026-08-22 11:18:59 +08:00
2026-08-25 17:19:46 +08:00
2026-08-26 12:42:42 +08:00
2026-08-26 12:42:42 +08:00
2026-08-25 12:51:44 +08:00
2026-08-13 13:48:18 +08:00
2026-06-30 14:46:46 +08:00
2026-06-30 14:46:46 +08:00
2026-06-11 13:00:56 +08:00
2026-07-22 15:38:38 +08:00
2026-08-26 15:45:06 +08:00
2026-08-13 13:48:18 +08:00
2026-08-13 13:48:18 +08:00
2026-06-01 15:19:42 +08:00
2026-07-22 14:38:31 +08:00
2026-08-26 15:45:06 +08:00
2026-06-29 14:09:34 +08:00
2026-07-09 15:07:11 +08:00
2026-08-25 12:00:49 +08:00
2026-08-27 16:55:03 +08:00
2026-08-25 12:00:49 +08:00
2026-08-27 16:55:03 +08:00
2026-05-13 18:46:20 +08:00
2026-08-06 21:05:21 +08:00
2026-08-24 14:38:07 +08:00
2026-08-24 14:38:07 +08:00
2026-07-15 03:09:56 +08:00
2026-07-08 14:51:54 +08:00
2026-08-24 14:38:07 +08:00
2026-07-03 14:18:43 +08:00
2026-08-07 12:40:12 +08:00
2026-08-24 14:38:07 +08:00
2026-08-20 11:32:17 +08:00
2026-08-19 16:33:48 +08:00
2026-07-15 03:09:56 +08:00
2026-08-24 14:38:07 +08:00
2026-07-31 16:52:17 +08:00
2026-07-31 16:52:17 +08:00
2026-05-11 12:39:45 +08:00
2026-07-31 16:52:17 +08:00
2026-08-27 16:55:03 +08:00
2026-08-21 15:17:02 +08:00
2026-08-20 01:30:58 +08:00
2026-07-14 13:16:50 +08:00
2026-08-05 19:14:33 +08:00
2026-08-19 23:04:26 +08:00
2026-08-19 23:04:26 +08:00
2026-07-31 14:40:16 +08:00
2026-07-16 15:23:56 +08:00
2026-06-02 14:29:29 +08:00
2026-05-21 15:33:47 +08:00
2026-08-20 13:42:44 +08:00
2026-07-24 16:39:22 +08:00
2026-07-24 16:39:22 +08:00
2026-08-17 18:32:02 +08:00
2026-07-24 16:39:22 +08:00
2026-08-19 15:51:26 +08:00
2026-08-19 15:51:26 +08:00
2026-08-20 13:42:44 +08:00
2026-08-17 12:51:39 +08:00
2026-08-17 12:51:39 +08:00
2026-08-08 19:20:38 +08:00
2026-08-08 02:01:43 +08:00
2026-08-08 19:20:38 +08:00
2026-08-12 14:09:48 +08:00
2026-08-11 02:23:11 +08:00
2026-08-25 18:28:01 +08:00
2026-08-12 14:09:48 +08:00
2026-08-14 19:49:37 +08:00
2026-08-14 19:49:37 +08:00
2026-08-14 19:49:37 +08:00
2026-08-14 19:49:37 +08:00
2026-08-14 19:49:37 +08:00
2026-05-08 19:14:12 +08:00
2026-08-25 17:19:46 +08:00
2026-08-25 12:00:49 +08:00
2026-08-25 17:19:46 +08:00
2026-08-20 01:30:58 +08:00