@vibe-lang/runtime 0.2.5

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 (250) hide show
  1. package/package.json +46 -0
  2. package/src/ast/index.ts +375 -0
  3. package/src/ast.ts +2 -0
  4. package/src/debug/advanced-features.ts +482 -0
  5. package/src/debug/bun-inspector.ts +424 -0
  6. package/src/debug/handoff-manager.ts +283 -0
  7. package/src/debug/index.ts +150 -0
  8. package/src/debug/runner.ts +365 -0
  9. package/src/debug/server.ts +565 -0
  10. package/src/debug/stack-merger.ts +267 -0
  11. package/src/debug/state.ts +581 -0
  12. package/src/debug/test/advanced-features.test.ts +300 -0
  13. package/src/debug/test/e2e.test.ts +218 -0
  14. package/src/debug/test/handoff-manager.test.ts +256 -0
  15. package/src/debug/test/runner.test.ts +256 -0
  16. package/src/debug/test/stack-merger.test.ts +163 -0
  17. package/src/debug/test/state.test.ts +400 -0
  18. package/src/debug/test/ts-debug-integration.test.ts +374 -0
  19. package/src/debug/test/ts-import-tracker.test.ts +125 -0
  20. package/src/debug/test/ts-source-map.test.ts +169 -0
  21. package/src/debug/ts-import-tracker.ts +151 -0
  22. package/src/debug/ts-source-map.ts +171 -0
  23. package/src/errors/index.ts +124 -0
  24. package/src/index.ts +358 -0
  25. package/src/lexer/index.ts +348 -0
  26. package/src/lexer.ts +2 -0
  27. package/src/parser/index.ts +792 -0
  28. package/src/parser/parse.ts +45 -0
  29. package/src/parser/test/async.test.ts +248 -0
  30. package/src/parser/test/destructuring.test.ts +167 -0
  31. package/src/parser/test/do-expression.test.ts +486 -0
  32. package/src/parser/test/errors/do-expression.test.ts +95 -0
  33. package/src/parser/test/errors/error-locations.test.ts +230 -0
  34. package/src/parser/test/errors/invalid-expressions.test.ts +144 -0
  35. package/src/parser/test/errors/missing-tokens.test.ts +126 -0
  36. package/src/parser/test/errors/model-declaration.test.ts +185 -0
  37. package/src/parser/test/errors/nested-blocks.test.ts +226 -0
  38. package/src/parser/test/errors/unclosed-delimiters.test.ts +122 -0
  39. package/src/parser/test/errors/unexpected-tokens.test.ts +120 -0
  40. package/src/parser/test/import-export.test.ts +143 -0
  41. package/src/parser/test/literals.test.ts +404 -0
  42. package/src/parser/test/model-declaration.test.ts +161 -0
  43. package/src/parser/test/nested-blocks.test.ts +402 -0
  44. package/src/parser/test/parser.test.ts +743 -0
  45. package/src/parser/test/private.test.ts +136 -0
  46. package/src/parser/test/template-literal.test.ts +127 -0
  47. package/src/parser/test/tool-declaration.test.ts +302 -0
  48. package/src/parser/test/ts-block.test.ts +252 -0
  49. package/src/parser/test/type-annotations.test.ts +254 -0
  50. package/src/parser/visitor/helpers.ts +330 -0
  51. package/src/parser/visitor.ts +794 -0
  52. package/src/parser.ts +2 -0
  53. package/src/runtime/ai/cache-chunking.test.ts +69 -0
  54. package/src/runtime/ai/cache-chunking.ts +73 -0
  55. package/src/runtime/ai/client.ts +109 -0
  56. package/src/runtime/ai/context.ts +168 -0
  57. package/src/runtime/ai/formatters.ts +316 -0
  58. package/src/runtime/ai/index.ts +38 -0
  59. package/src/runtime/ai/language-ref.ts +38 -0
  60. package/src/runtime/ai/providers/anthropic.ts +253 -0
  61. package/src/runtime/ai/providers/google.ts +201 -0
  62. package/src/runtime/ai/providers/openai.ts +156 -0
  63. package/src/runtime/ai/retry.ts +100 -0
  64. package/src/runtime/ai/return-tools.ts +301 -0
  65. package/src/runtime/ai/test/client.test.ts +83 -0
  66. package/src/runtime/ai/test/formatters.test.ts +485 -0
  67. package/src/runtime/ai/test/retry.test.ts +137 -0
  68. package/src/runtime/ai/test/return-tools.test.ts +450 -0
  69. package/src/runtime/ai/test/tool-loop.test.ts +319 -0
  70. package/src/runtime/ai/test/tool-schema.test.ts +241 -0
  71. package/src/runtime/ai/tool-loop.ts +203 -0
  72. package/src/runtime/ai/tool-schema.ts +151 -0
  73. package/src/runtime/ai/types.ts +113 -0
  74. package/src/runtime/ai-logger.ts +255 -0
  75. package/src/runtime/ai-provider.ts +347 -0
  76. package/src/runtime/async/dependencies.ts +276 -0
  77. package/src/runtime/async/executor.ts +293 -0
  78. package/src/runtime/async/index.ts +43 -0
  79. package/src/runtime/async/scheduling.ts +163 -0
  80. package/src/runtime/async/test/dependencies.test.ts +284 -0
  81. package/src/runtime/async/test/executor.test.ts +388 -0
  82. package/src/runtime/context.ts +357 -0
  83. package/src/runtime/exec/ai.ts +139 -0
  84. package/src/runtime/exec/expressions.ts +475 -0
  85. package/src/runtime/exec/frames.ts +26 -0
  86. package/src/runtime/exec/functions.ts +305 -0
  87. package/src/runtime/exec/interpolation.ts +312 -0
  88. package/src/runtime/exec/statements.ts +604 -0
  89. package/src/runtime/exec/tools.ts +129 -0
  90. package/src/runtime/exec/typescript.ts +215 -0
  91. package/src/runtime/exec/variables.ts +279 -0
  92. package/src/runtime/index.ts +975 -0
  93. package/src/runtime/modules.ts +452 -0
  94. package/src/runtime/serialize.ts +103 -0
  95. package/src/runtime/state.ts +489 -0
  96. package/src/runtime/stdlib/core.ts +45 -0
  97. package/src/runtime/stdlib/directory.test.ts +156 -0
  98. package/src/runtime/stdlib/edit.test.ts +154 -0
  99. package/src/runtime/stdlib/fastEdit.test.ts +201 -0
  100. package/src/runtime/stdlib/glob.test.ts +106 -0
  101. package/src/runtime/stdlib/grep.test.ts +144 -0
  102. package/src/runtime/stdlib/index.ts +16 -0
  103. package/src/runtime/stdlib/readFile.test.ts +123 -0
  104. package/src/runtime/stdlib/tools/index.ts +707 -0
  105. package/src/runtime/stdlib/writeFile.test.ts +157 -0
  106. package/src/runtime/step.ts +969 -0
  107. package/src/runtime/test/ai-context.test.ts +1086 -0
  108. package/src/runtime/test/ai-result-object.test.ts +419 -0
  109. package/src/runtime/test/ai-tool-flow.test.ts +859 -0
  110. package/src/runtime/test/async-execution-order.test.ts +618 -0
  111. package/src/runtime/test/async-execution.test.ts +344 -0
  112. package/src/runtime/test/async-nested.test.ts +660 -0
  113. package/src/runtime/test/async-parallel-timing.test.ts +546 -0
  114. package/src/runtime/test/basic1.test.ts +154 -0
  115. package/src/runtime/test/binary-operators.test.ts +431 -0
  116. package/src/runtime/test/break-statement.test.ts +257 -0
  117. package/src/runtime/test/context-modes.test.ts +650 -0
  118. package/src/runtime/test/context.test.ts +466 -0
  119. package/src/runtime/test/core-functions.test.ts +228 -0
  120. package/src/runtime/test/e2e.test.ts +88 -0
  121. package/src/runtime/test/error-locations/error-locations.test.ts +80 -0
  122. package/src/runtime/test/error-locations/main-error.vibe +4 -0
  123. package/src/runtime/test/error-locations/main-import-error.vibe +3 -0
  124. package/src/runtime/test/error-locations/utils/helper.vibe +5 -0
  125. package/src/runtime/test/for-in.test.ts +312 -0
  126. package/src/runtime/test/helpers.ts +69 -0
  127. package/src/runtime/test/imports.test.ts +334 -0
  128. package/src/runtime/test/json-expressions.test.ts +232 -0
  129. package/src/runtime/test/literals.test.ts +372 -0
  130. package/src/runtime/test/logical-indexing.test.ts +478 -0
  131. package/src/runtime/test/member-methods.test.ts +324 -0
  132. package/src/runtime/test/model-config.test.ts +338 -0
  133. package/src/runtime/test/null-handling.test.ts +342 -0
  134. package/src/runtime/test/private-visibility.test.ts +332 -0
  135. package/src/runtime/test/runtime-state.test.ts +514 -0
  136. package/src/runtime/test/scoping.test.ts +370 -0
  137. package/src/runtime/test/string-interpolation.test.ts +354 -0
  138. package/src/runtime/test/template-literal.test.ts +181 -0
  139. package/src/runtime/test/tool-execution.test.ts +467 -0
  140. package/src/runtime/test/tool-schema-generation.test.ts +477 -0
  141. package/src/runtime/test/tostring.test.ts +210 -0
  142. package/src/runtime/test/ts-block.test.ts +594 -0
  143. package/src/runtime/test/ts-error-location.test.ts +231 -0
  144. package/src/runtime/test/types.test.ts +732 -0
  145. package/src/runtime/test/verbose-logger.test.ts +710 -0
  146. package/src/runtime/test/vibe-expression.test.ts +54 -0
  147. package/src/runtime/test/vibe-value-errors.test.ts +541 -0
  148. package/src/runtime/test/while.test.ts +232 -0
  149. package/src/runtime/tools/builtin.ts +30 -0
  150. package/src/runtime/tools/directory-tools.ts +70 -0
  151. package/src/runtime/tools/file-tools.ts +228 -0
  152. package/src/runtime/tools/index.ts +5 -0
  153. package/src/runtime/tools/registry.ts +48 -0
  154. package/src/runtime/tools/search-tools.ts +134 -0
  155. package/src/runtime/tools/security.ts +36 -0
  156. package/src/runtime/tools/system-tools.ts +312 -0
  157. package/src/runtime/tools/test/fixtures/base-types.ts +40 -0
  158. package/src/runtime/tools/test/fixtures/test-types.ts +132 -0
  159. package/src/runtime/tools/test/registry.test.ts +713 -0
  160. package/src/runtime/tools/test/security.test.ts +86 -0
  161. package/src/runtime/tools/test/system-tools.test.ts +679 -0
  162. package/src/runtime/tools/test/ts-schema.test.ts +357 -0
  163. package/src/runtime/tools/ts-schema.ts +341 -0
  164. package/src/runtime/tools/types.ts +89 -0
  165. package/src/runtime/tools/utility-tools.ts +198 -0
  166. package/src/runtime/ts-eval.ts +126 -0
  167. package/src/runtime/types.ts +797 -0
  168. package/src/runtime/validation.ts +160 -0
  169. package/src/runtime/verbose-logger.ts +459 -0
  170. package/src/runtime.ts +2 -0
  171. package/src/semantic/analyzer-context.ts +62 -0
  172. package/src/semantic/analyzer-validators.ts +575 -0
  173. package/src/semantic/analyzer-visitors.ts +534 -0
  174. package/src/semantic/analyzer.ts +83 -0
  175. package/src/semantic/index.ts +11 -0
  176. package/src/semantic/symbol-table.ts +58 -0
  177. package/src/semantic/test/async-validation.test.ts +301 -0
  178. package/src/semantic/test/compress-validation.test.ts +179 -0
  179. package/src/semantic/test/const-reassignment.test.ts +111 -0
  180. package/src/semantic/test/control-flow.test.ts +346 -0
  181. package/src/semantic/test/destructuring.test.ts +185 -0
  182. package/src/semantic/test/duplicate-declarations.test.ts +168 -0
  183. package/src/semantic/test/export-validation.test.ts +111 -0
  184. package/src/semantic/test/fixtures/math.ts +31 -0
  185. package/src/semantic/test/imports.test.ts +148 -0
  186. package/src/semantic/test/json-type.test.ts +68 -0
  187. package/src/semantic/test/literals.test.ts +127 -0
  188. package/src/semantic/test/model-validation.test.ts +179 -0
  189. package/src/semantic/test/prompt-validation.test.ts +343 -0
  190. package/src/semantic/test/scoping.test.ts +312 -0
  191. package/src/semantic/test/tool-validation.test.ts +306 -0
  192. package/src/semantic/test/ts-type-checking.test.ts +563 -0
  193. package/src/semantic/test/type-constraints.test.ts +111 -0
  194. package/src/semantic/test/type-inference.test.ts +87 -0
  195. package/src/semantic/test/type-validation.test.ts +552 -0
  196. package/src/semantic/test/undefined-variables.test.ts +163 -0
  197. package/src/semantic/ts-block-checker.ts +204 -0
  198. package/src/semantic/ts-signatures.ts +194 -0
  199. package/src/semantic/ts-types.ts +170 -0
  200. package/src/semantic/types.ts +58 -0
  201. package/tests/fixtures/conditional-logic.vibe +14 -0
  202. package/tests/fixtures/function-call.vibe +16 -0
  203. package/tests/fixtures/imports/cycle-detection/a.vibe +6 -0
  204. package/tests/fixtures/imports/cycle-detection/b.vibe +5 -0
  205. package/tests/fixtures/imports/cycle-detection/main.vibe +3 -0
  206. package/tests/fixtures/imports/module-isolation/main-b.vibe +8 -0
  207. package/tests/fixtures/imports/module-isolation/main.vibe +9 -0
  208. package/tests/fixtures/imports/module-isolation/moduleA.vibe +6 -0
  209. package/tests/fixtures/imports/module-isolation/moduleB.vibe +6 -0
  210. package/tests/fixtures/imports/nested-import/helper.vibe +6 -0
  211. package/tests/fixtures/imports/nested-import/main.vibe +3 -0
  212. package/tests/fixtures/imports/nested-import/utils.ts +3 -0
  213. package/tests/fixtures/imports/nested-isolation/file2.vibe +15 -0
  214. package/tests/fixtures/imports/nested-isolation/file3.vibe +10 -0
  215. package/tests/fixtures/imports/nested-isolation/main.vibe +21 -0
  216. package/tests/fixtures/imports/pure-cycle/a.vibe +5 -0
  217. package/tests/fixtures/imports/pure-cycle/b.vibe +5 -0
  218. package/tests/fixtures/imports/pure-cycle/main.vibe +3 -0
  219. package/tests/fixtures/imports/ts-boolean/checks.ts +14 -0
  220. package/tests/fixtures/imports/ts-boolean/main.vibe +10 -0
  221. package/tests/fixtures/imports/ts-boolean/type-mismatch.vibe +5 -0
  222. package/tests/fixtures/imports/ts-boolean/use-constant.vibe +18 -0
  223. package/tests/fixtures/imports/ts-error-handling/helpers.ts +42 -0
  224. package/tests/fixtures/imports/ts-error-handling/main.vibe +5 -0
  225. package/tests/fixtures/imports/ts-import/main.vibe +4 -0
  226. package/tests/fixtures/imports/ts-import/math.ts +9 -0
  227. package/tests/fixtures/imports/ts-variables/call-non-function.vibe +5 -0
  228. package/tests/fixtures/imports/ts-variables/data.ts +10 -0
  229. package/tests/fixtures/imports/ts-variables/import-json.vibe +5 -0
  230. package/tests/fixtures/imports/ts-variables/import-type-mismatch.vibe +5 -0
  231. package/tests/fixtures/imports/ts-variables/import-variable.vibe +5 -0
  232. package/tests/fixtures/imports/vibe-import/greet.vibe +5 -0
  233. package/tests/fixtures/imports/vibe-import/main.vibe +3 -0
  234. package/tests/fixtures/multiple-ai-calls.vibe +10 -0
  235. package/tests/fixtures/simple-greeting.vibe +6 -0
  236. package/tests/fixtures/template-literals.vibe +11 -0
  237. package/tests/integration/basic-ai/basic-ai.integration.test.ts +166 -0
  238. package/tests/integration/basic-ai/basic-ai.vibe +12 -0
  239. package/tests/integration/bug-fix/bug-fix.integration.test.ts +201 -0
  240. package/tests/integration/bug-fix/buggy-code.ts +22 -0
  241. package/tests/integration/bug-fix/fix-bug.vibe +21 -0
  242. package/tests/integration/compress/compress.integration.test.ts +206 -0
  243. package/tests/integration/destructuring/destructuring.integration.test.ts +92 -0
  244. package/tests/integration/hello-world-translator/hello-world-translator.integration.test.ts +61 -0
  245. package/tests/integration/line-annotator/context-modes.integration.test.ts +261 -0
  246. package/tests/integration/line-annotator/line-annotator.integration.test.ts +148 -0
  247. package/tests/integration/multi-feature/cumulative-sum.integration.test.ts +75 -0
  248. package/tests/integration/multi-feature/number-analyzer.integration.test.ts +191 -0
  249. package/tests/integration/multi-feature/number-analyzer.vibe +59 -0
  250. package/tests/integration/tool-calls/tool-calls.integration.test.ts +93 -0
