Skip to content

Refactor Wingman class#387

Merged
Shackless merged 34 commits into
developfrom
refactor/wingman-modular-providers
Apr 13, 2026
Merged

Refactor Wingman class#387
Shackless merged 34 commits into
developfrom
refactor/wingman-modular-providers

Conversation

@Shackless

Copy link
Copy Markdown
Contributor

Claude called it a "Monolithic god class" before. Now it's less of that.

Shackless and others added 30 commits April 9, 2026 10:47
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ator registry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move all message-list management (add/update/trim tool responses, user/
assistant message helpers, history cleanup, token estimation, reset, and
text-extraction utilities) into a standalone ConversationManager class.
The original OpenAiWingman is unchanged; wiring happens in M5.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… ConversationCondenser, ContextBuilder, ToolExecutor)
Absorb all orchestration from OpenAiWingman into the unified Wingman
class. Provider routing is now handled by ProviderFactory which creates
SttInterface, TtsInterface, and LlmInterface instances. Conversation
management, condensation, context building, and tool execution are
delegated to the extracted services.

open_ai_wingman.py is reduced to a backward-compatibility shim that
re-exports Wingman as OpenAiWingman so existing skills, tower, and
custom wingmen continue to work without modification.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All skills now receive WingmanContext (controlled API surface) instead
of the raw Wingman instance. voice_changer and radio_chatter provider
pre-initialization removed — ProviderFactory handles it at switch time
via switch_tts_provider().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Parakeet's runtime auto-detect re-flipped manual CPU choices to CUDA on
every startup and persisted "cuda" even when ONNX Runtime fell back to
CPU. Move Parakeet into the same once-per-version hardware scan as
FasterWhisper so manual choices stick after the first run.

Also fix the misleading "Parakeet initialized with providers: [...]" log
that printed the requested provider list instead of what was actually
loadable, making CPU fallback look like CUDA success.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move command/action execution out of the unified Wingman class into
a focused service. Covers get_command, instant activation matching,
command execution, and the keyboard/mouse/joystick action dispatcher.

Part of the post-merge cleanup to make wingman.py more navigable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move MCP discovery, enable/disable, and connection orchestration out
of the unified Wingman class. The manager now owns the McpRegistry
and the secret/header/timeout handling for connecting to servers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move skill discovery, init, enable/disable, and prepare/unprepare
logic out of the unified Wingman class. Dedupe the ~50 lines of
yaml-loading + override-merging + platform-checking shared between
init_skills and enable_skill into private helpers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Drop the per-call skills/skill_registry/tool_skills kwargs from
ConversationManager methods. WingmanSkillManager now pushes the
current skill state into the conversation via set_skill_context()
after every init/enable/disable, eliminating the wrapper cluster
in Wingman that was just forwarding skill state on every call.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move per-turn benchmark snapshot building and token-usage broadcast
into a focused service. Local-LLM token-count fallback and the
formatting helpers move with them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move generic instant-filler generation (the LLM-driven phrase list
used during long tool calls) into a focused service. The JSON-retry
loop and the random-non-repeating selection logic move with it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
build_tools() becomes a 17-line orchestrator. The execute_command
tool definition lives in CommandExecutor; the persistent-memory
tool definitions live in PersistentMemoryService. Wingman just
asks each source for its tools.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Stop instantiating a fresh WingmanSubscription on every generate_image
call. The subscription is created lazily on first use and reused.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wingman.threaded_execution is now a one-line wrapper around the free
function in services/threading_utils.py. The wrapper is kept because
WingmanSkillManager binds it onto every skill instance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 13, 2026 09:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the Wingman orchestration layer by consolidating the previous Wingman/OpenAiWingman split into a unified Wingman class and extracting major subsystems into focused services (providers, conversation, tools, commands, skills, MCP).

