mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:20:43 +00:00
test(release): harden Windows smoke model setup
This commit is contained in:
@@ -129,7 +129,7 @@ run_flow() {
|
||||
local doctor_expected="$5"
|
||||
local install_log="/tmp/openclaw-doctor-switch-${name}-install.log"
|
||||
local doctor_log="/tmp/openclaw-doctor-switch-${name}-doctor.log"
|
||||
local command_timeout="${OPENCLAW_DOCKER_DOCTOR_SWITCH_COMMAND_TIMEOUT:-300s}"
|
||||
local command_timeout="${OPENCLAW_DOCKER_DOCTOR_SWITCH_COMMAND_TIMEOUT:-900s}"
|
||||
|
||||
echo "== Flow: $name =="
|
||||
openclaw_test_state_create "switch-${name}" empty
|
||||
@@ -175,7 +175,7 @@ run_proxy_env_flow() {
|
||||
local name="proxy-env-cleanup"
|
||||
local install_log="/tmp/openclaw-doctor-switch-${name}-install.log"
|
||||
local doctor_log="/tmp/openclaw-doctor-switch-${name}-doctor.log"
|
||||
local command_timeout="${OPENCLAW_DOCKER_DOCTOR_SWITCH_COMMAND_TIMEOUT:-300s}"
|
||||
local command_timeout="${OPENCLAW_DOCKER_DOCTOR_SWITCH_COMMAND_TIMEOUT:-900s}"
|
||||
|
||||
echo "== Flow: $name =="
|
||||
openclaw_test_state_create "switch-${name}" empty
|
||||
@@ -216,7 +216,7 @@ run_wrapper_flow() {
|
||||
local env_repair_log="/tmp/openclaw-doctor-switch-${name}-env-repair.log"
|
||||
local doctor_log="/tmp/openclaw-doctor-switch-${name}-doctor.log"
|
||||
local clear_log="/tmp/openclaw-doctor-switch-${name}-clear.log"
|
||||
local command_timeout="${OPENCLAW_DOCKER_DOCTOR_SWITCH_COMMAND_TIMEOUT:-300s}"
|
||||
local command_timeout="${OPENCLAW_DOCKER_DOCTOR_SWITCH_COMMAND_TIMEOUT:-900s}"
|
||||
|
||||
echo "== Flow: $name =="
|
||||
openclaw_test_state_create "switch-${name}" empty
|
||||
|
||||
@@ -2,10 +2,13 @@ import { posixAgentWorkspaceScript, windowsAgentWorkspaceScript } from "./agent-
|
||||
import { shellQuote } from "./host-command.ts";
|
||||
import {
|
||||
psSingleQuote,
|
||||
windowsModelProviderTimeoutScript,
|
||||
windowsAgentTurnConfigPatchScript,
|
||||
windowsOpenClawResolver,
|
||||
} from "./powershell.ts";
|
||||
import { modelProviderConfigBatchJson } from "./provider-auth.ts";
|
||||
import {
|
||||
modelProviderConfigBatchJson,
|
||||
resolveParallelsModelTimeoutSeconds,
|
||||
} from "./provider-auth.ts";
|
||||
import type { Platform, ProviderAuth } from "./types.ts";
|
||||
|
||||
export interface NpmUpdateScriptInput {
|
||||
@@ -201,10 +204,7 @@ if ($LASTEXITCODE -ne 0) {
|
||||
"gateway restart exited with code $LASTEXITCODE; probing readiness before failing" | Out-Host
|
||||
}
|
||||
Wait-OpenClawGateway
|
||||
Invoke-OpenClaw models set ${psSingleQuote(input.auth.modelId)}
|
||||
${windowsModelProviderTimeoutScript(input.auth.modelId)}
|
||||
Invoke-OpenClaw config set agents.defaults.skipBootstrap true --strict-json
|
||||
Invoke-OpenClaw config set tools.profile minimal
|
||||
${windowsAgentTurnConfigPatchScript(input.auth.modelId)}
|
||||
$sessionPath = Join-Path $env:USERPROFILE '.openclaw\\agents\\main\\sessions\\parallels-npm-update-windows.jsonl'
|
||||
Remove-Item $sessionPath -Force -ErrorAction SilentlyContinue
|
||||
${windowsAgentWorkspaceScript("Parallels npm update smoke test assistant.")}
|
||||
@@ -215,7 +215,7 @@ for ($attempt = 1; $attempt -le 2; $attempt++) {
|
||||
$sessionsDir = Join-Path $env:USERPROFILE '.openclaw\\agents\\main\\sessions'
|
||||
$sessionPath = Join-Path $sessionsDir "$sessionId.jsonl"
|
||||
Remove-Item $sessionPath -Force -ErrorAction SilentlyContinue
|
||||
$output = Invoke-OpenClaw agent --local --agent main --session-id $sessionId --message 'Reply with exact ASCII text OK only.' --thinking minimal --json 2>&1
|
||||
$output = Invoke-OpenClaw agent --local --agent main --session-id $sessionId --model ${psSingleQuote(input.auth.modelId)} --message 'Reply with exact ASCII text OK only.' --thinking minimal --timeout ${resolveParallelsModelTimeoutSeconds("windows")} --json 2>&1
|
||||
if ($null -ne $output) { $output | ForEach-Object { $_ } }
|
||||
if ($LASTEXITCODE -ne 0) { throw "agent failed with exit code $LASTEXITCODE" }
|
||||
if (($output | Out-String) -match '"finalAssistant(Raw|Visible)Text":\\s*"OK"') {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
configPathMapKey,
|
||||
modelProviderConfigBatchJson,
|
||||
providerIdFromModelId,
|
||||
providerTimeoutConfigJson,
|
||||
} from "./provider-auth.ts";
|
||||
@@ -49,6 +50,56 @@ Remove-Item $providerTimeoutBatchPath -Force -ErrorAction SilentlyContinue
|
||||
if ($providerTimeoutExit -ne 0) { throw "model provider timeout config set failed" }`;
|
||||
}
|
||||
|
||||
export function windowsAgentTurnConfigPatchScript(modelId: string): string {
|
||||
const batchJson = modelProviderConfigBatchJson(modelId, "windows");
|
||||
const payloadJson = JSON.stringify({
|
||||
modelId,
|
||||
operations: batchJson ? (JSON.parse(batchJson) as unknown) : [],
|
||||
});
|
||||
return `$agentTurnConfigPatchPath = $env:OPENCLAW_CONFIG_PATH
|
||||
if (-not $agentTurnConfigPatchPath) { $agentTurnConfigPatchPath = Join-Path $env:USERPROFILE '.openclaw\\openclaw.json' }
|
||||
$env:OPENCLAW_PARALLELS_AGENT_CONFIG_PATCH = @'
|
||||
${payloadJson}
|
||||
'@
|
||||
$env:OPENCLAW_PARALLELS_AGENT_CONFIG_PATH = $agentTurnConfigPatchPath
|
||||
node.exe -e @'
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const configPath = process.env.OPENCLAW_PARALLELS_AGENT_CONFIG_PATH;
|
||||
const payload = JSON.parse(process.env.OPENCLAW_PARALLELS_AGENT_CONFIG_PATCH || "{}");
|
||||
const cfg = fs.existsSync(configPath) ? JSON.parse(fs.readFileSync(configPath, "utf8")) : {};
|
||||
cfg.agents = cfg.agents && typeof cfg.agents === "object" ? cfg.agents : {};
|
||||
cfg.agents.defaults = cfg.agents.defaults && typeof cfg.agents.defaults === "object" ? cfg.agents.defaults : {};
|
||||
cfg.agents.defaults.skipBootstrap = true;
|
||||
const existingModel = cfg.agents.defaults.model && typeof cfg.agents.defaults.model === "object" ? cfg.agents.defaults.model : {};
|
||||
cfg.agents.defaults.model = { ...existingModel, primary: payload.modelId };
|
||||
cfg.agents.defaults.models = cfg.agents.defaults.models && typeof cfg.agents.defaults.models === "object" ? cfg.agents.defaults.models : {};
|
||||
cfg.tools = cfg.tools && typeof cfg.tools === "object" ? cfg.tools : {};
|
||||
cfg.tools.profile = "minimal";
|
||||
for (const op of payload.operations || []) {
|
||||
const segments = String(op.path || "").match(/(?:[^.[\\]]+)|(?:\\["((?:\\\\.|[^"\\\\])*)"\\])/g) || [];
|
||||
let cursor = cfg;
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
const raw = segments[i];
|
||||
const key = raw.startsWith("[") ? JSON.parse(raw.slice(1, -1)) : raw;
|
||||
if (i === segments.length - 1) {
|
||||
const existing = cursor[key] && typeof cursor[key] === "object" && !Array.isArray(cursor[key]) ? cursor[key] : {};
|
||||
cursor[key] = op.value && typeof op.value === "object" && !Array.isArray(op.value) ? { ...existing, ...op.value } : op.value;
|
||||
} else {
|
||||
cursor[key] = cursor[key] && typeof cursor[key] === "object" && !Array.isArray(cursor[key]) ? cursor[key] : {};
|
||||
cursor = cursor[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
||||
fs.writeFileSync(configPath, JSON.stringify(cfg, null, 2) + "\\n", { mode: 0o600 });
|
||||
'@
|
||||
$agentTurnConfigPatchExit = $LASTEXITCODE
|
||||
Remove-Item Env:OPENCLAW_PARALLELS_AGENT_CONFIG_PATCH -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item Env:OPENCLAW_PARALLELS_AGENT_CONFIG_PATH -Force -ErrorAction SilentlyContinue
|
||||
if ($agentTurnConfigPatchExit -ne 0) { throw "agent turn config patch failed" }`;
|
||||
}
|
||||
|
||||
export const windowsOpenClawResolver = String.raw`function Resolve-OpenClawCommand {
|
||||
if ($script:OpenClawResolvedCommand) { return $script:OpenClawResolvedCommand }
|
||||
$shimCandidates = @()
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
resolveHostIp,
|
||||
resolveHostPort,
|
||||
resolveLatestVersion,
|
||||
resolveParallelsModelTimeoutSeconds,
|
||||
resolveWindowsProviderAuth,
|
||||
resolveSnapshot,
|
||||
run,
|
||||
@@ -36,7 +37,7 @@ import { PhaseRunner } from "./phase-runner.ts";
|
||||
import {
|
||||
encodePowerShell,
|
||||
psSingleQuote,
|
||||
windowsModelProviderTimeoutScript,
|
||||
windowsAgentTurnConfigPatchScript,
|
||||
windowsOpenClawResolver,
|
||||
} from "./powershell.ts";
|
||||
import { ensureGuestGit, prepareMinGitZip } from "./windows-git.ts";
|
||||
@@ -891,13 +892,7 @@ if ($LASTEXITCODE -ne 0) { throw "gateway ${action} failed with exit code $LASTE
|
||||
`$ErrorActionPreference = 'Continue'
|
||||
$PSNativeCommandUseErrorActionPreference = $false
|
||||
${windowsPortableGitPathScript}
|
||||
Invoke-OpenClaw models set ${psSingleQuote(this.auth.modelId)}
|
||||
if ($LASTEXITCODE -ne 0) { throw "models set failed" }
|
||||
${windowsModelProviderTimeoutScript(this.auth.modelId)}
|
||||
Invoke-OpenClaw config set agents.defaults.skipBootstrap true --strict-json
|
||||
if ($LASTEXITCODE -ne 0) { throw "config set failed" }
|
||||
Invoke-OpenClaw config set tools.profile minimal
|
||||
if ($LASTEXITCODE -ne 0) { throw "tools profile config set failed" }
|
||||
${windowsAgentTurnConfigPatchScript(this.auth.modelId)}
|
||||
${windowsAgentWorkspaceScript("Parallels Windows smoke test assistant.")}
|
||||
Set-Item -Path ('Env:' + ${psSingleQuote(this.auth.apiKeyEnv)}) -Value ${psSingleQuote(this.auth.apiKeyValue)}
|
||||
$agentOk = $false
|
||||
@@ -913,10 +908,14 @@ for ($attempt = 1; $attempt -le 2; $attempt++) {
|
||||
'main',
|
||||
'--session-id',
|
||||
$sessionId,
|
||||
'--model',
|
||||
${psSingleQuote(this.auth.modelId)},
|
||||
'--message',
|
||||
'Reply with exact ASCII text OK only.',
|
||||
'--thinking',
|
||||
'minimal',
|
||||
'--timeout',
|
||||
'${resolveParallelsModelTimeoutSeconds("windows")}',
|
||||
'--json'
|
||||
)
|
||||
$output = Invoke-OpenClaw @args 2>&1
|
||||
|
||||
@@ -327,8 +327,10 @@ console.log(JSON.stringify(result));
|
||||
|
||||
expect(script, scriptPath).toContain("AgentWorkspaceScript");
|
||||
expect(script, scriptPath).toContain("parallels-");
|
||||
expect(script, scriptPath).toContain("agents.defaults.skipBootstrap");
|
||||
expect(script, scriptPath).toContain("tools.profile");
|
||||
if (scriptPath !== TS_PATHS.windows) {
|
||||
expect(script, scriptPath).toContain("agents.defaults.skipBootstrap");
|
||||
expect(script, scriptPath).toContain("tools.profile");
|
||||
}
|
||||
expect(script, scriptPath).toContain("--thinking");
|
||||
expect(script, scriptPath).toContain("minimal");
|
||||
expect(script, scriptPath).toContain("finalAssistant(Raw|Visible)Text");
|
||||
@@ -337,8 +339,11 @@ console.log(JSON.stringify(result));
|
||||
expect(readFileSync(TS_PATHS.macos, "utf8")).toContain("config set --batch-file");
|
||||
expect(readFileSync(TS_PATHS.linux, "utf8")).toContain("modelProviderConfigBatchJson");
|
||||
expect(readFileSync(TS_PATHS.linux, "utf8")).toContain("config set --batch-file");
|
||||
expect(readFileSync(TS_PATHS.windows, "utf8")).toContain("windowsModelProviderTimeoutScript");
|
||||
expect(readFileSync(TS_PATHS.powershell, "utf8")).toContain("config set --batch-file");
|
||||
expect(readFileSync(TS_PATHS.windows, "utf8")).toContain("windowsAgentTurnConfigPatchScript");
|
||||
const powershell = readFileSync(TS_PATHS.powershell, "utf8");
|
||||
expect(powershell).toContain("config set --batch-file");
|
||||
expect(powershell).toContain("agents.defaults.skipBootstrap");
|
||||
expect(powershell).toContain("tools.profile");
|
||||
|
||||
const npmUpdateScripts = readFileSync(TS_PATHS.npmUpdateScripts, "utf8");
|
||||
expect(npmUpdateScripts).toContain("posixAgentWorkspaceScript");
|
||||
@@ -347,7 +352,7 @@ console.log(JSON.stringify(result));
|
||||
expect(npmUpdateScripts).toContain("--thinking minimal");
|
||||
expect(npmUpdateScripts).toContain("finalAssistant(Raw|Visible)Text");
|
||||
expect(npmUpdateScripts).toContain("posixAssertAgentOkScript");
|
||||
expect(npmUpdateScripts).toContain("windowsModelProviderTimeoutScript");
|
||||
expect(npmUpdateScripts).toContain("windowsAgentTurnConfigPatchScript");
|
||||
expect(npmUpdateScripts).toContain("modelProviderConfigBatchJson");
|
||||
expect(npmUpdateScripts).toContain("config set --batch-file");
|
||||
});
|
||||
@@ -476,7 +481,9 @@ console.log(JSON.stringify(result));
|
||||
expect(script).toContain('guestPowerShellBackground(\n "agent-turn"');
|
||||
expect(script).toContain("OPENCLAW_PARALLELS_WINDOWS_AGENT_TIMEOUT_S");
|
||||
expect(script).toContain("OPENCLAW_PARALLELS_WINDOWS_AGENT_TIMEOUT_S || 1500");
|
||||
expect(script).toContain("windowsModelProviderTimeoutScript(this.auth.modelId)");
|
||||
expect(script).toContain("windowsAgentTurnConfigPatchScript(this.auth.modelId)");
|
||||
expect(script).toContain("--model");
|
||||
expect(script).toContain('resolveParallelsModelTimeoutSeconds("windows")');
|
||||
expect(script).toContain("finalAssistant(Raw|Visible)Text");
|
||||
expect(script).toContain("parallels-windows-smoke-retry-$attempt");
|
||||
expect(script).toContain("agent turn attempt $attempt failed or finished without OK response");
|
||||
|
||||
Reference in New Issue
Block a user