@@ -0,0 +1,89 @@
1
+ // JSON Schema type for tool parameters
2
+ export interface JsonSchema {
3
+ type: 'string' | 'number' | 'boolean' | 'object' | 'array';
4
+ description?: string;
5
+ properties?: Record<string, JsonSchema>;
6
+ items?: JsonSchema;
7
+ required?: string[];
8
+ additionalProperties?: boolean;
9
+ }
10
+
11
+ // Tool parameter schema for AI function calling
12
+ export interface ToolParameterSchema {
13
+ name: string;
14
+ type: JsonSchema;
15
+ description?: string;
16
+ required: boolean;
17
+ }
18
+
19
+ // Tool schema for AI function calling
20
+ export interface ToolSchema {
21
+ name: string;
22
+ description?: string;
23
+ parameters: ToolParameterSchema[];
24
+ returns?: JsonSchema;
25
+ }
26
+
27
+ // Context passed to tool executors
28
+ export interface ToolContext {
29
+ rootDir: string; // Root directory for path sandboxing
30
+ }
31
+
32
+ // Tool executor function signature
33
+ export type ToolExecutor = (
34
+ args: Record<string, unknown>,
35
+ context?: ToolContext
36
+ ) => Promise<unknown>;
37
+
38
+ // Pending tool call (when runtime is paused)
39
+ export interface PendingToolCall {
40
+ toolName: string;
41
+ toolCallId: string;
42
+ args: Record<string, unknown>;
43
+ executor: ToolExecutor; // The tool's executor function
44
+ // For multi-turn AI tool calling (deferred for now)
45
+ aiConversationState?: unknown;
46
+ }
47
+
48
+ // Tool execution result
49
+ export interface ToolResult {
50
+ value: unknown;
51
+ error?: string;
52
+ }
53
+
54
+ // Tool as a first-class Vibe value (like VibeModelValue)
55
+ // This is the value stored when a tool declaration is executed
56
+ export interface VibeToolValue {
57
+ __vibeTool: true; // Type guard marker
58
+ name: string;
59
+ schema: ToolSchema;
60
+ executor: ToolExecutor;
61
+ }
62
+
63
+ // Type guard for VibeToolValue
64
+ export function isVibeToolValue(value: unknown): value is VibeToolValue {
65
+ return (
66
+ typeof value === 'object' &&
67
+ value !== null &&
68
+ '__vibeTool' in value &&
69
+ (value as VibeToolValue).__vibeTool === true
70
+ );
71
+ }
72
+
73
+ // Registered tool in the registry
74
+ export interface RegisteredTool {
75
+ name: string;
76
+ kind: 'builtin' | 'user';
77
+ schema: ToolSchema;
78
+ executor: ToolExecutor;
79
+ }
80
+
81
+ // Tool registry interface
82
+ export interface ToolRegistry {
83
+ register(tool: RegisteredTool): void;
84
+ registerAll(tools: RegisteredTool[]): void;
85
+ get(name: string): RegisteredTool | undefined;
86
+ has(name: string): boolean;
87
+ list(): RegisteredTool[];
88
+ getSchemas(): ToolSchema[];
89
+ }
@@ -0,0 +1,198 @@
1
+ import type { RegisteredTool } from './types';
2
+ import { resolveValue } from '../types';
3
+
4
+ /**
5
+ * Utility tools: env, sleep, now, jsonParse, jsonStringify, print, random, uuid
6
+ */
7
+ export const utilityTools = [
8
+ {
9
+ name: 'env',
10
+ kind: 'builtin',
11
+ schema: {
12
+ name: 'env',
13
+ description: 'Get an environment variable.',
14
+ parameters: [
15
+ {
16
+ name: 'name',
17
+ type: { type: 'string' },
18
+ description: 'The environment variable name',
19
+ required: true,
20
+ },
21
+ {
22
+ name: 'defaultValue',
23
+ type: { type: 'string' },
24
+ description: 'Default value if not set',
25
+ required: false,
26
+ },
27
+ ],
28
+ returns: { type: 'string' },
29
+ },
30
+ executor: async (args: Record<string, unknown>) => {
31
+ const name = args.name as string;
32
+ const defaultValue = args.defaultValue as string | undefined;
33
+ return process.env[name] ?? defaultValue ?? '';
34
+ },
35
+ },
36
+
37
+ {
38
+ name: 'sleep',
39
+ kind: 'builtin',
40
+ schema: {
41
+ name: 'sleep',
42
+ description: 'Pause execution for a specified number of milliseconds.',
43
+ parameters: [
44
+ {
45
+ name: 'ms',
46
+ type: { type: 'number' },
47
+ description: 'Milliseconds to sleep',
48
+ required: true,
49
+ },
50
+ ],
51
+ returns: { type: 'boolean' },
52
+ },
53
+ executor: async (args: Record<string, unknown>) => {
54
+ const ms = args.ms as number;
55
+ await new Promise((resolve) => setTimeout(resolve, ms));
56
+ return true;
57
+ },
58
+ },
59
+
60
+ {
61
+ name: 'now',
62
+ kind: 'builtin',
63
+ schema: {
64
+ name: 'now',
65
+ description: 'Get the current timestamp in milliseconds.',
66
+ parameters: [],
67
+ returns: { type: 'number' },
68
+ },
69
+ executor: async () => {
70
+ return Date.now();
71
+ },
72
+ },
73
+
74
+ {
75
+ name: 'jsonParse',
76
+ kind: 'builtin',
77
+ schema: {
78
+ name: 'jsonParse',
79
+ description: 'Parse a JSON string into an object.',
80
+ parameters: [
81
+ {
82
+ name: 'text',
83
+ type: { type: 'string' },
84
+ description: 'The JSON string to parse',
85
+ required: true,
86
+ },
87
+ ],
88
+ returns: { type: 'object', additionalProperties: true },
89
+ },
90
+ executor: async (args: Record<string, unknown>) => {
91
+ const text = args.text as string;
92
+ return JSON.parse(text);
93
+ },
94
+ },
95
+
96
+ {
97
+ name: 'jsonStringify',
98
+ kind: 'builtin',
99
+ schema: {
100
+ name: 'jsonStringify',
101
+ description: 'Convert an object to a JSON string.',
102
+ parameters: [
103
+ {
104
+ name: 'value',
105
+ type: { type: 'object', additionalProperties: true },
106
+ description: 'The value to stringify',
107
+ required: true,
108
+ },
109
+ {
110
+ name: 'pretty',
111
+ type: { type: 'boolean' },
112
+ description: 'Whether to format with indentation',
113
+ required: false,
114
+ },
115
+ ],
116
+ returns: { type: 'string' },
117
+ },
118
+ executor: async (args: Record<string, unknown>) => {
119
+ const value = args.value;
120
+ const pretty = args.pretty as boolean | undefined;
121
+ return pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value);
122
+ },
123
+ },
124
+
125
+ {
126
+ name: 'print',
127
+ kind: 'builtin',
128
+ schema: {
129
+ name: 'print',
130
+ description: 'Output a message to the console.',
131
+ parameters: [
132
+ {
133
+ name: 'message',
134
+ type: { type: 'string' },
135
+ description: 'The message to print',
136
+ required: true,
137
+ },
138
+ ],
139
+ returns: { type: 'boolean' },
140
+ },
141
+ executor: async (args: Record<string, unknown>) => {
142
+ // Resolve AIResultObject to its value before printing
143
+ const message = resolveValue(args.message);
144
+ console.log(message);
145
+ return true;
146
+ },
147
+ },
148
+
149
+ {
150
+ name: 'random',
151
+ kind: 'builtin',
152
+ schema: {
153
+ name: 'random',
154
+ description: 'Generate a random number. Without arguments, returns 0-1. With min/max, returns integer in range.',
155
+ parameters: [
156
+ {
157
+ name: 'min',
158
+ type: { type: 'number' },
159
+ description: 'Minimum value (inclusive)',
160
+ required: false,
161
+ },
162
+ {
163
+ name: 'max',
164
+ type: { type: 'number' },
165
+ description: 'Maximum value (inclusive)',
166
+ required: false,
167
+ },
168
+ ],
169
+ returns: { type: 'number' },
170
+ },
171
+ executor: async (args: Record<string, unknown>) => {
172
+ const min = args.min as number | undefined;
173
+ const max = args.max as number | undefined;
174
+
175
+ if (min !== undefined && max !== undefined) {
176
+ // Return random integer in range [min, max]
177
+ return Math.floor(Math.random() * (max - min + 1)) + min;
178
+ }
179
+
180
+ // Return random float [0, 1)
181
+ return Math.random();
182
+ },
183
+ },
184
+
185
+ {
186
+ name: 'uuid',
187
+ kind: 'builtin',
188
+ schema: {
189
+ name: 'uuid',
190
+ description: 'Generate a UUID v4.',
191
+ parameters: [],
192
+ returns: { type: 'string' },
193
+ },
194
+ executor: async () => {
195
+ return crypto.randomUUID();
196
+ },
197
+ },
198
+ ] satisfies RegisteredTool[];
@@ -0,0 +1,126 @@
1
+ // TypeScript evaluation with caching
2
+ // Uses AsyncFunction constructor to compile and execute TypeScript code
3
+
4
+ import type { SourceLocation } from '../errors';
5
+
6
+ // Cache compiled functions by signature (params + body)
7
+ const functionCache = new Map<string, (...args: unknown[]) => Promise<unknown>>();
8
+
9
+ // Get the AsyncFunction constructor
10
+ const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor as new (
11
+ ...args: string[]
12
+ ) => (...args: unknown[]) => Promise<unknown>;
13
+
14
+ // Generate cache key from params and body
15
+ function getCacheKey(params: string[], body: string): string {
16
+ return `${params.join(',')}::${body}`;
17
+ }
18
+
19
+ // Custom error for TS block failures
20
+ export class TsBlockError extends Error {
21
+ constructor(
22
+ message: string,
23
+ public readonly params: string[],
24
+ public readonly body: string,
25
+ public readonly originalError: Error,
26
+ public readonly location?: SourceLocation
27
+ ) {
28
+ super(message);
29
+ this.name = 'TsBlockError';
30
+ }
31
+
32
+ // Format error with source location and original stack trace
33
+ format(): string {
34
+ let result = '';
35
+
36
+ // Add Vibe source location if available
37
+ if (this.location) {
38
+ const loc = `[${this.location.file ?? 'vibe'}:${this.location.line}:${this.location.column}]`;
39
+ result = `${loc} `;
40
+ }
41
+
42
+ result += this.message;
43
+
44
+ // Add original TypeScript stack trace for debugging
45
+ if (this.originalError.stack) {
46
+ result += `\n\nTypeScript stack trace:\n${this.originalError.stack}`;
47
+ }
48
+
49
+ return result;
50
+ }
51
+ }
52
+
53
+ // Evaluate a TypeScript block
54
+ export async function evalTsBlock(
55
+ params: string[],
56
+ body: string,
57
+ paramValues: unknown[],
58
+ location?: SourceLocation
59
+ ): Promise<unknown> {
60
+ const cacheKey = getCacheKey(params, body);
61
+
62
+ // Get or compile function
63
+ let fn = functionCache.get(cacheKey);
64
+ if (!fn) {
65
+ try {
66
+ // Prepend 'use strict' to ensure frozen object mutations throw errors
67
+ const strictBody = `'use strict';\n${body}`;
68
+ fn = new AsyncFunction(...params, strictBody);
69
+ functionCache.set(cacheKey, fn);
70
+ } catch (error) {
71
+ // Syntax error in TS block
72
+ const snippet = body.length > 50 ? body.slice(0, 50) + '...' : body;
73
+ throw new TsBlockError(
74
+ `ts block compilation error: ${error instanceof Error ? error.message : String(error)}\n Code: ${snippet}`,
75
+ params,
76
+ body,
77
+ error instanceof Error ? error : new Error(String(error)),
78
+ location
79
+ );
80
+ }
81
+ }
82
+
83
+ // Call with parameter values
84
+ try {
85
+ return await fn(...paramValues);
86
+ } catch (error) {
87
+ // Runtime error in TS block
88
+ const snippet = body.length > 50 ? body.slice(0, 50) + '...' : body;
89
+ throw new TsBlockError(
90
+ `ts block runtime error: ${error instanceof Error ? error.message : String(error)}\n Code: ${snippet}`,
91
+ params,
92
+ body,
93
+ error instanceof Error ? error : new Error(String(error)),
94
+ location
95
+ );
96
+ }
97
+ }
98
+
99
+ // Validate return type against expected type annotation
100
+ export function validateReturnType(
101
+ value: unknown,
102
+ expectedType: string | null,
103
+ varName: string
104
+ ): void {
105
+ if (!expectedType) return; // No type annotation, accept anything
106
+
107
+ if (expectedType === 'text' && typeof value !== 'string') {
108
+ throw new TypeError(`Variable '${varName}': expected text, got ${typeof value}`);
109
+ }
110
+
111
+ if (expectedType === 'json') {
112
+ if (typeof value !== 'object' || value === null) {
113
+ throw new TypeError(`Variable '${varName}': expected json (object/array), got ${typeof value}`);
114
+ }
115
+ }
116
+ }
117
+
118
+ // Clear the function cache (useful for testing)
119
+ export function clearFunctionCache(): void {
120
+ functionCache.clear();
121
+ }
122
+
123
+ // Get cache size (useful for testing)
124
+ export function getFunctionCacheSize(): number {
125
+ return functionCache.size;
126
+ }