Changes:

  • Introduces unified provider interfaces (SttInterface/TtsInterface/LlmInterface) and a ProviderFactory for config-driven provider instantiation.
  • Extracts Wingman responsibilities into services (conversation management/condensation, tool execution, command execution, metrics, skill & MCP managers).
  • Adds a restricted WingmanContext facade for skills and updates many skills to type against it; also renames Wingman Pro provider wrapper to WingmanSubscription.

Reviewed changes

Copilot reviewed 62 out of 63 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
wingmen/wingman.py Unified Wingman orchestrator delegating providers/services; adds new lifecycle, tool-loop, config/settings update paths.
wingmen/wingman_context.py New restricted facade passed into skills; includes helper APIs and TTS hot-swap.
wingman_core.py Uses WingmanSubscription; adds GUI mic toggle endpoints to start/stop recording per wingman.
skills/voice_changer/main.py Switches to WingmanContext typing; uses facade switch_tts_provider.
skills/vision_ai/main.py Updates Wingman type hints to WingmanContext.
skills/uexcorp/uexcorp/helper.py Updates Wingman type hints to WingmanContext.
skills/uexcorp/uexcorp/handler/config_handler.py Updates Wingman type hints to WingmanContext.
skills/uexcorp/main.py Updates Wingman type hints to WingmanContext.
skills/typing_assistant/main.py Updates Wingman type hints to WingmanContext.
skills/timer/main.py Updates Wingman type hints to WingmanContext.
skills/thinking_sound/main.py Updates Wingman type hints to WingmanContext.
skills/spotify/main.py Updates Wingman type hints to WingmanContext.
skills/skill_base.py Updates base skill typing to accept WingmanContext.
skills/README.md Updates documentation examples (but currently not aligned with WingmanContext facade).
skills/radio_chatter/main.py Updates Wingman type hints to WingmanContext; uses facade switch_tts_provider.
skills/quick_commands/main.py Updates Wingman type hints to WingmanContext.
skills/msfs2020_control/main.py Updates Wingman type hints to WingmanContext.
skills/image_generation/main.py Updates Wingman type hints to WingmanContext.
skills/hud/main.py Updates Wingman type hints to WingmanContext.
skills/file_manager/main.py Updates Wingman type hints to WingmanContext.
skills/control_windows/main.py Updates Wingman type hints to WingmanContext.
skills/auto_screenshot/main.py Updates Wingman type hints to WingmanContext.
skills/audio_device_changer/main.py Updates Wingman type hints to WingmanContext.
skills/ats_telemetry/main.py Updates Wingman type hints to WingmanContext.
skills/api_request/main.py Updates Wingman type hints to WingmanContext.
skills/AGENTS.md Updates skill authoring docs (but currently not aligned with WingmanContext facade).
services/wingman_skill_manager.py New skill discovery/lifecycle manager; instantiates skills with WingmanContext.
services/wingman_mcp_manager.py New MCP lifecycle/registry manager with secret injection + timeouts.
services/voice_service.py Replaces WingmanPro usage with WingmanSubscription.
services/turn_metrics.py New per-turn benchmarking + token usage broadcaster.
services/tower.py Simplifies wingman instantiation path (removes dynamic custom-class wingman creation).
services/tool_executor.py New tool-call dispatcher (skills/MCP/commands/memory/capabilities).
services/threading_utils.py Extracted helper for running callables/coroutines in daemon threads.
services/stt_provider_manager.py Removes Parakeet auto-detection helper (shifted to config hardware scan).
services/skill_local_ai.py Updates typing to WingmanContext.
services/provider_factory.py New factory that creates providers from enums + secrets + adapter registry.
services/platform_utils.py New shared normalize_platform() helper.
services/persistent_memory.py Exposes persistent-memory tool definitions for LLM calls.
services/module_manager.py Removes dynamic custom wingman creation helper; keeps skill loader.
services/instant_response_generator.py New service to generate & serve generic filler phrases.
services/conversation_manager.py New conversation state manager (messages, tool responses, trimming, history cleanup).
services/conversation_condenser.py New background condensation service using local AI support model.
services/context_builder.py New system prompt/context assembly (skills, summary, memory injection).
services/config_service.py Uses normalize_platform() for skill filtering.
services/config_manager.py Extends hardware scan to configure Parakeet execution provider and CPU fallback messaging.
services/command_executor.py Extracted command matching + action execution (keyboard/mouse/etc.) and tool schema creation.
services/benchmark.py Extracts format_ms() helper used by benchmarks/metrics.
providers/xvasynth.py Adds TTS adapter implementing TtsInterface + provider registration.
providers/x_ai.py Adds LLM adapter implementing LlmInterface + provider registration.
providers/wingman_subscription.py Renames WingmanProWingmanSubscription; adds STT/TTS/LLM adapters.
providers/whispercpp.py Adds STT adapter implementing SttInterface + provider registration.
providers/pocket_tts.py Adds TTS adapter implementing TtsInterface + provider registration.
providers/parakeet.py Improves provider selection logging; adds STT adapter + provider registration.
providers/open_ai.py Adds STT/TTS/LLM adapter classes + provider registration for many providers.
providers/inworld.py Adds TTS adapter + provider registration.
providers/interfaces.py New unified provider interfaces + registries/decorators.
providers/hume.py Adds TTS adapter + provider registration.
providers/google.py Adds LLM adapter + provider registration.
providers/faster_whisper.py Adds STT adapter + provider registration and hotword aggregation.
providers/elevenlabs.py Adds TTS adapter + provider registration.
providers/edge.py Adds TTS adapter + provider registration.
docs/parakeet-issues.md Removes Parakeet issues doc.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread wingmen/wingman.py
Comment thread wingmen/wingman.py
Comment thread wingmen/wingman.py
Comment thread wingmen/wingman_context.py
Comment thread wingmen/wingman_context.py
Comment thread services/context_builder.py Outdated
Comment thread services/tower.py
Comment thread skills/README.md
Comment thread skills/README.md
Comment thread skills/AGENTS.md
- Fix inverted no_interrupt boolean in tool-call loop play_to_user call
- Propagate config/settings updates to all extracted services (not just command_executor/skills)
- Roll back tts_provider config on failed provider creation
- Guard config_dir access in WingmanContext.get_context() matching Wingman's own guard
- Fix persistent memory tool names in context instructions (remember→memory_remember, etc.)
- Update skill docs to use WingmanContext type instead of Wingman

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 62 out of 63 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread services/tool_executor.py
Comment thread wingmen/wingman.py
Comment thread wingmen/wingman.py
Comment thread wingmen/wingman_context.py
Comment thread wingmen/wingman_context.py
Comment thread services/conversation_condenser.py Outdated
Comment thread services/instant_response_generator.py Outdated
- Fix duplicate tool response in exception path (update existing instead of adding new)
- Propagate config/settings to WingmanSkillManager in update_config/update_settings
- Delegate WingmanContext.add_user_message to Wingman wrapper (preserves memory reset + condensation)
- Clarify get_conversation_history docstring (shallow copy, not truly read-only)
- Remove "include all secrets" from condensation prompt to prevent leaking sensitive data
- Fix typo and improve JSON retry prompt in instant response generator

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 62 out of 63 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread services/conversation_condenser.py
Comment thread services/tool_executor.py
Comment thread wingmen/wingman.py
Comment thread wingmen/wingman_context.py Outdated
Comment thread services/provider_factory.py Outdated
- Fix chunked condensation prompt to also exclude secrets (missed in round 2)
- Fix dict[str, any] → dict[str, Any] type annotations in tool_executor and wingman
- Rename WingmanContext.retrieve_secret param from requester to secret_name to match API
- Move blocking requests.get to asyncio.to_thread in provider_factory OpenRouter check

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Shackless Shackless merged commit 63ecc32 into develop Apr 13, 2026
1 check failed
@Shackless Shackless deleted the refactor/wingman-modular-providers branch April 13, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants