@misterscan/sesi 1.1.1

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.
Files changed (82) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +191 -0
  3. package/bin/sesi.js +56 -0
  4. package/dist/ai-runtime.d.ts +15 -0
  5. package/dist/ai-runtime.d.ts.map +1 -0
  6. package/dist/ai-runtime.js +214 -0
  7. package/dist/ai-runtime.js.map +1 -0
  8. package/dist/builtins.d.ts +7 -0
  9. package/dist/builtins.d.ts.map +1 -0
  10. package/dist/builtins.js +473 -0
  11. package/dist/builtins.js.map +1 -0
  12. package/dist/index.d.ts +3 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +72 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/interpreter.d.ts +36 -0
  17. package/dist/interpreter.d.ts.map +1 -0
  18. package/dist/interpreter.js +495 -0
  19. package/dist/interpreter.js.map +1 -0
  20. package/dist/lexer.d.ts +26 -0
  21. package/dist/lexer.d.ts.map +1 -0
  22. package/dist/lexer.js +340 -0
  23. package/dist/lexer.js.map +1 -0
  24. package/dist/parser.d.ts +55 -0
  25. package/dist/parser.d.ts.map +1 -0
  26. package/dist/parser.js +1022 -0
  27. package/dist/parser.js.map +1 -0
  28. package/dist/types.d.ts +304 -0
  29. package/dist/types.d.ts.map +1 -0
  30. package/dist/types.js +63 -0
  31. package/dist/types.js.map +1 -0
  32. package/docs/ARCHITECTURE.md +430 -0
  33. package/docs/BUILTINS.md +577 -0
  34. package/docs/COMPARISON.md +334 -0
  35. package/docs/DISTRIBUTED_SYSTEMS.md +71 -0
  36. package/docs/IMAGE_GENERATION.md +76 -0
  37. package/docs/IMPLEMENTATION_SUMMARY.md +533 -0
  38. package/docs/QUICKSTART.md +351 -0
  39. package/docs/README.md +191 -0
  40. package/docs/ROADMAP.md +408 -0
  41. package/docs/SPECIFICATION.md +462 -0
  42. package/docs/SYSTEMS_REASONING.md +522 -0
  43. package/examples/01_hello.sesi +2 -0
  44. package/examples/02_variables.sesi +11 -0
  45. package/examples/03_functions.sesi +6 -0
  46. package/examples/04_conditionals.sesi +6 -0
  47. package/examples/05_loops.sesi +12 -0
  48. package/examples/06_arrays_objects.sesi +18 -0
  49. package/examples/07_prompts.sesi +10 -0
  50. package/examples/08_model_call.sesi +5 -0
  51. package/examples/09_structured_output.sesi +7 -0
  52. package/examples/10_code_generation.sesi +5 -0
  53. package/examples/11_memory_conversation.sesi +16 -0
  54. package/examples/12_classification.sesi +8 -0
  55. package/examples/13_data_pipeline.sesi +35 -0
  56. package/examples/14_folder_explainer.sesi +58 -0
  57. package/examples/15_image_generation.sesi +17 -0
  58. package/main/atm_deposit.sesi +37 -0
  59. package/main/atm_withdraw.sesi +37 -0
  60. package/main/data.txt +1 -0
  61. package/main/math_aggregator.sesi +15 -0
  62. package/main/math_generator.sesi +7 -0
  63. package/main/math_processor.sesi +23 -0
  64. package/main/orchestrator.sesi +15 -0
  65. package/main/playground.sesi +1 -0
  66. package/main/setup_swarm.sesi +5 -0
  67. package/main/start.sesi +13 -0
  68. package/main/tax_calculator.sesi +15 -0
  69. package/main/tests/compare.sesi +23 -0
  70. package/main/tests/compare.ts +104 -0
  71. package/main/tests/debug.sesi +1 -0
  72. package/main/tests/demo.sesi +24 -0
  73. package/main/tests/primitive_validation.sesi +18 -0
  74. package/main/tests/test_connection.sesi +4 -0
  75. package/main/tests/test_failure_debug.sesi +2 -0
  76. package/main/tests/test_image.sesi +3 -0
  77. package/main/tests/test_parser_config.sesi +2 -0
  78. package/main/tests/test_syntax.sesi +3 -0
  79. package/main/tests/test_tool_call.sesi +14 -0
  80. package/main/tests/try.sesi +7 -0
  81. package/main/vault.sesi +15 -0
  82. package/package.json +50 -0
