@nodetool-ai/runtime 0.8.8 → 0.8.9-beta.2
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/.nodetool-build-stamp +1 -1
- package/dist/context.d.ts +6 -2
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +13 -24
- package/dist/context.js.map +1 -1
- package/dist/host-binaries.d.ts +5 -5
- package/dist/host-binaries.js +5 -5
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/invocation-account.d.ts +1 -42
- package/dist/invocation-account.d.ts.map +1 -1
- package/dist/invocation-account.js +1 -59
- package/dist/invocation-account.js.map +1 -1
- package/dist/media/abort.d.ts +8 -0
- package/dist/media/abort.d.ts.map +1 -0
- package/dist/media/abort.js +18 -0
- package/dist/media/abort.js.map +1 -0
- package/dist/media/audio-encoder.d.ts +37 -0
- package/dist/media/audio-encoder.d.ts.map +1 -0
- package/dist/media/audio-encoder.js +118 -0
- package/dist/media/audio-encoder.js.map +1 -0
- package/dist/media/audio.d.ts +36 -0
- package/dist/media/audio.d.ts.map +1 -0
- package/dist/media/audio.js +84 -0
- package/dist/media/audio.js.map +1 -0
- package/dist/media/av.d.ts +51 -0
- package/dist/media/av.d.ts.map +1 -0
- package/dist/media/av.js +146 -0
- package/dist/media/av.js.map +1 -0
- package/dist/media/codecs.d.ts +9 -0
- package/dist/media/codecs.d.ts.map +1 -0
- package/dist/media/codecs.js +17 -0
- package/dist/media/codecs.js.map +1 -0
- package/dist/media/concat.d.ts +56 -0
- package/dist/media/concat.d.ts.map +1 -0
- package/dist/media/concat.js +319 -0
- package/dist/media/concat.js.map +1 -0
- package/dist/media/convert.d.ts +31 -0
- package/dist/media/convert.d.ts.map +1 -0
- package/dist/media/convert.js +114 -0
- package/dist/media/convert.js.map +1 -0
- package/dist/media/decode.d.ts +31 -0
- package/dist/media/decode.d.ts.map +1 -0
- package/dist/media/decode.js +85 -0
- package/dist/media/decode.js.map +1 -0
- package/dist/media/filter-graph.d.ts +53 -0
- package/dist/media/filter-graph.d.ts.map +1 -0
- package/dist/media/filter-graph.js +260 -0
- package/dist/media/filter-graph.js.map +1 -0
- package/dist/media/frames.d.ts +31 -0
- package/dist/media/frames.d.ts.map +1 -0
- package/dist/media/frames.js +112 -0
- package/dist/media/frames.js.map +1 -0
- package/dist/media/index.d.ts +26 -0
- package/dist/media/index.d.ts.map +1 -0
- package/dist/media/index.js +26 -0
- package/dist/media/index.js.map +1 -0
- package/dist/media/mux.d.ts +58 -0
- package/dist/media/mux.d.ts.map +1 -0
- package/dist/media/mux.js +234 -0
- package/dist/media/mux.js.map +1 -0
- package/dist/media/probe.d.ts +84 -0
- package/dist/media/probe.d.ts.map +1 -0
- package/dist/media/probe.js +133 -0
- package/dist/media/probe.js.map +1 -0
- package/dist/media/rgba.d.ts +78 -0
- package/dist/media/rgba.d.ts.map +1 -0
- package/dist/media/rgba.js +285 -0
- package/dist/media/rgba.js.map +1 -0
- package/dist/media/testing.d.ts +119 -0
- package/dist/media/testing.d.ts.map +1 -0
- package/dist/media/testing.js +343 -0
- package/dist/media/testing.js.map +1 -0
- package/dist/media/transcode.d.ts +17 -0
- package/dist/media/transcode.d.ts.map +1 -0
- package/dist/media/transcode.js +19 -0
- package/dist/media/transcode.js.map +1 -0
- package/dist/media/transform.d.ts +61 -0
- package/dist/media/transform.d.ts.map +1 -0
- package/dist/media/transform.js +371 -0
- package/dist/media/transform.js.map +1 -0
- package/dist/media/verify.d.ts +17 -0
- package/dist/media/verify.d.ts.map +1 -0
- package/dist/media/verify.js +65 -0
- package/dist/media/verify.js.map +1 -0
- package/dist/media-loader.d.ts +8 -0
- package/dist/media-loader.d.ts.map +1 -0
- package/dist/media-loader.js +10 -0
- package/dist/media-loader.js.map +1 -0
- package/dist/prefixed-storage-adapter.d.ts.map +1 -1
- package/dist/prefixed-storage-adapter.js +1 -1
- package/dist/prefixed-storage-adapter.js.map +1 -1
- package/dist/providers/anthropic-provider.d.ts.map +1 -1
- package/dist/providers/anthropic-provider.js +1 -17
- package/dist/providers/anthropic-provider.js.map +1 -1
- package/dist/providers/data-uri.d.ts +6 -0
- package/dist/providers/data-uri.d.ts.map +1 -0
- package/dist/providers/data-uri.js +19 -0
- package/dist/providers/data-uri.js.map +1 -0
- package/dist/providers/fake-provider.js +1 -1
- package/dist/providers/meta-transcription.d.ts +1 -5
- package/dist/providers/meta-transcription.d.ts.map +1 -1
- package/dist/providers/meta-transcription.js +9 -55
- package/dist/providers/meta-transcription.js.map +1 -1
- package/dist/providers/node-llama-cpp-trending.generated.js +132 -132
- package/dist/providers/node-llama-cpp-trending.generated.js.map +1 -1
- package/dist/providers/ollama-provider.d.ts.map +1 -1
- package/dist/providers/ollama-provider.js +1 -17
- package/dist/providers/ollama-provider.js.map +1 -1
- package/dist/providers/openai-provider.js +2 -2
- package/dist/providers/openai-provider.js.map +1 -1
- package/dist/providers/openrouter-provider.d.ts.map +1 -1
- package/dist/providers/openrouter-provider.js +1 -0
- package/dist/providers/openrouter-provider.js.map +1 -1
- package/dist/providers/safe-url.d.ts +1 -69
- package/dist/providers/safe-url.d.ts.map +1 -1
- package/dist/providers/safe-url.js +1 -284
- package/dist/providers/safe-url.js.map +1 -1
- package/dist/providers/topaz-provider.d.ts +1 -1
- package/dist/providers/topaz-provider.js +1 -1
- package/dist/providers/video-frame-fallback.d.ts +1 -1
- package/dist/providers/video-frame-fallback.js +4 -4
- package/dist/providers/video-frame-fallback.js.map +1 -1
- package/dist/providers/video-frames.d.ts +6 -16
- package/dist/providers/video-frames.d.ts.map +1 -1
- package/dist/providers/video-frames.js +48 -116
- package/dist/providers/video-frames.js.map +1 -1
- package/dist/storage-workspace.d.ts +1 -61
- package/dist/storage-workspace.d.ts.map +1 -1
- package/dist/storage-workspace.js +2 -430
- package/dist/storage-workspace.js.map +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +57 -1
- package/dist/testing.js.map +1 -1
- package/dist/trim-video-window.d.ts.map +1 -1
- package/dist/trim-video-window.js +2 -32
- package/dist/trim-video-window.js.map +1 -1
- package/dist/workspace.d.ts +1 -118
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +1 -111
- package/dist/workspace.js.map +1 -1
- package/dist/yt-dlp-format.d.ts +22 -0
- package/dist/yt-dlp-format.d.ts.map +1 -0
- package/dist/yt-dlp-format.js +90 -0
- package/dist/yt-dlp-format.js.map +1 -0
- package/package.json +23 -6
|
@@ -1,37 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Sample a video into still frames
|
|
2
|
+
* Sample a video into still frames, decoded in process.
|
|
3
3
|
*
|
|
4
4
|
* This is what lets a vision model that cannot read a clip still answer
|
|
5
5
|
* questions about one: the bytes are decoded here, a bounded number of frames
|
|
6
6
|
* come back as JPEGs, and the caller sends them as ordinary image content.
|
|
7
|
-
*
|
|
8
|
-
* The argv is ours, not a model's — the only input path is a temp file this
|
|
9
|
-
* module wrote — so the containment `packages/agents/src/host-binary-guard.ts`
|
|
10
|
-
* applies to a model-supplied argv is not needed. `-protocol_whitelist file`
|
|
11
|
-
* and `-nostdin` still go in: an mp4 can name an external opener, and a child
|
|
12
|
-
* that inherits the server's stdin outlives the call.
|
|
7
|
+
* The only input is a temp file this module wrote.
|
|
13
8
|
*/
|
|
14
9
|
import { importNodeBuiltin } from "@nodetool-ai/config";
|
|
10
|
+
import { loadSharpOrThrow } from "../image-codec.js";
|
|
11
|
+
import { loadMediaModule } from "../media-loader.js";
|
|
15
12
|
import { withSpan } from "../tracing-helpers.js";
|
|
16
13
|
import { mp4DurationSeconds } from "./video-duration.js";
|
|
17
|
-
/** ffmpeg or ffprobe is not installed. Names the binary and the way out. */
|
|
18
|
-
export class FrameSamplingUnavailableError extends Error {
|
|
19
|
-
binary;
|
|
20
|
-
constructor(binary) {
|
|
21
|
-
super(`${binary} is not installed or not on PATH. Reading a video with a ` +
|
|
22
|
-
`provider that has no video content part samples frames with ffmpeg ` +
|
|
23
|
-
`first — install ffmpeg (the Package Manager UI can do this), or use ` +
|
|
24
|
-
`a provider whose chat models read video natively (gemini).`);
|
|
25
|
-
this.name = "FrameSamplingUnavailableError";
|
|
26
|
-
this.binary = binary;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
14
|
const DEFAULT_MAX_FRAMES = 16;
|
|
30
15
|
const DEFAULT_MAX_FPS = 1;
|
|
31
16
|
const DEFAULT_MAX_DIMENSION = 768;
|
|
32
|
-
/**
|
|
33
|
-
const JPEG_QUALITY =
|
|
34
|
-
const FFMPEG_MAX_BUFFER = 8 * 1024 * 1024;
|
|
17
|
+
/** sharp JPEG quality, about what ffmpeg's `-q:v 4` gave. */
|
|
18
|
+
const JPEG_QUALITY = 85;
|
|
35
19
|
/** Read a positive number from the environment, or fall back. */
|
|
36
20
|
function envNumber(name, fallback) {
|
|
37
21
|
const raw = Number(globalThis.process?.env?.[name]);
|
|
@@ -46,63 +30,15 @@ function frameSamplingLimits() {
|
|
|
46
30
|
};
|
|
47
31
|
}
|
|
48
32
|
async function nodeModules() {
|
|
49
|
-
const [
|
|
50
|
-
importNodeBuiltin("node:child_process"),
|
|
33
|
+
const [fs, os, path] = await Promise.all([
|
|
51
34
|
importNodeBuiltin("node:fs/promises"),
|
|
52
35
|
importNodeBuiltin("node:os"),
|
|
53
36
|
importNodeBuiltin("node:path")
|
|
54
37
|
]);
|
|
55
|
-
if (!
|
|
38
|
+
if (!fs || !os || !path) {
|
|
56
39
|
throw new Error("Video frame sampling requires Node built-in modules");
|
|
57
40
|
}
|
|
58
|
-
return {
|
|
59
|
-
}
|
|
60
|
-
/** Whether a spawn failed because the binary is not on PATH. */
|
|
61
|
-
function isSpawnEnoent(err) {
|
|
62
|
-
return (typeof err === "object" &&
|
|
63
|
-
err !== null &&
|
|
64
|
-
err.code === "ENOENT");
|
|
65
|
-
}
|
|
66
|
-
async function run(cp, binary, args, signal) {
|
|
67
|
-
return await new Promise((resolve, reject) => {
|
|
68
|
-
cp.execFile(binary, args, { maxBuffer: FFMPEG_MAX_BUFFER, signal, windowsHide: true }, (error, stdout, stderr) => {
|
|
69
|
-
if (error) {
|
|
70
|
-
if (isSpawnEnoent(error)) {
|
|
71
|
-
reject(new FrameSamplingUnavailableError(binary));
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
reject(error);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
resolve({ stdout: String(stdout), stderr: String(stderr) });
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
/** Clip length in seconds, or null when ffprobe cannot say. */
|
|
82
|
-
async function probeDuration(cp, file, signal) {
|
|
83
|
-
try {
|
|
84
|
-
const { stdout } = await run(cp, "ffprobe", [
|
|
85
|
-
"-v",
|
|
86
|
-
"error",
|
|
87
|
-
"-show_entries",
|
|
88
|
-
"format=duration",
|
|
89
|
-
"-of",
|
|
90
|
-
"csv=p=0",
|
|
91
|
-
file
|
|
92
|
-
], signal);
|
|
93
|
-
const seconds = Number(stdout.trim().split("\n")[0]);
|
|
94
|
-
return Number.isFinite(seconds) && seconds > 0 ? seconds : null;
|
|
95
|
-
}
|
|
96
|
-
catch (error) {
|
|
97
|
-
if (signal?.aborted)
|
|
98
|
-
throw error;
|
|
99
|
-
// A missing binary is actionable and must reach the caller. A probe that
|
|
100
|
-
// ran and failed (an odd container, no format header) is not: the sample
|
|
101
|
-
// falls back to the ceiling rate below.
|
|
102
|
-
if (error instanceof FrameSamplingUnavailableError)
|
|
103
|
-
throw error;
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
41
|
+
return { fs, os, path };
|
|
106
42
|
}
|
|
107
43
|
/** Read a video duration from its bytes without decoding frames. */
|
|
108
44
|
export async function probeVideoDurationSeconds(bytes, signal) {
|
|
@@ -113,17 +49,10 @@ export async function probeVideoDurationSeconds(bytes, signal) {
|
|
|
113
49
|
return mp4Duration;
|
|
114
50
|
}
|
|
115
51
|
return withSpan("media.probe_video_duration", { "media.byte_length": bytes.byteLength }, async () => {
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
await fs.writeFile(input, bytes, { signal });
|
|
121
|
-
return await probeDuration(cp, input, signal);
|
|
122
|
-
}
|
|
123
|
-
finally {
|
|
124
|
-
// Cleanup failure must not replace the duration result or probe error.
|
|
125
|
-
await fs.rm(dir, { recursive: true, force: true }).catch(() => { });
|
|
126
|
-
}
|
|
52
|
+
// Loaded on demand: the media module is Node-only.
|
|
53
|
+
const { probeDurationSec } = await import("../media/probe.js");
|
|
54
|
+
const durationSec = await probeDurationSec(bytes, { signal });
|
|
55
|
+
return durationSec !== null && durationSec > 0 ? durationSec : null;
|
|
127
56
|
});
|
|
128
57
|
}
|
|
129
58
|
/**
|
|
@@ -140,7 +69,7 @@ export function frameRateFor(durationSec, maxFrames, maxFps) {
|
|
|
140
69
|
return Math.min(maxFps, Math.max(spread, 0.01));
|
|
141
70
|
}
|
|
142
71
|
/**
|
|
143
|
-
* Fit inside a square of `maxDimension` without upscaling.
|
|
72
|
+
* Fit inside a square of `maxDimension` without upscaling. libav's
|
|
144
73
|
* `force_original_aspect_ratio=decrease` would enlarge a smaller frame, which
|
|
145
74
|
* costs tokens and adds no detail.
|
|
146
75
|
*/
|
|
@@ -150,49 +79,52 @@ function scaleFilter(maxDimension) {
|
|
|
150
79
|
}
|
|
151
80
|
/**
|
|
152
81
|
* Decode `bytes` and return up to `maxFrames` JPEG stills spread across the
|
|
153
|
-
* clip.
|
|
82
|
+
* clip.
|
|
154
83
|
*/
|
|
155
84
|
export async function sampleVideoFrames(bytes, options = {}) {
|
|
156
85
|
const limits = frameSamplingLimits();
|
|
157
86
|
const maxFrames = Math.max(1, options.maxFrames ?? limits.maxFrames);
|
|
158
87
|
const maxFps = options.maxFps ?? limits.maxFps;
|
|
159
88
|
const maxDimension = options.maxDimension ?? limits.maxDimension;
|
|
160
|
-
const
|
|
89
|
+
const signal = options.signal ?? new AbortController().signal;
|
|
90
|
+
const { fs, os, path } = await nodeModules();
|
|
91
|
+
const [{ openRgbaFrameReader }, sharp] = await Promise.all([
|
|
92
|
+
loadMediaModule(),
|
|
93
|
+
loadSharpOrThrow()
|
|
94
|
+
]);
|
|
161
95
|
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "nodetool-vframes-"));
|
|
162
96
|
const input = path.join(dir, "input.bin");
|
|
163
|
-
const outDir = path.join(dir, "frames");
|
|
164
97
|
try {
|
|
165
98
|
await fs.writeFile(input, bytes);
|
|
166
|
-
await
|
|
167
|
-
const durationSec = await probeDuration(cp, input, options.signal);
|
|
99
|
+
const durationSec = await probeVideoDurationSeconds(bytes, signal);
|
|
168
100
|
const fps = frameRateFor(durationSec, maxFrames, maxFps);
|
|
169
|
-
await
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
"
|
|
176
|
-
"-i",
|
|
177
|
-
input,
|
|
178
|
-
"-vf",
|
|
179
|
-
`fps=${fps.toFixed(6)},${scaleFilter(maxDimension)}`,
|
|
180
|
-
"-frames:v",
|
|
181
|
-
String(maxFrames),
|
|
182
|
-
"-q:v",
|
|
183
|
-
String(JPEG_QUALITY),
|
|
184
|
-
path.join(outDir, "frame_%04d.jpg")
|
|
185
|
-
], options.signal);
|
|
186
|
-
const names = (await fs.readdir(outDir))
|
|
187
|
-
.filter((n) => n.startsWith("frame_") && n.endsWith(".jpg"))
|
|
188
|
-
.sort();
|
|
101
|
+
const reader = await openRgbaFrameReader({
|
|
102
|
+
filePath: input,
|
|
103
|
+
filter: `fps=${fps.toFixed(6)},${scaleFilter(maxDimension)},format=rgba`,
|
|
104
|
+
signal
|
|
105
|
+
});
|
|
106
|
+
if (!reader)
|
|
107
|
+
throw new Error("The video has no picture to sample");
|
|
189
108
|
const frames = [];
|
|
190
|
-
|
|
191
|
-
frames.
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
109
|
+
try {
|
|
110
|
+
while (frames.length < maxFrames) {
|
|
111
|
+
const frame = await reader.next();
|
|
112
|
+
if (!frame)
|
|
113
|
+
break;
|
|
114
|
+
const jpeg = await sharp(Buffer.from(frame.rgba.buffer, frame.rgba.byteOffset, frame.rgba.byteLength), {
|
|
115
|
+
raw: { width: frame.width, height: frame.height, channels: 4 }
|
|
116
|
+
})
|
|
117
|
+
.jpeg({ quality: JPEG_QUALITY })
|
|
118
|
+
.toBuffer();
|
|
119
|
+
frames.push({
|
|
120
|
+
data: new Uint8Array(jpeg),
|
|
121
|
+
mimeType: "image/jpeg",
|
|
122
|
+
timeSec: frames.length / fps
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
await reader.close();
|
|
196
128
|
}
|
|
197
129
|
return {
|
|
198
130
|
frames,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"video-frames.js","sourceRoot":"","sources":["../../src/providers/video-frames.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"video-frames.js","sourceRoot":"","sources":["../../src/providers/video-frames.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,62 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* The one {@link Workspace} implementation, over any {@link StorageAdapter}.
|
|
3
|
-
*
|
|
4
|
-
* There is deliberately no second implementation for local folders: a local
|
|
5
|
-
* workspace is this class over a `FileStorageAdapter`, which is what keeps the
|
|
6
|
-
* two deployments on the same code path instead of on two that drift.
|
|
7
|
-
*/
|
|
8
|
-
import { type StorageAdapter } from "./context.js";
|
|
9
|
-
import { type Workspace, type WorkspaceEntry, type WorkspaceStat } from "./workspace.js";
|
|
10
|
-
export declare class StorageWorkspace implements Workspace {
|
|
11
|
-
readonly storage: StorageAdapter;
|
|
12
|
-
readonly localDir: string | null;
|
|
13
|
-
private scratch;
|
|
14
|
-
constructor(storage: StorageAdapter, opts?: {
|
|
15
|
-
localDir?: string | null;
|
|
16
|
-
});
|
|
17
|
-
private rootReady;
|
|
18
|
-
/** Create the workspace directory once, on first use. */
|
|
19
|
-
private ensureRoot;
|
|
20
|
-
key(path: string): string;
|
|
21
|
-
/**
|
|
22
|
-
* Refuse a path whose real location leaves the workspace.
|
|
23
|
-
*
|
|
24
|
-
* Called on every operation that touches a local workspace. `key()` already
|
|
25
|
-
* refuses a `..` that climbs out lexically; this is the half a symlink
|
|
26
|
-
* defeats.
|
|
27
|
-
*/
|
|
28
|
-
private assertContained;
|
|
29
|
-
uri(path: string): string;
|
|
30
|
-
read(path: string): Promise<Uint8Array | null>;
|
|
31
|
-
readText(path: string): Promise<string | null>;
|
|
32
|
-
write(path: string, data: Uint8Array | string, contentType?: string): Promise<void>;
|
|
33
|
-
exists(path: string): Promise<boolean>;
|
|
34
|
-
stat(path: string): Promise<WorkspaceStat | null>;
|
|
35
|
-
list(path?: string, opts?: {
|
|
36
|
-
recursive?: boolean;
|
|
37
|
-
}): Promise<WorkspaceEntry[]>;
|
|
38
|
-
private listEntries;
|
|
39
|
-
delete(path: string): Promise<boolean>;
|
|
40
|
-
deleteAll(path: string): Promise<number>;
|
|
41
|
-
mkdir(path: string): Promise<void>;
|
|
42
|
-
copy(from: string, to: string): Promise<void>;
|
|
43
|
-
move(from: string, to: string): Promise<void>;
|
|
44
|
-
materialize(path: string): Promise<string>;
|
|
45
|
-
private stage;
|
|
46
|
-
absorb(localPath: string, path: string): Promise<void>;
|
|
47
|
-
private absorbFile;
|
|
48
|
-
scratchDir(): Promise<string>;
|
|
49
|
-
cleanupScratch(): Promise<void>;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Build a workspace over a storage backend.
|
|
53
|
-
*
|
|
54
|
-
* `prefix` carves a namespace out of a shared bucket — how a cloud deployment
|
|
55
|
-
* gives each user their own workspace inside the one bucket it has.
|
|
56
|
-
*/
|
|
57
|
-
export declare function createWorkspace(storage: StorageAdapter, opts?: {
|
|
58
|
-
prefix?: string | null;
|
|
59
|
-
}): Workspace;
|
|
60
|
-
/** A workspace over a real directory. */
|
|
61
|
-
export declare function createLocalWorkspace(dir: string): Workspace;
|
|
1
|
+
export { StorageWorkspace, createWorkspace, createLocalWorkspace } from "@nodetool-ai/runtime-core";
|
|
62
2
|
//# sourceMappingURL=storage-workspace.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-workspace.d.ts","sourceRoot":"","sources":["../src/storage-workspace.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"storage-workspace.d.ts","sourceRoot":"","sources":["../src/storage-workspace.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC"}
|