Merge branch 'main' into commands-list-clean
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
resolveAgentDir,
|
||||
resolveDefaultAgentId,
|
||||
} from "../../agents/agent-scope.js";
|
||||
import {
|
||||
ensureAuthProfileStore,
|
||||
resolveAuthProfileDisplayLabel,
|
||||
@@ -16,6 +20,13 @@ import {
|
||||
} from "../../agents/pi-embedded.js";
|
||||
import type { ClawdbotConfig } from "../../config/config.js";
|
||||
import {
|
||||
getConfigOverrides,
|
||||
resetConfigOverrides,
|
||||
setConfigOverride,
|
||||
unsetConfigOverride,
|
||||
} from "../../config/runtime-overrides.js";
|
||||
import {
|
||||
resolveAgentIdFromSessionKey,
|
||||
resolveSessionFilePath,
|
||||
type SessionEntry,
|
||||
type SessionScope,
|
||||
@@ -61,6 +72,7 @@ import type {
|
||||
} from "../thinking.js";
|
||||
import type { ReplyPayload } from "../types.js";
|
||||
import { isAbortTrigger, setAbortMemory } from "./abort.js";
|
||||
import { parseDebugCommand } from "./debug-commands.js";
|
||||
import type { InlineDirectives } from "./directive-handling.js";
|
||||
import { stripMentions, stripStructuralPrefixes } from "./mentions.js";
|
||||
import { getFollowupQueueDepth, resolveQueueSettings } from "./queue.js";
|
||||
@@ -135,6 +147,10 @@ export async function buildStatusReply(params: {
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
const statusAgentId = sessionKey
|
||||
? resolveAgentIdFromSessionKey(sessionKey)
|
||||
: resolveDefaultAgentId(cfg);
|
||||
const statusAgentDir = resolveAgentDir(cfg, statusAgentId);
|
||||
let usageLine: string | null = null;
|
||||
try {
|
||||
const usageProvider = resolveUsageProviderId(provider);
|
||||
@@ -142,8 +158,18 @@ export async function buildStatusReply(params: {
|
||||
const usageSummary = await loadProviderUsageSummary({
|
||||
timeoutMs: 3500,
|
||||
providers: [usageProvider],
|
||||
agentDir: statusAgentDir,
|
||||
});
|
||||
usageLine = formatUsageSummaryLine(usageSummary, { now: Date.now() });
|
||||
if (
|
||||
!usageLine &&
|
||||
(resolvedVerboseLevel === "on" || resolvedElevatedLevel === "on")
|
||||
) {
|
||||
const entry = usageSummary.providers[0];
|
||||
if (entry?.error) {
|
||||
usageLine = `📊 Usage: ${entry.displayName} (${entry.error})`;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
usageLine = null;
|
||||
@@ -164,18 +190,19 @@ export async function buildStatusReply(params: {
|
||||
? (normalizeGroupActivation(sessionEntry?.groupActivation) ??
|
||||
defaultGroupActivation())
|
||||
: undefined;
|
||||
const agentDefaults = cfg.agents?.defaults ?? {};
|
||||
const statusText = buildStatusMessage({
|
||||
config: cfg,
|
||||
agent: {
|
||||
...cfg.agent,
|
||||
...agentDefaults,
|
||||
model: {
|
||||
...cfg.agent?.model,
|
||||
...agentDefaults.model,
|
||||
primary: `${provider}/${model}`,
|
||||
},
|
||||
contextTokens,
|
||||
thinkingDefault: cfg.agent?.thinkingDefault,
|
||||
verboseDefault: cfg.agent?.verboseDefault,
|
||||
elevatedDefault: cfg.agent?.elevatedDefault,
|
||||
thinkingDefault: agentDefaults.thinkingDefault,
|
||||
verboseDefault: agentDefaults.verboseDefault,
|
||||
elevatedDefault: agentDefaults.elevatedDefault,
|
||||
},
|
||||
sessionEntry,
|
||||
sessionKey,
|
||||
@@ -185,7 +212,12 @@ export async function buildStatusReply(params: {
|
||||
resolvedVerbose: resolvedVerboseLevel,
|
||||
resolvedReasoning: resolvedReasoningLevel,
|
||||
resolvedElevated: resolvedElevatedLevel,
|
||||
modelAuth: resolveModelAuthLabel(provider, cfg, sessionEntry),
|
||||
modelAuth: resolveModelAuthLabel(
|
||||
provider,
|
||||
cfg,
|
||||
sessionEntry,
|
||||
statusAgentDir,
|
||||
),
|
||||
usageLine: usageLine ?? undefined,
|
||||
queue: {
|
||||
mode: queueSettings.mode,
|
||||
@@ -213,12 +245,15 @@ function resolveModelAuthLabel(
|
||||
provider?: string,
|
||||
cfg?: ClawdbotConfig,
|
||||
sessionEntry?: SessionEntry,
|
||||
agentDir?: string,
|
||||
): string | undefined {
|
||||
const resolved = provider?.trim();
|
||||
if (!resolved) return undefined;
|
||||
|
||||
const providerKey = normalizeProviderId(resolved);
|
||||
const store = ensureAuthProfileStore();
|
||||
const store = ensureAuthProfileStore(agentDir, {
|
||||
allowKeychainPrompt: false,
|
||||
});
|
||||
const profileOverride = sessionEntry?.authProfileOverride?.trim();
|
||||
const order = resolveAuthProfileOrder({
|
||||
cfg,
|
||||
@@ -593,6 +628,88 @@ export async function handleCommands(params: {
|
||||
return { shouldContinue: false, reply };
|
||||
}
|
||||
|
||||
const debugCommand = allowTextCommands
|
||||
? parseDebugCommand(command.commandBodyNormalized)
|
||||
: null;
|
||||
if (debugCommand) {
|
||||
if (!command.isAuthorizedSender) {
|
||||
logVerbose(
|
||||
`Ignoring /debug from unauthorized sender: ${command.senderE164 || "<unknown>"}`,
|
||||
);
|
||||
return { shouldContinue: false };
|
||||
}
|
||||
if (debugCommand.action === "error") {
|
||||
return {
|
||||
shouldContinue: false,
|
||||
reply: { text: `⚠️ ${debugCommand.message}` },
|
||||
};
|
||||
}
|
||||
if (debugCommand.action === "show") {
|
||||
const overrides = getConfigOverrides();
|
||||
const hasOverrides = Object.keys(overrides).length > 0;
|
||||
if (!hasOverrides) {
|
||||
return {
|
||||
shouldContinue: false,
|
||||
reply: { text: "⚙️ Debug overrides: (none)" },
|
||||
};
|
||||
}
|
||||
const json = JSON.stringify(overrides, null, 2);
|
||||
return {
|
||||
shouldContinue: false,
|
||||
reply: {
|
||||
text: `⚙️ Debug overrides (memory-only):\n\`\`\`json\n${json}\n\`\`\``,
|
||||
},
|
||||
};
|
||||
}
|
||||
if (debugCommand.action === "reset") {
|
||||
resetConfigOverrides();
|
||||
return {
|
||||
shouldContinue: false,
|
||||
reply: { text: "⚙️ Debug overrides cleared; using config on disk." },
|
||||
};
|
||||
}
|
||||
if (debugCommand.action === "unset") {
|
||||
const result = unsetConfigOverride(debugCommand.path);
|
||||
if (!result.ok) {
|
||||
return {
|
||||
shouldContinue: false,
|
||||
reply: { text: `⚠️ ${result.error ?? "Invalid path."}` },
|
||||
};
|
||||
}
|
||||
if (!result.removed) {
|
||||
return {
|
||||
shouldContinue: false,
|
||||
reply: {
|
||||
text: `⚙️ No debug override found for ${debugCommand.path}.`,
|
||||
},
|
||||
};
|
||||
}
|
||||
return {
|
||||
shouldContinue: false,
|
||||
reply: { text: `⚙️ Debug override removed for ${debugCommand.path}.` },
|
||||
};
|
||||
}
|
||||
if (debugCommand.action === "set") {
|
||||
const result = setConfigOverride(debugCommand.path, debugCommand.value);
|
||||
if (!result.ok) {
|
||||
return {
|
||||
shouldContinue: false,
|
||||
reply: { text: `⚠️ ${result.error ?? "Invalid override."}` },
|
||||
};
|
||||
}
|
||||
const valueLabel =
|
||||
typeof debugCommand.value === "string"
|
||||
? `"${debugCommand.value}"`
|
||||
: JSON.stringify(debugCommand.value);
|
||||
return {
|
||||
shouldContinue: false,
|
||||
reply: {
|
||||
text: `⚙️ Debug override set: ${debugCommand.path}=${valueLabel ?? "null"}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const stopRequested = command.commandBodyNormalized === "/stop";
|
||||
if (allowTextCommands && stopRequested) {
|
||||
if (!command.isAuthorizedSender) {
|
||||
|
||||
Reference in New Issue
Block a user