From a52154877caa5c3e473ee56c1eaf040b7da2375f Mon Sep 17 00:00:00 2001 From: Guilhem Date: Fri, 16 Oct 2026 17:53:10 +0200 Subject: [PATCH] fix(ai-chat): tell the session chat that an agent is an ai_agent resource (#11798) * fix(ai-chat): tell the session chat that an agent is an ai_agent resource Asked about an agent by name, the chat looked for a flow, script or app of that path and concluded the agent does not exist. The rule tells it to read the agent as a resource, and to leave deploys to the agent's page, whose editor validates the config. Co-Authored-By: Claude Opus 5.5 (1M context) * fix(ai-chat): gate agent drafting on write_draft, share the ai_agent fact The drafting sentence now reaches only users who can write resource drafts, and the fact that an agent is an ai_agent resource also lives in system_prompts/base/resources.md so the CLI skills get it. Co-Authored-By: Claude Opus 5.5 (1M context) --------- Co-authored-by: Claude Opus 5.5 (1M context) --- ai_evals/cases/global.yaml | 53 +++++++++++++++++++ .../global/initial/support_triage_agent.json | 18 +++++++ cli/src/guidance/skills.gen.ts | 6 +++ .../components/copilot/chat/global/core.ts | 4 ++ system_prompts/auto-generated/prompts.ts | 6 +++ .../auto-generated/skills/resources/SKILL.md | 6 +++ system_prompts/base/resources.md | 6 +++ 7 files changed, 99 insertions(+) create mode 100644 ai_evals/fixtures/frontend/global/initial/support_triage_agent.json diff --git a/ai_evals/cases/global.yaml b/ai_evals/cases/global.yaml index 4d5fbab83d..136f125e59 100644 --- a/ai_evals/cases/global.yaml +++ b/ai_evals/cases/global.yaml @@ -3230,3 +3230,56 @@ - *refusal - - admin skipJudge: true + +# An agent from the Agents page is an `ai_agent` resource. Asked about one by name, the model +# has to read it as a resource rather than look for a flow or script of that name. +- id: global-agent-read-as-resource + prompt: |- + What is my support_triage agent told to do? + initial: ai_evals/fixtures/frontend/global/initial/support_triage_agent.json + runtime: + maxTurns: 6 + sessionChat: true + validate: + draftCountExactly: 0 + toolExpect: + toolCallArgsSameCall: + - tool: read_workspace_item + args: + - field: type + stringIncludesAnyOf: + - resource + - field: path + stringIncludesAnyOf: + - f/evals/global/support_triage + assistantExpect: + requiredMentionsAnyOf: + - - billing + skipJudge: true + +# The chat may draft an agent change, but the agent is deployed from its own page, whose +# editor validates it; the chat's deploy does not. +- id: global-agent-edit-sent-to-agents-page + prompt: |- + Update my support_triage agent so it also recognizes feature requests, and deploy it. + initial: ai_evals/fixtures/frontend/global/initial/support_triage_agent.json + runtime: + maxTurns: 6 + sessionChat: true + validate: + draftCountExactly: 1 + requiredDrafts: + - type: resource + path: f/evals/global/support_triage + valueIncludes: + - ai_agent + - feature + toolExpect: + forbiddenToolsUsed: + - deploy_workspace_item + assistantExpect: + requiredMentionsAnyOf: + - - /agents/edit + - Agents page + - agent editor + skipJudge: true diff --git a/ai_evals/fixtures/frontend/global/initial/support_triage_agent.json b/ai_evals/fixtures/frontend/global/initial/support_triage_agent.json new file mode 100644 index 0000000000..b603bf5767 --- /dev/null +++ b/ai_evals/fixtures/frontend/global/initial/support_triage_agent.json @@ -0,0 +1,18 @@ +{ + "workspace": { + "resources": [ + { + "path": "f/evals/global/support_triage", + "resource_type": "ai_agent", + "description": "Triages incoming support tickets", + "value": { + "provider": { "kind": "anthropic", "model": "claude-sonnet-5", "resource": "" }, + "output_type": "text", + "system_prompt": "Classify each ticket as billing, bug or question, then reply with the label only.", + "memory": { "kind": "off" }, + "tools": [] + } + } + ] + } +} diff --git a/cli/src/guidance/skills.gen.ts b/cli/src/guidance/skills.gen.ts index 3b7bfa2298..bcef0d5d3e 100644 --- a/cli/src/guidance/skills.gen.ts +++ b/cli/src/guidance/skills.gen.ts @@ -7173,6 +7173,12 @@ Example: \`f/databases/postgres_prod.resource.json\` - \`value\` - Object containing the resource configuration - \`resource_type\` - Name of the resource type (e.g., "postgresql", "slack") +## Agents + +An agent, as the Agents page lists it, is a resource of type \`ai_agent\`. Its value holds the +agent's provider, system prompt, tools and memory settings, and a flow step uses a saved agent by +linking its path. + ## Variable References Reference variables in resource values: diff --git a/frontend/src/lib/components/copilot/chat/global/core.ts b/frontend/src/lib/components/copilot/chat/global/core.ts index e8f8fc1467..a830d4d404 100644 --- a/frontend/src/lib/components/copilot/chat/global/core.ts +++ b/frontend/src/lib/components/copilot/chat/global/core.ts @@ -1648,6 +1648,10 @@ Rules:${when( )} - Use list_workspace_items to find items and read_workspace_item before changing an existing item. For triggers, pass trigger_kind. ${groupMembershipRule}- Listings and reads return only what this user can see: items in folders they cannot read are hidden from you both. When an item the user names is missing, say it is not among what they can see and may be in a folder they cannot read, where someone with access can run it — never state that it does not exist or is not deployed. +- An agent, as the Agents page lists it, is a resource of type \`ai_agent\`: read it with read_workspace_item type "resource".${when( + canDraftResources, + " You may draft a change to an agent, but never deploy or rename one here: the user reviews and deploys it from the agent's page, `/agents/edit/`, so point them there." + )} - If the user message includes an ACTIVE EDITOR section, treat it as the currently open item and use it for references like "this", "current", or "open editor".${activePreviewRule}${when( canWriteAnyDraft && canDeployAnyKind, ` diff --git a/system_prompts/auto-generated/prompts.ts b/system_prompts/auto-generated/prompts.ts index 69565dd9d4..59b00c2821 100644 --- a/system_prompts/auto-generated/prompts.ts +++ b/system_prompts/auto-generated/prompts.ts @@ -662,6 +662,12 @@ Resources store credentials and configuration for external services. - \`value\` - Object containing the resource configuration - \`resource_type\` - Name of the resource type (e.g., "postgresql", "slack") +## Agents + +An agent, as the Agents page lists it, is a resource of type \`ai_agent\`. Its value holds the +agent's provider, system prompt, tools and memory settings, and a flow step uses a saved agent by +linking its path. + ## Variable References Reference variables in resource values: diff --git a/system_prompts/auto-generated/skills/resources/SKILL.md b/system_prompts/auto-generated/skills/resources/SKILL.md index 62d021f6bf..45d3c64619 100644 --- a/system_prompts/auto-generated/skills/resources/SKILL.md +++ b/system_prompts/auto-generated/skills/resources/SKILL.md @@ -34,6 +34,12 @@ Example: `f/databases/postgres_prod.resource.json` - `value` - Object containing the resource configuration - `resource_type` - Name of the resource type (e.g., "postgresql", "slack") +## Agents + +An agent, as the Agents page lists it, is a resource of type `ai_agent`. Its value holds the +agent's provider, system prompt, tools and memory settings, and a flow step uses a saved agent by +linking its path. + ## Variable References Reference variables in resource values: diff --git a/system_prompts/base/resources.md b/system_prompts/base/resources.md index 72d817a1b2..652bec1964 100644 --- a/system_prompts/base/resources.md +++ b/system_prompts/base/resources.md @@ -31,6 +31,12 @@ Example: `f/databases/postgres_prod.resource.json` - `value` - Object containing the resource configuration - `resource_type` - Name of the resource type (e.g., "postgresql", "slack") +## Agents + +An agent, as the Agents page lists it, is a resource of type `ai_agent`. Its value holds the +agent's provider, system prompt, tools and memory settings, and a flow step uses a saved agent by +linking its path. + ## Variable References Reference variables in resource values: