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,203 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core interpreter - maps to mask_integrate in MASK
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { DiracElement, DiracSession } from '../types/index.js';
|
|
6
|
-
import { substituteVariables, emit, getSubroutine } from './session.js';
|
|
7
|
-
import { executeDefvar } from '../tags/defvar.js';
|
|
8
|
-
import { executeVariable } from '../tags/variable.js';
|
|
9
|
-
import { executeAssign } from '../tags/assign.js';
|
|
10
|
-
import { executeOutput } from '../tags/output.js';
|
|
11
|
-
import { executeSubroutine } from '../tags/subroutine.js';
|
|
12
|
-
import { executeCall } from '../tags/call.js';
|
|
13
|
-
import { executeLoop } from '../tags/loop.js';
|
|
14
|
-
import { executeIf } from '../tags/if.js';
|
|
15
|
-
import { executeLLM } from '../tags/llm.js';
|
|
16
|
-
import { executeEval } from '../tags/eval.js';
|
|
17
|
-
import { executeExecute } from '../tags/execute.js';
|
|
18
|
-
import { executeImport } from '../tags/import.js';
|
|
19
|
-
import { executeParameters } from '../tags/parameters.js';
|
|
20
|
-
import { executeExpr } from '../tags/expr.js';
|
|
21
|
-
import { executeSystem } from '../tags/system.js';
|
|
22
|
-
import { executeRequireModule } from '../tags/require_module.js';
|
|
23
|
-
import { executeTagCheck } from '../tags/tag-check.js';
|
|
24
|
-
import { executeThrow } from '../tags/throw.js';
|
|
25
|
-
import { executeTry } from '../tags/try.js';
|
|
26
|
-
import { executeCatch } from '../tags/catch.js';
|
|
27
|
-
import { executeException } from '../tags/exception.js';
|
|
28
|
-
import { executeTestIf } from '../tags/test-if.js';
|
|
29
|
-
import { executeAvailableSubroutines } from '../tags/available-subroutines.js';
|
|
30
|
-
import { executeForeach } from '../tags/foreach.js';
|
|
31
|
-
import { executeAttr } from '../tags/attr.js';
|
|
32
|
-
import { executeEnvironment } from '../tags/environment.js';
|
|
33
|
-
import { executeInput } from '../tags/input.js';
|
|
34
|
-
|
|
35
|
-
export async function integrate(session: DiracSession, element: DiracElement): Promise<void> {
|
|
36
|
-
// Check execution limits
|
|
37
|
-
if (session.limits.currentDepth >= session.limits.maxDepth) {
|
|
38
|
-
throw new Error('Maximum execution depth exceeded');
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
session.limits.currentDepth++;
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
// Handle text nodes
|
|
45
|
-
if (element.text && !element.tag) {
|
|
46
|
-
const substituted = substituteVariables(session, element.text);
|
|
47
|
-
emit(session, substituted);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Check control flow
|
|
52
|
-
if (session.isReturn || session.isBreak) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Dispatch to tag handlers
|
|
57
|
-
switch (element.tag.toLowerCase()) {
|
|
58
|
-
case 'defvar':
|
|
59
|
-
await executeDefvar(session, element);
|
|
60
|
-
break;
|
|
61
|
-
|
|
62
|
-
case 'variable':
|
|
63
|
-
await executeVariable(session, element);
|
|
64
|
-
break;
|
|
65
|
-
|
|
66
|
-
case 'assign':
|
|
67
|
-
await executeAssign(session, element);
|
|
68
|
-
break;
|
|
69
|
-
|
|
70
|
-
case 'output':
|
|
71
|
-
await executeOutput(session, element);
|
|
72
|
-
break;
|
|
73
|
-
|
|
74
|
-
case 'subroutine':
|
|
75
|
-
await executeSubroutine(session, element);
|
|
76
|
-
break;
|
|
77
|
-
|
|
78
|
-
case 'call':
|
|
79
|
-
await executeCall(session, element);
|
|
80
|
-
break;
|
|
81
|
-
|
|
82
|
-
case 'loop':
|
|
83
|
-
await executeLoop(session, element);
|
|
84
|
-
break;
|
|
85
|
-
|
|
86
|
-
case 'if':
|
|
87
|
-
await executeIf(session, element);
|
|
88
|
-
break;
|
|
89
|
-
|
|
90
|
-
case 'llm':
|
|
91
|
-
await executeLLM(session, element);
|
|
92
|
-
break;
|
|
93
|
-
|
|
94
|
-
case 'eval':
|
|
95
|
-
await executeEval(session, element);
|
|
96
|
-
break;
|
|
97
|
-
|
|
98
|
-
case 'execute':
|
|
99
|
-
await executeExecute(session, element);
|
|
100
|
-
break;
|
|
101
|
-
|
|
102
|
-
case 'import':
|
|
103
|
-
await executeImport(session, element);
|
|
104
|
-
break;
|
|
105
|
-
|
|
106
|
-
case 'parameters': {
|
|
107
|
-
const result = await executeParameters(session, element);
|
|
108
|
-
if (typeof result === 'string') {
|
|
109
|
-
emit(session, result);
|
|
110
|
-
}
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
case 'expr':
|
|
115
|
-
await executeExpr(session, element);
|
|
116
|
-
break;
|
|
117
|
-
|
|
118
|
-
case 'system':
|
|
119
|
-
await executeSystem(session, element);
|
|
120
|
-
break;
|
|
121
|
-
|
|
122
|
-
case 'tag-check':
|
|
123
|
-
await executeTagCheck(session, element);
|
|
124
|
-
break;
|
|
125
|
-
|
|
126
|
-
case 'throw':
|
|
127
|
-
await executeThrow(session, element);
|
|
128
|
-
break;
|
|
129
|
-
|
|
130
|
-
case 'try':
|
|
131
|
-
await executeTry(session, element);
|
|
132
|
-
break;
|
|
133
|
-
|
|
134
|
-
case 'catch':
|
|
135
|
-
await executeCatch(session, element);
|
|
136
|
-
break;
|
|
137
|
-
|
|
138
|
-
case 'exception':
|
|
139
|
-
await executeException(session, element);
|
|
140
|
-
break;
|
|
141
|
-
|
|
142
|
-
case 'test-if':
|
|
143
|
-
await executeTestIf(session, element);
|
|
144
|
-
break;
|
|
145
|
-
|
|
146
|
-
case 'available-subroutines':
|
|
147
|
-
await executeAvailableSubroutines(session, element);
|
|
148
|
-
break;
|
|
149
|
-
|
|
150
|
-
case 'foreach':
|
|
151
|
-
await executeForeach(session, element);
|
|
152
|
-
break;
|
|
153
|
-
|
|
154
|
-
case 'attr':
|
|
155
|
-
await executeAttr(session, element);
|
|
156
|
-
break;
|
|
157
|
-
|
|
158
|
-
case 'environment':
|
|
159
|
-
await executeEnvironment(session, element);
|
|
160
|
-
break;
|
|
161
|
-
|
|
162
|
-
case 'input':
|
|
163
|
-
await executeInput(session, element);
|
|
164
|
-
break;
|
|
165
|
-
|
|
166
|
-
case 'require_module':
|
|
167
|
-
await executeRequireModule(session, element);
|
|
168
|
-
break;
|
|
169
|
-
|
|
170
|
-
case 'dirac':
|
|
171
|
-
case 'DIRAC-ROOT':
|
|
172
|
-
// Container tags - just execute children
|
|
173
|
-
for (const child of element.children) {
|
|
174
|
-
await integrate(session, child);
|
|
175
|
-
if (session.isReturn || session.isBreak) break;
|
|
176
|
-
}
|
|
177
|
-
break;
|
|
178
|
-
|
|
179
|
-
default:
|
|
180
|
-
// Unknown tag - check if it's a subroutine name
|
|
181
|
-
const subroutine = getSubroutine(session, element.tag);
|
|
182
|
-
if (subroutine) {
|
|
183
|
-
// Treat unknown tag as subroutine call
|
|
184
|
-
await executeCall(session, element);
|
|
185
|
-
} else {
|
|
186
|
-
// Really unknown - just process children
|
|
187
|
-
for (const child of element.children) {
|
|
188
|
-
await integrate(session, child);
|
|
189
|
-
if (session.isReturn || session.isBreak) break;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
} finally {
|
|
194
|
-
session.limits.currentDepth--;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
export async function integrateChildren(session: DiracSession, element: DiracElement): Promise<void> {
|
|
199
|
-
for (const child of element.children) {
|
|
200
|
-
await integrate(session, child);
|
|
201
|
-
if (session.isReturn || session.isBreak) break;
|
|
202
|
-
}
|
|
203
|
-
}
|
package/src/runtime/parser.ts
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* XML Parser for Dirac (.di files)
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { XMLParser } from 'fast-xml-parser';
|
|
6
|
-
import type { DiracElement } from '../types/index.js';
|
|
7
|
-
|
|
8
|
-
export class DiracParser {
|
|
9
|
-
private parser: XMLParser;
|
|
10
|
-
|
|
11
|
-
constructor() {
|
|
12
|
-
this.parser = new XMLParser({
|
|
13
|
-
ignoreAttributes: false,
|
|
14
|
-
attributeNamePrefix: '@_',
|
|
15
|
-
trimValues: false, // Preserve whitespace in mixed content
|
|
16
|
-
parseAttributeValue: false,
|
|
17
|
-
parseTagValue: false,
|
|
18
|
-
textNodeName: '#text',
|
|
19
|
-
cdataPropName: '#cdata',
|
|
20
|
-
preserveOrder: true, // Preserve element order!
|
|
21
|
-
commentPropName: '#comment',
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
parse(source: string): DiracElement {
|
|
26
|
-
// Strip shebang line if present
|
|
27
|
-
if (source.startsWith('#!')) {
|
|
28
|
-
source = source.replace(/^#!.*\n/, '');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Always wrap in DIRAC-ROOT to ensure valid XML with single root
|
|
32
|
-
// This allows files with comments, multiple elements, or no root
|
|
33
|
-
source = `<DIRAC-ROOT>\n${source}\n</DIRAC-ROOT>`;
|
|
34
|
-
|
|
35
|
-
const result = this.parser.parse(source);
|
|
36
|
-
// With preserveOrder, result is an array
|
|
37
|
-
if (!Array.isArray(result) || result.length === 0) {
|
|
38
|
-
throw new Error('Empty or invalid XML');
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Find the first non-comment element
|
|
42
|
-
for (const item of result) {
|
|
43
|
-
if (!item['#comment']) {
|
|
44
|
-
return this.convertOrderedToElement(item);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
throw new Error('No root element found');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
private convertOrderedToElement(obj: any): DiracElement {
|
|
52
|
-
// obj is like { "tagname": [...children], ":@": {...attributes} }
|
|
53
|
-
const tagName = Object.keys(obj).find(k => k !== ':@' && k !== '#comment');
|
|
54
|
-
|
|
55
|
-
if (!tagName) {
|
|
56
|
-
throw new Error('Invalid element structure');
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const element: DiracElement = {
|
|
60
|
-
tag: tagName,
|
|
61
|
-
attributes: {},
|
|
62
|
-
children: [],
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
// Extract attributes
|
|
66
|
-
if (obj[':@']) {
|
|
67
|
-
for (const [key, value] of Object.entries(obj[':@'])) {
|
|
68
|
-
if (key.startsWith('@_')) {
|
|
69
|
-
element.attributes[key.slice(2)] = value as string;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Extract children
|
|
75
|
-
const children = obj[tagName];
|
|
76
|
-
if (Array.isArray(children)) {
|
|
77
|
-
for (const child of children) {
|
|
78
|
-
if (child['#text']) {
|
|
79
|
-
// Text node - add as child AND to element.text for backward compat
|
|
80
|
-
element.children.push({
|
|
81
|
-
tag: '',
|
|
82
|
-
text: child['#text'],
|
|
83
|
-
attributes: {},
|
|
84
|
-
children: []
|
|
85
|
-
});
|
|
86
|
-
// Also set element.text if not set (for simple text-only elements)
|
|
87
|
-
if (!element.text) {
|
|
88
|
-
element.text = child['#text'];
|
|
89
|
-
} else {
|
|
90
|
-
element.text += child['#text'];
|
|
91
|
-
}
|
|
92
|
-
} else if (child['#comment']) {
|
|
93
|
-
// Skip comments
|
|
94
|
-
continue;
|
|
95
|
-
} else {
|
|
96
|
-
// Child element
|
|
97
|
-
element.children.push(this.convertOrderedToElement(child));
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return element;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Old method - no longer used
|
|
106
|
-
private convertToElement(obj: any, tagName?: string): DiracElement {
|
|
107
|
-
if (!tagName) {
|
|
108
|
-
// Root level - find the actual tag
|
|
109
|
-
const keys = Object.keys(obj);
|
|
110
|
-
if (keys.length === 0) {
|
|
111
|
-
throw new Error('Empty XML');
|
|
112
|
-
}
|
|
113
|
-
tagName = keys[0];
|
|
114
|
-
obj = obj[tagName];
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const element: DiracElement = {
|
|
118
|
-
tag: tagName,
|
|
119
|
-
attributes: {},
|
|
120
|
-
children: [],
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
if (typeof obj === 'string') {
|
|
124
|
-
element.text = obj;
|
|
125
|
-
return element;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (!obj) {
|
|
129
|
-
return element;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Extract attributes and children
|
|
133
|
-
for (const key of Object.keys(obj)) {
|
|
134
|
-
const value = obj[key];
|
|
135
|
-
|
|
136
|
-
if (key === '#text') {
|
|
137
|
-
element.text = value;
|
|
138
|
-
} else if (key.startsWith('@_')) {
|
|
139
|
-
// Attribute
|
|
140
|
-
element.attributes[key.slice(2)] = value;
|
|
141
|
-
} else {
|
|
142
|
-
// Child element
|
|
143
|
-
if (Array.isArray(value)) {
|
|
144
|
-
for (const item of value) {
|
|
145
|
-
element.children.push(this.convertToElement(item, key));
|
|
146
|
-
}
|
|
147
|
-
} else {
|
|
148
|
-
element.children.push(this.convertToElement(value, key));
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return element;
|
|
154
|
-
}
|
|
155
|
-
}
|
package/src/runtime/session.ts
DELETED
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
// Substitute both $var and ${var} in a string using session variables
|
|
2
|
-
export function substituteAttribute(session: DiracSession, value: any): string {
|
|
3
|
-
if (typeof value !== 'string') return value;
|
|
4
|
-
return value
|
|
5
|
-
.replace(/\$\{(\w+)\}/g, (match, varName) => {
|
|
6
|
-
const v = getVariable(session, varName);
|
|
7
|
-
return v !== undefined ? String(v) : match;
|
|
8
|
-
})
|
|
9
|
-
.replace(/\$(\w+)/g, (match, varName) => {
|
|
10
|
-
const v = getVariable(session, varName);
|
|
11
|
-
return v !== undefined ? String(v) : match;
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Session management - maps to MASK session functions
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
19
|
-
import OpenAI from 'openai';
|
|
20
|
-
import { OllamaProvider } from '../llm/ollama.js';
|
|
21
|
-
import type { DiracSession, DiracConfig, Variable, Subroutine, DiracElement } from '../types/index.js';
|
|
22
|
-
|
|
23
|
-
export function createSession(config: DiracConfig = {}): DiracSession {
|
|
24
|
-
const anthropicKey = process.env.ANTHROPIC_API_KEY;
|
|
25
|
-
const openaiKey = config.apiKey || process.env.OPENAI_API_KEY;
|
|
26
|
-
const llmProvider = config.llmProvider || process.env.LLM_PROVIDER;
|
|
27
|
-
const ollamaModel = config.llmModel || process.env.LLM_MODEL || 'llama2';
|
|
28
|
-
|
|
29
|
-
let llmClient: any;
|
|
30
|
-
switch (llmProvider) {
|
|
31
|
-
case 'ollama':
|
|
32
|
-
llmClient = new OllamaProvider({ model: ollamaModel });
|
|
33
|
-
break;
|
|
34
|
-
case 'anthropic':
|
|
35
|
-
if (!anthropicKey) throw new Error('ANTHROPIC_API_KEY required for Anthropic provider');
|
|
36
|
-
llmClient = new Anthropic({ apiKey: anthropicKey });
|
|
37
|
-
break;
|
|
38
|
-
case 'openai':
|
|
39
|
-
if (!openaiKey) throw new Error('OPENAI_API_KEY required for OpenAI provider');
|
|
40
|
-
llmClient = new OpenAI({ apiKey: openaiKey });
|
|
41
|
-
break;
|
|
42
|
-
default:
|
|
43
|
-
throw new Error('No valid LLM provider configured. Set llmProvider in config or LLM_PROVIDER env.');
|
|
44
|
-
}
|
|
45
|
-
return {
|
|
46
|
-
variables: [],
|
|
47
|
-
subroutines: [],
|
|
48
|
-
varBoundary: 0,
|
|
49
|
-
subBoundary: 0,
|
|
50
|
-
parameterStack: [],
|
|
51
|
-
exceptions: [],
|
|
52
|
-
currentException: {
|
|
53
|
-
size: 0,
|
|
54
|
-
exceptions: [],
|
|
55
|
-
},
|
|
56
|
-
output: [],
|
|
57
|
-
llmClient,
|
|
58
|
-
limits: {
|
|
59
|
-
maxLLMCalls: config.maxLLMCalls || 100,
|
|
60
|
-
currentLLMCalls: 0,
|
|
61
|
-
maxDepth: config.maxDepth || 50,
|
|
62
|
-
currentDepth: 0,
|
|
63
|
-
},
|
|
64
|
-
isReturn: false,
|
|
65
|
-
isBreak: false,
|
|
66
|
-
skipSubroutineRegistration: false,
|
|
67
|
-
debug: config.debug || false,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Variable management (maps to var_info functions in MASK)
|
|
72
|
-
|
|
73
|
-
export function setVariable(session: DiracSession, name: string, value: any, visible: boolean = false): void {
|
|
74
|
-
session.variables.push({
|
|
75
|
-
name,
|
|
76
|
-
value,
|
|
77
|
-
visible,
|
|
78
|
-
boundary: session.varBoundary,
|
|
79
|
-
passby: 'value',
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export function getVariable(session: DiracSession, name: string): any {
|
|
84
|
-
// Search from end (most recent) to beginning
|
|
85
|
-
for (let i = session.variables.length - 1; i >= 0; i--) {
|
|
86
|
-
if (session.variables[i].name === name) {
|
|
87
|
-
return session.variables[i].value;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return undefined;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export function hasVariable(session: DiracSession, name: string): boolean {
|
|
94
|
-
return session.variables.some(v => v.name === name);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Set boundary marker for local variables
|
|
99
|
-
* Maps to var_info_set_boundary in MASK
|
|
100
|
-
*/
|
|
101
|
-
export function setBoundary(session: DiracSession): number {
|
|
102
|
-
const oldBoundary = session.varBoundary;
|
|
103
|
-
session.varBoundary = session.variables.length;
|
|
104
|
-
return oldBoundary;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Pop variables back to boundary (cleanup local scope)
|
|
109
|
-
* Maps to var_info_pop_to_boundary in MASK
|
|
110
|
-
*/
|
|
111
|
-
export function popToBoundary(session: DiracSession): void {
|
|
112
|
-
session.variables = session.variables.slice(0, session.varBoundary);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Clean private variables but keep visible ones
|
|
117
|
-
* Maps to var_info_clean_to_boundary in MASK
|
|
118
|
-
*/
|
|
119
|
-
export function cleanToBoundary(session: DiracSession): void {
|
|
120
|
-
const kept: Variable[] = [];
|
|
121
|
-
|
|
122
|
-
for (let i = 0; i < session.varBoundary; i++) {
|
|
123
|
-
kept.push(session.variables[i]);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
for (let i = session.varBoundary; i < session.variables.length; i++) {
|
|
127
|
-
if (session.variables[i].visible) {
|
|
128
|
-
kept.push(session.variables[i]);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
session.variables = kept;
|
|
133
|
-
session.varBoundary = kept.length;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Subroutine management (maps to subroutine functions in MASK)
|
|
137
|
-
|
|
138
|
-
export function registerSubroutine(
|
|
139
|
-
session: DiracSession,
|
|
140
|
-
name: string,
|
|
141
|
-
element: DiracElement,
|
|
142
|
-
description?: string,
|
|
143
|
-
parameters?: any[],
|
|
144
|
-
meta?: Record<string, string>
|
|
145
|
-
): void {
|
|
146
|
-
session.subroutines.push({
|
|
147
|
-
name,
|
|
148
|
-
element,
|
|
149
|
-
boundary: session.subBoundary,
|
|
150
|
-
description,
|
|
151
|
-
parameters,
|
|
152
|
-
meta,
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export function getSubroutine(session: DiracSession, name: string): DiracElement | undefined {
|
|
157
|
-
// Search from end (most recent) to beginning
|
|
158
|
-
for (let i = session.subroutines.length - 1; i >= 0; i--) {
|
|
159
|
-
if (session.subroutines[i].name === name) {
|
|
160
|
-
return session.subroutines[i].element;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
return undefined;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
export function getParentSubroutine(
|
|
167
|
-
session: DiracSession,
|
|
168
|
-
name: string,
|
|
169
|
-
currentElement?: DiracElement
|
|
170
|
-
): DiracElement | undefined {
|
|
171
|
-
// Search from end, finding parent of currentElement
|
|
172
|
-
// If currentElement provided, skip until we find it, then return next match
|
|
173
|
-
// If not provided, just return most recent
|
|
174
|
-
|
|
175
|
-
let foundCurrent = currentElement === undefined;
|
|
176
|
-
|
|
177
|
-
for (let i = session.subroutines.length - 1; i >= 0; i--) {
|
|
178
|
-
if (session.subroutines[i].name === name) {
|
|
179
|
-
if (!foundCurrent) {
|
|
180
|
-
// Check if this is the current element
|
|
181
|
-
if (session.subroutines[i].element === currentElement) {
|
|
182
|
-
foundCurrent = true;
|
|
183
|
-
continue; // Skip current, look for parent
|
|
184
|
-
}
|
|
185
|
-
continue; // Not current yet, keep searching
|
|
186
|
-
}
|
|
187
|
-
// Found current, this is the parent
|
|
188
|
-
return session.subroutines[i].element;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return undefined;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export function setSubroutineBoundary(session: DiracSession): number {
|
|
195
|
-
const oldBoundary = session.subBoundary;
|
|
196
|
-
session.subBoundary = session.subroutines.length;
|
|
197
|
-
return oldBoundary;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
export function popSubroutinesToBoundary(session: DiracSession): void {
|
|
201
|
-
session.subroutines = session.subroutines.slice(0, session.subBoundary);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
export function cleanSubroutinesToBoundary(session: DiracSession): void {
|
|
205
|
-
// For now, same as pop (visibility not implemented for subroutines yet)
|
|
206
|
-
popSubroutinesToBoundary(session);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// Variable substitution (maps to var_replace functions in MASK)
|
|
210
|
-
|
|
211
|
-
export function substituteVariables(session: DiracSession, text: string): string {
|
|
212
|
-
// Decode HTML entities only; do NOT substitute variables globally
|
|
213
|
-
return text
|
|
214
|
-
.replace(/ /g, '\n')
|
|
215
|
-
.replace(/ /g, '\r')
|
|
216
|
-
.replace(/	/g, '\t')
|
|
217
|
-
.replace(/</g, '<')
|
|
218
|
-
.replace(/>/g, '>')
|
|
219
|
-
.replace(/&/g, '&')
|
|
220
|
-
.replace(/"/g, '"')
|
|
221
|
-
.replace(/'/g, "'");
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Output management
|
|
225
|
-
|
|
226
|
-
export function emit(session: DiracSession, content: string): void {
|
|
227
|
-
session.output.push(content);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
export function getOutput(session: DiracSession): string {
|
|
231
|
-
return session.output.join('');
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Parameter stack (for subroutine calls)
|
|
235
|
-
|
|
236
|
-
export function pushParameters(session: DiracSession, params: DiracElement[]): void {
|
|
237
|
-
session.parameterStack.push(params);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
export function popParameters(session: DiracSession): DiracElement[] | undefined {
|
|
241
|
-
return session.parameterStack.pop();
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
export function getCurrentParameters(session: DiracSession): DiracElement[] | undefined {
|
|
245
|
-
return session.parameterStack[session.parameterStack.length - 1];
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Reflection/Introspection API
|
|
249
|
-
|
|
250
|
-
export function getAvailableSubroutines(session: DiracSession): Array<{
|
|
251
|
-
name: string;
|
|
252
|
-
description?: string;
|
|
253
|
-
parameters?: Array<{
|
|
254
|
-
name: string;
|
|
255
|
-
type?: string;
|
|
256
|
-
required?: boolean;
|
|
257
|
-
description?: string;
|
|
258
|
-
enum?: string[];
|
|
259
|
-
}>;
|
|
260
|
-
}> {
|
|
261
|
-
return session.subroutines.map(sub => ({
|
|
262
|
-
name: sub.name,
|
|
263
|
-
description: sub.description,
|
|
264
|
-
parameters: sub.parameters,
|
|
265
|
-
meta: sub.meta,
|
|
266
|
-
}));
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// Exception handling (for try/catch/throw)
|
|
270
|
-
|
|
271
|
-
export function throwException(session: DiracSession, name: string, dom: DiracElement): void {
|
|
272
|
-
session.exceptions.push({
|
|
273
|
-
name,
|
|
274
|
-
dom,
|
|
275
|
-
isBoundary: 0,
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
export function setExceptionBoundary(session: DiracSession): void {
|
|
280
|
-
const size = session.exceptions.length;
|
|
281
|
-
if (size === 0) return;
|
|
282
|
-
const top = session.exceptions[size - 1];
|
|
283
|
-
top.isBoundary++;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
export function unsetExceptionBoundary(session: DiracSession): void {
|
|
287
|
-
const size = session.exceptions.length;
|
|
288
|
-
if (size === 0) return;
|
|
289
|
-
for (let i = size - 1; i >= 0; i--) {
|
|
290
|
-
const exception = session.exceptions[i];
|
|
291
|
-
if (exception.isBoundary > 0) {
|
|
292
|
-
exception.isBoundary--;
|
|
293
|
-
break;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
export function lookupException(session: DiracSession, name: string): number {
|
|
299
|
-
const size = session.exceptions.length;
|
|
300
|
-
if (size === 0) return 0;
|
|
301
|
-
|
|
302
|
-
let count = 0;
|
|
303
|
-
for (let i = size - 1; i >= 0; i--) {
|
|
304
|
-
const exception = session.exceptions[i];
|
|
305
|
-
if (exception.isBoundary > 0) break; // Stop at boundary
|
|
306
|
-
|
|
307
|
-
if (exception.name === name) {
|
|
308
|
-
// Add to current exception list
|
|
309
|
-
session.currentException.exceptions.push(exception.dom);
|
|
310
|
-
session.currentException.size++;
|
|
311
|
-
count++;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return count;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
export function flushCurrentException(session: DiracSession): void {
|
|
319
|
-
session.currentException.size = 0;
|
|
320
|
-
session.currentException.exceptions = [];
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
export function getCurrentExceptions(session: DiracSession): DiracElement[] {
|
|
324
|
-
return session.currentException.exceptions;
|
|
325
|
-
}
|