-
Notifications
You must be signed in to change notification settings - Fork 0
chore: sync workflow templates #149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,365 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env python3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Format raw issue text into the AGENT_ISSUE_TEMPLATE structure. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Run with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| python scripts/langchain/issue_formatter.py --input-file issue.md --output-file formatted.md | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from __future__ import annotations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import argparse | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import os | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import re | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import sys | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from pathlib import Path | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from typing import Any | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ISSUE_FORMATTER_PROMPT = """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| You are a formatting assistant. Convert the raw GitHub issue body into the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AGENT_ISSUE_TEMPLATE format with the exact section headers in order: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Why | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Scope | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Non-Goals | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Tasks | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Acceptance Criteria | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Implementation Notes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Rules: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Use bullet points ONLY in Tasks and Acceptance Criteria. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Every task/criterion must be specific, verifiable, and sized for ~10 minutes. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Use unchecked checkboxes: "- [ ]". | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Preserve file paths and concrete details when mentioned. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - If a section lacks content, use "_Not provided._" (or "- [ ] _Not provided._" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for Tasks/Acceptance). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Output ONLY the formatted markdown with these sections (no extra commentary). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Raw issue body: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {issue_body} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """.strip() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PROMPT_PATH = Path(__file__).resolve().parent / "prompts" / "format_issue.md" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FEEDBACK_PROMPT_PATH = Path(__file__).resolve().parent / "prompts" / "format_issue_feedback.md" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SECTION_ALIASES = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "why": ["why", "motivation", "summary", "goals"], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "scope": ["scope", "background", "context", "overview"], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "non_goals": ["non-goals", "nongoals", "out of scope", "constraints", "exclusions"], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "tasks": ["tasks", "task list", "tasklist", "todo", "to do", "implementation"], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "tasks": ["tasks", "task list", "tasklist", "todo", "to do", "implementation"], | |
| "tasks": ["tasks", "task list", "tasklist", "todo", "to do"], |
Copilot
AI
Jan 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The import from tools.llm_provider is not protected by error handling. If langchain_openai is available but tools.llm_provider cannot be imported, this will raise an uncaught ImportError. This import should be wrapped in a try-except block, or the function should return None if the import fails.
| from tools.llm_provider import DEFAULT_MODEL, GITHUB_MODELS_BASE_URL | |
| try: | |
| from tools.llm_provider import DEFAULT_MODEL, GITHUB_MODELS_BASE_URL | |
| except ImportError: | |
| return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolve missing llm_provider import in formatter
The new CLI tries to import DEFAULT_MODEL and GITHUB_MODELS_BASE_URL from tools.llm_provider, but that module does not exist anywhere in the repo (checked with rg "llm_provider"). When GITHUB_TOKEN or OPENAI_API_KEY is set and langchain_openai is installed, _get_llm_client will raise ModuleNotFoundError before it can fall back to the non‑LLM formatter, so scripts/langchain/issue_formatter.py crashes instead of emitting formatted output or JSON. Please vendor the missing module or guard the import so the formatter can run.
Useful? React with 👍 / 👎.
Copilot
AI
Jan 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Variable client_info is not used.
| client_info = None | |
| # langchain not available; fall back to non-LLM formatting below | |
| pass |
Copilot
AI
Jan 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The LLM invocation at this line is not wrapped in error handling. If the API call fails due to network issues, rate limiting, or other errors, the exception will propagate and crash the program instead of falling back to the non-LLM formatter. Consider wrapping this in a try-except block to catch exceptions and fall through to the fallback formatter.
| prompt = _load_prompt() | |
| template = ChatPromptTemplate.from_template(prompt) | |
| chain = template | client | |
| response = chain.invoke({"issue_body": issue_body}) | |
| content = getattr(response, "content", None) or str(response) | |
| formatted = content.strip() | |
| if _formatted_output_valid(formatted): | |
| return { | |
| "formatted_body": formatted, | |
| "provider_used": provider, | |
| "used_llm": True, | |
| } | |
| try: | |
| prompt = _load_prompt() | |
| template = ChatPromptTemplate.from_template(prompt) | |
| chain = template | client | |
| response = chain.invoke({"issue_body": issue_body}) | |
| content = getattr(response, "content", None) or str(response) | |
| formatted = content.strip() | |
| if _formatted_output_valid(formatted): | |
| return { | |
| "formatted_body": formatted, | |
| "provider_used": provider, | |
| "used_llm": True, | |
| } | |
| except Exception: | |
| # On any LLM-related error, fall back to the non-LLM formatter. | |
| pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The removal of
.toLowerCase()makes this comparison case-sensitive, which will cause it to fail if the verification status is not already lowercase. Thenormalisefunction only trims whitespace but doesn't convert to lowercase. Since the comparison array contains lowercase strings ('done', 'verified', 'complete'), the status should be normalized to lowercase for consistent comparison.