@mondaydotcomorg/atp-server 0.20.7 → 0.21.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/index.cjs CHANGED
@@ -10385,371 +10385,635 @@ var ExecutionStateManager = class {
10385
10385
  };
10386
10386
  }
10387
10387
  };
10388
-
10389
- // src/explorer/index.ts
10390
- var ExplorerService = class {
10388
+ var APIAggregator = class {
10391
10389
  static {
10392
- __name(this, "ExplorerService");
10390
+ __name(this, "APIAggregator");
10393
10391
  }
10394
- root;
10395
10392
  apiGroups;
10396
- apiGroupMap;
10393
+ /**
10394
+ * Creates a new APIAggregator instance.
10395
+ * @param apiGroups - Array of API group configurations
10396
+ */
10397
10397
  constructor(apiGroups) {
10398
10398
  this.apiGroups = apiGroups;
10399
- this.apiGroupMap = new Map(apiGroups.map((group) => [
10400
- group.name,
10401
- group
10402
- ]));
10403
- this.root = {
10404
- type: "directory",
10405
- name: "/",
10406
- children: /* @__PURE__ */ new Map()
10407
- };
10408
- this.buildTree(apiGroups);
10409
10399
  }
10410
10400
  /**
10411
- * Get filtering context based on current request's tool rules.
10412
- * Returns sets for allowed items and all known items (for filtering).
10401
+ * Generates TypeScript type definitions for selected API groups.
10402
+ * @param selectedGroups - Optional array of group names to include
10403
+ * @returns TypeScript definition string
10413
10404
  */
10414
- getFilterContext() {
10415
- const allowedGroups = filterApiGroups(this.apiGroups);
10416
- const context = {
10417
- allowedTypes: /* @__PURE__ */ new Set(),
10418
- allowedGroups: /* @__PURE__ */ new Set(),
10419
- allowedTools: /* @__PURE__ */ new Set(),
10420
- allGroups: new Set(this.apiGroups.map((g) => g.name))
10421
- };
10422
- for (const group of allowedGroups) {
10423
- if (group.type !== "graphql") {
10424
- context.allowedTypes.add(group.type);
10425
- }
10426
- context.allowedGroups.add(group.name);
10427
- }
10428
- for (const group of this.apiGroups) {
10429
- if (!context.allowedGroups.has(group.name)) continue;
10405
+ async generateTypeScript(selectedGroups) {
10406
+ const groups = selectedGroups ? this.apiGroups.filter((g) => selectedGroups.includes(g.name)) : this.apiGroups;
10407
+ let typescript = `// Agent Tool Protocol Runtime SDK v1.0.0
10408
+
10409
+ `;
10410
+ typescript += this.generateRuntimeTypes();
10411
+ for (const group of groups) {
10412
+ typescript += `
10413
+ // API Group: ${group.name}
10414
+ `;
10430
10415
  if (group.functions) {
10431
10416
  for (const func of group.functions) {
10432
- context.allowedTools.add(`${group.name}:${func.name}`);
10417
+ typescript += this.generateFunctionTypes(func, group.name);
10433
10418
  }
10434
10419
  }
10435
10420
  }
10436
- return context;
10421
+ typescript += this.generateAPINamespace(groups);
10422
+ return typescript;
10437
10423
  }
10438
10424
  /**
10439
- * Check if a directory should be visible based on filter context.
10425
+ * Generates TypeScript definitions for the runtime SDK.
10426
+ * @param options - Optional filtering options
10427
+ * @returns TypeScript definition string
10440
10428
  */
10441
- isDirectoryAllowed(name, currentPath, ctx) {
10442
- const API_TYPES = [
10443
- "openapi",
10444
- "mcp",
10445
- "custom",
10446
- "graphql"
10447
- ];
10448
- if (currentPath === "/" && API_TYPES.includes(name)) {
10449
- return ctx.allowedTypes.has(name) || ctx.allowedGroups.has(name);
10450
- }
10451
- if (ctx.allGroups.has(name)) {
10452
- return ctx.allowedGroups.has(name);
10453
- }
10454
- return true;
10429
+ generateRuntimeTypes(options) {
10430
+ return atpRuntime.generateRuntimeTypes(atpRuntime.GENERATED_METADATA, options);
10455
10431
  }
10456
10432
  /**
10457
- * Builds the virtual filesystem tree from API groups
10433
+ * Generates TypeScript types for a single function.
10434
+ * @param func - Function definition
10435
+ * @param groupName - API group name
10436
+ * @returns TypeScript definition string
10458
10437
  */
10459
- buildTree(apiGroups) {
10460
- for (const group of apiGroups) {
10461
- if (!group.functions || group.functions.length === 0) continue;
10462
- let groupFolder;
10463
- if (group.type === "graphql") {
10464
- groupFolder = this.ensureDirectory(this.root, group.name, group.description);
10465
- } else {
10466
- groupFolder = this.ensureDirectory(this.ensureDirectory(this.root, group.type), group.name, group.description);
10467
- }
10468
- groupFolder.apiGroupName = group.name;
10469
- for (const func of group.functions) {
10470
- const segments = this.extractSegments(func, group);
10471
- if (segments.length > 1) {
10472
- let current = groupFolder;
10473
- for (let i = 0; i < segments.length - 1; i++) {
10474
- current = this.ensureDirectory(current, segments[i]);
10475
- }
10476
- this.addFunction(current, segments[segments.length - 1], func, group.name);
10477
- } else {
10478
- this.addFunction(groupFolder, func.name, func, group.name);
10479
- }
10438
+ generateFunctionTypes(func, groupName) {
10439
+ const inputTypeName = `${func.name}_Input`;
10440
+ const outputTypeName = `${func.name}_Output`;
10441
+ let typescript = `
10442
+ interface ${inputTypeName} {
10443
+ `;
10444
+ if (func.inputSchema?.properties) {
10445
+ const required = func.inputSchema.required || [];
10446
+ for (const [key, value] of Object.entries(func.inputSchema.properties)) {
10447
+ const prop = value;
10448
+ const tsType = this.jsonSchemaTypeToTS(prop.type ?? "any");
10449
+ const comment = prop.description ? ` // ${prop.description}` : "";
10450
+ const optional = required.includes(key) ? "" : "?";
10451
+ typescript += ` ${key}${optional}: ${tsType};${comment}
10452
+ `;
10480
10453
  }
10481
10454
  }
10455
+ typescript += `}
10456
+ `;
10457
+ typescript += `
10458
+ interface ${outputTypeName} {
10459
+ `;
10460
+ if (func.outputSchema) {
10461
+ const outputType = this.jsonSchemaToTSInterface(func.outputSchema);
10462
+ typescript += outputType;
10463
+ } else {
10464
+ typescript += ` [key: string]: unknown;
10465
+ `;
10466
+ }
10467
+ typescript += `}
10468
+ `;
10469
+ return typescript;
10482
10470
  }
10483
10471
  /**
10484
- * Extract path segments for organizing functions
10472
+ * Converts JSON Schema type to TypeScript type.
10473
+ * @param type - JSON Schema type string
10474
+ * @returns TypeScript type string
10485
10475
  */
10486
- extractSegments(func, group) {
10487
- if (group.type === "graphql") {
10488
- const name = func.name;
10489
- if (name.startsWith("query_")) {
10490
- return [
10491
- "query",
10492
- name.replace("query_", "")
10493
- ];
10494
- }
10495
- if (name.startsWith("mutation_")) {
10496
- return [
10497
- "mutation",
10498
- name.replace("mutation_", "")
10499
- ];
10500
- }
10501
- }
10502
- if (group.type === "openapi") {
10503
- const name = func.name;
10504
- const camelSplit = name.match(/[A-Z]?[a-z]+|[A-Z]+(?=[A-Z][a-z]|\b)/g);
10505
- if (camelSplit && camelSplit.length > 2) {
10506
- const verb = camelSplit[0].toLowerCase();
10507
- const isVerb = [
10508
- "get",
10509
- "list",
10510
- "create",
10511
- "update",
10512
- "delete",
10513
- "post",
10514
- "put",
10515
- "patch"
10516
- ].includes(verb);
10517
- if (isVerb) {
10518
- const resource = camelSplit.slice(1).join("_").toLowerCase();
10519
- return [
10520
- resource,
10521
- name
10522
- ];
10523
- }
10524
- }
10525
- if (name.includes("_")) {
10526
- const parts = name.split("_");
10527
- if (parts.length > 1 && parts[0]) {
10528
- return [
10529
- parts[0],
10530
- name
10531
- ];
10532
- }
10533
- }
10534
- if (name.includes("-")) {
10535
- const parts = name.split("-");
10536
- if (parts.length > 1 && parts[0]) {
10537
- return [
10538
- parts[0],
10539
- name
10540
- ];
10541
- }
10542
- }
10476
+ jsonSchemaTypeToTS(type) {
10477
+ switch (type) {
10478
+ case "string":
10479
+ return "string";
10480
+ case "number":
10481
+ case "integer":
10482
+ return "number";
10483
+ case "boolean":
10484
+ return "boolean";
10485
+ case "array":
10486
+ return "unknown[]";
10487
+ case "object":
10488
+ return "Record<string, unknown>";
10489
+ default:
10490
+ return "unknown";
10543
10491
  }
10544
- return [
10545
- func.name
10546
- ];
10547
10492
  }
10548
10493
  /**
10549
- * Ensures a directory exists at the given path
10494
+ * Converts a full JSON Schema to TypeScript interface properties
10495
+ * @param schema - JSON Schema object
10496
+ * @param depth - Current recursion depth (prevents infinite recursion)
10497
+ * @returns TypeScript interface properties string
10550
10498
  */
10551
- ensureDirectory(parent, name, description) {
10552
- if (!parent.children) {
10553
- parent.children = /* @__PURE__ */ new Map();
10499
+ jsonSchemaToTSInterface(schema, depth = 0) {
10500
+ if (depth > 3) {
10501
+ return " [key: string]: unknown;\n";
10554
10502
  }
10555
- let child = parent.children.get(name);
10556
- if (!child) {
10557
- child = {
10558
- type: "directory",
10559
- name,
10560
- description,
10561
- children: /* @__PURE__ */ new Map()
10562
- };
10563
- parent.children.set(name, child);
10564
- } else if (description && !child.description) {
10565
- child.description = description;
10503
+ if (schema.type === "array" && schema.items) {
10504
+ const itemType = this.schemaToTSType(schema.items, depth + 1);
10505
+ return ` [index: number]: ${itemType};
10506
+ length: number;
10507
+ `;
10566
10508
  }
10567
- return child;
10509
+ if (schema.type === "object" && schema.properties) {
10510
+ const required = schema.required || [];
10511
+ let result = "";
10512
+ for (const [key, value] of Object.entries(schema.properties)) {
10513
+ const prop = value;
10514
+ const optional = required.includes(key) ? "" : "?";
10515
+ const tsType = this.schemaToTSType(prop, depth + 1);
10516
+ result += ` ${key}${optional}: ${tsType};
10517
+ `;
10518
+ }
10519
+ return result || " [key: string]: unknown;\n";
10520
+ }
10521
+ return " [key: string]: unknown;\n";
10568
10522
  }
10569
10523
  /**
10570
- * Adds a function to the tree
10571
- */
10572
- addFunction(parent, name, func, group) {
10573
- if (!parent.children) {
10574
- parent.children = /* @__PURE__ */ new Map();
10524
+ * Converts any JSON Schema to a TypeScript type expression
10525
+ * @param schema - JSON Schema object
10526
+ * @param depth - Current recursion depth
10527
+ * @returns TypeScript type expression
10528
+ */
10529
+ schemaToTSType(schema, depth = 0) {
10530
+ if (!schema) return "unknown";
10531
+ if (depth > 3) {
10532
+ return "unknown";
10575
10533
  }
10576
- parent.children.set(name, {
10577
- type: "function",
10578
- name,
10579
- functionDef: {
10580
- func,
10581
- group
10534
+ if (schema.type === "array") {
10535
+ if (schema.items) {
10536
+ const itemType = this.schemaToTSType(schema.items, depth + 1);
10537
+ return `${itemType}[]`;
10582
10538
  }
10583
- });
10539
+ return "unknown[]";
10540
+ }
10541
+ if (schema.enum) {
10542
+ return schema.enum.map((v) => `"${v}"`).join(" | ") || "string";
10543
+ }
10544
+ if (schema.type === "object" && schema.properties) {
10545
+ const required = schema.required || [];
10546
+ const props = [];
10547
+ for (const [key, value] of Object.entries(schema.properties)) {
10548
+ const prop = value;
10549
+ const optional = required.includes(key) ? "" : "?";
10550
+ const tsType = this.schemaToTSType(prop, depth + 1);
10551
+ props.push(`${key}${optional}: ${tsType}`);
10552
+ }
10553
+ if (props.length > 0) {
10554
+ return `{ ${props.join("; ")} }`;
10555
+ }
10556
+ return "Record<string, unknown>";
10557
+ }
10558
+ if (schema.type) {
10559
+ return this.jsonSchemaTypeToTS(schema.type);
10560
+ }
10561
+ return "unknown";
10584
10562
  }
10585
10563
  /**
10586
- * Explores the filesystem at the given path.
10587
- * Tool rules are automatically applied from the request scope.
10588
- * @param path - The path to explore
10564
+ * Helper to check if a string is a valid JavaScript identifier
10589
10565
  */
10590
- explore(path) {
10591
- const ctx = this.getFilterContext();
10592
- const normalizedPath = this.normalizePath(path);
10593
- const segments = normalizedPath === "/" ? [] : normalizedPath.split("/").filter((s) => s);
10594
- let current = this.root;
10595
- let currentPath = "/";
10596
- for (const segment of segments) {
10597
- if (!current.children || !current.children.has(segment)) {
10598
- return null;
10599
- }
10600
- current = current.children.get(segment);
10601
- currentPath = currentPath === "/" ? `/${segment}` : `${currentPath}/${segment}`;
10566
+ isValidIdentifier(name) {
10567
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
10568
+ }
10569
+ /**
10570
+ * Helper to safely format a property name for TypeScript type definitions
10571
+ * Returns the property name with quotes if needed, or just the name if valid
10572
+ */
10573
+ formatPropertyName(name) {
10574
+ if (!this.isValidIdentifier(name)) {
10575
+ return `'${name}'`;
10602
10576
  }
10603
- if (current.type === "directory") {
10604
- const items = [];
10605
- if (current.children) {
10606
- for (const [name, node] of current.children) {
10607
- if (node.type === "directory") {
10608
- if (!this.isDirectoryAllowed(name, currentPath, ctx)) continue;
10609
- } else if (node.type === "function" && node.functionDef) {
10610
- if (!ctx.allowedTools.has(`${node.functionDef.group}:${node.functionDef.func.name}`)) continue;
10611
- }
10612
- const item = {
10613
- name,
10614
- type: node.type
10615
- };
10616
- if (node.description) {
10617
- item.description = node.description;
10618
- } else if (node.type === "function" && node.functionDef?.func.description) {
10619
- item.description = node.functionDef.func.description;
10620
- }
10621
- items.push(item);
10577
+ return name;
10578
+ }
10579
+ /**
10580
+ * Generates the API namespace with all function declarations.
10581
+ * Handles hierarchical group names (e.g., "github/readOnly" -> api.github.readOnly)
10582
+ * @param groups - API groups to include
10583
+ * @returns TypeScript definition string
10584
+ */
10585
+ generateAPINamespace(groups) {
10586
+ const rootGroups = /* @__PURE__ */ new Map();
10587
+ for (const group of groups) {
10588
+ if (!group.functions || group.functions.length === 0) continue;
10589
+ const parts = group.name.split("/");
10590
+ let current = rootGroups;
10591
+ for (let i = 0; i < parts.length; i++) {
10592
+ const part = parts[i];
10593
+ if (!current.has(part)) {
10594
+ current.set(part, {
10595
+ functions: [],
10596
+ subgroups: /* @__PURE__ */ new Map()
10597
+ });
10622
10598
  }
10599
+ const node = current.get(part);
10600
+ if (i === parts.length - 1) {
10601
+ node.functions.push(...group.functions);
10602
+ }
10603
+ current = node.subgroups;
10623
10604
  }
10624
- items.sort((a, b) => {
10625
- if (a.type === b.type) {
10626
- return a.name.localeCompare(b.name);
10605
+ }
10606
+ const generateLevel = /* @__PURE__ */ __name((groups2, indent2) => {
10607
+ let ts = "";
10608
+ for (const [name, node] of groups2.entries()) {
10609
+ if (!name) continue;
10610
+ const formattedName = this.formatPropertyName(name);
10611
+ ts += `${indent2}${formattedName}: {
10612
+ `;
10613
+ for (const func of node.functions) {
10614
+ if (!func.name) continue;
10615
+ const funcName = this.formatPropertyName(func.name);
10616
+ const description = func.description && typeof func.description === "string" ? func.description.replace(/\n/g, " ").substring(0, 200) : "";
10617
+ ts += `${indent2} /**
10618
+ ${indent2} * ${description}
10619
+ ${indent2} */
10620
+ `;
10621
+ ts += `${indent2} ${funcName}(params: ${func.name}_Input): Promise<${func.name}_Output>;
10622
+ `;
10627
10623
  }
10628
- return a.type === "directory" ? -1 : 1;
10629
- });
10630
- const result = {
10631
- type: "directory",
10632
- path: currentPath,
10633
- items
10634
- };
10635
- if (current.apiGroupName) {
10636
- const apiGroup = this.apiGroupMap.get(current.apiGroupName);
10637
- if (apiGroup?.documentation) {
10638
- result.documentation = apiGroup.documentation;
10624
+ if (node.subgroups.size > 0) {
10625
+ ts += generateLevel(node.subgroups, indent2 + " ");
10639
10626
  }
10627
+ ts += `${indent2}};
10628
+ `;
10640
10629
  }
10641
- return result;
10642
- } else {
10643
- if (!current.functionDef) {
10644
- return null;
10645
- }
10646
- const { func, group } = current.functionDef;
10647
- if (!ctx.allowedTools.has(`${group}:${func.name}`)) {
10648
- return null;
10649
- }
10650
- const definition = this.generateFunctionDefinition(func, group);
10651
- return {
10652
- type: "function",
10653
- path: currentPath,
10654
- name: func.name,
10655
- description: func.description,
10656
- definition,
10657
- group,
10658
- inputSchema: func.inputSchema,
10659
- outputSchema: func.outputSchema
10660
- };
10661
- }
10630
+ return ts;
10631
+ }, "generateLevel");
10632
+ let typescript = `
10633
+ declare const api: {
10634
+ `;
10635
+ typescript += generateLevel(rootGroups, " ");
10636
+ typescript += `};
10637
+ `;
10638
+ typescript += `
10639
+ export { api };
10640
+ `;
10641
+ return typescript;
10662
10642
  }
10663
10643
  /**
10664
- * Normalizes a path (removes trailing slashes, ensures leading slash)
10644
+ * Gets the list of available API group names.
10645
+ * @returns Array of API group names
10665
10646
  */
10666
- normalizePath(path) {
10667
- if (!path || path === "") return "/";
10668
- if (!path.startsWith("/")) {
10669
- path = "/" + path;
10670
- }
10671
- if (path !== "/" && path.endsWith("/")) {
10672
- path = path.slice(0, -1);
10673
- }
10674
- return path;
10647
+ getApiGroups() {
10648
+ return this.apiGroups.map((g) => g.name);
10675
10649
  }
10676
10650
  /**
10677
- * Generates TypeScript function signature showing how to call the function.
10651
+ * Generates a compact TypeScript definition for a single function.
10652
+ * Includes input types with inline descriptions and compact output type.
10653
+ * @param func - Function definition
10654
+ * @param groupName - API group name
10655
+ * @returns Compact TypeScript definition string
10678
10656
  */
10679
- generateFunctionDefinition(func, group) {
10680
- const inputType = this.generateInputType(func.inputSchema);
10681
- const groupPath = group.replace(/\//g, ".");
10682
- const outputType = func.outputSchema ? this.generateOutputType(func.outputSchema) : "unknown";
10657
+ generateCompactFunctionDefinition(func, groupName) {
10658
+ const groupPath = groupName.replace(/\//g, ".");
10659
+ const inputType = this.generateCompactInputType(func.inputSchema);
10660
+ const outputType = func.outputSchema ? this.generateCompactOutputType(func.outputSchema) : "unknown";
10683
10661
  return `async function api.${groupPath}.${func.name}(${inputType}): Promise<${outputType}>`;
10684
10662
  }
10685
10663
  /**
10686
- * Generates TypeScript type from JSON schema
10664
+ * Generates compact input type with inline descriptions
10687
10665
  */
10688
- generateInputType(schema) {
10666
+ generateCompactInputType(schema) {
10689
10667
  if (!schema || !schema.properties) {
10690
10668
  return "{}";
10691
10669
  }
10692
10670
  const props = [];
10693
10671
  const required = schema.required || [];
10694
10672
  for (const [key, value] of Object.entries(schema.properties)) {
10695
- const isRequired = required.includes(key);
10696
10673
  const prop = value;
10697
- const tsType = this.jsonSchemaTypeToTS(prop.type ?? "any");
10674
+ const isRequired = required.includes(key);
10675
+ const tsType = prop.enum ? prop.enum.map((v) => `"${v}"`).join(" | ") : this.jsonSchemaTypeToTS(prop.type ?? "unknown");
10698
10676
  const optional = isRequired ? "" : "?";
10699
- props.push(`${key}${optional}: ${tsType}`);
10677
+ if (prop.description) {
10678
+ const desc = prop.description.replace(/\n/g, " ").substring(0, 100);
10679
+ props.push(`/* ${desc} */ ${key}${optional}: ${tsType}`);
10680
+ } else {
10681
+ props.push(`${key}${optional}: ${tsType}`);
10682
+ }
10700
10683
  }
10701
10684
  return `{ ${props.join("; ")} }`;
10702
10685
  }
10703
10686
  /**
10704
- * Generates output type from JSON schema
10687
+ * Generates compact output type with inline descriptions (top-level fields only, limited count)
10705
10688
  */
10706
- generateOutputType(schema) {
10689
+ generateCompactOutputType(schema) {
10707
10690
  if (!schema.properties) {
10708
10691
  return "unknown";
10709
10692
  }
10710
- const props = [];
10711
- for (const [key, value] of Object.entries(schema.properties)) {
10712
- const prop = value;
10713
- const tsType = this.jsonSchemaTypeToTS(prop.type ?? "any");
10714
- props.push(`${key}: ${tsType}`);
10693
+ const keys = Object.keys(schema.properties);
10694
+ if (keys.length === 0) {
10695
+ return "unknown";
10715
10696
  }
10716
- return `{ ${props.join("; ")} }`;
10717
- }
10718
- /**
10719
- * Converts JSON Schema type to TypeScript type
10720
- */
10721
- jsonSchemaTypeToTS(type) {
10722
- switch (type) {
10723
- case "string":
10724
- return "string";
10725
- case "number":
10726
- case "integer":
10727
- return "number";
10728
- case "boolean":
10729
- return "boolean";
10730
- case "array":
10731
- return "any[]";
10732
- case "object":
10733
- return "Record<string, any>";
10734
- default:
10735
- return "any";
10697
+ const maxFields = 6;
10698
+ const displayKeys = keys.slice(0, maxFields);
10699
+ const props = displayKeys.map((key) => {
10700
+ const prop = schema.properties[key];
10701
+ const tsType = this.jsonSchemaTypeToTS(prop.type ?? "unknown");
10702
+ if (prop.description) {
10703
+ const desc = prop.description.replace(/\n/g, " ").substring(0, 80);
10704
+ return `/* ${desc} */ ${key}: ${tsType}`;
10705
+ }
10706
+ return `${key}: ${tsType}`;
10707
+ });
10708
+ if (keys.length > maxFields) {
10709
+ return `{ ${props.join("; ")}; /* +${keys.length - maxFields} more */ }`;
10736
10710
  }
10711
+ return `{ ${props.join("; ")} }`;
10737
10712
  }
10738
10713
  };
10739
10714
 
10740
- // src/utils/schema.ts
10741
- function toJSONSchema(types) {
10742
- const properties = {};
10743
- const required = [];
10744
- for (const [key, type] of Object.entries(types)) {
10745
- properties[key] = {
10746
- type
10715
+ // src/explorer/index.ts
10716
+ var ExplorerService = class {
10717
+ static {
10718
+ __name(this, "ExplorerService");
10719
+ }
10720
+ root;
10721
+ apiGroups;
10722
+ apiGroupMap;
10723
+ aggregator;
10724
+ constructor(apiGroups) {
10725
+ this.apiGroups = apiGroups;
10726
+ this.apiGroupMap = new Map(apiGroups.map((group) => [
10727
+ group.name,
10728
+ group
10729
+ ]));
10730
+ this.aggregator = new APIAggregator(apiGroups);
10731
+ this.root = {
10732
+ type: "directory",
10733
+ name: "/",
10734
+ children: /* @__PURE__ */ new Map()
10747
10735
  };
10748
- required.push(key);
10736
+ this.buildTree(apiGroups);
10749
10737
  }
10750
- return {
10751
- type: "object",
10752
- properties,
10738
+ /**
10739
+ * Get filtering context based on current request's tool rules.
10740
+ * Returns sets for allowed items and all known items (for filtering).
10741
+ */
10742
+ getFilterContext() {
10743
+ const allowedGroups = filterApiGroups(this.apiGroups);
10744
+ const context = {
10745
+ allowedTypes: /* @__PURE__ */ new Set(),
10746
+ allowedGroups: /* @__PURE__ */ new Set(),
10747
+ allowedTools: /* @__PURE__ */ new Set(),
10748
+ allGroups: new Set(this.apiGroups.map((g) => g.name))
10749
+ };
10750
+ for (const group of allowedGroups) {
10751
+ if (group.type !== "graphql") {
10752
+ context.allowedTypes.add(group.type);
10753
+ }
10754
+ context.allowedGroups.add(group.name);
10755
+ }
10756
+ for (const group of this.apiGroups) {
10757
+ if (!context.allowedGroups.has(group.name)) continue;
10758
+ if (group.functions) {
10759
+ for (const func of group.functions) {
10760
+ context.allowedTools.add(`${group.name}:${func.name}`);
10761
+ }
10762
+ }
10763
+ }
10764
+ return context;
10765
+ }
10766
+ /**
10767
+ * Check if a directory should be visible based on filter context.
10768
+ */
10769
+ isDirectoryAllowed(name, currentPath, ctx) {
10770
+ const API_TYPES = [
10771
+ "openapi",
10772
+ "mcp",
10773
+ "custom",
10774
+ "graphql"
10775
+ ];
10776
+ if (currentPath === "/" && API_TYPES.includes(name)) {
10777
+ return ctx.allowedTypes.has(name) || ctx.allowedGroups.has(name);
10778
+ }
10779
+ if (ctx.allGroups.has(name)) {
10780
+ return ctx.allowedGroups.has(name);
10781
+ }
10782
+ return true;
10783
+ }
10784
+ /**
10785
+ * Builds the virtual filesystem tree from API groups
10786
+ */
10787
+ buildTree(apiGroups) {
10788
+ for (const group of apiGroups) {
10789
+ if (!group.functions || group.functions.length === 0) continue;
10790
+ let groupFolder;
10791
+ if (group.type === "graphql") {
10792
+ groupFolder = this.ensureDirectory(this.root, group.name, group.description);
10793
+ } else {
10794
+ groupFolder = this.ensureDirectory(this.ensureDirectory(this.root, group.type), group.name, group.description);
10795
+ }
10796
+ groupFolder.apiGroupName = group.name;
10797
+ for (const func of group.functions) {
10798
+ const segments = this.extractSegments(func, group);
10799
+ if (segments.length > 1) {
10800
+ let current = groupFolder;
10801
+ for (let i = 0; i < segments.length - 1; i++) {
10802
+ current = this.ensureDirectory(current, segments[i]);
10803
+ }
10804
+ this.addFunction(current, segments[segments.length - 1], func, group.name);
10805
+ } else {
10806
+ this.addFunction(groupFolder, func.name, func, group.name);
10807
+ }
10808
+ }
10809
+ }
10810
+ }
10811
+ /**
10812
+ * Extract path segments for organizing functions
10813
+ */
10814
+ extractSegments(func, group) {
10815
+ if (group.type === "graphql") {
10816
+ const name = func.name;
10817
+ if (name.startsWith("query_")) {
10818
+ return [
10819
+ "query",
10820
+ name.replace("query_", "")
10821
+ ];
10822
+ }
10823
+ if (name.startsWith("mutation_")) {
10824
+ return [
10825
+ "mutation",
10826
+ name.replace("mutation_", "")
10827
+ ];
10828
+ }
10829
+ }
10830
+ if (group.type === "openapi") {
10831
+ const name = func.name;
10832
+ const camelSplit = name.match(/[A-Z]?[a-z]+|[A-Z]+(?=[A-Z][a-z]|\b)/g);
10833
+ if (camelSplit && camelSplit.length > 2) {
10834
+ const verb = camelSplit[0].toLowerCase();
10835
+ const isVerb = [
10836
+ "get",
10837
+ "list",
10838
+ "create",
10839
+ "update",
10840
+ "delete",
10841
+ "post",
10842
+ "put",
10843
+ "patch"
10844
+ ].includes(verb);
10845
+ if (isVerb) {
10846
+ const resource = camelSplit.slice(1).join("_").toLowerCase();
10847
+ return [
10848
+ resource,
10849
+ name
10850
+ ];
10851
+ }
10852
+ }
10853
+ if (name.includes("_")) {
10854
+ const parts = name.split("_");
10855
+ if (parts.length > 1 && parts[0]) {
10856
+ return [
10857
+ parts[0],
10858
+ name
10859
+ ];
10860
+ }
10861
+ }
10862
+ if (name.includes("-")) {
10863
+ const parts = name.split("-");
10864
+ if (parts.length > 1 && parts[0]) {
10865
+ return [
10866
+ parts[0],
10867
+ name
10868
+ ];
10869
+ }
10870
+ }
10871
+ }
10872
+ return [
10873
+ func.name
10874
+ ];
10875
+ }
10876
+ /**
10877
+ * Ensures a directory exists at the given path
10878
+ */
10879
+ ensureDirectory(parent, name, description) {
10880
+ if (!parent.children) {
10881
+ parent.children = /* @__PURE__ */ new Map();
10882
+ }
10883
+ let child = parent.children.get(name);
10884
+ if (!child) {
10885
+ child = {
10886
+ type: "directory",
10887
+ name,
10888
+ description,
10889
+ children: /* @__PURE__ */ new Map()
10890
+ };
10891
+ parent.children.set(name, child);
10892
+ } else if (description && !child.description) {
10893
+ child.description = description;
10894
+ }
10895
+ return child;
10896
+ }
10897
+ /**
10898
+ * Adds a function to the tree
10899
+ */
10900
+ addFunction(parent, name, func, group) {
10901
+ if (!parent.children) {
10902
+ parent.children = /* @__PURE__ */ new Map();
10903
+ }
10904
+ parent.children.set(name, {
10905
+ type: "function",
10906
+ name,
10907
+ functionDef: {
10908
+ func,
10909
+ group
10910
+ }
10911
+ });
10912
+ }
10913
+ /**
10914
+ * Explores the filesystem at the given path.
10915
+ * Tool rules are automatically applied from the request scope.
10916
+ * @param path - The path to explore
10917
+ */
10918
+ explore(path) {
10919
+ const ctx = this.getFilterContext();
10920
+ const normalizedPath = this.normalizePath(path);
10921
+ const segments = normalizedPath === "/" ? [] : normalizedPath.split("/").filter((s) => s);
10922
+ let current = this.root;
10923
+ let currentPath = "/";
10924
+ for (const segment of segments) {
10925
+ if (!current.children || !current.children.has(segment)) {
10926
+ return null;
10927
+ }
10928
+ current = current.children.get(segment);
10929
+ currentPath = currentPath === "/" ? `/${segment}` : `${currentPath}/${segment}`;
10930
+ }
10931
+ if (current.type === "directory") {
10932
+ const items = [];
10933
+ if (current.children) {
10934
+ for (const [name, node] of current.children) {
10935
+ if (node.type === "directory") {
10936
+ if (!this.isDirectoryAllowed(name, currentPath, ctx)) continue;
10937
+ } else if (node.type === "function" && node.functionDef) {
10938
+ if (!ctx.allowedTools.has(`${node.functionDef.group}:${node.functionDef.func.name}`)) continue;
10939
+ }
10940
+ const item = {
10941
+ name,
10942
+ type: node.type
10943
+ };
10944
+ if (node.description) {
10945
+ item.description = node.description;
10946
+ } else if (node.type === "function" && node.functionDef?.func.description) {
10947
+ item.description = node.functionDef.func.description;
10948
+ }
10949
+ items.push(item);
10950
+ }
10951
+ }
10952
+ items.sort((a, b) => {
10953
+ if (a.type === b.type) {
10954
+ return a.name.localeCompare(b.name);
10955
+ }
10956
+ return a.type === "directory" ? -1 : 1;
10957
+ });
10958
+ const result = {
10959
+ type: "directory",
10960
+ path: currentPath,
10961
+ items
10962
+ };
10963
+ if (current.apiGroupName) {
10964
+ const apiGroup = this.apiGroupMap.get(current.apiGroupName);
10965
+ if (apiGroup?.documentation) {
10966
+ result.documentation = apiGroup.documentation;
10967
+ }
10968
+ }
10969
+ return result;
10970
+ } else {
10971
+ if (!current.functionDef) {
10972
+ return null;
10973
+ }
10974
+ const { func, group } = current.functionDef;
10975
+ if (!ctx.allowedTools.has(`${group}:${func.name}`)) {
10976
+ return null;
10977
+ }
10978
+ const definition = this.aggregator.generateCompactFunctionDefinition(func, group);
10979
+ return {
10980
+ type: "function",
10981
+ path: currentPath,
10982
+ name: func.name,
10983
+ description: func.description,
10984
+ definition,
10985
+ group
10986
+ };
10987
+ }
10988
+ }
10989
+ /**
10990
+ * Normalizes a path (removes trailing slashes, ensures leading slash)
10991
+ */
10992
+ normalizePath(path) {
10993
+ if (!path || path === "") return "/";
10994
+ if (!path.startsWith("/")) {
10995
+ path = "/" + path;
10996
+ }
10997
+ if (path !== "/" && path.endsWith("/")) {
10998
+ path = path.slice(0, -1);
10999
+ }
11000
+ return path;
11001
+ }
11002
+ };
11003
+
11004
+ // src/utils/schema.ts
11005
+ function toJSONSchema(types) {
11006
+ const properties = {};
11007
+ const required = [];
11008
+ for (const [key, type] of Object.entries(types)) {
11009
+ properties[key] = {
11010
+ type
11011
+ };
11012
+ required.push(key);
11013
+ }
11014
+ return {
11015
+ type: "object",
11016
+ properties,
10753
11017
  required
10754
11018
  };
10755
11019
  }
@@ -11396,640 +11660,377 @@ async function handleExecute(ctx, executor, stateManager, config, auditSink, ses
11396
11660
  executionId: prelimExecutionId
11397
11661
  });
11398
11662
  } catch (error) {
11399
- atpRuntime.log.error("Failed to verify provenance hints", {
11400
- error
11401
- });
11402
- }
11403
- }
11404
- const startTime = Date.now();
11405
- if (auditSink) {
11406
- const startEvent = {
11407
- eventId: crypto__default.default.randomUUID(),
11408
- timestamp: startTime,
11409
- clientId: ctx.clientId || "anonymous",
11410
- eventType: "execution",
11411
- action: "start",
11412
- code,
11413
- status: "success"
11414
- };
11415
- await auditSink.write(startEvent).catch(() => {
11416
- });
11417
- }
11418
- const result = await executor.execute(code, executionConfig, ctx.clientId, {
11419
- callbackHistory: [],
11420
- newCallbackResult: void 0,
11421
- executionId: prelimExecutionId
11422
- });
11423
- if (result.status === atpProtocol.ExecutionStatus.COMPLETED && executionConfig.provenanceMode && executionConfig.provenanceMode !== atpProtocol.ProvenanceMode.NONE && ctx.cache && result.provenanceSnapshot) {
11424
- try {
11425
- atpRuntime.log.info("Attempting to emit provenance tokens from snapshot", {
11426
- executionId: result.executionId,
11427
- provenanceMode: executionConfig.provenanceMode,
11428
- hasCache: !!ctx.cache,
11429
- hasSnapshot: !!result.provenanceSnapshot,
11430
- resultType: typeof result.result
11431
- });
11432
- const tokens = await emitProvenanceTokens(
11433
- result.result,
11434
- ctx.clientId || "anonymous",
11435
- result.executionId,
11436
- executionConfig.provenanceMode,
11437
- ctx.cache,
11438
- atpRuntime.log.child({
11439
- executionId: result.executionId
11440
- }),
11441
- 5e3,
11442
- 3600,
11443
- result.provenanceSnapshot
11444
- // Pass snapshot
11445
- );
11446
- atpRuntime.log.info("Provenance tokens emitted", {
11447
- executionId: result.executionId,
11448
- tokenCount: tokens.length
11449
- });
11450
- if (tokens.length > 0) {
11451
- result.provenanceTokens = tokens;
11452
- }
11453
- } catch (error) {
11454
- atpRuntime.log.error("Failed to emit provenance tokens", {
11455
- error,
11456
- executionId: result.executionId
11457
- });
11458
- }
11459
- }
11460
- delete result.provenanceSnapshot;
11461
- if (result.result && typeof result.result === "object") {
11462
- const hasProv = "__prov_id__" in result.result;
11463
- result.result = cleanProvenanceIds(result.result);
11464
- const stillHasProv = result.result && typeof result.result === "object" && "__prov_id__" in result.result;
11465
- if (hasProv && !stillHasProv) {
11466
- atpRuntime.log.debug("Successfully cleaned __prov_id__ from result");
11467
- } else if (hasProv && stillHasProv) {
11468
- atpRuntime.log.warn("Failed to clean __prov_id__ from result!");
11469
- }
11470
- }
11471
- if (auditSink) {
11472
- const endEvent = {
11473
- eventId: crypto__default.default.randomUUID(),
11474
- timestamp: Date.now(),
11475
- clientId: ctx.clientId || "anonymous",
11476
- eventType: "execution",
11477
- action: result.status === atpProtocol.ExecutionStatus.PAUSED ? "pause" : "complete",
11478
- resourceId: result.executionId,
11479
- status: result.status === atpProtocol.ExecutionStatus.COMPLETED ? "success" : result.status === atpProtocol.ExecutionStatus.FAILED ? "failed" : "paused",
11480
- duration: Date.now() - startTime,
11481
- memoryUsed: result.stats?.memoryUsed,
11482
- llmCallsCount: result.stats?.llmCallsCount,
11483
- error: result.error ? {
11484
- message: result.error.message,
11485
- code: result.error.code,
11486
- stack: result.error.stack
11487
- } : void 0
11488
- };
11489
- await auditSink.write(endEvent).catch(() => {
11490
- });
11491
- }
11492
- if (result.status === "paused" && (result.needsCallback || result.needsCallbacks) && result.callbackHistory) {
11493
- if (!ctx.clientId) {
11494
- ctx.throw(400, "Client ID required for paused executions");
11495
- }
11496
- const provenanceSnap = executionConfig.provenanceMode && executionConfig.provenanceMode !== atpProtocol.ProvenanceMode.NONE ? atpProvenance.captureProvenanceSnapshot(result.executionId) : void 0;
11497
- const callbackRequest = result.needsCallback || result.needsCallbacks && result.needsCallbacks[0];
11498
- if (!callbackRequest) {
11499
- ctx.throw(500, "Invalid paused state: no callback request");
11500
- }
11501
- const transformedCodeToSave = result.transformedCode || code;
11502
- await stateManager.pause({
11503
- executionId: result.executionId,
11504
- code: transformedCodeToSave,
11505
- config: executionConfig,
11506
- clientId: ctx.clientId,
11507
- callbackRequest,
11508
- pausedAt: Date.now(),
11509
- callbackHistory: result.callbackHistory,
11510
- currentCallbackIndex: result.callbackHistory.length - 1,
11511
- context: {
11512
- codeTransformed: !!result.transformedCode
11513
- },
11514
- provenanceState: provenanceSnap
11515
- });
11516
- }
11517
- if (hintMap && hintMap.size > 0) {
11518
- clearHintMap(prelimExecutionId);
11519
- }
11520
- return result;
11521
- }
11522
- __name(handleExecute, "handleExecute");
11523
- function tagCallbackResult(callbackRecord, result, provenanceMode) {
11524
- if (!provenanceMode || provenanceMode === atpProtocol.ProvenanceMode.NONE) {
11525
- return result;
11526
- }
11527
- if (result === null || result === void 0) {
11528
- return result;
11529
- }
11530
- const tagValue = /* @__PURE__ */ __name((value, source) => {
11531
- if (value === null || value === void 0) {
11532
- return value;
11533
- }
11534
- if (typeof value === "string" || typeof value === "number") {
11535
- const metadata = {
11536
- id: crypto.randomUUID(),
11537
- source,
11538
- readers: {
11539
- type: "public"
11540
- },
11541
- dependencies: [],
11542
- context: {}
11543
- };
11544
- atpProvenance.markPrimitiveTainted(value, metadata);
11545
- return value;
11546
- }
11547
- if (typeof value === "object") {
11548
- return atpProvenance.createProvenanceProxy(value, source, {
11549
- type: "public"
11663
+ atpRuntime.log.error("Failed to verify provenance hints", {
11664
+ error
11550
11665
  });
11551
11666
  }
11552
- return value;
11553
- }, "tagValue");
11554
- if (callbackRecord.type === "llm") {
11555
- const source = {
11556
- type: atpProvenance.ProvenanceSource.LLM,
11557
- operation: callbackRecord.operation || "call",
11558
- timestamp: Date.now()
11559
- };
11560
- return Array.isArray(result) ? result.map((r) => tagValue(r, source)) : tagValue(result, source);
11561
11667
  }
11562
- if (callbackRecord.type === "tool") {
11563
- const source = {
11564
- type: atpProvenance.ProvenanceSource.TOOL,
11565
- toolName: callbackRecord.payload?.toolName || "clientTool",
11566
- apiGroup: callbackRecord.payload?.namespace || "client",
11567
- timestamp: Date.now()
11668
+ const startTime = Date.now();
11669
+ if (auditSink) {
11670
+ const startEvent = {
11671
+ eventId: crypto__default.default.randomUUID(),
11672
+ timestamp: startTime,
11673
+ clientId: ctx.clientId || "anonymous",
11674
+ eventType: "execution",
11675
+ action: "start",
11676
+ code,
11677
+ status: "success"
11568
11678
  };
11569
- return Array.isArray(result) ? result.map((r) => tagValue(r, source)) : tagValue(result, source);
11570
- }
11571
- return result;
11572
- }
11573
- __name(tagCallbackResult, "tagCallbackResult");
11574
- async function handleResume(ctx, executionId, executor, stateManager, serverConfig, sessionManager) {
11575
- const requestClientId = ctx.headers["x-client-id"] || ctx.clientId;
11576
- const requestToken = ctx.headers["authorization"]?.replace("Bearer ", "");
11577
- if (!requestClientId || !requestToken) {
11578
- atpRuntime.log.warn("Resume attempt without authentication", {
11579
- executionId
11580
- });
11581
- ctx.throw(401, "Authentication required");
11582
- }
11583
- ctx.clientId = requestClientId;
11584
- if (sessionManager) {
11585
- const isValid = await sessionManager.verifyClient(requestClientId, requestToken);
11586
- if (!isValid) {
11587
- atpRuntime.log.warn("Resume attempt with invalid token", {
11588
- executionId,
11589
- clientId: requestClientId
11590
- });
11591
- ctx.throw(403, "Invalid client credentials");
11592
- }
11593
- }
11594
- const pausedState = await stateManager.get(executionId);
11595
- if (!pausedState) {
11596
- ctx.throw(404, "Not found");
11597
- }
11598
- if (pausedState.clientId !== requestClientId) {
11599
- atpRuntime.log.warn("Resume attempt by unauthorized client", {
11600
- executionId,
11601
- requestClientId,
11602
- ownerClientId: pausedState.clientId
11679
+ await auditSink.write(startEvent).catch(() => {
11603
11680
  });
11604
- ctx.throw(403, "Unauthorized: execution belongs to different client");
11605
11681
  }
11606
- atpRuntime.log.info("Resume authorized", {
11607
- executionId,
11608
- clientId: requestClientId
11682
+ const result = await executor.execute(code, executionConfig, ctx.clientId, {
11683
+ callbackHistory: [],
11684
+ newCallbackResult: void 0,
11685
+ executionId: prelimExecutionId
11609
11686
  });
11610
- if (pausedState.provenanceState && pausedState.config.provenanceMode && pausedState.config.provenanceMode !== atpProtocol.ProvenanceMode.NONE) {
11611
- const state = pausedState.provenanceState;
11612
- if ("primitives" in state) {
11613
- atpProvenance.restoreProvenanceSnapshot(executionId, state);
11614
- atpRuntime.log.info("Provenance snapshot restored", {
11615
- executionId,
11616
- registryEntries: state.registry.length,
11617
- primitiveEntries: state.primitives.length
11687
+ if (result.status === atpProtocol.ExecutionStatus.COMPLETED && executionConfig.provenanceMode && executionConfig.provenanceMode !== atpProtocol.ProvenanceMode.NONE && ctx.cache && result.provenanceSnapshot) {
11688
+ try {
11689
+ atpRuntime.log.info("Attempting to emit provenance tokens from snapshot", {
11690
+ executionId: result.executionId,
11691
+ provenanceMode: executionConfig.provenanceMode,
11692
+ hasCache: !!ctx.cache,
11693
+ hasSnapshot: !!result.provenanceSnapshot,
11694
+ resultType: typeof result.result
11618
11695
  });
11619
- } else {
11620
- const provenanceMap = new Map(state.registry);
11621
- atpProvenance.restoreProvenanceSnapshot(executionId, {
11622
- registry: state.registry,
11623
- primitives: []
11696
+ const tokens = await emitProvenanceTokens(
11697
+ result.result,
11698
+ ctx.clientId || "anonymous",
11699
+ result.executionId,
11700
+ executionConfig.provenanceMode,
11701
+ ctx.cache,
11702
+ atpRuntime.log.child({
11703
+ executionId: result.executionId
11704
+ }),
11705
+ 5e3,
11706
+ 3600,
11707
+ result.provenanceSnapshot
11708
+ // Pass snapshot
11709
+ );
11710
+ atpRuntime.log.info("Provenance tokens emitted", {
11711
+ executionId: result.executionId,
11712
+ tokenCount: tokens.length
11624
11713
  });
11625
- atpRuntime.log.info("Provenance state restored (legacy format)", {
11626
- executionId,
11627
- entries: provenanceMap.size
11714
+ if (tokens.length > 0) {
11715
+ result.provenanceTokens = tokens;
11716
+ }
11717
+ } catch (error) {
11718
+ atpRuntime.log.error("Failed to emit provenance tokens", {
11719
+ error,
11720
+ executionId: result.executionId
11628
11721
  });
11629
11722
  }
11630
11723
  }
11631
- const request = ctx.body;
11632
- let updatedHistory;
11633
- let callbackResult;
11634
- const lastRecord = pausedState.callbackHistory[pausedState.currentCallbackIndex];
11635
- if (!lastRecord) {
11636
- atpRuntime.log.error("No callback record found at current index", {
11637
- executionId,
11638
- currentIndex: pausedState.currentCallbackIndex
11639
- });
11640
- ctx.throw(500, "Invalid paused state: no callback record");
11641
- }
11642
- if (request.results) {
11643
- const batchResults = request.results;
11644
- atpRuntime.log.info("Processing batch callback results", {
11645
- executionId,
11646
- batchCount: batchResults.length
11647
- });
11648
- for (const br of batchResults) {
11649
- if (br.result && typeof br.result === "object" && "__error" in br.result) {
11650
- const errorObj = br.result;
11651
- if (errorObj.message && errorObj.message.includes("service not provided")) {
11652
- atpRuntime.log.error("Service provider error in batch", {
11653
- executionId,
11654
- error: errorObj.message
11655
- });
11656
- await stateManager.delete(executionId);
11657
- return {
11658
- executionId,
11659
- status: atpProtocol.ExecutionStatus.FAILED,
11660
- error: {
11661
- message: errorObj.message || "Service not available",
11662
- code: "SERVICE_NOT_PROVIDED"
11663
- },
11664
- stats: {
11665
- duration: 0,
11666
- memoryUsed: 0,
11667
- llmCallsCount: 0,
11668
- approvalCallsCount: 0
11669
- }
11670
- };
11671
- }
11672
- }
11673
- }
11674
- const taggedBatchResults = batchResults.map((br) => ({
11675
- ...br,
11676
- result: tagCallbackResult(lastRecord, br.result, pausedState.config.provenanceMode)
11677
- }));
11678
- callbackResult = taggedBatchResults.map((br) => br.result);
11679
- updatedHistory = pausedState.callbackHistory.map((record, index) => {
11680
- if (index === pausedState.currentCallbackIndex) {
11681
- return {
11682
- ...record,
11683
- result: callbackResult
11684
- };
11685
- }
11686
- return record;
11687
- });
11688
- } else {
11689
- const rawResult = request.result;
11690
- if (rawResult && typeof rawResult === "object" && "__error" in rawResult) {
11691
- const errorObj = rawResult;
11692
- if (errorObj.message && errorObj.message.includes("service not provided")) {
11693
- atpRuntime.log.error("Service provider error", {
11694
- executionId,
11695
- error: errorObj.message
11696
- });
11697
- await stateManager.delete(executionId);
11698
- return {
11699
- executionId,
11700
- status: atpProtocol.ExecutionStatus.FAILED,
11701
- error: {
11702
- message: errorObj.message || "Service not available",
11703
- code: "SERVICE_NOT_PROVIDED"
11704
- },
11705
- stats: {
11706
- duration: 0,
11707
- memoryUsed: 0,
11708
- llmCallsCount: 0,
11709
- approvalCallsCount: 0
11710
- }
11711
- };
11712
- }
11724
+ delete result.provenanceSnapshot;
11725
+ if (result.result && typeof result.result === "object") {
11726
+ const hasProv = "__prov_id__" in result.result;
11727
+ result.result = cleanProvenanceIds(result.result);
11728
+ const stillHasProv = result.result && typeof result.result === "object" && "__prov_id__" in result.result;
11729
+ if (hasProv && !stillHasProv) {
11730
+ atpRuntime.log.debug("Successfully cleaned __prov_id__ from result");
11731
+ } else if (hasProv && stillHasProv) {
11732
+ atpRuntime.log.warn("Failed to clean __prov_id__ from result!");
11713
11733
  }
11714
- callbackResult = tagCallbackResult(lastRecord, rawResult, pausedState.config.provenanceMode);
11715
- updatedHistory = pausedState.callbackHistory.map((record, index) => {
11716
- if (index === pausedState.currentCallbackIndex) {
11717
- return {
11718
- ...record,
11719
- result: callbackResult
11720
- };
11721
- }
11722
- return record;
11723
- });
11724
11734
  }
11725
- const restoredConfig = {
11726
- ...pausedState.config,
11727
- securityPolicies: serverConfig.execution.securityPolicies || []
11728
- };
11729
- const result = await executor.execute(pausedState.code, restoredConfig, pausedState.clientId, {
11730
- callbackHistory: updatedHistory,
11731
- newCallbackResult: callbackResult,
11732
- executionId
11733
- });
11734
- if (result.status === atpProtocol.ExecutionStatus.PAUSED && result.needsCallbacks && result.callbackHistory) {
11735
- const provenanceState = pausedState.config.provenanceMode && pausedState.config.provenanceMode !== atpProtocol.ProvenanceMode.NONE ? atpProvenance.captureProvenanceSnapshot(result.executionId) : void 0;
11736
- const codeToSave = result.transformedCode || pausedState.code;
11737
- await stateManager.pause({
11738
- executionId: result.executionId,
11739
- code: codeToSave,
11740
- config: pausedState.config,
11741
- clientId: pausedState.clientId,
11742
- callbackRequest: result.needsCallbacks[0],
11743
- pausedAt: Date.now(),
11744
- callbackHistory: result.callbackHistory,
11745
- currentCallbackIndex: result.callbackHistory.length - 1,
11746
- context: {},
11747
- provenanceState
11735
+ if (auditSink) {
11736
+ const endEvent = {
11737
+ eventId: crypto__default.default.randomUUID(),
11738
+ timestamp: Date.now(),
11739
+ clientId: ctx.clientId || "anonymous",
11740
+ eventType: "execution",
11741
+ action: result.status === atpProtocol.ExecutionStatus.PAUSED ? "pause" : "complete",
11742
+ resourceId: result.executionId,
11743
+ status: result.status === atpProtocol.ExecutionStatus.COMPLETED ? "success" : result.status === atpProtocol.ExecutionStatus.FAILED ? "failed" : "paused",
11744
+ duration: Date.now() - startTime,
11745
+ memoryUsed: result.stats?.memoryUsed,
11746
+ llmCallsCount: result.stats?.llmCallsCount,
11747
+ error: result.error ? {
11748
+ message: result.error.message,
11749
+ code: result.error.code,
11750
+ stack: result.error.stack
11751
+ } : void 0
11752
+ };
11753
+ await auditSink.write(endEvent).catch(() => {
11748
11754
  });
11749
- } else if (result.status === atpProtocol.ExecutionStatus.PAUSED && result.needsCallback && result.callbackHistory) {
11750
- const provenanceState = pausedState.config.provenanceMode && pausedState.config.provenanceMode !== atpProtocol.ProvenanceMode.NONE ? atpProvenance.captureProvenanceSnapshot(result.executionId) : void 0;
11751
- const codeToSave = result.transformedCode || pausedState.code;
11755
+ }
11756
+ if (result.status === "paused" && (result.needsCallback || result.needsCallbacks) && result.callbackHistory) {
11757
+ if (!ctx.clientId) {
11758
+ ctx.throw(400, "Client ID required for paused executions");
11759
+ }
11760
+ const provenanceSnap = executionConfig.provenanceMode && executionConfig.provenanceMode !== atpProtocol.ProvenanceMode.NONE ? atpProvenance.captureProvenanceSnapshot(result.executionId) : void 0;
11761
+ const callbackRequest = result.needsCallback || result.needsCallbacks && result.needsCallbacks[0];
11762
+ if (!callbackRequest) {
11763
+ ctx.throw(500, "Invalid paused state: no callback request");
11764
+ }
11765
+ const transformedCodeToSave = result.transformedCode || code;
11752
11766
  await stateManager.pause({
11753
11767
  executionId: result.executionId,
11754
- code: codeToSave,
11755
- config: pausedState.config,
11756
- clientId: pausedState.clientId,
11757
- callbackRequest: result.needsCallback,
11768
+ code: transformedCodeToSave,
11769
+ config: executionConfig,
11770
+ clientId: ctx.clientId,
11771
+ callbackRequest,
11758
11772
  pausedAt: Date.now(),
11759
11773
  callbackHistory: result.callbackHistory,
11760
11774
  currentCallbackIndex: result.callbackHistory.length - 1,
11761
- context: {},
11762
- provenanceState
11775
+ context: {
11776
+ codeTransformed: !!result.transformedCode
11777
+ },
11778
+ provenanceState: provenanceSnap
11763
11779
  });
11764
- } else {
11765
- await stateManager.delete(executionId);
11780
+ }
11781
+ if (hintMap && hintMap.size > 0) {
11782
+ clearHintMap(prelimExecutionId);
11766
11783
  }
11767
11784
  return result;
11768
11785
  }
11769
- __name(handleResume, "handleResume");
11770
- var APIAggregator = class {
11771
- static {
11772
- __name(this, "APIAggregator");
11773
- }
11774
- apiGroups;
11775
- /**
11776
- * Creates a new APIAggregator instance.
11777
- * @param apiGroups - Array of API group configurations
11778
- */
11779
- constructor(apiGroups) {
11780
- this.apiGroups = apiGroups;
11781
- }
11782
- /**
11783
- * Generates TypeScript type definitions for selected API groups.
11784
- * @param selectedGroups - Optional array of group names to include
11785
- * @returns TypeScript definition string
11786
- */
11787
- async generateTypeScript(selectedGroups) {
11788
- const groups = selectedGroups ? this.apiGroups.filter((g) => selectedGroups.includes(g.name)) : this.apiGroups;
11789
- let typescript = `// Agent Tool Protocol Runtime SDK v1.0.0
11790
-
11791
- `;
11792
- typescript += this.generateRuntimeTypes();
11793
- for (const group of groups) {
11794
- typescript += `
11795
- // API Group: ${group.name}
11796
- `;
11797
- if (group.functions) {
11798
- for (const func of group.functions) {
11799
- typescript += this.generateFunctionTypes(func, group.name);
11800
- }
11801
- }
11802
- }
11803
- typescript += this.generateAPINamespace(groups);
11804
- return typescript;
11786
+ __name(handleExecute, "handleExecute");
11787
+ function tagCallbackResult(callbackRecord, result, provenanceMode) {
11788
+ if (!provenanceMode || provenanceMode === atpProtocol.ProvenanceMode.NONE) {
11789
+ return result;
11805
11790
  }
11806
- /**
11807
- * Generates TypeScript definitions for the runtime SDK.
11808
- * @param options - Optional filtering options
11809
- * @returns TypeScript definition string
11810
- */
11811
- generateRuntimeTypes(options) {
11812
- return atpRuntime.generateRuntimeTypes(atpRuntime.GENERATED_METADATA, options);
11791
+ if (result === null || result === void 0) {
11792
+ return result;
11813
11793
  }
11814
- /**
11815
- * Generates TypeScript types for a single function.
11816
- * @param func - Function definition
11817
- * @param groupName - API group name
11818
- * @returns TypeScript definition string
11819
- */
11820
- generateFunctionTypes(func, groupName) {
11821
- const inputTypeName = `${func.name}_Input`;
11822
- const outputTypeName = `${func.name}_Output`;
11823
- let typescript = `
11824
- interface ${inputTypeName} {
11825
- `;
11826
- if (func.inputSchema?.properties) {
11827
- const required = func.inputSchema.required || [];
11828
- for (const [key, value] of Object.entries(func.inputSchema.properties)) {
11829
- const prop = value;
11830
- const tsType = this.jsonSchemaTypeToTS(prop.type ?? "any");
11831
- const comment = prop.description ? ` // ${prop.description}` : "";
11832
- const optional = required.includes(key) ? "" : "?";
11833
- typescript += ` ${key}${optional}: ${tsType};${comment}
11834
- `;
11835
- }
11794
+ const tagValue = /* @__PURE__ */ __name((value, source) => {
11795
+ if (value === null || value === void 0) {
11796
+ return value;
11836
11797
  }
11837
- typescript += `}
11838
- `;
11839
- typescript += `
11840
- interface ${outputTypeName} {
11841
- `;
11842
- if (func.outputSchema) {
11843
- const outputType = this.jsonSchemaToTSInterface(func.outputSchema);
11844
- typescript += outputType;
11845
- } else {
11846
- typescript += ` [key: string]: unknown;
11847
- `;
11798
+ if (typeof value === "string" || typeof value === "number") {
11799
+ const metadata = {
11800
+ id: crypto.randomUUID(),
11801
+ source,
11802
+ readers: {
11803
+ type: "public"
11804
+ },
11805
+ dependencies: [],
11806
+ context: {}
11807
+ };
11808
+ atpProvenance.markPrimitiveTainted(value, metadata);
11809
+ return value;
11848
11810
  }
11849
- typescript += `}
11850
- `;
11851
- return typescript;
11852
- }
11853
- /**
11854
- * Converts JSON Schema type to TypeScript type.
11855
- * @param type - JSON Schema type string
11856
- * @returns TypeScript type string
11857
- */
11858
- jsonSchemaTypeToTS(type) {
11859
- switch (type) {
11860
- case "string":
11861
- return "string";
11862
- case "number":
11863
- case "integer":
11864
- return "number";
11865
- case "boolean":
11866
- return "boolean";
11867
- case "array":
11868
- return "unknown[]";
11869
- case "object":
11870
- return "Record<string, unknown>";
11871
- default:
11872
- return "unknown";
11811
+ if (typeof value === "object") {
11812
+ return atpProvenance.createProvenanceProxy(value, source, {
11813
+ type: "public"
11814
+ });
11873
11815
  }
11816
+ return value;
11817
+ }, "tagValue");
11818
+ if (callbackRecord.type === "llm") {
11819
+ const source = {
11820
+ type: atpProvenance.ProvenanceSource.LLM,
11821
+ operation: callbackRecord.operation || "call",
11822
+ timestamp: Date.now()
11823
+ };
11824
+ return Array.isArray(result) ? result.map((r) => tagValue(r, source)) : tagValue(result, source);
11874
11825
  }
11875
- /**
11876
- * Converts a full JSON Schema to TypeScript interface properties
11877
- * @param schema - JSON Schema object
11878
- * @param depth - Current recursion depth (prevents infinite recursion)
11879
- * @returns TypeScript interface properties string
11880
- */
11881
- jsonSchemaToTSInterface(schema, depth = 0) {
11882
- if (depth > 3) {
11883
- return " [key: string]: unknown;\n";
11884
- }
11885
- if (schema.type === "array" && schema.items) {
11886
- const itemType = this.schemaToTSType(schema.items, depth + 1);
11887
- return ` [index: number]: ${itemType};
11888
- length: number;
11889
- `;
11890
- }
11891
- if (schema.type === "object" && schema.properties) {
11892
- const required = schema.required || [];
11893
- let result = "";
11894
- for (const [key, value] of Object.entries(schema.properties)) {
11895
- const prop = value;
11896
- const optional = required.includes(key) ? "" : "?";
11897
- const tsType = this.schemaToTSType(prop, depth + 1);
11898
- result += ` ${key}${optional}: ${tsType};
11899
- `;
11900
- }
11901
- return result || " [key: string]: unknown;\n";
11902
- }
11903
- return " [key: string]: unknown;\n";
11826
+ if (callbackRecord.type === "tool") {
11827
+ const source = {
11828
+ type: atpProvenance.ProvenanceSource.TOOL,
11829
+ toolName: callbackRecord.payload?.toolName || "clientTool",
11830
+ apiGroup: callbackRecord.payload?.namespace || "client",
11831
+ timestamp: Date.now()
11832
+ };
11833
+ return Array.isArray(result) ? result.map((r) => tagValue(r, source)) : tagValue(result, source);
11904
11834
  }
11905
- /**
11906
- * Converts any JSON Schema to a TypeScript type expression
11907
- * @param schema - JSON Schema object
11908
- * @param depth - Current recursion depth
11909
- * @returns TypeScript type expression
11910
- */
11911
- schemaToTSType(schema, depth = 0) {
11912
- if (!schema) return "unknown";
11913
- if (depth > 3) {
11914
- return "unknown";
11915
- }
11916
- if (schema.type === "array") {
11917
- if (schema.items) {
11918
- const itemType = this.schemaToTSType(schema.items, depth + 1);
11919
- return `${itemType}[]`;
11920
- }
11921
- return "unknown[]";
11922
- }
11923
- if (schema.enum) {
11924
- return schema.enum.map((v) => `"${v}"`).join(" | ") || "string";
11925
- }
11926
- if (schema.type === "object" && schema.properties) {
11927
- const required = schema.required || [];
11928
- const props = [];
11929
- for (const [key, value] of Object.entries(schema.properties)) {
11930
- const prop = value;
11931
- const optional = required.includes(key) ? "" : "?";
11932
- const tsType = this.schemaToTSType(prop, depth + 1);
11933
- props.push(`${key}${optional}: ${tsType}`);
11934
- }
11935
- if (props.length > 0) {
11936
- return `{ ${props.join("; ")} }`;
11937
- }
11938
- return "Record<string, unknown>";
11939
- }
11940
- if (schema.type) {
11941
- return this.jsonSchemaTypeToTS(schema.type);
11835
+ return result;
11836
+ }
11837
+ __name(tagCallbackResult, "tagCallbackResult");
11838
+ async function handleResume(ctx, executionId, executor, stateManager, serverConfig, sessionManager) {
11839
+ const requestClientId = ctx.headers["x-client-id"] || ctx.clientId;
11840
+ const requestToken = ctx.headers["authorization"]?.replace("Bearer ", "");
11841
+ if (!requestClientId || !requestToken) {
11842
+ atpRuntime.log.warn("Resume attempt without authentication", {
11843
+ executionId
11844
+ });
11845
+ ctx.throw(401, "Authentication required");
11846
+ }
11847
+ ctx.clientId = requestClientId;
11848
+ if (sessionManager) {
11849
+ const isValid = await sessionManager.verifyClient(requestClientId, requestToken);
11850
+ if (!isValid) {
11851
+ atpRuntime.log.warn("Resume attempt with invalid token", {
11852
+ executionId,
11853
+ clientId: requestClientId
11854
+ });
11855
+ ctx.throw(403, "Invalid client credentials");
11942
11856
  }
11943
- return "unknown";
11944
11857
  }
11945
- /**
11946
- * Helper to check if a string is a valid JavaScript identifier
11947
- */
11948
- isValidIdentifier(name) {
11949
- return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
11858
+ const pausedState = await stateManager.get(executionId);
11859
+ if (!pausedState) {
11860
+ ctx.throw(404, "Not found");
11950
11861
  }
11951
- /**
11952
- * Helper to safely format a property name for TypeScript type definitions
11953
- * Returns the property name with quotes if needed, or just the name if valid
11954
- */
11955
- formatPropertyName(name) {
11956
- if (!this.isValidIdentifier(name)) {
11957
- return `'${name}'`;
11862
+ if (pausedState.clientId !== requestClientId) {
11863
+ atpRuntime.log.warn("Resume attempt by unauthorized client", {
11864
+ executionId,
11865
+ requestClientId,
11866
+ ownerClientId: pausedState.clientId
11867
+ });
11868
+ ctx.throw(403, "Unauthorized: execution belongs to different client");
11869
+ }
11870
+ atpRuntime.log.info("Resume authorized", {
11871
+ executionId,
11872
+ clientId: requestClientId
11873
+ });
11874
+ if (pausedState.provenanceState && pausedState.config.provenanceMode && pausedState.config.provenanceMode !== atpProtocol.ProvenanceMode.NONE) {
11875
+ const state = pausedState.provenanceState;
11876
+ if ("primitives" in state) {
11877
+ atpProvenance.restoreProvenanceSnapshot(executionId, state);
11878
+ atpRuntime.log.info("Provenance snapshot restored", {
11879
+ executionId,
11880
+ registryEntries: state.registry.length,
11881
+ primitiveEntries: state.primitives.length
11882
+ });
11883
+ } else {
11884
+ const provenanceMap = new Map(state.registry);
11885
+ atpProvenance.restoreProvenanceSnapshot(executionId, {
11886
+ registry: state.registry,
11887
+ primitives: []
11888
+ });
11889
+ atpRuntime.log.info("Provenance state restored (legacy format)", {
11890
+ executionId,
11891
+ entries: provenanceMap.size
11892
+ });
11958
11893
  }
11959
- return name;
11960
11894
  }
11961
- /**
11962
- * Generates the API namespace with all function declarations.
11963
- * Handles hierarchical group names (e.g., "github/readOnly" -> api.github.readOnly)
11964
- * @param groups - API groups to include
11965
- * @returns TypeScript definition string
11966
- */
11967
- generateAPINamespace(groups) {
11968
- const rootGroups = /* @__PURE__ */ new Map();
11969
- for (const group of groups) {
11970
- if (!group.functions || group.functions.length === 0) continue;
11971
- const parts = group.name.split("/");
11972
- let current = rootGroups;
11973
- for (let i = 0; i < parts.length; i++) {
11974
- const part = parts[i];
11975
- if (!current.has(part)) {
11976
- current.set(part, {
11977
- functions: [],
11978
- subgroups: /* @__PURE__ */ new Map()
11895
+ const request = ctx.body;
11896
+ let updatedHistory;
11897
+ let callbackResult;
11898
+ const lastRecord = pausedState.callbackHistory[pausedState.currentCallbackIndex];
11899
+ if (!lastRecord) {
11900
+ atpRuntime.log.error("No callback record found at current index", {
11901
+ executionId,
11902
+ currentIndex: pausedState.currentCallbackIndex
11903
+ });
11904
+ ctx.throw(500, "Invalid paused state: no callback record");
11905
+ }
11906
+ if (request.results) {
11907
+ const batchResults = request.results;
11908
+ atpRuntime.log.info("Processing batch callback results", {
11909
+ executionId,
11910
+ batchCount: batchResults.length
11911
+ });
11912
+ for (const br of batchResults) {
11913
+ if (br.result && typeof br.result === "object" && "__error" in br.result) {
11914
+ const errorObj = br.result;
11915
+ if (errorObj.message && errorObj.message.includes("service not provided")) {
11916
+ atpRuntime.log.error("Service provider error in batch", {
11917
+ executionId,
11918
+ error: errorObj.message
11979
11919
  });
11920
+ await stateManager.delete(executionId);
11921
+ return {
11922
+ executionId,
11923
+ status: atpProtocol.ExecutionStatus.FAILED,
11924
+ error: {
11925
+ message: errorObj.message || "Service not available",
11926
+ code: "SERVICE_NOT_PROVIDED"
11927
+ },
11928
+ stats: {
11929
+ duration: 0,
11930
+ memoryUsed: 0,
11931
+ llmCallsCount: 0,
11932
+ approvalCallsCount: 0
11933
+ }
11934
+ };
11980
11935
  }
11981
- const node = current.get(part);
11982
- if (i === parts.length - 1) {
11983
- node.functions.push(...group.functions);
11984
- }
11985
- current = node.subgroups;
11986
11936
  }
11987
11937
  }
11988
- const generateLevel = /* @__PURE__ */ __name((groups2, indent2) => {
11989
- let ts = "";
11990
- for (const [name, node] of groups2.entries()) {
11991
- if (!name) continue;
11992
- const formattedName = this.formatPropertyName(name);
11993
- ts += `${indent2}${formattedName}: {
11994
- `;
11995
- for (const func of node.functions) {
11996
- if (!func.name) continue;
11997
- const funcName = this.formatPropertyName(func.name);
11998
- const description = func.description && typeof func.description === "string" ? func.description.replace(/\n/g, " ").substring(0, 200) : "";
11999
- ts += `${indent2} /**
12000
- ${indent2} * ${description}
12001
- ${indent2} */
12002
- `;
12003
- ts += `${indent2} ${funcName}(params: ${func.name}_Input): Promise<${func.name}_Output>;
12004
- `;
12005
- }
12006
- if (node.subgroups.size > 0) {
12007
- ts += generateLevel(node.subgroups, indent2 + " ");
12008
- }
12009
- ts += `${indent2}};
12010
- `;
11938
+ const taggedBatchResults = batchResults.map((br) => ({
11939
+ ...br,
11940
+ result: tagCallbackResult(lastRecord, br.result, pausedState.config.provenanceMode)
11941
+ }));
11942
+ callbackResult = taggedBatchResults.map((br) => br.result);
11943
+ updatedHistory = pausedState.callbackHistory.map((record, index) => {
11944
+ if (index === pausedState.currentCallbackIndex) {
11945
+ return {
11946
+ ...record,
11947
+ result: callbackResult
11948
+ };
12011
11949
  }
12012
- return ts;
12013
- }, "generateLevel");
12014
- let typescript = `
12015
- declare const api: {
12016
- `;
12017
- typescript += generateLevel(rootGroups, " ");
12018
- typescript += `};
12019
- `;
12020
- typescript += `
12021
- export { api };
12022
- `;
12023
- return typescript;
11950
+ return record;
11951
+ });
11952
+ } else {
11953
+ const rawResult = request.result;
11954
+ if (rawResult && typeof rawResult === "object" && "__error" in rawResult) {
11955
+ const errorObj = rawResult;
11956
+ if (errorObj.message && errorObj.message.includes("service not provided")) {
11957
+ atpRuntime.log.error("Service provider error", {
11958
+ executionId,
11959
+ error: errorObj.message
11960
+ });
11961
+ await stateManager.delete(executionId);
11962
+ return {
11963
+ executionId,
11964
+ status: atpProtocol.ExecutionStatus.FAILED,
11965
+ error: {
11966
+ message: errorObj.message || "Service not available",
11967
+ code: "SERVICE_NOT_PROVIDED"
11968
+ },
11969
+ stats: {
11970
+ duration: 0,
11971
+ memoryUsed: 0,
11972
+ llmCallsCount: 0,
11973
+ approvalCallsCount: 0
11974
+ }
11975
+ };
11976
+ }
11977
+ }
11978
+ callbackResult = tagCallbackResult(lastRecord, rawResult, pausedState.config.provenanceMode);
11979
+ updatedHistory = pausedState.callbackHistory.map((record, index) => {
11980
+ if (index === pausedState.currentCallbackIndex) {
11981
+ return {
11982
+ ...record,
11983
+ result: callbackResult
11984
+ };
11985
+ }
11986
+ return record;
11987
+ });
12024
11988
  }
12025
- /**
12026
- * Gets the list of available API group names.
12027
- * @returns Array of API group names
12028
- */
12029
- getApiGroups() {
12030
- return this.apiGroups.map((g) => g.name);
11989
+ const restoredConfig = {
11990
+ ...pausedState.config,
11991
+ securityPolicies: serverConfig.execution.securityPolicies || []
11992
+ };
11993
+ const result = await executor.execute(pausedState.code, restoredConfig, pausedState.clientId, {
11994
+ callbackHistory: updatedHistory,
11995
+ newCallbackResult: callbackResult,
11996
+ executionId
11997
+ });
11998
+ if (result.status === atpProtocol.ExecutionStatus.PAUSED && result.needsCallbacks && result.callbackHistory) {
11999
+ const provenanceState = pausedState.config.provenanceMode && pausedState.config.provenanceMode !== atpProtocol.ProvenanceMode.NONE ? atpProvenance.captureProvenanceSnapshot(result.executionId) : void 0;
12000
+ const codeToSave = result.transformedCode || pausedState.code;
12001
+ await stateManager.pause({
12002
+ executionId: result.executionId,
12003
+ code: codeToSave,
12004
+ config: pausedState.config,
12005
+ clientId: pausedState.clientId,
12006
+ callbackRequest: result.needsCallbacks[0],
12007
+ pausedAt: Date.now(),
12008
+ callbackHistory: result.callbackHistory,
12009
+ currentCallbackIndex: result.callbackHistory.length - 1,
12010
+ context: {},
12011
+ provenanceState
12012
+ });
12013
+ } else if (result.status === atpProtocol.ExecutionStatus.PAUSED && result.needsCallback && result.callbackHistory) {
12014
+ const provenanceState = pausedState.config.provenanceMode && pausedState.config.provenanceMode !== atpProtocol.ProvenanceMode.NONE ? atpProvenance.captureProvenanceSnapshot(result.executionId) : void 0;
12015
+ const codeToSave = result.transformedCode || pausedState.code;
12016
+ await stateManager.pause({
12017
+ executionId: result.executionId,
12018
+ code: codeToSave,
12019
+ config: pausedState.config,
12020
+ clientId: pausedState.clientId,
12021
+ callbackRequest: result.needsCallback,
12022
+ pausedAt: Date.now(),
12023
+ callbackHistory: result.callbackHistory,
12024
+ currentCallbackIndex: result.callbackHistory.length - 1,
12025
+ context: {},
12026
+ provenanceState
12027
+ });
12028
+ } else {
12029
+ await stateManager.delete(executionId);
12031
12030
  }
12032
- };
12031
+ return result;
12032
+ }
12033
+ __name(handleResume, "handleResume");
12033
12034
 
12034
12035
  // src/handlers/definitions.handler.ts
12035
12036
  async function getDefinitions(apiGroups) {