mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-12 09:41:11 +00:00
fix(runtime): tighten auth-scope and full-access hints
This commit is contained in:
@@ -242,6 +242,15 @@ describe("formatAssistantErrorText", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("does not misdiagnose generic Codex permission failures as missing-scope failures", () => {
|
||||
const msg = makeAssistantError(
|
||||
'403 {"type":"error","error":{"type":"permission_error","message":"Insufficient permissions for this organization"}}',
|
||||
);
|
||||
expect(formatAssistantErrorText(msg, { provider: "openai-codex" })).not.toContain(
|
||||
"required OpenAI Codex scopes",
|
||||
);
|
||||
});
|
||||
|
||||
it("returns an HTML-403 auth message for HTML provider auth failures", () => {
|
||||
const msg = makeAssistantError("403 <!DOCTYPE html><html><body>Access denied</body></html>");
|
||||
expect(formatAssistantErrorText(msg)).toBe(
|
||||
|
||||
@@ -1124,6 +1124,16 @@ describe("classifyProviderRuntimeFailureKind", () => {
|
||||
).not.toBe("auth_scope");
|
||||
});
|
||||
|
||||
it("does not treat generic Codex permission failures as missing scope failures", () => {
|
||||
expect(
|
||||
classifyProviderRuntimeFailureKind({
|
||||
provider: "openai-codex",
|
||||
message:
|
||||
'403 {"type":"error","error":{"type":"permission_error","message":"Insufficient permissions for this organization"}}',
|
||||
}),
|
||||
).not.toBe("auth_scope");
|
||||
});
|
||||
|
||||
it("classifies OAuth refresh failures", () => {
|
||||
expect(
|
||||
classifyProviderRuntimeFailureKind(
|
||||
|
||||
@@ -465,7 +465,7 @@ const TIMEOUT_ERROR_CODES = new Set([
|
||||
"EAI_AGAIN",
|
||||
]);
|
||||
const AUTH_SCOPE_HINT_RE =
|
||||
/\b(?:missing|required|requires|insufficient)\s+(?:the\s+following\s+)?scopes?\b|\bmissing\s+scope\b|\binsufficient\s+permissions?\b/i;
|
||||
/\b(?:missing|required|requires|insufficient)\s+(?:the\s+following\s+)?scopes?\b|\bmissing\s+scope\b/i;
|
||||
const AUTH_SCOPE_NAME_RE = /\b(?:api\.responses\.write|model\.request)\b/i;
|
||||
const HTML_BODY_RE = /^\s*(?:<!doctype\s+html\b|<html\b)/i;
|
||||
const HTML_CLOSE_RE = /<\/html>/i;
|
||||
|
||||
@@ -119,7 +119,6 @@ describe("resolveEmbeddedFullAccessState", () => {
|
||||
it("treats direct host runs with allowed elevation as full-access available", () => {
|
||||
expect(
|
||||
resolveEmbeddedFullAccessState({
|
||||
sandboxEnabled: false,
|
||||
execElevated: {
|
||||
enabled: true,
|
||||
allowed: true,
|
||||
@@ -132,7 +131,6 @@ describe("resolveEmbeddedFullAccessState", () => {
|
||||
it("keeps explicit runtime blocks even when host exec is allowed", () => {
|
||||
expect(
|
||||
resolveEmbeddedFullAccessState({
|
||||
sandboxEnabled: false,
|
||||
execElevated: {
|
||||
enabled: true,
|
||||
allowed: true,
|
||||
|
||||
@@ -2,10 +2,10 @@ import type { ExecElevatedDefaults } from "../bash-tools.js";
|
||||
import type { resolveSandboxContext } from "../sandbox.js";
|
||||
import type { EmbeddedFullAccessBlockedReason, EmbeddedSandboxInfo } from "./types.js";
|
||||
|
||||
export function resolveEmbeddedFullAccessState(params: {
|
||||
sandboxEnabled: boolean;
|
||||
execElevated?: ExecElevatedDefaults;
|
||||
}): { available: boolean; blockedReason?: EmbeddedFullAccessBlockedReason } {
|
||||
export function resolveEmbeddedFullAccessState(params: { execElevated?: ExecElevatedDefaults }): {
|
||||
available: boolean;
|
||||
blockedReason?: EmbeddedFullAccessBlockedReason;
|
||||
} {
|
||||
if (params.execElevated?.fullAccessAvailable === true) {
|
||||
return { available: true };
|
||||
}
|
||||
@@ -21,9 +21,6 @@ export function resolveEmbeddedFullAccessState(params: {
|
||||
blockedReason: "host-policy",
|
||||
};
|
||||
}
|
||||
if (!params.sandboxEnabled) {
|
||||
return { available: true };
|
||||
}
|
||||
return { available: true };
|
||||
}
|
||||
|
||||
@@ -37,7 +34,6 @@ export function buildEmbeddedSandboxInfo(
|
||||
const elevatedConfigured = execElevated?.enabled === true;
|
||||
const elevatedAllowed = Boolean(execElevated?.enabled && execElevated.allowed);
|
||||
const fullAccess = resolveEmbeddedFullAccessState({
|
||||
sandboxEnabled: true,
|
||||
execElevated,
|
||||
});
|
||||
return {
|
||||
|
||||
@@ -112,7 +112,6 @@ export async function resolveCommandsSystemPromptBundle(
|
||||
},
|
||||
});
|
||||
const fullAccessState = resolveEmbeddedFullAccessState({
|
||||
sandboxEnabled: sandboxRuntime.sandboxed,
|
||||
execElevated: {
|
||||
enabled: params.elevated.enabled,
|
||||
allowed: params.elevated.allowed,
|
||||
|
||||
@@ -48,7 +48,7 @@ describe("buildExecOverridePromptHint", () => {
|
||||
|
||||
expect(result).toContain("Current elevated level: full.");
|
||||
expect(result).toContain(
|
||||
"Auto-approved /elevated full is unavailable here (runtime). Use ask/on instead and do not ask the user to switch to /elevated full.",
|
||||
"Auto-approved /elevated full is unavailable here (runtime). Do not ask the user to switch to /elevated full.",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,7 +4,6 @@ import type { ExecToolDefaults } from "../../agents/bash-tools.js";
|
||||
import { resolveFastModeState } from "../../agents/fast-mode.js";
|
||||
import { resolveEmbeddedFullAccessState } from "../../agents/pi-embedded-runner/sandbox-info.js";
|
||||
import type { EmbeddedFullAccessBlockedReason } from "../../agents/pi-embedded-runner/types.js";
|
||||
import { resolveSandboxRuntimeStatus } from "../../agents/sandbox.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { resolveGroupSessionKey } from "../../config/sessions/group.js";
|
||||
import {
|
||||
@@ -76,7 +75,7 @@ export function buildExecOverridePromptHint(params: {
|
||||
const elevatedLine = `Current elevated level: ${params.elevatedLevel}.`;
|
||||
const fullAccessLine =
|
||||
params.fullAccessAvailable === false
|
||||
? `Auto-approved /elevated full is unavailable here (${params.fullAccessBlockedReason ?? "runtime"}). Use ask/on instead and do not ask the user to switch to /elevated full.`
|
||||
? `Auto-approved /elevated full is unavailable here (${params.fullAccessBlockedReason ?? "runtime"}). Do not ask the user to switch to /elevated full.`
|
||||
: undefined;
|
||||
return [
|
||||
"## Current Exec Session State",
|
||||
@@ -226,10 +225,6 @@ export async function runPreparedReply(
|
||||
isFastTestEnv: process.env.OPENCLAW_TEST_FAST === "1",
|
||||
});
|
||||
const fullAccessState = resolveEmbeddedFullAccessState({
|
||||
sandboxEnabled: resolveSandboxRuntimeStatus({
|
||||
cfg,
|
||||
sessionKey,
|
||||
}).sandboxed,
|
||||
execElevated: {
|
||||
enabled: elevatedEnabled,
|
||||
allowed: elevatedAllowed,
|
||||
|
||||
Reference in New Issue
Block a user