mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-13 15:47:28 +00:00
fix(agents): avoid Pi resource discovery stalls
Co-authored-by: dataCenter430 <titan032000@gmail.com>
This commit is contained in:
@@ -67,6 +67,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Gateway: share serialized streaming event envelopes across eligible WebSocket and node subscribers while preserving per-client sequence numbers. (#80299) Thanks @samzong.
|
||||
- Browser: report Chrome MCP existing-session page readiness in browser status without letting status probes exceed the client timeout. Fixes #80268. (#80280) Thanks @ai-hpc.
|
||||
- WhatsApp: route opening-phase Baileys 428 connectionClosed through the WhatsApp reconnect policy and keep post-open 428 closes retryable, so transient setup socket closes retry with WhatsApp diagnostics instead of escaping as a bare `channel exited` error. Fixes #75736; mitigates #77443. Thanks @dataCenter430.
|
||||
- Agents: disable Pi's default filesystem resource discovery for embedded runs while keeping OpenClaw inline extension factories active, avoiding Windows event-loop stalls during first WhatsApp-triggered agent startup. Fixes #77443. Thanks @dataCenter430.
|
||||
- Providers/self-hosted: read model-scoped llama.cpp runtime context from `/props.default_generation_settings.n_ctx` while keeping top-level `n_ctx` as a fallback, so session budgeting reflects the loaded context window. Fixes #73664. (#74057) Thanks @brokemac79.
|
||||
- Memory: reject symlinked directory components in configured extra memory paths before reading Markdown files. (#80331) Thanks @samzong.
|
||||
- Sessions/transcripts: replace whole-file `readFile` scans with shared streaming helpers (`streamSessionTranscriptLines` and `streamSessionTranscriptLinesReverse`) for idempotency lookup, latest/tail assistant text reads, delivery-mirror dedupe, and compaction fork loading, so long-running sessions no longer materialize the full transcript in memory. Forward scans use `readline` over a bounded `createReadStream`; reverse scans read bounded chunks from the file end and decode complete JSONL lines newest-first without a fixed tail cap. Synthetic 200 MiB transcript: peak RSS delta drops from +252 MiB to +27 MiB while preserving malformed-line tolerance and idempotency-key return semantics. Fixes #54296. Thanks @jack-stormentswe.
|
||||
|
||||
@@ -3,7 +3,6 @@ import os from "node:os";
|
||||
import type { AgentMessage } from "@earendil-works/pi-agent-core";
|
||||
import {
|
||||
createAgentSession,
|
||||
DefaultResourceLoader,
|
||||
estimateTokens,
|
||||
SessionManager,
|
||||
} from "@earendil-works/pi-coding-agent";
|
||||
@@ -141,6 +140,7 @@ import { buildEmbeddedMessageActionDiscoveryInput } from "./message-action-disco
|
||||
import { readPiModelContextTokens } from "./model-context-tokens.js";
|
||||
import { resolveModelAsync } from "./model.js";
|
||||
import { sanitizeSessionHistory, validateReplayTurns } from "./replay-history.js";
|
||||
import { createEmbeddedPiResourceLoader } from "./resource-loader.js";
|
||||
import { buildEmbeddedSandboxInfo } from "./sandbox-info.js";
|
||||
import { prewarmSessionFile, trackSessionManagerAccess } from "./session-manager-cache.js";
|
||||
import { resolveEmbeddedRunSkillEntries } from "./skills-runtime.js";
|
||||
@@ -996,7 +996,7 @@ async function compactEmbeddedPiSessionDirectOnce(
|
||||
modelId,
|
||||
model,
|
||||
});
|
||||
const resourceLoader = new DefaultResourceLoader({
|
||||
const resourceLoader = createEmbeddedPiResourceLoader({
|
||||
cwd: resolvedWorkspace,
|
||||
agentDir,
|
||||
settingsManager,
|
||||
|
||||
40
src/agents/pi-embedded-runner/resource-loader.test.ts
Normal file
40
src/agents/pi-embedded-runner/resource-loader.test.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { DefaultResourceLoader } from "@earendil-works/pi-coding-agent";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
createEmbeddedPiResourceLoader,
|
||||
EMBEDDED_PI_RESOURCE_LOADER_DISCOVERY_OPTIONS,
|
||||
} from "./resource-loader.js";
|
||||
|
||||
vi.mock("@earendil-works/pi-coding-agent", () => ({
|
||||
DefaultResourceLoader: vi.fn(function DefaultResourceLoader(
|
||||
this: Record<string, unknown>,
|
||||
options: unknown,
|
||||
) {
|
||||
Object.assign(this, {
|
||||
options,
|
||||
reload: vi.fn(async () => undefined),
|
||||
});
|
||||
}),
|
||||
}));
|
||||
|
||||
describe("createEmbeddedPiResourceLoader", () => {
|
||||
it("keeps inline extensions but disables Pi filesystem discovery", () => {
|
||||
const settingsManager = {};
|
||||
const extensionFactories = [vi.fn()];
|
||||
|
||||
createEmbeddedPiResourceLoader({
|
||||
cwd: "/workspace",
|
||||
agentDir: "/agent",
|
||||
settingsManager: settingsManager as never,
|
||||
extensionFactories: extensionFactories as never,
|
||||
});
|
||||
|
||||
expect(DefaultResourceLoader).toHaveBeenCalledWith({
|
||||
cwd: "/workspace",
|
||||
agentDir: "/agent",
|
||||
settingsManager,
|
||||
extensionFactories,
|
||||
...EMBEDDED_PI_RESOURCE_LOADER_DISCOVERY_OPTIONS,
|
||||
});
|
||||
});
|
||||
});
|
||||
23
src/agents/pi-embedded-runner/resource-loader.ts
Normal file
23
src/agents/pi-embedded-runner/resource-loader.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { DefaultResourceLoader } from "@earendil-works/pi-coding-agent";
|
||||
|
||||
type DefaultResourceLoaderInit = ConstructorParameters<typeof DefaultResourceLoader>[0];
|
||||
|
||||
export const EMBEDDED_PI_RESOURCE_LOADER_DISCOVERY_OPTIONS = {
|
||||
noExtensions: true,
|
||||
noSkills: true,
|
||||
noPromptTemplates: true,
|
||||
noThemes: true,
|
||||
noContextFiles: true,
|
||||
} satisfies Partial<DefaultResourceLoaderInit>;
|
||||
|
||||
export function createEmbeddedPiResourceLoader(
|
||||
options: Pick<
|
||||
DefaultResourceLoaderInit,
|
||||
"cwd" | "agentDir" | "settingsManager" | "extensionFactories"
|
||||
>,
|
||||
): DefaultResourceLoader {
|
||||
return new DefaultResourceLoader({
|
||||
...options,
|
||||
...EMBEDDED_PI_RESOURCE_LOADER_DISCOVERY_OPTIONS,
|
||||
});
|
||||
}
|
||||
@@ -2,11 +2,7 @@ import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import type { AgentMessage } from "@earendil-works/pi-agent-core";
|
||||
import {
|
||||
createAgentSession,
|
||||
DefaultResourceLoader,
|
||||
SessionManager,
|
||||
} from "@earendil-works/pi-coding-agent";
|
||||
import { createAgentSession, SessionManager } from "@earendil-works/pi-coding-agent";
|
||||
import { isAcpRuntimeSpawnAvailable } from "../../../acp/runtime/availability.js";
|
||||
import { buildHierarchyReinforcementMessage } from "../../../auto-reply/handoff-summarizer.js";
|
||||
import { filterHeartbeatPairs } from "../../../auto-reply/heartbeat-filter.js";
|
||||
@@ -223,6 +219,7 @@ import {
|
||||
validateReplayTurns,
|
||||
} from "../replay-history.js";
|
||||
import { observeReplayMetadata, replayMetadataFromState } from "../replay-state.js";
|
||||
import { createEmbeddedPiResourceLoader } from "../resource-loader.js";
|
||||
import {
|
||||
clearActiveEmbeddedRun,
|
||||
type EmbeddedPiQueueHandle,
|
||||
@@ -1715,7 +1712,7 @@ export async function runEmbeddedAttempt(
|
||||
modelId: params.modelId,
|
||||
model: params.model,
|
||||
});
|
||||
const resourceLoader = new DefaultResourceLoader({
|
||||
const resourceLoader = createEmbeddedPiResourceLoader({
|
||||
cwd: resolvedWorkspace,
|
||||
agentDir,
|
||||
settingsManager,
|
||||
|
||||
Reference in New Issue
Block a user