@misterscan/sesi 1.2.3 → 1.3.0
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/README.md +101 -35
- package/bin/sesi.js +163 -38
- package/dist/builtins.d.ts.map +1 -1
- package/dist/builtins.js +196 -4
- package/dist/builtins.js.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -5
- package/dist/index.js.map +1 -1
- package/dist/interpreter.d.ts +11 -2
- package/dist/interpreter.d.ts.map +1 -1
- package/dist/interpreter.js +181 -88
- package/dist/interpreter.js.map +1 -1
- package/dist/lexer.d.ts.map +1 -1
- package/dist/lexer.js +8 -4
- package/dist/lexer.js.map +1 -1
- package/dist/parser.d.ts +1 -0
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +18 -8
- package/dist/parser.js.map +1 -1
- package/dist/types.d.ts +13 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +33 -1
- package/dist/types.js.map +1 -1
- package/docs/ARCHITECTURE.md +22 -9
- package/docs/BUILTINS.md +111 -13
- package/docs/COMPARISON.md +7 -9
- package/docs/{DISTRIBUTED_SYSTEMS.md → CONCURRENCY.md} +11 -11
- package/docs/IMAGE_GENERATION.md +13 -14
- package/docs/IMPLEMENTATION_SUMMARY.md +141 -84
- package/docs/QUICKSTART.md +81 -28
- package/docs/README.md +140 -34
- package/docs/{SYSTEMS_REASONING.md → REASONING.md} +100 -110
- package/docs/ROADMAP.md +42 -43
- package/docs/SKILLS.md +56 -28
- package/docs/SPECIFICATION.md +25 -18
- package/docs/sesi_ai_chronicles.md +96 -209
- package/examples/07_prompts.sesi +1 -1
- package/examples/08_model_call.sesi +1 -1
- package/examples/09_structured_output.sesi +1 -1
- package/examples/10_code_generation.sesi +1 -1
- package/examples/13_data_pipeline.sesi +1 -1
- package/examples/14_folder_explainer.sesi +2 -2
- package/examples/15_image_generation.sesi +1 -1
- package/examples/16_modules.sesi +27 -27
- package/examples/20_model_aliases.sesi +22 -0
- package/examples/21_custom_tools.sesi +27 -0
- package/examples/22_reasoning_plus_custom_tools.sesi +19 -0
- package/main/orchestrator.sesi +2 -2
- package/main/sesi_db_chatbot.sesi +6 -2
- package/main/tests/test_grounding.sesi +2 -0
- package/package.json +2 -2
package/docs/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<img src="favicon.ico" alt="Sesi Logo" height="100" />
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
<h1 align="center">Sesi: A
|
|
5
|
+
<h1 align="center">Sesi: A Concise, Legible Programming Language</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<em>Pronounced "say-see" — What you say, you'll see.</em>
|
|
@@ -15,7 +15,13 @@
|
|
|
15
15
|
<img alt="Framework" src="https://img.shields.io/badge/Node.js-Engine-success?logo=node.js">
|
|
16
16
|
</p>
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
<p align="center">
|
|
19
|
+
<strong>Sesi</strong> is a clean, minimal, and highly legible programming language. Built from the ground up to be concise and buildable, Sesi removes unnecessary boilerplate. Because the language itself is so simple, integrating external tools like shell commands or Reasoning models becomes effortless. It is a language built for clarity.
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
<p align="center">
|
|
23
|
+
<a href="https://code-with-sesi.netlify.app/">Homepage</a>
|
|
24
|
+
</p>
|
|
19
25
|
|
|
20
26
|
## Quick Start
|
|
21
27
|
|
|
@@ -32,6 +38,26 @@ sesi examples/08_model_call.sesi
|
|
|
32
38
|
sesi examples.sesi
|
|
33
39
|
```
|
|
34
40
|
|
|
41
|
+
Useful CLI shortcuts:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Evaluate a quick snippet
|
|
45
|
+
sesi -e "print 'hello'"
|
|
46
|
+
|
|
47
|
+
# Ask the built-in co-pilot a question
|
|
48
|
+
sesi -help "how do I use memory?"
|
|
49
|
+
|
|
50
|
+
# Ask for help about a specific file
|
|
51
|
+
sesi main/playground.sesi -h "why is this failing"
|
|
52
|
+
|
|
53
|
+
# Encrypt or decrypt a script file
|
|
54
|
+
sesi -encrypt my_script.sesi -p "my-password"
|
|
55
|
+
sesi -decrypt my_script.sesi -p "my-password"
|
|
56
|
+
|
|
57
|
+
# Run with sandbox restrictions disabled
|
|
58
|
+
sesi main/start.sesi --local
|
|
59
|
+
```
|
|
60
|
+
|
|
35
61
|
# Local Execution (Development)
|
|
36
62
|
|
|
37
63
|
If you choose not use the `sesi` command, use the helper npm scripts:
|
|
@@ -67,6 +93,40 @@ let code = model("gemini-3.1-pro-preview") {generateCode}
|
|
|
67
93
|
print code
|
|
68
94
|
```
|
|
69
95
|
|
|
96
|
+
## Security & Sandboxing
|
|
97
|
+
|
|
98
|
+
Sesi is designed to run and orchestrate untrusted AI reasoning pipelines. Because code can be influenced by prompt injections or generated model instructions, Sesi incorporates a **safe-by-default, zero-trust sandboxing engine**.
|
|
99
|
+
|
|
100
|
+
### 🛡️ Core Security Features
|
|
101
|
+
|
|
102
|
+
1. **Safe-by-Default Execution**:
|
|
103
|
+
- Sesi's sandbox is **enabled by default**. Any standard Sesi interpreter execution blocks system command lines (`exec`, `spawn`) and locks down imports and paths.
|
|
104
|
+
- *Overriding Safety:* Developers can explicitly bypass safe mode programmatically by initializing the interpreter with options, or on the command line by setting `SESI_SAFE_MODE=false`.
|
|
105
|
+
|
|
106
|
+
2. **Absolute Prototype Pollution Immunity**:
|
|
107
|
+
- Sesi uses **prototype-free objects (`Object.create(null)`)** for all object literals, JSON parses (`from_json` or `std/json`), and structured model responses inside the interpreter.
|
|
108
|
+
- Because these objects do not inherit from standard JavaScript prototypes and possess no `__proto__` or prototype chain, **prototype pollution is physically and architecturally impossible**.
|
|
109
|
+
|
|
110
|
+
3. **Strict Path Whitelisting**:
|
|
111
|
+
- Sesi validates all filesystem and subprocess paths against a **strict directory whitelist** (by default, only the Current Working Directory and the Script's base directory are allowed).
|
|
112
|
+
- Any path traversal resolving outside the whitelist is instantly rejected with a `Security Violation` exception.
|
|
113
|
+
|
|
114
|
+
4. **Automated LLM Tool Call Sanitization**:
|
|
115
|
+
- Even if safe mode is explicitly turned off for developer automation, Sesi **strictly blocks automated tool execution** of sensitive commands (like `exec` and `spawn`) when requested dynamically by the model via `tool_call`. This completely isolates the host from prompt-injection RCE.
|
|
116
|
+
|
|
117
|
+
5. **Deep isolation & Map Cloning**:
|
|
118
|
+
- Sub-interpreters loaded via concurrent workflows (`multi_req`) are fully isolated. Sesi **deep-clones** prompts and memories, preventing concurrent agent tasks from leaking state or polluting each other.
|
|
119
|
+
|
|
120
|
+
### ⚙️ Programmatic Embedding Configurations
|
|
121
|
+
When embedding Sesi inside a host application, you can statically configure safety settings directly in code:
|
|
122
|
+
```typescript
|
|
123
|
+
const interpreter = new Interpreter(scriptDir, {
|
|
124
|
+
safeMode: true, // Enable full sandbox limits (on by default)
|
|
125
|
+
allowLocalFs: false, // Block directory escapes (on by default)
|
|
126
|
+
allowedPaths: ['/var/tmp/sandbox'] // Custom strict whitelist directories
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
70
130
|
## Documentation
|
|
71
131
|
|
|
72
132
|
- [Getting Started](https://github.com/Misterscan/Sesi/blob/main/QUICKSTART.md)
|
|
@@ -74,11 +134,11 @@ print code
|
|
|
74
134
|
- [Language Specification](https://github.com/Misterscan/Sesi/blob/main/docs/SPECIFICATION.md)
|
|
75
135
|
- [Language Comparison Showcase](https://github.com/Misterscan/Sesi/blob/main/docs/COMPARISON.md)
|
|
76
136
|
- [Built-in Functions](https://github.com/Misterscan/Sesi/blob/main/docs/BUILTINS.md)
|
|
77
|
-
- [Reasoning Guide](https://github.com/Misterscan/Sesi/blob/main/docs/
|
|
78
|
-
- [
|
|
137
|
+
- [Reasoning Guide](https://github.com/Misterscan/Sesi/blob/main/docs/REASONING.md)
|
|
138
|
+
- [Concurrency Systems](https://github.com/Misterscan/Sesi/blob/main/docs/CONCURRENCY.md)
|
|
79
139
|
- [Runtime Architecture](https://github.com/Misterscan/Sesi/blob/main/docs/ARCHITECTURE.md)
|
|
80
140
|
|
|
81
|
-
##
|
|
141
|
+
## Agent Context
|
|
82
142
|
|
|
83
143
|
The root-level `SKILLS.md` file is a workspace context file for AI agents. It records repo-specific constraints such as valid Sesi syntax expectations, execution conventions, and the intended meaning of directories like `main/` and `main/tests/`.
|
|
84
144
|
|
|
@@ -86,37 +146,83 @@ The root-level `SKILLS.md` file is a workspace context file for AI agents. It re
|
|
|
86
146
|
|
|
87
147
|
```
|
|
88
148
|
Sesi/
|
|
89
|
-
├── SKILLS.md
|
|
90
|
-
├── index.html
|
|
91
|
-
├── eslint.config.mjs
|
|
92
|
-
├──
|
|
93
|
-
├── example.js
|
|
94
|
-
├──
|
|
95
|
-
├──
|
|
96
|
-
├──
|
|
97
|
-
├──
|
|
98
|
-
├──
|
|
99
|
-
├──
|
|
100
|
-
│
|
|
101
|
-
|
|
102
|
-
│ ├──
|
|
103
|
-
│ ├──
|
|
104
|
-
│ ├──
|
|
105
|
-
│ ├──
|
|
106
|
-
│
|
|
149
|
+
├── SKILLS.md # Workspace context and repo guardrails
|
|
150
|
+
├── index.html # Sesi-generated systems landing page
|
|
151
|
+
├── eslint.config.mjs # ESLint configuration
|
|
152
|
+
├── example.js # Helper script to run basic examples
|
|
153
|
+
├── example-ai.js # Helper script to run reasoning examples
|
|
154
|
+
├── examples.sesi # Central execution suite for examples
|
|
155
|
+
├── README.md # Project overview
|
|
156
|
+
├── QUICKSTART.md # Getting started guide
|
|
157
|
+
├── package.json # Dependencies & scripts
|
|
158
|
+
├── tsconfig.json # TypeScript configuration
|
|
159
|
+
├── dist/ # Compiled TypeScript output
|
|
160
|
+
│
|
|
161
|
+
├── src/ # Source code
|
|
162
|
+
│ ├── types.ts # Type definitions & AST nodes (400+ lines)
|
|
163
|
+
│ ├── lexer.ts # Tokenization (350+ lines)
|
|
164
|
+
│ ├── parser.ts # Recursive descent parser (700+ lines)
|
|
165
|
+
│ ├── interpreter.ts # Tree-walking interpreter (600+ lines)
|
|
166
|
+
│ ├── builtins.ts # Built-in functions (250+ lines)
|
|
167
|
+
│ ├── ai-runtime.ts # Integrated reasoning integration (120+ lines)
|
|
168
|
+
│ └── index.ts # Entry point (30+ lines)
|
|
169
|
+
│
|
|
107
170
|
├── bin/
|
|
108
|
-
│ └── sesi.js
|
|
109
|
-
|
|
110
|
-
├── main/
|
|
111
|
-
│ ├── playground.sesi
|
|
112
|
-
│ ├── start.sesi
|
|
113
|
-
│
|
|
114
|
-
│
|
|
115
|
-
├──
|
|
116
|
-
|
|
171
|
+
│ └── sesi.js # CLI executable
|
|
172
|
+
│
|
|
173
|
+
├── main/ # Playgrounds & debugging
|
|
174
|
+
│ ├── playground.sesi # Main playground script
|
|
175
|
+
│ ├── start.sesi # Beginner script
|
|
176
|
+
│ └── tests/ # Additional syntax validation scripts
|
|
177
|
+
│
|
|
178
|
+
├── docs/
|
|
179
|
+
│ ├── SPECIFICATION.md # Complete language spec (600+ lines)
|
|
180
|
+
│ ├── ARCHITECTURE.md # Runtime & system design (400+ lines)
|
|
181
|
+
│ ├── BUILTINS.md # Built-in functions reference (450+ lines)
|
|
182
|
+
│ ├── COMPARISON.md # Language comparison showcase
|
|
183
|
+
│ ├── CONCURRENCY.md # Concurrency & coordination guide (>100 lines)
|
|
184
|
+
│ ├── IMAGE_GENERATION.md # Image generation guide (>100 lines)
|
|
185
|
+
│ ├── REASONING.md # Reasoning and simple logic guide (>500 lines)
|
|
186
|
+
│ ├── ROADMAP.md # V2-V4+ development plan (400+ lines)
|
|
187
|
+
│ └── sesi_ai_chronicles.md # AI project history & notes
|
|
188
|
+
│
|
|
189
|
+
├── examples/
|
|
190
|
+
│ ├── 01_hello.sesi # Hello World
|
|
191
|
+
│ ├── 02_variables.sesi # Variables & operations
|
|
192
|
+
│ ├── 03_functions.sesi # Functions with parameters
|
|
193
|
+
│ ├── 04_conditionals.sesi # If/else control flow
|
|
194
|
+
│ ├── 05_loops.sesi # While, for, for-in loops
|
|
195
|
+
│ ├── 06_arrays_objects.sesi # Collections
|
|
196
|
+
│ ├── 07_prompts.sesi # Reasoning blocks
|
|
197
|
+
│ ├── 08_model_call.sesi # Basic reasoning calls
|
|
198
|
+
│ ├── 09_structured_output.sesi # Type-safe reasoning responses
|
|
199
|
+
│ ├── 10_code_generation.sesi # Systems logic generation
|
|
200
|
+
│ ├── 11_memory_conversation.sesi # Multi-turn stateful reasoning
|
|
201
|
+
│ ├── 12_classification.sesi # Systems classification loop
|
|
202
|
+
│ ├── 13_data_pipeline.sesi # Complete systems pipeline
|
|
203
|
+
│ ├── 14_folder_explainer.sesi # Directory parsing & reasoning
|
|
204
|
+
│ ├── 15_image_generation.sesi # Image generation API test
|
|
205
|
+
│ ├── 16_modules.sesi # Modules & std library namespaces
|
|
206
|
+
│ ├── 17_http_client.sesi # Network GET/POST client
|
|
207
|
+
│ ├── 18_parallel_requests.sesi # Parallel requests concurrency
|
|
208
|
+
│ ├── 19_search_web.sesi # Web search integration
|
|
209
|
+
│ ├── 20_model_aliases.sesi # Custom model naming aliases
|
|
210
|
+
│ ├── 21_custom_tools.sesi # Custom runtime tool definitions
|
|
211
|
+
│ └── 22_reasoning_plus_custom_tools.sesi # Reasoning composed with custom tools
|
|
212
|
+
│
|
|
213
|
+
└── tests/ # Engine test suite
|
|
214
|
+
├── basic.test.ts # Core parsing & evaluation tests
|
|
215
|
+
├── cache.test.ts # Execution caching tests
|
|
216
|
+
├── http.test.ts # Web request builtins testing
|
|
217
|
+
├── module.test.ts # Imports & module loading tests
|
|
218
|
+
├── parallel.test.ts # Concurrent execution tests
|
|
219
|
+
├── security.test.ts # Sandbox & guardrail tests
|
|
220
|
+
├── test-gemini.ts # Base model integration test
|
|
221
|
+
├── test-gemini2.ts # Extended model integration test
|
|
222
|
+
└── workflow.test.ts # Complex sequence workflows tests
|
|
117
223
|
```
|
|
118
224
|
|
|
119
|
-
## Version 1.
|
|
225
|
+
## Version 1.3 Features (In Progress)
|
|
120
226
|
|
|
121
227
|
### Core Language ✅
|
|
122
228
|
|
|
@@ -170,4 +276,4 @@ Sesi/
|
|
|
170
276
|
|
|
171
277
|
## License
|
|
172
278
|
|
|
173
|
-
MIT
|
|
279
|
+
MIT
|
|
@@ -1,69 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Reasoning & Simple Logic
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
In Sesi, Reasoning is used to evaluate state, make logical decisions, and handle complex patterns. This guide covers how to leverage Sesi's built-in Reasoning functions (`model`, `image` `prompt`, `structured_output`, `tool_call`) to build scripts for your designated needs.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## 1. Prompting
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
The core of Sesi's power lies in its ability to manage distributed execution. Using the `spawn()` builtin, you can launch multiple concurrent Sesi processes that coordinate via shared state or the filesystem.
|
|
12
|
-
|
|
13
|
-
A master script can launch concurrent processes and poll for their completion.
|
|
14
|
-
|
|
15
|
-
```sesi
|
|
16
|
-
spawn("atm_deposit.sesi")
|
|
17
|
-
spawn("atm_withdraw.sesi")
|
|
18
|
-
let finished = false
|
|
19
|
-
while !finished {
|
|
20
|
-
try {
|
|
21
|
-
if read_file("bank/done_count.txt") == "2" {
|
|
22
|
-
finished = true
|
|
23
|
-
}
|
|
24
|
-
} catch (e) {
|
|
25
|
-
// Wait on I/O contention
|
|
26
|
-
let i = 0 while i < 1000 { i = i + 1 }
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
print "Swarm task completed."
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Coordination & Distributed Locking
|
|
33
|
-
|
|
34
|
-
When multiple processes access shared resources, use Sesi's `try/catch`, `time()`, and `random()` builtins to implement mutual exclusion (locking) via the **Double-Check Write** pattern.
|
|
35
|
-
|
|
36
|
-
```sesi
|
|
37
|
-
let id = "With_" + str(time()) + "_" + str(random())
|
|
38
|
-
let locked = true
|
|
39
|
-
while locked {
|
|
40
|
-
let status = "error"
|
|
41
|
-
try {
|
|
42
|
-
status = read_file("bank/lock.txt")
|
|
43
|
-
} catch (e) {
|
|
44
|
-
status = "error"
|
|
45
|
-
}
|
|
46
|
-
if status == "unlocked" {
|
|
47
|
-
try {
|
|
48
|
-
write_file("bank/lock.txt", id)
|
|
49
|
-
let i = 0 while i < 500 { i = i + 1 }
|
|
50
|
-
if read_file("bank/lock.txt") == id {
|
|
51
|
-
locked = false
|
|
52
|
-
}
|
|
53
|
-
} catch (e) {
|
|
54
|
-
status = "error"
|
|
55
|
-
}
|
|
56
|
-
} else {
|
|
57
|
-
let j = 0 while j < 1000 { j = j + 1 }
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
## 2. AI as a Reasoning Primitive
|
|
65
|
-
|
|
66
|
-
In an orchestrated system, AI is used to make decisions that would be too complex for static logic.
|
|
9
|
+
In Sesi, calling a reasoning model is as simple as defining a string and executing it.
|
|
67
10
|
|
|
68
11
|
Prompts are **composable message templates** that evaluate to strings.
|
|
69
12
|
|
|
@@ -102,7 +45,7 @@ print translatePrompt(text, language)
|
|
|
102
45
|
|
|
103
46
|
## 2. Model Calls
|
|
104
47
|
|
|
105
|
-
Call
|
|
48
|
+
Call a Reasoning model with a prompt and get back text.
|
|
106
49
|
|
|
107
50
|
### Basic Model Call
|
|
108
51
|
|
|
@@ -127,8 +70,8 @@ print creative
|
|
|
127
70
|
|
|
128
71
|
```sesi
|
|
129
72
|
// Fast model for simple tasks
|
|
130
|
-
let text = "
|
|
131
|
-
let quick = model("gemini-3.1-flash-lite") {"Summarize this in one sentence:" text}
|
|
73
|
+
let text = "Coding with Reasoning programming language is fun!"
|
|
74
|
+
let quick = model("gemini-3.1-flash-lite") {"Summarize this in one sentence: " text}
|
|
132
75
|
|
|
133
76
|
// Powerful model for complex reasoning
|
|
134
77
|
let code = "def calculate_sum(n):
|
|
@@ -136,25 +79,25 @@ let code = "def calculate_sum(n):
|
|
|
136
79
|
for i in range(1, n):
|
|
137
80
|
total += i
|
|
138
81
|
return total"
|
|
139
|
-
let smart = model("gemini-3.1-pro-preview") {"Analyze this code for bugs:" code}
|
|
82
|
+
let smart = model("gemini-3.1-pro-preview") {"Analyze this code for bugs: " code}
|
|
140
83
|
|
|
141
84
|
// Efficient model for many calls
|
|
142
|
-
let item = "
|
|
143
|
-
let cheap = model("gemini-3.5-flash") {thinkingLevel: "minimal"} {"Classify:" item}
|
|
85
|
+
let item = "Programming Languages"
|
|
86
|
+
let cheap = model("gemini-3.5-flash") {thinkingLevel: "minimal"} {"Classify: " item}
|
|
144
87
|
|
|
145
88
|
print quick
|
|
146
89
|
print smart
|
|
147
90
|
print cheap
|
|
148
91
|
```
|
|
149
92
|
|
|
150
|
-
### Available Models (v1.
|
|
93
|
+
### Available Models (v1.3)
|
|
151
94
|
|
|
152
95
|
- `gemini-2.5-flash` - Legacy, but supported. 1M tokens.
|
|
153
96
|
- `gemini-2.5-pro` - Legacy, but supported. 1M tokens.
|
|
154
97
|
- `gemini-2.5-flash-image` - Standard image model. (No `512` image size support for this model. Only `1K` is supported.)
|
|
155
|
-
- `gemini-3-flash-preview` - Fast, balanced
|
|
98
|
+
- `gemini-3-flash-preview` - Fast, most balanced model for coding and minimal tasks.
|
|
156
99
|
- `gemini-3.1-flash-lite` - Fastest, most cost-efficient.
|
|
157
|
-
- `gemini-3.5-flash` -
|
|
100
|
+
- `gemini-3.5-flash` - Newest GA model. Balanced, but token hungry (USE WISELY) supports all native thinking effort levels (`minimal`, `low`, `medium`, `high`).
|
|
158
101
|
- `gemini-3.1-pro-preview` - Most powerful reasoning model, doesn't support `minimal` thinking (falls back to `low`).
|
|
159
102
|
- `gemini-3.1-flash-image-preview` - Cost efficient image generation model.
|
|
160
103
|
- `gemini-3-pro-image-preview` - High quality image generation model. (No `512` image size support for this model.)
|
|
@@ -196,8 +139,7 @@ Get typed responses from Reasoning with field validation.
|
|
|
196
139
|
### Basic Structured Output
|
|
197
140
|
|
|
198
141
|
```sesi
|
|
199
|
-
let analysis = structured_output({sentiment: string, confidence: number, summary: string})
|
|
200
|
-
(model("gemini-3-flash-preview") {"Analyze sentiment of: " text "Return JSON with sentiment, confidence (0-1), and summary"})
|
|
142
|
+
let analysis = structured_output({sentiment: string, confidence: number, summary: string})(model("gemini-3-flash-preview") {"Analyze sentiment of: " text "Return JSON with sentiment, confidence (0-1), and summary"})
|
|
201
143
|
print analysis["sentiment"] // "positive"
|
|
202
144
|
print analysis["confidence"] // 0.85
|
|
203
145
|
print analysis["summary"] // "..."
|
|
@@ -216,12 +158,12 @@ print bookInfo["title"]
|
|
|
216
158
|
|
|
217
159
|
- Always include instructions for JSON format
|
|
218
160
|
- Specify the exact schema in the prompt
|
|
219
|
-
- Use "thinkingLevel": "
|
|
161
|
+
- Use "thinkingLevel": "minimal" for fast, consistent parsing
|
|
220
162
|
- Validate output structure in code
|
|
221
163
|
|
|
222
164
|
```sesi
|
|
223
165
|
let listText = "eggs, milk, bread, cheese, fruit, vegetables"
|
|
224
|
-
let output = structured_output({items: string})(model("gemini-3.5-flash") {thinkingLevel: "minimal"}{"Return JSON with items array containing: " listText})
|
|
166
|
+
let output = structured_output({items: string})(model("gemini-3.5-flash") {thinkingLevel: "minimal"} {"Return JSON with items array containing: " listText})
|
|
225
167
|
|
|
226
168
|
// Validate
|
|
227
169
|
if type(output["items"]) == "array" {print "Got" str(len(output["items"])) "items"} // Got 6 items
|
|
@@ -236,7 +178,8 @@ Let Reasoning call functions in your program.
|
|
|
236
178
|
```sesi
|
|
237
179
|
let city = "New York"
|
|
238
180
|
fn getWeather(city: string) -> string
|
|
239
|
-
{let weather = model("gemini-3.1-flash-lite"){"What is the weather like in " city}
|
|
181
|
+
{let weather = model("gemini-3.1-flash-lite") {"What is the weather like in " city}
|
|
182
|
+
return weather}
|
|
240
183
|
let result = getWeather(city)
|
|
241
184
|
print result
|
|
242
185
|
|
|
@@ -289,11 +232,11 @@ print response2 // Has context from turn 1
|
|
|
289
232
|
```sesi
|
|
290
233
|
memory conversation {"Chat history: "}
|
|
291
234
|
fn chat(userMessage: string) -> string
|
|
292
|
-
{let fullPrompt = conversation + "User:" + userMessage
|
|
235
|
+
{let fullPrompt = conversation + "User: " + userMessage
|
|
293
236
|
let response = model("gemini-3-flash-preview") {fullPrompt}
|
|
294
237
|
|
|
295
238
|
// Append to memory
|
|
296
|
-
conversation = conversation + "User:" + userMessage + "Assistant:" + response
|
|
239
|
+
conversation = conversation + "User: " + userMessage + "Assistant: " + response
|
|
297
240
|
return response}
|
|
298
241
|
let msg = "What is the capital of France? "
|
|
299
242
|
print "User:" msg
|
|
@@ -313,7 +256,7 @@ print "Updated Memory!"
|
|
|
313
256
|
memory conversation {"User: Hello! Assistant: Hi there! User: How are you? Assistant: I'm great!"}
|
|
314
257
|
fn summarizeMemory()
|
|
315
258
|
{let oldConversation = conversation
|
|
316
|
-
let summary = model("gemini-3.1-flash-lite") {"Summarize this conversation concisely:" oldConversation}
|
|
259
|
+
let summary = model("gemini-3.1-flash-lite") {"Summarize this conversation concisely: " oldConversation}
|
|
317
260
|
conversation = "Previous summary:" + summary + "Recent messages: " + oldConversation}
|
|
318
261
|
print "Original Memory:" conversation
|
|
319
262
|
summarizeMemory()
|
|
@@ -329,8 +272,7 @@ print conversation
|
|
|
329
272
|
let categories = "fruit, vegetable, grain"
|
|
330
273
|
let item = "banana"
|
|
331
274
|
fn classify(item: string, categories: string) -> string
|
|
332
|
-
{return model("gemini-3.5-flash") {thinkingLevel: "minimal"}
|
|
333
|
-
{"Classify this item into one category. Categories: " categories " Item: " item " Return only the category name."}}
|
|
275
|
+
{return model("gemini-3.5-flash") {thinkingLevel: "minimal"} {"Classify this item into one category. Categories: " categories " Item: " item " Return only the category name."}}
|
|
334
276
|
print "Item: " item //banana
|
|
335
277
|
print "Category: " classify(item, categories) //fruit
|
|
336
278
|
```
|
|
@@ -340,8 +282,7 @@ print "Category: " classify(item, categories) //fruit
|
|
|
340
282
|
```sesi
|
|
341
283
|
let text = "Elon Musk is the CEO of Tesla and SpaceX."
|
|
342
284
|
fn extractEntities(text: string) -> object
|
|
343
|
-
{let result = structured_output({people: string, places: string, organizations: string})
|
|
344
|
-
(model("gemini-3.5-flash") {thinkingLevel: "minimal"}{"Extract named entities from:" text})
|
|
285
|
+
{let result = structured_output({people: string, places: string, organizations: string})(model("gemini-3.5-flash") {thinkingLevel: "minimal"} {"Extract named entities from: " text})
|
|
345
286
|
print "Name(s) found: result"
|
|
346
287
|
return result}
|
|
347
288
|
print extractEntities(text)
|
|
@@ -354,9 +295,8 @@ print extractEntities(text)
|
|
|
354
295
|
let text = "Hello, world!"
|
|
355
296
|
let language = "Spanish"
|
|
356
297
|
fn translate(text: string, language: string) -> string
|
|
357
|
-
{return model("gemini-3-flash-preview") {"Translate to" language ":" text}}
|
|
358
|
-
print "Translation:"
|
|
359
|
-
print translate(text, language)
|
|
298
|
+
{return model("gemini-3-flash-preview") {"Translate to " language ": " text}}
|
|
299
|
+
print "Translation:" translate(text, language)
|
|
360
300
|
```
|
|
361
301
|
|
|
362
302
|
### Web Search Grounding
|
|
@@ -364,7 +304,8 @@ print translate(text, language)
|
|
|
364
304
|
Access real-time information by enabling the `search` shorthand configuration natively.
|
|
365
305
|
|
|
366
306
|
```sesi
|
|
367
|
-
let response = model("gemini-3.1-flash-lite") {search, max_tokens:
|
|
307
|
+
let response = model("gemini-3.1-flash-lite") {search, max_tokens: 200} {"What is the weather in Tokyo right now?"}
|
|
308
|
+
print response
|
|
368
309
|
```
|
|
369
310
|
|
|
370
311
|
### Image Generation
|
|
@@ -384,7 +325,7 @@ print "Image generated!"
|
|
|
384
325
|
```sesi
|
|
385
326
|
let requirement = "Write a function that reverses a string."
|
|
386
327
|
fn generateCode(requirement: string) -> string
|
|
387
|
-
{return model("gemini-3.5-flash") {thinkingLevel: "low"} {"Generate JavaScript code for:" requirement "Only provide code, no explanation."}}
|
|
328
|
+
{return model("gemini-3.5-flash") {thinkingLevel: "low"} {"Generate JavaScript code for: " requirement " Only provide code, no explanation."}}
|
|
388
329
|
print "Code generation:"
|
|
389
330
|
print generateCode(requirement)
|
|
390
331
|
```
|
|
@@ -394,8 +335,7 @@ print generateCode(requirement)
|
|
|
394
335
|
```sesi
|
|
395
336
|
let text = "I love Sesi!"
|
|
396
337
|
fn analyzeSentiment(text: string) -> object
|
|
397
|
-
{return structured_output({sentiment: string, score: number, explanation: string})
|
|
398
|
-
(model("gemini-3-flash-preview") {"Analyze sentiment of:" text})}
|
|
338
|
+
{return structured_output({sentiment: string, score: number, explanation: string})(model("gemini-3-flash-preview") {"Analyze sentiment of: " text})}
|
|
399
339
|
print "Sentiment analysis:"
|
|
400
340
|
print analyzeSentiment(text)
|
|
401
341
|
```
|
|
@@ -404,11 +344,11 @@ print analyzeSentiment(text)
|
|
|
404
344
|
|
|
405
345
|
Reasoning operations can fail. Handle gracefully.
|
|
406
346
|
|
|
407
|
-
### Try/Catch (v1.
|
|
347
|
+
### Try/Catch (v1.3)
|
|
408
348
|
|
|
409
349
|
```sesi
|
|
410
350
|
try
|
|
411
|
-
{let response = model("gemini-3-flash-preview") {"Analyze" text}
|
|
351
|
+
{let response = model("gemini-3-flash-preview") {"Analyze " text}
|
|
412
352
|
print response}
|
|
413
353
|
catch (e) {print "Reasoning call failed"
|
|
414
354
|
print e}
|
|
@@ -426,14 +366,13 @@ print e}
|
|
|
426
366
|
let text = "Coding is evolving rapidly!"
|
|
427
367
|
fn safeAnalyze(text: string) {
|
|
428
368
|
try
|
|
429
|
-
{let result = structured_output({sentiment: string, score: number})(model("gemini-3.1-flash-lite") {"Analyze sentiment and return JSON for:" text})
|
|
369
|
+
{let result = structured_output({sentiment: string, score: number})(model("gemini-3.1-flash-lite") {"Analyze sentiment, score, and return JSON for: " text})
|
|
430
370
|
if len(keys(result)) == 0 {print "Structured parsing failed"
|
|
431
371
|
return null}
|
|
432
|
-
return result
|
|
433
|
-
catch (e)
|
|
434
|
-
{print e
|
|
372
|
+
return result
|
|
373
|
+
} catch (e) {print e
|
|
435
374
|
return null}}
|
|
436
|
-
print "Analysis Result:
|
|
375
|
+
print "Analysis Result:" safeAnalyze(text)
|
|
437
376
|
```
|
|
438
377
|
|
|
439
378
|
## 8. Performance Tips
|
|
@@ -443,11 +382,11 @@ print "Analysis Result: " safeAnalyze(text)
|
|
|
443
382
|
```sesi
|
|
444
383
|
// Bad: Calls API 3 times
|
|
445
384
|
for item in items
|
|
446
|
-
{let analysis = model("gemini-3.1-flash-lite") {"Analyze:" item}}
|
|
385
|
+
{let analysis = model("gemini-3.1-flash-lite") {"Analyze: " item}}
|
|
447
386
|
print analysis
|
|
448
387
|
|
|
449
388
|
// Better: Batch into one call (v2: parallel calls)
|
|
450
|
-
let analyses = model("gemini-3.1-flash-lite") {"Analyze each:" join(items, " ")}
|
|
389
|
+
let analyses = model("gemini-3.1-flash-lite") {"Analyze each: " join(items, " ")}
|
|
451
390
|
print analyses
|
|
452
391
|
```
|
|
453
392
|
|
|
@@ -455,11 +394,11 @@ print analyses
|
|
|
455
394
|
|
|
456
395
|
```sesi
|
|
457
396
|
// Simple classification → flash-lite
|
|
458
|
-
let category = model("gemini-3.1-flash-lite") {"Classify:" item}
|
|
397
|
+
let category = model("gemini-3.1-flash-lite") {"Classify: " item}
|
|
459
398
|
print category
|
|
460
399
|
|
|
461
400
|
// Complex reasoning → pro
|
|
462
|
-
let analysis = model("gemini-3.1-pro-preview") {"Deep analysis of:" complex_problem}
|
|
401
|
+
let analysis = model("gemini-3.1-pro-preview") {"Deep analysis of: " complex_problem}
|
|
463
402
|
print analysis
|
|
464
403
|
```
|
|
465
404
|
|
|
@@ -468,7 +407,7 @@ print analysis
|
|
|
468
407
|
```sesi
|
|
469
408
|
// Long prompts waste tokens
|
|
470
409
|
// Bad:
|
|
471
|
-
let response = model("gemini-3-flash-preview") {"Here is a very long system prompt that repeats itself...
|
|
410
|
+
let response = model("gemini-3-flash-preview") {"Here is a very long system prompt that repeats itself... Please analyze the following text very carefully..." text}
|
|
472
411
|
print response
|
|
473
412
|
|
|
474
413
|
// Better:
|
|
@@ -480,14 +419,17 @@ print response
|
|
|
480
419
|
|
|
481
420
|
```sesi
|
|
482
421
|
// Bad: Same analysis done multiple times
|
|
483
|
-
for person in people
|
|
422
|
+
for person in people
|
|
423
|
+
{let assessment = model("gemini-3.1-flash-lite") {"Assess based on criteria A, B, C: " person}}
|
|
484
424
|
print assessment
|
|
485
425
|
|
|
486
426
|
|
|
487
427
|
// Better: Reuse cached prompt
|
|
488
428
|
let people = ["Elon Musk", "Bill Gates", "Steve Jobs"]
|
|
489
|
-
fn assessPerson(person: string) -> string
|
|
490
|
-
|
|
429
|
+
fn assessPerson(person: string) -> string
|
|
430
|
+
{return model("gemini-3.1-flash-lite") {"Assess on A, B, C: " person}}
|
|
431
|
+
for person in people
|
|
432
|
+
{print assessPerson(person)}
|
|
491
433
|
```
|
|
492
434
|
|
|
493
435
|
## 9. Token Counting (Future)
|
|
@@ -502,7 +444,7 @@ print "This costs " str(tokens * PRICE_PER_TOKEN) " cents"
|
|
|
502
444
|
// Plan memory size
|
|
503
445
|
let remaining = MAX_TOKENS - count_tokens(memory, model)
|
|
504
446
|
if remaining < 500 {summarizeMemory()}
|
|
505
|
-
print "Memory size:
|
|
447
|
+
print "Memory size:" count_tokens(memory, model)
|
|
506
448
|
```
|
|
507
449
|
|
|
508
450
|
## 10. Advanced: Custom Reasoning Workflows
|
|
@@ -515,20 +457,21 @@ fn smartSummarize(text: string) -> string
|
|
|
515
457
|
|
|
516
458
|
// Chain multiple Reasoning operations
|
|
517
459
|
// Step 1: Extract key points
|
|
518
|
-
{let keyPoints = model("gemini-3.1-pro-preview") {thinkingLevel: "low"} {"Extract 5 key points from:" text}
|
|
460
|
+
{let keyPoints = model("gemini-3.1-pro-preview") {thinkingLevel: "low"} {"Extract 5 key points from: " text}
|
|
519
461
|
|
|
520
462
|
// Step 2: Analyze topics
|
|
521
|
-
let topics = structured_output({
|
|
463
|
+
let topics = structured_output({topics: string})(model("gemini-3.5-flash") {thinkingLevel: "low"} {"Identify topics in: " keyPoints})
|
|
522
464
|
|
|
523
465
|
// Step 3: Generate summary
|
|
524
|
-
let summary = model("gemini-3-flash-preview") {"Summarize with topics " topics ":" keyPoints}
|
|
466
|
+
let summary = model("gemini-3-flash-preview") {"Summarize with topics " topics ": " keyPoints}
|
|
467
|
+
return summary}
|
|
525
468
|
print "Summary:" smartSummarize(text)
|
|
526
469
|
```
|
|
527
470
|
|
|
528
471
|
### Reasoning Pattern
|
|
529
472
|
|
|
530
473
|
```sesi
|
|
531
|
-
let analysis = model("gemini-3.5-flash") {thinkingLevel: "medium", max_tokens: 8192} {"Reason carefully about:" problem}
|
|
474
|
+
let analysis = model("gemini-3.5-flash") {thinkingLevel: "medium", max_tokens: 8192} {"Reason carefully about: " problem}
|
|
532
475
|
print analysis
|
|
533
476
|
```
|
|
534
477
|
|
|
@@ -537,12 +480,59 @@ print analysis
|
|
|
537
480
|
```sesi
|
|
538
481
|
let text = "banana"
|
|
539
482
|
fn classifyWithExamples(text: string) -> string
|
|
540
|
-
{return model("gemini-3.5-flash") {thinkingLevel: "minimal"} {"Classify as A, B, or C
|
|
483
|
+
{return model("gemini-3.5-flash") {thinkingLevel: "minimal"} {"Classify as A, B, or C. Examples: 'apple' -> A , 'dog' -> B , 'happy' -> C. Classify: " text}}
|
|
541
484
|
print "Classification:" classifyWithExamples(text)
|
|
542
485
|
```
|
|
543
486
|
|
|
544
487
|
---
|
|
545
488
|
|
|
489
|
+
## 11. Built-in Tools
|
|
490
|
+
|
|
491
|
+
### Built-in Workflows
|
|
492
|
+
|
|
493
|
+
Sesi provides a native `workflow` function to easily chain reasoning steps:
|
|
494
|
+
|
|
495
|
+
```sesi
|
|
496
|
+
let steps = [
|
|
497
|
+
{"prompt": "Summarize:"},
|
|
498
|
+
{"prompt": "Critique:"},
|
|
499
|
+
{"prompt": "Finalize:"}
|
|
500
|
+
]
|
|
501
|
+
let result = workflow(steps, "Design a landing page brief")
|
|
502
|
+
print result["final"]
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
### Model Aliases
|
|
506
|
+
|
|
507
|
+
You can define custom names for models using `set_alias`:
|
|
508
|
+
|
|
509
|
+
```sesi
|
|
510
|
+
set_alias("fast", "gemini-3.1-flash-lite")
|
|
511
|
+
let answer = model("fast") {"Summarize this paragraph."}
|
|
512
|
+
print answer
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### Custom Tools
|
|
516
|
+
|
|
517
|
+
Sesi allows you to define custom tools that can be invoked during reasoning operations.
|
|
518
|
+
|
|
519
|
+
```sesi
|
|
520
|
+
fn get_weather(city: string, conditions: string) -> string
|
|
521
|
+
{return "It is currently " + conditions + " in " + city}
|
|
522
|
+
// Register the tool
|
|
523
|
+
define_tool("weather", get_weather, "Get weather for a city")
|
|
524
|
+
|
|
525
|
+
// List available tools
|
|
526
|
+
print list_tools()
|
|
527
|
+
|
|
528
|
+
// Call the tool
|
|
529
|
+
let weatherData = structured_output({city: string, conditions: string})(model("gemini-3.1-flash-lite") {search} {"What is the weather like in London? Return JSON with the exact 'conditions' and 'city' name."})
|
|
530
|
+
let result = tool_call(weather)(weatherData["city"], weatherData["conditions"])
|
|
531
|
+
print result
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
---
|
|
535
|
+
|
|
546
536
|
## See Also
|
|
547
537
|
|
|
548
538
|
- [Compare to other languages](COMPARISON.md)
|