mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-08-29 04:26:38 +00:00
fix(python-sdk): make runtime readiness explicit
This commit is contained in:
@@ -149,6 +149,7 @@ MCP_SERVER_SCRIPT = """\
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
||||
log_path = os.environ.get("MCP_SMOKE_LOG")
|
||||
@@ -179,6 +180,10 @@ for line in sys.stdin:
|
||||
},
|
||||
})
|
||||
elif method == "tools/list":
|
||||
# Keep discovery pending longer than the old smoke's 100 ms grace
|
||||
# period. An SDK runtime that answers initialize too early will make
|
||||
# its first model request without this tool and fail deterministically.
|
||||
time.sleep(0.25)
|
||||
send({
|
||||
"jsonrpc": "2.0",
|
||||
"id": request_id,
|
||||
@@ -255,20 +260,6 @@ def mcp_cordis(server_script: Path) -> str:
|
||||
], indent=2)
|
||||
|
||||
|
||||
def wait_for_mcp_discovery(log_path: Path) -> None:
|
||||
"""Wait until the external server has answered initial tool discovery."""
|
||||
deadline = time.monotonic() + 10
|
||||
while time.monotonic() < deadline:
|
||||
if log_path.exists() and "tools/list" in log_path.read_text().splitlines():
|
||||
# The server records the request before flushing its response; give the
|
||||
# client one scheduler interval to register the returned generation.
|
||||
time.sleep(0.1)
|
||||
return
|
||||
time.sleep(0.025)
|
||||
observed = log_path.read_text() if log_path.exists() else "<no MCP requests>"
|
||||
raise AssertionError(f"packaged MCP client did not complete tool discovery: {observed}")
|
||||
|
||||
|
||||
class MockModelHandler(BaseHTTPRequestHandler):
|
||||
"""Return deterministic text, worker, and orchestration completions."""
|
||||
|
||||
@@ -861,7 +852,6 @@ def smoke_sdk_mcp(base_url: str, executable: Path | None) -> None:
|
||||
base_url=base_url,
|
||||
request_timeout_seconds=60,
|
||||
) as harness:
|
||||
wait_for_mcp_discovery(discovery_log)
|
||||
result = harness.run(MCP_PROMPT, session_id="mcp-smoke")
|
||||
|
||||
assert result.final_response == MCP_TEXT, result.final_response
|
||||
|
||||
@@ -99,6 +99,23 @@ describe('verifyRuntimeClosure', () => {
|
||||
expect(result.failures).toEqual([])
|
||||
})
|
||||
|
||||
it('requires preset plugins to be linked from the workspace', async () => {
|
||||
const root = fixture({
|
||||
'python/sdk-runtime/package.json': { name: 'runtime', dependencies: { '@scope/plugin': '1.2.3' } },
|
||||
'python/sdk-runtime/platforms.json': platforms,
|
||||
'apps/cli/config/agent-presets/standard/agent.cordis.yml': `
|
||||
- id: plugin
|
||||
name: '@scope/plugin'
|
||||
`,
|
||||
})
|
||||
|
||||
const result = await verifyRuntimeClosure(root)
|
||||
|
||||
expect(result.failures).toEqual([
|
||||
'standard preset -> @scope/plugin [runtime dependency is "1.2.3"; expected workspace:] (linux-arm64, linux-x64, macos-arm64)',
|
||||
])
|
||||
})
|
||||
|
||||
it('fails when no shipped preset is discovered', async () => {
|
||||
const root = fixture({
|
||||
'python/sdk-runtime/package.json': { name: 'runtime', dependencies: {} },
|
||||
|
||||
@@ -133,9 +133,13 @@ async function missingPresetPlugins(
|
||||
for (const target of targets) {
|
||||
const processPlatform = processPlatformForTarget(target)
|
||||
for (const plugin of activeBarePluginPackages(document, processPlatform)) {
|
||||
if (runtimeDependencies[plugin] !== undefined) continue
|
||||
const version = runtimeDependencies[plugin]
|
||||
if (version?.startsWith('workspace:') === true) continue
|
||||
const preset = basename(dirname(presetPath))
|
||||
const key = `${preset} preset -> ${plugin}`
|
||||
const declaration = version === undefined
|
||||
? ''
|
||||
: ` [runtime dependency is ${JSON.stringify(version)}; expected workspace:]`
|
||||
const key = `${preset} preset -> ${plugin}${declaration}`
|
||||
const targets = missing.get(key) ?? new Set<string>()
|
||||
targets.add(target)
|
||||
missing.set(key, targets)
|
||||
|
||||
Reference in New Issue
Block a user