@opengeni/runtime 0.7.1 → 0.13.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.
Files changed (61) hide show
  1. package/THIRD_PARTY_NOTICES +32 -0
  2. package/dist/agent-UMUIWWD2.js +8 -0
  3. package/dist/agent-UMUIWWD2.js.map +1 -0
  4. package/dist/chunk-4YJ5Z52Z.js +1789 -0
  5. package/dist/chunk-4YJ5Z52Z.js.map +1 -0
  6. package/dist/chunk-65UDUFUO.js +22133 -0
  7. package/dist/chunk-65UDUFUO.js.map +1 -0
  8. package/dist/chunk-DPULLAJG.js +215 -0
  9. package/dist/chunk-DPULLAJG.js.map +1 -0
  10. package/dist/chunk-HAN5D27J.js +292 -0
  11. package/dist/chunk-HAN5D27J.js.map +1 -0
  12. package/dist/chunk-K4V4QYCL.js +37683 -0
  13. package/dist/chunk-K4V4QYCL.js.map +1 -0
  14. package/dist/chunk-PZ5AY32C.js +10 -0
  15. package/dist/chunk-PZ5AY32C.js.map +1 -0
  16. package/dist/{index-DIiiwQY2.d.ts → index-DGUrY_yR.d.ts} +171 -18
  17. package/dist/index.d.ts +404 -125
  18. package/dist/index.js +8857 -412
  19. package/dist/index.js.map +1 -1
  20. package/dist/localSources-T3HZ6KY4.js +15 -0
  21. package/dist/localSources-T3HZ6KY4.js.map +1 -0
  22. package/dist/mcp-network.d.ts +78 -0
  23. package/dist/mcp-network.js +62 -0
  24. package/dist/mcp-network.js.map +1 -0
  25. package/dist/sandbox/index.d.ts +1 -1
  26. package/dist/sandbox/index.js +42 -5
  27. package/dist/skill-library.d.ts +74 -0
  28. package/dist/skill-library.js +18 -0
  29. package/dist/skill-library.js.map +1 -0
  30. package/package.json +18 -5
  31. package/src/bundled_hashicorp_terraform_skills/README.md +3 -3
  32. package/src/bundled_hashicorp_terraform_skills/checkov/SKILL.md +1 -1
  33. package/src/codex-tool-search.ts +20 -1
  34. package/src/context-compaction.ts +421 -24
  35. package/src/history-sanitizer.ts +14 -5
  36. package/src/index.ts +1806 -347
  37. package/src/mcp-network.ts +330 -0
  38. package/src/sandbox/channel-a.ts +526 -113
  39. package/src/sandbox/display-stack.ts +860 -23
  40. package/src/sandbox/exec-banner.ts +67 -0
  41. package/src/sandbox/index.ts +43 -2
  42. package/src/sandbox/providers/modal.ts +29 -2
  43. package/src/sandbox/routing/routing-session.ts +10 -2
  44. package/src/sandbox/run-credentials.ts +818 -0
  45. package/src/sandbox/select.ts +3 -3
  46. package/src/sandbox/selfhosted/capabilities.ts +1 -1
  47. package/src/sandbox/selfhosted/op-stream.ts +40 -0
  48. package/src/sandbox/selfhosted/op-testing.ts +50 -3
  49. package/src/sandbox/selfhosted/session.ts +17 -4
  50. package/src/sandbox/selfhosted/testing.ts +1 -1
  51. package/src/sandbox/stream-port.ts +1 -1
  52. package/src/sandbox/stream-token.ts +1 -1
  53. package/src/sandbox/terminal-server.ts +6 -2
  54. package/src/sandbox/toolspace-token.ts +147 -0
  55. package/src/sandbox/turn-tool-cancellation.ts +940 -0
  56. package/src/sandbox-computer.ts +3 -1
  57. package/src/skill-library.ts +323 -0
  58. package/src/usage-telemetry.ts +495 -51
  59. package/dist/chunk-RYDCVTMW.js +0 -5531
  60. package/dist/chunk-RYDCVTMW.js.map +0 -1
  61. /package/src/{bundled_hashicorp_terraform_skills → bundled_skill_library}/azure-verified-modules/SKILL.md +0 -0
@@ -1279,7 +1279,9 @@ export class ComputerUseCapability extends Capability {
1279
1279
  // any computer-use-only recording. One SandboxComputer instance caches
1280
1280
  // this for the rest of the turn.
1281
1281
  prepare: async (preparedSession) => {
1282
- await ensureDisplayStack(preparedSession);
1282
+ await ensureDisplayStack(preparedSession, {
1283
+ telemetryContext: { callerKind: "computer" },
1284
+ });
1283
1285
  await this.args.onReady?.(preparedSession);
1284
1286
  },
1285
1287
  });
