dirac-lang 0.1.2
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/.env.example +8 -0
- package/COMMUNITY.md +465 -0
- package/LIBRARIES.md +172 -0
- package/NAMESPACES.md +366 -0
- package/PROMOTION.md +257 -0
- package/QUICKSTART-LIBRARY.md +93 -0
- package/README.md +257 -0
- package/config.yml +6 -0
- package/config.yml.openai +4 -0
- package/dirac-http/examples/demo.di +9 -0
- package/dirac-http/lib/index.di +12 -0
- package/dist/chunk-NDIRTD3D.js +217 -0
- package/dist/chunk-S625X7ME.js +1071 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +261 -0
- package/dist/index.d.ts +144 -0
- package/dist/index.js +22 -0
- package/dist/session-4QG7OERD.js +42 -0
- package/examples/add-demo.di +74 -0
- package/examples/add.bk +11 -0
- package/examples/advanced-math-demo.di +53 -0
- package/examples/calculator.di +32 -0
- package/examples/comprehensive.bk +29 -0
- package/examples/defvar-variable-demo.di +18 -0
- package/examples/direct-call.di +17 -0
- package/examples/disk-analysis.di +16 -0
- package/examples/executable-hello.di +7 -0
- package/examples/execute-demo.di +38 -0
- package/examples/file-manager.di +77 -0
- package/examples/file-stats.di +18 -0
- package/examples/hello.bk +1 -0
- package/examples/hello.di +5 -0
- package/examples/import-demo.di +31 -0
- package/examples/inline-test.bk +7 -0
- package/examples/lib/advanced-math.di +81 -0
- package/examples/lib/fileops.di +26 -0
- package/examples/lib/math.di +25 -0
- package/examples/lib/mongodb.di +96 -0
- package/examples/llm-agent.di +32 -0
- package/examples/llm-basic.di +12 -0
- package/examples/llm-command-no-exec.di +13 -0
- package/examples/llm-command.di +13 -0
- package/examples/llm-complex.di +141 -0
- package/examples/llm-recursive.di +31 -0
- package/examples/llm-reflection-test.di +19 -0
- package/examples/llm-subs.di +132 -0
- package/examples/llm-use-subs.di +6 -0
- package/examples/loop.di +12 -0
- package/examples/math-test.di +22 -0
- package/examples/mongodb-count-events.di +8 -0
- package/examples/mongodb-import-demo.di +25 -0
- package/examples/mongodb-simple-test.di +18 -0
- package/examples/nl-agent.di +47 -0
- package/examples/parameters-demo.di +68 -0
- package/examples/params-test.di +10 -0
- package/examples/recipe-chain.di +38 -0
- package/examples/recursive-llm.di +44 -0
- package/examples/sample-library/README.md +152 -0
- package/examples/sample-library/examples/demo.di +34 -0
- package/examples/sample-library/lib/index.di +65 -0
- package/examples/sample-library/package.json +31 -0
- package/examples/seamless.di +45 -0
- package/examples/shell-test.bk +10 -0
- package/examples/simple-import.di +13 -0
- package/examples/simple-recursive.di +26 -0
- package/examples/story-builder.di +45 -0
- package/examples/subroutine.di +23 -0
- package/examples/system-llm.di +21 -0
- package/examples/system-simple.di +3 -0
- package/examples/system-test.di +13 -0
- package/examples/task-assistant.di +27 -0
- package/examples/test-parameters.di +50 -0
- package/examples/two-styles.di +28 -0
- package/examples/var-debug.di +6 -0
- package/examples/var-inline.di +4 -0
- package/examples/var-test2.di +6 -0
- package/examples/variable-simple.di +16 -0
- package/examples/variable-test.di +22 -0
- package/filePath +1 -0
- package/greeting.txt +1 -0
- package/package.json +41 -0
- package/src/cli.ts +118 -0
- package/src/index.ts +33 -0
- package/src/llm/ollama.ts +58 -0
- package/src/runtime/braket-parser.ts +234 -0
- package/src/runtime/interpreter.ts +135 -0
- package/src/runtime/parser.ts +151 -0
- package/src/runtime/session.ts +228 -0
- package/src/tags/assign.ts +37 -0
- package/src/tags/call.ts +156 -0
- package/src/tags/defvar.ts +56 -0
- package/src/tags/eval.ts +68 -0
- package/src/tags/execute.ts +52 -0
- package/src/tags/expr.ts +128 -0
- package/src/tags/if.ts +58 -0
- package/src/tags/import.ts +66 -0
- package/src/tags/index.ts +37 -0
- package/src/tags/llm.ts +207 -0
- package/src/tags/loop.ts +43 -0
- package/src/tags/mongodb.ts +70 -0
- package/src/tags/output.ts +23 -0
- package/src/tags/parameters.ts +79 -0
- package/src/tags/require_module.ts +19 -0
- package/src/tags/subroutine.ts +52 -0
- package/src/tags/system.ts +70 -0
- package/src/tags/variable.ts +25 -0
- package/src/types/index.ts +101 -0
- package/src/utils/llm-adapter.ts +113 -0
- package/tools/create-library.sh +175 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <parameters> tag - Access parameters passed to subroutine
|
|
3
|
+
* Maps to MASK parameter selection syntax
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { DiracSession, DiracElement } from '../types/index.js';
|
|
7
|
+
import { getCurrentParameters, emit, setVariable } from '../runtime/session.js';
|
|
8
|
+
import { integrate } from '../runtime/interpreter.js';
|
|
9
|
+
|
|
10
|
+
export async function executeParameters(session: DiracSession, element: DiracElement): Promise<string | void> {
|
|
11
|
+
const select = element.attributes.select;
|
|
12
|
+
|
|
13
|
+
if (!select) {
|
|
14
|
+
throw new Error('<parameters> requires select attribute');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Get parameters from current call context
|
|
18
|
+
const params = getCurrentParameters(session);
|
|
19
|
+
|
|
20
|
+
if (!params || params.length === 0) {
|
|
21
|
+
if (session.debug) {
|
|
22
|
+
console.error(`[PARAMETERS] No parameters available`);
|
|
23
|
+
}
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// The caller element is params[0] (the calling tag itself)
|
|
28
|
+
const caller = params[0];
|
|
29
|
+
|
|
30
|
+
if (select === '*') {
|
|
31
|
+
// Select all child elements - execute them and RETURN output
|
|
32
|
+
if (session.debug) {
|
|
33
|
+
console.error(`[PARAMETERS] Selecting all children (${caller.children.length} elements)`);
|
|
34
|
+
}
|
|
35
|
+
// Save current output buffer
|
|
36
|
+
const prevOutput = session.output;
|
|
37
|
+
session.output = [];
|
|
38
|
+
for (const child of caller.children) {
|
|
39
|
+
await integrate(session, child);
|
|
40
|
+
}
|
|
41
|
+
const captured = session.output.join('');
|
|
42
|
+
session.output = prevOutput;
|
|
43
|
+
return captured;
|
|
44
|
+
} else if (select.startsWith('@')) {
|
|
45
|
+
// Select attribute(s)
|
|
46
|
+
const attrName = select.slice(1); // Remove '@'
|
|
47
|
+
|
|
48
|
+
if (attrName === '*') {
|
|
49
|
+
// Select all attributes
|
|
50
|
+
if (session.debug) {
|
|
51
|
+
console.error(`[PARAMETERS] Selecting all attributes`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const attrs = Object.entries(caller.attributes)
|
|
55
|
+
.map(([key, val]) => `${key}="${val}"`)
|
|
56
|
+
.join(' ');
|
|
57
|
+
emit(session, attrs);
|
|
58
|
+
|
|
59
|
+
} else {
|
|
60
|
+
// Select specific attribute - automatically create variable with that name
|
|
61
|
+
const value = caller.attributes[attrName];
|
|
62
|
+
|
|
63
|
+
if (session.debug) {
|
|
64
|
+
console.error(`[PARAMETERS] Setting variable '${attrName}' = '${value}'`);
|
|
65
|
+
}
|
|
66
|
+
if (value !== undefined) {
|
|
67
|
+
setVariable(session, attrName, value, false);
|
|
68
|
+
// Debug: print variable stack after setting
|
|
69
|
+
console.error(`[PARAMETERS] Variable stack after setting '${attrName}':`, JSON.stringify(session.variables));
|
|
70
|
+
}
|
|
71
|
+
for (const child of element.children) {
|
|
72
|
+
await integrate(session, child);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
} else {
|
|
77
|
+
throw new Error(`<parameters> invalid select: ${select}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { DiracSession, DiracElement } from '../types/index.js';
|
|
2
|
+
import { setVariable } from '../runtime/session.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* <require_module name="mongodb" var="mongo" />
|
|
6
|
+
* Loads a Node.js module and stores it in a session variable.
|
|
7
|
+
*/
|
|
8
|
+
export async function executeRequireModule(session: DiracSession, element: DiracElement): Promise<void> {
|
|
9
|
+
const name = element.attributes.name;
|
|
10
|
+
const varName = element.attributes.var || name;
|
|
11
|
+
if (!name) throw new Error('<require_module> missing name attribute');
|
|
12
|
+
try {
|
|
13
|
+
// Dynamically import the module (ESM compatible)
|
|
14
|
+
const mod = await import(name);
|
|
15
|
+
setVariable(session, varName, mod, true); // visible: true
|
|
16
|
+
} catch (err) {
|
|
17
|
+
throw new Error(`<require_module> failed to load module '${name}': ${err}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <subroutine> tag - define reusable code block
|
|
3
|
+
* Maps to mask_tag_subroutine in MASK
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { DiracSession, DiracElement, ParameterMetadata } from '../types/index.js';
|
|
7
|
+
import { registerSubroutine } from '../runtime/session.js';
|
|
8
|
+
|
|
9
|
+
export function executeSubroutine(session: DiracSession, element: DiracElement): void {
|
|
10
|
+
const name = element.attributes.name;
|
|
11
|
+
|
|
12
|
+
if (!name) {
|
|
13
|
+
throw new Error('<subroutine> requires name attribute');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Extract metadata from attributes (no structural changes!)
|
|
17
|
+
const description = element.attributes.description;
|
|
18
|
+
const parameters: ParameterMetadata[] = [];
|
|
19
|
+
|
|
20
|
+
// Parse param- prefixed attributes for metadata
|
|
21
|
+
// e.g., param-color="string:required:Color name:red|blue|green"
|
|
22
|
+
for (const [attrName, attrValue] of Object.entries(element.attributes)) {
|
|
23
|
+
if (attrName.startsWith('param-')) {
|
|
24
|
+
const paramName = attrName.substring(6); // Remove "param-" prefix
|
|
25
|
+
|
|
26
|
+
// Parse format: "type:required:description:enum1|enum2|..."
|
|
27
|
+
const parts = attrValue.split(':');
|
|
28
|
+
const paramMeta: ParameterMetadata = {
|
|
29
|
+
name: paramName,
|
|
30
|
+
type: parts[0] || 'string',
|
|
31
|
+
required: parts[1] === 'required',
|
|
32
|
+
description: parts[2] || undefined,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Parse enum if present (after 3rd colon)
|
|
36
|
+
if (parts[3]) {
|
|
37
|
+
paramMeta.enum = parts[3].split('|');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
parameters.push(paramMeta);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Store subroutine exactly as before (preserves nesting and extends)
|
|
45
|
+
const subroutine: DiracElement = {
|
|
46
|
+
tag: 'subroutine',
|
|
47
|
+
attributes: { ...element.attributes },
|
|
48
|
+
children: element.children,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
registerSubroutine(session, name, subroutine, description, parameters.length > 0 ? parameters : undefined);
|
|
52
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <system> tag - Execute shell commands
|
|
3
|
+
* Spawns a Unix process and runs the command
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { DiracSession, DiracElement } from '../types/index.js';
|
|
7
|
+
import { substituteVariables, emit } from '../runtime/session.js';
|
|
8
|
+
import { exec } from 'child_process';
|
|
9
|
+
import { promisify } from 'util';
|
|
10
|
+
import { integrate } from '../runtime/interpreter.js';
|
|
11
|
+
|
|
12
|
+
const execAsync = promisify(exec);
|
|
13
|
+
|
|
14
|
+
export async function executeSystem(session: DiracSession, element: DiracElement): Promise<void> {
|
|
15
|
+
// Build command from text content or children
|
|
16
|
+
let command: string;
|
|
17
|
+
|
|
18
|
+
// Check if has non-text children (actual element children)
|
|
19
|
+
const hasElementChildren = element.children.some(child => child.tag !== '');
|
|
20
|
+
|
|
21
|
+
if (hasElementChildren) {
|
|
22
|
+
// Execute children to build command dynamically
|
|
23
|
+
const beforeOutput = session.output.length;
|
|
24
|
+
|
|
25
|
+
for (const child of element.children) {
|
|
26
|
+
await integrate(session, child);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Collect output from children as the command
|
|
30
|
+
const childOutput = session.output.slice(beforeOutput);
|
|
31
|
+
command = childOutput.join('');
|
|
32
|
+
|
|
33
|
+
// Remove child output from main output
|
|
34
|
+
session.output = session.output.slice(0, beforeOutput);
|
|
35
|
+
} else if (element.text) {
|
|
36
|
+
// Simple text command with variable substitution
|
|
37
|
+
command = substituteVariables(session, element.text);
|
|
38
|
+
} else {
|
|
39
|
+
throw new Error('<system> requires command content');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!command.trim()) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (session.debug) {
|
|
47
|
+
console.error(`[SYSTEM] Executing: ${command}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
const { stdout, stderr } = await execAsync(command, {
|
|
52
|
+
encoding: 'utf-8',
|
|
53
|
+
maxBuffer: 10 * 1024 * 1024, // 10MB buffer
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Emit stdout
|
|
57
|
+
if (stdout) {
|
|
58
|
+
emit(session, stdout);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Emit stderr if debug mode
|
|
62
|
+
if (stderr && session.debug) {
|
|
63
|
+
console.error(`[SYSTEM STDERR] ${stderr}`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
} catch (error: any) {
|
|
67
|
+
const errorMsg = error.message || String(error);
|
|
68
|
+
throw new Error(`System command failed: ${errorMsg}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <variable> tag - retrieve variable value
|
|
3
|
+
* Outputs the stored variable content (text or tags)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { DiracSession, DiracElement } from '../types/index.js';
|
|
7
|
+
import { getVariable, emit } from '../runtime/session.js';
|
|
8
|
+
|
|
9
|
+
export function executeVariable(session: DiracSession, element: DiracElement): void {
|
|
10
|
+
const name = element.attributes.name;
|
|
11
|
+
if (!name) {
|
|
12
|
+
// Debug: print the full element for diagnosis
|
|
13
|
+
console.error('[VariableTagError] <variable> tag missing name attribute:', JSON.stringify(element));
|
|
14
|
+
throw new Error('<variable> requires name attribute');
|
|
15
|
+
}
|
|
16
|
+
const value = getVariable(session, name);
|
|
17
|
+
if (value === undefined) {
|
|
18
|
+
if (session.debug) {
|
|
19
|
+
console.error(`[Warning] Variable '${name}' is undefined`);
|
|
20
|
+
}
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// Output the variable value
|
|
24
|
+
emit(session, String(value));
|
|
25
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types for Dirac interpreter
|
|
3
|
+
* Directly based on MASK C implementation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface DiracElement {
|
|
7
|
+
tag: string;
|
|
8
|
+
attributes: Record<string, string>;
|
|
9
|
+
children: DiracElement[];
|
|
10
|
+
text?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Variable info - maps to VarInfo in MASK
|
|
15
|
+
*/
|
|
16
|
+
export interface Variable {
|
|
17
|
+
name: string;
|
|
18
|
+
value: any;
|
|
19
|
+
visible: boolean;
|
|
20
|
+
boundary: number; // scope boundary marker
|
|
21
|
+
passby: 'value' | 'ref';
|
|
22
|
+
refName?: string; // for pass-by-reference
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Parameter metadata for introspection
|
|
27
|
+
*/
|
|
28
|
+
export interface ParameterMetadata {
|
|
29
|
+
name: string;
|
|
30
|
+
type?: string;
|
|
31
|
+
required?: boolean;
|
|
32
|
+
description?: string;
|
|
33
|
+
enum?: string[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Subroutine info - maps to Subroutine in MASK
|
|
38
|
+
*/
|
|
39
|
+
export interface Subroutine {
|
|
40
|
+
name: string;
|
|
41
|
+
element: DiracElement;
|
|
42
|
+
boundary: number; // scope boundary marker
|
|
43
|
+
extends?: string; // parent subroutine
|
|
44
|
+
// Metadata for reflection/introspection
|
|
45
|
+
description?: string;
|
|
46
|
+
parameters?: ParameterMetadata[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Execution context - maps to MaskSession in MASK
|
|
51
|
+
*/
|
|
52
|
+
export interface DiracSession {
|
|
53
|
+
// Variable stack (all variables are on stack)
|
|
54
|
+
variables: Variable[];
|
|
55
|
+
|
|
56
|
+
// Subroutine registry
|
|
57
|
+
subroutines: Subroutine[];
|
|
58
|
+
|
|
59
|
+
// Scope boundaries (for cleanup)
|
|
60
|
+
varBoundary: number;
|
|
61
|
+
subBoundary: number;
|
|
62
|
+
|
|
63
|
+
// Parameter stack (for subroutine calls)
|
|
64
|
+
parameterStack: DiracElement[][];
|
|
65
|
+
|
|
66
|
+
// Output buffer
|
|
67
|
+
output: string[];
|
|
68
|
+
|
|
69
|
+
// LLM client
|
|
70
|
+
llmClient?: any;
|
|
71
|
+
|
|
72
|
+
// Execution limits
|
|
73
|
+
limits: {
|
|
74
|
+
maxLLMCalls: number;
|
|
75
|
+
currentLLMCalls: number;
|
|
76
|
+
maxDepth: number;
|
|
77
|
+
currentDepth: number;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// Control flow
|
|
81
|
+
isReturn: boolean;
|
|
82
|
+
isBreak: boolean;
|
|
83
|
+
|
|
84
|
+
// Debugging
|
|
85
|
+
debug: boolean;
|
|
86
|
+
|
|
87
|
+
// Import tracking
|
|
88
|
+
currentFile?: string;
|
|
89
|
+
importedFiles?: Set<string>;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface DiracConfig {
|
|
93
|
+
apiKey?: string;
|
|
94
|
+
model?: string;
|
|
95
|
+
debug?: boolean;
|
|
96
|
+
maxLLMCalls?: number;
|
|
97
|
+
maxDepth?: number;
|
|
98
|
+
filePath?: string; // Current file path for imports
|
|
99
|
+
llmProvider?: string;
|
|
100
|
+
llmModel?: string;
|
|
101
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM Adapter - Auto-generate prompts and JSON→XML converters
|
|
3
|
+
* from Dirac subroutine definitions
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { DiracSession } from '../types/index.js';
|
|
7
|
+
import { getAvailableSubroutines } from '../runtime/session.js';
|
|
8
|
+
|
|
9
|
+
export interface LLMPromptGenerator {
|
|
10
|
+
generatePrompt(userInput: string): string;
|
|
11
|
+
intentToXML(intent: any): string | null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Create LLM adapter from session's registered subroutines
|
|
16
|
+
*/
|
|
17
|
+
export function createLLMAdapter(session: DiracSession): LLMPromptGenerator {
|
|
18
|
+
const subroutines = getAvailableSubroutines(session);
|
|
19
|
+
|
|
20
|
+
// Build JSON schema from subroutines
|
|
21
|
+
const actions = subroutines.map(s => `"${s.name}"`).join('|');
|
|
22
|
+
|
|
23
|
+
// Build examples
|
|
24
|
+
const examples = subroutines.slice(0, 3).map(sub => {
|
|
25
|
+
if (!sub.parameters || sub.parameters.length === 0) {
|
|
26
|
+
return `"${sub.name}" → {"action":"${sub.name}","params":{}}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const firstParam = sub.parameters[0];
|
|
30
|
+
const exampleValue = firstParam.enum?.[0] || 'value';
|
|
31
|
+
return `"call ${sub.name}" → {"action":"${sub.name}","params":{"${firstParam.name}":"${exampleValue}"}}`;
|
|
32
|
+
}).join('\n');
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
generatePrompt(userInput: string): string {
|
|
36
|
+
return `You are a command parser. Convert user input to JSON.
|
|
37
|
+
Return ONLY valid JSON, no other text.
|
|
38
|
+
|
|
39
|
+
Format: {"action": ${actions}, "params": {}}
|
|
40
|
+
|
|
41
|
+
Examples:
|
|
42
|
+
${examples}
|
|
43
|
+
|
|
44
|
+
User: ${userInput}
|
|
45
|
+
JSON:`;
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
intentToXML(intent: any): string | null {
|
|
49
|
+
if (!intent || !intent.action) return null;
|
|
50
|
+
|
|
51
|
+
const sub = subroutines.find(s => s.name === intent.action);
|
|
52
|
+
if (!sub) return null;
|
|
53
|
+
|
|
54
|
+
const attrs: string[] = [`name="${sub.name}"`];
|
|
55
|
+
|
|
56
|
+
// Map params to XML attributes
|
|
57
|
+
if (sub.parameters) {
|
|
58
|
+
for (const param of sub.parameters) {
|
|
59
|
+
const value = intent.params?.[param.name];
|
|
60
|
+
|
|
61
|
+
if (value != null) {
|
|
62
|
+
// Validate enum if present
|
|
63
|
+
if (param.enum && !param.enum.includes(value)) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
attrs.push(`${param.name}="${value}"`);
|
|
67
|
+
} else if (param.required) {
|
|
68
|
+
return null; // Missing required parameter
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return `<call ${attrs.join(' ')}/>`;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Higher-level helper: execute user command via LLM
|
|
80
|
+
*/
|
|
81
|
+
export async function executeUserCommand(
|
|
82
|
+
session: DiracSession,
|
|
83
|
+
userInput: string,
|
|
84
|
+
llmExecuteFn: (prompt: string) => Promise<string>
|
|
85
|
+
): Promise<{ success: boolean; xml?: string; error?: string }> {
|
|
86
|
+
try {
|
|
87
|
+
const adapter = createLLMAdapter(session);
|
|
88
|
+
const prompt = adapter.generatePrompt(userInput);
|
|
89
|
+
|
|
90
|
+
// Call LLM
|
|
91
|
+
const llmResponse = await llmExecuteFn(prompt);
|
|
92
|
+
|
|
93
|
+
// Parse JSON
|
|
94
|
+
let jsonStr = llmResponse.trim();
|
|
95
|
+
jsonStr = jsonStr.replace(/```json\s*/g, '').replace(/```\s*/g, '');
|
|
96
|
+
|
|
97
|
+
const intent = JSON.parse(jsonStr);
|
|
98
|
+
|
|
99
|
+
// Convert to XML
|
|
100
|
+
const xml = adapter.intentToXML(intent);
|
|
101
|
+
|
|
102
|
+
if (!xml) {
|
|
103
|
+
return { success: false, error: 'Could not convert intent to valid command' };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return { success: true, xml };
|
|
107
|
+
} catch (error) {
|
|
108
|
+
return {
|
|
109
|
+
success: false,
|
|
110
|
+
error: error instanceof Error ? error.message : String(error)
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Create a new Dirac library with proper structure
|
|
3
|
+
|
|
4
|
+
if [ -z "$1" ]; then
|
|
5
|
+
echo "Usage: ./create-library.sh <library-name>"
|
|
6
|
+
echo "Example: ./create-library.sh crypto"
|
|
7
|
+
exit 1
|
|
8
|
+
fi
|
|
9
|
+
|
|
10
|
+
LIBNAME="$1"
|
|
11
|
+
DIRNAME="dirac-$LIBNAME"
|
|
12
|
+
LIBNAME_UPPER=$(echo "$LIBNAME" | tr '[:lower:]' '[:upper:]')
|
|
13
|
+
|
|
14
|
+
echo "Creating Dirac library: $DIRNAME"
|
|
15
|
+
echo "Prefix convention: ${LIBNAME_UPPER}_"
|
|
16
|
+
echo ""
|
|
17
|
+
|
|
18
|
+
# Create directory structure
|
|
19
|
+
mkdir -p "$DIRNAME"/{lib,examples,tests}
|
|
20
|
+
|
|
21
|
+
# Create package.json
|
|
22
|
+
cat > "$DIRNAME/package.json" << EOF
|
|
23
|
+
{
|
|
24
|
+
"name": "dirac-$LIBNAME",
|
|
25
|
+
"version": "0.1.0",
|
|
26
|
+
"description": "$LIBNAME library for Dirac",
|
|
27
|
+
"main": "lib/index.di",
|
|
28
|
+
"scripts": {
|
|
29
|
+
"test": "dirac tests/test.di",
|
|
30
|
+
"example": "dirac examples/demo.di"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"dirac",
|
|
34
|
+
"$LIBNAME"
|
|
35
|
+
],
|
|
36
|
+
"author": "",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/yourusername/dirac-$LIBNAME"
|
|
41
|
+
},
|
|
42
|
+
"dirac": {
|
|
43
|
+
"version": ">=0.1.0"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
EOF
|
|
47
|
+
|
|
48
|
+
# Create lib/index.di
|
|
49
|
+
cat > "$DIRNAME/lib/index.di" << 'DIRAC_EOF'
|
|
50
|
+
<dirac>
|
|
51
|
+
|
|
52
|
+
<!-- All tags use the library prefix to avoid naming conflicts -->
|
|
53
|
+
<subroutine name="LIBPREFIX_EXAMPLE">
|
|
54
|
+
<eval>
|
|
55
|
+
const caller = getParams();
|
|
56
|
+
const input = caller.attributes.input || 'no input';
|
|
57
|
+
console.log('Processed: ' + input);
|
|
58
|
+
</eval>
|
|
59
|
+
</subroutine>
|
|
60
|
+
|
|
61
|
+
</dirac>
|
|
62
|
+
DIRAC_EOF
|
|
63
|
+
|
|
64
|
+
# Replace the placeholder with actual library name
|
|
65
|
+
sed -i '' "s/LIBPREFIX_/${LIBNAME_UPPER}_/g" "$DIRNAME/lib/index.di"
|
|
66
|
+
|
|
67
|
+
# Create examples/demo.di
|
|
68
|
+
cat > "$DIRNAME/examples/demo.di" << EOF
|
|
69
|
+
#!/usr/bin/env dirac
|
|
70
|
+
<dirac>
|
|
71
|
+
<import src="../lib/index.di"/>
|
|
72
|
+
|
|
73
|
+
<output>Demo: </output>
|
|
74
|
+
<${LIBNAME_UPPER}_EXAMPLE input="test"/>
|
|
75
|
+
</dirac>
|
|
76
|
+
EOF
|
|
77
|
+
|
|
78
|
+
chmod +x "$DIRNAME/examples/demo.di"
|
|
79
|
+
|
|
80
|
+
# Create tests/test.di
|
|
81
|
+
cat > "$DIRNAME/tests/test.di" << 'EOF'
|
|
82
|
+
#!/usr/bin/env dirac
|
|
83
|
+
<dirac>
|
|
84
|
+
<import src="../lib/index.di"/>
|
|
85
|
+
|
|
86
|
+
<output>Running tests... </output>
|
|
87
|
+
<EXAMPLE input="test"/>
|
|
88
|
+
<output>Tests passed! </output>
|
|
89
|
+
</dirac>
|
|
90
|
+
EOF
|
|
91
|
+
|
|
92
|
+
chmod +x "$DIRNAME/tests/test.di"
|
|
93
|
+
|
|
94
|
+
# Create README.md
|
|
95
|
+
cat > "$DIRNAME/README.md" << EOF
|
|
96
|
+
# dirac-$LIBNAME
|
|
97
|
+
|
|
98
|
+
$LIBNAME library for Dirac.
|
|
99
|
+
|
|
100
|
+
## Installation
|
|
101
|
+
|
|
102
|
+
\`\`\`bash
|
|
103
|
+
npm install dirac-$LIBNAME
|
|
104
|
+
\`\`\`
|
|
105
|
+
|
|
106
|
+
## Usage
|
|
107
|
+
|
|
108
|
+
\`\`\`xml
|
|
109
|
+
<dirac>
|
|
110
|
+
<import src="./node_modules/dirac-$LIBNAME/lib/index.di"/>
|
|
111
|
+
|
|
112
|
+
<EXAMPLE input="hello"/>
|
|
113
|
+
</dirac>
|
|
114
|
+
\`\`\`
|
|
115
|
+
|
|
116
|
+
## API
|
|
117
|
+
|
|
118
|
+
### EXAMPLE
|
|
119
|
+
|
|
120
|
+
**Attributes:**
|
|
121
|
+
- \`input\` (string) - Input text
|
|
122
|
+
|
|
123
|
+
## Development
|
|
124
|
+
|
|
125
|
+
\`\`\`bash
|
|
126
|
+
# Run examples
|
|
127
|
+
npm run example
|
|
128
|
+
|
|
129
|
+
# Run tests
|
|
130
|
+
npm test
|
|
131
|
+
\`\`\`
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
MIT
|
|
136
|
+
EOF
|
|
137
|
+
|
|
138
|
+
# Create .gitignore
|
|
139
|
+
cat > "$DIRNAME/.gitignore" << 'EOF'
|
|
140
|
+
node_modules/
|
|
141
|
+
.DS_Store
|
|
142
|
+
*.log
|
|
143
|
+
EOF
|
|
144
|
+
|
|
145
|
+
# Create LICENSE
|
|
146
|
+
cat > "$DIRNAME/LICENSE" << 'EOF'
|
|
147
|
+
MIT License
|
|
148
|
+
|
|
149
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
150
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
151
|
+
in the Software without restriction, including without limitation the rights
|
|
152
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
153
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
154
|
+
furnished to do so, subject to the following conditions:
|
|
155
|
+
|
|
156
|
+
The above copyright notice and this permission notice shall be included in all
|
|
157
|
+
copies or substantial portions of the Software.
|
|
158
|
+
|
|
159
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
160
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
161
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
162
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
163
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
164
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
165
|
+
SOFTWARE.
|
|
166
|
+
EOF
|
|
167
|
+
|
|
168
|
+
echo "✅ Library created: $DIRNAME/"
|
|
169
|
+
echo ""
|
|
170
|
+
echo "Next steps:"
|
|
171
|
+
echo " cd $DIRNAME"
|
|
172
|
+
echo " npm run example # Test your library"
|
|
173
|
+
echo " npm test # Run tests"
|
|
174
|
+
echo " git init # Initialize git"
|
|
175
|
+
echo " npm publish # Publish to npm"
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"lib": ["ES2022"],
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"resolveJsonModule": true,
|
|
8
|
+
"outDir": "dist",
|
|
9
|
+
"rootDir": "src",
|
|
10
|
+
"strict": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"forceConsistentCasingInFileNames": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"sourceMap": true
|
|
16
|
+
},
|
|
17
|
+
"include": ["src/**/*"],
|
|
18
|
+
"exclude": ["node_modules", "dist"]
|
|
19
|
+
}
|