Skip to content

bug(agents): model routing breaks block scalar descriptions and empties them #956

Description

@Rogercode97

Before submitting

  • I searched open and closed issues and did not find a report of this problem.
  • I reviewed this report and removed credentials, tokens, private paths, hostnames, and other sensitive data.

Problem

On every session start, gentle-pi rewrites agent model routing into the wrong position inside an agent definition whose description is a YAML block scalar. The model: key lands between the description: > header and its indented continuation lines, so the description parses as an empty string and its text is folded into the model value.

Observed on a real run against a project whose .agents/agents/ set declares description: > in 18 of 18 files:

description: >
model: deepseek/deepseek-v4-flash
  Adversarial review lens evaluating security risks, data exposure, and permission flaws.

which parses as:

description: ''
model: 'deepseek/deepseek-v4-flash Adversarial review lens evaluating security risks, data exposure, and permission flaws.'

Every discovered agent definition using a block scalar description is silently left with an empty description and a garbage model id.

This is not limited to one adapter. The packaged agent sets use description: > as follows: antigravity 18/18, claude 13/19, cursor 10/16, kimi 10/16, kiro 13/19.

Steps to reproduce

  1. Define an agent whose frontmatter uses a block scalar description:
---
name: review-risk
description: >
  Adversarial review lens evaluating security risks.
subagent: true
---
  1. Give it a routing entry, e.g. through /gentle:models or a model_profiles entry in .pi/subagents.json.
  2. Start a Pi session in that project.

Actual result: the definition is rewritten at the next session start into the broken frontmatter above.

Root cause in extensions/gentle-ai.ts (main @ db788aef):

const descriptionIndex = lines.findIndex((line) => line.startsWith("description:"));
const insertIndex = descriptionIndex >= 0 ? descriptionIndex + 1 : Math.min(1, lines.length);
lines.splice(insertIndex, 0, ...toInsert);

descriptionIndex + 1 is the first line of the block scalar, not the first key after it. The same logic existed a second time in lib/sdd-preflight.ts as updateAgentFrontmatterRouting.

The trigger is pi.on("session_start") -> applySavedModelConfig -> applyModelConfig. It does not require a model change.

Expected and actual behavior

Expected:

Routing keys are inserted after the block scalar's continuation lines, and a definition that already carries correct routing is left untouched.

Actual:

Routing keys are inserted inside the block scalar, so the description becomes empty and its text is folded into the model value on every session start.

gentle-pi version

2.5.0 (main @ db788ae)

Pi version

0.85.1

Operating system

Other

Relevant logs or error output (optional)

$ git diff .agents/agents/sdd-init.md
@@ -2,8 +2,8 @@
 name: sdd-init
 role: "SDD Stack Initializer"
 description: >
-  Initialize SDD context, detect project stack, testing capabilities, and bootstrap persistence backend.
 model: deepseek/deepseek-v4-flash
+  Initialize SDD context, detect project stack, testing capabilities, and bootstrap persistence backend.
 subagent: true

Parsed with PyYAML:

description repr: ''
model       repr: 'deepseek/deepseek-v4-flash Initialize SDD context, detect project stack, testing capabilities, and bootstrap persistence backend.'

Against the current implementation, a 12-case regression suite fails 5 cases. A local fix on branch fix/agent-frontmatter-block-scalar consolidates both writers into lib/agent-frontmatter.ts and inserts routing keys after the block scalar continuation lines.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions