@mondaydotcomorg/atp-server 0.17.14

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 (307) hide show
  1. package/README.md +489 -0
  2. package/dist/aggregator/index.d.ts +59 -0
  3. package/dist/aggregator/index.d.ts.map +1 -0
  4. package/dist/aggregator/index.js +171 -0
  5. package/dist/aggregator/index.js.map +1 -0
  6. package/dist/callback/index.d.ts +98 -0
  7. package/dist/callback/index.d.ts.map +1 -0
  8. package/dist/callback/index.js +136 -0
  9. package/dist/callback/index.js.map +1 -0
  10. package/dist/client-sessions.d.ts +82 -0
  11. package/dist/client-sessions.d.ts.map +1 -0
  12. package/dist/client-sessions.js +174 -0
  13. package/dist/client-sessions.js.map +1 -0
  14. package/dist/controllers/definitions.controller.d.ts +4 -0
  15. package/dist/controllers/definitions.controller.d.ts.map +1 -0
  16. package/dist/controllers/definitions.controller.js +11 -0
  17. package/dist/controllers/definitions.controller.js.map +1 -0
  18. package/dist/controllers/execute.controller.d.ts +18 -0
  19. package/dist/controllers/execute.controller.d.ts.map +1 -0
  20. package/dist/controllers/execute.controller.js +122 -0
  21. package/dist/controllers/execute.controller.js.map +1 -0
  22. package/dist/controllers/info.controller.d.ts +3 -0
  23. package/dist/controllers/info.controller.d.ts.map +1 -0
  24. package/dist/controllers/info.controller.js +13 -0
  25. package/dist/controllers/info.controller.js.map +1 -0
  26. package/dist/controllers/resume.controller.d.ts +11 -0
  27. package/dist/controllers/resume.controller.d.ts.map +1 -0
  28. package/dist/controllers/resume.controller.js +61 -0
  29. package/dist/controllers/resume.controller.js.map +1 -0
  30. package/dist/controllers/search.controller.d.ts +4 -0
  31. package/dist/controllers/search.controller.d.ts.map +1 -0
  32. package/dist/controllers/search.controller.js +7 -0
  33. package/dist/controllers/search.controller.js.map +1 -0
  34. package/dist/controllers/stream.controller.d.ts +19 -0
  35. package/dist/controllers/stream.controller.d.ts.map +1 -0
  36. package/dist/controllers/stream.controller.js +141 -0
  37. package/dist/controllers/stream.controller.js.map +1 -0
  38. package/dist/core/config.d.ts +161 -0
  39. package/dist/core/config.d.ts.map +1 -0
  40. package/dist/core/config.js +7 -0
  41. package/dist/core/config.js.map +1 -0
  42. package/dist/core/http.d.ts +4 -0
  43. package/dist/core/http.d.ts.map +1 -0
  44. package/dist/core/http.js +17 -0
  45. package/dist/core/http.js.map +1 -0
  46. package/dist/create-server.d.ts +120 -0
  47. package/dist/create-server.d.ts.map +1 -0
  48. package/dist/create-server.js +423 -0
  49. package/dist/create-server.js.map +1 -0
  50. package/dist/execution-state/index.d.ts +95 -0
  51. package/dist/execution-state/index.d.ts.map +1 -0
  52. package/dist/execution-state/index.js +128 -0
  53. package/dist/execution-state/index.js.map +1 -0
  54. package/dist/executor/ast-provenance-bridge.d.ts +12 -0
  55. package/dist/executor/ast-provenance-bridge.d.ts.map +1 -0
  56. package/dist/executor/ast-provenance-bridge.js +66 -0
  57. package/dist/executor/ast-provenance-bridge.js.map +1 -0
  58. package/dist/executor/ast-tracking-runtime.d.ts +7 -0
  59. package/dist/executor/ast-tracking-runtime.d.ts.map +1 -0
  60. package/dist/executor/ast-tracking-runtime.js +559 -0
  61. package/dist/executor/ast-tracking-runtime.js.map +1 -0
  62. package/dist/executor/bootstrap-generated.d.ts +32 -0
  63. package/dist/executor/bootstrap-generated.d.ts.map +1 -0
  64. package/dist/executor/bootstrap-generated.js +90 -0
  65. package/dist/executor/bootstrap-generated.js.map +1 -0
  66. package/dist/executor/compiler-config.d.ts +32 -0
  67. package/dist/executor/compiler-config.d.ts.map +1 -0
  68. package/dist/executor/compiler-config.js +99 -0
  69. package/dist/executor/compiler-config.js.map +1 -0
  70. package/dist/executor/constants.d.ts +4 -0
  71. package/dist/executor/constants.d.ts.map +1 -0
  72. package/dist/executor/constants.js +4 -0
  73. package/dist/executor/constants.js.map +1 -0
  74. package/dist/executor/error-handler.d.ts +9 -0
  75. package/dist/executor/error-handler.d.ts.map +1 -0
  76. package/dist/executor/error-handler.js +95 -0
  77. package/dist/executor/error-handler.js.map +1 -0
  78. package/dist/executor/execution-error-handler.d.ts +7 -0
  79. package/dist/executor/execution-error-handler.d.ts.map +1 -0
  80. package/dist/executor/execution-error-handler.js +136 -0
  81. package/dist/executor/execution-error-handler.js.map +1 -0
  82. package/dist/executor/executor.d.ts +20 -0
  83. package/dist/executor/executor.d.ts.map +1 -0
  84. package/dist/executor/executor.js +452 -0
  85. package/dist/executor/executor.js.map +1 -0
  86. package/dist/executor/index.d.ts +4 -0
  87. package/dist/executor/index.d.ts.map +1 -0
  88. package/dist/executor/index.js +3 -0
  89. package/dist/executor/index.js.map +1 -0
  90. package/dist/executor/resume-handler.d.ts +9 -0
  91. package/dist/executor/resume-handler.d.ts.map +1 -0
  92. package/dist/executor/resume-handler.js +22 -0
  93. package/dist/executor/resume-handler.js.map +1 -0
  94. package/dist/executor/sandbox-builder.d.ts +29 -0
  95. package/dist/executor/sandbox-builder.d.ts.map +1 -0
  96. package/dist/executor/sandbox-builder.js +538 -0
  97. package/dist/executor/sandbox-builder.js.map +1 -0
  98. package/dist/executor/sandbox-injector.d.ts +7 -0
  99. package/dist/executor/sandbox-injector.d.ts.map +1 -0
  100. package/dist/executor/sandbox-injector.js +293 -0
  101. package/dist/executor/sandbox-injector.js.map +1 -0
  102. package/dist/executor/types.d.ts +21 -0
  103. package/dist/executor/types.d.ts.map +1 -0
  104. package/dist/executor/types.js +2 -0
  105. package/dist/executor/types.js.map +1 -0
  106. package/dist/explorer/index.d.ts +69 -0
  107. package/dist/explorer/index.d.ts.map +1 -0
  108. package/dist/explorer/index.js +228 -0
  109. package/dist/explorer/index.js.map +1 -0
  110. package/dist/handlers/definitions.handler.d.ts +3 -0
  111. package/dist/handlers/definitions.handler.d.ts.map +1 -0
  112. package/dist/handlers/definitions.handler.js +11 -0
  113. package/dist/handlers/definitions.handler.js.map +1 -0
  114. package/dist/handlers/execute.handler.d.ts +7 -0
  115. package/dist/handlers/execute.handler.d.ts.map +1 -0
  116. package/dist/handlers/execute.handler.js +225 -0
  117. package/dist/handlers/execute.handler.js.map +1 -0
  118. package/dist/handlers/explorer.handler.d.ts +4 -0
  119. package/dist/handlers/explorer.handler.d.ts.map +1 -0
  120. package/dist/handlers/explorer.handler.js +10 -0
  121. package/dist/handlers/explorer.handler.js.map +1 -0
  122. package/dist/handlers/init.handler.d.ts +5 -0
  123. package/dist/handlers/init.handler.d.ts.map +1 -0
  124. package/dist/handlers/init.handler.js +41 -0
  125. package/dist/handlers/init.handler.js.map +1 -0
  126. package/dist/handlers/resume.handler.d.ts +6 -0
  127. package/dist/handlers/resume.handler.d.ts.map +1 -0
  128. package/dist/handlers/resume.handler.js +256 -0
  129. package/dist/handlers/resume.handler.js.map +1 -0
  130. package/dist/handlers/search.handler.d.ts +5 -0
  131. package/dist/handlers/search.handler.d.ts.map +1 -0
  132. package/dist/handlers/search.handler.js +11 -0
  133. package/dist/handlers/search.handler.js.map +1 -0
  134. package/dist/http/request-handler.d.ts +15 -0
  135. package/dist/http/request-handler.d.ts.map +1 -0
  136. package/dist/http/request-handler.js +94 -0
  137. package/dist/http/request-handler.js.map +1 -0
  138. package/dist/http/router.d.ts +4 -0
  139. package/dist/http/router.d.ts.map +1 -0
  140. package/dist/http/router.js +32 -0
  141. package/dist/http/router.js.map +1 -0
  142. package/dist/index.d.ts +10 -0
  143. package/dist/index.d.ts.map +1 -0
  144. package/dist/index.js +8 -0
  145. package/dist/index.js.map +1 -0
  146. package/dist/instrumentation/index.d.ts +5 -0
  147. package/dist/instrumentation/index.d.ts.map +1 -0
  148. package/dist/instrumentation/index.js +5 -0
  149. package/dist/instrumentation/index.js.map +1 -0
  150. package/dist/instrumentation/serializer.d.ts +61 -0
  151. package/dist/instrumentation/serializer.d.ts.map +1 -0
  152. package/dist/instrumentation/serializer.js +334 -0
  153. package/dist/instrumentation/serializer.js.map +1 -0
  154. package/dist/instrumentation/state-manager.d.ts +61 -0
  155. package/dist/instrumentation/state-manager.d.ts.map +1 -0
  156. package/dist/instrumentation/state-manager.js +205 -0
  157. package/dist/instrumentation/state-manager.js.map +1 -0
  158. package/dist/instrumentation/transformer.d.ts +9 -0
  159. package/dist/instrumentation/transformer.d.ts.map +1 -0
  160. package/dist/instrumentation/transformer.js +70 -0
  161. package/dist/instrumentation/transformer.js.map +1 -0
  162. package/dist/instrumentation/types.d.ts +59 -0
  163. package/dist/instrumentation/types.d.ts.map +1 -0
  164. package/dist/instrumentation/types.js +5 -0
  165. package/dist/instrumentation/types.js.map +1 -0
  166. package/dist/middleware/audit.d.ts +18 -0
  167. package/dist/middleware/audit.d.ts.map +1 -0
  168. package/dist/middleware/audit.js +76 -0
  169. package/dist/middleware/audit.js.map +1 -0
  170. package/dist/openapi/index.d.ts +133 -0
  171. package/dist/openapi/index.d.ts.map +1 -0
  172. package/dist/openapi/index.js +235 -0
  173. package/dist/openapi/index.js.map +1 -0
  174. package/dist/openapi-loader.d.ts +87 -0
  175. package/dist/openapi-loader.d.ts.map +1 -0
  176. package/dist/openapi-loader.js +491 -0
  177. package/dist/openapi-loader.js.map +1 -0
  178. package/dist/routes/index.d.ts +21 -0
  179. package/dist/routes/index.d.ts.map +1 -0
  180. package/dist/routes/index.js +47 -0
  181. package/dist/routes/index.js.map +1 -0
  182. package/dist/search/index.d.ts +48 -0
  183. package/dist/search/index.d.ts.map +1 -0
  184. package/dist/search/index.js +156 -0
  185. package/dist/search/index.js.map +1 -0
  186. package/dist/security/index.d.ts +2 -0
  187. package/dist/security/index.d.ts.map +1 -0
  188. package/dist/security/index.js +2 -0
  189. package/dist/security/index.js.map +1 -0
  190. package/dist/shutdown.d.ts +19 -0
  191. package/dist/shutdown.d.ts.map +1 -0
  192. package/dist/shutdown.js +87 -0
  193. package/dist/shutdown.js.map +1 -0
  194. package/dist/utils/banner.d.ts +12 -0
  195. package/dist/utils/banner.d.ts.map +1 -0
  196. package/dist/utils/banner.js +18 -0
  197. package/dist/utils/banner.js.map +1 -0
  198. package/dist/utils/context.d.ts +16 -0
  199. package/dist/utils/context.d.ts.map +1 -0
  200. package/dist/utils/context.js +44 -0
  201. package/dist/utils/context.js.map +1 -0
  202. package/dist/utils/error.d.ts +8 -0
  203. package/dist/utils/error.d.ts.map +1 -0
  204. package/dist/utils/error.js +17 -0
  205. package/dist/utils/error.js.map +1 -0
  206. package/dist/utils/hint-based-instrumentation.d.ts +14 -0
  207. package/dist/utils/hint-based-instrumentation.d.ts.map +1 -0
  208. package/dist/utils/hint-based-instrumentation.js +84 -0
  209. package/dist/utils/hint-based-instrumentation.js.map +1 -0
  210. package/dist/utils/index.d.ts +8 -0
  211. package/dist/utils/index.d.ts.map +1 -0
  212. package/dist/utils/index.js +8 -0
  213. package/dist/utils/index.js.map +1 -0
  214. package/dist/utils/info.d.ts +20 -0
  215. package/dist/utils/info.d.ts.map +1 -0
  216. package/dist/utils/info.js +15 -0
  217. package/dist/utils/info.js.map +1 -0
  218. package/dist/utils/provenance-reattachment.d.ts +32 -0
  219. package/dist/utils/provenance-reattachment.d.ts.map +1 -0
  220. package/dist/utils/provenance-reattachment.js +115 -0
  221. package/dist/utils/provenance-reattachment.js.map +1 -0
  222. package/dist/utils/request.d.ts +21 -0
  223. package/dist/utils/request.d.ts.map +1 -0
  224. package/dist/utils/request.js +44 -0
  225. package/dist/utils/request.js.map +1 -0
  226. package/dist/utils/response.d.ts +30 -0
  227. package/dist/utils/response.d.ts.map +1 -0
  228. package/dist/utils/response.js +53 -0
  229. package/dist/utils/response.js.map +1 -0
  230. package/dist/utils/runtime-types.d.ts +6 -0
  231. package/dist/utils/runtime-types.d.ts.map +1 -0
  232. package/dist/utils/runtime-types.js +14 -0
  233. package/dist/utils/runtime-types.js.map +1 -0
  234. package/dist/utils/schema.d.ts +9 -0
  235. package/dist/utils/schema.d.ts.map +1 -0
  236. package/dist/utils/schema.js +13 -0
  237. package/dist/utils/schema.js.map +1 -0
  238. package/dist/utils/token-emitter.d.ts +21 -0
  239. package/dist/utils/token-emitter.d.ts.map +1 -0
  240. package/dist/utils/token-emitter.js +129 -0
  241. package/dist/utils/token-emitter.js.map +1 -0
  242. package/dist/validator/index.d.ts +36 -0
  243. package/dist/validator/index.d.ts.map +1 -0
  244. package/dist/validator/index.js +224 -0
  245. package/dist/validator/index.js.map +1 -0
  246. package/package.json +68 -0
  247. package/src/aggregator/index.ts +207 -0
  248. package/src/callback/index.ts +191 -0
  249. package/src/client-sessions.ts +234 -0
  250. package/src/controllers/definitions.controller.ts +19 -0
  251. package/src/controllers/execute.controller.ts +166 -0
  252. package/src/controllers/info.controller.ts +14 -0
  253. package/src/controllers/resume.controller.ts +92 -0
  254. package/src/controllers/search.controller.ts +16 -0
  255. package/src/controllers/stream.controller.ts +190 -0
  256. package/src/core/config.ts +180 -0
  257. package/src/core/http.ts +21 -0
  258. package/src/create-server.ts +536 -0
  259. package/src/execution-state/index.ts +204 -0
  260. package/src/executor/ast-provenance-bridge.ts +80 -0
  261. package/src/executor/ast-tracking-runtime.ts +558 -0
  262. package/src/executor/bootstrap-generated.ts +90 -0
  263. package/src/executor/compiler-config.ts +146 -0
  264. package/src/executor/constants.ts +5 -0
  265. package/src/executor/error-handler.ts +118 -0
  266. package/src/executor/execution-error-handler.ts +178 -0
  267. package/src/executor/executor.ts +631 -0
  268. package/src/executor/index.ts +3 -0
  269. package/src/executor/resume-handler.ts +39 -0
  270. package/src/executor/sandbox-builder.ts +684 -0
  271. package/src/executor/sandbox-injector.ts +345 -0
  272. package/src/executor/types.ts +22 -0
  273. package/src/explorer/index.ts +297 -0
  274. package/src/handlers/definitions.handler.ts +13 -0
  275. package/src/handlers/execute.handler.ts +286 -0
  276. package/src/handlers/explorer.handler.ts +18 -0
  277. package/src/handlers/init.handler.ts +53 -0
  278. package/src/handlers/resume.handler.ts +316 -0
  279. package/src/handlers/search.handler.ts +32 -0
  280. package/src/http/request-handler.ts +117 -0
  281. package/src/http/router.ts +29 -0
  282. package/src/index.ts +60 -0
  283. package/src/instrumentation/index.ts +4 -0
  284. package/src/instrumentation/serializer.ts +421 -0
  285. package/src/instrumentation/state-manager.ts +237 -0
  286. package/src/instrumentation/transformer.ts +84 -0
  287. package/src/instrumentation/types.ts +76 -0
  288. package/src/middleware/audit.ts +101 -0
  289. package/src/openapi/index.ts +378 -0
  290. package/src/openapi-loader.ts +744 -0
  291. package/src/routes/index.ts +93 -0
  292. package/src/search/index.ts +216 -0
  293. package/src/security/index.ts +1 -0
  294. package/src/shutdown.ts +108 -0
  295. package/src/utils/banner.ts +25 -0
  296. package/src/utils/context.ts +58 -0
  297. package/src/utils/error.ts +25 -0
  298. package/src/utils/hint-based-instrumentation.ts +99 -0
  299. package/src/utils/index.ts +15 -0
  300. package/src/utils/info.ts +31 -0
  301. package/src/utils/provenance-reattachment.ts +144 -0
  302. package/src/utils/request.ts +53 -0
  303. package/src/utils/response.ts +69 -0
  304. package/src/utils/runtime-types.ts +14 -0
  305. package/src/utils/schema.ts +18 -0
  306. package/src/utils/token-emitter.ts +182 -0
  307. package/src/validator/index.ts +253 -0
