mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 11:13:43 +08:00
refactor(agent): tighten template pre-binding contract and prune product-assistant skills
This commit is contained in:
parent
201e510b17
commit
b74176ef66
@ -147,16 +147,16 @@ public class TemplateService {
|
||||
|
||||
// 4. Pre-bind skills the template declares so a hired agent is
|
||||
// usable out of the box ("数据分析师" already knows SQL, "代码审查员"
|
||||
// already has the test-driven-development playbook). Slugs are
|
||||
// resolved against the target workspace; missing skills are skipped
|
||||
// with a warning so a partially-installed environment can still
|
||||
// complete the hire.
|
||||
applyDefaultSkillBindings(template, created, workspaceId);
|
||||
// already has the test-driven-development playbook). Resolution
|
||||
// failures (slug missing in this workspace) are skipped with a
|
||||
// warning; bind-service exceptions still propagate and roll back
|
||||
// the @Transactional hire — see helper Javadoc.
|
||||
applyDefaultSkillBindings(template, created);
|
||||
|
||||
// 5. Pre-bind any standalone tools the template wants. Filtered
|
||||
// against the picker so a deprecated / unavailable tool name in the
|
||||
// template doesn't abort the hire — same forgiving stance as
|
||||
// skills above.
|
||||
// 5. Pre-bind any standalone tools the template wants. Picker
|
||||
// outage and unknown names are dropped with a warning; a
|
||||
// setToolBindings exception still propagates (same contract as
|
||||
// skills) — see helper Javadoc.
|
||||
applyDefaultToolBindings(template, created);
|
||||
|
||||
return created;
|
||||
@ -164,15 +164,39 @@ public class TemplateService {
|
||||
|
||||
/**
|
||||
* Resolve {@link TemplateDTO#getDefaultSkillSlugs()} to skill ids inside
|
||||
* {@code workspaceId} and pre-bind them on the freshly-created agent.
|
||||
* Slugs whose row is missing in the workspace are logged and dropped — a
|
||||
* template MUST be safe to apply even when some bundled skills haven't
|
||||
* landed yet (offline upgrade, partial seed, custom workspace).
|
||||
* the agent's own workspace and pre-bind them.
|
||||
*
|
||||
* <p><b>Failure contract — read carefully.</b>
|
||||
* <ul>
|
||||
* <li><b>Resolution failures</b> (slug not present in the agent's
|
||||
* workspace, blank entries) → logged and dropped. A template MUST
|
||||
* stay applyable on an offline upgrade or partial-seed install
|
||||
* where some bundled skills haven't landed yet.</li>
|
||||
* <li><b>Service-layer failures</b>
|
||||
* ({@link AgentBindingService#setSkillBindings} throws — e.g. a
|
||||
* race deletes the skill row between resolve and bind, or the
|
||||
* workspace check rejects it) → <em>propagate</em>. Because
|
||||
* {@link #applyTemplate} runs under {@code @Transactional}, this
|
||||
* rolls back the whole hire. That's deliberate: such a throw is
|
||||
* a real wiring/race problem, and pretending the hire succeeded
|
||||
* would leave the user with a half-configured agent.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>Reads the workspace off the just-persisted {@link AgentEntity}
|
||||
* rather than a separate parameter so the lookup and the validator
|
||||
* inside {@code AgentBindingService.requireSameWorkspace} can never
|
||||
* disagree on which workspace they're talking about.
|
||||
*/
|
||||
private void applyDefaultSkillBindings(TemplateDTO template, AgentEntity created, Long workspaceId) {
|
||||
private void applyDefaultSkillBindings(TemplateDTO template, AgentEntity created) {
|
||||
List<String> slugs = template.getDefaultSkillSlugs();
|
||||
if (slugs == null || slugs.isEmpty()) return;
|
||||
|
||||
// Mirror the fallback inside AgentBindingService.requireSameWorkspace:
|
||||
// a null workspace_id on a row is treated as workspace 1, so the
|
||||
// lookup needs to agree or we'd silently turn `eq(workspaceId, null)`
|
||||
// into `IS NULL` and match nothing.
|
||||
Long workspaceId = created.getWorkspaceId() == null ? 1L : created.getWorkspaceId();
|
||||
|
||||
List<Long> resolvedIds = new ArrayList<>();
|
||||
for (String slug : slugs) {
|
||||
if (slug == null || slug.isBlank()) continue;
|
||||
@ -198,6 +222,11 @@ public class TemplateService {
|
||||
* {@link AgentBindingService#setToolBindings} sees only resolvable names
|
||||
* — its own validation would otherwise abort the call on the first
|
||||
* unknown name and leave the agent with no tool bindings at all.
|
||||
*
|
||||
* <p>Failure contract mirrors {@link #applyDefaultSkillBindings}:
|
||||
* picker outage and unknown names are dropped with a warning; an
|
||||
* exception from {@code setToolBindings} itself still propagates and
|
||||
* rolls back the hire.
|
||||
*/
|
||||
private void applyDefaultToolBindings(TemplateDTO template, AgentEntity created) {
|
||||
List<String> names = template.getDefaultToolNames();
|
||||
|
||||
@ -10,8 +10,7 @@
|
||||
"maxIterations": 12,
|
||||
"defaultSkillSlugs": [
|
||||
"ideation",
|
||||
"make_plan",
|
||||
"writing-plans"
|
||||
"make_plan"
|
||||
],
|
||||
"systemPrompt": "## Role\n产品助理\n\n## Goal\n把模糊需求理成可执行的 PRD\n\n## Backstory\n你做产品做久了,知道一句话需求背后通常藏着三个不一样的问题。所以你拿到任何描述,先把它翻译成\"用户是谁 + 他在什么场景下 + 他想达成什么 + 现在的痛点是什么\"。你写 PRD 不堆功能列表,会先讲清楚\"不做什么\"和\"成功长什么样\"。\n\n## Additional Instructions\n输出结构:1) 用户与场景;2) 目标与反目标(不做什么);3) 核心流程;4) 验收标准。一段话能讲清的不用列表,能列清的不用图。讲清楚\"为什么\"比讲清楚\"做什么\"更重要。\n",
|
||||
"workspaceFiles": [
|
||||
|
||||
Loading…
Reference in New Issue
Block a user