@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,332 @@
|
|
|
1
|
+
# AgentScript Context Engineering
|
|
2
|
+
|
|
3
|
+
This document explains the core design semantics of `use`, scopes, and `generate` in AgentScript. These concepts are not specific to any version — they are the fundamental semantics that distinguish AgentScript from general-purpose programming languages.
|
|
4
|
+
|
|
5
|
+
AgentScript has variables, functions, loops, and agent calls, but its primary purpose is not to be a general-purpose language. It is an auditable, composable, explicit prompt context engineering DSL.
|
|
6
|
+
|
|
7
|
+
## Core positioning
|
|
8
|
+
|
|
9
|
+
AgentScript's control flow serves prompt context construction.
|
|
10
|
+
|
|
11
|
+
Ordinary statements organize data, call tools, call agents, and update intermediate state. LLM calls happen only through `generate(...) { return ... }`, and the context visible to `generate` must be declared explicitly with `use`.
|
|
12
|
+
|
|
13
|
+
The core objects are:
|
|
14
|
+
|
|
15
|
+
- **Data**: ordinary variables, JSON values, lists, file imports, tool observations, agent return values.
|
|
16
|
+
- **Context Source**: a prompt context origin declared by `use expr < budget`.
|
|
17
|
+
- **Generation Site**: an LLM call declared by `generate({ input, limit, attempts, debug }) { return shape }`.
|
|
18
|
+
- **Boundary**: context visibility boundaries formed by agent, function, and block scopes.
|
|
19
|
+
|
|
20
|
+
## Semantics of `use`
|
|
21
|
+
|
|
22
|
+
`use` is not a variable read or a namespace import. Its meaning is:
|
|
23
|
+
|
|
24
|
+
> Declare a prompt context source in the current scope, so that `generate` calls visible in that scope may include the source's current value in the prompt context.
|
|
25
|
+
|
|
26
|
+
Example:
|
|
27
|
+
|
|
28
|
+
```agentscript
|
|
29
|
+
func answer(question, scratch) {
|
|
30
|
+
use question
|
|
31
|
+
use scratch.summary < 2k
|
|
32
|
+
|
|
33
|
+
return generate({
|
|
34
|
+
input: "Answer the question using collected facts"
|
|
35
|
+
limit: 800
|
|
36
|
+
}) {
|
|
37
|
+
return {
|
|
38
|
+
ok boolean
|
|
39
|
+
text string
|
|
40
|
+
error string
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Here `question` and `scratch.summary` are explicit context sources for the `generate` call. Local variables not selected by `use` must not enter the prompt.
|
|
47
|
+
|
|
48
|
+
### Deferred evaluation
|
|
49
|
+
|
|
50
|
+
`use expr < budget` declares a context source, not a snapshot of the current value. The source is resolved at the `generate` execution point.
|
|
51
|
+
|
|
52
|
+
```agentscript
|
|
53
|
+
main func(input) {
|
|
54
|
+
scratch = []
|
|
55
|
+
use scratch.summary < 2k
|
|
56
|
+
|
|
57
|
+
scratch.add({ fact: "A" })
|
|
58
|
+
scratch.add({ fact: "B" })
|
|
59
|
+
|
|
60
|
+
return generate({ input: "Answer from scratch" }) {
|
|
61
|
+
return {
|
|
62
|
+
text string
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The `generate` call sees both facts.
|
|
69
|
+
|
|
70
|
+
Rationale:
|
|
71
|
+
|
|
72
|
+
- `use` expresses a context contract, not an assignment.
|
|
73
|
+
- Agent patterns continuously update scratch, plans, and observations.
|
|
74
|
+
- A snapshot-based `use` would require re-declaration before every `generate`, risking stale context.
|
|
75
|
+
|
|
76
|
+
### What cannot be used
|
|
77
|
+
|
|
78
|
+
The following runtime capabilities must never enter prompt context:
|
|
79
|
+
|
|
80
|
+
- Imported tools
|
|
81
|
+
- Imported LLMs / models
|
|
82
|
+
- Imported agent bindings
|
|
83
|
+
- Function bindings
|
|
84
|
+
- Provider URIs, workspace paths, and other execution configuration
|
|
85
|
+
|
|
86
|
+
These should be rejected by the semantic analyzer:
|
|
87
|
+
|
|
88
|
+
```agentscript
|
|
89
|
+
use Search -- invalid (tool binding)
|
|
90
|
+
use Qwen -- invalid (LLM binding)
|
|
91
|
+
use Worker -- invalid (agent binding)
|
|
92
|
+
use helper -- invalid (function binding)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Scope as context boundary
|
|
96
|
+
|
|
97
|
+
Scopes in AgentScript control both variable visibility and prompt context visibility.
|
|
98
|
+
|
|
99
|
+
### Function boundary
|
|
100
|
+
|
|
101
|
+
Each function call creates an independent context boundary.
|
|
102
|
+
|
|
103
|
+
```agentscript
|
|
104
|
+
func caller(input) {
|
|
105
|
+
use input.goal
|
|
106
|
+
return helper(input)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
func helper(input) {
|
|
110
|
+
use input.detail
|
|
111
|
+
return generate({ input: "Work on detail" }) {
|
|
112
|
+
return {
|
|
113
|
+
ok boolean
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The `generate` inside `helper` must not inherit `caller`'s `use input.goal`. Data must be passed as arguments and explicitly `use`d.
|
|
120
|
+
|
|
121
|
+
### Agent boundary
|
|
122
|
+
|
|
123
|
+
Agent calls create a stronger context boundary.
|
|
124
|
+
|
|
125
|
+
```agentscript
|
|
126
|
+
result = Worker({
|
|
127
|
+
goal: input.goal
|
|
128
|
+
previous: results.summary
|
|
129
|
+
})
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`Worker` must not see the caller's context. The caller passes data explicitly through arguments.
|
|
133
|
+
|
|
134
|
+
This guarantees:
|
|
135
|
+
|
|
136
|
+
- Each agent's prompt contract is independently auditable.
|
|
137
|
+
- Multi-agent composition does not cause implicit context leakage.
|
|
138
|
+
- Sub-agents see only explicitly passed data.
|
|
139
|
+
|
|
140
|
+
### Block boundary
|
|
141
|
+
|
|
142
|
+
Blocks (`if`, `repeat`, `loop`, `for`) create child scopes. `use` declarations inside a block affect only `generate` calls within that block.
|
|
143
|
+
|
|
144
|
+
```agentscript
|
|
145
|
+
if condition {
|
|
146
|
+
temp = compute(input)
|
|
147
|
+
use temp
|
|
148
|
+
result = generate({ input: "Use temp" }) {
|
|
149
|
+
return {
|
|
150
|
+
ok boolean
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
`temp` and `use temp` must not leak to the outer scope.
|
|
157
|
+
|
|
158
|
+
### Parent context visibility
|
|
159
|
+
|
|
160
|
+
A `generate` call in a nested scope can see context sources declared in parent scopes. The visible order must be stable from outer to inner for trace and prompt audit.
|
|
161
|
+
|
|
162
|
+
## Context construction model
|
|
163
|
+
|
|
164
|
+
A `generate` call's prompt consists of four layers.
|
|
165
|
+
|
|
166
|
+
### System
|
|
167
|
+
|
|
168
|
+
Describes agent identity and stable behavioral constraints:
|
|
169
|
+
|
|
170
|
+
- Agent name
|
|
171
|
+
- `role`
|
|
172
|
+
- `description`
|
|
173
|
+
|
|
174
|
+
Must not contain execution configuration (provider URIs, workspace paths, tool internals).
|
|
175
|
+
|
|
176
|
+
### Context
|
|
177
|
+
|
|
178
|
+
Comes from `use` declarations visible to the current `generate`.
|
|
179
|
+
|
|
180
|
+
Each context item records:
|
|
181
|
+
|
|
182
|
+
- source expression (e.g. `scratch.summary`)
|
|
183
|
+
- resolved value
|
|
184
|
+
- rendered text
|
|
185
|
+
- budget
|
|
186
|
+
- clipping status
|
|
187
|
+
|
|
188
|
+
Recommended prompt format:
|
|
189
|
+
|
|
190
|
+
```text
|
|
191
|
+
Context:
|
|
192
|
+
[0] question:
|
|
193
|
+
What is AgentScript?
|
|
194
|
+
|
|
195
|
+
[1] scratch.summary:
|
|
196
|
+
[
|
|
197
|
+
{ "fact": "..." }
|
|
198
|
+
]
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Source labels help models understand context and help humans audit prompts.
|
|
202
|
+
|
|
203
|
+
### Instruction
|
|
204
|
+
|
|
205
|
+
Comes from the `input` field of `generate(...)` options.
|
|
206
|
+
|
|
207
|
+
```agentscript
|
|
208
|
+
generate({ input: "Answer the question using only collected facts" }) {
|
|
209
|
+
return {
|
|
210
|
+
ok boolean
|
|
211
|
+
text string
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
The instruction is the per-call task. `limit`, `attempts`, and `debug` are local configuration, not prompt context. Error feedback from previous failed attempts is appended to the instruction.
|
|
217
|
+
|
|
218
|
+
### Output contract
|
|
219
|
+
|
|
220
|
+
Comes from `return { ... }` shape.
|
|
221
|
+
|
|
222
|
+
```agentscript
|
|
223
|
+
return {
|
|
224
|
+
ok boolean
|
|
225
|
+
text string
|
|
226
|
+
error string
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
The LLM provider and runtime enforce shape compliance as strictly as possible.
|
|
231
|
+
|
|
232
|
+
## Budget semantics
|
|
233
|
+
|
|
234
|
+
`use expr < budget` is a **context item budget**. It limits how much of that source may be rendered into the prompt.
|
|
235
|
+
|
|
236
|
+
`generate({ limit: budget })` is a **generation budget**. It limits output size or the provider's token limit.
|
|
237
|
+
|
|
238
|
+
They have different meanings and must not be confused.
|
|
239
|
+
|
|
240
|
+
Character count is used as an approximation. Future implementations may switch to token-aware budgets without changing the abstraction.
|
|
241
|
+
|
|
242
|
+
## Clipping strategy
|
|
243
|
+
|
|
244
|
+
Context clipping must not simply truncate strings, as that would break JSON and list structure.
|
|
245
|
+
|
|
246
|
+
Strategy:
|
|
247
|
+
|
|
248
|
+
- Strings: may be truncated by character count.
|
|
249
|
+
- Lists: prefer keeping complete items, dropping from the tail.
|
|
250
|
+
- Objects: prefer keeping complete fields, dropping from the tail.
|
|
251
|
+
- Trace: record original size, clipped size, and strategy for each item.
|
|
252
|
+
|
|
253
|
+
## Trace requirements
|
|
254
|
+
|
|
255
|
+
Trace is the primary debugging interface for a context engineering DSL.
|
|
256
|
+
|
|
257
|
+
`use` trace:
|
|
258
|
+
|
|
259
|
+
```json
|
|
260
|
+
{
|
|
261
|
+
"kind": "use",
|
|
262
|
+
"data": {
|
|
263
|
+
"source": "scratch.summary",
|
|
264
|
+
"budget": { "amount": 2, "unit": "k" }
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
`generate` trace:
|
|
270
|
+
|
|
271
|
+
```json
|
|
272
|
+
{
|
|
273
|
+
"kind": "generate",
|
|
274
|
+
"data": {
|
|
275
|
+
"instruction": "Answer from scratch",
|
|
276
|
+
"context": {
|
|
277
|
+
"items": [
|
|
278
|
+
{
|
|
279
|
+
"source": "scratch.summary",
|
|
280
|
+
"value": [{ "fact": "A" }],
|
|
281
|
+
"text": "[...]",
|
|
282
|
+
"budget": { "amount": 2, "unit": "k" },
|
|
283
|
+
"clipped": false
|
|
284
|
+
}
|
|
285
|
+
]
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
This answers:
|
|
292
|
+
|
|
293
|
+
- What did the LLM call actually see?
|
|
294
|
+
- Which context sources were declared but not included?
|
|
295
|
+
- What was clipped?
|
|
296
|
+
- Which expression was the source resolved from?
|
|
297
|
+
- Did caller and callee contexts leak?
|
|
298
|
+
|
|
299
|
+
## The `summary` view
|
|
300
|
+
|
|
301
|
+
`scratch.summary` is a common pattern:
|
|
302
|
+
|
|
303
|
+
```agentscript
|
|
304
|
+
scratch = []
|
|
305
|
+
scratch.add(observation)
|
|
306
|
+
use scratch.summary < 2k
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
It expresses "put the prompt-friendly view of scratch into context." If the implementation provides only a JSON-safe list view rather than a true LLM summary, this should be documented and visible in the trace.
|
|
310
|
+
|
|
311
|
+
## Implementation constraints
|
|
312
|
+
|
|
313
|
+
Future changes must respect:
|
|
314
|
+
|
|
315
|
+
- `generate` does not automatically capture local variables.
|
|
316
|
+
- `use` is a context declaration, not an assignment.
|
|
317
|
+
- `use` values are resolved when `generate` builds the prompt.
|
|
318
|
+
- Function and agent calls form context boundaries.
|
|
319
|
+
- Runtime capabilities must never enter prompt context.
|
|
320
|
+
- Prompts must distinguish system, context, instruction, and output contract layers.
|
|
321
|
+
- Trace must explain every `generate` call's actual context.
|
|
322
|
+
|
|
323
|
+
## Design checklist
|
|
324
|
+
|
|
325
|
+
Before modifying `use`, scope, context builder, trace, or the LLM provider, verify:
|
|
326
|
+
|
|
327
|
+
- Does this change let unused data enter the prompt?
|
|
328
|
+
- Does this change let caller context implicitly pollute callee?
|
|
329
|
+
- Does this change expose tool/model/agent/function bindings as prompt data?
|
|
330
|
+
- Does this change preserve audit information for context sources?
|
|
331
|
+
- Does this change reduce `use` to an ordinary variable snapshot?
|
|
332
|
+
- Does this change confuse context budget with generation budget?
|