mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-13 23:11:10 +00:00
Reasoning loop implemntation or handshake done and teste as well
This commit is contained in:
parent
085f30872a
commit
5f225d946f
7 changed files with 90 additions and 8 deletions
|
|
@ -1,3 +1,3 @@
|
|||
{"id":"df1a0b04-1993-45f4-b3cb-c0b4fcb2dba2","timestamp":"2026-02-21T08:37:15.794Z","vcs":{"revision_id":"abc123"},"files":[{"relative_path":"src/api/weather.ts","conversations":[{"url":"session-1","contributor":{"entity_type":"AI","model_identifier":"test-model"},"ranges":[{"start_line":1,"end_line":2,"content_hash":"sha256:2e4ec5cf14cfeb55ef32cb663ffd2c4fe6ab22bb2d2fe77ee8e284fe62866cac"}],"related":[{"type":"specification","value":"INT-001"}]}]}]}
|
||||
{"id":"7f9541c8-7fd4-4cef-ae44-c51f191b942a","timestamp":"2026-02-21T08:37:15.797Z","files":[{"relative_path":"src/api/forecast.ts","conversations":[{"contributor":{"entity_type":"AI","model_identifier":"unknown"},"ranges":[{"start_line":1,"end_line":1,"content_hash":"sha256:c47272be41ffa9d8a897b81b3f9f6d5e13fbb5d6dd4609a7b20c282950f11842"}],"related":[{"type":"specification","value":"INT-001"}]}]}]}
|
||||
{"id":"da60914f-8e16-4c59-8c5d-2c673793287d","timestamp":"2026-02-21T08:37:15.803Z","vcs":{"revision_id":"rev-1"},"files":[{"relative_path":"src/api/demo.ts","conversations":[{"url":"log-1","contributor":{"entity_type":"AI","model_identifier":"model-1"},"ranges":[{"start_line":1,"end_line":1,"content_hash":"sha256:bd994c26b795571c7c1e0357cba348f1d0238b648b748b9ec7a4d0de264d212f"}],"related":[{"type":"specification","value":"INT-001"}]}]}]}
|
||||
{"id":"02a7c124-4730-4e49-8783-08f861f640ba","timestamp":"2026-02-21T09:48:48.707Z","vcs":{"revision_id":"abc123"},"files":[{"relative_path":"src/api/weather.ts","conversations":[{"url":"session-1","contributor":{"entity_type":"AI","model_identifier":"test-model"},"ranges":[{"start_line":1,"end_line":2,"content_hash":"sha256:2e4ec5cf14cfeb55ef32cb663ffd2c4fe6ab22bb2d2fe77ee8e284fe62866cac"}],"related":[{"type":"specification","value":"INT-001"}]}]}]}
|
||||
{"id":"e55e9867-663a-412e-b341-af61f85dbedd","timestamp":"2026-02-21T09:48:48.716Z","files":[{"relative_path":"src/api/forecast.ts","conversations":[{"contributor":{"entity_type":"AI","model_identifier":"unknown"},"ranges":[{"start_line":1,"end_line":1,"content_hash":"sha256:c47272be41ffa9d8a897b81b3f9f6d5e13fbb5d6dd4609a7b20c282950f11842"}],"related":[{"type":"specification","value":"INT-001"}]}]}]}
|
||||
{"id":"3609a24b-418e-4e1a-a554-2e3cf9db1be9","timestamp":"2026-02-21T09:48:48.737Z","vcs":{"revision_id":"rev-1"},"files":[{"relative_path":"src/api/demo.ts","conversations":[{"url":"log-1","contributor":{"entity_type":"AI","model_identifier":"model-1"},"ranges":[{"start_line":1,"end_line":1,"content_hash":"sha256:bd994c26b795571c7c1e0357cba348f1d0238b648b748b9ec7a4d0de264d212f"}],"related":[{"type":"specification","value":"INT-001"}]}]}]}
|
||||
|
|
|
|||
47
scripts/test_phase1.js
Normal file
47
scripts/test_phase1.js
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
const fs = require("fs")
|
||||
const path = require("path")
|
||||
|
||||
// Load active intents
|
||||
const intentsPath = path.join(__dirname, "..", ".orchestration", "active_intents.yaml")
|
||||
const yaml = require("js-yaml")
|
||||
const intents = yaml.load(fs.readFileSync(intentsPath, "utf8")).active_intents
|
||||
|
||||
// Simple PreHook simulation
|
||||
function preHook(intentId, targetFile) {
|
||||
const intent = intents.find((i) => i.id === intentId)
|
||||
if (!intent) {
|
||||
throw new Error("You must select a valid active Intent ID before writing code.")
|
||||
}
|
||||
|
||||
const allowed = intent.owned_scope.some((scope) => targetFile.startsWith(scope.replace("**", "")))
|
||||
if (!allowed) {
|
||||
throw new Error(`Scope Violation: ${intentId} is not authorized to edit ${targetFile}`)
|
||||
}
|
||||
|
||||
console.log(`PreHook Passed: ${targetFile} is within scope for ${intentId}`)
|
||||
}
|
||||
|
||||
// Simulate AI writing a file
|
||||
function writeFile(intentId, filePath, content) {
|
||||
preHook(intentId, filePath)
|
||||
fs.writeFileSync(filePath, content)
|
||||
console.log(`File written successfully: ${filePath}`)
|
||||
}
|
||||
|
||||
// === TEST CASES ===
|
||||
try {
|
||||
// Valid case
|
||||
writeFile("INT-001", "src/api/weather.ts", "// Weather API code here")
|
||||
|
||||
// Invalid scope
|
||||
writeFile("INT-001", "src/db/db.ts", "// DB code here")
|
||||
} catch (err) {
|
||||
console.error("Error:", err.message)
|
||||
}
|
||||
|
||||
try {
|
||||
// Invalid intent
|
||||
writeFile("INT-999", "src/api/weather.ts", "// Should fail")
|
||||
} catch (err) {
|
||||
console.error("Error:", err.message)
|
||||
}
|
||||
1
src/api/weather.ts
Normal file
1
src/api/weather.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
// Weather API code here
|
||||
|
|
@ -10,6 +10,7 @@ import { isEmpty } from "../../utils/object"
|
|||
import { McpHub } from "../../services/mcp/McpHub"
|
||||
import { CodeIndexManager } from "../../services/code-index/manager"
|
||||
import { SkillsManager } from "../../services/skills/SkillsManager"
|
||||
import { INTENT_DRIVEN_PROMPT_SNIPPET } from "../../hooks/intent-prompt-snippet"
|
||||
|
||||
import type { SystemPromptSettings } from "./types"
|
||||
import {
|
||||
|
|
@ -84,6 +85,8 @@ async function generatePrompt(
|
|||
|
||||
const basePrompt = `${roleDefinition}
|
||||
|
||||
${INTENT_DRIVEN_PROMPT_SNIPPET}
|
||||
|
||||
${markdownFormattingSection()}
|
||||
|
||||
${getSharedToolUseSection()}${toolsCatalog}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import type OpenAI from "openai"
|
||||
import { selectActiveIntentToolDefinition } from "../../../../hooks/select-active-intent-tool"
|
||||
import accessMcpResource from "./access_mcp_resource"
|
||||
import { apply_diff } from "./apply_diff"
|
||||
import applyPatch from "./apply_patch"
|
||||
|
|
@ -47,6 +48,7 @@ export function getNativeTools(options: NativeToolsOptions = {}): OpenAI.Chat.Ch
|
|||
}
|
||||
|
||||
return [
|
||||
selectActiveIntentToolDefinition,
|
||||
accessMcpResource,
|
||||
apply_diff,
|
||||
applyPatch,
|
||||
|
|
|
|||
|
|
@ -34,8 +34,9 @@ export async function loadIntentContext(cwd: string, intentId: string): Promise<
|
|||
|
||||
/**
|
||||
* Build an XML block to inject as the tool result for select_active_intent.
|
||||
* Optionally include related agent trace entries for consolidated context.
|
||||
*/
|
||||
export function buildIntentContextXml(context: IntentContext): string {
|
||||
export function buildIntentContextXml(context: IntentContext, relatedTracePaths: string[] = []): string {
|
||||
const constraintsXml =
|
||||
context.constraints.length > 0
|
||||
? context.constraints.map((c) => ` <constraint>${escapeXml(c)}</constraint>`).join("\n")
|
||||
|
|
@ -48,6 +49,10 @@ export function buildIntentContextXml(context: IntentContext): string {
|
|||
(context.acceptance_criteria?.length ?? 0) > 0
|
||||
? context.acceptance_criteria!.map((a) => ` <criterion>${escapeXml(a)}</criterion>`).join("\n")
|
||||
: " <criterion>None specified</criterion>"
|
||||
const traceXml =
|
||||
relatedTracePaths.length > 0
|
||||
? relatedTracePaths.map((p) => ` <file>${escapeXml(p)}</file>`).join("\n")
|
||||
: " <file>None yet</file>"
|
||||
|
||||
return `<intent_context>
|
||||
<id>${escapeXml(context.id)}</id>
|
||||
|
|
@ -62,9 +67,34 @@ ${scopeXml}
|
|||
<acceptance_criteria>
|
||||
${criteriaXml}
|
||||
</acceptance_criteria>
|
||||
<related_agent_trace>
|
||||
${traceXml}
|
||||
</related_agent_trace>
|
||||
</intent_context>`
|
||||
}
|
||||
|
||||
/**
|
||||
* Load intent from active_intents.yaml, gather related agent_trace entries for that intent,
|
||||
* and return a consolidated XML context block (for Pre-Hook injection).
|
||||
*/
|
||||
export async function buildConsolidatedIntentContextXml(cwd: string, intentId: string): Promise<string | null> {
|
||||
const context = await loadIntentContext(cwd, intentId)
|
||||
if (!context) return null
|
||||
const traceLines = await readRecentTraceForIntent(cwd, intentId, 20)
|
||||
const paths = new Set<string>()
|
||||
for (const line of traceLines) {
|
||||
try {
|
||||
const entry = JSON.parse(line) as { files?: Array<{ relative_path?: string }> }
|
||||
for (const f of entry.files ?? []) {
|
||||
if (f.relative_path) paths.add(f.relative_path)
|
||||
}
|
||||
} catch {
|
||||
// skip malformed lines
|
||||
}
|
||||
}
|
||||
return buildIntentContextXml(context, [...paths])
|
||||
}
|
||||
|
||||
function escapeXml(s: string): string {
|
||||
return s
|
||||
.replace(/&/g, "&")
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import path from "path"
|
|||
|
||||
import type { HookResult } from "./types"
|
||||
import { DESTRUCTIVE_TOOLS } from "./types"
|
||||
import { loadIntentContext, buildIntentContextXml } from "./context-loader"
|
||||
import { loadIntentContext, buildConsolidatedIntentContextXml } from "./context-loader"
|
||||
import { pathInScope } from "./scope"
|
||||
|
||||
/** Block paths that escape workspace (.. or absolute outside cwd). */
|
||||
|
|
@ -41,15 +41,14 @@ export class PreHook {
|
|||
if (!intentId) {
|
||||
return { blocked: true, error: "You must provide a valid intent_id when calling select_active_intent." }
|
||||
}
|
||||
const context = await loadIntentContext(cwd, intentId)
|
||||
if (!context) {
|
||||
const xml = await buildConsolidatedIntentContextXml(cwd, intentId)
|
||||
if (!xml) {
|
||||
return {
|
||||
blocked: true,
|
||||
error: `You must cite a valid active Intent ID. Intent "${intentId}" was not found in .orchestration/active_intents.yaml.`,
|
||||
}
|
||||
}
|
||||
setActiveIntentId(intentId)
|
||||
const xml = buildIntentContextXml(context)
|
||||
return { blocked: false, injectResult: xml }
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue