@opengeni/runtime 2.4.3 → 2.5.2-canary.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-UA75SUZ7.js → agent-Q2VNH5FV.js} +2 -2
- package/dist/{chunk-ORKCCH5X.js → chunk-25B3EQRW.js} +3 -398
- package/dist/{chunk-ORKCCH5X.js.map → chunk-25B3EQRW.js.map} +1 -1
- package/dist/{chunk-YRKIQK25.js → chunk-CD22I76N.js} +2 -2
- package/dist/{chunk-7K6WOXFS.js → chunk-GB763TSV.js} +17 -1
- package/dist/chunk-GB763TSV.js.map +1 -0
- package/dist/{chunk-BV2DSPZK.js → chunk-GBHOT4KS.js} +267 -181
- package/dist/chunk-GBHOT4KS.js.map +1 -0
- package/dist/{chunk-WATBACLT.js → chunk-LEIGL6X2.js} +2309 -1428
- package/dist/chunk-LEIGL6X2.js.map +1 -0
- package/dist/index.d.ts +12 -5
- package/dist/index.js +15 -5
- package/dist/{localSources-GDQRRHT3.js → localSources-Z5IJIIRV.js} +3 -3
- package/dist/model-input.d.ts +2 -1
- package/dist/runtime-skills.d.ts +28 -5
- package/dist/sandbox/archive-spool.d.ts +14 -0
- package/dist/sandbox/host-archive-spool.d.ts +19 -0
- package/dist/sandbox/index.d.ts +5 -1
- package/dist/sandbox/index.js +7 -3
- package/dist/sandbox/workspace-archive.d.ts +7 -0
- package/dist/skill-files.d.ts +4 -0
- package/dist/skill-library.d.ts +1 -1
- package/dist/skill-library.js +3 -1
- package/dist/workspace-tool-gateway.js +5 -5
- package/package.json +11 -11
- package/src/bundled_management_skills/opengeni-skills/SKILL.md +3 -1
- package/src/index.ts +184 -33
- package/src/lazy-tool-transport.ts +0 -3
- package/src/model-input.ts +1 -1
- package/src/run-events.ts +23 -0
- package/src/runtime-skills.ts +122 -161
- package/src/sandbox/archive-spool.ts +16 -0
- package/src/sandbox/host-archive-spool.ts +1040 -0
- package/src/sandbox/index.ts +292 -203
- package/src/sandbox/routing/routing-session.ts +1 -1
- package/src/sandbox/workspace-archive.ts +54 -1
- package/src/skill-files.ts +20 -0
- package/src/skill-library.ts +1 -0
- package/dist/chunk-7K6WOXFS.js.map +0 -1
- package/dist/chunk-BV2DSPZK.js.map +0 -1
- package/dist/chunk-WATBACLT.js.map +0 -1
- /package/dist/{agent-UA75SUZ7.js.map → agent-Q2VNH5FV.js.map} +0 -0
- /package/dist/{chunk-YRKIQK25.js.map → chunk-CD22I76N.js.map} +0 -0
- /package/dist/{localSources-GDQRRHT3.js.map → localSources-Z5IJIIRV.js.map} +0 -0
package/src/runtime-skills.ts
CHANGED
|
@@ -1,29 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
cpSync,
|
|
3
|
-
existsSync,
|
|
4
|
-
mkdirSync,
|
|
5
|
-
readdirSync,
|
|
6
|
-
readFileSync,
|
|
7
|
-
renameSync,
|
|
8
|
-
rmSync,
|
|
9
|
-
} from "node:fs";
|
|
1
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
10
2
|
import { sitePackageVersions } from "./site-package-versions";
|
|
11
|
-
import { dirname,
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
12
4
|
import { fileURLToPath } from "node:url";
|
|
13
5
|
import { readSkillMetadata } from "@opengeni/contracts";
|
|
14
6
|
|
|
15
|
-
import { localDirLazySkillSource } from "@openai/agents/sandbox/local";
|
|
16
7
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
type SkillIndexEntry,
|
|
24
|
-
} from "@openai/agents/sandbox";
|
|
25
|
-
|
|
26
|
-
import { buildPortableSkillArtifact, readSkillLibraryArtifact } from "./skill-library";
|
|
8
|
+
PORTABLE_SKILL_MAX_FILES,
|
|
9
|
+
buildPortableSkillArtifact,
|
|
10
|
+
readSkillLibraryArtifact,
|
|
11
|
+
} from "./skill-library";
|
|
12
|
+
import { SkillFileError, listSkillPaths, readSkillFiles } from "./skill-files";
|
|
13
|
+
import type { SkillCatalogDescriptor } from "./skill-catalog";
|
|
27
14
|
|
|
28
15
|
export type RuntimeSkillArtifactFile = Readonly<{
|
|
29
16
|
path: string;
|
|
@@ -84,13 +71,28 @@ export type EffectiveSkillSelection = Readonly<{
|
|
|
84
71
|
reason: string;
|
|
85
72
|
}>;
|
|
86
73
|
|
|
74
|
+
export type RuntimeSkillReadable = Readonly<{
|
|
75
|
+
id: string;
|
|
76
|
+
name: string;
|
|
77
|
+
description: string;
|
|
78
|
+
files: readonly RuntimeSkillArtifactFile[];
|
|
79
|
+
}>;
|
|
80
|
+
|
|
87
81
|
export type RuntimeSkillComposition = Readonly<{
|
|
88
|
-
lazySource: LocalDirLazySkillSource;
|
|
89
82
|
selections: readonly EffectiveSkillSelection[];
|
|
90
83
|
/** Exact always-visible catalog descriptors for explicitly activated Skills. */
|
|
91
84
|
configuredDescriptors: readonly RuntimeSkillDescriptor[];
|
|
92
85
|
configuredNames: readonly string[];
|
|
93
86
|
nativeToolNames: readonly string[];
|
|
87
|
+
/** Model-facing catalog descriptors for configured and bundled Skills. */
|
|
88
|
+
index: readonly RuntimeSkillIndexEntry[];
|
|
89
|
+
artifacts: readonly RuntimeSkillReadable[];
|
|
90
|
+
}>;
|
|
91
|
+
|
|
92
|
+
export type RuntimeSkillIndexEntry = Readonly<{
|
|
93
|
+
id: string;
|
|
94
|
+
name: string;
|
|
95
|
+
description: string;
|
|
94
96
|
}>;
|
|
95
97
|
|
|
96
98
|
export type RuntimeSkillDescriptor = Readonly<{
|
|
@@ -101,6 +103,12 @@ export type RuntimeSkillDescriptor = Readonly<{
|
|
|
101
103
|
description: string;
|
|
102
104
|
}>;
|
|
103
105
|
|
|
106
|
+
export type RuntimeSkillReadRequest = Readonly<{
|
|
107
|
+
skill: string;
|
|
108
|
+
paths?: readonly string[];
|
|
109
|
+
listFiles?: boolean;
|
|
110
|
+
}>;
|
|
111
|
+
|
|
104
112
|
type ValidatedRuntimeSkillActivation = Readonly<{
|
|
105
113
|
activation: RuntimeSkillActivation;
|
|
106
114
|
contentSha256: string;
|
|
@@ -144,16 +152,11 @@ export function loadNativeToolSkillArtifacts(
|
|
|
144
152
|
});
|
|
145
153
|
}
|
|
146
154
|
|
|
147
|
-
let stagedBundledArtifactSkillsDir: string | null = null;
|
|
148
|
-
let stagedBundledVideoSkillsDir: string | null = null;
|
|
149
|
-
|
|
150
155
|
/**
|
|
151
156
|
* Compose the exact Skills surface for one agent.
|
|
152
|
-
*
|
|
153
157
|
* Optional/domain Skills enter only through explicit activations. Native
|
|
154
158
|
* Skills are admitted only with the exact executable tool surface they
|
|
155
|
-
* document.
|
|
156
|
-
* provenance so those projections cannot disagree.
|
|
159
|
+
* document. The result is an in-memory catalog and file set, not an SDK loader.
|
|
157
160
|
*/
|
|
158
161
|
export function composeRuntimeSkills(
|
|
159
162
|
activations: readonly RuntimeSkillActivation[],
|
|
@@ -167,39 +170,52 @@ export function composeRuntimeSkills(
|
|
|
167
170
|
activations.map(validateRuntimeSkillActivation),
|
|
168
171
|
nativeNameKeys,
|
|
169
172
|
);
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
for (const source of nativeSources) {
|
|
175
|
-
for (const name of source.names) {
|
|
176
|
-
children[name] = source.entries?.[name] ?? localDir({ src: join(source.directory, name) });
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const activationIndex: SkillIndexEntry[] = [];
|
|
181
|
-
for (const { activation } of effectiveActivations) {
|
|
182
|
-
const { artifact } = activation;
|
|
183
|
-
children[artifact.name] = runtimeSkillDirEntry(artifact);
|
|
184
|
-
activationIndex.push({
|
|
173
|
+
const nativeArtifacts = loadNativeToolSkillArtifacts(nativeTools);
|
|
174
|
+
const nativeReadables: RuntimeSkillReadable[] = nativeArtifacts.map((artifact) =>
|
|
175
|
+
Object.freeze({
|
|
176
|
+
id: `native-tool:${artifact.name}`,
|
|
185
177
|
name: artifact.name,
|
|
186
178
|
description: runtimeSkillDescription(artifact),
|
|
187
|
-
|
|
188
|
-
})
|
|
189
|
-
|
|
179
|
+
files: artifact.files,
|
|
180
|
+
}),
|
|
181
|
+
);
|
|
182
|
+
const configuredDescriptors = Object.freeze(
|
|
183
|
+
effectiveActivations.map(({ activation }) =>
|
|
184
|
+
Object.freeze({
|
|
185
|
+
id: activation.id,
|
|
186
|
+
name: activation.artifact.name,
|
|
187
|
+
source: activation.source,
|
|
188
|
+
reason: activation.reason,
|
|
189
|
+
description: runtimeSkillDescription(activation.artifact),
|
|
190
|
+
}),
|
|
191
|
+
),
|
|
192
|
+
);
|
|
193
|
+
const configuredReadables: RuntimeSkillReadable[] = effectiveActivations.map(({ activation }) =>
|
|
194
|
+
Object.freeze({
|
|
195
|
+
id: activation.id,
|
|
196
|
+
name: activation.artifact.name,
|
|
197
|
+
description: runtimeSkillDescription(activation.artifact),
|
|
198
|
+
files: activation.artifact.files,
|
|
199
|
+
}),
|
|
200
|
+
);
|
|
201
|
+
const index = Object.freeze([
|
|
202
|
+
...nativeReadables.map((artifact) =>
|
|
203
|
+
Object.freeze({
|
|
204
|
+
id: artifact.id,
|
|
205
|
+
name: artifact.name,
|
|
206
|
+
description: artifact.description,
|
|
207
|
+
}),
|
|
208
|
+
),
|
|
209
|
+
...configuredDescriptors.map((descriptor) =>
|
|
210
|
+
Object.freeze({
|
|
211
|
+
id: descriptor.id,
|
|
212
|
+
name: descriptor.name,
|
|
213
|
+
description: descriptor.description,
|
|
214
|
+
}),
|
|
215
|
+
),
|
|
216
|
+
]);
|
|
190
217
|
|
|
191
218
|
return Object.freeze({
|
|
192
|
-
lazySource: {
|
|
193
|
-
source: dir({ children }),
|
|
194
|
-
getIndex: (manifest, skillsPath) => [
|
|
195
|
-
...nativeSources.flatMap((source) =>
|
|
196
|
-
(source.lazySource.getIndex?.(manifest, skillsPath) ?? []).filter(
|
|
197
|
-
(entry) => !activatedNameKeys.has((entry.path ?? entry.name).toLowerCase()),
|
|
198
|
-
),
|
|
199
|
-
),
|
|
200
|
-
...activationIndex,
|
|
201
|
-
],
|
|
202
|
-
},
|
|
203
219
|
selections: Object.freeze([
|
|
204
220
|
...nativeSources.flatMap((source) =>
|
|
205
221
|
source.names.map((name) =>
|
|
@@ -215,24 +231,58 @@ export function composeRuntimeSkills(
|
|
|
215
231
|
),
|
|
216
232
|
...effectiveActivations.map((activation) => selectionForActivation(activation)),
|
|
217
233
|
]),
|
|
218
|
-
configuredDescriptors
|
|
219
|
-
effectiveActivations.map(({ activation }) =>
|
|
220
|
-
Object.freeze({
|
|
221
|
-
id: activation.id,
|
|
222
|
-
name: activation.artifact.name,
|
|
223
|
-
source: activation.source,
|
|
224
|
-
reason: activation.reason,
|
|
225
|
-
description: runtimeSkillDescription(activation.artifact),
|
|
226
|
-
}),
|
|
227
|
-
),
|
|
228
|
-
),
|
|
234
|
+
configuredDescriptors,
|
|
229
235
|
configuredNames: Object.freeze(
|
|
230
236
|
effectiveActivations.map(({ activation }) => activation.artifact.name),
|
|
231
237
|
),
|
|
232
238
|
nativeToolNames: Object.freeze([...nativeSources.flatMap((source) => source.names)]),
|
|
239
|
+
index,
|
|
240
|
+
artifacts: Object.freeze([...nativeReadables, ...configuredReadables]),
|
|
233
241
|
});
|
|
234
242
|
}
|
|
235
243
|
|
|
244
|
+
export function skillCatalogFromComposition(
|
|
245
|
+
composition: RuntimeSkillComposition,
|
|
246
|
+
): readonly SkillCatalogDescriptor[] {
|
|
247
|
+
return composition.index;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export function readRuntimeSkill(
|
|
251
|
+
composition: RuntimeSkillComposition,
|
|
252
|
+
request: RuntimeSkillReadRequest,
|
|
253
|
+
): { skillId: string; files?: ReturnType<typeof readSkillFiles>["files"]; paths?: string[] } {
|
|
254
|
+
const skill = request.skill.trim();
|
|
255
|
+
if (!skill)
|
|
256
|
+
throw new SkillFileError("invalid_request", "skill_read requires a Skill identifier.");
|
|
257
|
+
if (request.listFiles === true && request.paths !== undefined) {
|
|
258
|
+
throw new SkillFileError(
|
|
259
|
+
"invalid_request",
|
|
260
|
+
"skill_read listFiles:true cannot be combined with paths.",
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
const exact = composition.artifacts.find((artifact) => artifact.id === skill);
|
|
264
|
+
const matches = exact
|
|
265
|
+
? [exact]
|
|
266
|
+
: composition.artifacts.filter((artifact) => artifact.name === skill);
|
|
267
|
+
if (matches.length === 0) {
|
|
268
|
+
throw new SkillFileError("missing_file", `Skill not found: ${skill}`);
|
|
269
|
+
}
|
|
270
|
+
if (matches.length > 1) {
|
|
271
|
+
throw new SkillFileError(
|
|
272
|
+
"invalid_request",
|
|
273
|
+
`Skill name is ambiguous: ${skill}. Use the catalog id.`,
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
const artifact = matches[0]!;
|
|
277
|
+
if (request.listFiles === true) {
|
|
278
|
+
return { skillId: artifact.id, ...listSkillPaths(artifact.files, PORTABLE_SKILL_MAX_FILES) };
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
skillId: artifact.id,
|
|
282
|
+
files: readSkillFiles(artifact.files, request.paths).files,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
236
286
|
function resolveEffectiveActivations(
|
|
237
287
|
activations: readonly ValidatedRuntimeSkillActivation[],
|
|
238
288
|
nativeNameKeys: ReadonlySet<string>,
|
|
@@ -331,47 +381,25 @@ function selectionForActivation({
|
|
|
331
381
|
}
|
|
332
382
|
|
|
333
383
|
function nativeToolSkillSources(nativeTools: NativeToolSkillSet): Array<{
|
|
334
|
-
directory: string;
|
|
335
|
-
entries?: Record<string, Entry>;
|
|
336
|
-
lazySource: LocalDirLazySkillSource;
|
|
337
384
|
names: string[];
|
|
338
385
|
reason: string;
|
|
339
386
|
}> {
|
|
340
|
-
const sources: Array<{
|
|
341
|
-
directory: string;
|
|
342
|
-
entries?: Record<string, Entry>;
|
|
343
|
-
lazySource: LocalDirLazySkillSource;
|
|
344
|
-
names: string[];
|
|
345
|
-
reason: string;
|
|
346
|
-
}> = [];
|
|
387
|
+
const sources: Array<{ names: string[]; reason: string }> = [];
|
|
347
388
|
if (nativeTools.editableArtifacts) {
|
|
348
|
-
const directory = bundledArtifactSkillsDir();
|
|
349
389
|
sources.push({
|
|
350
|
-
|
|
351
|
-
lazySource: localDirLazySkillSource({ src: directory }),
|
|
352
|
-
names: skillDirNames(directory),
|
|
390
|
+
names: skillDirNames(packagedSkillDirectory("bundled_artifact_skills")),
|
|
353
391
|
reason: "native editable-artifact tool surface",
|
|
354
392
|
});
|
|
355
393
|
}
|
|
356
394
|
if (nativeTools.sites) {
|
|
357
|
-
const directory = packagedSkillDirectory("bundled_site_skills");
|
|
358
|
-
const site = bundledSkillEntry(join(directory, "opengeni-sites"), {
|
|
359
|
-
"package-versions.json": file({ content: JSON.stringify(sitePackageVersions(), null, 2) }),
|
|
360
|
-
});
|
|
361
395
|
sources.push({
|
|
362
|
-
|
|
363
|
-
entries: { "opengeni-sites": site },
|
|
364
|
-
lazySource: localDirLazySkillSource({ src: directory, baseDir: directory }),
|
|
365
|
-
names: skillDirNames(directory),
|
|
396
|
+
names: skillDirNames(packagedSkillDirectory("bundled_site_skills")),
|
|
366
397
|
reason: "bundled Site authoring skill",
|
|
367
398
|
});
|
|
368
399
|
}
|
|
369
400
|
if (nativeTools.videoGeneration) {
|
|
370
|
-
const directory = bundledVideoSkillsDir();
|
|
371
401
|
sources.push({
|
|
372
|
-
|
|
373
|
-
lazySource: localDirLazySkillSource({ src: directory }),
|
|
374
|
-
names: skillDirNames(directory),
|
|
402
|
+
names: skillDirNames(packagedSkillDirectory("bundled_video_skills")),
|
|
375
403
|
reason: "native video-generation tool surface",
|
|
376
404
|
});
|
|
377
405
|
}
|
|
@@ -389,62 +417,6 @@ function packagedSkillDirectory(directoryName: string): string {
|
|
|
389
417
|
);
|
|
390
418
|
}
|
|
391
419
|
|
|
392
|
-
function bundledArtifactSkillsDir(): string {
|
|
393
|
-
const packaged = packagedSkillDirectory("bundled_artifact_skills");
|
|
394
|
-
if (isPathWithin(process.cwd(), packaged)) return packaged;
|
|
395
|
-
if (!stagedBundledArtifactSkillsDir) {
|
|
396
|
-
stagedBundledArtifactSkillsDir = stageSkillDirectory(
|
|
397
|
-
packaged,
|
|
398
|
-
join(process.cwd(), ".opengeni", "bundled_artifact_skills"),
|
|
399
|
-
);
|
|
400
|
-
}
|
|
401
|
-
return stagedBundledArtifactSkillsDir;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
/** Compose generated metadata in the manifest, never in the installed application. */
|
|
405
|
-
function bundledSkillEntry(directory: string, overrides: Record<string, Entry> = {}): Dir {
|
|
406
|
-
const children: Record<string, Entry> = {};
|
|
407
|
-
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
408
|
-
const path = join(directory, entry.name);
|
|
409
|
-
children[entry.name] = entry.isDirectory()
|
|
410
|
-
? bundledSkillEntry(path)
|
|
411
|
-
: file({ content: readFileSync(path, "utf8") });
|
|
412
|
-
}
|
|
413
|
-
return dir({ children: { ...children, ...overrides } });
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
function bundledVideoSkillsDir(): string {
|
|
417
|
-
const packaged = packagedSkillDirectory("bundled_video_skills");
|
|
418
|
-
if (isPathWithin(process.cwd(), packaged)) return packaged;
|
|
419
|
-
if (!stagedBundledVideoSkillsDir) {
|
|
420
|
-
stagedBundledVideoSkillsDir = stageSkillDirectory(
|
|
421
|
-
packaged,
|
|
422
|
-
join(process.cwd(), ".opengeni", "bundled_video_skills"),
|
|
423
|
-
);
|
|
424
|
-
}
|
|
425
|
-
return stagedBundledVideoSkillsDir;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
function stageSkillDirectory(packaged: string, target: string): string {
|
|
429
|
-
const temporary = `${target}.tmp-${process.pid}`;
|
|
430
|
-
rmSync(temporary, { recursive: true, force: true });
|
|
431
|
-
mkdirSync(dirname(temporary), { recursive: true });
|
|
432
|
-
cpSync(packaged, temporary, { recursive: true });
|
|
433
|
-
rmSync(target, { recursive: true, force: true });
|
|
434
|
-
try {
|
|
435
|
-
renameSync(temporary, target);
|
|
436
|
-
} catch (error) {
|
|
437
|
-
rmSync(temporary, { recursive: true, force: true });
|
|
438
|
-
if (!existsSync(target)) throw error;
|
|
439
|
-
}
|
|
440
|
-
return target;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
function isPathWithin(root: string, candidate: string): boolean {
|
|
444
|
-
const relativePath = relative(root, candidate);
|
|
445
|
-
return relativePath === "" || (!relativePath.startsWith("..") && !isAbsolute(relativePath));
|
|
446
|
-
}
|
|
447
|
-
|
|
448
420
|
function skillDirNames(root: string): string[] {
|
|
449
421
|
return readdirSync(root, { withFileTypes: true })
|
|
450
422
|
.filter((entry) => entry.isDirectory() && existsSync(join(root, entry.name, "SKILL.md")))
|
|
@@ -457,10 +429,6 @@ type RuntimeSkillDirNode = {
|
|
|
457
429
|
files: Map<string, string>;
|
|
458
430
|
};
|
|
459
431
|
|
|
460
|
-
function runtimeSkillDirEntry(skill: RuntimeSkillArtifact): Dir {
|
|
461
|
-
return runtimeSkillDirFromNode(runtimeSkillDirNode(skill));
|
|
462
|
-
}
|
|
463
|
-
|
|
464
432
|
function runtimeSkillDirNode(skill: RuntimeSkillArtifact): RuntimeSkillDirNode {
|
|
465
433
|
const root: RuntimeSkillDirNode = { dirs: new Map(), files: new Map() };
|
|
466
434
|
for (const skillFile of skill.files) {
|
|
@@ -489,13 +457,6 @@ function runtimeSkillDirNode(skill: RuntimeSkillArtifact): RuntimeSkillDirNode {
|
|
|
489
457
|
return root;
|
|
490
458
|
}
|
|
491
459
|
|
|
492
|
-
function runtimeSkillDirFromNode(node: RuntimeSkillDirNode): Dir {
|
|
493
|
-
const children: Record<string, Entry> = {};
|
|
494
|
-
for (const [name, child] of node.dirs) children[name] = runtimeSkillDirFromNode(child);
|
|
495
|
-
for (const [name, content] of node.files) children[name] = file({ content });
|
|
496
|
-
return dir({ children });
|
|
497
|
-
}
|
|
498
|
-
|
|
499
460
|
function assertSafeRuntimeSkillName(name: string): void {
|
|
500
461
|
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u.test(name)) {
|
|
501
462
|
throw new Error(`Invalid Skill name: ${name}`);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { TarWorkspaceArchiveDescriptor } from "@opengeni/contracts";
|
|
2
|
+
|
|
3
|
+
/** Process-owned, reopenable archive bytes. Never persisted as a local path. */
|
|
4
|
+
export type WorkspaceArchiveSpool = {
|
|
5
|
+
path: string;
|
|
6
|
+
byteSize: number;
|
|
7
|
+
sha256: string;
|
|
8
|
+
open: () => AsyncIterable<Uint8Array>;
|
|
9
|
+
dispose: () => Promise<void>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type VerifiedHostWorkspaceArchive = {
|
|
13
|
+
kind: "host_spool";
|
|
14
|
+
spool: WorkspaceArchiveSpool;
|
|
15
|
+
descriptor: TarWorkspaceArchiveDescriptor;
|
|
16
|
+
};
|