@modelprofile.com/flexharness 6.1.0 → 7.0.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_ts/00_commitinfo_data.js +1 -1
- package/dist_ts_chat/classes.chatsession.d.ts +37 -0
- package/dist_ts_chat/classes.chatsession.js +102 -0
- package/dist_ts_chat/index.d.ts +2 -0
- package/dist_ts_chat/index.js +2 -0
- package/dist_ts_chat/interfaces.d.ts +72 -0
- package/dist_ts_chat/interfaces.js +2 -0
- package/dist_ts_chat/plugins.d.ts +4 -0
- package/dist_ts_chat/plugins.js +4 -0
- package/dist_ts_chat_cli/components.chatapp.d.ts +10 -0
- package/dist_ts_chat_cli/components.chatapp.js +75 -0
- package/dist_ts_chat_cli/components.inputarea.d.ts +7 -0
- package/dist_ts_chat_cli/components.inputarea.js +18 -0
- package/dist_ts_chat_cli/components.message.d.ts +12 -0
- package/dist_ts_chat_cli/components.message.js +21 -0
- package/dist_ts_chat_cli/components.messagelist.d.ts +9 -0
- package/dist_ts_chat_cli/components.messagelist.js +19 -0
- package/dist_ts_chat_cli/components.statusbar.d.ts +9 -0
- package/dist_ts_chat_cli/components.statusbar.js +15 -0
- package/dist_ts_chat_cli/index.d.ts +2 -0
- package/dist_ts_chat_cli/index.js +2 -0
- package/dist_ts_chat_cli/plugins.d.ts +12 -0
- package/dist_ts_chat_cli/plugins.js +14 -0
- package/dist_ts_chat_cli/startchat.d.ts +18 -0
- package/dist_ts_chat_cli/startchat.js +17 -0
- package/dist_ts_chat_web/flexchat-input.d.ts +21 -0
- package/dist_ts_chat_web/flexchat-input.js +172 -0
- package/dist_ts_chat_web/flexchat-message.d.ts +26 -0
- package/dist_ts_chat_web/flexchat-message.js +174 -0
- package/dist_ts_chat_web/flexchat-window.d.ts +34 -0
- package/dist_ts_chat_web/flexchat-window.js +394 -0
- package/dist_ts_chat_web/index.d.ts +3 -0
- package/dist_ts_chat_web/index.js +4 -0
- package/dist_ts_chat_web/plugins.d.ts +6 -0
- package/dist_ts_chat_web/plugins.js +4 -0
- package/dist_ts_compaction/index.d.ts +2 -0
- package/dist_ts_compaction/index.js +2 -0
- package/dist_ts_compaction/plugins.d.ts +4 -0
- package/dist_ts_compaction/plugins.js +3 -0
- package/dist_ts_compaction/smartagent.compaction.d.ts +14 -0
- package/dist_ts_compaction/smartagent.compaction.js +49 -0
- package/dist_ts_document/index.d.ts +19 -0
- package/dist_ts_document/index.js +55 -0
- package/dist_ts_document/plugins.d.ts +3 -0
- package/dist_ts_document/plugins.js +4 -0
- package/dist_ts_kvm/classes.browserkvm.d.ts +22 -0
- package/dist_ts_kvm/classes.browserkvm.js +271 -0
- package/dist_ts_kvm/classes.kvmterminal.d.ts +8 -0
- package/dist_ts_kvm/classes.kvmterminal.js +88 -0
- package/dist_ts_kvm/commandwrappers.d.ts +14 -0
- package/dist_ts_kvm/commandwrappers.js +58 -0
- package/dist_ts_kvm/index.d.ts +6 -0
- package/dist_ts_kvm/index.js +7 -0
- package/dist_ts_kvm/interfaces.d.ts +106 -0
- package/dist_ts_kvm/interfaces.js +2 -0
- package/dist_ts_kvm/ocr.d.ts +14 -0
- package/dist_ts_kvm/ocr.js +23 -0
- package/dist_ts_kvm/plugins.d.ts +6 -0
- package/dist_ts_kvm/plugins.js +10 -0
- package/dist_ts_kvm/tools.d.ts +15 -0
- package/dist_ts_kvm/tools.js +40 -0
- package/dist_ts_mcp/index.d.ts +86 -0
- package/dist_ts_mcp/index.js +284 -0
- package/dist_ts_mcp/requestcontext.d.ts +11 -0
- package/dist_ts_mcp/requestcontext.js +42 -0
- package/dist_ts_media/index.d.ts +8 -0
- package/dist_ts_media/index.js +21 -0
- package/dist_ts_media/plugins.d.ts +2 -0
- package/dist_ts_media/plugins.js +3 -0
- package/dist_ts_ocr/classes.imageocr.d.ts +19 -0
- package/dist_ts_ocr/classes.imageocr.js +27 -0
- package/dist_ts_ocr/index.d.ts +2 -0
- package/dist_ts_ocr/index.js +3 -0
- package/dist_ts_ocr/ocr.mistral.d.ts +75 -0
- package/dist_ts_ocr/ocr.mistral.js +77 -0
- package/dist_ts_tools/index.d.ts +17 -0
- package/dist_ts_tools/index.js +10 -0
- package/dist_ts_tools/plugins.d.ts +7 -0
- package/dist_ts_tools/plugins.js +6 -0
- package/dist_ts_tools/tool.browser.d.ts +11 -0
- package/dist_ts_tools/tool.browser.js +128 -0
- package/dist_ts_tools/tool.context.d.ts +4 -0
- package/dist_ts_tools/tool.context.js +23 -0
- package/dist_ts_tools/tool.filesystem.d.ts +11 -0
- package/dist_ts_tools/tool.filesystem.js +106 -0
- package/dist_ts_tools/tool.http.d.ts +2 -0
- package/dist_ts_tools/tool.http.js +65 -0
- package/dist_ts_tools/tool.json.d.ts +2 -0
- package/dist_ts_tools/tool.json.js +47 -0
- package/dist_ts_tools/tool.shell.d.ts +15 -0
- package/dist_ts_tools/tool.shell.js +329 -0
- package/dist_ts_tools/utils.truncation.d.ts +10 -0
- package/dist_ts_tools/utils.truncation.js +26 -0
- package/dist_ts_tools_node/index.d.ts +5 -0
- package/dist_ts_tools_node/index.js +4 -0
- package/dist_ts_tools_node/plugins.d.ts +13 -0
- package/dist_ts_tools_node/plugins.js +13 -0
- package/dist_ts_tools_node/tool.context.d.ts +31 -0
- package/dist_ts_tools_node/tool.context.js +837 -0
- package/dist_ts_tools_node/tool.persistence.d.ts +15 -0
- package/dist_ts_tools_node/tool.persistence.js +129 -0
- package/dist_ts_tools_node/tools.local.d.ts +11 -0
- package/dist_ts_tools_node/tools.local.js +15 -0
- package/package.json +112 -4
- package/readme.md +122 -66
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/readme.md +122 -66
- package/ts_chat/classes.chatsession.ts +116 -0
- package/ts_chat/index.ts +8 -0
- package/ts_chat/interfaces.ts +64 -0
- package/ts_chat/plugins.ts +7 -0
- package/ts_chat/readme.md +49 -0
- package/ts_chat_cli/components.chatapp.ts +103 -0
- package/ts_chat_cli/components.inputarea.ts +29 -0
- package/ts_chat_cli/components.message.ts +48 -0
- package/ts_chat_cli/components.messagelist.ts +45 -0
- package/ts_chat_cli/components.statusbar.ts +31 -0
- package/ts_chat_cli/index.ts +2 -0
- package/ts_chat_cli/plugins.ts +21 -0
- package/ts_chat_cli/readme.md +40 -0
- package/ts_chat_cli/startchat.ts +34 -0
- package/ts_chat_web/flexchat-input.ts +184 -0
- package/ts_chat_web/flexchat-message.ts +185 -0
- package/ts_chat_web/flexchat-window.ts +416 -0
- package/ts_chat_web/index.ts +3 -0
- package/ts_chat_web/plugins.ts +9 -0
- package/ts_chat_web/readme.md +46 -0
- package/ts_compaction/index.ts +2 -0
- package/ts_compaction/plugins.ts +6 -0
- package/ts_compaction/readme.md +37 -0
- package/ts_compaction/smartagent.compaction.ts +59 -0
- package/ts_document/index.ts +82 -0
- package/ts_document/plugins.ts +3 -0
- package/ts_document/readme.md +49 -0
- package/ts_kvm/classes.browserkvm.ts +335 -0
- package/ts_kvm/classes.kvmterminal.ts +103 -0
- package/ts_kvm/commandwrappers.ts +83 -0
- package/ts_kvm/index.ts +6 -0
- package/ts_kvm/interfaces.ts +152 -0
- package/ts_kvm/ocr.ts +41 -0
- package/ts_kvm/plugins.ts +13 -0
- package/ts_kvm/readme.md +482 -0
- package/ts_kvm/tools.ts +58 -0
- package/ts_mcp/index.ts +470 -0
- package/ts_mcp/readme.md +37 -0
- package/ts_mcp/requestcontext.ts +66 -0
- package/ts_media/index.ts +29 -0
- package/ts_media/plugins.ts +2 -0
- package/ts_media/readme.md +37 -0
- package/ts_ocr/classes.imageocr.ts +53 -0
- package/ts_ocr/index.ts +2 -0
- package/ts_ocr/ocr.mistral.ts +192 -0
- package/ts_ocr/readme.md +48 -0
- package/ts_tools/index.ts +49 -0
- package/ts_tools/plugins.ts +7 -0
- package/ts_tools/readme.md +37 -0
- package/ts_tools/tool.browser.ts +159 -0
- package/ts_tools/tool.context.ts +23 -0
- package/ts_tools/tool.filesystem.ts +144 -0
- package/ts_tools/tool.http.ts +78 -0
- package/ts_tools/tool.json.ts +53 -0
- package/ts_tools/tool.shell.ts +418 -0
- package/ts_tools/utils.truncation.ts +39 -0
- package/ts_tools_node/index.ts +5 -0
- package/ts_tools_node/plugins.ts +16 -0
- package/ts_tools_node/readme.md +37 -0
- package/ts_tools_node/tool.context.ts +991 -0
- package/ts_tools_node/tool.persistence.ts +146 -0
- package/ts_tools_node/tools.local.ts +26 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
export function jsonTool() {
|
|
3
|
+
return {
|
|
4
|
+
json_validate: plugins.tool({
|
|
5
|
+
description: 'Validate a JSON string and optionally check for required fields.',
|
|
6
|
+
inputSchema: plugins.z.object({
|
|
7
|
+
jsonString: plugins.z.string().describe('JSON string to validate'),
|
|
8
|
+
requiredFields: plugins.z
|
|
9
|
+
.array(plugins.z.string())
|
|
10
|
+
.optional()
|
|
11
|
+
.describe('Fields that must exist at the top level'),
|
|
12
|
+
}),
|
|
13
|
+
execute: async ({ jsonString, requiredFields, }) => {
|
|
14
|
+
try {
|
|
15
|
+
const parsed = JSON.parse(jsonString);
|
|
16
|
+
if (requiredFields?.length) {
|
|
17
|
+
const missing = requiredFields.filter((f) => !(f in parsed));
|
|
18
|
+
if (missing.length) {
|
|
19
|
+
return `Invalid: missing required fields: ${missing.join(', ')}`;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const type = Array.isArray(parsed) ? 'array' : typeof parsed;
|
|
23
|
+
return `Valid JSON (${type})`;
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
return `Invalid JSON: ${e.message}`;
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
}),
|
|
30
|
+
json_transform: plugins.tool({
|
|
31
|
+
description: 'Parse a JSON string and return it pretty-printed.',
|
|
32
|
+
inputSchema: plugins.z.object({
|
|
33
|
+
jsonString: plugins.z.string().describe('JSON string to format'),
|
|
34
|
+
}),
|
|
35
|
+
execute: async ({ jsonString }) => {
|
|
36
|
+
try {
|
|
37
|
+
const parsed = JSON.parse(jsonString);
|
|
38
|
+
return JSON.stringify(parsed, null, 2);
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
return `Error parsing JSON: ${e.message}`;
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
}),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC5qc29uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfdG9vbHMvdG9vbC5qc29uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBRXhDLE1BQU0sVUFBVSxRQUFRO0lBQ3RCLE9BQU87UUFDTCxhQUFhLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQztZQUMxQixXQUFXLEVBQ1Qsa0VBQWtFO1lBQ3BFLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztnQkFDNUIsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLHlCQUF5QixDQUFDO2dCQUNsRSxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7cUJBQ3RCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO3FCQUN6QixRQUFRLEVBQUU7cUJBQ1YsUUFBUSxDQUFDLHlDQUF5QyxDQUFDO2FBQ3ZELENBQUM7WUFDRixPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQ2QsVUFBVSxFQUNWLGNBQWMsR0FJZixFQUFFLEVBQUU7Z0JBQ0gsSUFBSSxDQUFDO29CQUNILE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQ3RDLElBQUksY0FBYyxFQUFFLE1BQU0sRUFBRSxDQUFDO3dCQUMzQixNQUFNLE9BQU8sR0FBRyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUM7d0JBQzdELElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDOzRCQUNuQixPQUFPLHFDQUFxQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7d0JBQ25FLENBQUM7b0JBQ0gsQ0FBQztvQkFDRCxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sTUFBTSxDQUFDO29CQUM3RCxPQUFPLGVBQWUsSUFBSSxHQUFHLENBQUM7Z0JBQ2hDLENBQUM7Z0JBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztvQkFDWCxPQUFPLGlCQUFrQixDQUFXLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2pELENBQUM7WUFDSCxDQUFDO1NBQ0YsQ0FBQztRQUVGLGNBQWMsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQzNCLFdBQVcsRUFBRSxtREFBbUQ7WUFDaEUsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO2dCQUM1QixVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsdUJBQXVCLENBQUM7YUFDakUsQ0FBQztZQUNGLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRSxVQUFVLEVBQTBCLEVBQUUsRUFBRTtnQkFDeEQsSUFBSSxDQUFDO29CQUNILE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQ3RDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUN6QyxDQUFDO2dCQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7b0JBQ1gsT0FBTyx1QkFBd0IsQ0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUN2RCxDQUFDO1lBQ0gsQ0FBQztTQUNGLENBQUM7S0FDSCxDQUFDO0FBQ0osQ0FBQyJ9
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { type IToolExecutionContext } from './tool.context.js';
|
|
3
|
+
export interface ICreateShellToolsOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Exact executable allowlist for structured execution. Raw command filtering is advisory.
|
|
6
|
+
*/
|
|
7
|
+
allowedCommands?: string[];
|
|
8
|
+
/** Maximum output lines before truncating. */
|
|
9
|
+
maxLines?: number;
|
|
10
|
+
/** Maximum output bytes before truncating. */
|
|
11
|
+
maxBytes?: number;
|
|
12
|
+
/** Expose start_shell when context.jobs exists. Default: true. */
|
|
13
|
+
includeBackground?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function createShellTools(context: IToolExecutionContext, options?: ICreateShellToolsOptions): plugins.ToolSet;
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { formatShellResult, } from './tool.context.js';
|
|
3
|
+
const DEFAULT_FOREGROUND_PREVIEW_BYTES = 50 * 1024;
|
|
4
|
+
const MAX_FOREGROUND_PRELIMINARY_CHUNKS = 64;
|
|
5
|
+
const MAX_FOREGROUND_PRELIMINARY_BYTES = 256 * 1024;
|
|
6
|
+
const singleShellOutput = async function* (output) {
|
|
7
|
+
yield output;
|
|
8
|
+
};
|
|
9
|
+
const foregroundPreviewByteLimit = (configuredMaxBytes) => (Number.isSafeInteger(configuredMaxBytes) && configuredMaxBytes > 0
|
|
10
|
+
? Math.min(configuredMaxBytes, DEFAULT_FOREGROUND_PREVIEW_BYTES)
|
|
11
|
+
: DEFAULT_FOREGROUND_PREVIEW_BYTES);
|
|
12
|
+
const formatForegroundShellPreview = (stdout, stderr, captureTruncated) => {
|
|
13
|
+
const output = stderr
|
|
14
|
+
? stdout
|
|
15
|
+
? `stdout:\n${stdout}\nstderr:\n${stderr}`
|
|
16
|
+
: `stderr:\n${stderr}`
|
|
17
|
+
: stdout;
|
|
18
|
+
return captureTruncated
|
|
19
|
+
? `${output}${output ? '\n' : ''}[Live output preview truncated; final output will follow.]`
|
|
20
|
+
: output;
|
|
21
|
+
};
|
|
22
|
+
class ForegroundShellResultStream {
|
|
23
|
+
options;
|
|
24
|
+
abortController = new AbortController();
|
|
25
|
+
abortSignal;
|
|
26
|
+
previewByteLimit;
|
|
27
|
+
queue = [];
|
|
28
|
+
waiters = [];
|
|
29
|
+
completion;
|
|
30
|
+
stdout = '';
|
|
31
|
+
stderr = '';
|
|
32
|
+
previewBytes = 0;
|
|
33
|
+
captureTruncated = false;
|
|
34
|
+
lastPreview = '';
|
|
35
|
+
preliminaryChunks = 0;
|
|
36
|
+
preliminaryBytes = 0;
|
|
37
|
+
previewsDisabled = false;
|
|
38
|
+
settled = false;
|
|
39
|
+
returned = false;
|
|
40
|
+
terminalError;
|
|
41
|
+
constructor(options) {
|
|
42
|
+
this.options = options;
|
|
43
|
+
this.abortSignal = options.abortSignal
|
|
44
|
+
? AbortSignal.any([options.abortSignal, this.abortController.signal])
|
|
45
|
+
: this.abortController.signal;
|
|
46
|
+
this.previewByteLimit = foregroundPreviewByteLimit(options.maxBytes);
|
|
47
|
+
}
|
|
48
|
+
[Symbol.asyncIterator]() {
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
next() {
|
|
52
|
+
if (this.returned)
|
|
53
|
+
return Promise.resolve({ done: true, value: undefined });
|
|
54
|
+
this.ensureStarted();
|
|
55
|
+
const queued = this.queue.shift();
|
|
56
|
+
if (queued)
|
|
57
|
+
return Promise.resolve(this.deliver(queued));
|
|
58
|
+
if (this.settled) {
|
|
59
|
+
return this.terminalError === undefined
|
|
60
|
+
? Promise.resolve({ done: true, value: undefined })
|
|
61
|
+
: Promise.reject(this.terminalError);
|
|
62
|
+
}
|
|
63
|
+
return new Promise((resolve, reject) => {
|
|
64
|
+
this.waiters.push({ resolve, reject });
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async return() {
|
|
68
|
+
if (!this.returned) {
|
|
69
|
+
this.returned = true;
|
|
70
|
+
this.abortController.abort(new DOMException('Foreground shell iteration stopped.', 'AbortError'));
|
|
71
|
+
this.queue.length = 0;
|
|
72
|
+
this.flushWaiters();
|
|
73
|
+
}
|
|
74
|
+
if (this.completion) {
|
|
75
|
+
try {
|
|
76
|
+
await this.completion;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Iterator cancellation owns the abort; the cancelled command result is not a tool failure.
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return { done: true, value: undefined };
|
|
83
|
+
}
|
|
84
|
+
async throw(error) {
|
|
85
|
+
if (!this.returned) {
|
|
86
|
+
this.returned = true;
|
|
87
|
+
this.abortController.abort(error);
|
|
88
|
+
this.queue.length = 0;
|
|
89
|
+
while (this.waiters.length > 0)
|
|
90
|
+
this.waiters.shift().reject(error);
|
|
91
|
+
}
|
|
92
|
+
if (this.completion) {
|
|
93
|
+
try {
|
|
94
|
+
await this.completion;
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// The caller-provided iterator error remains authoritative.
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
async handleOutput(stream, chunk) {
|
|
103
|
+
if (this.returned || this.settled || this.previewsDisabled || !chunk)
|
|
104
|
+
return;
|
|
105
|
+
let accepted = '';
|
|
106
|
+
let acceptedBytes = 0;
|
|
107
|
+
for (const character of chunk) {
|
|
108
|
+
const characterBytes = Buffer.byteLength(character);
|
|
109
|
+
if (this.previewBytes + acceptedBytes + characterBytes > this.previewByteLimit)
|
|
110
|
+
break;
|
|
111
|
+
accepted += character;
|
|
112
|
+
acceptedBytes += characterBytes;
|
|
113
|
+
}
|
|
114
|
+
if (acceptedBytes < Buffer.byteLength(chunk))
|
|
115
|
+
this.captureTruncated = true;
|
|
116
|
+
if (accepted) {
|
|
117
|
+
if (stream === 'stdout')
|
|
118
|
+
this.stdout += accepted;
|
|
119
|
+
else
|
|
120
|
+
this.stderr += accepted;
|
|
121
|
+
this.previewBytes += acceptedBytes;
|
|
122
|
+
}
|
|
123
|
+
const preview = plugins.truncateOutput(formatForegroundShellPreview(this.stdout, this.stderr, this.captureTruncated), { maxLines: this.options.maxLines, maxBytes: this.options.maxBytes }).content;
|
|
124
|
+
if (!preview || preview === this.lastPreview)
|
|
125
|
+
return;
|
|
126
|
+
const bytes = Buffer.byteLength(JSON.stringify(preview));
|
|
127
|
+
if (this.preliminaryChunks + 1 > MAX_FOREGROUND_PRELIMINARY_CHUNKS
|
|
128
|
+
|| this.preliminaryBytes + bytes > MAX_FOREGROUND_PRELIMINARY_BYTES) {
|
|
129
|
+
this.previewsDisabled = true;
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
this.lastPreview = preview;
|
|
133
|
+
for (let index = this.queue.length - 1; index >= 0; index--) {
|
|
134
|
+
if (this.queue[index].kind === 'preliminary')
|
|
135
|
+
this.queue.splice(index, 1);
|
|
136
|
+
}
|
|
137
|
+
this.queue.push({ kind: 'preliminary', content: preview, bytes });
|
|
138
|
+
if (this.captureTruncated)
|
|
139
|
+
this.previewsDisabled = true;
|
|
140
|
+
this.flushWaiters();
|
|
141
|
+
}
|
|
142
|
+
ensureStarted() {
|
|
143
|
+
if (this.completion)
|
|
144
|
+
return;
|
|
145
|
+
const completion = Promise.resolve().then(() => this.options.start(this.abortSignal, async (stream, chunk) => this.handleOutput(stream, chunk)));
|
|
146
|
+
this.completion = completion;
|
|
147
|
+
void completion.then((result) => this.finish(result), (error) => this.fail(error));
|
|
148
|
+
}
|
|
149
|
+
finish(result) {
|
|
150
|
+
this.settled = true;
|
|
151
|
+
if (this.returned)
|
|
152
|
+
return;
|
|
153
|
+
const content = plugins.truncateOutput(formatShellResult(result), {
|
|
154
|
+
maxLines: this.options.maxLines,
|
|
155
|
+
maxBytes: this.options.maxBytes,
|
|
156
|
+
}).content;
|
|
157
|
+
this.queue.push({ kind: 'final', content, bytes: Buffer.byteLength(content) });
|
|
158
|
+
this.flushWaiters();
|
|
159
|
+
}
|
|
160
|
+
fail(error) {
|
|
161
|
+
this.settled = true;
|
|
162
|
+
this.terminalError = error;
|
|
163
|
+
this.flushWaiters();
|
|
164
|
+
}
|
|
165
|
+
deliver(output) {
|
|
166
|
+
if (output.kind === 'preliminary') {
|
|
167
|
+
this.preliminaryChunks++;
|
|
168
|
+
this.preliminaryBytes += output.bytes;
|
|
169
|
+
}
|
|
170
|
+
return { done: false, value: output.content };
|
|
171
|
+
}
|
|
172
|
+
flushWaiters() {
|
|
173
|
+
while (this.waiters.length > 0 && this.queue.length > 0) {
|
|
174
|
+
this.waiters.shift().resolve(this.deliver(this.queue.shift()));
|
|
175
|
+
}
|
|
176
|
+
if (!this.settled && !this.returned)
|
|
177
|
+
return;
|
|
178
|
+
while (this.waiters.length > 0) {
|
|
179
|
+
const waiter = this.waiters.shift();
|
|
180
|
+
if (!this.returned && this.terminalError !== undefined)
|
|
181
|
+
waiter.reject(this.terminalError);
|
|
182
|
+
else
|
|
183
|
+
waiter.resolve({ done: true, value: undefined });
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
export function createShellTools(context, options = {}) {
|
|
188
|
+
const tools = {
|
|
189
|
+
run_command: plugins.tool({
|
|
190
|
+
description: 'Execute a raw shell command through bash -lc. Shell composition is supported. Prefer run_shell when direct structured execution is sufficient.',
|
|
191
|
+
inputSchema: plugins.z.object({
|
|
192
|
+
command: plugins.z.string().describe('The shell command to execute'),
|
|
193
|
+
cwd: plugins.z
|
|
194
|
+
.string()
|
|
195
|
+
.optional()
|
|
196
|
+
.describe('Working directory for the command'),
|
|
197
|
+
timeout: plugins.z
|
|
198
|
+
.number()
|
|
199
|
+
.optional()
|
|
200
|
+
.describe('Timeout in milliseconds'),
|
|
201
|
+
timeoutMs: plugins.z
|
|
202
|
+
.number()
|
|
203
|
+
.optional()
|
|
204
|
+
.describe('Timeout in milliseconds'),
|
|
205
|
+
}),
|
|
206
|
+
execute: ({ command, cwd, timeout, timeoutMs, }, invocationOptions) => {
|
|
207
|
+
const shell = context.shell;
|
|
208
|
+
if (!shell) {
|
|
209
|
+
throw new Error('Shell tool is not available in this execution context.');
|
|
210
|
+
}
|
|
211
|
+
if (options.allowedCommands?.length) {
|
|
212
|
+
const baseCommand = command.trim().split(/\s+/)[0];
|
|
213
|
+
if (!options.allowedCommands.includes(baseCommand)) {
|
|
214
|
+
return singleShellOutput(`Raw command "${baseCommand}" is not in the advisory allowed commands list: ${options.allowedCommands.join(', ')}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const abortSignal = invocationOptions?.abortSignal ?? context.abortSignal;
|
|
218
|
+
return new ForegroundShellResultStream({
|
|
219
|
+
abortSignal,
|
|
220
|
+
maxLines: options.maxLines,
|
|
221
|
+
maxBytes: options.maxBytes,
|
|
222
|
+
start: async (executionSignal, onOutput) => {
|
|
223
|
+
await context.requestPermission?.({
|
|
224
|
+
type: 'shell',
|
|
225
|
+
title: 'Run shell command',
|
|
226
|
+
metadata: { command, cwd: cwd ?? context.cwd },
|
|
227
|
+
toolCallId: invocationOptions?.toolCallId,
|
|
228
|
+
abortSignal: executionSignal,
|
|
229
|
+
});
|
|
230
|
+
executionSignal.throwIfAborted();
|
|
231
|
+
return shell.run(command, {
|
|
232
|
+
cwd: cwd ?? context.cwd,
|
|
233
|
+
timeoutMs: timeoutMs ?? timeout,
|
|
234
|
+
toolCallId: invocationOptions?.toolCallId,
|
|
235
|
+
abortSignal: executionSignal,
|
|
236
|
+
onOutput,
|
|
237
|
+
});
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
},
|
|
241
|
+
}),
|
|
242
|
+
};
|
|
243
|
+
if (context.shell?.runStructured) {
|
|
244
|
+
tools.run_shell = plugins.tool({
|
|
245
|
+
description: 'Execute an executable directly with a literal argument array. No shell parsing or shell composition is performed.',
|
|
246
|
+
inputSchema: plugins.z.object({
|
|
247
|
+
executable: plugins.z.string().describe('Exact executable name or path'),
|
|
248
|
+
args: plugins.z.array(plugins.z.string()).default([]).describe('Literal argument array'),
|
|
249
|
+
cwd: plugins.z.string().optional().describe('Working directory for the command'),
|
|
250
|
+
timeoutMs: plugins.z.number().optional().describe('Timeout in milliseconds'),
|
|
251
|
+
}),
|
|
252
|
+
execute: (input, invocationOptions) => {
|
|
253
|
+
const runStructured = context.shell?.runStructured;
|
|
254
|
+
if (!runStructured) {
|
|
255
|
+
throw new Error('Structured shell execution is not available in this execution context.');
|
|
256
|
+
}
|
|
257
|
+
if (options.allowedCommands?.length && !options.allowedCommands.includes(input.executable)) {
|
|
258
|
+
return singleShellOutput({
|
|
259
|
+
error: `Executable "${input.executable}" is not in the allowed commands list.`,
|
|
260
|
+
allowedCommands: options.allowedCommands,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
const abortSignal = invocationOptions?.abortSignal ?? context.abortSignal;
|
|
264
|
+
return new ForegroundShellResultStream({
|
|
265
|
+
abortSignal,
|
|
266
|
+
maxLines: options.maxLines,
|
|
267
|
+
maxBytes: options.maxBytes,
|
|
268
|
+
start: async (executionSignal, onOutput) => {
|
|
269
|
+
await context.requestPermission?.({
|
|
270
|
+
type: 'shell',
|
|
271
|
+
title: 'Run structured command',
|
|
272
|
+
metadata: { executable: input.executable, args: input.args, cwd: input.cwd ?? context.cwd },
|
|
273
|
+
toolCallId: invocationOptions?.toolCallId,
|
|
274
|
+
abortSignal: executionSignal,
|
|
275
|
+
});
|
|
276
|
+
executionSignal.throwIfAborted();
|
|
277
|
+
return runStructured({ executable: input.executable, args: input.args }, {
|
|
278
|
+
cwd: input.cwd ?? context.cwd,
|
|
279
|
+
timeoutMs: input.timeoutMs,
|
|
280
|
+
toolCallId: invocationOptions?.toolCallId,
|
|
281
|
+
abortSignal: executionSignal,
|
|
282
|
+
onOutput,
|
|
283
|
+
});
|
|
284
|
+
},
|
|
285
|
+
});
|
|
286
|
+
},
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
if (context.jobs && options.includeBackground !== false) {
|
|
290
|
+
tools.start_shell = plugins.tool({
|
|
291
|
+
description: 'Start a structured shell command as an independent background execution and return its execution ID immediately.',
|
|
292
|
+
inputSchema: plugins.z.object({
|
|
293
|
+
executable: plugins.z.string().describe('Exact executable name or path'),
|
|
294
|
+
args: plugins.z.array(plugins.z.string()).default([]).describe('Literal argument array'),
|
|
295
|
+
cwd: plugins.z.string().optional().describe('Working directory for the command'),
|
|
296
|
+
timeoutMs: plugins.z.number().optional().describe('Background execution timeout in milliseconds'),
|
|
297
|
+
}),
|
|
298
|
+
execute: async (input, invocationOptions) => {
|
|
299
|
+
if (!context.jobs)
|
|
300
|
+
throw new Error('Background jobs are not available in this execution context.');
|
|
301
|
+
if (options.allowedCommands?.length && !options.allowedCommands.includes(input.executable)) {
|
|
302
|
+
throw new Error(`Executable "${input.executable}" is not in the allowed commands list.`);
|
|
303
|
+
}
|
|
304
|
+
const admissionSignal = invocationOptions?.abortSignal ?? context.abortSignal;
|
|
305
|
+
await context.requestPermission?.({
|
|
306
|
+
type: 'shell-background',
|
|
307
|
+
title: 'Start background shell command',
|
|
308
|
+
metadata: { executable: input.executable, args: input.args, cwd: input.cwd ?? context.cwd },
|
|
309
|
+
toolCallId: invocationOptions?.toolCallId,
|
|
310
|
+
abortSignal: admissionSignal,
|
|
311
|
+
});
|
|
312
|
+
admissionSignal?.throwIfAborted();
|
|
313
|
+
const handle = await context.jobs.start({
|
|
314
|
+
type: 'shell',
|
|
315
|
+
command: { executable: input.executable, args: input.args },
|
|
316
|
+
cwd: input.cwd ?? context.cwd,
|
|
317
|
+
timeoutMs: input.timeoutMs,
|
|
318
|
+
metadata: { toolCallId: invocationOptions?.toolCallId },
|
|
319
|
+
}, {
|
|
320
|
+
toolCallId: invocationOptions?.toolCallId,
|
|
321
|
+
abortSignal: admissionSignal,
|
|
322
|
+
});
|
|
323
|
+
return { executionId: handle.executionId, state: 'running' };
|
|
324
|
+
},
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
return tools;
|
|
328
|
+
}
|
|
329
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC5zaGVsbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX3Rvb2xzL3Rvb2wuc2hlbGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUNMLGlCQUFpQixHQUtsQixNQUFNLG1CQUFtQixDQUFDO0FBRTNCLE1BQU0sZ0NBQWdDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUNuRCxNQUFNLGlDQUFpQyxHQUFHLEVBQUUsQ0FBQztBQUM3QyxNQUFNLGdDQUFnQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUM7QUE0QnBELE1BQU0saUJBQWlCLEdBQUcsS0FBSyxTQUFTLENBQUMsRUFBVyxNQUFlO0lBQ2pFLE1BQU0sTUFBTSxDQUFDO0FBQ2YsQ0FBQyxDQUFDO0FBRUYsTUFBTSwwQkFBMEIsR0FBRyxDQUFDLGtCQUEyQixFQUFVLEVBQUUsQ0FBQyxDQUMxRSxNQUFNLENBQUMsYUFBYSxDQUFDLGtCQUFrQixDQUFDLElBQUksa0JBQW1CLEdBQUcsQ0FBQztJQUNqRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxrQkFBbUIsRUFBRSxnQ0FBZ0MsQ0FBQztJQUNqRSxDQUFDLENBQUMsZ0NBQWdDLENBQ3JDLENBQUM7QUFFRixNQUFNLDRCQUE0QixHQUFHLENBQ25DLE1BQWMsRUFDZCxNQUFjLEVBQ2QsZ0JBQXlCLEVBQ2pCLEVBQUU7SUFDVixNQUFNLE1BQU0sR0FBRyxNQUFNO1FBQ25CLENBQUMsQ0FBQyxNQUFNO1lBQ04sQ0FBQyxDQUFDLFlBQVksTUFBTSxjQUFjLE1BQU0sRUFBRTtZQUMxQyxDQUFDLENBQUMsWUFBWSxNQUFNLEVBQUU7UUFDeEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUNYLE9BQU8sZ0JBQWdCO1FBQ3JCLENBQUMsQ0FBQyxHQUFHLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMs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
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface ITruncateResult {
|
|
2
|
+
content: string;
|
|
3
|
+
truncated: boolean;
|
|
4
|
+
/** Set when truncated: describes what was dropped */
|
|
5
|
+
notice?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function truncateOutput(text: string, options?: {
|
|
8
|
+
maxLines?: number;
|
|
9
|
+
maxBytes?: number;
|
|
10
|
+
}): ITruncateResult;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Truncation logic derived from opencode (MIT) — https://github.com/sst/opencode
|
|
2
|
+
const MAX_LINES = 2000;
|
|
3
|
+
const MAX_BYTES = 50 * 1024; // 50 KB
|
|
4
|
+
export function truncateOutput(text, options) {
|
|
5
|
+
const maxLines = options?.maxLines ?? MAX_LINES;
|
|
6
|
+
const maxBytes = options?.maxBytes ?? MAX_BYTES;
|
|
7
|
+
const lines = text.split('\n');
|
|
8
|
+
const totalBytes = Buffer.byteLength(text, 'utf-8');
|
|
9
|
+
if (lines.length <= maxLines && totalBytes <= maxBytes) {
|
|
10
|
+
return { content: text, truncated: false };
|
|
11
|
+
}
|
|
12
|
+
const out = [];
|
|
13
|
+
let bytes = 0;
|
|
14
|
+
for (let i = 0; i < lines.length && i < maxLines; i++) {
|
|
15
|
+
const size = Buffer.byteLength(lines[i], 'utf-8') + (i > 0 ? 1 : 0);
|
|
16
|
+
if (bytes + size > maxBytes)
|
|
17
|
+
break;
|
|
18
|
+
out.push(lines[i]);
|
|
19
|
+
bytes += size;
|
|
20
|
+
}
|
|
21
|
+
const kept = out.length;
|
|
22
|
+
const dropped = lines.length - kept;
|
|
23
|
+
const notice = `\n[Output truncated: showing ${kept}/${lines.length} lines. ${dropped} lines omitted.]`;
|
|
24
|
+
return { content: out.join('\n') + notice, truncated: true, notice };
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMudHJ1bmNhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX3Rvb2xzL3V0aWxzLnRydW5jYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsaUZBQWlGO0FBRWpGLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQztBQUN2QixNQUFNLFNBQVMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsUUFBUTtBQVNyQyxNQUFNLFVBQVUsY0FBYyxDQUM1QixJQUFZLEVBQ1osT0FBa0Q7SUFFbEQsTUFBTSxRQUFRLEdBQUcsT0FBTyxFQUFFLFFBQVEsSUFBSSxTQUFTLENBQUM7SUFDaEQsTUFBTSxRQUFRLEdBQUcsT0FBTyxFQUFFLFFBQVEsSUFBSSxTQUFTLENBQUM7SUFDaEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMvQixNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUVwRCxJQUFJLEtBQUssQ0FBQyxNQUFNLElBQUksUUFBUSxJQUFJLFVBQVUsSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUN2RCxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDN0MsQ0FBQztJQUVELE1BQU0sR0FBRyxHQUFhLEVBQUUsQ0FBQztJQUN6QixJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDZCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sSUFBSSxDQUFDLEdBQUcsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDdEQsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BFLElBQUksS0FBSyxHQUFHLElBQUksR0FBRyxRQUFRO1lBQUUsTUFBTTtRQUNuQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25CLEtBQUssSUFBSSxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVELE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7SUFDeEIsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDcEMsTUFBTSxNQUFNLEdBQUcsZ0NBQWdDLElBQUksSUFBSSxLQUFLLENBQUMsTUFBTSxXQUFXLE9BQU8sa0JBQWtCLENBQUM7SUFDeEcsT0FBTyxFQUFFLE9BQU8sRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDO0FBQ3ZFLENBQUMifQ==
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { createLocalToolExecutionContext } from './tool.context.js';
|
|
2
|
+
export type { ILocalToolExecutionContextOptions } from './tool.context.js';
|
|
3
|
+
export { FileToolJobStore } from './tool.persistence.js';
|
|
4
|
+
export type { IFileToolJobStoreOptions } from './tool.persistence.js';
|
|
5
|
+
export * from './tools.local.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { createLocalToolExecutionContext } from './tool.context.js';
|
|
2
|
+
export { FileToolJobStore } from './tool.persistence.js';
|
|
3
|
+
export * from './tools.local.js';
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c190b29sc19ub2RlL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXBFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXpELGNBQWMsa0JBQWtCLENBQUMifQ==
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as childProcess from 'node:child_process';
|
|
2
|
+
import * as crypto from 'node:crypto';
|
|
3
|
+
import * as fs from 'node:fs';
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import { StringDecoder } from 'node:string_decoder';
|
|
6
|
+
import * as v8 from 'node:v8';
|
|
7
|
+
export { childProcess, crypto, fs, path, StringDecoder, v8 };
|
|
8
|
+
import { createToolJobSnapshot, JOB_SNAPSHOT_SCHEMA_VERSION, ToolJobStoreConflictError } from '@modelprofile.com/flexharness-agent';
|
|
9
|
+
export { createToolJobSnapshot, JOB_SNAPSHOT_SCHEMA_VERSION, ToolJobStoreConflictError };
|
|
10
|
+
import { createFilesystemTools, createShellTools } from '@modelprofile.com/flexharness/tools';
|
|
11
|
+
export { createFilesystemTools, createShellTools };
|
|
12
|
+
export type { ICreateFilesystemToolsOptions, ICreateShellToolsOptions, ToolSet } from '@modelprofile.com/flexharness/tools';
|
|
13
|
+
export type { IToolExecutionContext } from '@modelprofile.com/flexharness-agent';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// node native
|
|
2
|
+
import * as childProcess from 'node:child_process';
|
|
3
|
+
import * as crypto from 'node:crypto';
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
import { StringDecoder } from 'node:string_decoder';
|
|
7
|
+
import * as v8 from 'node:v8';
|
|
8
|
+
export { childProcess, crypto, fs, path, StringDecoder, v8 };
|
|
9
|
+
import { createToolJobSnapshot, JOB_SNAPSHOT_SCHEMA_VERSION, ToolJobStoreConflictError } from '@modelprofile.com/flexharness-agent';
|
|
10
|
+
export { createToolJobSnapshot, JOB_SNAPSHOT_SCHEMA_VERSION, ToolJobStoreConflictError };
|
|
11
|
+
import { createFilesystemTools, createShellTools } from '@modelprofile.com/flexharness/tools';
|
|
12
|
+
export { createFilesystemTools, createShellTools };
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX3Rvb2xzX25vZGUvcGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjO0FBQ2QsT0FBTyxLQUFLLFlBQVksTUFBTSxvQkFBb0IsQ0FBQztBQUNuRCxPQUFPLEtBQUssTUFBTSxNQUFNLGFBQWEsQ0FBQztBQUN0QyxPQUFPLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM5QixPQUFPLEtBQUssSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUNsQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFOUIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsRUFBRSxFQUFFLENBQUM7QUFFN0QsT0FBTyxFQUFFLHFCQUFxQixFQUFFLDJCQUEyQixFQUFFLHlCQUF5QixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDcEksT0FBTyxFQUFFLHFCQUFxQixFQUFFLDJCQUEyQixFQUFFLHlCQUF5QixFQUFFLENBQUM7QUFDekYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLGdCQUFnQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDOUYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLGdCQUFnQixFQUFFLENBQUMifQ==
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { IToolJobStore } from '@modelprofile.com/flexharness-agent';
|
|
2
|
+
import type { IToolPermissionRequest, IToolJobState, IToolExecutionContext } from '@modelprofile.com/flexharness-agent';
|
|
3
|
+
export interface ILocalToolExecutionContextOptions {
|
|
4
|
+
cwd?: string;
|
|
5
|
+
rootDir?: string;
|
|
6
|
+
/** Additional canonical roots available to filesystem read/list operations only. */
|
|
7
|
+
additionalReadOnlyRoots?: string[];
|
|
8
|
+
abortSignal?: AbortSignal;
|
|
9
|
+
/** Guards each local filesystem operation or shell side effect. */
|
|
10
|
+
beforeOperation?: () => Promise<void> | void;
|
|
11
|
+
/** Hard combined stdout/stderr capture limit for each local shell command. Default: 1 MiB. */
|
|
12
|
+
maxShellOutputBytes?: number;
|
|
13
|
+
/** Number of terminal background job snapshots retained for get/list. Default: 100. */
|
|
14
|
+
maxRetainedJobs?: number;
|
|
15
|
+
/** Optional durable store used to restore terminal jobs after host restarts. */
|
|
16
|
+
jobStore?: IToolJobStore;
|
|
17
|
+
/** Maximum wait for each local shell output listener before its process is terminated. Default: 30 seconds. */
|
|
18
|
+
outputListenerTimeoutMs?: number;
|
|
19
|
+
/** Maximum wait for job-store load/save operations. Defaults to outputListenerTimeoutMs. */
|
|
20
|
+
jobStoreOperationTimeoutMs?: number;
|
|
21
|
+
/** Reconciles a persisted running job whose original process ownership was lost. */
|
|
22
|
+
settleOrphanedJob?: (job: IToolJobState, abortSignal: AbortSignal) => Promise<IToolJobState> | IToolJobState;
|
|
23
|
+
requestPermission?: (request: IToolPermissionRequest) => Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
export declare const createLocalToolExecutionContext: (options?: ILocalToolExecutionContextOptions) => IToolExecutionContext;
|
|
26
|
+
/** @internal */
|
|
27
|
+
export declare const handleLocalShellChildError: (error: Error, childPid: number | undefined, handlers: {
|
|
28
|
+
settleSpawnFailure: (error: Error) => void;
|
|
29
|
+
retainError: (error: Error) => void;
|
|
30
|
+
requestTermination: () => void;
|
|
31
|
+
}) => void;
|