chore(conductor): Archive track 'Add support for the deepseek api as a provider.'

This commit is contained in:
2026-02-25 23:34:46 -05:00
parent f2b29a06d5
commit d030897520
12 changed files with 235 additions and 19 deletions

View File

@@ -0,0 +1,5 @@
# Track deepseek_support_20260225 Context
- [Specification](./spec.md)
- [Implementation Plan](./plan.md)
- [Metadata](./metadata.json)

View File

@@ -0,0 +1,8 @@
{
"track_id": "deepseek_support_20260225",
"type": "feature",
"status": "new",
"created_at": "2026-02-25T00:00:00Z",
"updated_at": "2026-02-25T00:00:00Z",
"description": "Add support for the deepseek api as a provider."
}

View File

@@ -0,0 +1,27 @@
# Implementation Plan: DeepSeek API Provider Support
## Phase 1: Infrastructure & Common Logic [checkpoint: 0ec3720]
- [x] Task: Initialize MMA Environment `activate_skill mma-orchestrator` 1b3ff23
- [x] Task: Update `credentials.toml` schema and configuration logic in `project_manager.py` to support `deepseek` 1b3ff23
- [x] Task: Define the `DeepSeekProvider` interface in `ai_client.py` and align with existing provider patterns 1b3ff23
- [x] Task: Conductor - User Manual Verification 'Infrastructure & Common Logic' (Protocol in workflow.md) 1b3ff23
## Phase 2: DeepSeek API Client Implementation
- [x] Task: Write failing tests for `DeepSeekProvider` model selection and basic completion
- [x] Task: Implement `DeepSeekProvider` using the dedicated SDK
- [x] Task: Write failing tests for streaming and tool calling parity in `DeepSeekProvider`
- [x] Task: Implement streaming and tool calling logic for DeepSeek models
- [x] Task: Conductor - User Manual Verification 'DeepSeek API Client Implementation' (Protocol in workflow.md)
## Phase 3: Reasoning Traces & Advanced Capabilities
- [x] Task: Write failing tests for reasoning trace capture in `DeepSeekProvider` (DeepSeek-R1)
- [x] Task: Implement reasoning trace processing and integration with discussion history
- [x] Task: Write failing tests for token estimation and cost tracking for DeepSeek models
- [x] Task: Implement token usage tracking according to DeepSeek pricing
- [x] Task: Conductor - User Manual Verification 'Reasoning Traces & Advanced Capabilities' (Protocol in workflow.md)
## Phase 4: GUI Integration & Final Verification
- [x] Task: Update `gui_2.py` and `theme_2.py` (if necessary) to include DeepSeek in the provider selection UI
- [x] Task: Implement automated regression tests for the full DeepSeek lifecycle (prompt, streaming, tool call, reasoning)
- [x] Task: Verify overall performance and UI responsiveness with the new provider
- [x] Task: Conductor - User Manual Verification 'GUI Integration & Final Verification' (Protocol in workflow.md)

View File

@@ -0,0 +1,31 @@
# Specification: DeepSeek API Provider Support
## Overview
Implement a new AI provider module to support the DeepSeek API within the Manual Slop application. This integration will leverage a dedicated SDK to provide access to high-performance models (DeepSeek-V3 and DeepSeek-R1) with support for streaming, tool calling, and detailed reasoning traces.
## Functional Requirements
- **Dedicated SDK Integration:** Utilize a DeepSeek-specific Python client for API interactions.
- **Model Support:** Initial support for `deepseek-v3` (general performance) and `deepseek-r1` (reasoning).
- **Core Features:**
- **Streaming:** Support real-time response generation for a better user experience.
- **Tool Calling:** Integrate with Manual Slop's existing tool/function execution framework.
- **Reasoning Traces:** Capture and display reasoning paths if provided by the model (e.g., DeepSeek-R1).
- **Configuration Management:**
- Add `[deepseek]` section to `credentials.toml` for `api_key`.
- Update `config.toml` to allow selecting DeepSeek as the active provider.
## Non-Functional Requirements
- **Parity:** Maintain consistency with existing Gemini and Anthropic provider implementations in `ai_client.py`.
- **Error Handling:** Robust handling of API rate limits and connection issues specific to DeepSeek.
- **Observability:** Track token usage and costs according to DeepSeek's pricing model.
## Acceptance Criteria
- [ ] User can select "DeepSeek" as a provider in the GUI.
- [ ] Successful completion of prompts using both DeepSeek-V3 and DeepSeek-R1 models.
- [ ] Tool calling works correctly for standard operations (e.g., `read_file`).
- [ ] Reasoning traces from R1 are captured and visible in the discussion history.
- [ ] Streaming responses function correctly without blocking the GUI.
## Out of Scope
- Support for OpenAI-compatible proxies for DeepSeek in this initial track.
- Automated fine-tuning or custom model endpoints.

