refactor: centralize agent concurrency defaults
This commit is contained in:
@@ -7,6 +7,7 @@ Docs: https://docs.clawd.bot
|
|||||||
### Changes
|
### Changes
|
||||||
- Repo: remove the Peekaboo git submodule now that the SPM release is used.
|
- Repo: remove the Peekaboo git submodule now that the SPM release is used.
|
||||||
- Gateway: raise default lane concurrency for main and sub-agent runs.
|
- Gateway: raise default lane concurrency for main and sub-agent runs.
|
||||||
|
- Config: centralize default agent concurrency limits.
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Web search: infer Perplexity base URL from API key source (direct vs OpenRouter).
|
- Web search: infer Perplexity base URL from API key source (direct vs OpenRouter).
|
||||||
|
|||||||
2
src/config/agent-limits.ts
Normal file
2
src/config/agent-limits.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export const DEFAULT_AGENT_MAX_CONCURRENT = 4;
|
||||||
|
export const DEFAULT_SUBAGENT_MAX_CONCURRENT = 8;
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { resolveTalkApiKey } from "./talk.js";
|
import { resolveTalkApiKey } from "./talk.js";
|
||||||
import type { ClawdbotConfig } from "./types.js";
|
import type { ClawdbotConfig } from "./types.js";
|
||||||
|
import { DEFAULT_AGENT_MAX_CONCURRENT, DEFAULT_SUBAGENT_MAX_CONCURRENT } from "./agent-limits.js";
|
||||||
|
|
||||||
type WarnState = { warned: boolean };
|
type WarnState = { warned: boolean };
|
||||||
|
|
||||||
@@ -105,6 +106,43 @@ export function applyModelDefaults(cfg: ClawdbotConfig): ClawdbotConfig {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function applyAgentDefaults(cfg: ClawdbotConfig): ClawdbotConfig {
|
||||||
|
const agents = cfg.agents;
|
||||||
|
const defaults = agents?.defaults;
|
||||||
|
const hasMax =
|
||||||
|
typeof defaults?.maxConcurrent === "number" && Number.isFinite(defaults.maxConcurrent);
|
||||||
|
const hasSubMax =
|
||||||
|
typeof defaults?.subagents?.maxConcurrent === "number" &&
|
||||||
|
Number.isFinite(defaults.subagents.maxConcurrent);
|
||||||
|
if (hasMax && hasSubMax) return cfg;
|
||||||
|
|
||||||
|
let mutated = false;
|
||||||
|
const nextDefaults = defaults ? { ...defaults } : {};
|
||||||
|
if (!hasMax) {
|
||||||
|
nextDefaults.maxConcurrent = DEFAULT_AGENT_MAX_CONCURRENT;
|
||||||
|
mutated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextSubagents = defaults?.subagents ? { ...defaults.subagents } : {};
|
||||||
|
if (!hasSubMax) {
|
||||||
|
nextSubagents.maxConcurrent = DEFAULT_SUBAGENT_MAX_CONCURRENT;
|
||||||
|
mutated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mutated) return cfg;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...cfg,
|
||||||
|
agents: {
|
||||||
|
...agents,
|
||||||
|
defaults: {
|
||||||
|
...nextDefaults,
|
||||||
|
subagents: nextSubagents,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function applyLoggingDefaults(cfg: ClawdbotConfig): ClawdbotConfig {
|
export function applyLoggingDefaults(cfg: ClawdbotConfig): ClawdbotConfig {
|
||||||
const logging = cfg.logging;
|
const logging = cfg.logging;
|
||||||
if (!logging) return cfg;
|
if (!logging) return cfg;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { DuplicateAgentDirError, findDuplicateAgentDirs } from "./agent-dirs.js"
|
|||||||
import {
|
import {
|
||||||
applyCompactionDefaults,
|
applyCompactionDefaults,
|
||||||
applyContextPruningDefaults,
|
applyContextPruningDefaults,
|
||||||
|
applyAgentDefaults,
|
||||||
applyLoggingDefaults,
|
applyLoggingDefaults,
|
||||||
applyMessageDefaults,
|
applyMessageDefaults,
|
||||||
applyModelDefaults,
|
applyModelDefaults,
|
||||||
@@ -244,8 +245,10 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
|
|||||||
const cfg = applyModelDefaults(
|
const cfg = applyModelDefaults(
|
||||||
applyCompactionDefaults(
|
applyCompactionDefaults(
|
||||||
applyContextPruningDefaults(
|
applyContextPruningDefaults(
|
||||||
applySessionDefaults(
|
applyAgentDefaults(
|
||||||
applyLoggingDefaults(applyMessageDefaults(validated.data as ClawdbotConfig)),
|
applySessionDefaults(
|
||||||
|
applyLoggingDefaults(applyMessageDefaults(validated.data as ClawdbotConfig)),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -291,7 +294,9 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
|
|||||||
const config = applyTalkApiKey(
|
const config = applyTalkApiKey(
|
||||||
applyModelDefaults(
|
applyModelDefaults(
|
||||||
applyCompactionDefaults(
|
applyCompactionDefaults(
|
||||||
applyContextPruningDefaults(applySessionDefaults(applyMessageDefaults({}))),
|
applyContextPruningDefaults(
|
||||||
|
applyAgentDefaults(applySessionDefaults(applyMessageDefaults({}))),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -402,7 +407,9 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
|
|||||||
config: normalizeConfigPaths(
|
config: normalizeConfigPaths(
|
||||||
applyTalkApiKey(
|
applyTalkApiKey(
|
||||||
applyModelDefaults(
|
applyModelDefaults(
|
||||||
applySessionDefaults(applyLoggingDefaults(applyMessageDefaults(validated.config))),
|
applyAgentDefaults(
|
||||||
|
applySessionDefaults(applyLoggingDefaults(applyMessageDefaults(validated.config))),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { findDuplicateAgentDirs, formatDuplicateAgentDirError } from "./agent-dirs.js";
|
import { findDuplicateAgentDirs, formatDuplicateAgentDirError } from "./agent-dirs.js";
|
||||||
import { applyModelDefaults, applySessionDefaults } from "./defaults.js";
|
import { applyAgentDefaults, applyModelDefaults, applySessionDefaults } from "./defaults.js";
|
||||||
import { findLegacyConfigIssues } from "./legacy.js";
|
import { findLegacyConfigIssues } from "./legacy.js";
|
||||||
import type { ClawdbotConfig, ConfigValidationIssue } from "./types.js";
|
import type { ClawdbotConfig, ConfigValidationIssue } from "./types.js";
|
||||||
import { ClawdbotSchema } from "./zod-schema.js";
|
import { ClawdbotSchema } from "./zod-schema.js";
|
||||||
@@ -41,6 +41,8 @@ export function validateConfigObject(
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
ok: true,
|
ok: true,
|
||||||
config: applyModelDefaults(applySessionDefaults(validated.data as ClawdbotConfig)),
|
config: applyModelDefaults(
|
||||||
|
applyAgentDefaults(applySessionDefaults(validated.data as ClawdbotConfig)),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
import type { loadConfig } from "../config/config.js";
|
import type { loadConfig } from "../config/config.js";
|
||||||
|
import {
|
||||||
|
DEFAULT_AGENT_MAX_CONCURRENT,
|
||||||
|
DEFAULT_SUBAGENT_MAX_CONCURRENT,
|
||||||
|
} from "../config/agent-limits.js";
|
||||||
import { setCommandLaneConcurrency } from "../process/command-queue.js";
|
import { setCommandLaneConcurrency } from "../process/command-queue.js";
|
||||||
|
|
||||||
export function applyGatewayLaneConcurrency(cfg: ReturnType<typeof loadConfig>) {
|
export function applyGatewayLaneConcurrency(cfg: ReturnType<typeof loadConfig>) {
|
||||||
setCommandLaneConcurrency("cron", cfg.cron?.maxConcurrentRuns ?? 1);
|
setCommandLaneConcurrency("cron", cfg.cron?.maxConcurrentRuns ?? 1);
|
||||||
setCommandLaneConcurrency("main", cfg.agents?.defaults?.maxConcurrent ?? 4);
|
setCommandLaneConcurrency(
|
||||||
setCommandLaneConcurrency("subagent", cfg.agents?.defaults?.subagents?.maxConcurrent ?? 8);
|
"main",
|
||||||
|
cfg.agents?.defaults?.maxConcurrent ?? DEFAULT_AGENT_MAX_CONCURRENT,
|
||||||
|
);
|
||||||
|
setCommandLaneConcurrency(
|
||||||
|
"subagent",
|
||||||
|
cfg.agents?.defaults?.subagents?.maxConcurrent ?? DEFAULT_SUBAGENT_MAX_CONCURRENT,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ import {
|
|||||||
setGatewaySigusr1RestartPolicy,
|
setGatewaySigusr1RestartPolicy,
|
||||||
} from "../infra/restart.js";
|
} from "../infra/restart.js";
|
||||||
import { setCommandLaneConcurrency } from "../process/command-queue.js";
|
import { setCommandLaneConcurrency } from "../process/command-queue.js";
|
||||||
|
import {
|
||||||
|
DEFAULT_AGENT_MAX_CONCURRENT,
|
||||||
|
DEFAULT_SUBAGENT_MAX_CONCURRENT,
|
||||||
|
} from "../config/agent-limits.js";
|
||||||
import { isTruthyEnvValue } from "../infra/env.js";
|
import { isTruthyEnvValue } from "../infra/env.js";
|
||||||
import type { ChannelKind, GatewayReloadPlan } from "./config-reload.js";
|
import type { ChannelKind, GatewayReloadPlan } from "./config-reload.js";
|
||||||
import { resolveHooksConfig } from "./hooks.js";
|
import { resolveHooksConfig } from "./hooks.js";
|
||||||
@@ -127,10 +131,13 @@ export function createGatewayReloadHandlers(params: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setCommandLaneConcurrency("cron", nextConfig.cron?.maxConcurrentRuns ?? 1);
|
setCommandLaneConcurrency("cron", nextConfig.cron?.maxConcurrentRuns ?? 1);
|
||||||
setCommandLaneConcurrency("main", nextConfig.agents?.defaults?.maxConcurrent ?? 4);
|
setCommandLaneConcurrency(
|
||||||
|
"main",
|
||||||
|
nextConfig.agents?.defaults?.maxConcurrent ?? DEFAULT_AGENT_MAX_CONCURRENT,
|
||||||
|
);
|
||||||
setCommandLaneConcurrency(
|
setCommandLaneConcurrency(
|
||||||
"subagent",
|
"subagent",
|
||||||
nextConfig.agents?.defaults?.subagents?.maxConcurrent ?? 8,
|
nextConfig.agents?.defaults?.subagents?.maxConcurrent ?? DEFAULT_SUBAGENT_MAX_CONCURRENT,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (plan.hotReasons.length > 0) {
|
if (plan.hotReasons.length > 0) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { type RunOptions, run } from "@grammyjs/runner";
|
import { type RunOptions, run } from "@grammyjs/runner";
|
||||||
import type { ClawdbotConfig } from "../config/config.js";
|
import type { ClawdbotConfig } from "../config/config.js";
|
||||||
import { loadConfig } from "../config/config.js";
|
import { loadConfig } from "../config/config.js";
|
||||||
|
import { DEFAULT_AGENT_MAX_CONCURRENT } from "../config/agent-limits.js";
|
||||||
import { computeBackoff, sleepWithAbort } from "../infra/backoff.js";
|
import { computeBackoff, sleepWithAbort } from "../infra/backoff.js";
|
||||||
import { formatDurationMs } from "../infra/format-duration.js";
|
import { formatDurationMs } from "../infra/format-duration.js";
|
||||||
import type { RuntimeEnv } from "../runtime.js";
|
import type { RuntimeEnv } from "../runtime.js";
|
||||||
@@ -28,7 +29,7 @@ export type MonitorTelegramOpts = {
|
|||||||
export function createTelegramRunnerOptions(cfg: ClawdbotConfig): RunOptions<unknown> {
|
export function createTelegramRunnerOptions(cfg: ClawdbotConfig): RunOptions<unknown> {
|
||||||
return {
|
return {
|
||||||
sink: {
|
sink: {
|
||||||
concurrency: cfg.agents?.defaults?.maxConcurrent ?? 1,
|
concurrency: cfg.agents?.defaults?.maxConcurrent ?? DEFAULT_AGENT_MAX_CONCURRENT,
|
||||||
},
|
},
|
||||||
runner: {
|
runner: {
|
||||||
fetch: {
|
fetch: {
|
||||||
|
|||||||
Reference in New Issue
Block a user