Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/src/create/NewAgentWorkbench.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ export function NewAgentWorkbench({
const [maxInstance, setMaxInstance] = useState(
sessionStorage === "in-memory" ? "1" : "5",
);
const [createEvaluationSets, setCreateEvaluationSets] = useState(true);
const [createEvaluationSets, setCreateEvaluationSets] = useState(false);
const [deployResources, setDeployResources] = useState<DeployResources>(
DEFAULT_DEPLOY_RESOURCES,
);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/ui/ProjectPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,7 @@ export function ProjectPreview({
const [maxInstance, setMaxInstance] = useState(
inMemorySession || sidecarEnabled ? "1" : "5",
);
const [createEvaluationSets, setCreateEvaluationSets] = useState(true);
const [createEvaluationSets, setCreateEvaluationSets] = useState(false);
const supportsEvaluationSets = cloudProvider !== "byteplus";
const effectiveCreateEvaluationSets =
supportsEvaluationSets && createEvaluationSets;
Expand Down
12 changes: 10 additions & 2 deletions frontend/tests/deploymentConfigUi.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ const customCreateSource = readFileSync(
new URL("../src/create/CustomCreate.tsx", import.meta.url),
"utf8",
);
const newAgentWorkbenchSource = readFileSync(
new URL("../src/create/NewAgentWorkbench.tsx", import.meta.url),
"utf8",
);
const agentTypeMetaSource = readFileSync(
new URL("../src/create/agentTypeMeta.tsx", import.meta.url),
"utf8",
Expand Down Expand Up @@ -428,10 +432,14 @@ test("requires explicit confirmation before starting deployment", () => {
);
});

test("creates feedback evaluation sets by default and sends the deployment choice", () => {
test("leaves feedback evaluation sets off by default in both deployment workbenches", () => {
assert.match(
projectPreviewSource,
/useState\(true\)[\s\S]*?projectPreview\.createEvaluationSets[\s\S]*?projectPreview\.createEvaluationSetsHint/,
/const \[createEvaluationSets, setCreateEvaluationSets\] = useState\(false\);/,
);
assert.match(
newAgentWorkbenchSource,
/const \[createEvaluationSets, setCreateEvaluationSets\] = useState\(false\);/,
);
assert.match(
projectPreviewSource,
Expand Down
152 changes: 152 additions & 0 deletions tests/cli/test_generated_agent_backend_codegen_extended.py
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,158 @@ async def fail_mcp_discovery(draft):
assert response.json()["detail"] == original_detail


@pytest.mark.parametrize(
(
"credential_storage",
"tool_name",
"edited_url",
"expected_status",
"expect_credential",
),
[
("reference-env", "jvmdiag", "https://8.8.8.8/mcp", 200, True),
("reference-env", "", "https://8.8.8.8/mcp", 200, True),
("servers-json", "jvmdiag", "https://8.8.8.8/mcp", 200, True),
("servers-json", "", "https://8.8.8.8/mcp", 200, True),
(
"servers-json",
"jvmdiag",
"https://8.8.8.8/changed-mcp",
422,
False,
),
],
)
def test_generated_debug_applies_published_mcp_credential_contract_before_discovery(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
credential_storage: str,
tool_name: str,
edited_url: str,
expected_status: int,
expect_credential: bool,
) -> None:
from agentkit.sdk.runtime.client import AgentkitRuntimeClient
from veadk.cli.generated_agent_mcp import McpDebugConnectionError

credential_reference = "MCP_LEGACY_AGENT_JVMDIAG_AUTH_TOKEN"
credential_value = "server-retained-debug-secret"
published_draft = {
"name": "legacy_agent",
"description": "Existing Agent",
"instruction": "Use the diagnostic MCP.",
"mcpTools": [
{
"name": tool_name,
"transport": "http",
"url": "https://8.8.8.8/mcp",
"authTokenEnv": credential_reference,
}
],
}
runtime_envs = [SimpleNamespace(key=credential_reference, value=credential_value)]
if credential_storage == "servers-json":
runtime_envs = [
SimpleNamespace(
key="MCP_SERVERS_JSON",
value=json.dumps(
[
{
"name": tool_name or "mcp",
"url": "https://8.8.8.8/mcp",
"headers": {"Authorization": f"Bearer {credential_value}"},
}
]
),
)
]
runtime = SimpleNamespace(
runtime_id="runtime-debug-mcp",
runtime_name="legacy-agent-runtime",
current_version_number=3,
tags=[],
envs=runtime_envs,
network_configurations=[
SimpleNamespace(
endpoint="https://runtime.example.com",
network_type="public",
)
],
authorizer_configuration=SimpleNamespace(
key_auth=SimpleNamespace(api_key="runtime-api-key"),
custom_jwt_authorizer=None,
),
)

monkeypatch.setattr(
AgentkitRuntimeClient,
"get_runtime",
lambda _self, _request: runtime,
)

captured_discovery_env: dict[str, str] = {}

async def capture_mcp_discovery(draft, env_values=None):
captured_discovery_env.update(env_values or {})
if not expect_credential:
raise McpDebugConnectionError("changed MCP endpoint rejected")
return draft

monkeypatch.setattr(
"veadk.cli.generated_agent_mcp.resolve_debug_mcp_endpoints",
capture_mcp_discovery,
)

class RuntimeDebugClient(_FakeAsyncClient):
async def request(self, _method: str, url: str, **_kwargs: Any):
if url.endswith("/list-apps"):
return _FakeResponse(json_data=["legacy_agent"])
if url.endswith("/web/agent-info/legacy_agent"):
return _FakeResponse(
json_data={
"name": "legacy_agent",
"description": "Existing Agent",
"draft": published_draft,
}
)
raise AssertionError(f"unexpected Runtime request path: {url}")

monkeypatch.setenv("_FAAS_FUNC_ID", "function-test")
app = _generated_debug_app(monkeypatch, tmp_path)
_FakeProcess.created.clear()
_FakeAsyncClient.listed_apps = ["legacy_agent"]
monkeypatch.setattr("subprocess.Popen", _FakeProcess)
monkeypatch.setattr("httpx.AsyncClient", RuntimeDebugClient)
real_socket = socket.socket
monkeypatch.setattr(
"socket.socket",
lambda *args, **kwargs: (
real_socket(*args, **kwargs)
if len(args) >= 4 or "fileno" in kwargs
else _FakeSocket(*args, **kwargs)
),
)

with TestClient(app) as client:
edited_draft = json.loads(json.dumps(published_draft))
edited_draft["mcpTools"][0]["url"] = edited_url
response = client.post(
"/web/generated-agent-test-runs",
json={
"draft": edited_draft,
"runtimeId": runtime.runtime_id,
"runtimeRegion": "cn-shanghai",
},
)

assert response.status_code == expected_status, response.text
if expect_credential:
assert captured_discovery_env[credential_reference] == credential_value
else:
assert credential_reference not in captured_discovery_env
assert credential_value not in response.text


def test_debug_text_redacts_environment_and_inline_markers(
monkeypatch: pytest.MonkeyPatch,
) -> None:
Expand Down
58 changes: 58 additions & 0 deletions tests/cli/test_studio_rbac.py
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,63 @@ async def initialize_evaluation_sets(**_kwargs: Any) -> list[str]:
assert os.environ.get("BYTEPLUS_ACCESS_KEY") is None


def test_volcengine_deploy_omits_feedback_evaluation_sets_by_default(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
) -> None:
evaluation_set_calls = 0

def launch(*, config_file: str, **_kwargs: Any) -> SimpleNamespace:
assert Path(config_file).is_file()
return SimpleNamespace(
success=True,
error=None,
deploy_result=SimpleNamespace(
endpoint_url="https://runtime.example.com",
metadata={
"runtime_id": "runtime-default-evaluation-off",
"runtime_name": "default-evaluation-off",
"runtime_endpoint": "https://runtime.example.com",
"runtime_apikey": "secret",
},
),
)

async def initialize_evaluation_sets(**_kwargs: Any) -> list[str]:
nonlocal evaluation_set_calls
evaluation_set_calls += 1
return ["unexpected"]

monkeypatch.setattr("agentkit.toolkit.sdk.launch", launch)
monkeypatch.setattr(
"frontend.server.evaluation_automation.datasets.ensure_feedback_sets",
initialize_evaluation_sets,
)
app = _create_studio_app(monkeypatch, tmp_path, developers="developer")

with TestClient(app) as client:
with client.stream(
"POST",
"/web/deploy-agentkit",
headers={"X-VeADK-Local-User": "developer"},
json={
"name": "default-evaluation-off",
"files": [{"path": "app.py", "content": "app = object()\n"}],
"config": {"region": "cn-beijing", "projectName": "default"},
},
) as response:
frames = [
json.loads(line.removeprefix("data: "))
for line in response.iter_lines()
if line.startswith("data: ")
]

assert response.status_code == 200
assert frames[-1]["success"] is True
assert not [frame for frame in frames if frame.get("phase") == "evaluation"]
assert evaluation_set_calls == 0


def test_migration_routes_require_agent_management_role(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
Expand Down Expand Up @@ -5442,6 +5499,7 @@ async def _mark_validated_oauth_token(request: Request, call_next):
"removeRuntimeEnvKeys": remove_runtime_env_keys,
"files": [{"path": "app.py", "content": "app = object()\n"}],
"config": {"region": region, "projectName": "default"},
"createEvaluationSets": True,
"authentication": {"type": "api_key"},
"im": {"feishu": {"enabled": not remove_feishu_credentials}},
"envs": requested_envs,
Expand Down
Loading
Loading