← Back ← Back

Fix the VibeChat agent tool loop

Problem

The chat agent gets stuck on multi-step tasks. Example: operator said
"add dark mode", the chat called read_file 5-6 times in chunks
without ever calling write_file. Burned all 8 iterations. The
3-strike stuck detection only FIRES the loop break — it doesn't
prevent the dead end. The chat ends with "I looped" but no actual
change.

Current behavior

src/vibechat/components/ChatPanel.tsx line 299-518 is the tool
loop. maxIterations=8. After 3 same-tool-3x with no failure, it
breaks with a "I looped" message but no write.

src/vibechat/tools.ts line 164+ is executeTool. It dispatches
to bridge endpoints.

/opt/vibecoder-bridge/server.js line 64 is read_file. maxLines
capped at 500, default 200.

What to fix

1. Add read_files_for_context bridge endpoint

In /opt/vibecoder-bridge/server.js, add a new endpoint at line 95
(after read_file). Body:

{
  workspaceRoot: string,
  paths: string[]  // array of file paths relative to workspaceRoot
}

Behavior:
- Read each file. If a file is ≤ 1500 lines, include the full content.
- If a file is > 1500 lines, include first 800 lines + note "file is
2000 lines total, use read_file with offset=800 maxLines=200 to get
the rest"
- Return JSON:

{
  files: {
    "path/to/file.tsx": { content: "...", totalLines: 600, truncated: false },
    ...
  }
}

2. Add read_files_for_context to client tools

In src/vibechat/tools.ts:
- Add a new tool definition in TOOLS array
- Add a case in executeTool switch for read_files_for_context
that calls POST /api/agent/read_files_for_context with
{ workspaceRoot, paths: args.paths }

3. Update read_file tool description to discourage pagination

In src/vibechat/tools.ts, change read_file description from:
"By default returns up to 200 lines; pass offset=N maxLines=M to paginate"
to:
"Returns up to 2000 lines. Most files are < 1500 lines, so just call
once with maxLines=2000 and you'll get the whole file. Only paginate
if the file is genuinely huge AND you need the whole thing. If the
result has truncated=true, you should WRITE with what you have —
partial changes are better than no changes."

4. Add "act now" pressure at iteration 3

In src/vibechat/components/ChatPanel.tsx, after the model returns
a tool_call (around line 430, after workingMessages.push), check:

if (iterations >= 3 && !hasWrittenYet && !hasRunCommandYet) {
  // Inject a nudge
  const nudgeMsg = { role: 'system', content: 'You have used 3 of 8 iterations on reading. If you have enough info to write, do it NOW. Partial changes are better than no changes. The operator is waiting.' };
  workingMessages.push(nudgeMsg);
}

Track hasWrittenYet and hasRunCommandYet flags initialized to
false, set to true when write_file or run_command is called.

5. Add read_files_for_context to system prompt

In src/vibechat/prompts.ts SYSTEM_PROMPT, in the "# Your Abilities"
section, add:
"- read_files_for_context(paths: string[]) — read up to 5 files in
ONE tool call. Returns content for each. Use this when you need to
see multiple files before writing. Each call costs 1 iteration total,
not 1 per file."

6. Lower maxIterations from 8 to 6

In src/vibechat/components/ChatPanel.tsx line 294, change
const maxIterations = 8; to const maxIterations = 6;

What to deliver

  1. Show the new code for each section, with file paths and line
    numbers
  2. Build the project with npm run build (assume cwd is the
    vibecoder-standalone repo at /tmp/vc-deploy)
  3. Commit with message: "fix(vibechat): make agent act on multi-step
    tasks (read_files_for_context + act-now pressure)"
  4. Push to origin main
  5. Deploy via the same SFTP pattern (upload dist/ to
    /var/www/freshvibeapps/clients/vibecoder/vibechat/)
  6. Also update the bridge by uploading the new server.js to
    /opt/vibecoder-bridge/server.js and restarting the service

Constraints

Output format

After your work, show:
- The 6 file changes (path + relevant diff)
- The build output (last 3 lines)
- The git commit hash
- The push confirmation
- The bridge restart confirmation
- The deploy_info JSON showing the new bundle hash
- A ### 📋 Report block with Did/Verified/Next/Issues

If any step fails, say so clearly and stop. Don't pretend success.