Files
Aakash BakhleandGitHub 6d38b4d39c fix(captain): improve complex migration instructions (#15002)
Improves Captain V1 → V2 migration for complex legacy instructions so
mandatory triggers, workflows, language rules, and escalation behavior
remain active while query-dependent product knowledge is prepared as
pending FAQ candidates.

## What changed

- Added explicit preservation rules for mandatory triggers, verification
steps, escalation conditions, exceptions, and language behavior.
- Added an auditor that checks the draft and fixes any issues before
manual review.
- Kept the existing migration application contract and schema limits
unchanged
- Added focused regression coverage for the complex-prompt classifier
contract.

## How to reproduce

Generate a migration draft for an assistant with dense legacy
instructions containing mandatory handoff triggers, verification rules,
product facts, and multi-step workflows. The resulting draft should keep
actions active, place query-dependent facts in FAQ candidates, and avoid
silently dropping or reversing source requirements.

Focused Captain migration specs and RuboCop checks pass locally.
2026-07-15 14:51:51 +05:30

90 lines
4.9 KiB
Ruby

class Captain::AssistantMigration::InstructionClassifierSchema < RubyLLM::Schema
DESCRIPTION_LENGTH_LIMIT = 500
def self.instruction_items(field_name, description:, max_items: 20)
array field_name,
description: "#{description} Return plain standalone sentences without numbering, bullets, or section labels.",
max_items: max_items,
of: :string
end
array :business_product_context,
description: "Single compact root assistant description for the root orchestrator prompt, maximum #{DESCRIPTION_LENGTH_LIMIT} characters: " \
'preserve the existing assistant description and enrich it only with relevant business/product context from the ' \
'custom instructions. Include assistant identity, product scope, high-level mission, and high-level source/routing ' \
'priorities only. Do not include workflows, procedures, attribute glossaries, policy details, or long inventories. ' \
'Return complete plain prose without numbering, bullets, section labels, or a truncated final sentence.',
min_items: 1,
max_items: 1 do
string max_length: DESCRIPTION_LENGTH_LIMIT
end
instruction_items :response_guidelines,
description: 'Tone, language, answer length, formatting, and clarification behavior.',
max_items: 20
instruction_items :guardrails,
description: 'Refusal rules, escalation boundaries, source boundaries, safety limits, and things the assistant must not do.',
max_items: 20
array :scenario_candidates,
description: 'Review-stage specialized-agent candidates. These are also temporarily flattened into response guidelines.',
max_items: 15 do
object do
string :title,
description: 'Short scenario agent title for a distinct user-intent workflow.',
max_length: 80
string :description,
description: 'When this specialized scenario should be used. This is shown to the orchestrator for routing.',
max_length: 500
string :instruction,
description: 'How the specialized agent should handle the workflow. Include only evidence-backed markdown tool links. ' \
'Do not include confidence labels or review notes.',
max_length: 2000
string :response_guideline,
description: 'Same-language, customer-visible response guideline that preserves this scenario behavior when flattened. ' \
'Do not include tool syntax, tool names, labels, private-note instructions, or internal implementation details.',
max_length: 1000
array :tool_ids,
description: 'Available tool IDs explicitly referenced in instruction using markdown links. Empty when no tools are required.',
max_items: 10,
of: :string
end
end
object :conversation_messages, description: 'Exact globally reusable customer-facing message copy found in instructions. ' \
'Leave empty for conditional, placeholder, or workflow-specific copy.' do
string :welcome_message, description: 'Exact globally reusable initial greeting copy from instructions, or empty string. ' \
'Do not convert an instruction about greeting into message copy.',
max_length: 1000
string :handoff_message,
description: 'Exact globally reusable human-handoff message copy from instructions, or empty string. ' \
'Do not use scenario-specific, team-specific, placeholder, or conditional handoff copy.',
max_length: 1000
string :resolution_message,
description: 'Exact globally reusable resolution/closing message copy from instructions, or empty string. ' \
'Do not use conditional or placeholder closing copy.',
max_length: 1000
end
array :faq_document_candidates,
description: 'FAQ candidates for reusable query-dependent facts such as pricing, policy, setup, troubleshooting, ' \
'or operational details.',
max_items: 25 do
object do
string :question,
description: 'Natural, standalone customer question about factual product or business knowledge.',
max_length: 255
string :answer,
description: 'Self-contained factual answer using only the existing instructions. Do not include assistant behavior, ' \
'tool use, or message copy. Preserve exact values, conditions, and exceptions.',
max_length: 2000
end
end
instruction_items :needs_review,
description: 'Unclear, conflicting, risky, duplicated, or uncertain content that needs human review. ' \
'Include the reason in the item text.',
max_items: 20
end