fmt, fix
This commit is contained in:
@@ -145,7 +145,9 @@ def challenge_report_schema_errors(report: dict[str, Any]) -> list[str]:
|
||||
read = report.get("read")
|
||||
if isinstance(read, dict):
|
||||
missing_read = sorted(CHALLENGE_REPORT_READ_FIELDS.difference(read))
|
||||
errors.extend(f"missing challenge_report.read.{field}" for field in missing_read)
|
||||
errors.extend(
|
||||
f"missing challenge_report.read.{field}" for field in missing_read
|
||||
)
|
||||
for field in CHALLENGE_REPORT_READ_FIELDS.intersection(read):
|
||||
if not isinstance(read[field], bool):
|
||||
errors.append(f"challenge_report.read.{field} must be boolean")
|
||||
@@ -156,8 +158,7 @@ def challenge_report_schema_errors(report: dict[str, Any]) -> list[str]:
|
||||
if isinstance(attempts, dict):
|
||||
missing_attempts = sorted(CHALLENGE_REPORT_ATTEMPT_FIELDS.difference(attempts))
|
||||
errors.extend(
|
||||
f"missing challenge_report.attempts.{field}"
|
||||
for field in missing_attempts
|
||||
f"missing challenge_report.attempts.{field}" for field in missing_attempts
|
||||
)
|
||||
for field in CHALLENGE_REPORT_ATTEMPT_FIELDS.intersection(attempts):
|
||||
value = attempts[field]
|
||||
|
||||
@@ -467,7 +467,9 @@ def main(argv: list[str] | None = None) -> int:
|
||||
success_count = sum(
|
||||
1 for item in summaries if item["classification"] == "success"
|
||||
)
|
||||
print(json.dumps({"success_count": success_count, "trial_count": len(summaries)}))
|
||||
print(
|
||||
json.dumps({"success_count": success_count, "trial_count": len(summaries)})
|
||||
)
|
||||
return 0
|
||||
finally:
|
||||
if managed_server is not None:
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import html
|
||||
import json
|
||||
import threading
|
||||
import uuid
|
||||
import webbrowser
|
||||
from dataclasses import dataclass
|
||||
import html
|
||||
from http import HTTPStatus
|
||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||
from typing import ClassVar
|
||||
|
||||
@@ -113,8 +113,7 @@ def _render_markdown_report(payload: MarkdownInput) -> MarkdownOutput:
|
||||
"Actions:",
|
||||
]
|
||||
lines.extend(
|
||||
f"- {item.owner} | {item.task} | {item.due}"
|
||||
for item in report.action_items
|
||||
f"- {item.owner} | {item.task} | {item.due}" for item in report.action_items
|
||||
)
|
||||
lines.extend(["", "Risks:"])
|
||||
lines.extend(f"- {risk}" for risk in report.risks)
|
||||
|
||||
@@ -24,11 +24,7 @@ def validate_deployment_dependencies(
|
||||
|
||||
for logical_source, concrete_source in bindings.items():
|
||||
source = sources_by_id.get(logical_source)
|
||||
if (
|
||||
source is not None
|
||||
and source.platform
|
||||
and concrete_source != logical_source
|
||||
):
|
||||
if source is not None and source.platform and concrete_source != logical_source:
|
||||
diagnostics.append(
|
||||
DependencyDiagnostic(
|
||||
severity=DiagnosticSeverity.ERROR,
|
||||
|
||||
@@ -112,7 +112,9 @@ def reducer(
|
||||
def decorate_config(
|
||||
raw: ConfigReducerCallable[ConfigT],
|
||||
) -> AuthoredReducer:
|
||||
reducer_name = name or getattr(raw, "__name__", "<anonymous config reducer>")
|
||||
reducer_name = name or getattr(
|
||||
raw, "__name__", "<anonymous config reducer>"
|
||||
)
|
||||
reducer_description = description or raw.__doc__
|
||||
|
||||
model_type = config_model
|
||||
|
||||
@@ -22,6 +22,7 @@ def _parse_map_flags(values: list[str] | None) -> dict[str, str]:
|
||||
parsed[source] = target
|
||||
return parsed
|
||||
|
||||
|
||||
app = typer.Typer(
|
||||
name="draft",
|
||||
help="Create, inspect, patch, validate, and save draft workflows.",
|
||||
@@ -162,9 +163,7 @@ def set_draft_route(
|
||||
],
|
||||
step_id: Annotated[str, typer.Option("--step", help="Draft step id.")],
|
||||
outcome: Annotated[str, typer.Option("--outcome", help="Step outcome.")],
|
||||
target: Annotated[
|
||||
str, typer.Option("--to", help="Target step id or __end__.")
|
||||
],
|
||||
target: Annotated[str, typer.Option("--to", help="Target step id or __end__.")],
|
||||
) -> None:
|
||||
"""Set one route: steps.<step> outcome -> target."""
|
||||
context = load_cli_context(ctx)
|
||||
|
||||
@@ -148,5 +148,7 @@ def _source_capability_names(
|
||||
raise ValueError("source inventory missing capabilities object")
|
||||
value = capabilities.get(capability_key)
|
||||
if not isinstance(value, list):
|
||||
raise ValueError(f"source inventory capabilities.{capability_key} must be a list")
|
||||
raise ValueError(
|
||||
f"source inventory capabilities.{capability_key} must be a list"
|
||||
)
|
||||
return [str(item) for item in value]
|
||||
|
||||
@@ -124,7 +124,9 @@ class ContentAccessService:
|
||||
return _truncate_resource_payload(payload, max_chars=max_chars)
|
||||
|
||||
|
||||
def _truncate_resource_payload(payload: dict[str, Any], *, max_chars: int) -> dict[str, Any]:
|
||||
def _truncate_resource_payload(
|
||||
payload: dict[str, Any], *, max_chars: int
|
||||
) -> dict[str, Any]:
|
||||
"""Bound text content returned by source URI reads without mutating upstream payload."""
|
||||
|
||||
contents = payload.get("contents")
|
||||
|
||||
@@ -150,7 +150,9 @@ class SourceDiagnosticsProvider:
|
||||
"fetched_at_epoch_ms": None
|
||||
if snapshot is None
|
||||
else snapshot.fetched_at_epoch_ms,
|
||||
"max_age_seconds": None if snapshot is None else snapshot.max_age_seconds,
|
||||
"max_age_seconds": None
|
||||
if snapshot is None
|
||||
else snapshot.max_age_seconds,
|
||||
"node_count": 0 if snapshot is None else len(snapshot.nodes),
|
||||
"resource_count": 0 if snapshot is None else len(snapshot.resources),
|
||||
"prompt_count": 0 if snapshot is None else len(snapshot.prompts),
|
||||
|
||||
@@ -88,7 +88,13 @@ class WorkflowRuntimeService:
|
||||
deployment: WorkflowDeployment | None,
|
||||
artifact: WorkflowArtifact | None,
|
||||
saved_subgraph_tree: SavedSubgraphTree | None = None,
|
||||
) -> tuple[Workflow, dict[str, Any], dict[str, Any], dict[str, Any], SourceBindingPlatformContext]:
|
||||
) -> tuple[
|
||||
Workflow,
|
||||
dict[str, Any],
|
||||
dict[str, Any],
|
||||
dict[str, Any],
|
||||
SourceBindingPlatformContext,
|
||||
]:
|
||||
"""Resolve bindings once into the executable pieces core expects.
|
||||
|
||||
Saved-run resume still rebuilds prepared dependencies from the current
|
||||
|
||||
@@ -151,7 +151,13 @@ class LocalWorkflowRuntimeRunner(WorkflowRuntimeRunner):
|
||||
deployment: WorkflowDeployment | None,
|
||||
artifact: WorkflowArtifact | None,
|
||||
saved_subgraph_tree: SavedSubgraphTree | None = None,
|
||||
) -> tuple[Workflow, dict[str, Any], dict[str, Any], dict[str, Any], SourceBindingPlatformContext]:
|
||||
) -> tuple[
|
||||
Workflow,
|
||||
dict[str, Any],
|
||||
dict[str, Any],
|
||||
dict[str, Any],
|
||||
SourceBindingPlatformContext,
|
||||
]:
|
||||
plan_node_names = [
|
||||
node.node for node in plan.nodes if isinstance(node, NodeUse)
|
||||
]
|
||||
|
||||
@@ -186,7 +186,9 @@ class HttpxOAuthTokenRefresher:
|
||||
payload = response.json()
|
||||
access_token = payload.get("access_token")
|
||||
if not isinstance(access_token, str) or not access_token:
|
||||
raise ValueError("OAuth token refresh response did not include access_token")
|
||||
raise ValueError(
|
||||
"OAuth token refresh response did not include access_token"
|
||||
)
|
||||
expires_in = payload.get("expires_in")
|
||||
return OAuthAccessToken(
|
||||
access_token=access_token,
|
||||
@@ -232,7 +234,9 @@ class McpAuthBinder:
|
||||
if isinstance(auth, EnvAuth):
|
||||
raise ValueError("env auth is not supported for MCP HTTP")
|
||||
if isinstance(auth, OpaqueAuth):
|
||||
raise ValueError(f"opaque auth scheme {auth.scheme!r} is not supported for MCP HTTP")
|
||||
raise ValueError(
|
||||
f"opaque auth scheme {auth.scheme!r} is not supported for MCP HTTP"
|
||||
)
|
||||
raise TypeError(f"unsupported auth variant {type(auth).__name__}")
|
||||
|
||||
async def bind_stdio_auth(
|
||||
@@ -244,7 +248,9 @@ class McpAuthBinder:
|
||||
auth = record.auth
|
||||
if isinstance(auth, EnvAuth):
|
||||
return BoundMcpStdioAuth(env=dict(auth.env))
|
||||
if isinstance(auth, BearerAuth | HeaderAuth | OAuthRefreshTokenAuth | OpaqueAuth):
|
||||
if isinstance(
|
||||
auth, BearerAuth | HeaderAuth | OAuthRefreshTokenAuth | OpaqueAuth
|
||||
):
|
||||
raise ValueError(f"{auth.kind} auth is not supported for MCP stdio")
|
||||
raise TypeError(f"unsupported auth variant {type(auth).__name__}")
|
||||
|
||||
|
||||
@@ -16,7 +16,9 @@ from wf_sources_mcp.connections import McpSourceConnection
|
||||
from wf_sources_mcp.transports import HttpSourceTransport, StdioSourceTransport
|
||||
|
||||
|
||||
def _as_stored_auth(auth: AuthRecord | StoredAuthRecord | None) -> StoredAuthRecord | None:
|
||||
def _as_stored_auth(
|
||||
auth: AuthRecord | StoredAuthRecord | None,
|
||||
) -> StoredAuthRecord | None:
|
||||
if auth is None or isinstance(auth, StoredAuthRecord):
|
||||
return auth
|
||||
return auth_record_from_compat(
|
||||
|
||||
@@ -65,10 +65,10 @@ async def _list_optional_capabilities(
|
||||
root = _root_exception(exc)
|
||||
if isinstance(root, McpError) and root.error.code == METHOD_NOT_FOUND:
|
||||
return []
|
||||
if (
|
||||
isinstance(root, httpx.HTTPStatusError)
|
||||
and root.response.status_code in {400, 404}
|
||||
):
|
||||
if isinstance(root, httpx.HTTPStatusError) and root.response.status_code in {
|
||||
400,
|
||||
404,
|
||||
}:
|
||||
return []
|
||||
raise
|
||||
|
||||
|
||||
@@ -59,7 +59,9 @@ class AuthStore:
|
||||
def save_auth_record(self, record: NeutralAuthRecord | StoredAuthRecord) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def load_auth_record(self, auth_ref: str) -> NeutralAuthRecord | StoredAuthRecord | None:
|
||||
def load_auth_record(
|
||||
self, auth_ref: str
|
||||
) -> NeutralAuthRecord | StoredAuthRecord | None:
|
||||
raise NotImplementedError
|
||||
|
||||
def delete_auth(self, connection_id: str) -> bool:
|
||||
@@ -139,7 +141,9 @@ class FileAuthStore(AuthStore):
|
||||
else:
|
||||
self.save_auth(mcp_auth_from_neutral(record))
|
||||
|
||||
def load_auth_record(self, auth_ref: str) -> NeutralAuthRecord | StoredAuthRecord | None:
|
||||
def load_auth_record(
|
||||
self, auth_ref: str
|
||||
) -> NeutralAuthRecord | StoredAuthRecord | None:
|
||||
path = self._auth_path(auth_ref)
|
||||
if not path.exists():
|
||||
return None
|
||||
@@ -258,7 +262,9 @@ class FileStore(Store):
|
||||
def save_auth_record(self, record: NeutralAuthRecord | StoredAuthRecord) -> None:
|
||||
self._auth.save_auth_record(record)
|
||||
|
||||
def load_auth_record(self, auth_ref: str) -> NeutralAuthRecord | StoredAuthRecord | None:
|
||||
def load_auth_record(
|
||||
self, auth_ref: str
|
||||
) -> NeutralAuthRecord | StoredAuthRecord | None:
|
||||
return self._auth.load_auth_record(auth_ref)
|
||||
|
||||
def delete_auth(self, connection_id: str) -> bool:
|
||||
|
||||
@@ -43,8 +43,6 @@ def register_methods(
|
||||
params: DiagnoseSourceParams = RpcParams(),
|
||||
) -> dict[str, Any]:
|
||||
try:
|
||||
return await server.source_admin.diagnose_source(
|
||||
source_id=params.source_id
|
||||
)
|
||||
return await server.source_admin.diagnose_source(source_id=params.source_id)
|
||||
except (ValueError, KeyError, LookupError, FileNotFoundError) as exc:
|
||||
raise_workflow_rpc_error(exc)
|
||||
|
||||
@@ -68,7 +68,9 @@ def test_browser_click_source_human_timeout_cleans_up() -> None:
|
||||
assert _active_session_count() == 0
|
||||
|
||||
|
||||
EXAMPLE_DIR = Path(__file__).resolve().parents[2] / "examples" / "browser_click_workflow"
|
||||
EXAMPLE_DIR = (
|
||||
Path(__file__).resolve().parents[2] / "examples" / "browser_click_workflow"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -234,4 +236,3 @@ async def test_browser_click_workflow_artifact_deployment_run_path(tmp_path) ->
|
||||
assert run["output"]["after"]["status_text"] == "Button clicked"
|
||||
assert run["output"]["closed"] is True
|
||||
assert run["trace_count"] >= 3
|
||||
|
||||
|
||||
@@ -103,7 +103,9 @@ async def test_call_openapi_operation_maps_unexpected_status() -> None:
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_call_openapi_operation_maps_invalid_request_to_validation_error() -> None:
|
||||
async def test_call_openapi_operation_maps_invalid_request_to_validation_error() -> (
|
||||
None
|
||||
):
|
||||
app = load_openapi_app(FIXTURE)
|
||||
operation = next(
|
||||
op for op in load_openapi_operations(FIXTURE) if op.name == "create_pet"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from dataclasses import replace
|
||||
from pathlib import Path
|
||||
from typing import Any, cast
|
||||
@@ -98,6 +97,7 @@ def _deployment_api(
|
||||
context = context_from_service(service)
|
||||
return WorkflowDeploymentApi(context), service
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_save_deployment_stores_and_returns_stable_fields(tmp_path: Path) -> None:
|
||||
artifact_store = FileWorkflowArtifactStore(tmp_path / "deploy_save")
|
||||
@@ -108,9 +108,7 @@ async def test_save_deployment_stores_and_returns_stable_fields(tmp_path: Path)
|
||||
id="echo.personal",
|
||||
artifact_id="echo",
|
||||
artifact_version=1,
|
||||
bindings=[
|
||||
{"logical_source": "demo", "concrete_source": "demo.personal"}
|
||||
],
|
||||
bindings=[{"logical_source": "demo", "concrete_source": "demo.personal"}],
|
||||
).model_dump(mode="json")
|
||||
)
|
||||
|
||||
@@ -119,6 +117,7 @@ async def test_save_deployment_stores_and_returns_stable_fields(tmp_path: Path)
|
||||
assert result["artifact_id"] == "echo"
|
||||
assert result["artifact_version"] == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_deployments_returns_compact_summaries(tmp_path: Path) -> None:
|
||||
artifact_store = FileWorkflowArtifactStore(tmp_path / "deploy_list")
|
||||
@@ -141,7 +140,9 @@ async def test_list_deployments_returns_compact_summaries(tmp_path: Path) -> Non
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_deployments_returns_empty_without_artifact_store(tmp_path: Path) -> None:
|
||||
async def test_list_deployments_returns_empty_without_artifact_store(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
artifact_store = FileWorkflowArtifactStore(tmp_path / "deploy_no_store")
|
||||
_api, service = _deployment_api(artifact_store)
|
||||
context = replace(context_from_service(service), artifact_store=None)
|
||||
@@ -173,7 +174,9 @@ async def test_delete_deployment_removes_one(tmp_path: Path) -> None:
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_validate_deployment_returns_runnable_for_valid_binding(tmp_path: Path) -> None:
|
||||
async def test_validate_deployment_returns_runnable_for_valid_binding(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
artifact_store = FileWorkflowArtifactStore(tmp_path / "deploy_validate_runnable")
|
||||
api, service = _deployment_api(artifact_store, register_echo=True)
|
||||
artifact_store.save_artifact(_echo_artifact())
|
||||
@@ -186,7 +189,9 @@ async def test_validate_deployment_returns_runnable_for_valid_binding(tmp_path:
|
||||
)
|
||||
)
|
||||
|
||||
result = await api.validate_deployment(deployment_id="echo.personal", live_check=False)
|
||||
result = await api.validate_deployment(
|
||||
deployment_id="echo.personal", live_check=False
|
||||
)
|
||||
|
||||
assert result["status"] == "runnable"
|
||||
assert result["diagnostics"] == []
|
||||
@@ -202,7 +207,9 @@ class FailingLivenessAdapter:
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_validate_deployment_live_check_calls_live_checker(tmp_path: Path) -> None:
|
||||
async def test_validate_deployment_live_check_calls_live_checker(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
artifact_store = FileWorkflowArtifactStore(tmp_path / "deploy_validate_live")
|
||||
api, service = _deployment_api(artifact_store, register_echo=True)
|
||||
artifact_store.save_artifact(_echo_artifact())
|
||||
@@ -219,7 +226,9 @@ async def test_validate_deployment_live_check_calls_live_checker(tmp_path: Path)
|
||||
cast(BackendAdapter, FailingLivenessAdapter()),
|
||||
)
|
||||
|
||||
result = await api.validate_deployment(deployment_id="echo.personal", live_check=True)
|
||||
result = await api.validate_deployment(
|
||||
deployment_id="echo.personal", live_check=True
|
||||
)
|
||||
|
||||
assert result["status"] == "unrunnable"
|
||||
assert result["diagnostics"][0]["code"] == "source_unreachable"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
@@ -25,7 +25,9 @@ def test_platform_context_uses_identity_for_platform_sources() -> None:
|
||||
|
||||
|
||||
def test_platform_context_rejects_unbound_source() -> None:
|
||||
context = SourceBindingPlatformContext(source_bindings={}, read_resource_handler=None)
|
||||
context = SourceBindingPlatformContext(
|
||||
source_bindings={}, read_resource_handler=None
|
||||
)
|
||||
|
||||
with pytest.raises(KeyError, match="unbound logical source"):
|
||||
context.resolve_source("drive")
|
||||
|
||||
@@ -214,7 +214,9 @@ edges: []
|
||||
assert payload["source_bindings"] == {"local.ops": "local.ops"}
|
||||
|
||||
|
||||
def test_artifact_create_from_plan_rejects_non_object_yaml(monkeypatch, tmp_path) -> None:
|
||||
def test_artifact_create_from_plan_rejects_non_object_yaml(
|
||||
monkeypatch, tmp_path
|
||||
) -> None:
|
||||
handlers = _ArtifactHandlers()
|
||||
monkeypatch.setattr(
|
||||
"wf_cli.commands.artifacts.load_cli_context",
|
||||
|
||||
@@ -77,12 +77,16 @@ class _FakeOAuthClient:
|
||||
self.auth_kwargs: dict[str, object] = {}
|
||||
self.fetch_calls: list[str] = []
|
||||
|
||||
def create_authorization_url(self, auth_url: str, **kwargs: object) -> tuple[str, str]:
|
||||
def create_authorization_url(
|
||||
self, auth_url: str, **kwargs: object
|
||||
) -> tuple[str, str]:
|
||||
assert auth_url == "https://accounts.google.com/o/oauth2/v2/auth"
|
||||
self.auth_kwargs = dict(kwargs)
|
||||
return self.authorization_url, "state-123"
|
||||
|
||||
async def fetch_token(self, token_url: str, authorization_response: str) -> dict[str, object]:
|
||||
async def fetch_token(
|
||||
self, token_url: str, authorization_response: str
|
||||
) -> dict[str, object]:
|
||||
self.fetch_calls.append(authorization_response)
|
||||
return {
|
||||
"refresh_token": "refresh",
|
||||
@@ -144,7 +148,9 @@ async def test_oauth_code_login_flow_callback_can_supply_response() -> None:
|
||||
assert client.fetch_calls == ["http://127.0.0.1/callback?code=abc&state=state-123"]
|
||||
|
||||
|
||||
def test_auth_oauth_login_saves_record_from_provider_profile(monkeypatch, tmp_path) -> None:
|
||||
def test_auth_oauth_login_saves_record_from_provider_profile(
|
||||
monkeypatch, tmp_path
|
||||
) -> None:
|
||||
saved: list[dict[str, object]] = []
|
||||
|
||||
class _FakeAdmin:
|
||||
@@ -178,7 +184,9 @@ def test_auth_oauth_login_saves_record_from_provider_profile(monkeypatch, tmp_pa
|
||||
"auth_url": "https://accounts.google.com/o/oauth2/v2/auth",
|
||||
"token_url": "https://oauth2.googleapis.com/token",
|
||||
"client_id_env": "GOOGLE_OAUTH_CLIENT_ID",
|
||||
"scopes": ["https://www.googleapis.com/auth/drive.readonly"],
|
||||
"scopes": [
|
||||
"https://www.googleapis.com/auth/drive.readonly"
|
||||
],
|
||||
"extra_authorize_params": {
|
||||
"access_type": "offline",
|
||||
"prompt": "consent",
|
||||
|
||||
@@ -170,12 +170,12 @@ def test_wf_config_validate_uses_global_config_when_path_omitted(
|
||||
payload = json.loads(result.output)
|
||||
assert payload["valid"] is True
|
||||
assert payload["path"] == str(config_path)
|
||||
assert payload["sources"] == [
|
||||
{"id": "wf.std", "kind": "stdlib", "status": "ok"}
|
||||
]
|
||||
assert payload["sources"] == [{"id": "wf.std", "kind": "stdlib", "status": "ok"}]
|
||||
|
||||
|
||||
def test_wf_config_validate_reports_python_source_import_failure(tmp_path: Path) -> None:
|
||||
def test_wf_config_validate_reports_python_source_import_failure(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
config_path = tmp_path / "wf.config.json"
|
||||
config_path.write_text(
|
||||
json.dumps(
|
||||
|
||||
@@ -268,9 +268,7 @@ async def test_content_access_uses_stateful_runtime_for_upstream_content() -> No
|
||||
|
||||
|
||||
async def test_read_resource_by_source_uri_reads_upstream() -> None:
|
||||
service = WfMcpService(
|
||||
store=FileStore(local_temp_root() / "content_source_uri")
|
||||
)
|
||||
service = WfMcpService(store=FileStore(local_temp_root() / "content_source_uri"))
|
||||
service.register_connection(
|
||||
ConnectionConfig(id="demo.personal", server="demo", account="personal")
|
||||
)
|
||||
|
||||
@@ -20,7 +20,9 @@ def _connection(**metadata: object) -> ConnectionConfig:
|
||||
)
|
||||
|
||||
|
||||
def _provider(tmp_path: Path, connection: ConnectionConfig) -> SourceDiagnosticsProvider:
|
||||
def _provider(
|
||||
tmp_path: Path, connection: ConnectionConfig
|
||||
) -> SourceDiagnosticsProvider:
|
||||
registry = ConnectionRegistry()
|
||||
registry.register(connection)
|
||||
return SourceDiagnosticsProvider(
|
||||
|
||||
@@ -100,11 +100,13 @@ def test_workflow_runtime_service_prepares_node_registry_and_reducers() -> None:
|
||||
emit_event=lambda event: None,
|
||||
)
|
||||
|
||||
workflow, registry, reducers, prepared_subgraphs, platform_context = runtime.prepare_workflow_runtime(
|
||||
workflow, registry, reducers, prepared_subgraphs, platform_context = (
|
||||
runtime.prepare_workflow_runtime(
|
||||
single_echo_plan("runtime_prepare", "demo.personal.echo_tool"),
|
||||
deployment=None,
|
||||
artifact=None,
|
||||
)
|
||||
)
|
||||
|
||||
assert "demo.personal.echo_tool" in [nd.name for nd in workflow.node_defs]
|
||||
assert "demo.personal.echo_tool" in registry
|
||||
|
||||
@@ -129,7 +129,9 @@ def test_file_auth_store_writes_new_stored_auth_record_shape(tmp_path: Path) ->
|
||||
assert data["metadata"]["provider"] == "google"
|
||||
|
||||
|
||||
def test_file_auth_store_loads_old_format_through_load_auth_record(tmp_path: Path) -> None:
|
||||
def test_file_auth_store_loads_old_format_through_load_auth_record(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
store = FileAuthStore(tmp_path)
|
||||
path = tmp_path / "auth" / "github.work.json"
|
||||
path.write_text(
|
||||
|
||||
@@ -449,7 +449,9 @@ async def test_rpc_client_draft_workspace_focused_edit_methods(tmp_path) -> None
|
||||
server = build_local_static_workflow_server(tmp_path / "store")
|
||||
app = create_rpc_app(server)
|
||||
transport = httpx.ASGITransport(app=app)
|
||||
async with httpx.AsyncClient(transport=transport, base_url="http://test") as http_client:
|
||||
async with httpx.AsyncClient(
|
||||
transport=transport, base_url="http://test"
|
||||
) as http_client:
|
||||
client = RpcWorkflowApiClient(
|
||||
url="http://test/rpc",
|
||||
timeout_seconds=5,
|
||||
@@ -503,6 +505,4 @@ async def test_rpc_client_diagnoses_source(tmp_path) -> None:
|
||||
payload = await Client().diagnose_source(source_id="demo.personal")
|
||||
|
||||
assert payload == {"source_id": "demo.personal", "status": "ok"}
|
||||
assert calls == [
|
||||
("workflow.sources.diagnose", {"source_id": "demo.personal"})
|
||||
]
|
||||
assert calls == [("workflow.sources.diagnose", {"source_id": "demo.personal"})]
|
||||
|
||||
Reference in New Issue
Block a user