mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:50:43 +00:00
fix: restore CI restart and provider compat
This commit is contained in:
@@ -709,6 +709,32 @@ describe("provider attribution", () => {
|
||||
endpointClass: "modelstudio-native",
|
||||
supportsNativeStreamingUsageCompat: true,
|
||||
});
|
||||
|
||||
expect(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "ollama",
|
||||
api: "openai-completions",
|
||||
baseUrl: "http://127.0.0.1:11434/v1",
|
||||
capability: "llm",
|
||||
transport: "stream",
|
||||
}),
|
||||
).toMatchObject({
|
||||
endpointClass: "local",
|
||||
supportsNativeStreamingUsageCompat: true,
|
||||
});
|
||||
|
||||
expect(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "ollama",
|
||||
api: "openai-completions",
|
||||
baseUrl: "http://127.0.0.1:11434/v1",
|
||||
capability: "llm",
|
||||
transport: "stream",
|
||||
modelId: "kimi-k2.5:cloud",
|
||||
}),
|
||||
).toMatchObject({
|
||||
compatibilityFamily: "moonshot",
|
||||
});
|
||||
});
|
||||
|
||||
it("treats native GitHub Copilot base URLs as known native endpoints", () => {
|
||||
@@ -902,6 +928,28 @@ describe("provider attribution", () => {
|
||||
supportsNativeStreamingUsageCompat: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Ollama OpenAI-compatible completions",
|
||||
input: {
|
||||
provider: "ollama",
|
||||
api: "openai-completions",
|
||||
baseUrl: "http://127.0.0.1:11434/v1",
|
||||
capability: "llm" as const,
|
||||
transport: "stream" as const,
|
||||
},
|
||||
expected: {
|
||||
knownProviderFamily: "ollama",
|
||||
endpointClass: "local",
|
||||
isKnownNativeEndpoint: false,
|
||||
allowsOpenAIServiceTier: false,
|
||||
supportsOpenAIReasoningCompatPayload: false,
|
||||
allowsResponsesStore: false,
|
||||
supportsResponsesStoreField: false,
|
||||
shouldStripResponsesPromptCache: false,
|
||||
allowsAnthropicServiceTier: false,
|
||||
supportsNativeStreamingUsageCompat: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "native Google Gemini api",
|
||||
input: {
|
||||
|
||||
@@ -132,6 +132,10 @@ const OPENAI_RESPONSES_APIS = new Set([
|
||||
const OPENAI_RESPONSES_PROVIDERS = new Set(["openai", "azure-openai", "azure-openai-responses"]);
|
||||
const MOONSHOT_COMPAT_PROVIDERS = new Set(["moonshot", "kimi"]);
|
||||
|
||||
function isOllamaMoonshotCompatModel(modelId: string | null | undefined): boolean {
|
||||
return /^kimi-k2\.5(?::|$)/i.test(modelId?.trim() ?? "");
|
||||
}
|
||||
|
||||
function formatOpenClawUserAgent(version: string): string {
|
||||
return `${OPENCLAW_ATTRIBUTION_ORIGINATOR}/${version}`;
|
||||
}
|
||||
@@ -571,7 +575,12 @@ export function resolveProviderRequestCapabilities(
|
||||
endpointClass === "google-vertex";
|
||||
|
||||
let compatibilityFamily: ProviderRequestCompatibilityFamily | undefined;
|
||||
if (provider && MOONSHOT_COMPAT_PROVIDERS.has(provider)) {
|
||||
const isOllamaOpenAICompletions = provider === "ollama" && api === "openai-completions";
|
||||
if (
|
||||
provider &&
|
||||
(MOONSHOT_COMPAT_PROVIDERS.has(provider) ||
|
||||
(provider === "ollama" && isOllamaMoonshotCompatModel(input.modelId)))
|
||||
) {
|
||||
compatibilityFamily = "moonshot";
|
||||
}
|
||||
|
||||
@@ -629,7 +638,9 @@ export function resolveProviderRequestCapabilities(
|
||||
// Native endpoint class is the real signal here. Users can point a generic
|
||||
// provider key at Moonshot or DashScope and still need streaming usage.
|
||||
supportsNativeStreamingUsageCompat:
|
||||
endpointClass === "moonshot-native" || endpointClass === "modelstudio-native",
|
||||
endpointClass === "moonshot-native" ||
|
||||
endpointClass === "modelstudio-native" ||
|
||||
isOllamaOpenAICompletions,
|
||||
compatibilityFamily,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -165,9 +165,7 @@ exit 0
|
||||
OPENCLAW_PROFILE: "default",
|
||||
HOME: "/Users/testuser",
|
||||
});
|
||||
expect(content).toContain(
|
||||
"exec >>'/Users/testuser/.openclaw/logs/gateway-restart.log' 2>&1 || true",
|
||||
);
|
||||
expect(content).toContain("exec >>'/Users/testuser/.openclaw/logs/gateway-restart.log' 2>&1");
|
||||
// Every launchctl call should allow output through now (no `2>/dev/null`)
|
||||
// and the final kickstart must not swallow its exit code.
|
||||
expect(content).not.toMatch(/launchctl[^\n]*2>\/dev\/null/);
|
||||
@@ -185,10 +183,10 @@ exit 0
|
||||
OPENCLAW_STATE_DIR: "/tmp/openclaw-state",
|
||||
});
|
||||
|
||||
expect(content).toContain("mkdir -p '/tmp/openclaw-state/logs' 2>/dev/null || true");
|
||||
expect(content).toContain(
|
||||
"exec >>'/tmp/openclaw-state/logs/gateway-restart.log' 2>&1 || true",
|
||||
"if mkdir -p '/tmp/openclaw-state/logs' 2>/dev/null && : >>'/tmp/openclaw-state/logs/gateway-restart.log' 2>/dev/null; then",
|
||||
);
|
||||
expect(content).toContain("exec >>'/tmp/openclaw-state/logs/gateway-restart.log' 2>&1");
|
||||
await cleanupScript(scriptPath);
|
||||
});
|
||||
|
||||
|
||||
@@ -41,9 +41,7 @@ describe("scheduleDetachedLaunchdRestartHandoff", () => {
|
||||
expect(args[6]).toBe("9876");
|
||||
expect(args[7]).toBe("ai.openclaw.gateway");
|
||||
expect(args[1]).toContain('while kill -0 "$wait_pid" >/dev/null 2>&1; do');
|
||||
expect(args[1]).toContain(
|
||||
"exec >>'/Users/test/.openclaw/logs/gateway-restart.log' 2>&1 || true",
|
||||
);
|
||||
expect(args[1]).toContain("exec >>'/Users/test/.openclaw/logs/gateway-restart.log' 2>&1");
|
||||
expect(args[1]).toContain("openclaw restart attempt source=launchd-handoff mode=kickstart");
|
||||
expect(args[1]).toContain('launchctl enable "$service_target"');
|
||||
expect(args[1]).toContain('if launchctl kickstart -k "$service_target"; then');
|
||||
|
||||
@@ -40,10 +40,10 @@ describe("restart log conventions", () => {
|
||||
HOME: "/Users/test's",
|
||||
});
|
||||
|
||||
expect(setup).toContain("mkdir -p '/Users/test'\\''s/.openclaw/logs' 2>/dev/null || true");
|
||||
expect(setup).toContain(
|
||||
"exec >>'/Users/test'\\''s/.openclaw/logs/gateway-restart.log' 2>&1 || true",
|
||||
"if mkdir -p '/Users/test'\\''s/.openclaw/logs' 2>/dev/null && : >>'/Users/test'\\''s/.openclaw/logs/gateway-restart.log' 2>/dev/null; then",
|
||||
);
|
||||
expect(setup).toContain("exec >>'/Users/test'\\''s/.openclaw/logs/gateway-restart.log' 2>&1");
|
||||
});
|
||||
|
||||
it("renders CMD log setup with quoted paths", () => {
|
||||
|
||||
@@ -31,8 +31,11 @@ export function shellEscapeRestartLogValue(value: string): string {
|
||||
export function renderPosixRestartLogSetup(env: GatewayServiceEnv): string {
|
||||
const logDir = path.dirname(resolveGatewayRestartLogPath(env));
|
||||
const logPath = resolveGatewayRestartLogPath(env);
|
||||
return `mkdir -p '${shellEscapeRestartLogValue(logDir)}' 2>/dev/null || true
|
||||
exec >>'${shellEscapeRestartLogValue(logPath)}' 2>&1 || true`;
|
||||
const escapedLogDir = shellEscapeRestartLogValue(logDir);
|
||||
const escapedLogPath = shellEscapeRestartLogValue(logPath);
|
||||
return `if mkdir -p '${escapedLogDir}' 2>/dev/null && : >>'${escapedLogPath}' 2>/dev/null; then
|
||||
exec >>'${escapedLogPath}' 2>&1
|
||||
fi`;
|
||||
}
|
||||
|
||||
export function renderCmdRestartLogSetup(env: GatewayServiceEnv): {
|
||||
|
||||
Reference in New Issue
Block a user