Release 0.12.0a1 - #49
Open
github-actions[bot] wants to merge 36 commits into
Open
Conversation
chore: Configure Renovate
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
* chore: migrate setup.py→pyproject.toml, consolidate CI workflows Replace setup.py with pyproject.toml (dynamic version from version.py). Add build_tests, license_tests, lint, pip_audit workflows using OpenVoiceOS/gh-automations@dev reusable workflows. Migrate publish_stable and release_workflow from TigreGotico/gh-automations@master to OpenVoiceOS/gh-automations@dev; add workflow_dispatch trigger and bot-safety guard. split from #25 * fix: define __version__ attr required by pyproject dynamic version * test: guard dynamic-version contract (version.py ↔ __version__ fields) Asserts VERSION_* integers are non-negative, __version__ is correctly derived from them, and the string matches PEP-440 format. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…t in chat.py (#40) * fix: declare uvicorn+ovos-workshop deps; restore py3.9 compat in chat.py Fixes #39 (partial — OPM lang-detector fallback fix in ovos-lang-detector-classics-plugin, see fix/issue-39-cld2-exception branch there) (a) Add uvicorn and ovos-workshop to [project].dependencies in pyproject.toml. Both are imported at runtime (__main__.py and ollama.py respectively) but were not declared, causing ImportError in clean environments. (b) Replace two multi-line f-string expressions in streaming_completion_response (chat.py lines ~285 and ~302) with intermediate dict variables. Multi-line dict literals inside f-string {} require Python 3.12 (PEP 701) but the package declares requires-python >= 3.9. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Delete tests/test_issue_39.py --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…aths (#29) * feat: vendor-prefixed OpenAI/Ollama routers + deprecated legacy paths * test: cover deprecated paths middleware and route registration (split/router-infra) - Verify Deprecation + Link headers on /v1 and /api legacy paths - Verify canonical paths receive no deprecation headers - Cover _build_successor_path mapping and passthrough - Cover FastAPI 422 responses for malformed/missing bodies - Smoke-test register_deprecated_routes mounts /v1/ legacy paths Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: normalize Google-style docstrings in chat and ollama routers Remove ``(Type)`` annotations from Args/Returns sections (redundant with function signatures). Condense multi-line boilerplate docstrings on lifespan managers and inner streaming generators to one-liners. No logic changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat: A2A server endpoint (/a2a) with agent card + executor * test: full A2A server coverage — agent card, executor, cancel, SDK-absent path, invalid base_url Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: improve OVOSPersonaAgentExecutor.__init__ docstring Add summary sentence to the __init__ docstring; no logic changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
) * feat(compat): Anthropic Claude-compatible endpoints (/anthropic/v1) * test: full Anthropic compat coverage — schema, multi-turn, system, streaming, errors Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: real-SDK e2e against live server + enable CI test execution Add tests/e2e/test_e2e_anthropic.py driving the official anthropic SDK (Anthropic(base_url=...)) against a live uvicorn-served app, covering non-streaming, system prompt, multi-turn and streaming. Add anthropic to the dev extra and wire build_tests.yml to install it and run the suite. * test: use asyncio.run in A2A executor tests (py3.14 compatibility) asyncio.get_event_loop() raises on Python 3.14 (and whenever a prior test closes the main-thread loop); switch the A2A executor tests to asyncio.run so the suite is loop-state independent. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat(compat): Google Gemini-compatible endpoints (/gemini/v1beta) * test: full Gemini compat coverage — schema, multi-turn, system-instruction, streaming, errors Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: real-SDK e2e against live server + enable CI test execution Add tests/e2e/test_e2e_gemini.py driving the official google-genai SDK (genai.Client(http_options=HttpOptions(base_url=...))) against a live uvicorn-served app, covering non-streaming, system instruction, multi-turn and streaming. Add google-genai to the dev extra and wire build_tests.yml to install it and run the suite. * test: use asyncio.run in A2A executor tests (py3.14 compatibility) asyncio.get_event_loop() raises on Python 3.14 (and whenever a prior test closes the main-thread loop); switch the A2A executor tests to asyncio.run so the suite is loop-state independent. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat(compat): AWS Bedrock-compatible endpoints (/bedrock/model) * test: full AWS Bedrock compat coverage — all model families, invoke, stream, converse, schema errors Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(compat): emit AWS event-stream framing for Bedrock streaming invoke-with-response-stream now encodes vnd.amazon.eventstream binary frames (prelude/headers/payload with CRC32 checksums) instead of SSE, so boto3's invoke_model_with_response_stream parses the stream natively. Add tests/e2e/test_e2e_bedrock.py driving the official boto3 bedrock-runtime client (invoke_model for Claude + Titan, converse, streaming). Add boto3 to the dev extra and wire build_tests.yml to run the suite. * test(compat): decode Bedrock stream as event-stream frames in unit tests Update the invoke-with-response-stream unit tests to decode the vnd.amazon.eventstream binary framing via botocore's EventStreamBuffer, matching the streaming format boto3 consumes. * test: use asyncio.run in A2A executor tests (py3.14 compatibility) asyncio.get_event_loop() raises on Python 3.14 (and whenever a prior test closes the main-thread loop); switch the A2A executor tests to asyncio.run so the suite is loop-state independent. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat(compat): HuggingFace TGI-compatible endpoints (/tgi) * test: full TGI compat coverage — schema, generate, streaming, info/health, errors Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(compat): serve TGI generation at endpoint root for InferenceClient The maintained huggingface_hub InferenceClient posts to the bare endpoint URL and selects streaming via the body 'stream' flag; add a root dispatch route delegating to the shared non-streaming/streaming handlers so the official client works against the server unchanged. Add tests/e2e/test_e2e_tgi.py driving InferenceClient (non-stream, details, stream) plus /health, /info and the native /generate route. Add huggingface_hub to the dev extra and wire build_tests.yml to run the suite. * test: use asyncio.run in A2A executor tests (py3.14 compatibility) asyncio.get_event_loop() raises on Python 3.14 (and whenever a prior test closes the main-thread loop); switch the A2A executor tests to asyncio.run so the suite is loop-state independent. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat(compat): Cohere-compatible endpoints (/cohere/v1) * test: full Cohere compat coverage — schema, multi-turn, preamble, streaming, embed, errors Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: real-SDK e2e against live server + enable CI test execution Add tests/e2e/test_e2e_cohere.py driving the official cohere SDK (cohere.Client(base_url=...)) against a live uvicorn-served app, covering /v1/chat (with preamble + history), /v1/generate and streaming chat. Add cohere to the dev extra and wire build_tests.yml to install it and run the suite. * test: use asyncio.run in A2A executor tests (py3.14 compatibility) asyncio.get_event_loop() raises on Python 3.14 (and whenever a prior test closes the main-thread loop); switch the A2A executor tests to asyncio.run so the suite is loop-state independent. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat: expose OPM tool plugins via MCP and UTCP
Discovers all installed ToolBox plugins (opm.agents.toolbox entry-point
group) at startup and surfaces each tool over two protocols:
- UTCP: GET /tools/manual returns a machine-readable manual; POST
/tools/{name} invokes a tool with a JSON body.
- MCP: when the [mcp] extra is installed, an SSE MCP server is mounted at
/mcp; a standalone stdio server is available as ovos-persona-tools-mcp.
Adds ovos_persona_server/tools.py (discovery + flat registry),
ovos_persona_server/mcp_server.py ([mcp] extra), ovos_persona_server/utcp.py
(UTCP router), 21 pytest unit tests, setup.py [mcp] extra + console script,
and README docs with client config examples.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test: add e2e tests for MCP and UTCP tool endpoints; add CI workflow
Boots a minimal FastAPI app wired to the UTCP router and (when mcp is
installed) a standalone MCP Starlette server, both with an empty tool
registry. Exercises GET /tools/manual structure, 404 on unknown tool, MCP
initialize → list_tools handshake.
CI: new build-tests.yml using gh-automations@dev with install_extras='mcp'
and test_path='tests'. setup.py gains [test] extra for pytest/httpx/uvicorn.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test: deepen coverage for tools, UTCP and MCP on feat/expose-tools-mcp-utcp
- Cover name-collision prefixing (both entries qualified)
- Cover refresh_tools exception silencing
- Cover registry=None fallback in invoke_tool and list_tool_schemas
- Cover OPM-absent _load_toolboxes empty-list path
- Cover UTCP 500 error path and empty-registry manual response
- Cover MCP handler success and error JSON return
- Cover build_mcp_server with no plugins
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(mcp): working mounted transport — path override + chained lifespan
The previous mount used sse_app() with fallback to streamable_http_app()
without (a) overriding FastMCP's default /mcp sub-path (so the endpoint
was at /mcp/mcp) and (b) chaining the MCP session manager into the host
app lifespan (Starlette does not propagate lifespan to mounted sub-apps,
so every /mcp request 500d). Add mount_mcp_on_app() that does both fixes
and update __init__.py and the e2e test to use it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(mcp): add mount_mcp_on_app with path override and lifespan chain
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: python<3.12 compatible f-strings in completion streaming
Nested same-quote expressions inside multi-line f-strings are 3.12+ syntax;
they made the package unimportable on 3.11 (server could not start).
Payload dicts extracted to locals before interpolation.
* test: use asyncio.run in A2A executor tests; consolidate CI workflow
The A2A executor tests used asyncio.get_event_loop().run_until_complete,
which raises once another test closes the main-thread loop; switch to
asyncio.run so the full suite is order-independent. Remove the duplicate
build-tests.yml and run the suite (dev,mcp extras) from build_tests.yml.
* fix: require ovos-plugin-manager>=2.4.0a1 for AgentTool/ToolBox templates
The tool-plugin layer uses ovos_plugin_manager.templates.agent_tools and
PluginTypes.AGENT_TOOLBOX, introduced in ovos-plugin-manager 2.4.0a1. Pin
that prerelease floor so the published dependency carries the templates and
the tool tests run against them.
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Human review requested!