@@ -0,0 +1,323 @@
1
+ import { createHash } from "node:crypto";
2
+ import { lstatSync, readFileSync, readdirSync } from "node:fs";
3
+ import { dirname, isAbsolute, join, relative } from "node:path";
4
+ import { TextDecoder } from "node:util";
5
+ import { fileURLToPath } from "node:url";
6
+
7
+ /**
8
+ * Metadata for a platform-curated skill. The metadata is deliberately
9
+ * provider-neutral: it describes guidance provenance and compatibility, not
10
+ * credentials, tools, permissions, or a model route.
11
+ *
12
+ * Entries are immutable in the runtime. A new artifact gets a new version and
13
+ * content hash; callers must not mutate the returned records.
14
+ */
15
+ export type SkillLibraryEntry = Readonly<{
16
+ id: string;
17
+ name: string;
18
+ version: string;
19
+ description: string;
20
+ category: string;
21
+ tags: readonly string[];
22
+ /** SHA-256 over the complete canonical artifact manifest, not just SKILL.md. */
23
+ contentSha256: string;
24
+ sourceCommit: string;
25
+ sourceUrl: string;
26
+ provenance: string;
27
+ license: string;
28
+ documentationUrl: string;
29
+ compatibility: Readonly<{
30
+ runtime: string;
31
+ minimumSkillCapabilityVersion: string;
32
+ }>;
33
+ upgrade: Readonly<{
34
+ policy: "immutable-replacement";
35
+ supersedes: string | null;
36
+ }>;
37
+ relativePath: string;
38
+ }>;
39
+
40
+ export type SkillLibraryFile = Readonly<{
41
+ path: string;
42
+ content: string;
43
+ }>;
44
+
45
+ export type SkillLibraryArtifact = Readonly<{
46
+ files: readonly SkillLibraryFile[];
47
+ /** SHA-256 over the complete canonical artifact manifest, not just SKILL.md. */
48
+ contentSha256: string;
49
+ }>;
50
+
51
+ export type SkillLibrarySkill = Readonly<{
52
+ name: string;
53
+ description: string;
54
+ files: readonly SkillLibraryFile[];
55
+ }>;
56
+
57
+ const skillLibraryEntries: readonly SkillLibraryEntry[] = Object.freeze([
58
+ Object.freeze({
59
+ id: "azure-verified-modules",
60
+ name: "azure-verified-modules",
61
+ version: "1.0.0",
62
+ description:
63
+ "Azure Verified Modules (AVM) requirements and best practices for certified Terraform modules.",
64
+ category: "infrastructure",
65
+ tags: Object.freeze(["skill", "infrastructure", "terraform", "azure", "opt-in"]),
66
+ contentSha256: "bbc029412fd4893c35cf2a4df6e052efa5583d57d3c26e35d62869dcf4625699",
67
+ sourceCommit: "de4323afdfbc30d1387f287b55062fa8d82b62e8",
68
+ sourceUrl:
69
+ "https://github.com/hashicorp/agent-skills/tree/de4323afdfbc30d1387f287b55062fa8d82b62e8/terraform/code-generation/skills/azure-verified-modules",
70
+ provenance: "Vendored from hashicorp/agent-skills; reviewed OpenGeni curated entry.",
71
+ license: "MPL-2.0",
72
+ documentationUrl: "https://azure.github.io/Azure-Verified-Modules/",
73
+ compatibility: Object.freeze({
74
+ runtime: "openai-agents-skills",
75
+ minimumSkillCapabilityVersion: "0.13.3",
76
+ }),
77
+ upgrade: Object.freeze({
78
+ policy: "immutable-replacement",
79
+ supersedes: null,
80
+ }),
81
+ relativePath: "azure-verified-modules",
82
+ }),
83
+ ]);
84
+
85
+ const skillLibraryRootCandidates = (): string[] => {
86
+ const moduleDir = dirname(fileURLToPath(import.meta.url));
87
+ return [
88
+ join(moduleDir, "bundled_skill_library"),
89
+ join(moduleDir, "..", "src", "bundled_skill_library"),
90
+ ];
91
+ };
92
+
93
+ function skillLibraryRoot(): string | null {
94
+ return skillLibraryRootCandidates().find((candidate) => isRealDirectory(candidate)) ?? null;
95
+ }
96
+
97
+ function entryDirectory(entry: SkillLibraryEntry): string | null {
98
+ const root = skillLibraryRoot();
99
+ if (!root) return null;
100
+ const directory = join(root, entry.relativePath);
101
+ const withinRoot = relative(root, directory);
102
+ if (
103
+ isAbsolute(withinRoot) ||
104
+ withinRoot === ".." ||
105
+ withinRoot.startsWith("../") ||
106
+ !isRealDirectory(directory)
107
+ ) {
108
+ return null;
109
+ }
110
+ return directory;
111
+ }
112
+
113
+ /** Return only entries whose reviewed artifact is present in this deployment. */
114
+ export function listSkillLibraryEntries(): readonly SkillLibraryEntry[] {
115
+ return skillLibraryEntries.filter((entry) => reviewedArtifactIsAvailable(entry));
116
+ }
117
+
118
+ /** Return whether an id belongs to the immutable library, even if its artifact is unavailable. */
119
+ export function isSkillLibraryEntryId(id: string): boolean {
120
+ return skillLibraryEntries.some((entry) => entry.id === id);
121
+ }
122
+
123
+ /** Resolve an exact immutable library entry by id and version. */
124
+ export function getSkillLibraryEntry(id: string, version?: string): SkillLibraryEntry | null {
125
+ const entry = skillLibraryEntries.find(
126
+ (candidate) => candidate.id === id && (version === undefined || candidate.version === version),
127
+ );
128
+ return entry && reviewedArtifactIsAvailable(entry) ? entry : null;
129
+ }
130
+
131
+ /**
132
+ * Load a selected curated entry into the SDK's in-memory skill shape.
133
+ * Selection is guidance-only: this function has no access to settings,
134
+ * credentials, MCP declarations, or model-provider configuration.
135
+ */
136
+ export function loadSkillLibrarySkill(
137
+ id: string,
138
+ version?: string,
139
+ ): { entry: SkillLibraryEntry; skill: SkillLibrarySkill } {
140
+ const entry = getSkillLibraryEntry(id, version);
141
+ if (!entry) {
142
+ throw new Error(
143
+ version
144
+ ? `Skill library entry is unavailable: ${id}@${version}`
145
+ : `Skill library entry is unavailable: ${id}`,
146
+ );
147
+ }
148
+ const directory = entryDirectory(entry);
149
+ if (!directory) {
150
+ throw new Error(`Skill library entry is unavailable: ${entry.id}@${entry.version}`);
151
+ }
152
+ const artifact = verifySkillLibraryArtifact(directory, entry.contentSha256, entry);
153
+ const files = artifact.files;
154
+ const skillMarkdown = files.find((file) => file.path === "SKILL.md")?.content;
155
+ if (skillMarkdown === undefined) {
156
+ throw new Error(`Skill library entry is missing SKILL.md: ${entry.id}@${entry.version}`);
157
+ }
158
+ return {
159
+ entry,
160
+ skill: Object.freeze({
161
+ name: entry.name,
162
+ description: entry.description,
163
+ files: Object.freeze(files.map((file) => Object.freeze(file))),
164
+ }),
165
+ };
166
+ }
167
+
168
+ /**
169
+ * Read a curated artifact and calculate its canonical whole-artifact digest.
170
+ *
171
+ * The manifest is JSON encoded as sorted `[normalizedRelativePath, base64Bytes]`
172
+ * tuples. Base64 preserves every byte, including bytes that would not survive
173
+ * a lossy UTF-8 string round-trip. Files are decoded only after the digest
174
+ * input has been captured because the SDK skill surface is text-based.
175
+ */
176
+ export function readSkillLibraryArtifact(root: string): SkillLibraryArtifact {
177
+ const files = materializeSkillLibraryFiles(root);
178
+ const contentSha256 = skillLibraryArtifactSha256(files);
179
+ return Object.freeze({
180
+ files: Object.freeze(
181
+ files.map((file) =>
182
+ Object.freeze({
183
+ path: file.path,
184
+ content: decodeSkillLibraryFile(file.bytes, file.path),
185
+ }),
186
+ ),
187
+ ),
188
+ contentSha256,
189
+ });
190
+ }
191
+
192
+ /** Verify a reviewed artifact against its immutable catalog digest. */
193
+ export function verifySkillLibraryArtifact(
194
+ root: string,
195
+ expectedSha256: string,
196
+ entry?: Pick<SkillLibraryEntry, "id" | "version">,
197
+ ): SkillLibraryArtifact {
198
+ const artifact = readSkillLibraryArtifact(root);
199
+ if (artifact.files.every((file) => file.path !== "SKILL.md")) {
200
+ throw new Error(
201
+ entry
202
+ ? `Skill library entry is missing SKILL.md: ${entry.id}@${entry.version}`
203
+ : "Skill library artifact is missing SKILL.md",
204
+ );
205
+ }
206
+ if (artifact.contentSha256 !== expectedSha256) {
207
+ const label = entry ? ` for ${entry.id}@${entry.version}` : "";
208
+ throw new Error(
209
+ `Skill library artifact hash mismatch${label}: expected ${expectedSha256}, got ${artifact.contentSha256}`,
210
+ );
211
+ }
212
+ return artifact;
213
+ }
214
+
215
+ type MaterializedSkillLibraryFile = Readonly<{
216
+ path: string;
217
+ bytes: Uint8Array;
218
+ }>;
219
+
220
+ const utf8Decoder = new TextDecoder("utf-8", { fatal: true });
221
+
222
+ function materializeSkillLibraryFiles(root: string, current = ""): MaterializedSkillLibraryFile[] {
223
+ const directory = current ? join(root, current) : root;
224
+ if (!isRealDirectory(directory)) {
225
+ throw new Error(`Skill library artifact root is not a real directory: ${directory}`);
226
+ }
227
+ return readdirSync(directory, { withFileTypes: true })
228
+ .sort((a, b) => compareCanonicalPath(a.name, b.name))
229
+ .flatMap((child) => {
230
+ const childName = normalizeSkillLibraryRelativePath(child.name, true);
231
+ const path = current ? `${current}/${childName}` : childName;
232
+ normalizeSkillLibraryRelativePath(path);
233
+ const childPath = join(root, path);
234
+ if (child.isSymbolicLink()) {
235
+ throw new Error(`Skill library artifact contains a symbolic link: ${path}`);
236
+ }
237
+ if (child.isDirectory()) {
238
+ return materializeSkillLibraryFiles(root, path);
239
+ }
240
+ if (!child.isFile() || !isRealFile(childPath)) {
241
+ throw new Error(`Skill library artifact contains a non-regular file: ${path}`);
242
+ }
243
+ return [{ path, bytes: Uint8Array.from(readFileSync(childPath)) }];
244
+ });
245
+ }
246
+
247
+ function reviewedArtifactIsAvailable(entry: SkillLibraryEntry): boolean {
248
+ const directory = entryDirectory(entry);
249
+ if (!directory) return false;
250
+ try {
251
+ verifySkillLibraryArtifact(directory, entry.contentSha256, entry);
252
+ return true;
253
+ } catch {
254
+ return false;
255
+ }
256
+ }
257
+
258
+ function skillLibraryArtifactSha256(files: readonly MaterializedSkillLibraryFile[]): string {
259
+ const manifest = files
260
+ .map((file) => {
261
+ const path = normalizeSkillLibraryRelativePath(file.path);
262
+ return [path, Buffer.from(file.bytes).toString("base64")] as const;
263
+ })
264
+ .sort((left, right) => compareCanonicalPath(left[0], right[0]));
265
+ const paths = new Set<string>();
266
+ for (const [path] of manifest) {
267
+ if (paths.has(path)) {
268
+ throw new Error(`Skill library artifact contains duplicate file path: ${path}`);
269
+ }
270
+ paths.add(path);
271
+ }
272
+ return createHash("sha256").update(JSON.stringify(manifest), "utf8").digest("hex");
273
+ }
274
+
275
+ function decodeSkillLibraryFile(bytes: Uint8Array, path: string): string {
276
+ try {
277
+ return utf8Decoder.decode(bytes);
278
+ } catch {
279
+ throw new Error(`Skill library artifact contains invalid UTF-8: ${path}`);
280
+ }
281
+ }
282
+
283
+ function normalizeSkillLibraryRelativePath(path: string, segment = false): string {
284
+ if (
285
+ path.length === 0 ||
286
+ path.includes("\\") ||
287
+ path.includes("\0") ||
288
+ path.startsWith("/") ||
289
+ /^[A-Za-z]:(?:\/|$)/u.test(path)
290
+ ) {
291
+ throw new Error(`Skill library artifact contains an unsafe path: ${path}`);
292
+ }
293
+ const parts = path.split("/");
294
+ if (parts.some((part) => part.length === 0 || part === "." || part === "..")) {
295
+ throw new Error(`Skill library artifact contains an unsafe path: ${path}`);
296
+ }
297
+ if (segment && parts.length !== 1) {
298
+ throw new Error(`Skill library artifact contains an unsafe path: ${path}`);
299
+ }
300
+ return parts.join("/");
301
+ }
302
+
303
+ function compareCanonicalPath(left: string, right: string): number {
304
+ return left < right ? -1 : left > right ? 1 : 0;
305
+ }
306
+
307
+ function isRealDirectory(path: string): boolean {
308
+ try {
309
+ const stats = lstatSync(path);
310
+ return stats.isDirectory() && !stats.isSymbolicLink();
311
+ } catch {
312
+ return false;
313
+ }
314
+ }
315
+
316
+ function isRealFile(path: string): boolean {
317
+ try {
318
+ const stats = lstatSync(path);
319
+ return stats.isFile() && !stats.isSymbolicLink();
320
+ } catch {
321
+ return false;
322
+ }
323
+ }