negotium 0.3.11 → 0.3.13
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 +2 -2
- package/dist/agent-helpers.js.map +2 -2
- package/dist/hosted-agent.js +2 -2
- package/dist/hosted-agent.js.map +2 -2
- package/dist/main.js +113 -15
- package/dist/main.js.map +9 -9
- package/dist/mcp-factories.js +2 -2
- package/dist/mcp-factories.js.map +2 -2
- package/dist/registry.js +2 -2
- package/dist/registry.js.map +2 -2
- package/dist/runtime/src/application/submit-runtime-gateway-turn.ts +12 -0
- package/dist/runtime/src/version.ts +1 -1
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -1869,7 +1869,7 @@ var exports_version = {};
|
|
|
1869
1869
|
__export(exports_version, {
|
|
1870
1870
|
NEGOTIUM_VERSION: () => NEGOTIUM_VERSION
|
|
1871
1871
|
});
|
|
1872
|
-
var NEGOTIUM_VERSION = "0.3.
|
|
1872
|
+
var NEGOTIUM_VERSION = "0.3.13";
|
|
1873
1873
|
|
|
1874
1874
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
1875
1875
|
import { spawn } from "child_process";
|
|
@@ -20499,7 +20499,8 @@ function gatewayPayloadHash(params, requestId, actorUserId) {
|
|
|
20499
20499
|
requestId,
|
|
20500
20500
|
params.allowAutoContinue ?? true,
|
|
20501
20501
|
params.respond ?? true,
|
|
20502
|
-
params.threadRootId ?? null
|
|
20502
|
+
params.threadRootId ?? null,
|
|
20503
|
+
params.attachments ?? []
|
|
20503
20504
|
])).digest("hex");
|
|
20504
20505
|
}
|
|
20505
20506
|
function submitRuntimeGatewayTurn(params) {
|
|
@@ -20512,6 +20513,10 @@ function submitRuntimeGatewayTurn(params) {
|
|
|
20512
20513
|
return duplicateResult(existing, params, requestId, actorUserId, payloadHash);
|
|
20513
20514
|
}
|
|
20514
20515
|
const createdAt = new Date().toISOString();
|
|
20516
|
+
const attachments2 = params.attachments?.map(resolveAttachmentByFileId);
|
|
20517
|
+
if (attachments2?.some((attachment) => !attachment)) {
|
|
20518
|
+
throw new Error("gateway attachment could not be resolved");
|
|
20519
|
+
}
|
|
20515
20520
|
const message = {
|
|
20516
20521
|
id: randomUUID17(),
|
|
20517
20522
|
topicId: params.topic.id,
|
|
@@ -20520,6 +20525,7 @@ function submitRuntimeGatewayTurn(params) {
|
|
|
20520
20525
|
sourceAdapter: "runtime-gateway",
|
|
20521
20526
|
sourceMessageId: params.clientMessageId,
|
|
20522
20527
|
text: params.text,
|
|
20528
|
+
...attachments2?.length ? { attachments: attachments2 } : {},
|
|
20523
20529
|
...params.threadRootId ? { threadRootId: params.threadRootId } : {},
|
|
20524
20530
|
createdAt
|
|
20525
20531
|
};
|
|
@@ -20545,7 +20551,8 @@ function submitRuntimeGatewayTurn(params) {
|
|
|
20545
20551
|
{
|
|
20546
20552
|
prompt: params.text,
|
|
20547
20553
|
actorUserId,
|
|
20548
|
-
...params.actorLabel ? { actorLabel: params.actorLabel } : {}
|
|
20554
|
+
...params.actorLabel ? { actorLabel: params.actorLabel } : {},
|
|
20555
|
+
...params.attachments?.length ? { attachments: params.attachments } : {}
|
|
20549
20556
|
}
|
|
20550
20557
|
],
|
|
20551
20558
|
allowAutoContinue: params.allowAutoContinue ?? true,
|
|
@@ -20592,6 +20599,7 @@ function submitRuntimeGatewayTurn(params) {
|
|
|
20592
20599
|
}
|
|
20593
20600
|
var RuntimeGatewayIdempotencyConflictError;
|
|
20594
20601
|
var init_submit_runtime_gateway_turn = __esm(async () => {
|
|
20602
|
+
init_file_hooks();
|
|
20595
20603
|
await init_api_messages();
|
|
20596
20604
|
await init_api_topics();
|
|
20597
20605
|
await init_forum_db();
|
|
@@ -29814,6 +29822,46 @@ class NodeFileStore {
|
|
|
29814
29822
|
storeLocalFileAsUpload: (absPath, access = {}) => this.store(absPath, access),
|
|
29815
29823
|
deleteFilesForTopic: (topicId) => this.deleteForTopic(topicId)
|
|
29816
29824
|
};
|
|
29825
|
+
async storeUploadedFile(fileId, file, access) {
|
|
29826
|
+
if (!FILE_ID_RE.test(fileId) || file.size > MAX_NODE_UPLOAD_BYTES)
|
|
29827
|
+
return null;
|
|
29828
|
+
this.#ensureDir();
|
|
29829
|
+
const filename = basename10(file.name || "upload") || "upload";
|
|
29830
|
+
const extension = safeExtension(filename);
|
|
29831
|
+
const mimeType = file.type || MIME_BY_EXT2[extension] || "application/octet-stream";
|
|
29832
|
+
const existing = this.#metadata(fileId);
|
|
29833
|
+
if (existing) {
|
|
29834
|
+
const matches = existing.filename === filename && existing.mimeType === mimeType && existing.sizeBytes === file.size && existing.ownerUserId === access.ownerUserId && existing.topicId === access.topicId && existsSync31(join40(this.uploadDir, existing.savedName));
|
|
29835
|
+
return matches ? this.#attachment(fileId, existing) : null;
|
|
29836
|
+
}
|
|
29837
|
+
const savedName = `${fileId}${extension}`;
|
|
29838
|
+
const savedPath = join40(this.uploadDir, savedName);
|
|
29839
|
+
try {
|
|
29840
|
+
const sizeBytes = await Bun.write(savedPath, file);
|
|
29841
|
+
if (sizeBytes !== file.size)
|
|
29842
|
+
throw new Error("incomplete upload write");
|
|
29843
|
+
const metadata = {
|
|
29844
|
+
filename,
|
|
29845
|
+
mimeType,
|
|
29846
|
+
sizeBytes,
|
|
29847
|
+
savedName,
|
|
29848
|
+
ownerUserId: access.ownerUserId,
|
|
29849
|
+
topicId: access.topicId,
|
|
29850
|
+
visibility: "private"
|
|
29851
|
+
};
|
|
29852
|
+
writeFileSync23(this.#metadataPath(fileId), JSON.stringify(metadata), { mode: 384 });
|
|
29853
|
+
return this.#attachment(fileId, metadata);
|
|
29854
|
+
} catch (error2) {
|
|
29855
|
+
rmSync9(savedPath, { force: true });
|
|
29856
|
+
rmSync9(this.#metadataPath(fileId), { force: true });
|
|
29857
|
+
logger.warn({ err: error2, fileId }, "node files: failed to store gateway upload");
|
|
29858
|
+
return null;
|
|
29859
|
+
}
|
|
29860
|
+
}
|
|
29861
|
+
allows(fileId, access) {
|
|
29862
|
+
const metadata = this.#metadata(fileId);
|
|
29863
|
+
return Boolean(metadata && metadata.ownerUserId === access.ownerUserId && metadata.topicId === access.topicId && existsSync31(join40(this.uploadDir, metadata.savedName)));
|
|
29864
|
+
}
|
|
29817
29865
|
store(absPath, access = {}) {
|
|
29818
29866
|
this.#ensureDir();
|
|
29819
29867
|
const fileId = randomUUID24();
|
|
@@ -29822,7 +29870,7 @@ class NodeFileStore {
|
|
|
29822
29870
|
const savedPath = join40(this.uploadDir, savedName);
|
|
29823
29871
|
try {
|
|
29824
29872
|
const stats = statSync18(absPath);
|
|
29825
|
-
if (!stats.isFile() || stats.size >
|
|
29873
|
+
if (!stats.isFile() || stats.size > MAX_NODE_UPLOAD_BYTES)
|
|
29826
29874
|
return null;
|
|
29827
29875
|
const metadata = {
|
|
29828
29876
|
filename: basename10(absPath),
|
|
@@ -29875,10 +29923,10 @@ class NodeFileStore {
|
|
|
29875
29923
|
}
|
|
29876
29924
|
}
|
|
29877
29925
|
}
|
|
29878
|
-
var
|
|
29926
|
+
var MAX_NODE_UPLOAD_BYTES, FILE_ID_RE, MIME_BY_EXT2, nodeFileStore;
|
|
29879
29927
|
var init_files = __esm(async () => {
|
|
29880
29928
|
await init_node_host();
|
|
29881
|
-
|
|
29929
|
+
MAX_NODE_UPLOAD_BYTES = 2 * 1024 * 1024 * 1024;
|
|
29882
29930
|
FILE_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
29883
29931
|
MIME_BY_EXT2 = {
|
|
29884
29932
|
".csv": "text/csv",
|
|
@@ -30213,11 +30261,34 @@ function createNodeControlHandler(options) {
|
|
|
30213
30261
|
"canonical-history-import",
|
|
30214
30262
|
"canonical-topic-abort",
|
|
30215
30263
|
"canonical-session-reset",
|
|
30216
|
-
"canonical-session-compact"
|
|
30264
|
+
"canonical-session-compact",
|
|
30265
|
+
"canonical-input-files"
|
|
30217
30266
|
],
|
|
30218
30267
|
cursor: latestRuntimeEventSeq()
|
|
30219
30268
|
});
|
|
30220
30269
|
}
|
|
30270
|
+
if (req.method === "POST" && runtimePath === "/input-files") {
|
|
30271
|
+
const form = await req.formData();
|
|
30272
|
+
const topicId = requiredText(form.get("topicId"), "topicId");
|
|
30273
|
+
const userId = requiredText(form.get("userId"), "userId");
|
|
30274
|
+
const fileId = requiredText(form.get("fileId"), "fileId");
|
|
30275
|
+
const file = form.get("file");
|
|
30276
|
+
if (!(file instanceof File))
|
|
30277
|
+
throw new ControlRequestError("file is required");
|
|
30278
|
+
if (file.size > MAX_NODE_UPLOAD_BYTES)
|
|
30279
|
+
return jsonError(413, "File too large");
|
|
30280
|
+
const topic = getTopic(topicId);
|
|
30281
|
+
if (!topic || !topicInRequestScope(req, topic) || !topic.participants.some((participant) => participant.userId === userId)) {
|
|
30282
|
+
return jsonError(404, "Topic not found");
|
|
30283
|
+
}
|
|
30284
|
+
const attachment = await nodeFileStore.storeUploadedFile(fileId, file, {
|
|
30285
|
+
topicId,
|
|
30286
|
+
ownerUserId: userId
|
|
30287
|
+
});
|
|
30288
|
+
if (!attachment)
|
|
30289
|
+
return jsonError(409, "File id is already bound to another upload");
|
|
30290
|
+
return Response.json({ ok: true, v: NODE_RUNTIME_CONTRACT_VERSION, attachment }, { status: 201 });
|
|
30291
|
+
}
|
|
30221
30292
|
if (req.method === "POST" && runtimePath === "/turns") {
|
|
30222
30293
|
const body = await bodyRecord(req);
|
|
30223
30294
|
if (body.v !== NODE_RUNTIME_CONTRACT_VERSION)
|
|
@@ -30231,16 +30302,27 @@ function createNodeControlHandler(options) {
|
|
|
30231
30302
|
const actorUserId = body.actorUserId === undefined ? undefined : requiredText(body.actorUserId, "actorUserId");
|
|
30232
30303
|
const actorLabel = body.actorLabel === undefined ? undefined : requiredText(body.actorLabel, "actorLabel");
|
|
30233
30304
|
const vaultUserId = body.vaultUserId === undefined ? undefined : requiredText(body.vaultUserId, "vaultUserId");
|
|
30234
|
-
|
|
30305
|
+
if (typeof body.text !== "string")
|
|
30306
|
+
throw new ControlRequestError("text is required");
|
|
30307
|
+
const text2 = body.text;
|
|
30235
30308
|
const clientMessageId = requiredText(body.clientMessageId, "clientMessageId");
|
|
30236
30309
|
const requestId = body.requestId === undefined ? undefined : requiredText(body.requestId, "requestId");
|
|
30237
30310
|
const threadRootId = body.threadRootId === undefined ? undefined : requiredText(body.threadRootId, "threadRootId");
|
|
30311
|
+
const attachments2 = body.attachments === undefined ? [] : Array.isArray(body.attachments) && body.attachments.every((value) => typeof value === "string" && value.trim()) ? body.attachments : (() => {
|
|
30312
|
+
throw new ControlRequestError("attachments must be an array of file ids");
|
|
30313
|
+
})();
|
|
30314
|
+
if (!text2.trim() && attachments2.length === 0) {
|
|
30315
|
+
throw new ControlRequestError("text or attachments required");
|
|
30316
|
+
}
|
|
30238
30317
|
const topic = getTopic(topicId);
|
|
30239
30318
|
if (!topic)
|
|
30240
30319
|
return jsonError(404, "Topic not found");
|
|
30241
30320
|
if (!topic.participants.some((participant) => participant.userId === userId)) {
|
|
30242
30321
|
return jsonError(404, "Topic not found");
|
|
30243
30322
|
}
|
|
30323
|
+
if (attachments2.some((fileId) => !nodeFileStore.allows(fileId, { topicId, ownerUserId: userId }))) {
|
|
30324
|
+
return jsonError(404, "Attachment not found");
|
|
30325
|
+
}
|
|
30244
30326
|
if (threadRootId) {
|
|
30245
30327
|
const root = getApiMessage(topicId, threadRootId);
|
|
30246
30328
|
if (!root || root.deleted || root.threadRootId) {
|
|
@@ -30258,6 +30340,7 @@ function createNodeControlHandler(options) {
|
|
|
30258
30340
|
requestId,
|
|
30259
30341
|
allowAutoContinue: body.allowAutoContinue !== false,
|
|
30260
30342
|
respond: body.respond !== false,
|
|
30343
|
+
...attachments2.length ? { attachments: attachments2 } : {},
|
|
30261
30344
|
...threadRootId ? { threadRootId } : {}
|
|
30262
30345
|
});
|
|
30263
30346
|
return Response.json({
|
|
@@ -45240,7 +45323,7 @@ function allowedRuntimePath(path, method) {
|
|
|
45240
45323
|
return /^\/topics\/[^/]+(\/messages)?$/.test(path);
|
|
45241
45324
|
}
|
|
45242
45325
|
if (method === "POST") {
|
|
45243
|
-
if (path === "/turns")
|
|
45326
|
+
if (path === "/turns" || path === "/input-files")
|
|
45244
45327
|
return true;
|
|
45245
45328
|
if (path === "/topics")
|
|
45246
45329
|
return true;
|
|
@@ -45359,7 +45442,7 @@ function localCapabilities() {
|
|
|
45359
45442
|
runtimeVersion: RUNTIME_VERSION,
|
|
45360
45443
|
features: {
|
|
45361
45444
|
remoteAsk: true,
|
|
45362
|
-
inputFiles:
|
|
45445
|
+
inputFiles: true,
|
|
45363
45446
|
outputFiles: true,
|
|
45364
45447
|
visualBridge: true,
|
|
45365
45448
|
askUserBridge: true,
|
|
@@ -46086,10 +46169,25 @@ function option2(args, name) {
|
|
|
46086
46169
|
const index = args.indexOf(`--${name}`);
|
|
46087
46170
|
return index >= 0 ? args[index + 1]?.trim() : undefined;
|
|
46088
46171
|
}
|
|
46089
|
-
function
|
|
46090
|
-
const normalized =
|
|
46172
|
+
function normalizeNodeNameCandidate(raw) {
|
|
46173
|
+
const normalized = raw.trim().toLowerCase().replace(/\.local$/, "").replace(/[^a-z0-9._-]+/g, "-").replace(/^[-._]+|[-._]+$/g, "").slice(0, 32).replace(/[-._]+$/g, "");
|
|
46091
46174
|
return normalized || undefined;
|
|
46092
46175
|
}
|
|
46176
|
+
function localNodeNameDefault() {
|
|
46177
|
+
const configured = process.env.NEGOTIUM_NODE_NAME?.trim();
|
|
46178
|
+
if (configured) {
|
|
46179
|
+
const normalized = normalizeNodeNameCandidate(configured);
|
|
46180
|
+
if (normalized)
|
|
46181
|
+
return normalized;
|
|
46182
|
+
}
|
|
46183
|
+
const aiName = getGlobalAiName().trim();
|
|
46184
|
+
if (aiName && aiName !== DEFAULT_AI_NAME) {
|
|
46185
|
+
const normalized = normalizeNodeNameCandidate(aiName);
|
|
46186
|
+
if (normalized)
|
|
46187
|
+
return normalized;
|
|
46188
|
+
}
|
|
46189
|
+
return normalizeNodeNameCandidate(hostname2());
|
|
46190
|
+
}
|
|
46093
46191
|
async function confirmEnrollment(message) {
|
|
46094
46192
|
if (!process.stdin.isTTY)
|
|
46095
46193
|
return false;
|
|
@@ -46122,13 +46220,12 @@ async function joinCommand(args) {
|
|
|
46122
46220
|
try {
|
|
46123
46221
|
const invite = parseEnrollmentInvite(code);
|
|
46124
46222
|
const resuming = isEnrollmentPending(invite);
|
|
46125
|
-
|
|
46223
|
+
const nodeName = option2(args, "name") || localNodeNameDefault();
|
|
46126
46224
|
if (resuming) {
|
|
46127
46225
|
console.log(`Resuming interrupted Otium enrollment with ${invite.central}`);
|
|
46128
46226
|
} else {
|
|
46129
46227
|
const preview = await previewEnrollment(invite);
|
|
46130
46228
|
const workspace = preview.preview?.workspace;
|
|
46131
|
-
nodeName ||= preview.preview?.suggestedNodeName || undefined;
|
|
46132
46229
|
console.log(`Otium workspace: ${workspace?.name ?? workspace?.slug ?? workspace?.id}`);
|
|
46133
46230
|
console.log(` central: ${invite.central}`);
|
|
46134
46231
|
console.log(` transport: ${preview.preview?.transport ?? "relay"}`);
|
|
@@ -46181,6 +46278,7 @@ async function joinCommand(args) {
|
|
|
46181
46278
|
console.log("\nnext: `negotium-otium serve` (mounts the otium peer routes automatically)");
|
|
46182
46279
|
}
|
|
46183
46280
|
var init_join_cli = __esm(async () => {
|
|
46281
|
+
await init_src();
|
|
46184
46282
|
await init_central();
|
|
46185
46283
|
await init_enrollment();
|
|
46186
46284
|
await init_join();
|
|
@@ -47227,4 +47325,4 @@ switch (command) {
|
|
|
47227
47325
|
}
|
|
47228
47326
|
}
|
|
47229
47327
|
|
|
47230
|
-
//# debugId=
|
|
47328
|
+
//# debugId=28B32B58D5A6FD9664756E2164756E21
|