@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.
- package/package.json +46 -0
- package/src/ast/index.ts +375 -0
- package/src/ast.ts +2 -0
- package/src/debug/advanced-features.ts +482 -0
- package/src/debug/bun-inspector.ts +424 -0
- package/src/debug/handoff-manager.ts +283 -0
- package/src/debug/index.ts +150 -0
- package/src/debug/runner.ts +365 -0
- package/src/debug/server.ts +565 -0
- package/src/debug/stack-merger.ts +267 -0
- package/src/debug/state.ts +581 -0
- package/src/debug/test/advanced-features.test.ts +300 -0
- package/src/debug/test/e2e.test.ts +218 -0
- package/src/debug/test/handoff-manager.test.ts +256 -0
- package/src/debug/test/runner.test.ts +256 -0
- package/src/debug/test/stack-merger.test.ts +163 -0
- package/src/debug/test/state.test.ts +400 -0
- package/src/debug/test/ts-debug-integration.test.ts +374 -0
- package/src/debug/test/ts-import-tracker.test.ts +125 -0
- package/src/debug/test/ts-source-map.test.ts +169 -0
- package/src/debug/ts-import-tracker.ts +151 -0
- package/src/debug/ts-source-map.ts +171 -0
- package/src/errors/index.ts +124 -0
- package/src/index.ts +358 -0
- package/src/lexer/index.ts +348 -0
- package/src/lexer.ts +2 -0
- package/src/parser/index.ts +792 -0
- package/src/parser/parse.ts +45 -0
- package/src/parser/test/async.test.ts +248 -0
- package/src/parser/test/destructuring.test.ts +167 -0
- package/src/parser/test/do-expression.test.ts +486 -0
- package/src/parser/test/errors/do-expression.test.ts +95 -0
- package/src/parser/test/errors/error-locations.test.ts +230 -0
- package/src/parser/test/errors/invalid-expressions.test.ts +144 -0
- package/src/parser/test/errors/missing-tokens.test.ts +126 -0
- package/src/parser/test/errors/model-declaration.test.ts +185 -0
- package/src/parser/test/errors/nested-blocks.test.ts +226 -0
- package/src/parser/test/errors/unclosed-delimiters.test.ts +122 -0
- package/src/parser/test/errors/unexpected-tokens.test.ts +120 -0
- package/src/parser/test/import-export.test.ts +143 -0
- package/src/parser/test/literals.test.ts +404 -0
- package/src/parser/test/model-declaration.test.ts +161 -0
- package/src/parser/test/nested-blocks.test.ts +402 -0
- package/src/parser/test/parser.test.ts +743 -0
- package/src/parser/test/private.test.ts +136 -0
- package/src/parser/test/template-literal.test.ts +127 -0
- package/src/parser/test/tool-declaration.test.ts +302 -0
- package/src/parser/test/ts-block.test.ts +252 -0
- package/src/parser/test/type-annotations.test.ts +254 -0
- package/src/parser/visitor/helpers.ts +330 -0
- package/src/parser/visitor.ts +794 -0
- package/src/parser.ts +2 -0
- package/src/runtime/ai/cache-chunking.test.ts +69 -0
- package/src/runtime/ai/cache-chunking.ts +73 -0
- package/src/runtime/ai/client.ts +109 -0
- package/src/runtime/ai/context.ts +168 -0
- package/src/runtime/ai/formatters.ts +316 -0
- package/src/runtime/ai/index.ts +38 -0
- package/src/runtime/ai/language-ref.ts +38 -0
- package/src/runtime/ai/providers/anthropic.ts +253 -0
- package/src/runtime/ai/providers/google.ts +201 -0
- package/src/runtime/ai/providers/openai.ts +156 -0
- package/src/runtime/ai/retry.ts +100 -0
- package/src/runtime/ai/return-tools.ts +301 -0
- package/src/runtime/ai/test/client.test.ts +83 -0
- package/src/runtime/ai/test/formatters.test.ts +485 -0
- package/src/runtime/ai/test/retry.test.ts +137 -0
- package/src/runtime/ai/test/return-tools.test.ts +450 -0
- package/src/runtime/ai/test/tool-loop.test.ts +319 -0
- package/src/runtime/ai/test/tool-schema.test.ts +241 -0
- package/src/runtime/ai/tool-loop.ts +203 -0
- package/src/runtime/ai/tool-schema.ts +151 -0
- package/src/runtime/ai/types.ts +113 -0
- package/src/runtime/ai-logger.ts +255 -0
- package/src/runtime/ai-provider.ts +347 -0
- package/src/runtime/async/dependencies.ts +276 -0
- package/src/runtime/async/executor.ts +293 -0
- package/src/runtime/async/index.ts +43 -0
- package/src/runtime/async/scheduling.ts +163 -0
- package/src/runtime/async/test/dependencies.test.ts +284 -0
- package/src/runtime/async/test/executor.test.ts +388 -0
- package/src/runtime/context.ts +357 -0
- package/src/runtime/exec/ai.ts +139 -0
- package/src/runtime/exec/expressions.ts +475 -0
- package/src/runtime/exec/frames.ts +26 -0
- package/src/runtime/exec/functions.ts +305 -0
- package/src/runtime/exec/interpolation.ts +312 -0
- package/src/runtime/exec/statements.ts +604 -0
- package/src/runtime/exec/tools.ts +129 -0
- package/src/runtime/exec/typescript.ts +215 -0
- package/src/runtime/exec/variables.ts +279 -0
- package/src/runtime/index.ts +975 -0
- package/src/runtime/modules.ts +452 -0
- package/src/runtime/serialize.ts +103 -0
- package/src/runtime/state.ts +489 -0
- package/src/runtime/stdlib/core.ts +45 -0
- package/src/runtime/stdlib/directory.test.ts +156 -0
- package/src/runtime/stdlib/edit.test.ts +154 -0
- package/src/runtime/stdlib/fastEdit.test.ts +201 -0
- package/src/runtime/stdlib/glob.test.ts +106 -0
- package/src/runtime/stdlib/grep.test.ts +144 -0
- package/src/runtime/stdlib/index.ts +16 -0
- package/src/runtime/stdlib/readFile.test.ts +123 -0
- package/src/runtime/stdlib/tools/index.ts +707 -0
- package/src/runtime/stdlib/writeFile.test.ts +157 -0
- package/src/runtime/step.ts +969 -0
- package/src/runtime/test/ai-context.test.ts +1086 -0
- package/src/runtime/test/ai-result-object.test.ts +419 -0
- package/src/runtime/test/ai-tool-flow.test.ts +859 -0
- package/src/runtime/test/async-execution-order.test.ts +618 -0
- package/src/runtime/test/async-execution.test.ts +344 -0
- package/src/runtime/test/async-nested.test.ts +660 -0
- package/src/runtime/test/async-parallel-timing.test.ts +546 -0
- package/src/runtime/test/basic1.test.ts +154 -0
- package/src/runtime/test/binary-operators.test.ts +431 -0
- package/src/runtime/test/break-statement.test.ts +257 -0
- package/src/runtime/test/context-modes.test.ts +650 -0
- package/src/runtime/test/context.test.ts +466 -0
- package/src/runtime/test/core-functions.test.ts +228 -0
- package/src/runtime/test/e2e.test.ts +88 -0
- package/src/runtime/test/error-locations/error-locations.test.ts +80 -0
- package/src/runtime/test/error-locations/main-error.vibe +4 -0
- package/src/runtime/test/error-locations/main-import-error.vibe +3 -0
- package/src/runtime/test/error-locations/utils/helper.vibe +5 -0
- package/src/runtime/test/for-in.test.ts +312 -0
- package/src/runtime/test/helpers.ts +69 -0
- package/src/runtime/test/imports.test.ts +334 -0
- package/src/runtime/test/json-expressions.test.ts +232 -0
- package/src/runtime/test/literals.test.ts +372 -0
- package/src/runtime/test/logical-indexing.test.ts +478 -0
- package/src/runtime/test/member-methods.test.ts +324 -0
- package/src/runtime/test/model-config.test.ts +338 -0
- package/src/runtime/test/null-handling.test.ts +342 -0
- package/src/runtime/test/private-visibility.test.ts +332 -0
- package/src/runtime/test/runtime-state.test.ts +514 -0
- package/src/runtime/test/scoping.test.ts +370 -0
- package/src/runtime/test/string-interpolation.test.ts +354 -0
- package/src/runtime/test/template-literal.test.ts +181 -0
- package/src/runtime/test/tool-execution.test.ts +467 -0
- package/src/runtime/test/tool-schema-generation.test.ts +477 -0
- package/src/runtime/test/tostring.test.ts +210 -0
- package/src/runtime/test/ts-block.test.ts +594 -0
- package/src/runtime/test/ts-error-location.test.ts +231 -0
- package/src/runtime/test/types.test.ts +732 -0
- package/src/runtime/test/verbose-logger.test.ts +710 -0
- package/src/runtime/test/vibe-expression.test.ts +54 -0
- package/src/runtime/test/vibe-value-errors.test.ts +541 -0
- package/src/runtime/test/while.test.ts +232 -0
- package/src/runtime/tools/builtin.ts +30 -0
- package/src/runtime/tools/directory-tools.ts +70 -0
- package/src/runtime/tools/file-tools.ts +228 -0
- package/src/runtime/tools/index.ts +5 -0
- package/src/runtime/tools/registry.ts +48 -0
- package/src/runtime/tools/search-tools.ts +134 -0
- package/src/runtime/tools/security.ts +36 -0
- package/src/runtime/tools/system-tools.ts +312 -0
- package/src/runtime/tools/test/fixtures/base-types.ts +40 -0
- package/src/runtime/tools/test/fixtures/test-types.ts +132 -0
- package/src/runtime/tools/test/registry.test.ts +713 -0
- package/src/runtime/tools/test/security.test.ts +86 -0
- package/src/runtime/tools/test/system-tools.test.ts +679 -0
- package/src/runtime/tools/test/ts-schema.test.ts +357 -0
- package/src/runtime/tools/ts-schema.ts +341 -0
- package/src/runtime/tools/types.ts +89 -0
- package/src/runtime/tools/utility-tools.ts +198 -0
- package/src/runtime/ts-eval.ts +126 -0
- package/src/runtime/types.ts +797 -0
- package/src/runtime/validation.ts +160 -0
- package/src/runtime/verbose-logger.ts +459 -0
- package/src/runtime.ts +2 -0
- package/src/semantic/analyzer-context.ts +62 -0
- package/src/semantic/analyzer-validators.ts +575 -0
- package/src/semantic/analyzer-visitors.ts +534 -0
- package/src/semantic/analyzer.ts +83 -0
- package/src/semantic/index.ts +11 -0
- package/src/semantic/symbol-table.ts +58 -0
- package/src/semantic/test/async-validation.test.ts +301 -0
- package/src/semantic/test/compress-validation.test.ts +179 -0
- package/src/semantic/test/const-reassignment.test.ts +111 -0
- package/src/semantic/test/control-flow.test.ts +346 -0
- package/src/semantic/test/destructuring.test.ts +185 -0
- package/src/semantic/test/duplicate-declarations.test.ts +168 -0
- package/src/semantic/test/export-validation.test.ts +111 -0
- package/src/semantic/test/fixtures/math.ts +31 -0
- package/src/semantic/test/imports.test.ts +148 -0
- package/src/semantic/test/json-type.test.ts +68 -0
- package/src/semantic/test/literals.test.ts +127 -0
- package/src/semantic/test/model-validation.test.ts +179 -0
- package/src/semantic/test/prompt-validation.test.ts +343 -0
- package/src/semantic/test/scoping.test.ts +312 -0
- package/src/semantic/test/tool-validation.test.ts +306 -0
- package/src/semantic/test/ts-type-checking.test.ts +563 -0
- package/src/semantic/test/type-constraints.test.ts +111 -0
- package/src/semantic/test/type-inference.test.ts +87 -0
- package/src/semantic/test/type-validation.test.ts +552 -0
- package/src/semantic/test/undefined-variables.test.ts +163 -0
- package/src/semantic/ts-block-checker.ts +204 -0
- package/src/semantic/ts-signatures.ts +194 -0
- package/src/semantic/ts-types.ts +170 -0
- package/src/semantic/types.ts +58 -0
- package/tests/fixtures/conditional-logic.vibe +14 -0
- package/tests/fixtures/function-call.vibe +16 -0
- package/tests/fixtures/imports/cycle-detection/a.vibe +6 -0
- package/tests/fixtures/imports/cycle-detection/b.vibe +5 -0
- package/tests/fixtures/imports/cycle-detection/main.vibe +3 -0
- package/tests/fixtures/imports/module-isolation/main-b.vibe +8 -0
- package/tests/fixtures/imports/module-isolation/main.vibe +9 -0
- package/tests/fixtures/imports/module-isolation/moduleA.vibe +6 -0
- package/tests/fixtures/imports/module-isolation/moduleB.vibe +6 -0
- package/tests/fixtures/imports/nested-import/helper.vibe +6 -0
- package/tests/fixtures/imports/nested-import/main.vibe +3 -0
- package/tests/fixtures/imports/nested-import/utils.ts +3 -0
- package/tests/fixtures/imports/nested-isolation/file2.vibe +15 -0
- package/tests/fixtures/imports/nested-isolation/file3.vibe +10 -0
- package/tests/fixtures/imports/nested-isolation/main.vibe +21 -0
- package/tests/fixtures/imports/pure-cycle/a.vibe +5 -0
- package/tests/fixtures/imports/pure-cycle/b.vibe +5 -0
- package/tests/fixtures/imports/pure-cycle/main.vibe +3 -0
- package/tests/fixtures/imports/ts-boolean/checks.ts +14 -0
- package/tests/fixtures/imports/ts-boolean/main.vibe +10 -0
- package/tests/fixtures/imports/ts-boolean/type-mismatch.vibe +5 -0
- package/tests/fixtures/imports/ts-boolean/use-constant.vibe +18 -0
- package/tests/fixtures/imports/ts-error-handling/helpers.ts +42 -0
- package/tests/fixtures/imports/ts-error-handling/main.vibe +5 -0
- package/tests/fixtures/imports/ts-import/main.vibe +4 -0
- package/tests/fixtures/imports/ts-import/math.ts +9 -0
- package/tests/fixtures/imports/ts-variables/call-non-function.vibe +5 -0
- package/tests/fixtures/imports/ts-variables/data.ts +10 -0
- package/tests/fixtures/imports/ts-variables/import-json.vibe +5 -0
- package/tests/fixtures/imports/ts-variables/import-type-mismatch.vibe +5 -0
- package/tests/fixtures/imports/ts-variables/import-variable.vibe +5 -0
- package/tests/fixtures/imports/vibe-import/greet.vibe +5 -0
- package/tests/fixtures/imports/vibe-import/main.vibe +3 -0
- package/tests/fixtures/multiple-ai-calls.vibe +10 -0
- package/tests/fixtures/simple-greeting.vibe +6 -0
- package/tests/fixtures/template-literals.vibe +11 -0
- package/tests/integration/basic-ai/basic-ai.integration.test.ts +166 -0
- package/tests/integration/basic-ai/basic-ai.vibe +12 -0
- package/tests/integration/bug-fix/bug-fix.integration.test.ts +201 -0
- package/tests/integration/bug-fix/buggy-code.ts +22 -0
- package/tests/integration/bug-fix/fix-bug.vibe +21 -0
- package/tests/integration/compress/compress.integration.test.ts +206 -0
- package/tests/integration/destructuring/destructuring.integration.test.ts +92 -0
- package/tests/integration/hello-world-translator/hello-world-translator.integration.test.ts +61 -0
- package/tests/integration/line-annotator/context-modes.integration.test.ts +261 -0
- package/tests/integration/line-annotator/line-annotator.integration.test.ts +148 -0
- package/tests/integration/multi-feature/cumulative-sum.integration.test.ts +75 -0
- package/tests/integration/multi-feature/number-analyzer.integration.test.ts +191 -0
- package/tests/integration/multi-feature/number-analyzer.vibe +59 -0
- 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
|
+
}
|