View File

@@ -40,8 +40,3 @@ This file tracks all major tracks for the project. Each track has its own detail
---
- [x] **Track: Add support for the deepseek api as a provider.**
*Link: [./tracks/deepseek_support_20260225/](./tracks/deepseek_support_20260225/)*
---

View File

@@ -1,6 +1,6 @@
[ai]
provider = "gemini"
model = "gemini-2.5-flash-lite"
provider = "deepseek"
model = "deepseek-chat"
temperature = 0.0
max_tokens = 8192
history_trunc_limit = 8000

17
fix_task.toml Normal file
View File

@@ -0,0 +1,17 @@
role = "tier3-worker"
prompt = """FIX DeepSeek implementation in ai_client.py.
CONTEXT:
Several tests in @tests/test_deepseek_provider.py are failing (returning '(No text returned by the model)') because the current implementation of '_send_deepseek' in @ai_client.py forces 'stream=True' and expects SSE format, but the test mocks provide standard JSON responses.
TASK:
1. Modify '_send_deepseek' in @ai_client.py to handle the response correctly whether it is a stream or a standard JSON response.
- You should probably determine this based on the 'stream' value in the payload (which is currently hardcoded to True, but the implementation should be flexible).
- If 'stream' is True, use the iter_lines() logic to aggregate chunks.
- If 'stream' is False, use resp.json() to get the content.
2. Fix the 'NameError: name 'data' is not defined' and ensure 'usage' is correctly extracted.
3. Ensure 'full_content', 'full_reasoning' (thinking tags), and 'tool_calls' are correctly captured and added to the conversation history in both modes.
4. Ensure all tests in @tests/test_deepseek_provider.py pass.
OUTPUT: Provide the raw Python code for the modified '_send_deepseek' function."""
docs = ["ai_client.py", "tests/test_deepseek_provider.py"]

View File

@@ -79,7 +79,7 @@ DockId=0x0000000F,2
[Window][Theme]
Pos=0,17
Size=588,400
Size=588,545
Collapsed=0
DockId=0x00000005,1
@@ -96,7 +96,7 @@ DockId=0x0000000E,0
[Window][Context Hub]
Pos=0,17
Size=588,400
Size=588,545
Collapsed=0
DockId=0x00000005,0
@@ -119,14 +119,14 @@ Collapsed=0
DockId=0x0000000E,1
[Window][Files & Media]
Pos=0,419
Size=588,781
Pos=0,564
Size=588,636
Collapsed=0
DockId=0x00000006,1
[Window][AI Settings]
Pos=0,419
Size=588,781
Pos=0,564
Size=588,636
Collapsed=0
DockId=0x00000006,0
@@ -140,8 +140,8 @@ DockSpace ID=0xAFC85805 Window=0x079D3A04 Pos=0,17 Size=1680,1183 Sp
DockNode ID=0x0000000B Parent=0x00000003 SizeRef=404,1186 Split=Y Selected=0xF4139CA2
DockNode ID=0x00000002 Parent=0x0000000B SizeRef=1029,1119 Split=X Selected=0xF4139CA2
DockNode ID=0x00000007 Parent=0x00000002 SizeRef=588,858 Split=Y Selected=0x8CA2375C
DockNode ID=0x00000005 Parent=0x00000007 SizeRef=295,400 Selected=0xF4139CA2
DockNode ID=0x00000006 Parent=0x00000007 SizeRef=295,781 CentralNode=1 Selected=0x7BD57D6A
DockNode ID=0x00000005 Parent=0x00000007 SizeRef=295,545 Selected=0xF4139CA2
DockNode ID=0x00000006 Parent=0x00000007 SizeRef=295,636 CentralNode=1 Selected=0x7BD57D6A
DockNode ID=0x0000000E Parent=0x00000002 SizeRef=530,858 Selected=0x418C7449
DockNode ID=0x00000001 Parent=0x0000000B SizeRef=1029,775 Selected=0x8B4EBFA6
DockNode ID=0x0000000D Parent=0x00000003 SizeRef=435,1186 Selected=0x363E93D6