@@ -0,0 +1,334 @@
1
+ # The Sesi Advantage: Why We Built a Systems & Orchestration Language
2
+
3
+ Integrating Large Language Models (LLMs) into traditional applications today is painful. Standard programming languages treat AI as an external service requiring SDKs, manual prompt string concatenation, complex schema definitions, and fragile JSON parsing.
4
+
5
+ **Sesi treats Reasoning as a first-class language primitive.**
6
+
7
+ This document demonstrates exactly how much boilerplate and complexity Sesi eliminates compared to traditional languages like TypeScript, Python, and Go.
8
+
9
+ ---
10
+
11
+ ## 📊 The Cost of Boilerplate: A Data Comparison
12
+
13
+ When building a simple AI-powered data pipeline (structured data extraction + conditional function calling), traditional languages spend more than half their code managing the SDK rather than executing business logic.
14
+
15
+ ```mermaid
16
+ xychart-beta
17
+ title "Lines of Code (LOC) for an AI Data Pipeline"
18
+ x-axis ["Sesi", "Python", "TypeScript", "Go"]
19
+ y-axis "Lines of Code" 0 --> 140
20
+ bar [16, 45, 105, 130]
21
+ ```
22
+
23
+ ### Where do the lines go?
24
+
25
+ ```mermaid
26
+ pie title TypeScript Pipeline Breakdown (105 LOC)
27
+ "Business Logic" : 45
28
+ "Schema Declarations" : 25
29
+ "SDK & Config Boilerplate" : 15
30
+ "Manual JSON Parsing/Try-Catch" : 10
31
+ "Empty Lines" : 10
32
+ ```
33
+
34
+ ```mermaid
35
+ pie title Sesi Pipeline Breakdown (16 LOC)
36
+ "Business Logic" : 16
37
+ "SDK Setup (Native)" : 0
38
+ "Schema Boilerplate (Native)" : 0
39
+ "JSON Parsing (Native)" : 0
40
+ "Comments" : 0
41
+ ```
42
+
43
+ ---
44
+
45
+ ## đź’» The Side-by-Side Comparison
46
+
47
+ We tasked four languages with building the same script:
48
+
49
+ 1. Loop over customer feedback.
50
+ 2. Extract structured data (Sentiment, Category, Urgency).
51
+ 3. If urgent, execute a local function (`escalateTicket`).
52
+
53
+ ### 1. The Sesi Implementation (16 Lines)
54
+
55
+ In Sesi, there are no SDK imports, no manual API key initializations, no complex schema builder libraries, mininmal to no comments, and no manual response parsing.
56
+
57
+ ```sesi
58
+ fn escalateTicket(customerId: string, reason: string) {
59
+ print "ESCALATION: Customer" customerId "for" reason
60
+ return "Escalation logged."
61
+ }
62
+ memory processingLog {"Pipeline Start:"}
63
+ let rawFeedback = ["My account was charged twice for the pro plan! Fix this now!", "The new dashboard is really clean, great job team.", "I can't figure out how to export my data to CSV, it just spins."]
64
+ for feedback in rawFeedback
65
+ {processingLog = processingLog + "Processing:" + feedback
66
+ let analysis = structured_output({sentiment: string, category: string, isUrgent: bool, summary: string})
67
+ (model("gemini-3.1-flash-lite") {"Analyze the customer feedback. Category should be Billing, UI, or Technical. Feedback:" feedback})
68
+ print "Result for:" analysis["summary"]
69
+ if analysis["isUrgent"]
70
+ {let resolution = tool_call(escalateTicket)(model("gemini-3.1-flash-lite") {"Call escalateTicket for customer '1234' with an exact reason based on:" feedback})
71
+ processingLog = processingLog + "Urgent action taken:" + resolution} else {processingLog = processingLog + "Logged routinely."}}
72
+ print "--- Final Processing Log ---"
73
+ print processingLog
74
+ ```
75
+
76
+ ### 2. The TypeScript Implementation (105 Lines)
77
+
78
+ TypeScript requires the official Google Gen AI SDK. Notice how much code is dedicated just to telling the model _what_ we want it to do (Schemas, Tool Declarations) and _handling_ what it gives back (JSON.parse).
79
+
80
+ ```typescript
81
+ import { GoogleGenAI, Type } from "@google/genai";
82
+
83
+ const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
84
+
85
+ // The tool we want the model to call
86
+ function escalateTicket(customerId: string, reason: string): string {
87
+ console.log(`ESCALATION: Customer ${customerId} for ${reason}`);
88
+ return "Escalation logged.";
89
+ }
90
+
91
+ // 1. Tool Declaration for the SDK (Boilerplate)
92
+ const escalateToolDeclaration = {
93
+ functionDeclarations: [
94
+ {
95
+ name: "escalateTicket",
96
+ description: "Escalate an urgent customer ticket",
97
+ parameters: {
98
+ type: Type.OBJECT,
99
+ properties: {
100
+ customerId: { type: Type.STRING, description: "ID of the customer" },
101
+ reason: { type: Type.STRING, description: "Reason for escalation" },
102
+ },
103
+ required: ["customerId", "reason"],
104
+ },
105
+ },
106
+ ],
107
+ };
108
+
109
+ async function processFeedback() {
110
+ let processingLog = "Pipeline Start:\n";
111
+
112
+ const rawFeedback = [
113
+ "My account was charged twice for the pro plan! Fix this now!",
114
+ "The new dashboard is really clean, great job team.",
115
+ "I can't figure out how to export my data to CSV, it just spins.",
116
+ ];
117
+
118
+ for (const feedback of rawFeedback) {
119
+ processingLog += `Processing: ${feedback}\n`;
120
+
121
+ // 2. Structured Data Extraction (Boilerplate Schema)
122
+ const schema = {
123
+ type: Type.OBJECT,
124
+ properties: {
125
+ sentiment: { type: Type.STRING },
126
+ category: {
127
+ type: Type.STRING,
128
+ description: "Billing, UI, or Technical",
129
+ },
130
+ isUrgent: { type: Type.BOOLEAN },
131
+ summary: { type: Type.STRING },
132
+ },
133
+ required: ["sentiment", "category", "isUrgent", "summary"],
134
+ };
135
+
136
+ const analysisResponse = await ai.models.generateContent({
137
+ model: "gemini-3.1-flash-lite",
138
+ contents: `Analyze the customer feedback. Category should be Billing, UI, or Technical.\nFeedback: ${feedback}`,
139
+ config: {
140
+ responseMimeType: "application/json",
141
+ responseSchema: schema,
142
+ },
143
+ });
144
+
145
+ // 3. Manual JSON parsing and error handling
146
+ let analysis;
147
+ try {
148
+ analysis = JSON.parse(analysisResponse.text || "{}");
149
+ } catch (e) {
150
+ console.error("Failed to parse JSON");
151
+ continue;
152
+ }
153
+
154
+ console.log(`Result for: ${analysis.summary}`);
155
+
156
+ // 4. Conditional Tool Calling & Response Handling
157
+ if (analysis.isUrgent) {
158
+ const escalationResponse = await ai.models.generateContent({
159
+ model: "gemini-3.1-flash-lite",
160
+ contents: `Call escalateTicket for customer '1234' with an exact reason based on:\n${feedback}`,
161
+ config: {
162
+ tools: [escalateToolDeclaration],
163
+ },
164
+ });
165
+
166
+ // 5. Manual extraction of the function call from the response object
167
+ if (
168
+ escalationResponse.functionCalls &&
169
+ escalationResponse.functionCalls.length > 0
170
+ ) {
171
+ const call = escalationResponse.functionCalls[0];
172
+ if (call.name === "escalateTicket") {
173
+ const args = call.args as any;
174
+ // Manual invocation of our local function using the args
175
+ const resolution = escalateTicket(args.customerId, args.reason);
176
+ processingLog += `Urgent action taken: ${resolution}\n`;
177
+ }
178
+ } else {
179
+ processingLog += `Urgent action failed to trigger tool.\n`;
180
+ }
181
+ } else {
182
+ processingLog += "Logged routinely.\n";
183
+ }
184
+ }
185
+
186
+ console.log("\n--- Final Processing Log ---");
187
+ console.log(processingLog);
188
+ }
189
+
190
+ processFeedback().catch(console.error);
191
+ ```
192
+
193
+ ### 3. The Python Implementation (45 Lines)
194
+
195
+ Python is cleaner than TypeScript thanks to `Pydantic`, but still requires significant setup for function calling and schema extraction.
196
+
197
+ ```python
198
+ import os
199
+ import json
200
+ from google import genai
201
+ from pydantic import BaseModel
202
+
203
+ client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
204
+
205
+ def escalate_ticket(customer_id: str, reason: str) -> str:
206
+ print(f"ESCALATION: Customer {customer_id} for {reason}")
207
+ return "Escalation logged."
208
+
209
+ # BOILERPLATE: Pydantic Schema Definition
210
+ class FeedbackAnalysis(BaseModel):
211
+ sentiment: str
212
+ category: str
213
+ is_urgent: bool
214
+ summary: str
215
+
216
+ def process_feedback():
217
+ raw_feedback = ["My account was charged twice..."]
218
+
219
+ for feedback in raw_feedback:
220
+ response = client.models.generate_content(
221
+ model='gemini-3.1-flash-lite',
222
+ contents=f'Analyze the customer feedback.\nFeedback: {feedback}',
223
+ config={'response_mime_type': 'application/json', 'response_schema': FeedbackAnalysis}
224
+ )
225
+
226
+ # Parse Pydantic object
227
+ analysis = FeedbackAnalysis.model_validate_json(response.text)
228
+
229
+ if analysis.is_urgent:
230
+ escalation_response = client.models.generate_content(
231
+ model='gemini-3.1-flash-lite',
232
+ contents=f"Call escalate_ticket for customer '1234' based on:\n{feedback}",
233
+ config={'tools': [escalate_ticket]}
234
+ )
235
+
236
+ # BOILERPLATE: Manual Tool Routing
237
+ for tool_call in escalation_response.function_calls:
238
+ if tool_call.name == "escalate_ticket":
239
+ escalate_ticket(**tool_call.args)
240
+
241
+ if __name__ == "__main__":
242
+ process_feedback()
243
+ ```
244
+
245
+ ### 4. The Go Implementation (130+ Lines)
246
+
247
+ In Go, statically typed strictness combined with AI responses creates massive struct-defining overhead. You must define deeply nested JSON structs, handle raw byte marshaling/unmarshaling, and manually map AI function call payloads to Go reflection or manual switch statements. Sesi replaces all 130 lines of this with just its native 16 lines.
248
+
249
+ ---
250
+
251
+ ## Showcase 3: Distributed Orchestration Swarm
252
+
253
+ This example demonstrates a complex distributed task: Spawning a background researcher, polling for completion with fault tolerance, and synthesizing results with AI.
254
+
255
+ ### TypeScript (Systems Boilerplate)
256
+
257
+ ```typescript
258
+ import { spawn } from "child_process";
259
+ import { readFile, writeFile } from "fs/promises";
260
+ import { GoogleGenerativeAI } from "@google/generative-ai";
261
+
262
+ async function run() {
263
+ const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!);
264
+ const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
265
+
266
+ const worker = spawn("node", ["dist/index.js", "researcher.sesi"], {
267
+ detached: true,
268
+ });
269
+ worker.unref();
270
+
271
+ let research = null;
272
+ while (!research) {
273
+ try {
274
+ const status = await readFile("status.txt", "utf8");
275
+ if (status.trim() === "done") {
276
+ research = await readFile("output.txt", "utf8");
277
+ }
278
+ } catch (e) {
279
+ await new Promise((r) => setTimeout(r, 500));
280
+ }
281
+ }
282
+
283
+ const result = await model.generateContent(`Synthesize: ${research}`);
284
+ console.log(result.response.text());
285
+ }
286
+ run();
287
+ ```
288
+
289
+ ### Sesi (Agentic Systems Native)
290
+
291
+ ```sesi
292
+ spawn("researcher.sesi")
293
+ let research = ""
294
+ while research == "" {
295
+ try {
296
+ if read_file("status.txt") == "done" {
297
+ research = read_file("output.txt")
298
+ }
299
+ } catch (e) {
300
+ let i = 0 while i < 1000 { i = i + 1 }
301
+ }
302
+ }
303
+ print model("gemini-3.1-flash-lite") {"Synthesize: " research}
304
+ ```
305
+
306
+ **Analysis**:
307
+
308
+ - **Conciseness**: Sesi achieves in 12 lines of native logic what requires 30+ lines of asynchronous boilerplate in TypeScript.
309
+ - **Orchestration**: `spawn` and `model` are first-class primitives in Sesi, removing the need for manual process management and SDK initialization.
310
+ - **Fault Tolerance**: Sesi's native `try/catch` handles filesystem contention with zero external library overhead.
311
+
312
+ ---
313
+
314
+ ## The Verdict
315
+
316
+ Sesi isn't just syntactic sugar. By embedding the AI runtime directly into the parser and interpreter, Sesi understands _intent_:
317
+
318
+ - You don't serialize schemas; Sesi builds the JSONSchema dynamically from your literal `{ key: type }` maps.
319
+ - You don't parse responses; Sesi validates and hydrates the objects for you.
320
+ - You don't route tool calls; Sesi pauses execution and handles the function reference automatically.
321
+
322
+ **Less boilerplate. Fewer bugs. Faster development.**
323
+
324
+ ---
325
+
326
+ ## See Also
327
+
328
+ - [Quickstart](../QUICKSTART.md)
329
+ - [Language Specification](SPECIFICATION.md)
330
+ - [Image Generation](IMAGE_GENERATION.md)
331
+ - [Built-in Functions](BUILTINS.md)
332
+ - [Architecture](ARCHITECTURE.md)
333
+ - [Reasoning Features](SYSTEMS_REASONING.md)
334
+ - [Distributed Systems](DISTRIBUTED_SYSTEMS.md)
@@ -0,0 +1,71 @@
1
+ # Distributed Systems with Sesi
2
+
3
+ Sesi is a robust systems-level environment capable of orchestrating complex, multi-process agent swarms. This document details how Sesi handles concurrency, race conditions, and distributed state.
4
+
5
+ ## The "Bank Swarm" Case Study
6
+
7
+ In this experiment, Sesi was used to solve a classic distributed systems problem: **Concurrent Mutual Exclusion.**
8
+
9
+ ### The Challenge
10
+
11
+ Five independent Sesi agents (3 Deposits, 2 Withdrawals) were launched simultaneously. All agents needed to update a single `balance.txt` file without causing data loss through race conditions.
12
+
13
+ ### The Sesi Solution (The "Double-Check Write" Pattern)
14
+
15
+ Sesi solves this using a high-level implementation of a filesystem lock. Even without low-level semaphores, Sesi's `try/catch` and file I/O builtins allow for an "indestructible" locking logic.
16
+
17
+ #### 1. Unique Identity
18
+
19
+ Each agent generates a globally 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 agents gracefully handle filesystem contention (when the OS prevents two processes from reading the same file at the exact same micro-second).
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+ introduces the `spawn()` builtin, allowing a single **Master Orchestrator** to launch an entire swarm of agents from one file.
57
+
58
+ ```sesi
59
+ // Master: Launching 5-Agent Swarm
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.
@@ -0,0 +1,76 @@
1
+ # Image Generation in Sesi
2
+
3
+ Sesi provides a native, language-level primitive for generating images using AI models. This primitive is designed to interoperate seamlessly with Sesi's file system builtins, allowing you to generate and persist images with minimal boilerplate.
4
+
5
+ ## The `image` Primitive
6
+
7
+ To generate an image, use the `image` keyword followed by the model name, an optional configuration block, and a prompt block.
8
+
9
+ ### Syntax
10
+
11
+ The syntax parallels standard `model` calls:
12
+
13
+ ```
14
+ image("model-name") {"configKey": "configValue"} {"Prompt text"}
15
+ ```
16
+
17
+ ### Basic Example
18
+
19
+ Here is a simple example demonstrating how to generate a single image and save it to disk directly:
20
+
21
+ ```sesi
22
+ // 1. Define the generation prompt natively
23
+ prompt request {"A simple minimalist company logo for a bakery"}
24
+
25
+ // 2. Call the image generation primitive
26
+ let imageData = image("gemini-3.1-flash-image-preview") {"ratio": "1:1", "size": "1K"} {request}
27
+
28
+ // 3. Write the payload to disk
29
+ try
30
+ {let success = write_image("bakery_logo.png", imageData)
31
+ if success {print "Saved bakery_logo.png successfully."}}
32
+ catch (e) {print "Failed to generate image:"
33
+ print e}
34
+ ```
35
+
36
+ ### Advanced Example: Batch Asset Generation Workflow
37
+
38
+ Here is a practical script demonstrating how to iterate over a data set, generate assets, and save them to a specific directory. This is useful for building automated pipelines like generating UI placeholders or product catalog images.
39
+
40
+ ```sesi
41
+ // Set up output directory
42
+ let outputDir = "assets/products/"
43
+ make_dir(outputDir)
44
+ let products = ["coffee_mug", "desk_lamp", "notebook"]
45
+
46
+ // Iterate through the list and generate a file for each
47
+ for product in products
48
+ {print "Generating asset for:" product
49
+
50
+ // Construct the instruction for the model
51
+ prompt request {"A clean studio presentation photograph of a " product " on a solid white background."}
52
+ prompt filename { outputDir product ".png" }
53
+ try
54
+ {let imageData = image("gemini-3.1-flash-image-preview") {"ratio": '1:1', "size": "1K"} {request}
55
+
56
+ // Attempt local file write
57
+ let success = write_image(filename, imageData)
58
+ if success {print "Saved:" filename}}
59
+ catch (e) {print "Failed processing" product ":"
60
+ print e}}
61
+ print "Asset generation complete."
62
+ ```
63
+
64
+ ## Configuration Options
65
+
66
+ When configuring the `image` call (specifically for models like `gemini-3.1-flash-image-preview`), the configuration block maps directly to backend SDK capabilities:
67
+
68
+ - `"ratio"`: The aspect ratio of the image (e.g., `"1:1"`, `"16:9"`, `"9:16"`).
69
+ - `"size"`: Dimensional sizing constraints (Must be `"512"`, `"1K"`, `"2K"`, or `"4K"`).
70
+ - `"temperature"`: Controls variance (e.g., `0.3`).
71
+
72
+ ## File I/O Integration: `write_image`
73
+
74
+ The `image()` call evaluates to a `string` (specifically, base64-encoded image data). To convert this into a standard image file on disk, you must use the `write_image(path, base64_content)` builtin.
75
+
76
+ **Important:** Do *not* use `write_file` for image payloads—`write_image` is explicitly implemented in the Sesi engine (`src/builtins.ts`) to handle `Buffer.from(content, 'base64')` decoding for writing safe binary formats.