@@ -0,0 +1,345 @@
1
+ import ivm from 'isolated-vm';
2
+ import type { Logger } from '@mondaydotcomorg/atp-runtime';
3
+ import { isPauseError, runInExecutionContext } from '@mondaydotcomorg/atp-runtime';
4
+ import { isBatchPauseError } from '@mondaydotcomorg/atp-compiler';
5
+ import { PAUSE_EXECUTION_MARKER } from './constants.js';
6
+
7
+ export async function injectTimerPolyfills(ivmContext: ivm.Context): Promise<void> {
8
+ await ivmContext.eval(`
9
+ globalThis._timerCounter = 1;
10
+ globalThis._activeTimers = new Map();
11
+
12
+ globalThis.setTimeout = function(callback, delay) {
13
+ const timerId = globalThis._timerCounter++;
14
+ const startTime = Date.now();
15
+
16
+ const pollTimer = () => {
17
+ if (!globalThis._activeTimers.has(timerId)) {
18
+ return;
19
+ }
20
+
21
+ if (Date.now() - startTime >= delay) {
22
+ globalThis._activeTimers.delete(timerId);
23
+ callback();
24
+ } else {
25
+ Promise.resolve().then(pollTimer);
26
+ }
27
+ };
28
+
29
+ globalThis._activeTimers.set(timerId, true);
30
+ Promise.resolve().then(pollTimer);
31
+ return timerId;
32
+ };
33
+
34
+ globalThis.clearTimeout = function(timerId) {
35
+ globalThis._activeTimers.delete(timerId);
36
+ };
37
+ `);
38
+ }
39
+
40
+ export async function injectSandbox(
41
+ ivmContext: ivm.Context,
42
+ jail: ivm.Reference<Record<string, unknown>>,
43
+ sandbox: Record<string, unknown>,
44
+ executionLogger: Logger,
45
+ onPauseError: (error: unknown) => void,
46
+ executionId?: string,
47
+ provenanceMode?: string,
48
+ hintMetadata?: Map<string, any>
49
+ ): Promise<void> {
50
+ const injectFunctions = async (obj: unknown, prefix: string): Promise<void> => {
51
+ if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
52
+ return;
53
+ }
54
+
55
+ for (const [key, value] of Object.entries(obj)) {
56
+ if (typeof value === 'function') {
57
+ const boundFunc = value.bind(obj);
58
+
59
+ const isVoidFunction =
60
+ prefix === 'atp_log' || prefix === 'atp_progress' || prefix === 'atp_output';
61
+
62
+ if (isVoidFunction) {
63
+ await jail.set(
64
+ `__${prefix}_${key}`,
65
+ new ivm.Reference((...args: unknown[]) => {
66
+ try {
67
+ boundFunc(...args);
68
+ } catch (error) {
69
+ executionLogger.error('Error in void function', { prefix, key, error });
70
+ }
71
+ })
72
+ );
73
+ } else {
74
+ await jail.set(
75
+ `__${prefix}_${key}`,
76
+ new ivm.Reference(async (...args: unknown[]) => {
77
+ try {
78
+ const result = await boundFunc(...args);
79
+ return new ivm.ExternalCopy(result).copyInto();
80
+ } catch (error) {
81
+ const err = error as Error;
82
+ if (isPauseError(error) || err.message === PAUSE_EXECUTION_MARKER) {
83
+ if (isPauseError(error)) {
84
+ onPauseError(error);
85
+ }
86
+ throw new Error(PAUSE_EXECUTION_MARKER);
87
+ }
88
+ throw error;
89
+ }
90
+ })
91
+ );
92
+ }
93
+ } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
94
+ await injectFunctions(value, `${prefix}_${key}`);
95
+ }
96
+ }
97
+ };
98
+
99
+ const injectAPIFunctions = async (obj: unknown, pathPrefix: string): Promise<void> => {
100
+ if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
101
+ return;
102
+ }
103
+
104
+ for (const [key, value] of Object.entries(obj)) {
105
+ const newPath = pathPrefix ? `${pathPrefix}_${key}` : key;
106
+
107
+ if (typeof value === 'function') {
108
+ const boundFunc = value.bind(obj);
109
+ const safeName = newPath.replace(/-/g, '_').replace(/\//g, '_').replace(/\./g, '_');
110
+
111
+ await jail.set(
112
+ `__api_${safeName}`,
113
+ new ivm.Reference(async (...args: unknown[]) => {
114
+ try {
115
+ const result = await boundFunc(...args);
116
+ // In AST mode, tag result with provenance ID before copying so tag survives
117
+ if (isASTMode && result && typeof result === 'object') {
118
+ try {
119
+ // Generate unique ID for this API result
120
+ const provId = `tracked_${Date.now()}_${Math.random().toString(36).substring(7)}`;
121
+ Object.defineProperty(result, '__prov_id__', {
122
+ value: provId,
123
+ writable: false,
124
+ enumerable: true,
125
+ configurable: true,
126
+ });
127
+ } catch (e) {
128
+ // If can't define property, that's ok
129
+ }
130
+ }
131
+ return new ivm.ExternalCopy(result).copyInto();
132
+ } catch (error) {
133
+ const err = error as Error;
134
+ if (isPauseError(error) || err.message === PAUSE_EXECUTION_MARKER) {
135
+ if (isPauseError(error)) {
136
+ onPauseError(error);
137
+ }
138
+ throw new Error(PAUSE_EXECUTION_MARKER);
139
+ }
140
+ throw error;
141
+ }
142
+ })
143
+ );
144
+ } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
145
+ await injectAPIFunctions(value, newPath);
146
+ }
147
+ }
148
+ };
149
+
150
+ const isASTMode = provenanceMode === 'ast';
151
+ if (isASTMode) {
152
+ if (hintMetadata && hintMetadata.size > 0) {
153
+ const hintsArray = Array.from(hintMetadata.entries());
154
+ await jail.set('__provenance_hints', new ivm.ExternalCopy(hintsArray).copyInto());
155
+ const valueMap = (hintMetadata as any).__valueMap;
156
+ if (valueMap && valueMap.size > 0) {
157
+ const valueMapArray = Array.from(valueMap.entries());
158
+ await jail.set('__provenance_hint_values', new ivm.ExternalCopy(valueMapArray).copyInto());
159
+ }
160
+ }
161
+ const { AST_TRACKING_RUNTIME } = await import('./ast-tracking-runtime.js');
162
+ await ivmContext.eval(AST_TRACKING_RUNTIME);
163
+ executionLogger.info('AST tracking runtime injected into isolate');
164
+ }
165
+
166
+ const hasASTTracking = isASTMode;
167
+
168
+ for (const [namespace, value] of Object.entries(sandbox)) {
169
+ if (
170
+ hasASTTracking &&
171
+ (namespace.startsWith('__track') ||
172
+ namespace.startsWith('__get_provenance') ||
173
+ namespace.startsWith('__mark_tainted'))
174
+ ) {
175
+ continue;
176
+ }
177
+
178
+ if (namespace === '__runtime' && typeof value === 'object' && value !== null) {
179
+ for (const [key, fn] of Object.entries(value)) {
180
+ if (typeof fn === 'function') {
181
+ await jail.set(
182
+ `__runtime_${key}_impl`,
183
+ new ivm.Reference(async (...args: unknown[]) => {
184
+ try {
185
+ const execute = async () => {
186
+ const result = await fn(...args);
187
+ return new ivm.ExternalCopy(result).copyInto();
188
+ };
189
+
190
+ if (executionId) {
191
+ return await runInExecutionContext(executionId, execute);
192
+ } else {
193
+ return await execute();
194
+ }
195
+ } catch (error) {
196
+ const err = error as Error;
197
+ if (isBatchPauseError(error)) {
198
+ onPauseError(error);
199
+ throw new Error(PAUSE_EXECUTION_MARKER);
200
+ }
201
+ if (isPauseError(error) || err.message === PAUSE_EXECUTION_MARKER) {
202
+ if (isPauseError(error)) {
203
+ onPauseError(error);
204
+ }
205
+ throw new Error(PAUSE_EXECUTION_MARKER);
206
+ }
207
+ throw error;
208
+ }
209
+ })
210
+ );
211
+ }
212
+ }
213
+ } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
214
+ if (namespace === 'api') {
215
+ await injectAPIFunctions(value, '');
216
+ } else {
217
+ await injectFunctions(value, namespace);
218
+ }
219
+ }
220
+ }
221
+ }
222
+
223
+ export async function setupRuntimeNamespace(
224
+ ivmContext: ivm.Context,
225
+ sandbox: Record<string, unknown>
226
+ ): Promise<void> {
227
+ const runtimeObject = sandbox.__runtime as Record<string, unknown>;
228
+ if (!runtimeObject || typeof runtimeObject !== 'object') {
229
+ return;
230
+ }
231
+
232
+ const runtimeKeys = Object.keys(runtimeObject).filter(
233
+ (k) => typeof runtimeObject[k] === 'function'
234
+ );
235
+ if (runtimeKeys.length === 0) {
236
+ return;
237
+ }
238
+
239
+ let runtimeSetup = 'globalThis.__runtime = {\n';
240
+ runtimeSetup += runtimeKeys
241
+ .map(
242
+ (key) =>
243
+ `\t${key}: async (...args) => {\n\t\treturn await __runtime_${key}_impl.apply(undefined, args, { arguments: { copy: true }, result: { promise: true } });\n\t}`
244
+ )
245
+ .join(',\n');
246
+ runtimeSetup += '\n};';
247
+
248
+ await ivmContext.eval(runtimeSetup);
249
+ }
250
+
251
+ export async function setupAPINamespace(
252
+ ivmContext: ivm.Context,
253
+ sandbox: Record<string, unknown>,
254
+ provenanceMode?: string
255
+ ): Promise<void> {
256
+ const apiObject = sandbox.api as Record<string, unknown>;
257
+ if (!apiObject || typeof apiObject !== 'object') {
258
+ return;
259
+ }
260
+
261
+ const apiGroupNames = Object.keys(apiObject);
262
+ if (apiGroupNames.length === 0) {
263
+ return;
264
+ }
265
+
266
+ const isASTMode = provenanceMode === 'ast';
267
+ let apiSetup = 'globalThis.api = {};';
268
+
269
+ function setupNestedAPI(
270
+ obj: Record<string, unknown>,
271
+ pathPrefix: string,
272
+ accessPath: string
273
+ ): void {
274
+ for (const [key, value] of Object.entries(obj)) {
275
+ const newPath = pathPrefix ? `${pathPrefix}_${key}` : key;
276
+ const safeKey = JSON.stringify(key);
277
+ const newAccessPath = `${accessPath}[${safeKey}]`;
278
+
279
+ if (typeof value === 'function') {
280
+ const safeName = newPath.replace(/-/g, '_').replace(/\//g, '_').replace(/\./g, '_');
281
+
282
+ if (isASTMode) {
283
+ const toolNameEscaped = newPath.replace(/'/g, "\\'");
284
+ apiSetup += `
285
+ ${newAccessPath} = async function(...args) {
286
+ // In AST mode, recursively wrap arguments to preserve tainted primitive provenance
287
+ function wrapTaintedValues(obj, visited = new WeakSet()) {
288
+ if (obj === null || obj === undefined) return obj;
289
+
290
+ // If this is already a wrapped tainted value, don't wrap it again!
291
+ if (typeof obj === 'object' && '__tainted_value' in obj && '__prov_meta' in obj) {
292
+ return obj; // Return as-is, already wrapped
293
+ }
294
+
295
+ // Check if this value itself has provenance (primitive or object)
296
+ if (typeof globalThis.__check_provenance === 'function') {
297
+ const prov = globalThis.__check_provenance(obj);
298
+ if (prov && (typeof obj === 'string' || typeof obj === 'number')) {
299
+ // Wrap tainted primitive
300
+ return { __tainted_value: obj, __prov_meta: prov };
301
+ }
302
+ }
303
+
304
+ // For objects/arrays, recursively wrap their contents
305
+ if (typeof obj === 'object') {
306
+ if (visited.has(obj)) return obj; // Avoid circular refs
307
+ visited.add(obj);
308
+
309
+ if (Array.isArray(obj)) {
310
+ return obj.map(item => wrapTaintedValues(item, visited));
311
+ } else {
312
+ const wrapped = {};
313
+ for (const [key, val] of Object.entries(obj)) {
314
+ wrapped[key] = wrapTaintedValues(val, visited);
315
+ }
316
+ return wrapped;
317
+ }
318
+ }
319
+
320
+ return obj;
321
+ }
322
+
323
+ const wrappedArgs = args.map(arg => wrapTaintedValues(arg));
324
+ const result = await __api_${safeName}.apply(undefined, wrappedArgs, { arguments: { copy: true }, result: { promise: true } });
325
+ if (typeof globalThis.__track === 'function' && result !== null && result !== undefined) {
326
+ return globalThis.__track(result, { type: 'tool', tool: '${toolNameEscaped}', operation: 'read' }, []);
327
+ }
328
+ return result;
329
+ };`;
330
+ } else {
331
+ apiSetup += `
332
+ ${newAccessPath} = async function(...args) {
333
+ return await __api_${safeName}.apply(undefined, args, { arguments: { copy: true }, result: { promise: true } });
334
+ };`;
335
+ }
336
+ } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
337
+ apiSetup += `\n${newAccessPath} = {};`;
338
+ setupNestedAPI(value as Record<string, unknown>, newPath, newAccessPath);
339
+ }
340
+ }
341
+ }
342
+
343
+ setupNestedAPI(apiObject, '', 'globalThis.api');
344
+ await ivmContext.eval(apiSetup);
345
+ }
@@ -0,0 +1,22 @@
1
+ import type { CacheProvider } from '@mondaydotcomorg/atp-protocol';
2
+
3
+ export interface RuntimeContext {
4
+ llmCallCount: number;
5
+ approvalCallCount: number;
6
+ logs: string[];
7
+ startTime: number;
8
+ maxLLMCalls: number;
9
+ executionId: string;
10
+ clientId?: string;
11
+ hintMetadata?: Map<string, any>;
12
+ }
13
+
14
+ export interface ExecutorConfig {
15
+ defaultTimeout: number;
16
+ maxTimeout: number;
17
+ defaultMemoryLimit: number;
18
+ maxMemoryLimit: number;
19
+ defaultLLMCallLimit: number;
20
+ maxLLMCallLimit: number;
21
+ cacheProvider?: CacheProvider;
22
+ }
@@ -0,0 +1,297 @@
1
+ import type { APIGroupConfig, CustomFunctionDef } from '@mondaydotcomorg/atp-protocol';
2
+
3
+ interface TreeNode {
4
+ type: 'directory' | 'function';
5
+ name: string;
6
+ children?: Map<string, TreeNode>;
7
+ functionDef?: {
8
+ func: CustomFunctionDef;
9
+ group: string;
10
+ };
11
+ }
12
+
13
+ interface ExploreDirectoryResult {
14
+ type: 'directory';
15
+ path: string;
16
+ items: Array<{ name: string; type: 'directory' | 'function' }>;
17
+ }
18
+
19
+ interface ExploreFunctionResult {
20
+ type: 'function';
21
+ path: string;
22
+ name: string;
23
+ description: string;
24
+ definition: string;
25
+ group: string;
26
+ }
27
+
28
+ export type ExploreResult = ExploreDirectoryResult | ExploreFunctionResult;
29
+
30
+ /**
31
+ * ExplorerService provides filesystem-like navigation of API groups.
32
+ * Enables progressive discovery of APIs by allowing agents to explore
33
+ * tool hierarchies on-demand rather than loading everything upfront.
34
+ */
35
+ export class ExplorerService {
36
+ private root: TreeNode;
37
+
38
+ constructor(apiGroups: APIGroupConfig[]) {
39
+ this.root = { type: 'directory', name: '/', children: new Map() };
40
+ this.buildTree(apiGroups);
41
+ }
42
+
43
+ /**
44
+ * Builds the virtual filesystem tree from API groups
45
+ */
46
+ private buildTree(apiGroups: APIGroupConfig[]): void {
47
+ for (const group of apiGroups) {
48
+ if (!group.functions || group.functions.length === 0) continue;
49
+
50
+ const typeFolder = this.ensureDirectory(this.root, group.type);
51
+ const groupFolder = this.ensureDirectory(typeFolder, group.name);
52
+
53
+ for (const func of group.functions) {
54
+ const segments = this.extractSegments(func, group);
55
+
56
+ if (segments.length > 1) {
57
+ let current = groupFolder;
58
+ for (let i = 0; i < segments.length - 1; i++) {
59
+ current = this.ensureDirectory(current, segments[i]!);
60
+ }
61
+ this.addFunction(current, segments[segments.length - 1]!, func, group.name);
62
+ } else {
63
+ this.addFunction(groupFolder, func.name, func, group.name);
64
+ }
65
+ }
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Extract path segments for organizing functions
71
+ */
72
+ private extractSegments(func: CustomFunctionDef, group: APIGroupConfig): string[] {
73
+ if (group.type === 'openapi') {
74
+ const name = func.name;
75
+
76
+ const camelSplit = name.match(/[A-Z]?[a-z]+|[A-Z]+(?=[A-Z][a-z]|\b)/g);
77
+ if (camelSplit && camelSplit.length > 2) {
78
+ const verb = camelSplit[0].toLowerCase();
79
+ const isVerb = [
80
+ 'get',
81
+ 'list',
82
+ 'create',
83
+ 'update',
84
+ 'delete',
85
+ 'post',
86
+ 'put',
87
+ 'patch',
88
+ ].includes(verb);
89
+
90
+ if (isVerb) {
91
+ const resource = camelSplit.slice(1).join('_').toLowerCase();
92
+ return [resource, name];
93
+ }
94
+ }
95
+
96
+ if (name.includes('_')) {
97
+ const parts = name.split('_');
98
+ if (parts.length > 1 && parts[0]) {
99
+ return [parts[0], name];
100
+ }
101
+ }
102
+
103
+ if (name.includes('-')) {
104
+ const parts = name.split('-');
105
+ if (parts.length > 1 && parts[0]) {
106
+ return [parts[0], name];
107
+ }
108
+ }
109
+ }
110
+
111
+ return [func.name];
112
+ }
113
+
114
+ /**
115
+ * Ensures a directory exists at the given path
116
+ */
117
+ private ensureDirectory(parent: TreeNode, name: string): TreeNode {
118
+ if (!parent.children) {
119
+ parent.children = new Map();
120
+ }
121
+
122
+ let child = parent.children.get(name);
123
+ if (!child) {
124
+ child = { type: 'directory', name, children: new Map() };
125
+ parent.children.set(name, child);
126
+ }
127
+
128
+ return child;
129
+ }
130
+
131
+ /**
132
+ * Adds a function to the tree
133
+ */
134
+ private addFunction(
135
+ parent: TreeNode,
136
+ name: string,
137
+ func: CustomFunctionDef,
138
+ group: string
139
+ ): void {
140
+ if (!parent.children) {
141
+ parent.children = new Map();
142
+ }
143
+
144
+ parent.children.set(name, {
145
+ type: 'function',
146
+ name,
147
+ functionDef: { func, group },
148
+ });
149
+ }
150
+
151
+ /**
152
+ * Explores the filesystem at the given path
153
+ */
154
+ explore(path: string): ExploreResult | null {
155
+ const normalizedPath = this.normalizePath(path);
156
+ const segments = normalizedPath === '/' ? [] : normalizedPath.split('/').filter((s) => s);
157
+
158
+ let current = this.root;
159
+ let currentPath = '/';
160
+
161
+ for (const segment of segments) {
162
+ if (!current.children || !current.children.has(segment)) {
163
+ return null;
164
+ }
165
+ current = current.children.get(segment)!;
166
+ currentPath = currentPath === '/' ? `/${segment}` : `${currentPath}/${segment}`;
167
+ }
168
+
169
+ if (current.type === 'directory') {
170
+ const items: Array<{ name: string; type: 'directory' | 'function' }> = [];
171
+ if (current.children) {
172
+ for (const [name, node] of current.children) {
173
+ items.push({ name, type: node.type });
174
+ }
175
+ }
176
+ items.sort((a, b) => {
177
+ if (a.type === b.type) {
178
+ return a.name.localeCompare(b.name);
179
+ }
180
+ return a.type === 'directory' ? -1 : 1;
181
+ });
182
+
183
+ return {
184
+ type: 'directory',
185
+ path: currentPath,
186
+ items,
187
+ };
188
+ } else {
189
+ if (!current.functionDef) {
190
+ return null;
191
+ }
192
+
193
+ const { func, group } = current.functionDef;
194
+ const definition = this.generateFunctionDefinition(func);
195
+
196
+ return {
197
+ type: 'function',
198
+ path: currentPath,
199
+ name: func.name,
200
+ description: func.description,
201
+ definition,
202
+ group,
203
+ };
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Normalizes a path (removes trailing slashes, ensures leading slash)
209
+ */
210
+ private normalizePath(path: string): string {
211
+ if (!path || path === '') return '/';
212
+
213
+ if (!path.startsWith('/')) {
214
+ path = '/' + path;
215
+ }
216
+
217
+ if (path !== '/' && path.endsWith('/')) {
218
+ path = path.slice(0, -1);
219
+ }
220
+
221
+ return path;
222
+ }
223
+
224
+ /**
225
+ * Generates TypeScript function signature
226
+ */
227
+ private generateFunctionDefinition(func: CustomFunctionDef): string {
228
+ const inputType = this.generateInputType(func.inputSchema);
229
+ const outputType = func.outputSchema ? this.generateOutputType(func.outputSchema) : 'unknown';
230
+
231
+ return `async function ${func.name}(params: ${inputType}): Promise<${outputType}>`;
232
+ }
233
+
234
+ /**
235
+ * Generates TypeScript type from JSON schema
236
+ */
237
+ private generateInputType(schema?: {
238
+ properties?: Record<string, any>;
239
+ required?: string[];
240
+ }): string {
241
+ if (!schema || !schema.properties) {
242
+ return '{}';
243
+ }
244
+
245
+ const props: string[] = [];
246
+ const required = schema.required || [];
247
+
248
+ for (const [key, value] of Object.entries(schema.properties)) {
249
+ const isRequired = required.includes(key);
250
+ const prop = value as { type?: string; description?: string };
251
+ const tsType = this.jsonSchemaTypeToTS(prop.type ?? 'any');
252
+ const optional = isRequired ? '' : '?';
253
+ props.push(`${key}${optional}: ${tsType}`);
254
+ }
255
+
256
+ return `{ ${props.join('; ')} }`;
257
+ }
258
+
259
+ /**
260
+ * Generates output type from JSON schema
261
+ */
262
+ private generateOutputType(schema: { properties?: Record<string, any> }): string {
263
+ if (!schema.properties) {
264
+ return 'unknown';
265
+ }
266
+
267
+ const props: string[] = [];
268
+ for (const [key, value] of Object.entries(schema.properties)) {
269
+ const prop = value as { type?: string };
270
+ const tsType = this.jsonSchemaTypeToTS(prop.type ?? 'any');
271
+ props.push(`${key}: ${tsType}`);
272
+ }
273
+
274
+ return `{ ${props.join('; ')} }`;
275
+ }
276
+
277
+ /**
278
+ * Converts JSON Schema type to TypeScript type
279
+ */
280
+ private jsonSchemaTypeToTS(type: string): string {
281
+ switch (type) {
282
+ case 'string':
283
+ return 'string';
284
+ case 'number':
285
+ case 'integer':
286
+ return 'number';
287
+ case 'boolean':
288
+ return 'boolean';
289
+ case 'array':
290
+ return 'any[]';
291
+ case 'object':
292
+ return 'Record<string, any>';
293
+ default:
294
+ return 'any';
295
+ }
296
+ }
297
+ }
@@ -0,0 +1,13 @@
1
+ import type { APIGroupConfig } from '@mondaydotcomorg/atp-protocol';
2
+ import { APIAggregator } from '../aggregator/index.js';
3
+
4
+ export async function getDefinitions(apiGroups: APIGroupConfig[]): Promise<unknown> {
5
+ const aggregator = new APIAggregator(apiGroups);
6
+ const typescript = await aggregator.generateTypeScript();
7
+
8
+ return {
9
+ typescript,
10
+ apiGroups: apiGroups.map((g) => g.name),
11
+ version: '1.0.0',
12
+ };
13
+ }