Merge 7c5d26aa9c into 09be5d45d5
This commit is contained in:
commit
5dc856bf2a
15
pnpm-lock.yaml
generated
15
pnpm-lock.yaml
generated
@ -172,6 +172,13 @@ importers:
|
||||
zod:
|
||||
specifier: ^4.3.6
|
||||
version: 4.3.6
|
||||
optionalDependencies:
|
||||
'@napi-rs/canvas':
|
||||
specifier: ^0.1.88
|
||||
version: 0.1.88
|
||||
node-llama-cpp:
|
||||
specifier: 3.15.0
|
||||
version: 3.15.0(typescript@5.9.3)
|
||||
devDependencies:
|
||||
'@grammyjs/types':
|
||||
specifier: ^3.23.0
|
||||
@ -254,13 +261,6 @@ importers:
|
||||
wireit:
|
||||
specifier: ^0.14.12
|
||||
version: 0.14.12
|
||||
optionalDependencies:
|
||||
'@napi-rs/canvas':
|
||||
specifier: ^0.1.88
|
||||
version: 0.1.88
|
||||
node-llama-cpp:
|
||||
specifier: 3.15.0
|
||||
version: 3.15.0(typescript@5.9.3)
|
||||
|
||||
extensions/bluebubbles: {}
|
||||
|
||||
@ -1328,7 +1328,6 @@ packages:
|
||||
'@lancedb/lancedb@0.23.0':
|
||||
resolution: {integrity: sha512-aYrIoEG24AC+wILCL57Ius/Y4yU+xFHDPKLvmjzzN4byAjzeIGF0TC86S5RBt4Ji+dxS7yIWV5Q/gE5/fybIFQ==}
|
||||
engines: {node: '>= 18'}
|
||||
cpu: [x64, arm64]
|
||||
os: [darwin, linux, win32]
|
||||
peerDependencies:
|
||||
apache-arrow: '>=15.0.0 <=18.1.0'
|
||||
|
||||
@ -351,6 +351,7 @@ export async function compactEmbeddedPiSessionDirect(
|
||||
|
||||
const sessionLock = await acquireSessionWriteLock({
|
||||
sessionFile: params.sessionFile,
|
||||
timeoutMs: params.config?.agents?.defaults?.sessionWriteLockTimeoutMs,
|
||||
});
|
||||
try {
|
||||
await prewarmSessionFile(params.sessionFile);
|
||||
|
||||
@ -386,6 +386,7 @@ export async function runEmbeddedAttempt(
|
||||
|
||||
const sessionLock = await acquireSessionWriteLock({
|
||||
sessionFile: params.sessionFile,
|
||||
timeoutMs: params.config?.agents?.defaults?.sessionWriteLockTimeoutMs,
|
||||
});
|
||||
|
||||
let sessionManager: ReturnType<typeof guardSessionManager> | undefined;
|
||||
|
||||
@ -107,7 +107,9 @@ export async function acquireSessionWriteLock(params: {
|
||||
release: () => Promise<void>;
|
||||
}> {
|
||||
registerCleanupHandlers();
|
||||
const timeoutMs = params.timeoutMs ?? 10_000;
|
||||
// Default timeout increased from 10s to 60s to prevent premature termination
|
||||
// when multiple subagents compete for session file locks (see issue #4355)
|
||||
const timeoutMs = params.timeoutMs ?? 60_000;
|
||||
const staleMs = params.staleMs ?? 30 * 60 * 1000;
|
||||
const sessionFile = path.resolve(params.sessionFile);
|
||||
const sessionDir = path.dirname(sessionFile);
|
||||
|
||||
87
src/config/config.session-write-lock-timeout.test.ts
Normal file
87
src/config/config.session-write-lock-timeout.test.ts
Normal file
@ -0,0 +1,87 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { AgentDefaultsConfig } from "./types.agent-defaults.js";
|
||||
import { AgentDefaultsSchema } from "./zod-schema.agent-defaults.js";
|
||||
|
||||
/**
|
||||
* Helper to resolve session write lock timeout from config.
|
||||
* Matches the pattern in session-write-lock.ts where default is 60_000ms.
|
||||
*/
|
||||
function resolveSessionWriteLockTimeout(config: {
|
||||
agents?: { defaults?: { sessionWriteLockTimeoutMs?: number } };
|
||||
}): number {
|
||||
return config.agents?.defaults?.sessionWriteLockTimeoutMs ?? 60_000;
|
||||
}
|
||||
|
||||
describe("sessionWriteLockTimeoutMs config", () => {
|
||||
it("uses default timeout when unset", () => {
|
||||
const config = {};
|
||||
expect(resolveSessionWriteLockTimeout(config)).toBe(60_000);
|
||||
});
|
||||
|
||||
it("uses default timeout when agents.defaults is empty", () => {
|
||||
const config = { agents: { defaults: {} } };
|
||||
expect(resolveSessionWriteLockTimeout(config)).toBe(60_000);
|
||||
});
|
||||
|
||||
it("uses custom timeout from config", () => {
|
||||
const config = {
|
||||
agents: {
|
||||
defaults: {
|
||||
sessionWriteLockTimeoutMs: 30_000,
|
||||
},
|
||||
},
|
||||
};
|
||||
expect(resolveSessionWriteLockTimeout(config)).toBe(30_000);
|
||||
});
|
||||
|
||||
it("accepts large timeout values", () => {
|
||||
const config = {
|
||||
agents: {
|
||||
defaults: {
|
||||
sessionWriteLockTimeoutMs: 120_000,
|
||||
},
|
||||
},
|
||||
};
|
||||
expect(resolveSessionWriteLockTimeout(config)).toBe(120_000);
|
||||
});
|
||||
|
||||
it("config type includes sessionWriteLockTimeoutMs field", () => {
|
||||
const config: AgentDefaultsConfig = {
|
||||
sessionWriteLockTimeoutMs: 45_000,
|
||||
};
|
||||
expect(config.sessionWriteLockTimeoutMs).toBe(45_000);
|
||||
});
|
||||
|
||||
it("validates positive integer timeout via zod schema", () => {
|
||||
const validConfig = { sessionWriteLockTimeoutMs: 30_000 };
|
||||
const result = AgentDefaultsSchema.safeParse(validConfig);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.sessionWriteLockTimeoutMs).toBe(30_000);
|
||||
}
|
||||
});
|
||||
|
||||
it("rejects negative timeout values", () => {
|
||||
const invalidConfig = { sessionWriteLockTimeoutMs: -1000 };
|
||||
const result = AgentDefaultsSchema.safeParse(invalidConfig);
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects zero timeout value", () => {
|
||||
const invalidConfig = { sessionWriteLockTimeoutMs: 0 };
|
||||
const result = AgentDefaultsSchema.safeParse(invalidConfig);
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects non-integer timeout values", () => {
|
||||
const invalidConfig = { sessionWriteLockTimeoutMs: 1000.5 };
|
||||
const result = AgentDefaultsSchema.safeParse(invalidConfig);
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it("allows undefined/optional timeout", () => {
|
||||
const config = {};
|
||||
const result = AgentDefaultsSchema.safeParse(config);
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
});
|
||||
@ -196,6 +196,8 @@ export type AgentDefaultsConfig = {
|
||||
};
|
||||
/** Max concurrent agent runs across all conversations. Default: 1 (sequential). */
|
||||
maxConcurrent?: number;
|
||||
/** Timeout (ms) for acquiring per-session write lock. Default: 10000. */
|
||||
sessionWriteLockTimeoutMs?: number;
|
||||
/** Sub-agent defaults (spawned via sessions_spawn). */
|
||||
subagents?: {
|
||||
/** Max concurrent sub-agent runs (global lane: "subagent"). Default: 1. */
|
||||
|
||||
@ -123,6 +123,7 @@ export const AgentDefaultsSchema = z
|
||||
blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
|
||||
humanDelay: HumanDelaySchema.optional(),
|
||||
timeoutSeconds: z.number().int().positive().optional(),
|
||||
sessionWriteLockTimeoutMs: z.number().int().positive().optional(),
|
||||
mediaMaxMb: z.number().positive().optional(),
|
||||
typingIntervalSeconds: z.number().int().positive().optional(),
|
||||
typingMode: z
|
||||
|
||||
Loading…
Reference in New Issue
Block a user