From 11423c97a7124bab8a148cf5fc92ba058fa96ecc Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Wed, 11 Mar 2026 21:45:35 +0900 Subject: [PATCH] fix(agents): add anti-duplication rules to Prometheus and Metis agents - Import and inject buildAntiDuplicationSection() in all 3 Prometheus variants (interview-mode, gpt, gemini) and Metis - Added tests verifying anti-dup section presence in all prompt variants - Completes anti-duplication coverage for all delegating agents --- src/agents/anti-duplication.test.ts | 14 ++++++++++++++ src/agents/metis.ts | 3 +++ src/agents/prometheus-prompt.test.ts | 21 +++++++++++++++++++++ src/agents/prometheus/gemini.ts | 6 +++++- src/agents/prometheus/gpt.ts | 4 ++++ src/agents/prometheus/interview-mode.ts | 4 ++++ 6 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/agents/anti-duplication.test.ts b/src/agents/anti-duplication.test.ts index 49137329a..56c3dfd6e 100644 --- a/src/agents/anti-duplication.test.ts +++ b/src/agents/anti-duplication.test.ts @@ -2,6 +2,7 @@ import { describe, it, expect } from "bun:test" import { buildAntiDuplicationSection } from "./dynamic-agent-prompt-builder" +import { METIS_SYSTEM_PROMPT } from "./metis" describe("buildAntiDuplicationSection", () => { it("#given no arguments #when building anti-duplication section #then returns comprehensive rule section", () => { @@ -90,3 +91,16 @@ describe("buildAntiDuplicationSection", () => { expect(result).toContain("") }) }) + +describe("METIS_SYSTEM_PROMPT anti-duplication coverage", () => { + it("#given the system prompt #when reading delegated exploration rules #then includes anti-duplication guidance", () => { + // given + const prompt = METIS_SYSTEM_PROMPT + + // when / then + expect(prompt).toContain("") + expect(prompt).toContain("Anti-Duplication Rule") + expect(prompt).toContain("DO NOT perform the same search yourself") + expect(prompt).toContain("non-overlapping work") + }) +}) diff --git a/src/agents/metis.ts b/src/agents/metis.ts index e1d75cccd..47eba612f 100644 --- a/src/agents/metis.ts +++ b/src/agents/metis.ts @@ -1,5 +1,6 @@ import type { AgentConfig } from "@opencode-ai/sdk" import type { AgentMode, AgentPromptMetadata } from "./types" +import { buildAntiDuplicationSection } from "../dynamic-agent-prompt-builder" import { createAgentToolRestrictions } from "../shared/permission-compat" const MODE: AgentMode = "subagent" @@ -25,6 +26,8 @@ export const METIS_SYSTEM_PROMPT = `# Metis - Pre-Planning Consultant - **READ-ONLY**: You analyze, question, advise. You do NOT implement or modify files. - **OUTPUT**: Your analysis feeds into Prometheus (planner). Be actionable. +${buildAntiDuplicationSection()} + --- ## PHASE 0: INTENT CLASSIFICATION (MANDATORY FIRST STEP) diff --git a/src/agents/prometheus-prompt.test.ts b/src/agents/prometheus-prompt.test.ts index 266b8f80f..d1e6b87f8 100644 --- a/src/agents/prometheus-prompt.test.ts +++ b/src/agents/prometheus-prompt.test.ts @@ -1,5 +1,7 @@ import { describe, test, expect } from "bun:test" import { PROMETHEUS_SYSTEM_PROMPT } from "./prometheus" +import { PROMETHEUS_GPT_SYSTEM_PROMPT } from "./prometheus/gpt" +import { PROMETHEUS_GEMINI_SYSTEM_PROMPT } from "./prometheus/gemini" describe("PROMETHEUS_SYSTEM_PROMPT Momus invocation policy", () => { test("should direct providing ONLY the file path string when invoking Momus", () => { @@ -82,3 +84,22 @@ describe("PROMETHEUS_SYSTEM_PROMPT zero human intervention", () => { expect(lowerPrompt).toMatch(/zero acceptance criteria require human/) }) }) + +describe("Prometheus prompts anti-duplication coverage", () => { + test("all variants should include anti-duplication rules for delegated exploration", () => { + // given + const prompts = [ + PROMETHEUS_SYSTEM_PROMPT, + PROMETHEUS_GPT_SYSTEM_PROMPT, + PROMETHEUS_GEMINI_SYSTEM_PROMPT, + ] + + // when / then + for (const prompt of prompts) { + expect(prompt).toContain("") + expect(prompt).toContain("Anti-Duplication Rule") + expect(prompt).toContain("DO NOT perform the same search yourself") + expect(prompt).toContain("non-overlapping work") + } + }) +}) diff --git a/src/agents/prometheus/gemini.ts b/src/agents/prometheus/gemini.ts index 5612d36d5..a43e2a5eb 100644 --- a/src/agents/prometheus/gemini.ts +++ b/src/agents/prometheus/gemini.ts @@ -9,6 +9,8 @@ * - Tool-call mandate for every phase transition */ +import { buildAntiDuplicationSection } from "../dynamic-agent-prompt-builder" + export const PROMETHEUS_GEMINI_SYSTEM_PROMPT = ` You are Prometheus - Strategic Planning Consultant from OhMyOpenCode. @@ -43,6 +45,8 @@ A plan is "decision complete" when the implementer needs ZERO judgment calls — This is your north star quality metric. +${buildAntiDuplicationSection()} + ## Three Principles @@ -325,4 +329,4 @@ You are Prometheus, the strategic planning consultant. You bring foresight and s export function getGeminiPrometheusPrompt(): string { return PROMETHEUS_GEMINI_SYSTEM_PROMPT -} \ No newline at end of file +} diff --git a/src/agents/prometheus/gpt.ts b/src/agents/prometheus/gpt.ts index 94810b10f..a9ff96a73 100644 --- a/src/agents/prometheus/gpt.ts +++ b/src/agents/prometheus/gpt.ts @@ -8,6 +8,8 @@ * - Principle-driven: Decision Complete, Explore Before Asking, Two Kinds of Unknowns */ +import { buildAntiDuplicationSection } from "../dynamic-agent-prompt-builder"; + export const PROMETHEUS_GPT_SYSTEM_PROMPT = ` You are Prometheus - Strategic Planning Consultant from OhMyOpenCode. @@ -25,6 +27,8 @@ A plan is "decision complete" when the implementer needs ZERO judgment calls — This is your north star quality metric. +${buildAntiDuplicationSection()} + ## Three Principles (Read First) diff --git a/src/agents/prometheus/interview-mode.ts b/src/agents/prometheus/interview-mode.ts index 1d4007518..66427b318 100644 --- a/src/agents/prometheus/interview-mode.ts +++ b/src/agents/prometheus/interview-mode.ts @@ -5,6 +5,8 @@ * Includes intent classification, research patterns, and anti-patterns. */ +import { buildAntiDuplicationSection } from "../dynamic-agent-prompt-builder" + export const PROMETHEUS_INTERVIEW_MODE = `# PHASE 1: INTERVIEW MODE (DEFAULT) ## Step 0: Intent Classification (EVERY request) @@ -29,6 +31,8 @@ Before diving into consultation, classify the work intent. This determines your - **Simple** (1-2 files, clear scope, <30 min work) — **Lightweight**: 1-2 targeted questions → propose approach. - **Complex** (3+ files, multiple components, architectural impact) — **Full consultation**: Intent-specific deep interview. +${buildAntiDuplicationSection()} + --- ## Intent-Specific Interview Strategies