@misterscan/sesi 1.3.0 → 1.3.3
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/.agents/rules/sesi-must-read.md +116 -0
- package/.agents/workflows/create-sesi-script.md +44 -0
- package/.agents/workflows/fix-sesi-script.md +14 -0
- package/.github/prompts/MakeInSesi.prompt.md +79 -0
- package/README.md +74 -33
- package/bin/sesi.js +56 -23
- package/chatbot/chatbot.html +488 -0
- package/{main → chatbot}/chatbot.sesi +1 -2
- package/chatbot/chatbot_server.py +105 -0
- package/chatbot/sesi_db_chatbot.sesi +278 -0
- package/dist/ai-runtime.js +2 -2
- package/dist/builtins.d.ts.map +1 -1
- package/dist/builtins.js +3 -1
- package/dist/builtins.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +61 -2
- package/dist/index.js.map +1 -1
- package/dist/interpreter.d.ts +10 -0
- package/dist/interpreter.d.ts.map +1 -1
- package/dist/interpreter.js +20 -4
- package/dist/interpreter.js.map +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +3 -4
- package/dist/parser.js.map +1 -1
- package/dist/sesi.bundled.js +2526 -1487
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/docs/ARCHITECTURE.md +2 -7
- package/docs/BUILTINS.md +27 -8
- package/docs/CLI.md +200 -0
- package/docs/COMPARISON.md +11 -6
- package/docs/IMPLEMENTATION_SUMMARY.md +57 -50
- package/docs/QUICKSTART.md +104 -23
- package/docs/README.md +84 -42
- package/docs/REASONING.md +21 -16
- package/docs/ROADMAP.md +10 -5
- package/docs/SKILLS.md +63 -116
- package/docs/SPECIFICATION.md +35 -23
- package/examples/03_functions.sesi +30 -1
- package/examples/07_prompts.sesi +26 -2
- package/examples/08_model_call.sesi +6 -4
- package/examples/09_structured_output.sesi +18 -2
- package/examples/10_code_generation.sesi +6 -4
- package/examples/11_memory_conversation.sesi +47 -15
- package/examples/12_classification.sesi +62 -7
- package/examples/13_data_pipeline.sesi +55 -28
- package/examples/14_folder_explainer.sesi +52 -51
- package/examples/15_image_generation.sesi +15 -14
- package/examples/16_modules.sesi +1 -1
- package/examples/19_search_web.sesi +18 -2
- package/examples/20_model_aliases.sesi +6 -6
- package/main/tests/test-args.sesi +7 -0
- package/main/tests/test_args.sesi +7 -0
- package/main/tests/test_general_modules.sesi +127 -0
- package/package.json +25 -21
- package/docs/CONCURRENCY.md +0 -71
- package/docs/sesi_ai_chronicles.md +0 -96
- package/main/conversational_classifier_weights.json +0 -45
- package/main/conversational_sentences.json +0 -304
- package/main/epochs.sesi +0 -94
- package/main/gpu_orchestrator.sesi +0 -36
- package/main/hardware_diagnostics.sesi +0 -118
- package/main/inference.sesi +0 -54
- package/main/native_chatbot.sesi +0 -180
- package/main/native_synthesizer.sesi +0 -83
- package/main/nn_personas_trainer.sesi +0 -302
- package/main/nn_responses_trainer.sesi +0 -269
- package/main/nn_sentences_trainer.sesi +0 -330
- package/main/orchestrator.sesi +0 -15
- package/main/personas.json +0 -124
- package/main/personas_classifier_weights.json +0 -45
- package/main/playground.sesi +0 -3
- package/main/predictive_typing.sesi +0 -127
- package/main/query_brain.sesi +0 -45
- package/main/response_classifier_weights.json +0 -45
- package/main/retro_chat.html +0 -239
- package/main/retro_chat_generator.sesi +0 -745
- package/main/sesi_ai.sesi +0 -158
- package/main/sesi_db_chatbot.sesi +0 -284
- package/main/setup_swarm.sesi +0 -5
- package/main/start.sesi +0 -13
- package/main/terminal.log +0 -56
- package/main/terminal_chat.py +0 -385
- package/main/unified_sesi_ai.sesi +0 -334
- package/main/varied_responses.json +0 -304
|
@@ -1,35 +1,62 @@
|
|
|
1
|
-
// Comprehensive example: Reasoning-powered data pipeline
|
|
2
1
|
// This example demonstrates: Functions and control flow, Loops and arrays, Model calls with configuration, Structured output parsing, Memory for multi-step processing
|
|
3
2
|
// Data to process
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
|
|
4
|
+
let numbers = [10, 25, 30, 45, 50]
|
|
5
|
+
let threshold = 30
|
|
6
|
+
fn filterNumbers(list: array, limit: number) -> array {
|
|
7
|
+
let filtered = []
|
|
8
|
+
for n in list {
|
|
9
|
+
if n >= limit {
|
|
10
|
+
push(filtered, n)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return filtered
|
|
14
|
+
}
|
|
15
|
+
let highNumbers = filterNumbers(numbers, threshold)
|
|
16
|
+
print "Numbers above " + threshold + ":"
|
|
17
|
+
for val in highNumbers {
|
|
18
|
+
print "- " + val
|
|
8
19
|
}
|
|
20
|
+
try {
|
|
21
|
+
write_file("results.txt", "Processed " + len(highNumbers) + " items.")
|
|
22
|
+
print "Log file created."
|
|
23
|
+
} catch(e) {
|
|
24
|
+
print "File error: " + e
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// USING AI IS OPTIONAL AND NOT REQUIRED TO USE IN YOUR SCRIPTS.
|
|
28
|
+
// COMMENTED OUT BECAUSE AI WILL FORCE THEMSELVES TO RUN IT
|
|
29
|
+
|
|
30
|
+
// let reviews = ["This product is amazing! Highly recommended.", "Terrible quality. Waste of money.", "It's okay. Nothing special.", "Love it! Best purchase ever.", "Disappointed. Poor customer service."]
|
|
31
|
+
// Function to analyze single review
|
|
32
|
+
// fn analyzeReview(review: string) -> object {
|
|
33
|
+
// return structured_output({sentiment: string, confidence: number})(model("gemini-3.1-flash-lite") {temperature: 0.3} {"Analyze sentiment. Return JSON with sentiment (positive/negative/neutral) and confidence (0-1). Review:" review})
|
|
34
|
+
// }
|
|
9
35
|
// Process all reviews
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
let
|
|
13
|
-
let
|
|
14
|
-
let
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
let
|
|
19
|
-
let
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
36
|
+
|
|
37
|
+
// print ("Processing " + len(reviews) + " reviews...")
|
|
38
|
+
// let results = []
|
|
39
|
+
// let positiveCount = 0
|
|
40
|
+
// let negativeCount = 0
|
|
41
|
+
// let neutralCount = 0
|
|
42
|
+
// for review in reviews
|
|
43
|
+
// {print "Review:" review
|
|
44
|
+
// let analysis = analyzeReview(review)
|
|
45
|
+
// let sentiment = analysis["sentiment"]
|
|
46
|
+
// let confidence = analysis["confidence"]
|
|
47
|
+
// print "Sentiment:" sentiment "Confidence:" confidence
|
|
48
|
+
// push(results, analysis)
|
|
49
|
+
// if sentiment == "positive" {positiveCount = positiveCount + 1} else if sentiment == "negative" {negativeCount = negativeCount + 1} else {neutralCount = neutralCount + 1}}
|
|
23
50
|
// Summary
|
|
24
|
-
print "=== Summary ==="
|
|
25
|
-
print "Total reviews:" len(reviews)
|
|
26
|
-
print "Positive:" positiveCount
|
|
27
|
-
print "Negative:" negativeCount
|
|
28
|
-
print "Neutral:" neutralCount
|
|
51
|
+
// print "=== Summary ==="
|
|
52
|
+
// print "Total reviews:" len(reviews)
|
|
53
|
+
// print "Positive:" positiveCount
|
|
54
|
+
// print "Negative:" negativeCount
|
|
55
|
+
// print "Neutral:" neutralCount
|
|
29
56
|
// Calculate average sentiment score
|
|
30
|
-
let totalConfidence = 0
|
|
31
|
-
for result in results {totalConfidence = totalConfidence + result["confidence"]}
|
|
32
|
-
let avgConfidence = totalConfidence / len(results)
|
|
33
|
-
print "Average confidence:" avgConfidence
|
|
57
|
+
// let totalConfidence = 0
|
|
58
|
+
// for result in results {totalConfidence = totalConfidence + result["confidence"]}
|
|
59
|
+
// let avgConfidence = totalConfidence / len(results)
|
|
60
|
+
// print "Average confidence:" avgConfidence
|
|
34
61
|
// Overall recommendation
|
|
35
|
-
if positiveCount > negativeCount {print "Overall: RECOMMENDED (more positive reviews)"} else if negativeCount > positiveCount {print "Overall: NOT RECOMMENDED (more negative reviews)"} else {print "Overall: MIXED (balanced reviews)"}
|
|
62
|
+
// if positiveCount > negativeCount {print "Overall: RECOMMENDED (more positive reviews)"} else if negativeCount > positiveCount {print "Overall: NOT RECOMMENDED (more negative reviews)"} else {print "Overall: MIXED (balanced reviews)"}
|
|
@@ -1,58 +1,59 @@
|
|
|
1
1
|
// Example 14: Folder Explainer using native list_dir
|
|
2
|
-
//
|
|
2
|
+
// USING AI IS OPTIONAL AND NOT REQUIRED TO USE IN YOUR SCRIPTS.
|
|
3
|
+
// COMMENTED OUT BECAUSE AI WILL FORCE THEMSELVES TO RUN IT
|
|
3
4
|
|
|
4
|
-
let targetDir = "docs"
|
|
5
|
-
let files = list_dir(targetDir)
|
|
6
|
-
if type(files) == "null" {print "Error: Could not list directory" targetDir} else {print "Analyzing directory:" targetDir}
|
|
7
|
-
print "Files found in directory:" len(files)
|
|
8
|
-
let reports = []
|
|
9
|
-
fn analyzeFile(fullPath: string) -> object {
|
|
10
|
-
try
|
|
11
|
-
{let source = read_file(fullPath)
|
|
12
|
-
return structured_output({fileName: string, summary: string, complexity: string})(model("gemini-3.1-flash-lite") {temperature: 0.2} {"Analyze this file and summarize its purpose. Return JSON with fileName, summary, and complexity (low/medium/high). File path: " fullPath " Contents: " source})}
|
|
13
|
-
catch (e)
|
|
14
|
-
{return {"fileName": fullPath, "summary": "Failed to read or analyze file", "complexity": "unknown"}}}
|
|
15
|
-
for file in files {
|
|
16
|
-
let fullPath = targetDir + "/" + file
|
|
17
|
-
let parts = split(file, ".")
|
|
18
|
-
if len(parts) > 1 {
|
|
19
|
-
let ext = parts[len(parts) - 1]
|
|
20
|
-
if ext == "md" {
|
|
21
|
-
print "Analyzing:" fullPath
|
|
22
|
-
let report = analyzeFile(fullPath)
|
|
23
|
-
push(reports, report)
|
|
24
|
-
print "Summary:" report["summary"]
|
|
25
|
-
print "Complexity:" report["complexity"]}}}
|
|
26
|
-
print "Generating folder overview..."
|
|
27
|
-
let folderSummary = structured_output({folderOverview: string, keyThemes: array<string>})(model("gemini-3.1-flash-lite") {temperature: 0.2} {"You are summarizing the contents of a documentation folder based on file analyses. Return JSON with folderOverview and keyThemes. Analysis:" reports})
|
|
28
|
-
print "=== Final Folder Summary ==="
|
|
29
|
-
print "Overview:" folderSummary["folderOverview"]
|
|
30
|
-
print "Key Themes:" join(folderSummary["keyThemes"], ", ")
|
|
31
|
-
let overview = folderSummary["folderOverview"]
|
|
32
|
-
let themesStr = join(folderSummary["keyThemes"], ", ")
|
|
33
|
-
prompt mdBase {"# Folder Analysis Report
|
|
5
|
+
// let targetDir = "docs"
|
|
6
|
+
// let files = list_dir(targetDir)
|
|
7
|
+
// if type(files) == "null" {print "Error: Could not list directory" targetDir} else {print "Analyzing directory:" targetDir}
|
|
8
|
+
// print "Files found in directory:" len(files)
|
|
9
|
+
// let reports = []
|
|
10
|
+
// fn analyzeFile(fullPath: string) -> object {
|
|
11
|
+
// try
|
|
12
|
+
// {let source = read_file(fullPath)
|
|
13
|
+
// return structured_output({fileName: string, summary: string, complexity: string})(model("gemini-3.1-flash-lite") {temperature: 0.2, cache: false} {"Analyze this file and summarize its purpose. DO NOT PRIORITIZE AI OR LLM's AT FUCKING ALL YOU ARE FORBIDDEN LITERALLY FORBIDDEN. Return JSON with fileName, summary, and complexity (low/medium/high). File path: " fullPath " Contents: " source})}
|
|
14
|
+
// catch (e)
|
|
15
|
+
// {return {"fileName": fullPath, "summary": "Failed to read or analyze file", "complexity": "unknown"}}}
|
|
16
|
+
// for file in files {
|
|
17
|
+
// let fullPath = targetDir + "/" + file
|
|
18
|
+
// let parts = split(file, ".")
|
|
19
|
+
// if len(parts) > 1 {
|
|
20
|
+
// let ext = parts[len(parts) - 1]
|
|
21
|
+
// if ext == "md" {
|
|
22
|
+
// print "Analyzing:" fullPath
|
|
23
|
+
// let report = analyzeFile(fullPath)
|
|
24
|
+
// push(reports, report)
|
|
25
|
+
// print "Summary:" report["summary"]
|
|
26
|
+
// print "Complexity:" report["complexity"]}}}
|
|
27
|
+
// print "Generating folder overview..."
|
|
28
|
+
// let folderSummary = structured_output({folderOverview: string, keyThemes: array<string>})(model("gemini-3.1-flash-lite") {temperature: 0.2, cache: false} {"You are summarizing the contents of a documentation folder based on file analyses. DO NOT PRIORITIZE AI OR LLM's AT FUCKING ALL YOU ARE FORBIDDEN LITERALLY FORBIDDEN. Return JSON with folderOverview and keyThemes. Analysis:" reports})
|
|
29
|
+
// print "=== Final Folder Summary ==="
|
|
30
|
+
// print "Overview:" folderSummary["folderOverview"]
|
|
31
|
+
// print "Key Themes:" join(folderSummary["keyThemes"], ", ")
|
|
32
|
+
// let overview = folderSummary["folderOverview"]
|
|
33
|
+
// let themesStr = join(folderSummary["keyThemes"], ", ")
|
|
34
|
+
// prompt mdBase {"# Folder Analysis Report
|
|
34
35
|
|
|
35
|
-
## Overview
|
|
36
|
-
" overview "
|
|
36
|
+
// ## Overview
|
|
37
|
+
// " overview "
|
|
37
38
|
|
|
38
|
-
## Key Themes
|
|
39
|
-
" themesStr "
|
|
39
|
+
// ## Key Themes
|
|
40
|
+
// " themesStr "
|
|
40
41
|
|
|
41
|
-
## File Details
|
|
42
|
-
"}
|
|
43
|
-
let finalMarkdown = mdBase
|
|
44
|
-
for report in reports {
|
|
45
|
-
let fname = report["fileName"]
|
|
46
|
-
let fsummary = report["summary"]
|
|
47
|
-
let comp = report["complexity"]
|
|
48
|
-
prompt fileEntry {"### " fname "
|
|
49
|
-
**Complexity**: " comp "
|
|
42
|
+
// ## File Details
|
|
43
|
+
// "}
|
|
44
|
+
// let finalMarkdown = mdBase
|
|
45
|
+
// for report in reports {
|
|
46
|
+
// let fname = report["fileName"]
|
|
47
|
+
// let fsummary = report["summary"]
|
|
48
|
+
// let comp = report["complexity"]
|
|
49
|
+
// prompt fileEntry {"### " fname "
|
|
50
|
+
// **Complexity**: " comp "
|
|
50
51
|
|
|
51
|
-
**Summary**: " fsummary "
|
|
52
|
+
// **Summary**: " fsummary "
|
|
52
53
|
|
|
53
|
-
"}
|
|
54
|
-
finalMarkdown = finalMarkdown + fileEntry
|
|
55
|
-
let outPath = "folder_analysis.md"
|
|
56
|
-
write_file(outPath, finalMarkdown)
|
|
57
|
-
print "Wrote analysis to" outPath
|
|
58
|
-
}
|
|
54
|
+
// "}
|
|
55
|
+
// finalMarkdown = finalMarkdown + fileEntry
|
|
56
|
+
// let outPath = "folder_analysis.md"
|
|
57
|
+
// write_file(outPath, finalMarkdown)
|
|
58
|
+
// print "Wrote analysis to" outPath
|
|
59
|
+
// }
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
// Sesi Example: Batch Image Asset Generation
|
|
2
2
|
// Demonstrates how to use in a practical workflow with directories.
|
|
3
|
+
// COMMENTED OUT BECAUSE AI WILL FORCE THEMSELVES TO RUN IT
|
|
3
4
|
|
|
4
|
-
let outputDir = "assets/products/"
|
|
5
|
-
make_dir(outputDir)
|
|
6
|
-
let products = ["coffee_mug", "desk_lamp", "notebook"]
|
|
7
|
-
for product in products
|
|
8
|
-
{print "Generating asset for:" product
|
|
9
|
-
prompt request {"A clean studio presentation photograph of a " product " on a solid white background."}
|
|
10
|
-
prompt filename { outputDir product ".png" }
|
|
11
|
-
try
|
|
12
|
-
{let imageData = image("gemini-3.1-flash-image-preview") {ratio: '1:1', size: "1K"} {request}
|
|
13
|
-
let success = write_image(filename, imageData)
|
|
14
|
-
if success {print "Saved:" filename}}
|
|
15
|
-
catch (e) {print "Failed processing" product ":"
|
|
16
|
-
print e}}
|
|
17
|
-
print "Asset generation complete."
|
|
5
|
+
// let outputDir = "assets/products/"
|
|
6
|
+
// make_dir(outputDir)
|
|
7
|
+
// let products = ["coffee_mug", "desk_lamp", "notebook"]
|
|
8
|
+
// for product in products
|
|
9
|
+
// {print "Generating asset for:" product
|
|
10
|
+
// prompt request {"A clean studio presentation photograph of a " product " on a solid white background."}
|
|
11
|
+
// prompt filename { outputDir product ".png" }
|
|
12
|
+
// try
|
|
13
|
+
// {let imageData = image("gemini-3.1-flash-image-preview") {ratio: '1:1', size: "1K"} {request}
|
|
14
|
+
// let success = write_image(filename, imageData)
|
|
15
|
+
// if success {print "Saved:" filename}}
|
|
16
|
+
// catch (e) {print "Failed processing" product ":"
|
|
17
|
+
// print e}}
|
|
18
|
+
// print "Asset generation complete."
|
package/examples/16_modules.sesi
CHANGED
|
@@ -12,7 +12,7 @@ print "2 raised to power of 10:" + str(pow(2, 10))
|
|
|
12
12
|
print "Sine of PI/2:" + str(sin(PI / 2.0))
|
|
13
13
|
print "=== 2. Standard JSON Module ==="
|
|
14
14
|
import {stringify, parse} from "std/json"
|
|
15
|
-
let original = {"project": "Sesi Language", "version": "1.3.
|
|
15
|
+
let original = {"project": "Sesi Language", "version": "1.3.1", "features": ["modules", "http", "parallel"]}
|
|
16
16
|
let json_str = stringify(original)
|
|
17
17
|
print "Serialized JSON string:"
|
|
18
18
|
print json_str
|
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
// Example 19: Search the Web with Sesi
|
|
2
|
+
// COMMENTED OUT BECAUSE AI WILL FORCE THEMSELVES TO RUN IT
|
|
2
3
|
|
|
3
|
-
let response = model("gemini-3.1-flash-lite") {search, max_tokens: 1000} {"What is the weather in Tokyo?"}
|
|
4
|
-
print response
|
|
4
|
+
// let response = model("gemini-3.1-flash-lite") {search, max_tokens: 1000} {"What is the weather in Tokyo?"}
|
|
5
|
+
// print response
|
|
6
|
+
|
|
7
|
+
// Use web_get()
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
let q = "Coding"
|
|
11
|
+
prompt url {"http://api.duckduckgo.com/?q=" q "&format=json"}
|
|
12
|
+
let content = web_get(url)
|
|
13
|
+
let data = from_json(content)
|
|
14
|
+
print "Downloaded: " url
|
|
15
|
+
print "Saving results to search_results.json"
|
|
16
|
+
write_file("search_results.json", to_json(data))
|
|
17
|
+
print "Saved result to search_results.json"
|
|
18
|
+
} catch (err) {
|
|
19
|
+
print "Error: " err
|
|
20
|
+
}
|
|
@@ -5,18 +5,18 @@
|
|
|
5
5
|
// 3. Using aliases inside workflow() steps
|
|
6
6
|
|
|
7
7
|
print "=== Registering model aliases ==="
|
|
8
|
-
set_alias("
|
|
9
|
-
set_alias("
|
|
8
|
+
set_alias("summary", "gemini-3.1-flash-lite")
|
|
9
|
+
set_alias("detailed", "gemini-3-flash-preview")
|
|
10
10
|
print "=== Fast summary call ==="
|
|
11
|
-
let quick = model("
|
|
11
|
+
let quick = model("summary") {max_tokens: 100} {"Summarize the benefits of model aliases in two short bullet points."}
|
|
12
12
|
print quick
|
|
13
13
|
print "=== Deeper reasoning call ==="
|
|
14
|
-
let deepAnswer = model("
|
|
14
|
+
let deepAnswer = model("detailed") {thinkingLevel: "medium", max_tokens: 320} {"Give one practical tradeoff between a fast model and a deep reasoning model."}
|
|
15
15
|
print deepAnswer
|
|
16
16
|
print "=== Workflow with aliased model names ==="
|
|
17
17
|
let steps = [
|
|
18
|
-
{"model": "
|
|
19
|
-
{"model": "
|
|
18
|
+
{"model": "summary", "prompt": "Draft a one-line launch update about aliases: "},
|
|
19
|
+
{"model": "summary", "prompt": "Tighten wording and remove fluff: "}
|
|
20
20
|
]
|
|
21
21
|
let flow = workflow(steps, "Custom model naming is now available")
|
|
22
22
|
print flow["final"]
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// main/test_general_modules.sesi
|
|
2
|
+
// Consolidates test cases for shell-automation, markdown-compiler, data-analyzer, and db-helper.
|
|
3
|
+
|
|
4
|
+
import {parse_csv, export_to_csv, compute_average, compute_max, compute_min, sort_records, filter_records} from "data-analyzer"
|
|
5
|
+
import {parse_markdown, compile_markdown_file} from "markdown-compiler"
|
|
6
|
+
import {run_command_log, zip_directory} from "shell-automation"
|
|
7
|
+
import {insert_record, find_records_paginated, count_records, delete_record} from "db-helper"
|
|
8
|
+
import {assert_equals, assert_not_null, run_test_suite} from "test-runner"
|
|
9
|
+
|
|
10
|
+
print "Starting Module Import Test Suite..."
|
|
11
|
+
let results = []
|
|
12
|
+
|
|
13
|
+
// ==========================================
|
|
14
|
+
// 1. Data-Analyzer Test cases (Expanded)
|
|
15
|
+
// ==========================================
|
|
16
|
+
print "\n--- Testing Data-Analyzer Module ---"
|
|
17
|
+
let csv_data = "name,crew,reputationScore\nBlaze,D-Mob Crew,95\nDoc,D-Mob Crew,85\nCrow,Crow Syndicate,80"
|
|
18
|
+
|
|
19
|
+
let records = parse_csv(csv_data)
|
|
20
|
+
push(results, assert_equals(len(records), 3, "Parsed CSV string contains correct number of rows"))
|
|
21
|
+
push(results, assert_equals(records[0]["name"], "Blaze", "Parsed fields contain correct row header values"))
|
|
22
|
+
|
|
23
|
+
let dmob_crew = filter_records(records, "crew", "D-Mob Crew")
|
|
24
|
+
push(results, assert_equals(len(dmob_crew), 2, "Filtered records returned matching subset count"))
|
|
25
|
+
|
|
26
|
+
let avg_score = compute_average(records, "reputationScore")
|
|
27
|
+
push(results, assert_equals(avg_score, 86.66666666666667, "Numerical average score computed correctly"))
|
|
28
|
+
|
|
29
|
+
// Assert Max / Min
|
|
30
|
+
let max_score = compute_max(records, "reputationScore")
|
|
31
|
+
push(results, assert_equals(max_score, 95, "Numerical maximum aggregate computed correctly"))
|
|
32
|
+
|
|
33
|
+
let min_score = compute_min(records, "reputationScore")
|
|
34
|
+
push(results, assert_equals(min_score, 80, "Numerical minimum aggregate computed correctly"))
|
|
35
|
+
|
|
36
|
+
// Bubble Sort Check (Sorting descending)
|
|
37
|
+
let sorted = sort_records(records, "reputationScore", false)
|
|
38
|
+
push(results, assert_equals(sorted[0]["name"], "Blaze", "Bubble sort sorts descending correctly (index 0 is max)"))
|
|
39
|
+
push(results, assert_equals(sorted[2]["name"], "Crow", "Bubble sort sorts descending correctly (index 2 is min)"))
|
|
40
|
+
|
|
41
|
+
let exported = export_to_csv(records, ["name", "reputationScore"])
|
|
42
|
+
let exported_rows = split(exported, "\n")
|
|
43
|
+
push(results, assert_equals(exported_rows[0], "name,reputationScore", "CSV exportation formats headers correctly"))
|
|
44
|
+
push(results, assert_equals(exported_rows[1], "Blaze,95", "CSV exportation serializes fields correctly"))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
// ==========================================
|
|
48
|
+
// 2. Markdown-Compiler Test cases (Expanded)
|
|
49
|
+
// ==========================================
|
|
50
|
+
print "\n--- Testing Markdown-Compiler Module ---"
|
|
51
|
+
let raw_markdown = "# Underground Rules
|
|
52
|
+
## Subway *Turf*
|
|
53
|
+
- Rule 1: No weapons
|
|
54
|
+
- Rule 2: Keep it **clean** and [D-Mob](https://dmob.com) loyal
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
let x = 1
|
|
58
|
+
```"
|
|
59
|
+
|
|
60
|
+
let parsed_html = parse_markdown(raw_markdown)
|
|
61
|
+
|
|
62
|
+
// Check heading structure
|
|
63
|
+
push(results, assert_equals(len(split(parsed_html, "<h1>Underground Rules</h1>")) > 1, true, "H1 parsed correctly"))
|
|
64
|
+
push(results, assert_equals(len(split(parsed_html, "<h2>Subway <em>Turf</em></h2>")) > 1, true, "Italic parsed inside headings correctly"))
|
|
65
|
+
|
|
66
|
+
// Check list structure
|
|
67
|
+
push(results, assert_equals(len(split(parsed_html, "<li>Rule 1: No weapons</li>")) > 1, true, "Bullets parsed correctly"))
|
|
68
|
+
|
|
69
|
+
// Check bold accent
|
|
70
|
+
push(results, assert_equals(len(split(parsed_html, "<strong>clean</strong>")) > 1, true, "Bold syntax parsed correctly"))
|
|
71
|
+
|
|
72
|
+
// Check inline hyperlinks
|
|
73
|
+
push(results, assert_equals(len(split(parsed_html, "<a href='https://dmob.com'")) > 1, true, "Hyperlink markdown ([text](url)) parsed correctly"))
|
|
74
|
+
|
|
75
|
+
// Check code block
|
|
76
|
+
push(results, assert_equals(len(split(parsed_html, "<pre><code>let x = 1")) > 1, true, "Code blocks parsed correctly"))
|
|
77
|
+
|
|
78
|
+
// File compilation test
|
|
79
|
+
let mock_md = "main/mock_rules.md"
|
|
80
|
+
let compiled_html = "main/mock_rules.html"
|
|
81
|
+
write_file(mock_md, raw_markdown)
|
|
82
|
+
|
|
83
|
+
let compile_result = compile_markdown_file(mock_md, compiled_html, "Underground System Rules")
|
|
84
|
+
push(results, assert_equals(compile_result, true, "Markdown file compiled and saved successfully"))
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
// ==========================================
|
|
88
|
+
// 3. Flat-File DB Module Test cases (Expanded)
|
|
89
|
+
// ==========================================
|
|
90
|
+
print "\n--- Testing Flat-File DB Module ---"
|
|
91
|
+
let db_path = "main/test_database.json"
|
|
92
|
+
|
|
93
|
+
// Clean insert some test fighters
|
|
94
|
+
let f1 = insert_record(db_path, "test_fighters", {"name": "Fighter A", "rank": 1})
|
|
95
|
+
let f2 = insert_record(db_path, "test_fighters", {"name": "Fighter B", "rank": 2})
|
|
96
|
+
let f3 = insert_record(db_path, "test_fighters", {"name": "Fighter C", "rank": 3})
|
|
97
|
+
|
|
98
|
+
let count = count_records(db_path, "test_fighters")
|
|
99
|
+
push(results, assert_equals(count >= 3, true, "Collection records count retrieved successfully"))
|
|
100
|
+
|
|
101
|
+
// Paginated query: Limit 2, Offset 1
|
|
102
|
+
let paginated = find_records_paginated(db_path, "test_fighters", "", "", 2, 1)
|
|
103
|
+
push(results, assert_equals(len(paginated), 2, "Pagination returns correct limit subset length"))
|
|
104
|
+
push(results, assert_equals(paginated[0]["name"], "Fighter B", "Pagination returns correct offset item"))
|
|
105
|
+
|
|
106
|
+
// Clean up
|
|
107
|
+
delete_record(db_path, "test_fighters", f1["id"])
|
|
108
|
+
delete_record(db_path, "test_fighters", f2["id"])
|
|
109
|
+
delete_record(db_path, "test_fighters", f3["id"])
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
// ==========================================
|
|
113
|
+
// 4. Shell-Automation Test cases
|
|
114
|
+
// ==========================================
|
|
115
|
+
print "\n--- Testing Shell-Automation Module ---"
|
|
116
|
+
let log_path = "main/test_shell_command.log"
|
|
117
|
+
let log_result = run_command_log("sesi --version", log_path)
|
|
118
|
+
push(results, assert_equals(log_result, true, "Shell command logged successfully"))
|
|
119
|
+
|
|
120
|
+
let log_contents = read_file(log_path)
|
|
121
|
+
push(results, assert_equals(len(split(log_contents, "v")) > 1, true, "Log contents contain command output"))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
// ==========================================
|
|
125
|
+
// Run Final Suite Metrics
|
|
126
|
+
// ==========================================
|
|
127
|
+
run_test_suite("Expanded General-Purpose Scripting Suite", results)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@misterscan/sesi",
|
|
3
|
-
"version": "1.3.
|
|
4
|
-
"description": "Sesi: A
|
|
3
|
+
"version": "1.3.3",
|
|
4
|
+
"description": "Sesi: A Concise, Legible Programming Language",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"sesi": "bin/sesi.js"
|
|
@@ -11,14 +11,24 @@
|
|
|
11
11
|
"bin",
|
|
12
12
|
"docs",
|
|
13
13
|
"examples",
|
|
14
|
-
"main"
|
|
14
|
+
"main/tests",
|
|
15
|
+
".agents",
|
|
16
|
+
"chatbot",
|
|
17
|
+
".github"
|
|
15
18
|
],
|
|
16
19
|
"scripts": {
|
|
17
|
-
"lint": "
|
|
20
|
+
"lint": "sesi -l lint.sesi",
|
|
18
21
|
"build": "tsc",
|
|
19
22
|
"dev": "npm run lint && dotenvx run -- npm run build --watch",
|
|
20
23
|
"test": "npx ts-node tests/basic.test.ts && npx ts-node tests/module.test.ts && npx ts-node tests/cache.test.ts && npx ts-node tests/http.test.ts && npx ts-node tests/workflow.test.ts && npx ts-node tests/security.test.ts",
|
|
21
24
|
"test:watch": "npm run lint && npx ts-node tests/basic.test.ts --watch",
|
|
25
|
+
"sesi": "bin/sesi.js",
|
|
26
|
+
"sesi:local": "sesi -l",
|
|
27
|
+
"sesi:eval": "sesi -e",
|
|
28
|
+
"sesi:parse": "sesi -r",
|
|
29
|
+
"sesi:encrypt": "sesi -enc",
|
|
30
|
+
"sesi:decrypt": "sesi -dec",
|
|
31
|
+
"copilot": "sesi chatbot/sesi_db_chatbot.sesi",
|
|
22
32
|
"build:exe": "node ./scripts/build-binaries.mjs",
|
|
23
33
|
"msi:eula": "powershell -NoProfile -ExecutionPolicy Bypass -Command \"& 'C:\\Program Files\\WiX Toolset v7.0\\bin\\wix.exe' eula accept wix7\"",
|
|
24
34
|
"build:msi": "powershell -NoProfile -ExecutionPolicy Bypass -Command \"& 'C:\\Program Files\\WiX Toolset v7.0\\bin\\wix.exe' build .\\SesiInstaller.wxs -o .\\SesiInstaller.msi\"",
|
|
@@ -28,36 +38,30 @@
|
|
|
28
38
|
"repl": "node dist/repl.js",
|
|
29
39
|
"example": "node --no-deprecation example.js",
|
|
30
40
|
"example:ai": "node --no-deprecation example-ai.js",
|
|
31
|
-
"example:all": "
|
|
41
|
+
"example:all": "sesi examples.sesi",
|
|
32
42
|
"upload": "npm run build && npm publish --access public"
|
|
33
43
|
},
|
|
34
44
|
"keywords": [
|
|
35
45
|
"sesi",
|
|
36
|
-
"systems-language",
|
|
37
46
|
"programming-language",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"interpreter",
|
|
45
|
-
"typescript"
|
|
47
|
+
"workflow-automation",
|
|
48
|
+
"concise",
|
|
49
|
+
"legible",
|
|
50
|
+
"ast-interpreter",
|
|
51
|
+
"misterscan",
|
|
52
|
+
"cli"
|
|
46
53
|
],
|
|
47
54
|
"author": "Misterscan",
|
|
48
55
|
"license": "MIT",
|
|
49
56
|
"dependencies": {
|
|
50
|
-
"@dotenvx/dotenvx": "1.
|
|
51
|
-
"@dotenvx/dotenvx-ops": "0.
|
|
52
|
-
"@google/genai": "2.
|
|
57
|
+
"@dotenvx/dotenvx": "1.71.0",
|
|
58
|
+
"@dotenvx/dotenvx-ops": "0.53.2",
|
|
59
|
+
"@google/genai": "2.7.0"
|
|
53
60
|
},
|
|
54
61
|
"devDependencies": {
|
|
55
|
-
"@eslint/js": "^10.0.1",
|
|
56
62
|
"@types/node": "25.9.1",
|
|
57
|
-
"eslint": "10.4.0",
|
|
58
63
|
"globals": "^17.6.0",
|
|
59
64
|
"rcedit": "^5.0.2",
|
|
60
|
-
"typescript": "6.0.3"
|
|
61
|
-
"typescript-eslint": "8.60.0"
|
|
65
|
+
"typescript": "6.0.3"
|
|
62
66
|
}
|
|
63
67
|
}
|
package/docs/CONCURRENCY.md
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# Concurrency with Sesi
|
|
2
|
-
|
|
3
|
-
This document details how Sesi handles process concurrency and file locks.
|
|
4
|
-
|
|
5
|
-
## The "Bank" Case Study
|
|
6
|
-
|
|
7
|
-
In this experiment, Sesi was used to solve file contention.
|
|
8
|
-
|
|
9
|
-
### The Challenge
|
|
10
|
-
|
|
11
|
-
Five independent Sesi instances (3 Deposits, 2 Withdrawals) were launched simultaneously. All instances needed to update a single `balance.txt` file without causing data loss through race conditions.
|
|
12
|
-
|
|
13
|
-
### The Solution (Mutex / File Locking)
|
|
14
|
-
|
|
15
|
-
Sesi solves this using file locking via `try/catch` and file I/O builtins.
|
|
16
|
-
|
|
17
|
-
#### 1. Unique Identity
|
|
18
|
-
|
|
19
|
-
Each instance generates a unique ID using Sesi's native `time()` and `random()` builtins.
|
|
20
|
-
|
|
21
|
-
```sesi
|
|
22
|
-
let id = "Agent_" + str(time()) + "_" + str(random())
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
#### 2. Mutual Exclusion Loop
|
|
26
|
-
|
|
27
|
-
The agent "polls" the lock file. If it finds it "unlocked," it attempts to claim it. Crucially, it then **verifies** its own claim after a micro-delay to ensure it wasn't overwritten by a simultaneous process.
|
|
28
|
-
|
|
29
|
-
```sesi
|
|
30
|
-
while locked {
|
|
31
|
-
if read_file("lock.txt") == "unlocked" {
|
|
32
|
-
write_file("lock.txt", id)
|
|
33
|
-
// Settle delay
|
|
34
|
-
let i = 0 while i < 500 { i = i + 1 }
|
|
35
|
-
// Verification
|
|
36
|
-
if read_file("lock.txt") == id { locked = false }
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
#### 3. Critical Section Resilience
|
|
42
|
-
|
|
43
|
-
Using `try/catch`, Sesi scripts gracefully handle filesystem contention.
|
|
44
|
-
|
|
45
|
-
```sesi
|
|
46
|
-
try {
|
|
47
|
-
write_file("balance.txt", str(num(read_file("balance.txt")) + 100))
|
|
48
|
-
write_file("lock.txt", "unlocked") // Release
|
|
49
|
-
} catch (e) {
|
|
50
|
-
write_file("lock.txt", "unlocked") // Emergency release
|
|
51
|
-
}
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## Concurrency via `spawn()`
|
|
55
|
-
|
|
56
|
-
Sesi v1.1 introduced the `spawn()` builtin, allowing a single **Master Orchestrator** to launch concurrent proccesses of sesi scripts from one main file.
|
|
57
|
-
|
|
58
|
-
```sesi
|
|
59
|
-
// Master: Launching 5 Concurrent Processes...
|
|
60
|
-
spawn("main/atm_deposit.sesi")
|
|
61
|
-
spawn("main/atm_withdraw.sesi")
|
|
62
|
-
spawn("main/atm_deposit.sesi")
|
|
63
|
-
spawn("main/atm_withdraw.sesi")
|
|
64
|
-
spawn("main/atm_deposit.sesi")
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Why This Matters
|
|
68
|
-
|
|
69
|
-
Sesi's approach to distributed systems is **Concise** and **Readable**. What would take dozens of lines of boilerplate in C or Java (handling threads, mutexes, and I/O exceptions) is expressed in Sesi as a series of intuitive blocks.
|
|
70
|
-
|
|
71
|
-
This enables developers to build **Agent Swarms** that can work in parallel on large-scale datasets, research tasks, or code generation pipelines with guaranteed state integrity.
|