negotium 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-helpers.js +146 -23
- package/dist/agent-helpers.js.map +14 -12
- package/dist/cron.js +137 -52
- package/dist/cron.js.map +20 -19
- package/dist/hosted-agent.js +29 -17
- package/dist/hosted-agent.js.map +7 -7
- package/dist/main.js +145 -55
- package/dist/main.js.map +20 -19
- package/dist/mcp-factories.js +23 -22
- package/dist/mcp-factories.js.map +3 -3
- package/dist/prompts.js +98 -9
- package/dist/prompts.js.map +6 -5
- package/dist/runtime/scripts/browser-passkey-policy.mjs +36 -0
- package/dist/runtime/scripts/browser-vault-transform.mjs +33 -0
- package/dist/runtime/scripts/mcp-patchright-http.mjs +22 -4
- package/dist/runtime/src/agents/archiver.ts +0 -14
- package/dist/runtime/src/agents/claude-provider.ts +11 -7
- package/dist/runtime/src/agents/execution-host.ts +10 -1
- package/dist/runtime/src/agents/idle-archiver.ts +21 -0
- package/dist/runtime/src/agents/maestro-provider.ts +9 -14
- package/dist/runtime/src/agents/mcp-tools/self-config.ts +1 -1
- package/dist/runtime/src/agents/mcp-tools/spawn-subagent.ts +6 -1
- package/dist/runtime/src/agents/memory-archive-policy.ts +34 -0
- package/dist/runtime/src/agents/model-catalog.ts +84 -18
- package/dist/runtime/src/mcp/factories/vault.ts +36 -34
- package/dist/runtime/src/mcp/vault-server.ts +1 -0
- package/dist/runtime/src/platform/mcp-config.ts +4 -8
- package/dist/runtime/src/platform/playwright/manager.ts +5 -2
- package/dist/runtime/src/prompts/builders.ts +36 -7
- package/dist/runtime/src/runtime/turn-runner.ts +2 -0
- package/dist/runtime/src/storage/topic-archive.ts +5 -2
- package/dist/runtime/src/topics/lifecycle.ts +2 -1
- package/dist/runtime/src/topics/session.ts +2 -0
- package/dist/runtime/src/version.ts +1 -1
- package/dist/storage.js +23 -3
- package/dist/storage.js.map +5 -4
- package/dist/types/packages/core/src/agents/claude-provider.d.ts +1 -0
- package/dist/types/packages/core/src/agents/execution-host.d.ts +2 -0
- package/dist/types/packages/core/src/agents/idle-archiver.d.ts +2 -0
- package/dist/types/packages/core/src/agents/memory-archive-policy.d.ts +14 -0
- package/dist/types/packages/core/src/agents/model-catalog.d.ts +77 -0
- package/dist/types/packages/core/src/mcp/factories/vault.d.ts +1 -0
- package/dist/types/packages/core/src/prompts/builders.d.ts +5 -1
- package/dist/types/packages/core/src/storage/topic-archive.d.ts +1 -0
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/package.json +2 -2
package/dist/cron.js
CHANGED
|
@@ -1947,6 +1947,19 @@ function vaultListWithValues(userId) {
|
|
|
1947
1947
|
function vaultList(userId) {
|
|
1948
1948
|
return activeVaultDatabase().prepare("SELECT key, description FROM vault WHERE user_id = ? ORDER BY key").all(userId);
|
|
1949
1949
|
}
|
|
1950
|
+
function vaultSubstituteDetailed(userId, text) {
|
|
1951
|
+
const entries = new Map(vaultListWithValues(userId).map((entry) => [entry.key, entry.value]));
|
|
1952
|
+
const usedKeys = new Set;
|
|
1953
|
+
const substituted = text.replace(/\{\{([^}]+)\}\}/g, (match, rawKey) => {
|
|
1954
|
+
const key = normalizeVaultKey(rawKey);
|
|
1955
|
+
const value = entries.get(key);
|
|
1956
|
+
if (value === undefined)
|
|
1957
|
+
return match;
|
|
1958
|
+
usedKeys.add(key);
|
|
1959
|
+
return value;
|
|
1960
|
+
});
|
|
1961
|
+
return { text: substituted, usedKeys: [...usedKeys] };
|
|
1962
|
+
}
|
|
1950
1963
|
function valueReferencesVaultKey(userId, value) {
|
|
1951
1964
|
const keys = new Set(vaultList(userId).map((entry) => entry.key));
|
|
1952
1965
|
const visit = (candidate) => {
|
|
@@ -2037,7 +2050,7 @@ function createVaultToolPolicy(host) {
|
|
|
2037
2050
|
}
|
|
2038
2051
|
return { isVaultBrokerTool, referencesRuntimeSecretStorage, shouldRedirectVaultTool };
|
|
2039
2052
|
}
|
|
2040
|
-
var SENSITIVE_RUNTIME_NAMES,
|
|
2053
|
+
var SENSITIVE_RUNTIME_NAMES, defaultVaultToolPolicy, isVaultBrokerTool, referencesRuntimeSecretStorage, shouldRedirectVaultTool;
|
|
2041
2054
|
var init_vault_tool_policy = __esm(async () => {
|
|
2042
2055
|
init_sensitive_path();
|
|
2043
2056
|
await init_vault();
|
|
@@ -2838,9 +2851,7 @@ var init_mcp_config = __esm(() => {
|
|
|
2838
2851
|
vault: {
|
|
2839
2852
|
...commonRuntimeMcpPolicy("vault"),
|
|
2840
2853
|
build({ userId, agent }) {
|
|
2841
|
-
const args = [`--user-id=${userId}
|
|
2842
|
-
if (agent === "codex")
|
|
2843
|
-
args.push("--http-only=true");
|
|
2854
|
+
const args = [`--user-id=${userId}`, "--list-only=true"];
|
|
2844
2855
|
return buildStdioMcpServer(agent, VAULT_SERVER, args);
|
|
2845
2856
|
}
|
|
2846
2857
|
}
|
|
@@ -2870,12 +2881,12 @@ function hostedMcpServers(opts) {
|
|
|
2870
2881
|
function redactHostedSecrets(userId, value) {
|
|
2871
2882
|
return activeHost().redactVaultSecrets(userId, value);
|
|
2872
2883
|
}
|
|
2884
|
+
function substituteHostedSecrets(userId, value) {
|
|
2885
|
+
return activeHost().substituteVaultSecrets(userId, value);
|
|
2886
|
+
}
|
|
2873
2887
|
function referencesHostedSecretStorage(value) {
|
|
2874
2888
|
return activeHost().referencesRuntimeSecretStorage(value);
|
|
2875
2889
|
}
|
|
2876
|
-
function shouldRedirectHostedVaultTool(userId, toolName, input) {
|
|
2877
|
-
return activeHost().shouldRedirectVaultTool(userId, toolName, input);
|
|
2878
|
-
}
|
|
2879
2890
|
function hostedClaudeCodeExecutablePath() {
|
|
2880
2891
|
return activeHost().claudeCodeExecutablePath();
|
|
2881
2892
|
}
|
|
@@ -2891,6 +2902,7 @@ var init_execution_host = __esm(async () => {
|
|
|
2891
2902
|
defaultHost = {
|
|
2892
2903
|
getMcpServersForQuery,
|
|
2893
2904
|
redactVaultSecrets,
|
|
2905
|
+
substituteVaultSecrets: (userId, value) => vaultSubstituteDetailed(userId, value).text,
|
|
2894
2906
|
referencesRuntimeSecretStorage,
|
|
2895
2907
|
shouldRedirectVaultTool,
|
|
2896
2908
|
claudeCodeExecutablePath: () => CLAUDE_EXECUTABLE,
|
|
@@ -2985,6 +2997,9 @@ var DEFAULT_CONTEXT_WARNING_RATIO = 0.8;
|
|
|
2985
2997
|
import { spawn as spawn2 } from "child_process";
|
|
2986
2998
|
import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
|
|
2987
2999
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
3000
|
+
function substituteClaudeToolInput(userId, input) {
|
|
3001
|
+
return deepMapStrings(input, (value) => substituteHostedSecrets(userId, value));
|
|
3002
|
+
}
|
|
2988
3003
|
function buildClaudeDisallowedTools(extra = undefined) {
|
|
2989
3004
|
return [
|
|
2990
3005
|
...new Set([
|
|
@@ -3215,14 +3230,14 @@ async function* claudeProvider(opts) {
|
|
|
3215
3230
|
};
|
|
3216
3231
|
}
|
|
3217
3232
|
const userId = opts.userId ?? "";
|
|
3218
|
-
|
|
3233
|
+
const withVault = substituteClaudeToolInput(userId, tool_input);
|
|
3234
|
+
if (JSON.stringify(withVault) === JSON.stringify(tool_input)) {
|
|
3219
3235
|
return { continue: true };
|
|
3220
3236
|
}
|
|
3221
3237
|
return {
|
|
3222
3238
|
hookSpecificOutput: {
|
|
3223
3239
|
hookEventName: "PreToolUse",
|
|
3224
|
-
|
|
3225
|
-
permissionDecisionReason: VAULT_BROKER_REDIRECT_ERROR
|
|
3240
|
+
updatedInput: withVault
|
|
3226
3241
|
}
|
|
3227
3242
|
};
|
|
3228
3243
|
}
|
|
@@ -3432,7 +3447,6 @@ var CLAUDE_DEFAULT_DISALLOWED_TOOLS, CLAUDE_NATIVE_AGENT_TOOLS, CLAUDE_IMAGE_MAX
|
|
|
3432
3447
|
var init_claude_provider = __esm(async () => {
|
|
3433
3448
|
init_claude_registry();
|
|
3434
3449
|
await init_execution_host();
|
|
3435
|
-
await init_vault_tool_policy();
|
|
3436
3450
|
init_file_events();
|
|
3437
3451
|
init_logger();
|
|
3438
3452
|
CLAUDE_DEFAULT_DISALLOWED_TOOLS = [
|
|
@@ -3455,7 +3469,7 @@ var init_claude_provider = __esm(async () => {
|
|
|
3455
3469
|
});
|
|
3456
3470
|
|
|
3457
3471
|
// ../../packages/core/src/version.ts
|
|
3458
|
-
var NEGOTIUM_VERSION = "0.1.
|
|
3472
|
+
var NEGOTIUM_VERSION = "0.1.21";
|
|
3459
3473
|
|
|
3460
3474
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
3461
3475
|
import { spawn as spawn3 } from "child_process";
|
|
@@ -4093,14 +4107,12 @@ function buildMaestroDisallowedTools(callerDisallowedTools = []) {
|
|
|
4093
4107
|
function buildVaultHook(userId) {
|
|
4094
4108
|
return {
|
|
4095
4109
|
name: "vault-guard",
|
|
4096
|
-
pre({
|
|
4110
|
+
pre({ input }) {
|
|
4097
4111
|
if (referencesHostedSecretStorage(input)) {
|
|
4098
4112
|
return { decision: "block", error: "Runtime secret storage access is not permitted" };
|
|
4099
4113
|
}
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
}
|
|
4103
|
-
return { decision: "allow" };
|
|
4114
|
+
const substituted = deepMapStrings(input, (value) => substituteHostedSecrets(userId, value));
|
|
4115
|
+
return JSON.stringify(substituted) === JSON.stringify(input) ? { decision: "allow" } : { decision: "modify", input: substituted };
|
|
4104
4116
|
},
|
|
4105
4117
|
post({ output }) {
|
|
4106
4118
|
const redacted = redactHostedSecrets(userId, output);
|
|
@@ -4156,7 +4168,6 @@ var MAESTRO_DEFAULT_MAX_TOKENS = 32768, PROVIDER_ASK_USER_TOOL = "AskUserQuestio
|
|
|
4156
4168
|
var init_maestro_provider = __esm(async () => {
|
|
4157
4169
|
init_maestro_bootstrap_env();
|
|
4158
4170
|
await init_execution_host();
|
|
4159
|
-
await init_vault_tool_policy();
|
|
4160
4171
|
MAESTRO_NATIVE_TASK_TOOLS = [
|
|
4161
4172
|
"TaskCreate",
|
|
4162
4173
|
"TaskUpdate",
|
|
@@ -5437,6 +5448,10 @@ var init_ask_user = __esm(async () => {
|
|
|
5437
5448
|
});
|
|
5438
5449
|
|
|
5439
5450
|
// ../../packages/core/src/agents/model-catalog.ts
|
|
5451
|
+
function formatSelectableModel(candidate) {
|
|
5452
|
+
const tier = `${candidate.intelligenceTier[0].toUpperCase()}${candidate.intelligenceTier.slice(1)}`;
|
|
5453
|
+
return `${candidate.agent} / \`${candidate.model}\` [${tier}-level]: ${candidate.routingSummary}`;
|
|
5454
|
+
}
|
|
5440
5455
|
function selectableModel(value) {
|
|
5441
5456
|
const normalized = value.trim().toLowerCase();
|
|
5442
5457
|
return SELECTABLE_MODELS.find((candidate) => candidate.model === normalized);
|
|
@@ -5459,7 +5474,7 @@ function resolveModelForAgent(agent, requested, registry) {
|
|
|
5459
5474
|
return defaultModel;
|
|
5460
5475
|
return registry.validateModel(requested) ? requested : defaultModel;
|
|
5461
5476
|
}
|
|
5462
|
-
var MODEL_OWNER, SELECTABLE_MODELS, FALLBACK_ORDER, AGENT_DISPLAY_NAME;
|
|
5477
|
+
var MODEL_OWNER, MODEL_COST_RESEARCHED_AT = "2026-07-19", MODEL_COST_ROUTING_SUMMARY = "Cost basis (2026-07-19): Codex Pro 20x and Claude Max 20x are each $200/month; DeepSeek Pro is pay-per-token. Relative marginal token cost: DeepSeek Pro << Codex < Claude.", CODEX_PRO_20X_COST = "ChatGPT Pro 20x subscription: $200/month", CODEX_COMMUNITY_WEEKLY = "Community plan-level observation: roughly 2\u20134B raw/cached tokens per week; fresh-input equivalent is much lower and unstable (low confidence)", CLAUDE_MAX_20X_COST = "Claude Max 20x subscription: $200/month", CLAUDE_COMMUNITY_SESSION = "Community observations vary from roughly 220\u2013250K locally displayed tokens per 5-hour session to billions of cache-heavy raw tokens per week; calibrated reports value a full weekly allowance around $680\u2013$1,900 at API rates. Recent heavy-model reports reach the weekly cap after about 4\u20135 full sessions (low confidence; not a token cap)", SELECTABLE_MODELS, FALLBACK_ORDER, AGENT_DISPLAY_NAME;
|
|
5463
5478
|
var init_model_catalog = __esm(() => {
|
|
5464
5479
|
init_config();
|
|
5465
5480
|
MODEL_OWNER = {
|
|
@@ -5479,47 +5494,72 @@ var init_model_catalog = __esm(() => {
|
|
|
5479
5494
|
{
|
|
5480
5495
|
model: "gpt-5.6-sol",
|
|
5481
5496
|
agent: "codex",
|
|
5482
|
-
description: "
|
|
5497
|
+
description: "Highest-capability Codex route for the hardest agentic coding work.",
|
|
5498
|
+
intelligenceTier: "fable",
|
|
5499
|
+
routingSummary: "hardest coding work; 5x Codex quota cost",
|
|
5500
|
+
accessCost: CODEX_PRO_20X_COST,
|
|
5501
|
+
marginalTokenCost: "Codex credits: $5/M uncached input, $0.50/M cached input, $30/M output",
|
|
5502
|
+
estimatedUsage: `Official Pro 20x range: 300\u20131,800 local messages per 5 hours; quota weight 5x Luna. ${CODEX_COMMUNITY_WEEKLY}`
|
|
5483
5503
|
},
|
|
5484
5504
|
{
|
|
5485
5505
|
model: "gpt-5.6-terra",
|
|
5486
5506
|
agent: "codex",
|
|
5487
|
-
description: "
|
|
5507
|
+
description: "High-capability Codex route for complex coding and reasoning.",
|
|
5508
|
+
intelligenceTier: "opus",
|
|
5509
|
+
routingSummary: "complex coding and reasoning; 2.5x Codex quota cost",
|
|
5510
|
+
accessCost: CODEX_PRO_20X_COST,
|
|
5511
|
+
marginalTokenCost: "Codex credits: $2.50/M uncached input, $0.25/M cached input, $15/M output",
|
|
5512
|
+
estimatedUsage: `Official Pro 20x range: 400\u20132,200 local messages per 5 hours; quota weight 2.5x Luna. ${CODEX_COMMUNITY_WEEKLY}`
|
|
5488
5513
|
},
|
|
5489
5514
|
{
|
|
5490
5515
|
model: "gpt-5.6-luna",
|
|
5491
5516
|
agent: "codex",
|
|
5492
|
-
description: "
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5517
|
+
description: "Default Codex route with strong everyday coding intelligence.",
|
|
5518
|
+
intelligenceTier: "sonnet",
|
|
5519
|
+
routingSummary: "everyday coding default; lowest Codex quota cost (1x)",
|
|
5520
|
+
accessCost: CODEX_PRO_20X_COST,
|
|
5521
|
+
marginalTokenCost: "Codex credits: $1/M uncached input, $0.10/M cached input, $6/M output",
|
|
5522
|
+
estimatedUsage: `Official Pro 20x range: 1,000\u20135,600 local messages per 5 hours; lowest Codex quota weight (1x). ${CODEX_COMMUNITY_WEEKLY}`
|
|
5498
5523
|
},
|
|
5499
5524
|
{
|
|
5500
5525
|
model: "fable",
|
|
5501
5526
|
agent: "claude",
|
|
5502
|
-
description: "
|
|
5527
|
+
description: "Highest-capability Claude route for the hardest and longest-running tasks.",
|
|
5528
|
+
intelligenceTier: "fable",
|
|
5529
|
+
routingSummary: "hardest long-running work; highest Claude cost; explicit request only",
|
|
5530
|
+
accessCost: CLAUDE_MAX_20X_COST,
|
|
5531
|
+
marginalTokenCost: "Claude API/extra usage: $10/M input, $12.50/M cache write, $1/M cache read, $50/M output",
|
|
5532
|
+
estimatedUsage: `${CLAUDE_COMMUNITY_SESSION}; Fable drains weighted quota fastest, so use only on explicit user request. No stable per-model token cap is published.`
|
|
5503
5533
|
},
|
|
5504
5534
|
{
|
|
5505
5535
|
model: "opus",
|
|
5506
5536
|
agent: "claude",
|
|
5507
|
-
description: "
|
|
5537
|
+
description: "High-capability Claude route for complex reasoning and tool-heavy work.",
|
|
5538
|
+
intelligenceTier: "opus",
|
|
5539
|
+
routingSummary: "complex reasoning and tool-heavy work; about 2.5x Sonnet marginal cost",
|
|
5540
|
+
accessCost: CLAUDE_MAX_20X_COST,
|
|
5541
|
+
marginalTokenCost: "Claude API/extra usage: $5/M input, $6.25/M cache write, $0.50/M cache read, $25/M output",
|
|
5542
|
+
estimatedUsage: `${CLAUDE_COMMUNITY_SESSION}; Opus uses the shared all-model weekly pool more quickly than Sonnet. No stable per-model token cap is published.`
|
|
5508
5543
|
},
|
|
5509
5544
|
{
|
|
5510
5545
|
model: "sonnet",
|
|
5511
5546
|
agent: "claude",
|
|
5512
|
-
description: "
|
|
5547
|
+
description: "Default Claude route for capable, efficient everyday work.",
|
|
5548
|
+
intelligenceTier: "sonnet",
|
|
5549
|
+
routingSummary: "capable everyday default; lowest Claude model cost",
|
|
5550
|
+
accessCost: CLAUDE_MAX_20X_COST,
|
|
5551
|
+
marginalTokenCost: "Claude API/extra usage introductory rate: $2/M input, $2.50/M cache write, $0.20/M cache read, $10/M output through 2026-08-31; then $3/M input and $15/M output",
|
|
5552
|
+
estimatedUsage: `${CLAUDE_COMMUNITY_SESSION}; Sonnet also has a separate weekly allowance and normally provides the highest Claude throughput. No stable weekly token cap is published.`
|
|
5513
5553
|
},
|
|
5514
5554
|
{
|
|
5515
5555
|
model: "deepseek-pro",
|
|
5516
5556
|
agent: "maestro",
|
|
5517
|
-
description: "Sonnet-level
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5557
|
+
description: "API-priced Sonnet-level route for cost-efficient everyday work.",
|
|
5558
|
+
intelligenceTier: "sonnet",
|
|
5559
|
+
routingSummary: "cost-efficient everyday work; pay-per-token and cheapest route",
|
|
5560
|
+
accessCost: "DeepSeek V4 Pro pay-as-you-go API; no monthly subscription required",
|
|
5561
|
+
marginalTokenCost: "DeepSeek API: $0.435/M uncached input, $0.003625/M cached input, $0.87/M output",
|
|
5562
|
+
estimatedUsage: "No subscription token cap; pay per token. Official account concurrency limit is 500 requests."
|
|
5523
5563
|
}
|
|
5524
5564
|
];
|
|
5525
5565
|
FALLBACK_ORDER = {
|
|
@@ -6155,6 +6195,7 @@ async function spawnPlaywright(instanceKey, userId, reservedPort, browserBin = P
|
|
|
6155
6195
|
String(port),
|
|
6156
6196
|
"--host",
|
|
6157
6197
|
"127.0.0.1",
|
|
6198
|
+
"--headed",
|
|
6158
6199
|
"--user-data-dir",
|
|
6159
6200
|
userDataDir
|
|
6160
6201
|
];
|
|
@@ -6163,6 +6204,7 @@ async function spawnPlaywright(instanceKey, userId, reservedPort, browserBin = P
|
|
|
6163
6204
|
const childEnv = {
|
|
6164
6205
|
...process.env,
|
|
6165
6206
|
NEGOTIUM_BROWSER_CAPABILITY: capability,
|
|
6207
|
+
NEGOTIUM_BROWSER_VAULT_USER_ID: userId,
|
|
6166
6208
|
...proxy ? {
|
|
6167
6209
|
NEGOTIUM_BROWSER_PROXY_SERVER: proxy.server,
|
|
6168
6210
|
...proxy.username ? { NEGOTIUM_BROWSER_PROXY_USERNAME: proxy.username } : {},
|
|
@@ -6994,7 +7036,7 @@ function loadAgentPrompt(filename) {
|
|
|
6994
7036
|
prompt: match[2].trim()
|
|
6995
7037
|
};
|
|
6996
7038
|
}
|
|
6997
|
-
function buildRuntimeToolSection(agentKind, canSpawnSubagents = false, visualTools = false, fileDeliveryTools = false) {
|
|
7039
|
+
function buildRuntimeToolSection(agentKind, canSpawnSubagents = false, visualTools = false, fileDeliveryTools = false, currentModel, currentEffort) {
|
|
6998
7040
|
const runtimeNamespace = "mcp__runtime";
|
|
6999
7041
|
const taskNamespace = "mcp__task";
|
|
7000
7042
|
const visualToolLine = agentKind === "codex" ? `To display charts, tables, or interactive HTML results to the user, call the \`show_html\` function in the \`${runtimeNamespace}\` namespace with { html: "<complete HTML string>", title?: "optional title" }.` : `To display charts, tables, or interactive HTML results to the user, call the MCP tool "${runtimeNamespace}__show_html" with { html: "<complete HTML string>", title?: "optional title" }.`;
|
|
@@ -7052,20 +7094,26 @@ function buildRuntimeToolSection(agentKind, canSpawnSubagents = false, visualToo
|
|
|
7052
7094
|
"Do not use session communication to make another topic perform destructive changes without the user's clear intent.",
|
|
7053
7095
|
...spawnSubagentSection
|
|
7054
7096
|
];
|
|
7097
|
+
const modelCatalog = SELECTABLE_MODELS.map((candidate) => `- ${formatSelectableModel(candidate)}`);
|
|
7055
7098
|
const topicConfig = [
|
|
7056
7099
|
"",
|
|
7057
7100
|
"## Topic Configuration (model / agent / effort)",
|
|
7101
|
+
`Current execution: agent=\`${agentKind}\`, model=\`${currentModel ?? "unknown (call get_model)"}\`, effort=\`${currentEffort ?? "provider default/off"}\`.`,
|
|
7058
7102
|
"The user's configured agent/model/effort is intentional. Preserve it by default.",
|
|
7059
7103
|
`When the user explicitly asks to change the model, agent backend, or reasoning effort for THIS topic, call "${runtimeNamespace}__set_model", "${runtimeNamespace}__set_agent", or "${runtimeNamespace}__set_effort". The change applies from your NEXT turn. After calling, briefly confirm and the system will continue with the new setting.`,
|
|
7060
7104
|
"`set_effort` is available but discouraged; use it only when the user explicitly requests an effort change.",
|
|
7061
|
-
"`set_model` may be called autonomously only when the current model is clearly below the task's required capability, such as complex algorithm design, proof-level math, or broad multi-file refactoring.
|
|
7105
|
+
"`set_model` may be called autonomously only when the current model is clearly below the task's required capability, such as complex algorithm design, proof-level math, or broad multi-file refactoring. Choose the best-fit model directly from the same-agent catalog; model selection is not a mandatory one-step ladder. End the turn after changing it. Do not use vague task complexity as a trigger.",
|
|
7062
7106
|
"`set_agent` autonomous calls are forbidden. Only switch agent when the user explicitly asks to switch runtime, e.g. \u201Ccodex\uB85C \uAC00\u201D, \u201Cclaude\uB85C \uBC14\uAFD4\u201D.",
|
|
7063
7107
|
"Never use `fable` unless the user explicitly requests it; it is expensive.",
|
|
7064
7108
|
"",
|
|
7065
|
-
"
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
"
|
|
7109
|
+
"Model catalog (capability/cost routing guidance):",
|
|
7110
|
+
MODEL_COST_ROUTING_SUMMARY,
|
|
7111
|
+
...modelCatalog,
|
|
7112
|
+
"",
|
|
7113
|
+
"Accepted effort values:",
|
|
7114
|
+
"- claude: `low`, `medium`, `high`, `xhigh`, `max`.",
|
|
7115
|
+
"- codex: `low`, `medium`, `high`, `xhigh`, `max`.",
|
|
7116
|
+
"- maestro: `low`, `medium`, `high`, `xhigh`, `max`.",
|
|
7069
7117
|
"Agent guidance when the user explicitly asks to switch: `codex` for deepest reasoning and complex code/math; `claude` for tool-heavy MCP/file automation; `maestro` for inexpensive fast drafts and lighter experiments."
|
|
7070
7118
|
];
|
|
7071
7119
|
if (agentKind !== "claude") {
|
|
@@ -7088,7 +7136,7 @@ function buildTopicSystemPrompt(opts) {
|
|
|
7088
7136
|
TOPIC_TITLE: opts.topicTitle,
|
|
7089
7137
|
WORKSPACE_CWD: opts.workspaceCwd,
|
|
7090
7138
|
UPLOADS_DIR: uploadsDir
|
|
7091
|
-
}) + buildRuntimeToolSection(opts.agentKind, opts.canSpawnSubagents, opts.visualTools, opts.fileDeliveryTools);
|
|
7139
|
+
}) + buildRuntimeToolSection(opts.agentKind, opts.canSpawnSubagents, opts.visualTools, opts.fileDeliveryTools, opts.currentModel, opts.currentEffort);
|
|
7092
7140
|
if (opts.description?.trim()) {
|
|
7093
7141
|
prompt += `
|
|
7094
7142
|
|
|
@@ -7104,7 +7152,7 @@ function buildChannelSystemPrompt(opts) {
|
|
|
7104
7152
|
TOPIC_TITLE: opts.topicTitle,
|
|
7105
7153
|
WORKSPACE_CWD: opts.workspaceCwd,
|
|
7106
7154
|
UPLOADS_DIR: uploadsDir
|
|
7107
|
-
}) + buildRuntimeToolSection(opts.agentKind, false, opts.visualTools, opts.fileDeliveryTools);
|
|
7155
|
+
}) + buildRuntimeToolSection(opts.agentKind, false, opts.visualTools, opts.fileDeliveryTools, opts.currentModel, opts.currentEffort);
|
|
7108
7156
|
}
|
|
7109
7157
|
function buildManagerSystemPrompt(opts) {
|
|
7110
7158
|
return `${buildTopicSystemPrompt(opts)}
|
|
@@ -7154,6 +7202,7 @@ User-uploaded files for this Channel are copied under "{{UPLOADS_DIR}}" as attac
|
|
|
7154
7202
|
This is the shared "General" hub of the user's workspace.
|
|
7155
7203
|
Act as the workspace manager: orient the user across topics, summarize what is going on, and route focused work to the right room.`, _topicSystemPromptTemplate = null, _channelSystemPromptTemplate = null, _managerSystemPromptTemplate = null, _visualDesignGuide = null;
|
|
7156
7204
|
var init_builders = __esm(() => {
|
|
7205
|
+
init_model_catalog();
|
|
7157
7206
|
init_config();
|
|
7158
7207
|
init_logger();
|
|
7159
7208
|
PROMPTS_DIR = resolve6(PROJECT_ROOT, "src/prompts");
|
|
@@ -7266,10 +7315,6 @@ function getArchiverDef() {
|
|
|
7266
7315
|
}
|
|
7267
7316
|
function runArchiverTurn(params) {
|
|
7268
7317
|
const { userId, topicId, topicTitle, archivePath, messageCount, mode = "deleted-topic" } = params;
|
|
7269
|
-
if (mode !== "active-topic" && messageCount < MIN_ARCHIVE_MESSAGES) {
|
|
7270
|
-
logger.info({ userId, topicTitle, messageCount, min: MIN_ARCHIVE_MESSAGES }, "archiver: skipped \u2014 too few messages to distil");
|
|
7271
|
-
return false;
|
|
7272
|
-
}
|
|
7273
7318
|
let archiverDef;
|
|
7274
7319
|
try {
|
|
7275
7320
|
archiverDef = getArchiverDef();
|
|
@@ -7477,7 +7522,7 @@ ${rolled.join(`
|
|
|
7477
7522
|
logger.warn({ err, topicTitle }, "archiver: failed to post #General notification");
|
|
7478
7523
|
}
|
|
7479
7524
|
}
|
|
7480
|
-
var MAX_BRIEF_ENTRIES = 8,
|
|
7525
|
+
var MAX_BRIEF_ENTRIES = 8, MAX_SESSION_STEPS = 20, activeArchiverSessions, _archiverDef = null;
|
|
7481
7526
|
var init_archiver = __esm(async () => {
|
|
7482
7527
|
await init_agents();
|
|
7483
7528
|
await init_bus();
|
|
@@ -7492,6 +7537,25 @@ var init_archiver = __esm(async () => {
|
|
|
7492
7537
|
activeArchiverSessions = new Map;
|
|
7493
7538
|
});
|
|
7494
7539
|
|
|
7540
|
+
// ../../packages/core/src/agents/memory-archive-policy.ts
|
|
7541
|
+
function countMemoryArchiveExchanges(rows) {
|
|
7542
|
+
let waitingForAssistant = false;
|
|
7543
|
+
let completed = 0;
|
|
7544
|
+
for (const row of rows) {
|
|
7545
|
+
const assistant = row.author_id === "ai" || Boolean(row.agent_type);
|
|
7546
|
+
const conversational = row.kind == null || row.kind === "message";
|
|
7547
|
+
if (!assistant && row.author_id !== "system" && conversational) {
|
|
7548
|
+
waitingForAssistant = true;
|
|
7549
|
+
continue;
|
|
7550
|
+
}
|
|
7551
|
+
if (assistant && conversational && waitingForAssistant) {
|
|
7552
|
+
completed++;
|
|
7553
|
+
waitingForAssistant = false;
|
|
7554
|
+
}
|
|
7555
|
+
}
|
|
7556
|
+
return completed;
|
|
7557
|
+
}
|
|
7558
|
+
|
|
7495
7559
|
// ../../packages/core/src/storage/topic-transcript.ts
|
|
7496
7560
|
function parseJsonField(value) {
|
|
7497
7561
|
if (!value)
|
|
@@ -7579,8 +7643,9 @@ function archiveTopicMessages(topicId, topicTitle, options = {}) {
|
|
|
7579
7643
|
counter++;
|
|
7580
7644
|
}
|
|
7581
7645
|
}
|
|
7582
|
-
|
|
7583
|
-
|
|
7646
|
+
const exchangeCount = countMemoryArchiveExchanges(rows);
|
|
7647
|
+
logger.info({ topicId, topicTitle, archive: path, messageCount: rows.length, exchangeCount, lastRowid }, "archiveTopicMessages: archived topic messages");
|
|
7648
|
+
return { path, messageCount: rows.length, exchangeCount, lastRowid };
|
|
7584
7649
|
}
|
|
7585
7650
|
var init_topic_archive = __esm(async () => {
|
|
7586
7651
|
init_logger();
|
|
@@ -7784,6 +7849,7 @@ function archiveActiveTopicForMemory(topicId, userId, options) {
|
|
|
7784
7849
|
if (!options.allowMentionOnly && topic.aiMode === "mention")
|
|
7785
7850
|
return "mention-only-channel";
|
|
7786
7851
|
let skipped = "empty";
|
|
7852
|
+
let skipMemoryTurn = false;
|
|
7787
7853
|
const claim = claimTopicArchiveJob(topicId, (afterRowid) => {
|
|
7788
7854
|
const pending = getMessagesForTopicAfterRowid(topicId, afterRowid);
|
|
7789
7855
|
const minMessages = options.minMessages;
|
|
@@ -7792,6 +7858,8 @@ function archiveActiveTopicForMemory(topicId, userId, options) {
|
|
|
7792
7858
|
logger.debug({ topicId, topicTitle: topic.title, pending: pending.length, minMessages }, "topic-memory-archiver: skipped below threshold");
|
|
7793
7859
|
return null;
|
|
7794
7860
|
}
|
|
7861
|
+
const exchangeCount = countMemoryArchiveExchanges(pending);
|
|
7862
|
+
skipMemoryTurn = options.minExchanges !== undefined && exchangeCount < options.minExchanges;
|
|
7795
7863
|
const archived = (options.archiveMessages ?? archiveTopicMessages)(topicId, topic.title, {
|
|
7796
7864
|
afterRowid,
|
|
7797
7865
|
reason: options.reason
|
|
@@ -7809,6 +7877,18 @@ function archiveActiveTopicForMemory(topicId, userId, options) {
|
|
|
7809
7877
|
if (claim.kind === "busy")
|
|
7810
7878
|
return "busy";
|
|
7811
7879
|
const { job } = claim;
|
|
7880
|
+
if (skipMemoryTurn) {
|
|
7881
|
+
settleTopicArchiveJob(topicId, job.archivePath, true);
|
|
7882
|
+
logger.info({
|
|
7883
|
+
topicId,
|
|
7884
|
+
topicTitle: topic.title,
|
|
7885
|
+
messageCount: job.messageCount,
|
|
7886
|
+
minExchanges: options.minExchanges,
|
|
7887
|
+
archive: job.archivePath,
|
|
7888
|
+
reason: options.reason
|
|
7889
|
+
}, "topic-memory-archiver: raw snapshot preserved below exchange threshold");
|
|
7890
|
+
return "below-threshold";
|
|
7891
|
+
}
|
|
7812
7892
|
const memoryTopic = getTopicMemoryOrigin(topicId) ?? topic;
|
|
7813
7893
|
const launched = (options.launchArchiver ?? runArchiverTurn)({
|
|
7814
7894
|
userId,
|
|
@@ -9711,6 +9791,7 @@ __export(exports_turn_runner, {
|
|
|
9711
9791
|
isPathInside: () => isPathInside,
|
|
9712
9792
|
isLikelyCurrentChannelTrigger: () => isLikelyCurrentChannelTrigger,
|
|
9713
9793
|
ingestAttachment: () => ingestAttachment,
|
|
9794
|
+
formatSelectableModel: () => formatSelectableModel,
|
|
9714
9795
|
formatChannelTranscriptLine: () => formatChannelTranscriptLine,
|
|
9715
9796
|
escapeRegExp: () => escapeRegExp,
|
|
9716
9797
|
escapeHtml: () => escapeHtml2,
|
|
@@ -9728,6 +9809,8 @@ __export(exports_turn_runner, {
|
|
|
9728
9809
|
SESSION_EXPIRED_MSG: () => SESSION_EXPIRED_MSG,
|
|
9729
9810
|
SELECTABLE_MODELS: () => SELECTABLE_MODELS,
|
|
9730
9811
|
MODEL_OWNER: () => MODEL_OWNER,
|
|
9812
|
+
MODEL_COST_ROUTING_SUMMARY: () => MODEL_COST_ROUTING_SUMMARY,
|
|
9813
|
+
MODEL_COST_RESEARCHED_AT: () => MODEL_COST_RESEARCHED_AT,
|
|
9731
9814
|
FALLBACK_ORDER: () => FALLBACK_ORDER,
|
|
9732
9815
|
AGENT_DISPLAY_NAME: () => AGENT_DISPLAY_NAME
|
|
9733
9816
|
});
|
|
@@ -10935,6 +11018,8 @@ function startAiTurn(params) {
|
|
|
10935
11018
|
topicTitle: topic.title,
|
|
10936
11019
|
workspaceCwd,
|
|
10937
11020
|
agentKind,
|
|
11021
|
+
currentModel: resolvedModel,
|
|
11022
|
+
currentEffort: resolvedEffort,
|
|
10938
11023
|
description: topic.description,
|
|
10939
11024
|
canSpawnSubagents: peerBridge?.canSpawnSubagents ?? (topicRecord?.kind === "agent" && !topicRecord.isSubagent),
|
|
10940
11025
|
visualTools,
|
|
@@ -13845,4 +13930,4 @@ export {
|
|
|
13845
13930
|
CRON_CONTEXT_RETAIN_TURNS
|
|
13846
13931
|
};
|
|
13847
13932
|
|
|
13848
|
-
//# debugId=
|
|
13933
|
+
//# debugId=85C745F136B1D17364756E2164756E21
|