@segmentstream/agent 0.21.7 → 0.22.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/README.md +8 -0
- package/dist/_chunks/{build-metadata-96xS1MkA.mjs → build-metadata-B_3wcMyz.mjs} +1 -1
- package/dist/extension/instructions/sandbox.mjs +6 -0
- package/dist/extension/lib/build-metadata.mjs +1 -1
- package/dist/extension/lib/ontology-file-call.d.ts +1 -0
- package/dist/extension/lib/ontology-file-call.mjs +14 -4
- package/dist/extension/lib/ontology-result-file.d.ts +10 -0
- package/dist/extension/lib/ontology-result-file.mjs +46 -0
- package/dist/extension/lib/telegram/adapter.mjs +1 -1
- package/dist/extension/lib/telegram/health.mjs +1 -1
- package/dist/extension/lib/telegram/lifecycle.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -264,6 +264,14 @@ Eve has no public connection API for reading arguments from a sandbox file. This
|
|
|
264
264
|
has no discovery or inline-call API; ordinary calls use Eve. Chat posting is excluded.
|
|
265
265
|
File-taking actions remain reachable through `segmentstream__attachments_promote`.
|
|
266
266
|
|
|
267
|
+
Set `save_result: true` on that file call to save a permitted read-only tool's exact JSON response
|
|
268
|
+
in the same session's verified sandbox. The response gives a generated `result_file`, byte size,
|
|
269
|
+
SHA-256 and query/paging metadata, without copying rows through the model. This mode refuses write
|
|
270
|
+
tools before dispatch and checks their read-only annotation again at execution. Files are limited
|
|
271
|
+
to 8 MiB; the query's existing permissions and bounds still apply. A file's row count covers that
|
|
272
|
+
result only: follow continuations or split truncated aggregate groups into disjoint filters before
|
|
273
|
+
combining and deduplicating them with a script. The file is temporary, like the sandbox itself.
|
|
274
|
+
|
|
267
275
|
Under `eve dev` the sandbox is a Vercel Sandbox too and needs local Vercel credentials; without
|
|
268
276
|
them the sandbox tools, and turns carrying files, fail.
|
|
269
277
|
|
|
@@ -4,7 +4,7 @@ import { createRequire as __eveCreateRequire } from "node:module";
|
|
|
4
4
|
const __filename = __eveFileURLToPath(import.meta.url);
|
|
5
5
|
__eveDirname(__filename);
|
|
6
6
|
__eveCreateRequire(import.meta.url);
|
|
7
|
-
var version = "0.
|
|
7
|
+
var version = "0.22.0";
|
|
8
8
|
function agentBuild(environment = process.env) {
|
|
9
9
|
return {
|
|
10
10
|
agent: version,
|
|
@@ -25,6 +25,12 @@ Downloads and package installs fail. For reading one file or exact totals over o
|
|
|
25
25
|
Discover the target's schema through Eve first. Write the complete object to the file; never
|
|
26
26
|
retype calculated amounts, dates or digests. The call snapshots the file before approval.
|
|
27
27
|
Ordinary inline calls and chat posting use Eve's native ontology connection.
|
|
28
|
+
- To combine or deduplicate large ontology read results with a script, set \`save_result: true\`
|
|
29
|
+
on \`segmentstream__ontology_call_file\`. Write the normal read arguments into its JSON file;
|
|
30
|
+
the tool saves the exact response in this sandbox and returns \`result_file\`, its SHA-256 and
|
|
31
|
+
paging metadata. Scripts can read that JSON directly; do not retype rows. This mode accepts only
|
|
32
|
+
permitted read-only tools. A saved result's row count covers that result only. Follow its cursor
|
|
33
|
+
or split truncated aggregate groups into disjoint filters, verify coverage, then combine files.
|
|
28
34
|
- A command still running after 30 seconds keeps running and returns status "running" with a
|
|
29
35
|
directory under /tmp/.eve/jobs; check its stdout and exit files with later commands. Output over
|
|
30
36
|
50 KiB is truncated: write large output to a file and read it in parts.
|
|
@@ -4,5 +4,5 @@ import { createRequire as __eveCreateRequire } from "node:module";
|
|
|
4
4
|
const __filename = __eveFileURLToPath(import.meta.url);
|
|
5
5
|
__eveDirname(__filename);
|
|
6
6
|
__eveCreateRequire(import.meta.url);
|
|
7
|
-
import { t as agentBuild } from "../../_chunks/build-metadata-
|
|
7
|
+
import { t as agentBuild } from "../../_chunks/build-metadata-B_3wcMyz.mjs";
|
|
8
8
|
export { agentBuild };
|
|
@@ -2,6 +2,7 @@ import type { TelegramTexts } from "./telegram/texts.js";
|
|
|
2
2
|
export interface FileCall {
|
|
3
3
|
readonly name: string;
|
|
4
4
|
readonly arguments_file: string;
|
|
5
|
+
readonly save_result?: boolean;
|
|
5
6
|
}
|
|
6
7
|
export declare function releaseOntologyFilePayloads(): void;
|
|
7
8
|
/** Eve has no public API for supplying connection arguments from a sandbox file. Keep this
|
|
@@ -10,6 +10,7 @@ import { isChatPost } from "./chat-post-confirmation.mjs";
|
|
|
10
10
|
import { actionApproval, confirmations, inputHash } from "./confirmations.mjs";
|
|
11
11
|
import { ontologyTools } from "./ontology-tools.mjs";
|
|
12
12
|
import { sandboxFile } from "./sandbox-session.mjs";
|
|
13
|
+
import { saveOntologyResult } from "./ontology-result-file.mjs";
|
|
13
14
|
import { defineState } from "eve/context";
|
|
14
15
|
import { defineTool } from "eve/tools";
|
|
15
16
|
const snapshots = defineState("segmentstream.ontologyFiles", () => ({}));
|
|
@@ -41,7 +42,9 @@ function ontologyFileCall(texts) {
|
|
|
41
42
|
const policy = (principal) => actionApproval({
|
|
42
43
|
labels: async (actor, _action, input) => {
|
|
43
44
|
const saved = bound(input, ownerOf(actor));
|
|
44
|
-
|
|
45
|
+
const labels = await ontologyTools({ principal }).labels(actor, saved.name, saved.arguments);
|
|
46
|
+
if (saved.saveResult && labels.readOnlyHint !== true) throw new Error("Saving a result requires a permitted read-only ontology tool.");
|
|
47
|
+
return labels;
|
|
45
48
|
},
|
|
46
49
|
describe: async (actor, _action, input) => {
|
|
47
50
|
const saved = bound(input, ownerOf(actor));
|
|
@@ -67,7 +70,7 @@ function ontologyFileCall(texts) {
|
|
|
67
70
|
}
|
|
68
71
|
return defineTool({
|
|
69
72
|
deferred: true,
|
|
70
|
-
description: "Call an ontology tool with the complete JSON object computed in a sandbox file. Use
|
|
73
|
+
description: "Call an ontology tool with the complete JSON object computed in a sandbox file. Use for script-generated arguments, or set save_result to save a permitted read's exact JSON result in the isolated sandbox for scripts, without copying rows through the model. Find the real tool and its schema through Eve search first; ordinary inline calls use Eve. Chat posting is excluded. Saving a result never permits a write tool or expands query limits.",
|
|
71
74
|
inputSchema: {
|
|
72
75
|
type: "object",
|
|
73
76
|
properties: {
|
|
@@ -79,6 +82,10 @@ function ontologyFileCall(texts) {
|
|
|
79
82
|
arguments_file: {
|
|
80
83
|
type: "string",
|
|
81
84
|
description: "Absolute path of a JSON object inside /workspace; maximum 1 MiB."
|
|
85
|
+
},
|
|
86
|
+
save_result: {
|
|
87
|
+
type: "boolean",
|
|
88
|
+
description: "For read-only tools, save the exact result as JSON in this session's sandbox and return its generated path, digest and paging metadata instead of the rows. Maximum 8 MiB."
|
|
82
89
|
}
|
|
83
90
|
},
|
|
84
91
|
required: ["name", "arguments_file"],
|
|
@@ -105,7 +112,8 @@ function ontologyFileCall(texts) {
|
|
|
105
112
|
requestHash: inputHash(input),
|
|
106
113
|
name: input.name,
|
|
107
114
|
digest: inputHash(args),
|
|
108
|
-
arguments: args
|
|
115
|
+
arguments: args,
|
|
116
|
+
...input.save_result === true ? { saveResult: true } : {}
|
|
109
117
|
}
|
|
110
118
|
}));
|
|
111
119
|
}
|
|
@@ -151,6 +159,7 @@ function ontologyFileCall(texts) {
|
|
|
151
159
|
const saved = bound(request(ctx.callId, input, owner), owner);
|
|
152
160
|
const confirmation = confirmations.get()[ctx.callId];
|
|
153
161
|
if (confirmation !== void 0 && confirmation.status !== "consumed") throw new Error("The file call has not been confirmed.");
|
|
162
|
+
if (saved.saveResult && (await ontologyTools({ principal: ctx.session.auth.current }).labels(actor, saved.name, saved.arguments)).readOnlyHint !== true) throw new Error("Saving a result requires a permitted read-only ontology tool.");
|
|
154
163
|
const result = await ontologyTools({
|
|
155
164
|
principal: ctx.session.auth.current,
|
|
156
165
|
envelope: runtimeEnvelope({
|
|
@@ -169,7 +178,8 @@ function ontologyFileCall(texts) {
|
|
|
169
178
|
name: saved.name,
|
|
170
179
|
arguments: saved.arguments
|
|
171
180
|
});
|
|
172
|
-
|
|
181
|
+
const output = result.structuredContent ?? result;
|
|
182
|
+
return saved.saveResult ? saveOntologyResult(ctx, output) : output;
|
|
173
183
|
}
|
|
174
184
|
});
|
|
175
185
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type SandboxContext } from "./sandbox-session.js";
|
|
2
|
+
/** Exact, caller-authorized read data goes only into the same session's verified sandbox.
|
|
3
|
+
* The generated directory cannot be chosen by a prompt or overwrite an authored file. */
|
|
4
|
+
export declare function saveOntologyResult(context: SandboxContext, result: unknown): Promise<{
|
|
5
|
+
row_count?: number | undefined;
|
|
6
|
+
row_count_scope?: string | undefined;
|
|
7
|
+
result_file: string;
|
|
8
|
+
bytes: number;
|
|
9
|
+
sha256: string;
|
|
10
|
+
}>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { fileURLToPath as __eveFileURLToPath } from "node:url";
|
|
2
|
+
import { dirname as __eveDirname } from "node:path";
|
|
3
|
+
import { createRequire as __eveCreateRequire } from "node:module";
|
|
4
|
+
const __filename = __eveFileURLToPath(import.meta.url);
|
|
5
|
+
__eveDirname(__filename);
|
|
6
|
+
__eveCreateRequire(import.meta.url);
|
|
7
|
+
import { sessionSandbox } from "./sandbox-session.mjs";
|
|
8
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
9
|
+
const MAXIMUM_BYTES = 8388608;
|
|
10
|
+
const METADATA = [
|
|
11
|
+
"deploymentId",
|
|
12
|
+
"definitionDigest",
|
|
13
|
+
"fields",
|
|
14
|
+
"execution",
|
|
15
|
+
"truncated",
|
|
16
|
+
"next_cursor",
|
|
17
|
+
"nextCursor",
|
|
18
|
+
"page_count",
|
|
19
|
+
"page_count_scope",
|
|
20
|
+
"total_scope"
|
|
21
|
+
];
|
|
22
|
+
async function saveOntologyResult(context, result) {
|
|
23
|
+
const content = JSON.stringify(result);
|
|
24
|
+
if (content === void 0) throw new TypeError("The ontology read returned no JSON result.");
|
|
25
|
+
const bytes = Buffer.byteLength(content, "utf8");
|
|
26
|
+
if (bytes > MAXIMUM_BYTES) throw new RangeError("The ontology read result exceeds 8 MiB; request smaller groups or pages.");
|
|
27
|
+
const sandbox = await sessionSandbox(context);
|
|
28
|
+
const path = `/workspace/.segmentstream/results/${randomUUID()}/result.json`;
|
|
29
|
+
await sandbox.writeTextFile({
|
|
30
|
+
path,
|
|
31
|
+
content
|
|
32
|
+
});
|
|
33
|
+
const value = result !== null && typeof result === "object" && !Array.isArray(result) ? result : {};
|
|
34
|
+
const rows = Array.isArray(value.rows) ? value.rows : Array.isArray(value.items) ? value.items : void 0;
|
|
35
|
+
return {
|
|
36
|
+
result_file: path,
|
|
37
|
+
bytes,
|
|
38
|
+
sha256: createHash("sha256").update(content).digest("hex"),
|
|
39
|
+
...rows === void 0 ? {} : {
|
|
40
|
+
row_count: rows.length,
|
|
41
|
+
row_count_scope: "result"
|
|
42
|
+
},
|
|
43
|
+
...Object.fromEntries(METADATA.filter((key) => value[key] !== void 0).map((key) => [key, value[key]]))
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export { saveOntologyResult };
|
|
@@ -24,7 +24,7 @@ import { MAXIMUM_DOWNLOAD_BYTES, connectionProxy } from "../connection-proxy.mjs
|
|
|
24
24
|
import { dispatchStructuredMessage, structuredMessage } from "./structured.mjs";
|
|
25
25
|
import { scopedAddress, sessionPolicy } from "./sessions.mjs";
|
|
26
26
|
import { handleWorkspaceCallback, isWorkspaceCallback } from "./callbacks.mjs";
|
|
27
|
-
import { t as agentBuild } from "../../../_chunks/build-metadata-
|
|
27
|
+
import { t as agentBuild } from "../../../_chunks/build-metadata-B_3wcMyz.mjs";
|
|
28
28
|
import { attachmentLifecycle } from "./lifecycle.mjs";
|
|
29
29
|
import { observedMessages } from "./observed.mjs";
|
|
30
30
|
import { expireDeferredCards, handleDeferredCallback, isDeferredCallback } from "./deferred-confirmations.mjs";
|
|
@@ -5,7 +5,7 @@ const __filename = __eveFileURLToPath(import.meta.url);
|
|
|
5
5
|
__eveDirname(__filename);
|
|
6
6
|
__eveCreateRequire(import.meta.url);
|
|
7
7
|
import { runtimeRequestFailure } from "./runtime-request.mjs";
|
|
8
|
-
import { t as agentBuild } from "../../../_chunks/build-metadata-
|
|
8
|
+
import { t as agentBuild } from "../../../_chunks/build-metadata-B_3wcMyz.mjs";
|
|
9
9
|
import { GET } from "eve/channels";
|
|
10
10
|
const HEALTH_ROUTE = "/eve/v1/telegram/health";
|
|
11
11
|
function healthRoute(input) {
|
|
@@ -10,7 +10,7 @@ import { n as currentInboundRequest, p as reportTelegramError } from "../../../_
|
|
|
10
10
|
import { member } from "../actor.mjs";
|
|
11
11
|
import { needsConfirmation } from "../confirmations.mjs";
|
|
12
12
|
import { OntologyActionNotPermitted, actionToolName, ontologyTools } from "../ontology-tools.mjs";
|
|
13
|
-
import { t as agentBuild } from "../../../_chunks/build-metadata-
|
|
13
|
+
import { t as agentBuild } from "../../../_chunks/build-metadata-B_3wcMyz.mjs";
|
|
14
14
|
var AttachmentLifecycleNotPermitted = class extends Error {
|
|
15
15
|
code = "attachment_lifecycle_not_permitted";
|
|
16
16
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@segmentstream/agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Mount a SegmentStream workspace's agent on eve: the ontology as tools, acting as the member who writes, and Telegram through the workspace's connection.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "SegmentStream",
|