negotium 0.5.12 → 0.5.14
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 +40 -29
- package/dist/agent-helpers.js.map +6 -5
- package/dist/hosted-agent.js +2 -2
- package/dist/hosted-agent.js.map +2 -2
- package/dist/main.js +456 -302
- package/dist/main.js.map +8 -6
- package/dist/mcp-factories.js +42 -31
- package/dist/mcp-factories.js.map +6 -5
- package/dist/outbox.js +103 -21
- package/dist/outbox.js.map +5 -4
- package/dist/registry.js +2 -2
- package/dist/registry.js.map +2 -2
- package/dist/runtime/src/outbox/coalescing-runner.ts +157 -0
- package/dist/runtime/src/outbox/index.ts +6 -0
- package/dist/runtime/src/runtime/inbox.ts +64 -15
- package/dist/runtime/src/storage/session-inbox-signal.ts +76 -0
- package/dist/runtime/src/storage/session-inbox.ts +5 -1
- package/dist/runtime/src/version.ts +1 -1
- package/dist/runtime-helpers.js +49 -10
- package/dist/runtime-helpers.js.map +5 -4
- package/dist/types/packages/core/src/outbox/coalescing-runner.d.ts +68 -0
- package/dist/types/packages/core/src/outbox/index.d.ts +1 -0
- package/dist/types/packages/core/src/storage/session-inbox-signal.d.ts +35 -0
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/agent-helpers.js
CHANGED
|
@@ -2443,7 +2443,7 @@ var init_claude_registry = __esm(() => {
|
|
|
2443
2443
|
});
|
|
2444
2444
|
|
|
2445
2445
|
// ../../packages/core/src/version.ts
|
|
2446
|
-
var NEGOTIUM_VERSION = "0.5.
|
|
2446
|
+
var NEGOTIUM_VERSION = "0.5.14";
|
|
2447
2447
|
|
|
2448
2448
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
2449
2449
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -13308,12 +13308,23 @@ var init_session_inbox_path = __esm(() => {
|
|
|
13308
13308
|
init_config();
|
|
13309
13309
|
});
|
|
13310
13310
|
|
|
13311
|
+
// ../../packages/core/src/storage/session-inbox-signal.ts
|
|
13312
|
+
import { join as join23 } from "path";
|
|
13313
|
+
var SESSION_INBOX_WAKE_FILE, listeners;
|
|
13314
|
+
var init_session_inbox_signal = __esm(() => {
|
|
13315
|
+
init_config();
|
|
13316
|
+
init_logger();
|
|
13317
|
+
SESSION_INBOX_WAKE_FILE = join23(SESSION_INBOX_DIR, ".wake");
|
|
13318
|
+
listeners = new Set;
|
|
13319
|
+
});
|
|
13320
|
+
|
|
13311
13321
|
// ../../packages/core/src/storage/session-inbox.ts
|
|
13312
13322
|
function deleteSessionInboxForTopic(topicId) {
|
|
13313
13323
|
return Number(db.run("DELETE FROM session_inbox WHERE topic_id = ?", [topicId]).changes ?? 0);
|
|
13314
13324
|
}
|
|
13315
13325
|
var init_session_inbox = __esm(async () => {
|
|
13316
13326
|
await init_forum_db();
|
|
13327
|
+
init_session_inbox_signal();
|
|
13317
13328
|
await init_storage_host();
|
|
13318
13329
|
registerStorageSchemaInitializer((database) => {
|
|
13319
13330
|
database.exec(`
|
|
@@ -13339,13 +13350,13 @@ var init_session_inbox = __esm(async () => {
|
|
|
13339
13350
|
|
|
13340
13351
|
// ../../packages/core/src/query/session-inbox-cleanup.ts
|
|
13341
13352
|
import { unlinkSync as unlinkSync14 } from "fs";
|
|
13342
|
-
import { basename as basename3, join as
|
|
13353
|
+
import { basename as basename3, join as join24 } from "path";
|
|
13343
13354
|
function cleanupSessionInboxFiles(userId, topicId, legacyTopicTitle) {
|
|
13344
13355
|
const live = sessionInboxPath(userId, topicId);
|
|
13345
13356
|
const scheduled = scheduledSessionInboxPath(userId, topicId);
|
|
13346
13357
|
const candidates = new Set([live, `${live}.processing`, scheduled, `${scheduled}.processing`]);
|
|
13347
13358
|
if (legacyTopicTitle && legacyTopicTitle !== "." && legacyTopicTitle !== ".." && basename3(legacyTopicTitle) === legacyTopicTitle) {
|
|
13348
|
-
const legacyBase =
|
|
13359
|
+
const legacyBase = join24(SESSION_INBOX_DIR, userId, legacyTopicTitle);
|
|
13349
13360
|
for (const suffix of [".jsonl", ".jsonl.processing", ".schedule", ".schedule.processing"]) {
|
|
13350
13361
|
candidates.add(`${legacyBase}${suffix}`);
|
|
13351
13362
|
}
|
|
@@ -13372,16 +13383,16 @@ var init_session_inbox_cleanup = __esm(async () => {
|
|
|
13372
13383
|
|
|
13373
13384
|
// ../../packages/core/src/query/state.ts
|
|
13374
13385
|
import { mkdirSync as mkdirSync14, renameSync as renameSync7, unlinkSync as unlinkSync15, writeFileSync as writeFileSync12 } from "fs";
|
|
13375
|
-
import { basename as basename4, join as
|
|
13386
|
+
import { basename as basename4, join as join25 } from "path";
|
|
13376
13387
|
function createQueryStateStore(options) {
|
|
13377
13388
|
const sanitize = options.sanitizeTopicId ?? sanitizeId;
|
|
13378
|
-
const queryStateDirPath = (userId) =>
|
|
13379
|
-
const queryStateFile = (userId, topicId) =>
|
|
13389
|
+
const queryStateDirPath = (userId) => join25(options.usersLogDir, String(userId), "active-queries");
|
|
13390
|
+
const queryStateFile = (userId, topicId) => join25(queryStateDirPath(userId), `${sanitize(topicId)}.json`);
|
|
13380
13391
|
const legacyQueryStateFile = (userId, topicName) => {
|
|
13381
13392
|
if (!topicName || topicName === "." || topicName === ".." || basename4(topicName) !== topicName) {
|
|
13382
13393
|
return null;
|
|
13383
13394
|
}
|
|
13384
|
-
return
|
|
13395
|
+
return join25(queryStateDirPath(userId), `${topicName}.json`);
|
|
13385
13396
|
};
|
|
13386
13397
|
return {
|
|
13387
13398
|
write(userId, topicId, topicName, task) {
|
|
@@ -13542,29 +13553,29 @@ import {
|
|
|
13542
13553
|
unlinkSync as unlinkSync16,
|
|
13543
13554
|
writeFileSync as writeFileSync13
|
|
13544
13555
|
} from "fs";
|
|
13545
|
-
import { dirname as dirname14, join as
|
|
13556
|
+
import { dirname as dirname14, join as join26 } from "path";
|
|
13546
13557
|
function pendingAskDir(userId) {
|
|
13547
13558
|
const rawUserId = String(userId);
|
|
13548
13559
|
const safeUserId = /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..") ? rawUserId : `sha256-${createHash6("sha256").update(rawUserId).digest("hex")}`;
|
|
13549
|
-
return
|
|
13560
|
+
return join26(resolveStorageSessionAsksDir(), safeUserId);
|
|
13550
13561
|
}
|
|
13551
13562
|
function encodeAskKey(key) {
|
|
13552
13563
|
return JSON.stringify([key.from, key.to]);
|
|
13553
13564
|
}
|
|
13554
13565
|
function pendingAskPath(key) {
|
|
13555
13566
|
const digest = createHash6("sha256").update(encodeAskKey(key)).digest("hex");
|
|
13556
|
-
return
|
|
13567
|
+
return join26(pendingAskDir(key.userId), `${ASK_FILENAME_PREFIX}${digest}.pending`);
|
|
13557
13568
|
}
|
|
13558
13569
|
function v2PendingAskPath(key) {
|
|
13559
13570
|
const encoded = Buffer.from(encodeAskKey(key), "utf8").toString("base64url");
|
|
13560
|
-
return
|
|
13571
|
+
return join26(pendingAskDir(key.userId), `${V2_ASK_FILENAME_PREFIX}${encoded}.pending`);
|
|
13561
13572
|
}
|
|
13562
13573
|
function legacyPendingAskPath(key) {
|
|
13563
13574
|
if (key.from.includes("/") || key.from.includes("\\") || key.to.includes("/") || key.to.includes("\\") || key.from.includes("\x00") || key.to.includes("\x00")) {
|
|
13564
13575
|
return null;
|
|
13565
13576
|
}
|
|
13566
13577
|
const dir = pendingAskDir(key.userId);
|
|
13567
|
-
const candidate =
|
|
13578
|
+
const candidate = join26(dir, `${key.from}___${key.to}.pending`);
|
|
13568
13579
|
return dirname14(candidate) === dir ? candidate : null;
|
|
13569
13580
|
}
|
|
13570
13581
|
function parsePendingAskFilename(fileName) {
|
|
@@ -13805,7 +13816,7 @@ function listPendingAsksForCaller(args) {
|
|
|
13805
13816
|
const parsed = isV3 ? { from: args.from, to: "" } : parsePendingAskFilename(fileName);
|
|
13806
13817
|
if (!parsed)
|
|
13807
13818
|
continue;
|
|
13808
|
-
const path =
|
|
13819
|
+
const path = join26(dir, fileName);
|
|
13809
13820
|
const record = readPendingAskFile(path, {
|
|
13810
13821
|
userId: args.userId,
|
|
13811
13822
|
from: parsed.from,
|
|
@@ -13847,7 +13858,7 @@ function deletePendingAsksForTopic(args) {
|
|
|
13847
13858
|
}
|
|
13848
13859
|
let deleted = 0;
|
|
13849
13860
|
for (const fileName of files) {
|
|
13850
|
-
const path =
|
|
13861
|
+
const path = join26(dir, fileName);
|
|
13851
13862
|
const parsed = parsePendingAskFilename(fileName);
|
|
13852
13863
|
const record = readPendingAskFile(path, {
|
|
13853
13864
|
userId: args.userId,
|
|
@@ -14247,7 +14258,7 @@ body{font-family:system-ui,-apple-system,"Segoe UI",sans-serif;background:var(--
|
|
|
14247
14258
|
// ../../packages/core/src/storage/token-stats.ts
|
|
14248
14259
|
import { createHash as createHash7 } from "crypto";
|
|
14249
14260
|
import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync14 } from "fs";
|
|
14250
|
-
import { join as
|
|
14261
|
+
import { join as join27 } from "path";
|
|
14251
14262
|
function tokenStatsFileId(userId) {
|
|
14252
14263
|
const rawUserId = String(userId);
|
|
14253
14264
|
return /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..") ? rawUserId : `sha256-${createHash7("sha256").update(rawUserId).digest("hex")}`;
|
|
@@ -14256,7 +14267,7 @@ function queriesPath(userId) {
|
|
|
14256
14267
|
const fileId = tokenStatsFileId(userId);
|
|
14257
14268
|
const logDir = resolveStorageLogDir();
|
|
14258
14269
|
mkdirSync16(logDir, { recursive: true });
|
|
14259
|
-
return
|
|
14270
|
+
return join27(logDir, `token-queries-${fileId}.jsonl`);
|
|
14260
14271
|
}
|
|
14261
14272
|
function estimateUsageCost(agent, model, usage) {
|
|
14262
14273
|
const prices = TOKEN_PRICES[`${agent}:${model}`];
|
|
@@ -14600,7 +14611,7 @@ var init_lifecycle = __esm(async () => {
|
|
|
14600
14611
|
// ../../packages/core/src/runtime/attachments.ts
|
|
14601
14612
|
import { randomUUID as randomUUID14 } from "crypto";
|
|
14602
14613
|
import { copyFileSync as copyFileSync2, mkdirSync as mkdirSync17, writeFileSync as writeFileSync15 } from "fs";
|
|
14603
|
-
import { basename as basename5, join as
|
|
14614
|
+
import { basename as basename5, join as join28 } from "path";
|
|
14604
14615
|
function workspaceCwdFor(topicId) {
|
|
14605
14616
|
return resolveTopicWorkspaceDir(topicId);
|
|
14606
14617
|
}
|
|
@@ -14613,7 +14624,7 @@ function materializePromptAttachments(topicId, queryId, attachmentIds) {
|
|
|
14613
14624
|
if (!attachmentIds?.length)
|
|
14614
14625
|
return [];
|
|
14615
14626
|
const out = [];
|
|
14616
|
-
const destDir =
|
|
14627
|
+
const destDir = join28(workspaceCwdFor(topicId), "attachments", queryId);
|
|
14617
14628
|
for (const rawId of attachmentIds) {
|
|
14618
14629
|
if (typeof rawId !== "string")
|
|
14619
14630
|
continue;
|
|
@@ -14630,7 +14641,7 @@ function materializePromptAttachments(topicId, queryId, attachmentIds) {
|
|
|
14630
14641
|
mkdirSync17(destDir, { recursive: true });
|
|
14631
14642
|
const index = String(out.length + 1).padStart(2, "0");
|
|
14632
14643
|
const safeName = safeAttachmentFilename(attachment.filename, fileId);
|
|
14633
|
-
const destPath =
|
|
14644
|
+
const destPath = join28(destDir, `${index}-${fileId.slice(0, 8)}-${safeName}`);
|
|
14634
14645
|
copyFileSync2(sourcePath, destPath);
|
|
14635
14646
|
out.push({
|
|
14636
14647
|
id: attachment.id,
|
|
@@ -14660,10 +14671,10 @@ function promptWithAttachments(prompt, attachments) {
|
|
|
14660
14671
|
return composeAttachmentPrompt(prompt, attachments.map(({ filename, path }) => attachmentPromptLine(filename, path)));
|
|
14661
14672
|
}
|
|
14662
14673
|
function ingestAttachment(args) {
|
|
14663
|
-
const destDir =
|
|
14674
|
+
const destDir = join28(UPLOADS_DIR, args.topicId);
|
|
14664
14675
|
mkdirSync17(destDir, { recursive: true });
|
|
14665
14676
|
const safeName = safeAttachmentFilename(args.filename, "upload");
|
|
14666
|
-
const destPath =
|
|
14677
|
+
const destPath = join28(destDir, `${Date.now()}-${randomUUID14().slice(0, 8)}-${safeName}`);
|
|
14667
14678
|
if (args.sourcePath !== undefined) {
|
|
14668
14679
|
copyFileSync2(args.sourcePath, destPath);
|
|
14669
14680
|
} else if (args.bytes !== undefined) {
|
|
@@ -15958,9 +15969,9 @@ var init_turn_session = __esm(async () => {
|
|
|
15958
15969
|
|
|
15959
15970
|
// ../../packages/core/src/storage/app-settings.ts
|
|
15960
15971
|
import { existsSync as existsSync19, mkdirSync as mkdirSync18, readFileSync as readFileSync17, writeFileSync as writeFileSync16 } from "fs";
|
|
15961
|
-
import { dirname as dirname15, join as
|
|
15972
|
+
import { dirname as dirname15, join as join29 } from "path";
|
|
15962
15973
|
function settingsFile() {
|
|
15963
|
-
return
|
|
15974
|
+
return join29(resolveStorageDataDir(), "otium-settings.json");
|
|
15964
15975
|
}
|
|
15965
15976
|
function getGlobalAiName() {
|
|
15966
15977
|
const path = settingsFile();
|
|
@@ -16055,7 +16066,7 @@ __export(exports_turn_runner, {
|
|
|
16055
16066
|
});
|
|
16056
16067
|
import { randomUUID as randomUUID16 } from "crypto";
|
|
16057
16068
|
import { existsSync as existsSync20, mkdirSync as mkdirSync19, readdirSync as readdirSync5, statSync as statSync10 } from "fs";
|
|
16058
|
-
import { join as
|
|
16069
|
+
import { join as join30 } from "path";
|
|
16059
16070
|
function withDefaultPlaywright(configuredMcp, isManager) {
|
|
16060
16071
|
if (isManager)
|
|
16061
16072
|
return configuredMcp;
|
|
@@ -16110,7 +16121,7 @@ function appendAskReplyMessage(topicId, text2, agentType) {
|
|
|
16110
16121
|
return message;
|
|
16111
16122
|
}
|
|
16112
16123
|
function resolveWikiMirrorPath(directory, preferredFilename, matchesLegacyId, matchesTitle, preferExact = true) {
|
|
16113
|
-
const preferred =
|
|
16124
|
+
const preferred = join30(directory, preferredFilename);
|
|
16114
16125
|
if (preferExact && existsSync20(preferred))
|
|
16115
16126
|
return preferred;
|
|
16116
16127
|
let newestLegacyId = null;
|
|
@@ -16121,7 +16132,7 @@ function resolveWikiMirrorPath(directory, preferredFilename, matchesLegacyId, ma
|
|
|
16121
16132
|
const legacyIdMatch = !titleMatch && matchesLegacyId(filename);
|
|
16122
16133
|
if (!titleMatch && !legacyIdMatch)
|
|
16123
16134
|
continue;
|
|
16124
|
-
const path =
|
|
16135
|
+
const path = join30(directory, filename);
|
|
16125
16136
|
const mtimeMs = statSync10(path).mtimeMs;
|
|
16126
16137
|
if (titleMatch) {
|
|
16127
16138
|
if (!newestTitle || mtimeMs > newestTitle.mtimeMs) {
|
|
@@ -16135,9 +16146,9 @@ function resolveWikiMirrorPath(directory, preferredFilename, matchesLegacyId, ma
|
|
|
16135
16146
|
return newestTitle?.path ?? newestLegacyId?.path ?? preferred;
|
|
16136
16147
|
}
|
|
16137
16148
|
function resolveWikiMemoryMirror(wikiDir, topicId, topicTitle) {
|
|
16138
|
-
const briefFile = resolveWikiMirrorPath(
|
|
16149
|
+
const briefFile = resolveWikiMirrorPath(join30(wikiDir, "topic"), `${wikiBriefStorageKey(topicTitle, topicId)}.md`, (filename) => isTopicBriefFile(filename, topicId), (filename) => isTopicBriefFile(filename, topicId, topicTitle));
|
|
16139
16150
|
const hasBriefFile = existsSync20(briefFile) && statSync10(briefFile).isFile();
|
|
16140
|
-
const latestSummaryCandidate = resolveWikiMirrorPath(
|
|
16151
|
+
const latestSummaryCandidate = resolveWikiMirrorPath(join30(wikiDir, "summaries"), `__missing__-${wikiSummaryFilename("0000-00-00", topicTitle, topicId)}`, (filename) => isTopicSummaryFile(filename, topicId), (filename) => isTopicSummaryFile(filename, topicId, topicTitle), false);
|
|
16141
16152
|
const latestSummaryFile = existsSync20(latestSummaryCandidate) && statSync10(latestSummaryCandidate).isFile() ? latestSummaryCandidate : null;
|
|
16142
16153
|
return { briefFile, hasBriefFile, latestSummaryFile };
|
|
16143
16154
|
}
|
|
@@ -19219,4 +19230,4 @@ export {
|
|
|
19219
19230
|
DEFAULT_SELF_CONFIG_PRODUCT
|
|
19220
19231
|
};
|
|
19221
19232
|
|
|
19222
|
-
//# debugId=
|
|
19233
|
+
//# debugId=A34C5AACD9F421F064756E2164756E21
|