@rong/agentscript 0.1.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/CHANGELOG.md +22 -0
- package/INSTALL.md +92 -0
- package/LICENSE +21 -0
- package/README.md +246 -0
- package/dist/ast/constants.js +1 -0
- package/dist/ast/format.js +41 -0
- package/dist/ast/types.js +1 -0
- package/dist/bin/agentscript.js +234 -0
- package/dist/bin/input.js +19 -0
- package/dist/bin/repl.js +290 -0
- package/dist/index.js +26 -0
- package/dist/parser/errors.js +8 -0
- package/dist/parser/parser.js +661 -0
- package/dist/parser/tokenizer.js +246 -0
- package/dist/providers/llm/anthropic.js +36 -0
- package/dist/providers/llm/index.js +3 -0
- package/dist/providers/llm/ollama.js +19 -0
- package/dist/providers/llm/openai.js +31 -0
- package/dist/providers/llm/protocol.js +45 -0
- package/dist/providers/llm/shared.js +147 -0
- package/dist/providers/llm/types.js +1 -0
- package/dist/providers/llm/uri.js +24 -0
- package/dist/providers/memory/file.js +44 -0
- package/dist/providers/memory/host.js +66 -0
- package/dist/providers/memory/index.js +1 -0
- package/dist/providers/memory/shared.js +56 -0
- package/dist/providers/memory/sqlite.js +98 -0
- package/dist/providers/mock/index.js +32 -0
- package/dist/providers/tools/env.js +11 -0
- package/dist/providers/tools/file.js +99 -0
- package/dist/providers/tools/host.js +34 -0
- package/dist/providers/tools/http.js +40 -0
- package/dist/providers/tools/index.js +2 -0
- package/dist/providers/tools/scheme.js +16 -0
- package/dist/providers/tools/shared.js +92 -0
- package/dist/providers/tools/shell.js +80 -0
- package/dist/runtime/context.js +160 -0
- package/dist/runtime/errors.js +14 -0
- package/dist/runtime/evaluator.js +276 -0
- package/dist/runtime/generate.js +175 -0
- package/dist/runtime/guards.js +39 -0
- package/dist/runtime/input.js +38 -0
- package/dist/runtime/interpreter.js +314 -0
- package/dist/runtime/json.js +59 -0
- package/dist/runtime/loader.js +146 -0
- package/dist/runtime/scope.js +47 -0
- package/dist/runtime/shape.js +132 -0
- package/dist/runtime/trace.js +54 -0
- package/dist/runtime/truth.js +13 -0
- package/dist/runtime/types.js +1 -0
- package/dist/runtime/uri.js +10 -0
- package/dist/semantic/analyzer.js +519 -0
- package/dist/semantic/diagnostics.js +16 -0
- package/dist/utils/assert.js +3 -0
- package/docs/cn/context-engineering.md +389 -0
- package/docs/cn/language.md +478 -0
- package/docs/design-history/v0-design.md +365 -0
- package/docs/design-history/v0-implement.md +274 -0
- package/docs/design-history/v1-design.md +323 -0
- package/docs/design-history/v1-implement.md +267 -0
- package/docs/design-history/v2-design.md +387 -0
- package/docs/design-history/v2-implement.md +399 -0
- package/docs/en/context-engineering.md +332 -0
- package/docs/en/language.md +478 -0
- package/examples/changelog.as +29 -0
- package/examples/extract.as +29 -0
- package/examples/review.as +38 -0
- package/examples/summarize.as +28 -0
- package/examples/translate.as +33 -0
- package/package.json +59 -0
- package/tutorials/cli.as +22 -0
- package/tutorials/helloworld.as +14 -0
- package/tutorials/memory.as +19 -0
- package/tutorials/plan-execute.as +155 -0
- package/tutorials/react.as +98 -0
- package/tutorials/repl.as +31 -0
- package/tutorials/self-improve.as +60 -0
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
# AgentScript Language
|
|
2
|
+
|
|
3
|
+
This document describes the current AgentScript v1.0.0 language.
|
|
4
|
+
|
|
5
|
+
## Design principles
|
|
6
|
+
|
|
7
|
+
- Agent is the unit of execution and prompt identity.
|
|
8
|
+
- Context is explicit: ordinary variables, tool results, memory records, and trace events do not enter prompts unless selected with `use`.
|
|
9
|
+
- Scope controls variable lifetime, context inheritance, and prompt exposure.
|
|
10
|
+
- LLM, tool, memory, file, and agent imports are runtime capabilities with explicit boundaries.
|
|
11
|
+
- AgentScript keeps pattern names such as planner, executor, verifier, reflect, improve, and evolve as ordinary agent or function names.
|
|
12
|
+
- Trace is for debugging and audit; it is not prompt context.
|
|
13
|
+
|
|
14
|
+
## Program structure
|
|
15
|
+
|
|
16
|
+
A program contains imports and agents. Execution starts from the selected agent and function, or from the program's `main agent` and `main func`.
|
|
17
|
+
|
|
18
|
+
```agentscript
|
|
19
|
+
import llm Qwen from "ollama://localhost:11434/qwen3.6"
|
|
20
|
+
|
|
21
|
+
main agent Assistant {
|
|
22
|
+
model Qwen
|
|
23
|
+
role "Assistant"
|
|
24
|
+
description "Answer with structured JSON."
|
|
25
|
+
|
|
26
|
+
main func(input {
|
|
27
|
+
question string
|
|
28
|
+
}) {
|
|
29
|
+
use input.question
|
|
30
|
+
return generate({ input: "Answer the question" }) {
|
|
31
|
+
return {
|
|
32
|
+
ok boolean
|
|
33
|
+
answer string
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Imports
|
|
41
|
+
|
|
42
|
+
AgentScript supports five resource kinds:
|
|
43
|
+
|
|
44
|
+
```agentscript
|
|
45
|
+
import llm Qwen from "ollama://localhost:11434/qwen3.6"
|
|
46
|
+
import tool Find from "sh://find"
|
|
47
|
+
import memory Lessons from "file://./.agentscript/lessons.jsonl"
|
|
48
|
+
import file Requirements from "./requirements.md"
|
|
49
|
+
import agent Worker from "./worker.as"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Resource bindings are explicit capabilities. `llm`, `tool`, `memory`, and `agent` bindings cannot be directly added to prompt context with `use`. File imports are read-only context resources and must still be explicitly used.
|
|
53
|
+
|
|
54
|
+
### LLM URIs
|
|
55
|
+
|
|
56
|
+
```agentscript
|
|
57
|
+
import llm Fast from "openai://gpt-4.1-mini"
|
|
58
|
+
import llm Strong from "anthropic://claude-sonnet-4-0"
|
|
59
|
+
import llm Local from "ollama://localhost:11434/qwen3.6"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Environment variables:
|
|
63
|
+
- `OPENAI_API_KEY` / `OPENAI_BASE_URL`
|
|
64
|
+
- `ANTHROPIC_API_KEY` / `ANTHROPIC_BASE_URL`
|
|
65
|
+
- `OLLAMA_BASE_URL`
|
|
66
|
+
|
|
67
|
+
### Tool URIs
|
|
68
|
+
|
|
69
|
+
Tools use URI schemes for dispatch:
|
|
70
|
+
|
|
71
|
+
| Scheme | Provider | Example |
|
|
72
|
+
|--------|----------|---------|
|
|
73
|
+
| `sh://` | Shell-based tools | `sh://find`, `sh://grep` |
|
|
74
|
+
| `file://` | File operations | `file://workspace` |
|
|
75
|
+
| `env://` | Environment variables | `env://process` |
|
|
76
|
+
| `http://` / `https://` | HTTP requests | `https://api.example.com` |
|
|
77
|
+
| `mcp://` | External MCP tools | `mcp://tools/search` |
|
|
78
|
+
|
|
79
|
+
### Memory URIs
|
|
80
|
+
|
|
81
|
+
```agentscript
|
|
82
|
+
import memory Lessons from "file://./.agentscript/lessons.jsonl"
|
|
83
|
+
import memory Runs from "sqlite://./.agentscript/memory.db#runs"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
File memory uses JSONL format. SQLite memory uses a fixed schema with namespaced records.
|
|
87
|
+
|
|
88
|
+
### File URIs
|
|
89
|
+
|
|
90
|
+
Relative paths are resolved from the importing `.as` file (or from the current working directory in REPL). Path access is constrained to the workspace root.
|
|
91
|
+
|
|
92
|
+
## Agents and functions
|
|
93
|
+
|
|
94
|
+
Agents contain configuration and functions. Functions create runtime scopes. Cross-agent calls create isolated function scopes and nested trace events.
|
|
95
|
+
|
|
96
|
+
```agentscript
|
|
97
|
+
result = Worker(input)
|
|
98
|
+
result = Worker.run(input)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`AgentName(input)` calls the target agent's `main func`. `AgentName.funcName(input)` calls a named function.
|
|
102
|
+
|
|
103
|
+
### Entry rules
|
|
104
|
+
|
|
105
|
+
- A program may have at most one `main agent`.
|
|
106
|
+
- An agent may have at most one `main func`.
|
|
107
|
+
- Multi-agent programs must declare a `main agent`.
|
|
108
|
+
- `main agent { ... }` may omit the agent name.
|
|
109
|
+
- `main func(input) { ... }` may omit the function name.
|
|
110
|
+
|
|
111
|
+
## Configuration
|
|
112
|
+
|
|
113
|
+
`model`, `role`, and `description` are scoped configuration values used by `generate`.
|
|
114
|
+
|
|
115
|
+
```agentscript
|
|
116
|
+
agent A {
|
|
117
|
+
model Qwen
|
|
118
|
+
role "Researcher"
|
|
119
|
+
description "Collect facts and answer carefully."
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
A child scope can override these values:
|
|
124
|
+
|
|
125
|
+
```agentscript
|
|
126
|
+
func careful(input) {
|
|
127
|
+
model Strong
|
|
128
|
+
role "Specialist"
|
|
129
|
+
...
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Values and shapes
|
|
134
|
+
|
|
135
|
+
Runtime values are JSON-oriented:
|
|
136
|
+
|
|
137
|
+
- `string`, `number`, `boolean`, `none`
|
|
138
|
+
- `list`, `object`
|
|
139
|
+
|
|
140
|
+
Shapes are used for input validation and `generate` output validation:
|
|
141
|
+
|
|
142
|
+
```agentscript
|
|
143
|
+
return generate({ input: "Extract facts" }) {
|
|
144
|
+
return {
|
|
145
|
+
ok boolean
|
|
146
|
+
title string
|
|
147
|
+
items list[json]
|
|
148
|
+
meta json
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Supported shape types: `string`, `number`, `boolean`, `json`, `list`, `list[T]` where T is any supported type.
|
|
154
|
+
|
|
155
|
+
Shapes are not a full static type system.
|
|
156
|
+
|
|
157
|
+
## Explicit context with `use`
|
|
158
|
+
|
|
159
|
+
`use` selects values that may be included in later `generate` prompts within the current scope and child scopes.
|
|
160
|
+
|
|
161
|
+
```agentscript
|
|
162
|
+
use input.question
|
|
163
|
+
use Requirements < 4k
|
|
164
|
+
use past_lessons < 2k
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Rules
|
|
168
|
+
|
|
169
|
+
- Unused variables do not enter prompts.
|
|
170
|
+
- Tool outputs do not automatically enter prompts.
|
|
171
|
+
- Memory query results do not automatically enter prompts.
|
|
172
|
+
- Trace events do not automatically enter prompts.
|
|
173
|
+
- `use value < n` applies a context budget.
|
|
174
|
+
- `llm`, `tool`, `agent`, `memory` bindings cannot be used.
|
|
175
|
+
- Function bindings cannot be used.
|
|
176
|
+
- `use` declarations are inherited by child scopes.
|
|
177
|
+
|
|
178
|
+
### Deferred evaluation
|
|
179
|
+
|
|
180
|
+
`use expr < budget` declares a context source, not a snapshot. The expression is re-evaluated when `generate` builds the prompt. This means updates to a variable made after `use` but before `generate` are visible at generation time.
|
|
181
|
+
|
|
182
|
+
## Generate
|
|
183
|
+
|
|
184
|
+
`generate` calls the current model and requires an `input` instruction plus a return shape.
|
|
185
|
+
|
|
186
|
+
```agentscript
|
|
187
|
+
answer = generate({
|
|
188
|
+
input: "Answer using the selected context."
|
|
189
|
+
limit: 800
|
|
190
|
+
attempts: 3
|
|
191
|
+
debug: true
|
|
192
|
+
}) {
|
|
193
|
+
return {
|
|
194
|
+
ok boolean
|
|
195
|
+
answer string
|
|
196
|
+
reason string
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Semantics
|
|
202
|
+
|
|
203
|
+
- `input` is the per-generation instruction. Required.
|
|
204
|
+
- `limit` is the generation budget (number or `2k` style). Optional.
|
|
205
|
+
- `attempts` controls retry for JSON parse errors or shape mismatch. Optional, defaults to 1.
|
|
206
|
+
- `debug` prints the full prompt to stderr. Optional, defaults to false.
|
|
207
|
+
- The `return { ... }` block declares the expected output shape.
|
|
208
|
+
- Provider errors (auth, network, timeout, missing model) fail directly without retry.
|
|
209
|
+
- Shape validation includes coercion (e.g. `"true"` -> `true`, `"42"` -> `42`).
|
|
210
|
+
|
|
211
|
+
## Control flow
|
|
212
|
+
|
|
213
|
+
### If / else
|
|
214
|
+
|
|
215
|
+
```agentscript
|
|
216
|
+
if answer.ok and not input.dry_run {
|
|
217
|
+
return answer
|
|
218
|
+
} else {
|
|
219
|
+
return fallback(answer)
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Supported operators: `==`, `!=`, `and`, `or`, `not`. `<` is not a general comparison operator — it is used for budgets and loop limits.
|
|
224
|
+
|
|
225
|
+
### Loop until
|
|
226
|
+
|
|
227
|
+
```agentscript
|
|
228
|
+
done = false
|
|
229
|
+
|
|
230
|
+
loop until done < 6 {
|
|
231
|
+
observation = observe(input)
|
|
232
|
+
done = observation.ok
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Checks the condition before each iteration. Exits when the condition is true or the iteration limit is reached.
|
|
237
|
+
|
|
238
|
+
### Repeat
|
|
239
|
+
|
|
240
|
+
```agentscript
|
|
241
|
+
repeat * 3 {
|
|
242
|
+
result = attempt(input)
|
|
243
|
+
if result.ok {
|
|
244
|
+
return result
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Each iteration creates a child scope. Outer variables updated inside the loop persist across iterations. New variables created inside are discarded after each iteration.
|
|
250
|
+
|
|
251
|
+
### For in
|
|
252
|
+
|
|
253
|
+
```agentscript
|
|
254
|
+
for step in plan.steps < 12 {
|
|
255
|
+
result = Executor(step)
|
|
256
|
+
results.add(result)
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The list is evaluated once at loop start. Each iteration creates a child scope. The loop variable is scoped to the body.
|
|
261
|
+
|
|
262
|
+
## Lists and JSON helpers
|
|
263
|
+
|
|
264
|
+
```agentscript
|
|
265
|
+
first = items[0]
|
|
266
|
+
count = items.length
|
|
267
|
+
items.add(new_item)
|
|
268
|
+
summary = items.summary
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
- `list[index]` is read-only. Index must be a non-negative integer.
|
|
272
|
+
- `list.add(value)` mutates the list. Takes exactly one argument.
|
|
273
|
+
- `.length` returns the list length.
|
|
274
|
+
- `.summary` returns a JSON-safe runtime view of the list. It is not an LLM-generated summary or semantic compression; any prompt-size reduction comes from explicit context budgets such as `use scratch.summary < 2k`.
|
|
275
|
+
|
|
276
|
+
## Tools
|
|
277
|
+
|
|
278
|
+
Tools are imported by URI scheme and called with structured JSON arguments.
|
|
279
|
+
|
|
280
|
+
```agentscript
|
|
281
|
+
import tool Find from "sh://find"
|
|
282
|
+
import tool Grep from "sh://grep"
|
|
283
|
+
import tool File from "file://workspace"
|
|
284
|
+
import tool Env from "env://process"
|
|
285
|
+
import tool Http from "https://api.example.com"
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Find
|
|
289
|
+
|
|
290
|
+
```agentscript
|
|
291
|
+
files = Find.run({
|
|
292
|
+
path: "."
|
|
293
|
+
name: "*.ts"
|
|
294
|
+
type: "file"
|
|
295
|
+
max: 50
|
|
296
|
+
})
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Grep
|
|
300
|
+
|
|
301
|
+
```agentscript
|
|
302
|
+
matches = Grep.run({
|
|
303
|
+
path: "src"
|
|
304
|
+
pattern: "TODO"
|
|
305
|
+
include: "*.ts"
|
|
306
|
+
max: 100
|
|
307
|
+
})
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Sed
|
|
311
|
+
|
|
312
|
+
```agentscript
|
|
313
|
+
lines = Sed.run({
|
|
314
|
+
path: "src/main.as"
|
|
315
|
+
start: 1
|
|
316
|
+
max: 20
|
|
317
|
+
})
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### File
|
|
321
|
+
|
|
322
|
+
```agentscript
|
|
323
|
+
content = File.read({ path: "README.md" })
|
|
324
|
+
entries = File.list({ path: "src" })
|
|
325
|
+
result = File.write({ path: "output.md", content: "# Result" })
|
|
326
|
+
result = File.patch({ path: "file.as", search: "old", replace: "new" })
|
|
327
|
+
result = File.undo(effects)
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Write and patch operations return undoable effect records. `File.undo` accepts a list of effect records and reverses them.
|
|
331
|
+
|
|
332
|
+
### Env
|
|
333
|
+
|
|
334
|
+
```agentscript
|
|
335
|
+
home = Env.get({ name: "HOME" })
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Http
|
|
339
|
+
|
|
340
|
+
```agentscript
|
|
341
|
+
response = Http.get({ url: "/api/data", headers: { Authorization: "Bearer ..." }, timeout: 10000 })
|
|
342
|
+
response = Http.post({ url: "/api/submit", body: { key: "value" }, timeout: 10000 })
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
HTTP requests are restricted to the origin of the import URI.
|
|
346
|
+
|
|
347
|
+
### Security
|
|
348
|
+
|
|
349
|
+
- General shell entry points (`sh://sh`, `sh://bash`, `sh://zsh`, `sh://fish`) are forbidden.
|
|
350
|
+
- File paths are constrained to the workspace root.
|
|
351
|
+
- Symlinks escaping the workspace are not followed.
|
|
352
|
+
- Write operations return effect records for audit and undo.
|
|
353
|
+
|
|
354
|
+
## Memory
|
|
355
|
+
|
|
356
|
+
Memory provides durable, explicit, auditable state across runs.
|
|
357
|
+
|
|
358
|
+
```agentscript
|
|
359
|
+
import memory Lessons from "file://./.agentscript/lessons.jsonl"
|
|
360
|
+
import memory Runs from "sqlite://./.agentscript/memory.db#runs"
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## File imports
|
|
364
|
+
|
|
365
|
+
File imports load local files as explicit context resources.
|
|
366
|
+
|
|
367
|
+
```agentscript
|
|
368
|
+
import file Requirements from "./requirements.md"
|
|
369
|
+
import file Config from "./config.json"
|
|
370
|
+
|
|
371
|
+
func answer(input) {
|
|
372
|
+
use Requirements < 4k
|
|
373
|
+
use Config
|
|
374
|
+
return generate({ input: "Answer from the referenced file." }) {
|
|
375
|
+
return {
|
|
376
|
+
ok boolean
|
|
377
|
+
answer string
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Text files are loaded as strings. JSON files are parsed as JSON values. File contents must be explicitly `use`d to enter prompt context.
|
|
384
|
+
|
|
385
|
+
### API
|
|
386
|
+
|
|
387
|
+
```agentscript
|
|
388
|
+
Lessons.add({
|
|
389
|
+
kind: "lesson"
|
|
390
|
+
text: reflection.insight
|
|
391
|
+
goal: input.goal
|
|
392
|
+
})
|
|
393
|
+
|
|
394
|
+
past = Lessons.query({
|
|
395
|
+
kind: "lesson"
|
|
396
|
+
text: input.goal
|
|
397
|
+
limit: 5
|
|
398
|
+
})
|
|
399
|
+
|
|
400
|
+
use past < 2k
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Rules
|
|
404
|
+
|
|
405
|
+
- Memory bindings cannot be used directly as prompt context.
|
|
406
|
+
- Query results are ordinary data and must be explicitly selected with `use`.
|
|
407
|
+
- `add` takes one object argument. Runtime adds `id`, `created_at`, `updated_at`.
|
|
408
|
+
- `query` supports `text` (case-insensitive substring), `kind` (exact match), `where` (exact field match), and `limit`.
|
|
409
|
+
- File memory uses JSONL format with automatic file and directory creation.
|
|
410
|
+
- SQLite memory uses a fixed schema. No arbitrary SQL is exposed.
|
|
411
|
+
|
|
412
|
+
## Agent composition
|
|
413
|
+
|
|
414
|
+
Multi-agent composition uses imports, function calls, and explicit parameter passing.
|
|
415
|
+
|
|
416
|
+
```agentscript
|
|
417
|
+
import agent Planner from "./planner.as"
|
|
418
|
+
import agent Executor from "./executor.as"
|
|
419
|
+
|
|
420
|
+
main agent Controller {
|
|
421
|
+
main func(input) {
|
|
422
|
+
plan = Planner(input)
|
|
423
|
+
results = []
|
|
424
|
+
for step in plan.steps < 10 {
|
|
425
|
+
result = Executor({ goal: input.goal, step: step })
|
|
426
|
+
results.add(result)
|
|
427
|
+
}
|
|
428
|
+
return results.summary
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
Each agent call creates an isolated scope. Context boundaries are never implicitly crossed. Trace events are nested.
|
|
434
|
+
|
|
435
|
+
## Reserved words
|
|
436
|
+
|
|
437
|
+
`import`, `from`, `main`, `agent`, `func`, `use`, `loop`, `until`, `repeat`, `for`, `in`, `return`, `if`, `else`, `and`, `or`, `not`, `generate`, `true`, `false`, `none`, `string`, `number`, `boolean`, `json`, `list`.
|
|
438
|
+
|
|
439
|
+
The following are NOT reserved: `input`, `act`, `reason`, `observe`, `reflect`, `answer`, `scratch`, `done`, `task`, `output`, `context`, `repair`.
|
|
440
|
+
|
|
441
|
+
## Execution model
|
|
442
|
+
|
|
443
|
+
```text
|
|
444
|
+
source -> tokenizer -> parser -> AST -> semantic analyzer -> interpreter -> trace + result
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
The interpreter is a tree-walking evaluator. There is no IR, bytecode, or compilation step.
|
|
448
|
+
|
|
449
|
+
## Modules
|
|
450
|
+
|
|
451
|
+
| Module | Path | Responsibility |
|
|
452
|
+
|--------|------|---------------|
|
|
453
|
+
| Tokenizer | `src/parser/tokenizer.ts` | Lexical analysis |
|
|
454
|
+
| Parser | `src/parser/parser.ts` | Recursive descent parsing |
|
|
455
|
+
| Semantic analyzer | `src/semantic/analyzer.ts` | Static semantic checks |
|
|
456
|
+
| Interpreter | `src/runtime/interpreter.ts` | Entry point, agent/function calls |
|
|
457
|
+
| Evaluator | `src/runtime/evaluator.ts` | Expression evaluation, tool dispatch, use resolution |
|
|
458
|
+
| Generator | `src/runtime/generate.ts` | Generate execution, repair, context building |
|
|
459
|
+
| Scope | `src/runtime/scope.ts` | Variable scope, config, use declarations |
|
|
460
|
+
| Context builder | `src/runtime/context.ts` | Prompt construction, clipping |
|
|
461
|
+
| LLM provider | `src/providers/llm/` | OpenAI, Anthropic, Ollama |
|
|
462
|
+
| Memory provider | `src/providers/memory/` | File JSONL, SQLite |
|
|
463
|
+
| Tool provider | `src/providers/tools/` | Host tool implementations |
|
|
464
|
+
| CLI | `src/bin/agentscript.ts` | Command-line interface |
|
|
465
|
+
| REPL | `src/bin/repl.ts` | Interactive REPL |
|
|
466
|
+
|
|
467
|
+
## Non-goals
|
|
468
|
+
|
|
469
|
+
AgentScript v1.0.0 does not provide:
|
|
470
|
+
|
|
471
|
+
- A general workflow engine.
|
|
472
|
+
- General parallel execution syntax.
|
|
473
|
+
- General transactions or automatic rollback.
|
|
474
|
+
- Arbitrary SQL.
|
|
475
|
+
- Automatic long-term memory.
|
|
476
|
+
- Automatic prompt capture of local variables.
|
|
477
|
+
- Automatic modification of `.as` source files.
|
|
478
|
+
- A full static type system.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import llm Qwen from "ollama://localhost:11434/qwen3.6"
|
|
2
|
+
import tool File from "file://workspace"
|
|
3
|
+
|
|
4
|
+
main agent ChangelogWriter {
|
|
5
|
+
model Qwen
|
|
6
|
+
role "Release Manager"
|
|
7
|
+
description "Read a git diff saved to a file and generate a release changelog draft."
|
|
8
|
+
|
|
9
|
+
main func(input {
|
|
10
|
+
diff_path string
|
|
11
|
+
}) {
|
|
12
|
+
diff = File.read({
|
|
13
|
+
path: input.diff_path
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
use input.diff_path
|
|
17
|
+
use diff < 10k
|
|
18
|
+
|
|
19
|
+
return generate({ input: "Write a changelog from this git diff", limit: 1200 }) {
|
|
20
|
+
return {
|
|
21
|
+
title string
|
|
22
|
+
highlights list[string]
|
|
23
|
+
breaking_changes list[string]
|
|
24
|
+
fixes list[string]
|
|
25
|
+
notes string
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import llm Qwen from "ollama://localhost:11434/qwen3.6"
|
|
2
|
+
import tool Api from "https://api.example.com"
|
|
3
|
+
|
|
4
|
+
main agent ApiExtractor {
|
|
5
|
+
model Qwen
|
|
6
|
+
role "Data Engineer"
|
|
7
|
+
description "Call an API endpoint and extract normalized structured data from the response."
|
|
8
|
+
|
|
9
|
+
main func(input {
|
|
10
|
+
url string
|
|
11
|
+
}) {
|
|
12
|
+
response = Api.get({
|
|
13
|
+
url: input.url,
|
|
14
|
+
timeout: 10000
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
use input.url
|
|
18
|
+
use response < 8k
|
|
19
|
+
|
|
20
|
+
return generate({ input: "Extract normalized data from the API response", limit: 1200 }) {
|
|
21
|
+
return {
|
|
22
|
+
records list[json]
|
|
23
|
+
fields list[string]
|
|
24
|
+
warnings list[string]
|
|
25
|
+
summary string
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import llm Qwen from "ollama://localhost:11434/qwen3.6"
|
|
2
|
+
import tool Grep from "sh://grep"
|
|
3
|
+
|
|
4
|
+
main agent CodeReviewAssistant {
|
|
5
|
+
model Qwen
|
|
6
|
+
role "Senior Code Reviewer"
|
|
7
|
+
description "Scan TODO and FIXME markers and return concrete review actions."
|
|
8
|
+
|
|
9
|
+
main func(input {
|
|
10
|
+
path string
|
|
11
|
+
}) {
|
|
12
|
+
todos = Grep.run({
|
|
13
|
+
path: input.path,
|
|
14
|
+
pattern: "TODO",
|
|
15
|
+
include: "*",
|
|
16
|
+
max: 100
|
|
17
|
+
})
|
|
18
|
+
fixmes = Grep.run({
|
|
19
|
+
path: input.path,
|
|
20
|
+
pattern: "FIXME",
|
|
21
|
+
include: "*",
|
|
22
|
+
max: 100
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
use input.path
|
|
26
|
+
use todos < 4k
|
|
27
|
+
use fixmes < 4k
|
|
28
|
+
|
|
29
|
+
return generate({ input: "Turn TODO and FIXME scan results into prioritized repair suggestions", limit: 1200 }) {
|
|
30
|
+
return {
|
|
31
|
+
summary string
|
|
32
|
+
findings list[string]
|
|
33
|
+
suggested_fixes list[string]
|
|
34
|
+
next_steps list[string]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import llm Qwen from "ollama://localhost:11434/qwen3.6"
|
|
2
|
+
import tool File from "file://workspace"
|
|
3
|
+
|
|
4
|
+
main agent FileSummarizer {
|
|
5
|
+
model Qwen
|
|
6
|
+
role "Technical Writer"
|
|
7
|
+
description "Read one local file and produce a useful structured summary."
|
|
8
|
+
|
|
9
|
+
main func(input {
|
|
10
|
+
path string
|
|
11
|
+
}) {
|
|
12
|
+
content = File.read({
|
|
13
|
+
path: input.path
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
use input.path
|
|
17
|
+
use content < 8k
|
|
18
|
+
|
|
19
|
+
return generate({ input: "Summarize the file for a busy teammate", limit: 1000 }) {
|
|
20
|
+
return {
|
|
21
|
+
title string
|
|
22
|
+
summary string
|
|
23
|
+
key_points list[string]
|
|
24
|
+
action_items list[string]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import llm Qwen from "ollama://localhost:11434/qwen3.6"
|
|
2
|
+
import tool Find from "sh://find"
|
|
3
|
+
|
|
4
|
+
main agent MarkdownTranslator {
|
|
5
|
+
model Qwen
|
|
6
|
+
role "Documentation Translator"
|
|
7
|
+
description "Find markdown files and prepare a batch translation plan."
|
|
8
|
+
|
|
9
|
+
main func(input {
|
|
10
|
+
path string
|
|
11
|
+
target_language string
|
|
12
|
+
}) {
|
|
13
|
+
files = Find.run({
|
|
14
|
+
path: input.path,
|
|
15
|
+
name: "*.md",
|
|
16
|
+
type: "file",
|
|
17
|
+
max: 50
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
use input.path
|
|
21
|
+
use input.target_language
|
|
22
|
+
use files < 4k
|
|
23
|
+
|
|
24
|
+
return generate({ input: "Create a practical markdown translation plan", limit: 1000 }) {
|
|
25
|
+
return {
|
|
26
|
+
target_language string
|
|
27
|
+
files list[string]
|
|
28
|
+
glossary_notes list[string]
|
|
29
|
+
instructions string
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rong/agentscript",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "AgentScript context engineering language runtime",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"agentscript": "dist/bin/agentscript.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"examples",
|
|
12
|
+
"tutorials",
|
|
13
|
+
"docs",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE",
|
|
16
|
+
"CHANGELOG.md",
|
|
17
|
+
"INSTALL.md"
|
|
18
|
+
],
|
|
19
|
+
"directories": {
|
|
20
|
+
"doc": "docs"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && chmod +x dist/bin/agentscript.js",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest",
|
|
26
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
27
|
+
"prepublishOnly": "npm run typecheck && npm test && npm run build",
|
|
28
|
+
"agentscript": "npm run build --silent && node dist/bin/agentscript.js",
|
|
29
|
+
"parse": "npm run agentscript -- --parse",
|
|
30
|
+
"check": "npm run agentscript -- --check",
|
|
31
|
+
"execute": "npm run agentscript --",
|
|
32
|
+
"execute:llm": "npm run agentscript -- --real-llm"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"agentscript",
|
|
36
|
+
"llm",
|
|
37
|
+
"agent",
|
|
38
|
+
"ai-agent",
|
|
39
|
+
"multi-agent",
|
|
40
|
+
"context-engineering",
|
|
41
|
+
"dsl",
|
|
42
|
+
"prompt",
|
|
43
|
+
"react-agent",
|
|
44
|
+
"tool-use",
|
|
45
|
+
"automation",
|
|
46
|
+
"workflow"
|
|
47
|
+
],
|
|
48
|
+
"author": "Rong Zhou",
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"type": "module",
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=25"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@types/node": "^25.6.2",
|
|
56
|
+
"typescript": "^6.0.3",
|
|
57
|
+
"vitest": "^4.1.5"
|
|
58
|
+
}
|
|
59
|
+
}
|