View File

@@ -229,6 +229,74 @@ def get_file_summary(path: str) -> str:
return f"ERROR summarising '{path}': {e}"
def get_python_skeleton(path: str) -> str:
"""
Returns a skeleton of a Python file (preserving docstrings, stripping function bodies).
"""
p, err = _resolve_and_check(path)
if err:
return err
if not p.exists():
return f"ERROR: file not found: {path}"
if not p.is_file() or p.suffix != ".py":
return f"ERROR: not a python file: {path}"
try:
# Use mma_exec's generator if possible, or a local simplified version
# For now, we will use a dedicated script or just inline logic here.
# Given we have tree-sitter already installed in the env...
import tree_sitter
import tree_sitter_python
code = p.read_text(encoding="utf-8")
PY_LANGUAGE = tree_sitter.Language(tree_sitter_python.language())
parser = tree_sitter.Parser(PY_LANGUAGE)
tree = parser.parse(bytes(code, "utf8"))
edits = []
def is_docstring(node):
if node.type == "expression_statement" and node.child_count > 0:
if node.children[0].type == "string":
return True
return False
def walk(node):
if node.type == "function_definition":
body = node.child_by_field_name("body")
if body and body.type == "block":
indent = " " * body.start_point.column
first_stmt = None
for child in body.children:
if child.type != "comment":
first_stmt = child
break
if first_stmt and is_docstring(first_stmt):
start_byte = first_stmt.end_byte
end_byte = body.end_byte
if end_byte > start_byte:
edits.append((start_byte, end_byte, f"\\n{indent}..."))
else:
start_byte = body.start_byte
end_byte = body.end_byte
edits.append((start_byte, end_byte, "..."))
for child in node.children:
walk(child)
walk(tree.root_node)
edits.sort(key=lambda x: x[0], reverse=True)
code_bytes = bytearray(code, "utf8")
for start, end, replacement in edits:
code_bytes[start:end] = bytes(replacement, "utf8")
return code_bytes.decode("utf8")
except Exception as e:
return f"ERROR generating skeleton for '{path}': {e}"
# ------------------------------------------------------------------ web tools
@@ -355,7 +423,7 @@ def get_ui_performance() -> str:
# ------------------------------------------------------------------ tool dispatch
TOOL_NAMES = {"read_file", "list_directory", "search_files", "get_file_summary", "web_search", "fetch_url", "get_ui_performance"}
TOOL_NAMES = {"read_file", "list_directory", "search_files", "get_file_summary", "get_python_skeleton", "web_search", "fetch_url", "get_ui_performance"}
def dispatch(tool_name: str, tool_input: dict) -> str:
@@ -370,6 +438,8 @@ def dispatch(tool_name: str, tool_input: dict) -> str:
return search_files(tool_input.get("path", ""), tool_input.get("pattern", "*"))
if tool_name == "get_file_summary":
return get_file_summary(tool_input.get("path", ""))
if tool_name == "get_python_skeleton":
return get_python_skeleton(tool_input.get("path", ""))
if tool_name == "web_search":
return web_search(tool_input.get("query", ""))
if tool_name == "fetch_url":
@@ -458,6 +528,25 @@ MCP_TOOL_SPECS = [
"required": ["path"],
},
},
{
"name": "get_python_skeleton",
"description": (
"Get a skeleton view of a Python file. "
"This returns all classes and function signatures with their docstrings, "
"but replaces function bodies with '...'. "
"Use this to understand module interfaces without reading the full implementation."
),
"parameters": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the .py file.",
}
},
"required": ["path"],
},
},
{
"name": "web_search",
"description": "Search the web using DuckDuckGo. Returns the top 5 search results with titles, URLs, and snippets. Chain this with fetch_url to read specific pages.",
@@ -472,6 +561,20 @@ MCP_TOOL_SPECS = [
"required": ["query"]
}
},
{
"name": "fetch_url",
"description": "Fetch the full text content of a URL (stripped of HTML tags). Use this after web_search to read relevant information from the web.",
"parameters": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "The full URL to fetch."
}
},
"required": ["url"]
}
},
{
"name": "get_ui_performance",
"description": "Get a snapshot of the current UI performance metrics, including FPS, Frame Time (ms), CPU usage (%), and Input Lag (ms). Use this to diagnose UI slowness or verify that your changes haven't degraded the user experience.",

3
sanity_task.toml Normal file
View File

@@ -0,0 +1,3 @@
role = "tier3-worker"
prompt = "Read @ai_client.py and describe the current placeholder implementation of _send_deepseek. Just a one-sentence summary."
docs = ["ai_client.py"]

17
task.toml Normal file
View File

@@ -0,0 +1,17 @@
role = "tier3-worker"
prompt = """TASK: Implement streaming support for the DeepSeek provider in ai_client.py and add failing tests.
INSTRUCTIONS:
1. In @tests/test_deepseek_provider.py:
- Add a test function 'test_deepseek_streaming' that mocks a streaming API response using 'requests.post(..., stream=True)'.
- Use 'mock_response.iter_lines()' to simulate chunks of data.
- Assert that 'ai_client.send()' correctly aggregates these chunks into a single string.
2. In @ai_client.py:
- Modify the '_send_deepseek' function to use 'requests.post(..., stream=True)'.
- Implement a loop to iterate over the response lines using 'iter_lines()'.
- Aggregate the content from each chunk.
- Ensure the aggregated content is added to the history and returned by the function.
OUTPUT: Provide the raw Python code for the modified sections or the full files. No pleasantries."""
docs = ["conductor/workflow.md", "ai_client.py", "tests/test_deepseek_provider.py", "mcp_client.py"]

View File

@@ -4,10 +4,20 @@ roles = [
"Vendor API",
"System",
]
active = "main"
active = "testing deepseek"
auto_add = true
[discussions.main]
git_commit = ""
last_updated = "2026-02-25T21:55:15"
history = []
last_updated = "2026-02-25T23:33:11"
history = [
"@2026-02-25T22:34:11\nSystem:\n[PERFORMANCE ALERT] CPU usage high: 92.2%. Please consider optimizing recent changes or reducing load.",
]
[discussions."testing deepseek"]
git_commit = ""
last_updated = "2026-02-25T23:33:45"
history = [
"@2026-02-25T23:33:21\nUser:\ntesting testing 123?",
"@2026-02-25T23:33:25\nAI:\nI see you're testing with \"testing testing 123\". I'm here and ready to help! I'm a helpful coding assistant with access to PowerShell and various tools for file operations and web access.\n\nWhat would you like me to help you with today? I can assist with:\n- Writing or editing code files\n- Searching for information\n- Reading or analyzing files\n- Running commands\n- Web searches\n- And much more!\n\nJust let me know what you need help with.",
]