Conversation
…am reliability (#44) Add the missing `content_index` field to `response.output_text.delta` SSE events so clients that validate against the OpenAI Responses API spec (e.g. ChatKit SDK) no longer fail with a Pydantic validation error. Also introduces SSE heartbeat keepalives, configurable stream timeout, and structured stream timing logs to improve reliability with slow backends. Closes #44 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add try/finally to _with_heartbeat() to cancel in-flight tasks and close the underlying async iterator on cancellation/exit - Guard against interval <= 0 to prevent tight heartbeat loops - Fix trailing whitespace and missing newline in config.py Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- S7497: Re-raise asyncio.CancelledError after cleanup instead of swallowing it - B110: Replace bare except/pass with logger.debug for aclose errors - S5806: Rename `aiter` to `inner` to avoid shadowing the builtin - S3776: Extract cleanup logic to _cleanup_heartbeat() to reduce cognitive complexity below threshold Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tories Add SkillManager that discovers, caches, and executes agent skills from a configurable directory. Skills follow the Claude Code standard (SKILL.md + scripts/ + references/). Each skill is exposed as a callable tool alongside MCP tools. Feature is off by default (SKILLS_ENABLED=false) with path confinement, no-shell execution, and configurable timeout for security. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Review Summary by QodoAdd agent skills execution engine with streaming reliability improvements
WalkthroughsDescription• Add SkillManager singleton for discovering and executing agent skills from configurable directory • Inject skill tools alongside MCP tools in chat completions and responses endpoints • Implement SSE heartbeat keepalives and configurable stream timeout for reliability • Add missing content_index field to streamed text delta events for OpenAI spec compliance • Implement path traversal protection and execution timeout for skill security Diagramflowchart LR
A["SKILLS_DIR"] -->|scan & parse| B["SkillManager"]
B -->|cache tools| C["skill_functions_cache"]
C -->|inject| D["Chat Completions"]
D -->|execute| E["Skill Scripts"]
E -->|return output| F["Tool Result"]
G["LLM Stream"] -->|_with_heartbeat| H["SSE Events"]
H -->|content_index| I["OutputTextDelta"]
File Changes1. src/open_responses_server/common/skill_manager.py
|
Code Review by Qodo
1. Skill failure logged success
|
There was a problem hiding this comment.
Pull request overview
Adds an Agent Skills execution engine that discovers local “skills” from SKILLS_DIR, exposes them as skill__<name> tools alongside MCP tools, and routes tool calls to server-side execution with configurable timeouts and SSE heartbeats.
Changes:
- Introduces
SkillManagerfor skill discovery, tool schema generation, and secure script execution (path confinement, no shell). - Injects skill tools into
/responsesand/v1/chat/completionsflows and adds routing to execute skill tools server-side. - Adds streaming controls (
STREAM_TIMEOUT, SSE heartbeat interval) and expands tests to cover new behavior.
Reviewed changes
Copilot reviewed 14 out of 15 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/open_responses_server/common/skill_manager.py |
Implements skill discovery, caching, and script execution for skill__* tools. |
src/open_responses_server/api_controller.py |
Starts/stops skills on app lifecycle; injects skill tools; adds SSE heartbeat wrapper. |
src/open_responses_server/responses_service.py |
Routes tool execution to MCP vs skills; adds content_index to deltas; improves stream timing logs. |
src/open_responses_server/chat_completions_service.py |
Adds skill tool routing in streaming and non-streaming tool-call handlers; uses STREAM_TIMEOUT. |
src/open_responses_server/common/config.py |
Adds streaming + skills env vars and logs them on startup. |
src/open_responses_server/common/llm_client.py |
Uses configurable STREAM_TIMEOUT for the shared HTTPX client. |
src/open_responses_server/models/responses_models.py |
Adds required content_index field to OutputTextDelta. |
tests/test_skill_manager.py |
Adds test suite for skill parsing, discovery, execution, traversal, and timeouts. |
tests/test_api_controller_endpoints.py |
Adds unit tests for the heartbeat wrapper. |
tests/test_responses_service.py |
Updates streaming delta expectations to include content_index. |
tests/test_chat_completions_service.py |
Updates error-message expectations for non-server tools. |
README.md |
Documents Agent Skills usage and security model. |
pyproject.toml |
Adds pyyaml>=6.0 dependency. |
uv.lock |
Locks pyyaml in dependency graph. |
.env.example |
Documents new streaming env vars. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…on script failure 1. Add skill tool injection in handle_chat_completions() alongside MCP tools, so skills are discoverable via /v1/chat/completions endpoint. 2. Raise RuntimeError on non-zero script exit instead of returning error string, so callers correctly log failures and error handling matches MCP pattern. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Reject symlinks pointing outside scripts/ during discovery (security). 2. Validate skill names against tool-name rules (alphanumeric/hyphens/underscores, max 64 chars). 3. Include stderr in output on successful execution (preserves warnings). 4. Add SKILLS_* vars to .env.example for discoverability. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|


Summary
SkillManagersingleton that discovers and executes agent skills from a configurable directory (SKILLS_DIR)SKILL.md(YAML frontmatter + instructions) +scripts/(executables) +references/(docs)skill__<name>) alongside MCP tools in both/responsesand/v1/chat/completionsendpointsSKILLS_ENABLED=false) with security controls: path confinement, no shell execution, executable check, configurable timeoutNew files
src/open_responses_server/common/skill_manager.py— core skill discovery, caching, and executiontests/test_skill_manager.py— 25 tests covering parsing, discovery, execution, path traversal, timeoutModified files
common/config.py— 3 new env vars (SKILLS_ENABLED,SKILLS_DIR,SKILLS_EXEC_TIMEOUT)api_controller.py— startup/shutdown hooks + skill tool injectionresponses_service.py— skill routing at all tool execution pointschat_completions_service.py— skill routing in streaming and non-streaming handlerspyproject.toml— addedpyyaml>=6.0dependencyREADME.md— Agent Skills documentation sectionTest plan
pytest tests/test_skill_manager.py)SKILLS_ENABLED=true, verify tool injection and execution🤖 Generated with Claude Code