mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-02 02:57:51 +00:00
Agent: resolve resumed session agent scope before run
This commit is contained in:
@@ -202,6 +202,7 @@ Docs: https://docs.openclaw.ai
|
|||||||
- Agents/Subagents: honor `tools.subagents.tools.alsoAllow` and explicit subagent `allow` entries when resolving built-in subagent deny defaults, so explicitly granted tools (for example `sessions_send`) are no longer blocked unless re-denied in `tools.subagents.tools.deny`. (#23359) Thanks @goren-beehero.
|
- Agents/Subagents: honor `tools.subagents.tools.alsoAllow` and explicit subagent `allow` entries when resolving built-in subagent deny defaults, so explicitly granted tools (for example `sessions_send`) are no longer blocked unless re-denied in `tools.subagents.tools.deny`. (#23359) Thanks @goren-beehero.
|
||||||
- Agents/Subagents: make announce call timeouts configurable via `agents.defaults.subagents.announceTimeoutMs` and restore a 60s default to prevent false timeout failures on slower announce paths. (#22719) Thanks @Valadon.
|
- Agents/Subagents: make announce call timeouts configurable via `agents.defaults.subagents.announceTimeoutMs` and restore a 60s default to prevent false timeout failures on slower announce paths. (#22719) Thanks @Valadon.
|
||||||
- Agents/Diagnostics: include resolved lifecycle error text in `embedded run agent end` warnings so UI/TUI “Connection error” runs expose actionable provider failure reasons in gateway logs. (#23054) Thanks @Raize.
|
- Agents/Diagnostics: include resolved lifecycle error text in `embedded run agent end` warnings so UI/TUI “Connection error” runs expose actionable provider failure reasons in gateway logs. (#23054) Thanks @Raize.
|
||||||
|
- Agents/Auth profiles: resolve `agentCommand` session scope before choosing `agentDir`/workspace so resumed runs no longer read auth from `agents/main/agent` when the resolved session belongs to a different/default agent (for example `agent:exec:*` sessions). (#24016) Thanks @abersonFAC.
|
||||||
- Agents/Auth profiles: skip auth-profile cooldown writes for timeout failures in embedded runner rotation so model/network timeouts do not poison same-provider fallback model selection while still allowing in-turn account rotation. (#22622) Thanks @vageeshkumar.
|
- Agents/Auth profiles: skip auth-profile cooldown writes for timeout failures in embedded runner rotation so model/network timeouts do not poison same-provider fallback model selection while still allowing in-turn account rotation. (#22622) Thanks @vageeshkumar.
|
||||||
- Plugins/Hooks: run legacy `before_agent_start` once per agent turn and reuse that result across model-resolve and prompt-build compatibility paths, preventing duplicate hook side effects (for example duplicate external API calls). (#23289) Thanks @ksato8710.
|
- Plugins/Hooks: run legacy `before_agent_start` once per agent turn and reuse that result across model-resolve and prompt-build compatibility paths, preventing duplicate hook side effects (for example duplicate external API calls). (#23289) Thanks @ksato8710.
|
||||||
- Models/Config: default missing Anthropic provider/model `api` fields to `anthropic-messages` during config validation so custom relay model entries are preserved instead of being dropped by runtime model registry validation. (#23332) Thanks @bigbigmonkey123.
|
- Models/Config: default missing Anthropic provider/model `api` fields to `anthropic-messages` during config validation so custom relay model entries are preserved instead of being dropped by runtime model registry validation. (#23332) Thanks @bigbigmonkey123.
|
||||||
|
|||||||
@@ -205,6 +205,31 @@ describe("agentCommand", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("uses the resumed session agent scope when sessionId resolves to another agent store", async () => {
|
||||||
|
await withTempHome(async (home) => {
|
||||||
|
const storePattern = path.join(home, "sessions", "{agentId}", "sessions.json");
|
||||||
|
const execStore = path.join(home, "sessions", "exec", "sessions.json");
|
||||||
|
writeSessionStoreSeed(execStore, {
|
||||||
|
"agent:exec:hook:gmail:thread-1": {
|
||||||
|
sessionId: "session-exec-hook",
|
||||||
|
updatedAt: Date.now(),
|
||||||
|
systemSent: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
mockConfig(home, storePattern, undefined, undefined, [
|
||||||
|
{ id: "dev" },
|
||||||
|
{ id: "exec", default: true },
|
||||||
|
]);
|
||||||
|
|
||||||
|
await agentCommand({ message: "resume me", sessionId: "session-exec-hook" }, runtime);
|
||||||
|
|
||||||
|
const callArgs = vi.mocked(runEmbeddedPiAgent).mock.calls.at(-1)?.[0];
|
||||||
|
expect(callArgs?.sessionKey).toBe("agent:exec:hook:gmail:thread-1");
|
||||||
|
expect(callArgs?.agentId).toBe("exec");
|
||||||
|
expect(callArgs?.agentDir).toContain(`${path.sep}agents${path.sep}exec${path.sep}agent`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("resolves resumed session transcript path from custom session store directory", async () => {
|
it("resolves resumed session transcript path from custom session store directory", async () => {
|
||||||
await withTempHome(async (home) => {
|
await withTempHome(async (home) => {
|
||||||
const customStoreDir = path.join(home, "custom-state");
|
const customStoreDir = path.join(home, "custom-state");
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
resolveAgentDir,
|
resolveAgentDir,
|
||||||
resolveEffectiveModelFallbacks,
|
resolveEffectiveModelFallbacks,
|
||||||
resolveAgentModelPrimary,
|
resolveAgentModelPrimary,
|
||||||
|
resolveSessionAgentId,
|
||||||
resolveAgentSkillsFilter,
|
resolveAgentSkillsFilter,
|
||||||
resolveAgentWorkspaceDir,
|
resolveAgentWorkspaceDir,
|
||||||
} from "../agents/agent-scope.js";
|
} from "../agents/agent-scope.js";
|
||||||
@@ -218,14 +219,6 @@ export async function agentCommand(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const agentCfg = cfg.agents?.defaults;
|
const agentCfg = cfg.agents?.defaults;
|
||||||
const sessionAgentId = agentIdOverride ?? resolveAgentIdFromSessionKey(opts.sessionKey?.trim());
|
|
||||||
const workspaceDirRaw = resolveAgentWorkspaceDir(cfg, sessionAgentId);
|
|
||||||
const agentDir = resolveAgentDir(cfg, sessionAgentId);
|
|
||||||
const workspace = await ensureAgentWorkspace({
|
|
||||||
dir: workspaceDirRaw,
|
|
||||||
ensureBootstrapFiles: !agentCfg?.skipBootstrap,
|
|
||||||
});
|
|
||||||
const workspaceDir = workspace.dir;
|
|
||||||
const configuredModel = resolveConfiguredModelRef({
|
const configuredModel = resolveConfiguredModelRef({
|
||||||
cfg,
|
cfg,
|
||||||
defaultProvider: DEFAULT_PROVIDER,
|
defaultProvider: DEFAULT_PROVIDER,
|
||||||
@@ -284,6 +277,19 @@ export async function agentCommand(
|
|||||||
persistedThinking,
|
persistedThinking,
|
||||||
persistedVerbose,
|
persistedVerbose,
|
||||||
} = sessionResolution;
|
} = sessionResolution;
|
||||||
|
const sessionAgentId =
|
||||||
|
agentIdOverride ??
|
||||||
|
resolveSessionAgentId({
|
||||||
|
sessionKey: sessionKey ?? opts.sessionKey?.trim(),
|
||||||
|
config: cfg,
|
||||||
|
});
|
||||||
|
const workspaceDirRaw = resolveAgentWorkspaceDir(cfg, sessionAgentId);
|
||||||
|
const agentDir = resolveAgentDir(cfg, sessionAgentId);
|
||||||
|
const workspace = await ensureAgentWorkspace({
|
||||||
|
dir: workspaceDirRaw,
|
||||||
|
ensureBootstrapFiles: !agentCfg?.skipBootstrap,
|
||||||
|
});
|
||||||
|
const workspaceDir = workspace.dir;
|
||||||
let sessionEntry = resolvedSessionEntry;
|
let sessionEntry = resolvedSessionEntry;
|
||||||
const runId = opts.runId?.trim() || sessionId;
|
const runId = opts.runId?.trim() || sessionId;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user