mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-15 03:55:09 +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
|
// 4. Pre-bind skills the template declares so a hired agent is
|
||||||
// usable out of the box ("数据分析师" already knows SQL, "代码审查员"
|
// usable out of the box ("数据分析师" already knows SQL, "代码审查员"
|
||||||
// already has the test-driven-development playbook). Slugs are
|
// already has the test-driven-development playbook). Resolution
|
||||||
// resolved against the target workspace; missing skills are skipped
|
// failures (slug missing in this workspace) are skipped with a
|
||||||
// with a warning so a partially-installed environment can still
|
// warning; bind-service exceptions still propagate and roll back
|
||||||
// complete the hire.
|
// the @Transactional hire — see helper Javadoc.
|
||||||
applyDefaultSkillBindings(template, created, workspaceId);
|
applyDefaultSkillBindings(template, created);
|
||||||
|
|
||||||
// 5. Pre-bind any standalone tools the template wants. Filtered
|
// 5. Pre-bind any standalone tools the template wants. Picker
|
||||||
// against the picker so a deprecated / unavailable tool name in the
|
// outage and unknown names are dropped with a warning; a
|
||||||
// template doesn't abort the hire — same forgiving stance as
|
// setToolBindings exception still propagates (same contract as
|
||||||
// skills above.
|
// skills) — see helper Javadoc.
|
||||||
applyDefaultToolBindings(template, created);
|
applyDefaultToolBindings(template, created);
|
||||||
|
|
||||||
return created;
|
return created;
|
||||||
@ -164,15 +164,39 @@ public class TemplateService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve {@link TemplateDTO#getDefaultSkillSlugs()} to skill ids inside
|
* Resolve {@link TemplateDTO#getDefaultSkillSlugs()} to skill ids inside
|
||||||
* {@code workspaceId} and pre-bind them on the freshly-created agent.
|
* the agent's own workspace and pre-bind them.
|
||||||
* 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
|
* <p><b>Failure contract — read carefully.</b>
|
||||||
* landed yet (offline upgrade, partial seed, custom workspace).
|
* <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();
|
List<String> slugs = template.getDefaultSkillSlugs();
|
||||||
if (slugs == null || slugs.isEmpty()) return;
|
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<>();
|
List<Long> resolvedIds = new ArrayList<>();
|
||||||
for (String slug : slugs) {
|
for (String slug : slugs) {
|
||||||
if (slug == null || slug.isBlank()) continue;
|
if (slug == null || slug.isBlank()) continue;
|
||||||
@ -198,6 +222,11 @@ public class TemplateService {
|
|||||||
* {@link AgentBindingService#setToolBindings} sees only resolvable names
|
* {@link AgentBindingService#setToolBindings} sees only resolvable names
|
||||||
* — its own validation would otherwise abort the call on the first
|
* — its own validation would otherwise abort the call on the first
|
||||||
* unknown name and leave the agent with no tool bindings at all.
|
* 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) {
|
private void applyDefaultToolBindings(TemplateDTO template, AgentEntity created) {
|
||||||
List<String> names = template.getDefaultToolNames();
|
List<String> names = template.getDefaultToolNames();
|
||||||
|
|||||||
@ -10,8 +10,7 @@
|
|||||||
"maxIterations": 12,
|
"maxIterations": 12,
|
||||||
"defaultSkillSlugs": [
|
"defaultSkillSlugs": [
|
||||||
"ideation",
|
"ideation",
|
||||||
"make_plan",
|
"make_plan"
|
||||||
"writing-plans"
|
|
||||||
],
|
],
|
||||||
"systemPrompt": "## Role\n产品助理\n\n## Goal\n把模糊需求理成可执行的 PRD\n\n## Backstory\n你做产品做久了,知道一句话需求背后通常藏着三个不一样的问题。所以你拿到任何描述,先把它翻译成\"用户是谁 + 他在什么场景下 + 他想达成什么 + 现在的痛点是什么\"。你写 PRD 不堆功能列表,会先讲清楚\"不做什么\"和\"成功长什么样\"。\n\n## Additional Instructions\n输出结构:1) 用户与场景;2) 目标与反目标(不做什么);3) 核心流程;4) 验收标准。一段话能讲清的不用列表,能列清的不用图。讲清楚\"为什么\"比讲清楚\"做什么\"更重要。\n",
|
"systemPrompt": "## Role\n产品助理\n\n## Goal\n把模糊需求理成可执行的 PRD\n\n## Backstory\n你做产品做久了,知道一句话需求背后通常藏着三个不一样的问题。所以你拿到任何描述,先把它翻译成\"用户是谁 + 他在什么场景下 + 他想达成什么 + 现在的痛点是什么\"。你写 PRD 不堆功能列表,会先讲清楚\"不做什么\"和\"成功长什么样\"。\n\n## Additional Instructions\n输出结构:1) 用户与场景;2) 目标与反目标(不做什么);3) 核心流程;4) 验收标准。一段话能讲清的不用列表,能列清的不用图。讲清楚\"为什么\"比讲清楚\"做什么\"更重要。\n",
|
||||||
"workspaceFiles": [
|
"workspaceFiles": [
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user