orchestrated-discussions/smarttools/discussion-qa/config.yaml

136 lines
6.9 KiB
YAML

name: discussion-qa
description: Quality assurance specialist participant for discussions
category: Discussion
meta:
display_name: AI-QA
alias: qa
type: voting
expertise:
- Test strategy
- Edge case identification
- Regression testing
- Error handling
- Quality metrics
- Bug prevention
- Test automation
concerns:
- What could go wrong?
- How do we test this?
- What are the edge cases?
- Is error handling sufficient?
voice: en-US-Neural2-D
provider: gemini
color:
- 180
- 255
- 100
arguments:
- flag: --callout
variable: callout
default: ''
description: Specific question or @mention context
- flag: --templates-dir
variable: templates_dir
default: templates
description: Path to templates directory
- flag: --diagrams-dir
variable: diagrams_dir
default: diagrams
description: Path to save diagrams
- flag: --log-file
variable: log_file
default: ''
description: Path to log file for progress updates
steps:
- type: code
code: "import re\nimport os\n\nphase_match = re.search(r'<!--\\s*Phase:\\s*(\\w+)\\\
s*-->', input, re.IGNORECASE)\ntemplate_match = re.search(r'<!--\\s*Template:\\\
s*(\\w+)\\s*-->', input, re.IGNORECASE)\n\ncurrent_phase = phase_match.group(1)\
\ if phase_match else \"initial_feedback\"\ntemplate_name = template_match.group(1)\
\ if template_match else \"feature\"\n\ntemplate_path = os.path.join(templates_dir,\
\ template_name + \".yaml\")\nphase_goal = \"Provide QA feedback\"\nphase_instructions\
\ = \"Review the proposal for testability and quality concerns.\"\n\nif os.path.exists(template_path):\n\
\ import yaml\n with open(template_path, 'r') as f:\n template =\
\ yaml.safe_load(f)\n phases = template.get(\"phases\", {})\n phase_info\
\ = phases.get(current_phase, {})\n phase_goal = phase_info.get(\"goal\", phase_goal)\n\
\ phase_instructions = phase_info.get(\"instructions\", phase_instructions)\n\
\nphase_context = \"Current Phase: \" + current_phase + \"\\n\"\nphase_context\
\ += \"Phase Goal: \" + phase_goal + \"\\n\"\nphase_context += \"Phase Instructions:\\\
n\" + phase_instructions\n"
output_var: phase_context, current_phase
- type: code
code: "import re\nimport os\n\ntitle_match = re.search(r'<!--\\s*Title:\\s*(.+?)\\\
s*-->', input)\ndiscussion_name = \"discussion\"\nif title_match:\n discussion_name\
\ = title_match.group(1).strip().lower()\n discussion_name = re.sub(r'[^a-z0-9]+',\
\ '-', discussion_name)\n\nos.makedirs(diagrams_dir, exist_ok=True)\n\nexisting\
\ = []\nif os.path.exists(diagrams_dir):\n for f in os.listdir(diagrams_dir):\n\
\ if f.startswith(discussion_name):\n existing.append(f)\n\n\
next_num = len(existing) + 1\ndiagram_path = diagrams_dir + \"/\" + discussion_name\
\ + \"_qa_\" + str(next_num) + \".puml\"\n"
output_var: diagram_path
- type: code
code: "import sys\nimport datetime as dt\ntimestamp = dt.datetime.now().strftime(\"\
%H:%M:%S\")\nfor msg in [f\"Phase: {current_phase}\", \"Calling AI provider...\"\
]:\n line = f\"[{timestamp}] [qa] {msg}\"\n print(line, file=sys.stderr)\n\
\ sys.stderr.flush()\n if log_file:\n with open(log_file, 'a') as\
\ f:\n f.write(line + \"\\n\")\n f.flush()\n"
output_var: _progress1
- type: prompt
prompt: "You are AI-QA (also known as Quinn), a quality assurance specialist who\
\ ensures\nsoftware is reliable, well-tested, and handles edge cases gracefully.\n\
\n## Your Role\n- Identify potential bugs and edge cases before they happen\n\
- Design comprehensive test strategies\n- Evaluate error handling and failure\
\ modes\n- Ensure testability of proposed implementations\n- Think about what\
\ could go wrong\n\n## Your Perspective\n- If it can break, it will break - in\
\ production, at 3 AM\n- Edge cases are where most bugs hide\n- Good error messages\
\ save hours of debugging\n- Tests are documentation that never goes stale\n-\
\ Prevention is cheaper than debugging\n\n## QA Checklist\n- Happy path testing\n\
- Error/exception handling\n- Boundary conditions (empty, null, max values)\n\
- Concurrency and race conditions\n- Integration points and failure modes\n- Rollback\
\ and recovery scenarios\n- Data validation and sanitization\n- Performance under\
\ load\n\n## Phase Context\n{phase_context}\n\n## Current Discussion\n{input}\n\
\n## Your Task\n{callout}\n\nFollow the phase instructions. Analyze from a quality\
\ assurance perspective.\nIdentify edge cases, failure modes, and testing requirements.\n\
\n## Response Format\nRespond with valid JSON only. Use \\n for newlines in strings:\n\
{{\n \"comment\": \"Your QA analysis...\\n\\nTest cases:\\n1. ...\\n2. ...\"\
,\n \"vote\": \"READY\" or \"CHANGES\" or \"REJECT\" or null,\n \"diagram\"\
: null\n}}\n\nVote meanings:\n- READY: Quality is assured, testable\n- CHANGES:\
\ Testing/quality improvements needed\n- REJECT: Untestable or high-risk implementation\n\
- null: Comment only, no vote change\n\nIf you have nothing meaningful to add,\
\ respond: {{\"sentinel\": \"NO_RESPONSE\"}}\n"
provider: gemini
output_var: response
- type: code
code: "import sys\nimport datetime as dt\ntimestamp = dt.datetime.now().strftime(\"\
%H:%M:%S\")\nline = f\"[{timestamp}] [qa] AI response received\"\nprint(line,\
\ file=sys.stderr)\nsys.stderr.flush()\nif log_file:\n with open(log_file,\
\ 'a') as f:\n f.write(line + \"\\n\")\n f.flush()\n"
output_var: _progress2
- type: code
code: "import re\njson_text = response.strip()\nif json_text.startswith('```'):\n\
\ code_block = re.search(r'```(?:json)?\\s*(\\{.*\\})\\s*```', json_text, re.DOTALL)\n\
\ if code_block:\n json_text = code_block.group(1).strip()\n"
output_var: json_text
- type: code
code: "import json\ntry:\n parsed = json.loads(json_text)\nexcept json.JSONDecodeError\
\ as e:\n fixed = json_text.replace('\\n', '\\\\n')\n try:\n parsed\
\ = json.loads(fixed)\n except json.JSONDecodeError:\n import re\n \
\ comment_match = re.search(r'\"comment\"\\s*:\\s*\"(.*?)\"(?=\\s*[,}])',\
\ json_text, re.DOTALL)\n vote_match = re.search(r'\"vote\"\\s*:\\s*(\"\
?\\w+\"?|null)', json_text)\n parsed = {\n \"comment\": comment_match.group(1).replace('\\\
n', ' ') if comment_match else \"Parse error\",\n \"vote\": vote_match.group(1).strip('\"\
') if vote_match else None\n }\n if parsed[\"vote\"] == \"null\"\
:\n parsed[\"vote\"] = None\ncomment = parsed.get(\"comment\", \"\"\
)\nvote = parsed.get(\"vote\")\n"
output_var: comment, vote
- type: code
code: 'import json
result = {"comment": comment, "vote": vote}
final_response = json.dumps(result)
'
output_var: final_response
output: '{final_response}'