dirac-lang 0.1.24 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +13 -1
- package/lib/index.di +9 -0
- package/{examples/lib → lib}/math.di +3 -3
- package/package.json +13 -1
- package/.env.example +0 -8
- package/COMMUNITY.md +0 -465
- package/CONDITIONAL-TAGS.md +0 -172
- package/EXCEPTION-HANDLING.md +0 -156
- package/LIBRARIES.md +0 -172
- package/LLM-VALIDATION.md +0 -128
- package/NAMESPACES.md +0 -366
- package/PROMOTION.md +0 -257
- package/QUICKSTART-LIBRARY.md +0 -93
- package/TEST-COVERAGE.md +0 -113
- package/TESTING.md +0 -162
- package/config.test.yml +0 -5
- package/dirac-http/examples/demo.di +0 -9
- package/dirac-http/lib/index.di +0 -12
- package/examples/add-demo.di +0 -74
- package/examples/add.bk +0 -11
- package/examples/advanced-math-demo.di +0 -53
- package/examples/calculator.di +0 -32
- package/examples/compact-test.di +0 -6
- package/examples/comprehensive.bk +0 -29
- package/examples/defvar-variable-demo.di +0 -18
- package/examples/direct-call.di +0 -17
- package/examples/disk-analysis.di +0 -16
- package/examples/exception-demo.di +0 -82
- package/examples/executable-hello.di +0 -7
- package/examples/execute-demo.di +0 -38
- package/examples/file-manager.di +0 -77
- package/examples/file-stats.di +0 -18
- package/examples/hello.bk +0 -1
- package/examples/hello.di +0 -5
- package/examples/if-comparison.di +0 -91
- package/examples/if-cstyle-test.di +0 -149
- package/examples/if-vs-testif.di +0 -56
- package/examples/import-demo.di +0 -31
- package/examples/inline-test.bk +0 -7
- package/examples/llm-agent.di +0 -32
- package/examples/llm-basic.di +0 -12
- package/examples/llm-command-more.di +0 -6
- package/examples/llm-command-no-exec.di +0 -13
- package/examples/llm-command.di +0 -6
- package/examples/llm-complex.di +0 -141
- package/examples/llm-feedback-debug.di +0 -30
- package/examples/llm-feedback-demo.di +0 -19
- package/examples/llm-feedback-math.di +0 -22
- package/examples/llm-feedback-simple.di +0 -16
- package/examples/llm-feedback-sub.di +0 -22
- package/examples/llm-no-feedback.di +0 -10
- package/examples/llm-recursive.di +0 -31
- package/examples/llm-reflection-test.di +0 -19
- package/examples/llm-simple-test.di +0 -12
- package/examples/llm-subs.di +0 -132
- package/examples/llm-use-subs.di +0 -6
- package/examples/llm-validate-test.di +0 -18
- package/examples/loop.di +0 -12
- package/examples/math-test.di +0 -22
- package/examples/minimal-test.di +0 -13
- package/examples/mongodb-context-test.di +0 -27
- package/examples/mongodb-count-events.di +0 -8
- package/examples/mongodb-import-demo.di +0 -25
- package/examples/mongodb-simple-test.di +0 -18
- package/examples/nl-agent.di +0 -47
- package/examples/parameters-demo.di +0 -68
- package/examples/params-meta-test.di +0 -17
- package/examples/params-test.di +0 -10
- package/examples/recipe-chain.di +0 -38
- package/examples/recursive-llm.di +0 -44
- package/examples/sample-library/README.md +0 -152
- package/examples/sample-library/examples/demo.di +0 -34
- package/examples/sample-library/lib/index.di +0 -65
- package/examples/sample-library/package.json +0 -31
- package/examples/scope-test-nested.di +0 -60
- package/examples/scope-test.di +0 -55
- package/examples/seamless.di +0 -45
- package/examples/shell-test.bk +0 -10
- package/examples/simple-import.di +0 -13
- package/examples/simple-recursive.di +0 -26
- package/examples/story-builder.di +0 -45
- package/examples/subroutine.di +0 -23
- package/examples/system-llm.di +0 -21
- package/examples/system-simple.di +0 -3
- package/examples/system-test.di +0 -8
- package/examples/tag-check-test.di +0 -139
- package/examples/task-assistant.di +0 -27
- package/examples/test-if-demo.di +0 -110
- package/examples/test-parameters.di +0 -50
- package/examples/try-catch-test.di +0 -118
- package/examples/two-styles.di +0 -28
- package/examples/var-debug.di +0 -6
- package/examples/var-inline.di +0 -4
- package/examples/var-test2.di +0 -6
- package/examples/variable-replace.di +0 -25
- package/examples/variable-simple.di +0 -16
- package/examples/variable-test.di +0 -22
- package/examples/whitespace-test.di +0 -24
- package/filePath +0 -1
- package/greeting.txt +0 -1
- package/src/cli.ts +0 -140
- package/src/index.ts +0 -33
- package/src/llm/ollama.ts +0 -58
- package/src/runtime/braket-parser.ts +0 -234
- package/src/runtime/interpreter.ts +0 -203
- package/src/runtime/parser.ts +0 -155
- package/src/runtime/session.ts +0 -325
- package/src/tags/assign.ts +0 -37
- package/src/tags/attr.ts +0 -64
- package/src/tags/available-subroutines.ts +0 -70
- package/src/tags/call.ts +0 -259
- package/src/tags/catch.ts +0 -24
- package/src/tags/defvar.ts +0 -115
- package/src/tags/environment.ts +0 -21
- package/src/tags/eval.ts +0 -71
- package/src/tags/exception.ts +0 -20
- package/src/tags/execute.ts +0 -52
- package/src/tags/expr.ts +0 -128
- package/src/tags/foreach.ts +0 -170
- package/src/tags/if.ts +0 -191
- package/src/tags/import.ts +0 -135
- package/src/tags/index.ts +0 -41
- package/src/tags/input.ts +0 -182
- package/src/tags/llm.ts +0 -415
- package/src/tags/loop.ts +0 -43
- package/src/tags/mongodb.ts +0 -70
- package/src/tags/output.ts +0 -53
- package/src/tags/parameters.ts +0 -81
- package/src/tags/require_module.ts +0 -19
- package/src/tags/subroutine.ts +0 -75
- package/src/tags/system.ts +0 -93
- package/src/tags/tag-check.ts +0 -176
- package/src/tags/test-if.ts +0 -112
- package/src/tags/throw.ts +0 -26
- package/src/tags/try.ts +0 -19
- package/src/tags/variable.ts +0 -25
- package/src/test-runner.ts +0 -300
- package/src/types/index.ts +0 -128
- package/src/utils/llm-adapter.ts +0 -113
- package/src/utils/tag-validator.ts +0 -231
- package/test-available-extends.di +0 -28
- package/test-available-simple.di +0 -12
- package/test-available-subroutines.di +0 -16
- package/test-call.di +0 -9
- package/test-extend-basic.di +0 -17
- package/test-extend-chain.di +0 -26
- package/test-extend-debug.di +0 -17
- package/test-extend-debug2.di +0 -15
- package/test-extend-person.di +0 -17
- package/test-extend-simple.di +0 -11
- package/test-extend-zhi.di +0 -23
- package/test-extend.di +0 -19
- package/test-extend2.di +0 -26
- package/test-extend3-fixed.di +0 -23
- package/test-extend3-trouble.di +0 -23
- package/test-extend3.di +0 -21
- package/test-factorial.di +0 -19
- package/test-input-debug.di +0 -19
- package/test-nested-debug.di +0 -7
- package/test-nested-debug2.di +0 -8
- package/test-no-extend.di +0 -16
- package/test-simple-call.di +0 -7
- package/test-simple.di +0 -6
- package/tests/README.md +0 -69
- package/tests/assign-basic.test.di +0 -7
- package/tests/assign-from-eval.test.di +0 -7
- package/tests/available-subroutines-foreach.test.di +0 -32
- package/tests/basic-output.test.di +0 -5
- package/tests/call-basic.test.di +0 -11
- package/tests/call-with-output.test.di +0 -10
- package/tests/comments-before-content.test.di +0 -6
- package/tests/defvar-multiple.test.di +0 -8
- package/tests/environment-basic.test.di +0 -22
- package/tests/environment-nonexistent.test.di +0 -5
- package/tests/environment-with-defvar.test.di +0 -15
- package/tests/eval-basic.test.di +0 -6
- package/tests/eval-with-variables.test.di +0 -8
- package/tests/exception-basic.test.di +0 -10
- package/tests/expr-basic.test.di +0 -11
- package/tests/extend-basic.test.di +0 -19
- package/tests/extend-inheritance-chain.test.di +0 -26
- package/tests/extend-multiple-nested.test.di +0 -24
- package/tests/extend-self.test.di +0 -19
- package/tests/extend-with-parameters.test.di +0 -14
- package/tests/generate-dirac.test.di +0 -22
- package/tests/if-conditional.test.di +0 -17
- package/tests/if-else.test.di +0 -11
- package/tests/if-with-variables.test.di +0 -8
- package/tests/import-basic.test.di +0 -6
- package/tests/input-file-all.test.di +0 -5
- package/tests/input-file-line.test.di +0 -15
- package/tests/input-file-loop.test.di +0 -12
- package/tests/input-stdin-all.test.di +0 -8
- package/tests/input-stdin-all.txt +0 -1
- package/tests/llm-validate.test.di +0 -17
- package/tests/loop-basic.test.di +0 -9
- package/tests/loop-nested.test.di +0 -10
- package/tests/loop-with-eval.test.di +0 -8
- package/tests/no-root-element.test.di +0 -6
- package/tests/output-file.test.di +0 -19
- package/tests/output-multiple.test.di +0 -9
- package/tests/parameters-basic.test.di +0 -6
- package/tests/require-module-basic.test.di +0 -7
- package/tests/subroutine-basic.test.di +0 -9
- package/tests/subroutine-multiple-params.test.di +0 -10
- package/tests/subroutine-nested-calls.test.di +0 -32
- package/tests/subroutine-sequential-calls.test.di +0 -36
- package/tests/system-background.test.di +0 -39
- package/tests/system-basic.test.di +0 -5
- package/tests/tag-check.test.di +0 -27
- package/tests/test-if-basic.test.di +0 -8
- package/tests/test-input.txt +0 -3
- package/tests/try-catch-basic.test.di +0 -10
- package/tests/try-catch-eval-error.test.di +0 -10
- package/tests/variable-basic.test.di +0 -6
- package/tests/variable-interpolation.test.di +0 -7
- package/tools/create-library.sh +0 -175
- package/tsconfig.json +0 -19
- /package/{examples/lib → lib}/advanced-math.di +0 -0
- /package/{examples/lib → lib}/fileops.di +0 -0
- /package/{examples/lib → lib}/mongodb.di +0 -0
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
<dirac>
|
|
2
|
-
<subroutine name="test" param-color="string:required" >
|
|
3
|
-
<output>In test: <variable name="color" /></output>
|
|
4
|
-
<test2 color="$color" > I am in body: <variable name="color" /></test2>
|
|
5
|
-
</subroutine>
|
|
6
|
-
<subroutine name="test2" param-color="string:required" >
|
|
7
|
-
<output>in subroutine 2: <variable name="color" /></output>
|
|
8
|
-
<output><parameters select="*" /></output>
|
|
9
|
-
</subroutine>
|
|
10
|
-
|
|
11
|
-
<defvar name="index" value="1" />
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<loop count="2" var="i" >
|
|
15
|
-
i:<variable name="i" />
|
|
16
|
-
<if test="$i == 0" >
|
|
17
|
-
<test color="red" />
|
|
18
|
-
</if>
|
|
19
|
-
<if test="$i > 0" >
|
|
20
|
-
<test color="blue" />
|
|
21
|
-
</if>
|
|
22
|
-
</loop>
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
</dirac>
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
<dirac>
|
|
2
|
-
<!-- Test 1: Simple text variable -->
|
|
3
|
-
<defvar name="name">Alice</defvar>
|
|
4
|
-
<output>Hello, <variable name="name"/>!</output>
|
|
5
|
-
<output> </output>
|
|
6
|
-
|
|
7
|
-
<!-- Test 2: Using ${} substitution -->
|
|
8
|
-
<output>Using substitution: Hello, ${name}!</output>
|
|
9
|
-
<output> </output>
|
|
10
|
-
|
|
11
|
-
<!-- Test 3: Number variable -->
|
|
12
|
-
<defvar name="x">5</defvar>
|
|
13
|
-
<defvar name="y">3</defvar>
|
|
14
|
-
<output>x = <variable name="x"/>, y = <variable name="y"/></output>
|
|
15
|
-
<output> </output>
|
|
16
|
-
</dirac>
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<dirac>
|
|
2
|
-
<!-- Test 1: Simple text variable -->
|
|
3
|
-
<defvar name="name">Alice</defvar>
|
|
4
|
-
<output>Hello, <variable name="name"/>!</output>
|
|
5
|
-
<output> </output>
|
|
6
|
-
|
|
7
|
-
<!-- Test 2: Using ${} substitution -->
|
|
8
|
-
<output>Using substitution: Hello, ${name}!</output>
|
|
9
|
-
<output> </output>
|
|
10
|
-
|
|
11
|
-
<!-- Test 3: Variable with XML code as string -->
|
|
12
|
-
<defvar name="template"><output>Template says: Hello, <variable name="name"/>!</output></defvar>
|
|
13
|
-
|
|
14
|
-
<output>Raw template: </output>
|
|
15
|
-
<variable name="template"/>
|
|
16
|
-
<output> </output>
|
|
17
|
-
|
|
18
|
-
<!-- Test 4: Execute the template -->
|
|
19
|
-
<output>Executed: </output>
|
|
20
|
-
<execute source="template"/>
|
|
21
|
-
<output> </output>
|
|
22
|
-
</dirac>
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
<dirac>
|
|
2
|
-
<defvar name="dir">examples</defvar>
|
|
3
|
-
|
|
4
|
-
<output>Test 1 - Text with variable inline:</output>
|
|
5
|
-
<output> </output>
|
|
6
|
-
<output>Files in <variable name="dir" />:</output>
|
|
7
|
-
<output> </output>
|
|
8
|
-
<output> </output>
|
|
9
|
-
|
|
10
|
-
<output>Test 2 - System tag with variable:</output>
|
|
11
|
-
<output> </output>
|
|
12
|
-
<system>echo "ls -la <variable name="dir" />"</system>
|
|
13
|
-
<output> </output>
|
|
14
|
-
|
|
15
|
-
<output>Test 3 - Output tag content only:</output>
|
|
16
|
-
<output> </output>
|
|
17
|
-
<output>Files in examples:</output>
|
|
18
|
-
<output> </output>
|
|
19
|
-
|
|
20
|
-
<output>Test 4 - Variable value alone:</output>
|
|
21
|
-
<output> </output>
|
|
22
|
-
<variable name="dir" />
|
|
23
|
-
<output> </output>
|
|
24
|
-
</dirac>
|
package/filePath
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
fileContent
|
package/greeting.txt
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
hello world
|
package/src/cli.ts
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Dirac CLI
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import 'dotenv/config';
|
|
8
|
-
import pkg from '../package.json' assert { type: 'json' };
|
|
9
|
-
import fs from 'fs';
|
|
10
|
-
import yaml from 'js-yaml';
|
|
11
|
-
import { resolve, extname } from 'path';
|
|
12
|
-
import { execute } from './index.js';
|
|
13
|
-
import { BraKetParser } from './runtime/braket-parser.js';
|
|
14
|
-
|
|
15
|
-
async function main() {
|
|
16
|
-
const args = process.argv.slice(2);
|
|
17
|
-
|
|
18
|
-
// --help option
|
|
19
|
-
if (args.includes('--help') || args.includes('-h')) {
|
|
20
|
-
console.log('Usage: dirac <file.di|file.bk>');
|
|
21
|
-
console.log('');
|
|
22
|
-
console.log('File formats:');
|
|
23
|
-
console.log(' .di XML notation (verbose)');
|
|
24
|
-
console.log(' .bk Bra-ket notation (compact)');
|
|
25
|
-
console.log('');
|
|
26
|
-
console.log('Options:');
|
|
27
|
-
console.log(' --help, -h Show this help message');
|
|
28
|
-
console.log(' --version, -v Show version');
|
|
29
|
-
console.log(' --debug Enable debug output');
|
|
30
|
-
console.log(' --emit-xml Output intermediate XML (for .bk files)');
|
|
31
|
-
console.log(' --model <name> Set default LLM model');
|
|
32
|
-
console.log(' --max-llm <n> Maximum LLM calls (default: 100)');
|
|
33
|
-
console.log(' --max-depth <n> Maximum recursion depth (default: 50)');
|
|
34
|
-
process.exit(0);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// --version option
|
|
38
|
-
if (args.includes('--version') || args.includes('-v')) {
|
|
39
|
-
console.log(pkg.version);
|
|
40
|
-
process.exit(0);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (args.length === 0) {
|
|
44
|
-
console.error('Usage: dirac <file.di|file.bk>');
|
|
45
|
-
console.error('Try dirac --help for more information.');
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Parse options
|
|
50
|
-
const config: any = {};
|
|
51
|
-
let filePath: string | undefined;
|
|
52
|
-
let emitXml = false;
|
|
53
|
-
let configFile: string | undefined;
|
|
54
|
-
|
|
55
|
-
for (let i = 0; i < args.length; i++) {
|
|
56
|
-
const arg = args[i];
|
|
57
|
-
|
|
58
|
-
if (arg === '--debug') {
|
|
59
|
-
config.debug = true;
|
|
60
|
-
} else if (arg === '--emit-xml') {
|
|
61
|
-
emitXml = true;
|
|
62
|
-
} else if (arg === '--model' && i + 1 < args.length) {
|
|
63
|
-
config.model = args[++i];
|
|
64
|
-
} else if (arg === '--provider' && i + 1 < args.length) {
|
|
65
|
-
config.llmProvider = args[++i];
|
|
66
|
-
} else if ((arg === '-f' || arg === '--config') && i + 1 < args.length) {
|
|
67
|
-
configFile = args[++i];
|
|
68
|
-
} else if (arg === '--max-llm' && i + 1 < args.length) {
|
|
69
|
-
config.maxLLMCalls = parseInt(args[++i], 10);
|
|
70
|
-
} else if (arg === '--max-depth' && i + 1 < args.length) {
|
|
71
|
-
config.maxDepth = parseInt(args[++i], 10);
|
|
72
|
-
} else if (!arg.startsWith('--')) {
|
|
73
|
-
filePath = arg;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Load config from YAML file if specified, or use ./config.yml if present
|
|
78
|
-
if (!configFile) {
|
|
79
|
-
const defaultConfigPath = resolve(process.cwd(), 'config.yml');
|
|
80
|
-
if (fs.existsSync(defaultConfigPath)) {
|
|
81
|
-
configFile = defaultConfigPath;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
if (configFile) {
|
|
85
|
-
try {
|
|
86
|
-
const loadedConfig = yaml.load(fs.readFileSync(resolve(configFile), 'utf8')) || {};
|
|
87
|
-
Object.assign(config, loadedConfig);
|
|
88
|
-
} catch (err) {
|
|
89
|
-
console.error('Failed to load config file:', err);
|
|
90
|
-
process.exit(1);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (!filePath) {
|
|
95
|
-
console.error('Error: No input file specified');
|
|
96
|
-
process.exit(1);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
try {
|
|
100
|
-
const fullPath = resolve(process.cwd(), filePath);
|
|
101
|
-
let source = fs.readFileSync(fullPath, 'utf-8');
|
|
102
|
-
const ext = extname(fullPath);
|
|
103
|
-
|
|
104
|
-
// Convert bra-ket notation to XML if needed
|
|
105
|
-
if (ext === '.bk') {
|
|
106
|
-
if (config.debug) {
|
|
107
|
-
console.error(`[Dirac] Compiling bra-ket notation to XML`);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const braketParser = new BraKetParser();
|
|
111
|
-
const xml = braketParser.parse(source);
|
|
112
|
-
|
|
113
|
-
if (emitXml) {
|
|
114
|
-
console.log(xml);
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
source = xml;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (config.debug) {
|
|
122
|
-
console.error(`[Dirac] Executing ${fullPath}`);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Pass file path to config for import resolution
|
|
126
|
-
config.filePath = fullPath;
|
|
127
|
-
|
|
128
|
-
const result = await execute(source, config);
|
|
129
|
-
process.stdout.write(result);
|
|
130
|
-
|
|
131
|
-
} catch (error) {
|
|
132
|
-
console.error('Error:', error instanceof Error ? error.message : String(error));
|
|
133
|
-
if (config.debug && error instanceof Error && error.stack) {
|
|
134
|
-
console.error(error.stack);
|
|
135
|
-
}
|
|
136
|
-
process.exit(1);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
main();
|
package/src/index.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Main entry point for Dirac interpreter
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export { DiracParser } from './runtime/parser.js';
|
|
6
|
-
export { createSession, getOutput, getAvailableSubroutines } from './runtime/session.js';
|
|
7
|
-
export { integrate } from './runtime/interpreter.js';
|
|
8
|
-
export { createLLMAdapter, executeUserCommand } from './utils/llm-adapter.js';
|
|
9
|
-
export type { DiracSession, DiracConfig, DiracElement, ParameterMetadata } from './types/index.js';
|
|
10
|
-
export type { LLMPromptGenerator } from './utils/llm-adapter.js';
|
|
11
|
-
|
|
12
|
-
import { DiracParser } from './runtime/parser.js';
|
|
13
|
-
import { createSession, getOutput } from './runtime/session.js';
|
|
14
|
-
import { integrate } from './runtime/interpreter.js';
|
|
15
|
-
import type { DiracConfig } from './types/index.js';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Execute Dirac source code
|
|
19
|
-
*/
|
|
20
|
-
export async function execute(source: string, config: DiracConfig = {}): Promise<string> {
|
|
21
|
-
const parser = new DiracParser();
|
|
22
|
-
const session = createSession(config);
|
|
23
|
-
|
|
24
|
-
// Set current file if provided in config
|
|
25
|
-
if (config.filePath) {
|
|
26
|
-
session.currentFile = config.filePath;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const ast = parser.parse(source);
|
|
30
|
-
await integrate(session, ast);
|
|
31
|
-
|
|
32
|
-
return getOutput(session);
|
|
33
|
-
}
|
package/src/llm/ollama.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export class OllamaClient {
|
|
4
|
-
baseUrl: string;
|
|
5
|
-
|
|
6
|
-
constructor({ baseUrl = 'http://localhost:11434' }: { baseUrl?: string } = {}) {
|
|
7
|
-
this.baseUrl = baseUrl;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
async generate({ model, prompt, options = {} }: { model: string; prompt: string; options?: Record<string, any> }) {
|
|
11
|
-
const res = await fetch(`${this.baseUrl}/api/generate`, {
|
|
12
|
-
method: 'POST',
|
|
13
|
-
headers: { 'Content-Type': 'application/json' },
|
|
14
|
-
body: JSON.stringify({ model, prompt, ...options }),
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
let output = '';
|
|
18
|
-
for await (const chunk of res.body as any) {
|
|
19
|
-
const chunkStr = chunk.toString();
|
|
20
|
-
// console.log('[OllamaClient] Raw chunk:', chunkStr);
|
|
21
|
-
const lines = chunkStr.split('\n');
|
|
22
|
-
for (const line of lines) {
|
|
23
|
-
if (line.trim()) {
|
|
24
|
-
let jsonLine = line.trim();
|
|
25
|
-
// If line looks like comma-separated numbers, decode as ASCII
|
|
26
|
-
if (/^\d+(,\d+)*$/.test(jsonLine)) {
|
|
27
|
-
jsonLine = jsonLine.split(',').map(n => String.fromCharCode(Number(n))).join('');
|
|
28
|
-
}
|
|
29
|
-
try {
|
|
30
|
-
const obj = JSON.parse(jsonLine);
|
|
31
|
-
if (obj.response) output += obj.response;
|
|
32
|
-
} catch (err) {
|
|
33
|
-
// Silently skip lines that can't be parsed
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return output;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export class OllamaProvider {
|
|
43
|
-
client: OllamaClient;
|
|
44
|
-
model: string;
|
|
45
|
-
|
|
46
|
-
constructor(options: { baseUrl?: string; model?: string } = {}) {
|
|
47
|
-
this.client = new OllamaClient(options);
|
|
48
|
-
this.model = options.model || 'llama2';
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async complete(prompt: string, opts: Record<string, any> = {}) {
|
|
52
|
-
return await this.client.generate({
|
|
53
|
-
model: this.model,
|
|
54
|
-
prompt,
|
|
55
|
-
options: opts,
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
}
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bra-Ket Parser - Converts bra-ket notation to XML
|
|
3
|
-
*
|
|
4
|
-
* Syntax:
|
|
5
|
-
* - Bra (subroutine): <name| ... defines a subroutine
|
|
6
|
-
* - Ket (everything else): |tag attrs> ... can have children/content
|
|
7
|
-
* - Indentation: Defines scope (like Python/YAML)
|
|
8
|
-
*
|
|
9
|
-
* Examples:
|
|
10
|
-
* |output>Hello World → <output>Hello World</output>
|
|
11
|
-
* |variable name=x> → <variable name="x"/>
|
|
12
|
-
* <add| → <subroutine name="add">
|
|
13
|
-
* |output>test → <output>test</output>
|
|
14
|
-
* → </subroutine>
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
interface BraKetLine {
|
|
18
|
-
indent: number;
|
|
19
|
-
type: 'bra' | 'ket' | 'text' | 'empty';
|
|
20
|
-
tag?: string;
|
|
21
|
-
attrs?: string;
|
|
22
|
-
text?: string;
|
|
23
|
-
raw: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export class BraKetParser {
|
|
27
|
-
private lines: string[] = [];
|
|
28
|
-
private currentLine = 0;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Parse bra-ket notation and compile to XML
|
|
32
|
-
*/
|
|
33
|
-
parse(source: string): string {
|
|
34
|
-
this.lines = source.split('\n');
|
|
35
|
-
this.currentLine = 0;
|
|
36
|
-
|
|
37
|
-
const xml: string[] = ['<dirac>'];
|
|
38
|
-
this.parseBlock(xml, -1);
|
|
39
|
-
xml.push('</dirac>');
|
|
40
|
-
|
|
41
|
-
return xml.join('\n');
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Parse a block of lines at a given indentation level
|
|
46
|
-
*/
|
|
47
|
-
private parseBlock(output: string[], parentIndent: number): void {
|
|
48
|
-
while (this.currentLine < this.lines.length) {
|
|
49
|
-
const line = this.parseLine(this.lines[this.currentLine]);
|
|
50
|
-
|
|
51
|
-
// Empty lines are preserved as-is
|
|
52
|
-
if (line.type === 'empty') {
|
|
53
|
-
this.currentLine++;
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// If indent is less than or equal to parent, we're done with this block
|
|
58
|
-
if (line.indent <= parentIndent) {
|
|
59
|
-
break;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Bra: <name| defines a subroutine
|
|
63
|
-
if (line.type === 'bra') {
|
|
64
|
-
const attrs = line.attrs ? ` ${this.convertAttributes(line.attrs)}` : '';
|
|
65
|
-
output.push(`${' '.repeat(line.indent)}<subroutine name="${line.tag}"${attrs}>`);
|
|
66
|
-
this.currentLine++;
|
|
67
|
-
this.parseBlock(output, line.indent);
|
|
68
|
-
output.push(`${' '.repeat(line.indent)}</subroutine>`);
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Ket: |tag attrs>
|
|
73
|
-
if (line.type === 'ket') {
|
|
74
|
-
const indent = ' '.repeat(line.indent);
|
|
75
|
-
const attrs = line.attrs ? ` ${this.convertAttributes(line.attrs)}` : '';
|
|
76
|
-
|
|
77
|
-
// Check if next line is more indented (has children/content)
|
|
78
|
-
const nextLine = this.currentLine + 1 < this.lines.length
|
|
79
|
-
? this.parseLine(this.lines[this.currentLine + 1])
|
|
80
|
-
: null;
|
|
81
|
-
|
|
82
|
-
if (nextLine && nextLine.indent > line.indent && nextLine.type !== 'empty') {
|
|
83
|
-
// Has children - opening tag
|
|
84
|
-
output.push(`${indent}<${line.tag}${attrs}>`);
|
|
85
|
-
this.currentLine++;
|
|
86
|
-
this.parseBlock(output, line.indent);
|
|
87
|
-
output.push(`${indent}</${line.tag}>`);
|
|
88
|
-
} else {
|
|
89
|
-
// Self-closing or inline text
|
|
90
|
-
if (line.text) {
|
|
91
|
-
// Inline text with embedded kets
|
|
92
|
-
const content = this.convertInlineKets(line.text);
|
|
93
|
-
output.push(`${indent}<${line.tag}${attrs}>${content}</${line.tag}>`);
|
|
94
|
-
} else {
|
|
95
|
-
// Self-closing
|
|
96
|
-
output.push(`${indent}<${line.tag}${attrs}/>`);
|
|
97
|
-
}
|
|
98
|
-
this.currentLine++;
|
|
99
|
-
}
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Plain text content
|
|
104
|
-
if (line.type === 'text') {
|
|
105
|
-
const indent = ' '.repeat(line.indent);
|
|
106
|
-
const content = this.convertInlineKets(line.text || '');
|
|
107
|
-
output.push(`${indent}${content}`);
|
|
108
|
-
this.currentLine++;
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Parse a single line into structured form
|
|
116
|
-
*/
|
|
117
|
-
private parseLine(raw: string): BraKetLine {
|
|
118
|
-
// Count leading spaces for indentation
|
|
119
|
-
const match = raw.match(/^(\s*)(.*)/);
|
|
120
|
-
const indent = match ? Math.floor(match[1].length / 2) : 0;
|
|
121
|
-
const content = match ? match[2] : '';
|
|
122
|
-
|
|
123
|
-
// Empty line
|
|
124
|
-
if (!content.trim()) {
|
|
125
|
-
return { indent, type: 'empty', raw };
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Bra: <name| or <name attrs|
|
|
129
|
-
const braMatch = content.match(/^<([a-zA-Z_][a-zA-Z0-9_-]*)\s*([^|]*)\|$/);
|
|
130
|
-
if (braMatch) {
|
|
131
|
-
return {
|
|
132
|
-
indent,
|
|
133
|
-
type: 'bra',
|
|
134
|
-
tag: braMatch[1],
|
|
135
|
-
attrs: braMatch[2].trim() || undefined,
|
|
136
|
-
raw
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Ket: |tag> or |tag attrs> or |tag>text
|
|
141
|
-
const ketMatch = content.match(/^\|([a-zA-Z_][a-zA-Z0-9_-]*)\s*([^>]*?)>\s*(.*)/);
|
|
142
|
-
if (ketMatch) {
|
|
143
|
-
return {
|
|
144
|
-
indent,
|
|
145
|
-
type: 'ket',
|
|
146
|
-
tag: ketMatch[1],
|
|
147
|
-
attrs: ketMatch[2].trim() || undefined,
|
|
148
|
-
text: ketMatch[3] || undefined,
|
|
149
|
-
raw
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Plain text
|
|
154
|
-
return {
|
|
155
|
-
indent,
|
|
156
|
-
type: 'text',
|
|
157
|
-
text: content,
|
|
158
|
-
raw
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Convert bra-ket attribute syntax to XML
|
|
164
|
-
* Examples:
|
|
165
|
-
* name=value → name="value"
|
|
166
|
-
* x=5 y=10 → x="5" y="10"
|
|
167
|
-
* select=@* → select="@*"
|
|
168
|
-
*/
|
|
169
|
-
private convertAttributes(attrs: string): string {
|
|
170
|
-
if (!attrs) return '';
|
|
171
|
-
|
|
172
|
-
// Split by spaces but respect quoted strings
|
|
173
|
-
const parts: string[] = [];
|
|
174
|
-
let current = '';
|
|
175
|
-
let inQuotes = false;
|
|
176
|
-
let quoteChar = '';
|
|
177
|
-
|
|
178
|
-
for (let i = 0; i < attrs.length; i++) {
|
|
179
|
-
const char = attrs[i];
|
|
180
|
-
|
|
181
|
-
if ((char === '"' || char === "'") && (i === 0 || attrs[i - 1] !== '\\')) {
|
|
182
|
-
if (!inQuotes) {
|
|
183
|
-
inQuotes = true;
|
|
184
|
-
quoteChar = char;
|
|
185
|
-
current += char;
|
|
186
|
-
} else if (char === quoteChar) {
|
|
187
|
-
inQuotes = false;
|
|
188
|
-
current += char;
|
|
189
|
-
} else {
|
|
190
|
-
current += char;
|
|
191
|
-
}
|
|
192
|
-
} else if (char === ' ' && !inQuotes) {
|
|
193
|
-
if (current.trim()) {
|
|
194
|
-
parts.push(current.trim());
|
|
195
|
-
current = '';
|
|
196
|
-
}
|
|
197
|
-
} else {
|
|
198
|
-
current += char;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
if (current.trim()) {
|
|
203
|
-
parts.push(current.trim());
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Convert each attribute
|
|
207
|
-
return parts.map(part => {
|
|
208
|
-
const match = part.match(/^([a-zA-Z_][a-zA-Z0-9_-]*)=(.+)$/);
|
|
209
|
-
if (!match) return part;
|
|
210
|
-
|
|
211
|
-
const [, name, value] = match;
|
|
212
|
-
|
|
213
|
-
// Already quoted
|
|
214
|
-
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
215
|
-
(value.startsWith("'") && value.endsWith("'"))) {
|
|
216
|
-
return `${name}=${value}`;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// Quote it
|
|
220
|
-
return `${name}="${value}"`;
|
|
221
|
-
}).join(' ');
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Convert inline kets within text content
|
|
226
|
-
* Example: "Hello |variable name=x> world" → "Hello <variable name="x"/> world"
|
|
227
|
-
*/
|
|
228
|
-
private convertInlineKets(text: string): string {
|
|
229
|
-
return text.replace(/\|([a-zA-Z_][a-zA-Z0-9_-]*)\s*([^>]*?)>/g, (match, tag, attrs) => {
|
|
230
|
-
const attrStr = attrs.trim() ? ` ${this.convertAttributes(attrs.trim())}` : '';
|
|
231
|
-
return `<${tag}${attrStr}/>`;
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
}
|