negotium 0.22.7 → 0.23.0
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 +31 -14
- package/dist/agent-helpers.js.map +4 -4
- package/dist/{chunk-1gznvrth.js → chunk-qmpbb92y.js} +2 -2
- package/dist/{chunk-1gznvrth.js.map → chunk-qmpbb92y.js.map} +2 -2
- package/dist/hosted-agent.js +2 -2
- package/dist/hosted-agent.js.map +2 -2
- package/dist/main.js +664 -107
- package/dist/main.js.map +10 -10
- package/dist/mcp-factories.js +31 -14
- package/dist/mcp-factories.js.map +4 -4
- package/dist/registry.js +1 -1
- package/dist/runtime/src/mcp-runtime-host.ts +1 -0
- package/dist/runtime/src/runtime/visuals.ts +47 -11
- package/dist/runtime/src/version.ts +1 -1
- package/dist/types/packages/core/src/runtime/visuals.d.ts +9 -2
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/registry.js
CHANGED
|
@@ -132,7 +132,7 @@ var codexRegistryOperations = {
|
|
|
132
132
|
return { sessionId: threadId, rolloutPath };
|
|
133
133
|
},
|
|
134
134
|
async forkSession({ parentSessionId }) {
|
|
135
|
-
const { forkCodexSession } = await import("./chunk-
|
|
135
|
+
const { forkCodexSession } = await import("./chunk-qmpbb92y.js");
|
|
136
136
|
return await forkCodexSession(parentSessionId);
|
|
137
137
|
},
|
|
138
138
|
async cleanupRollouts({ sessionIds }) {
|
|
@@ -49,6 +49,7 @@ export {
|
|
|
49
49
|
THREAD_READ_DEFAULT_LIMIT,
|
|
50
50
|
THREAD_READ_MAX_LIMIT,
|
|
51
51
|
} from "#runtime/thread-read";
|
|
52
|
+
export { isVisualsShowImageTool, visualMediaInputError } from "#runtime/visuals";
|
|
52
53
|
export { isSensitivePath } from "#security/sensitive-path";
|
|
53
54
|
export {
|
|
54
55
|
appendApiMessage,
|
|
@@ -123,10 +123,19 @@ export function buildVideoHtml(mimeType: string): string {
|
|
|
123
123
|
</html>`;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
type VisualMediaInput = { file_path?: unknown; file_id?: unknown };
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Where a media visual's bytes come from, checked but not yet stored: an upload
|
|
130
|
+
* already in the topic, or a readable workspace file.
|
|
131
|
+
*/
|
|
132
|
+
function locateVisualMediaInput(
|
|
127
133
|
topicId: string,
|
|
128
|
-
input:
|
|
129
|
-
):
|
|
134
|
+
input: VisualMediaInput,
|
|
135
|
+
):
|
|
136
|
+
| { kind: "upload"; fileId: string; mimeType: string }
|
|
137
|
+
| { kind: "file"; path: string; rawPath: string }
|
|
138
|
+
| { error: string } {
|
|
130
139
|
if (typeof input.file_id === "string" && input.file_id.trim()) {
|
|
131
140
|
const fileId = input.file_id.trim().toLowerCase();
|
|
132
141
|
if (!isUploadFileId(fileId)) return { error: "file_id must be a full uploaded-file UUID" };
|
|
@@ -136,11 +145,7 @@ export function resolveVisualMediaInput(
|
|
|
136
145
|
const attachment = resolveAttachmentByFileId(fileId);
|
|
137
146
|
const filePath = resolveUploadedFilePathByFileId(fileId);
|
|
138
147
|
if (!attachment || !filePath) return { error: `uploaded file not found: ${fileId}` };
|
|
139
|
-
return {
|
|
140
|
-
fileId: attachment.id,
|
|
141
|
-
mimeType: attachment.mimeType,
|
|
142
|
-
source: `file_id:${attachment.id}`,
|
|
143
|
-
};
|
|
148
|
+
return { kind: "upload", fileId: attachment.id, mimeType: attachment.mimeType };
|
|
144
149
|
}
|
|
145
150
|
|
|
146
151
|
if (typeof input.file_path !== "string" || !input.file_path.trim()) {
|
|
@@ -149,18 +154,49 @@ export function resolveVisualMediaInput(
|
|
|
149
154
|
const rawPath = input.file_path.trim();
|
|
150
155
|
const cwd = workspaceCwdFor(topicId);
|
|
151
156
|
const candidate = isAbsolute(rawPath) ? rawPath : resolve(cwd, rawPath);
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
157
|
+
// Existence first: the containment check resolves both ends on disk, so a
|
|
158
|
+
// missing file would otherwise be reported as being outside the workspace.
|
|
155
159
|
let realCandidate: string;
|
|
156
160
|
try {
|
|
157
161
|
realCandidate = realpathSync(candidate);
|
|
158
162
|
} catch {
|
|
159
163
|
return { error: `file not found: ${rawPath}` };
|
|
160
164
|
}
|
|
165
|
+
if (!isPathInside(cwd, realCandidate)) {
|
|
166
|
+
return {
|
|
167
|
+
error: `file_path must be inside the topic workspace (${cwd}); copy the file into it and pass the copy`,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
161
170
|
if (isSensitivePath(realCandidate)) {
|
|
162
171
|
return { error: "file_path matches the sensitive-file blacklist" };
|
|
163
172
|
}
|
|
173
|
+
return { kind: "file", path: realCandidate, rawPath };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Why a media visual call cannot be displayed, or null when it can. The same
|
|
178
|
+
* checks the turn runs before rendering, so the tool can answer the agent with
|
|
179
|
+
* the real outcome instead of a success it never had.
|
|
180
|
+
*/
|
|
181
|
+
export function visualMediaInputError(topicId: string, input: VisualMediaInput): string | null {
|
|
182
|
+
const located = locateVisualMediaInput(topicId, input);
|
|
183
|
+
return "error" in located ? located.error : null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function resolveVisualMediaInput(
|
|
187
|
+
topicId: string,
|
|
188
|
+
input: VisualMediaInput,
|
|
189
|
+
): { fileId: string; mimeType: string; source: string } | { error: string } {
|
|
190
|
+
const located = locateVisualMediaInput(topicId, input);
|
|
191
|
+
if ("error" in located) return located;
|
|
192
|
+
if (located.kind === "upload") {
|
|
193
|
+
return {
|
|
194
|
+
fileId: located.fileId,
|
|
195
|
+
mimeType: located.mimeType,
|
|
196
|
+
source: `file_id:${located.fileId}`,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
const { path: realCandidate, rawPath } = located;
|
|
164
200
|
const attachment = storeLocalFileAsUpload(realCandidate, { topicId });
|
|
165
201
|
if (!attachment) return { error: `failed to store media file: ${rawPath}` };
|
|
166
202
|
const filePath = resolveUploadedFilePathByFileId(attachment.id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const NEGOTIUM_VERSION = "0.
|
|
1
|
+
export const NEGOTIUM_VERSION = "0.23.0";
|
|
@@ -14,10 +14,17 @@ export declare function topicAllowsVisualFileId(topicId: string, fileId: string)
|
|
|
14
14
|
export declare function isPathInside(baseDir: string, filePath: string): boolean;
|
|
15
15
|
export declare function buildImageHtml(alt: string): string;
|
|
16
16
|
export declare function buildVideoHtml(mimeType: string): string;
|
|
17
|
-
|
|
17
|
+
type VisualMediaInput = {
|
|
18
18
|
file_path?: unknown;
|
|
19
19
|
file_id?: unknown;
|
|
20
|
-
}
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Why a media visual call cannot be displayed, or null when it can. The same
|
|
23
|
+
* checks the turn runs before rendering, so the tool can answer the agent with
|
|
24
|
+
* the real outcome instead of a success it never had.
|
|
25
|
+
*/
|
|
26
|
+
export declare function visualMediaInputError(topicId: string, input: VisualMediaInput): string | null;
|
|
27
|
+
export declare function resolveVisualMediaInput(topicId: string, input: VisualMediaInput): {
|
|
21
28
|
fileId: string;
|
|
22
29
|
mimeType: string;
|
|
23
30
|
source: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const NEGOTIUM_VERSION = "0.
|
|
1
|
+
export declare const NEGOTIUM_VERSION = "0.23.0";
|