@rong/agentscript 0.1.4 → 0.1.5
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 +10 -0
- package/README.md +16 -10
- package/dist/parser/parser.js +14 -6
- package/dist/parser/tokenizer.js +2 -1
- package/dist/runtime/evaluator.js +8 -0
- package/docs/cn/context-engineering.md +1 -1
- package/docs/cn/final-expression-return.md +4 -4
- package/docs/cn/generate.md +35 -39
- package/docs/cn/language.md +67 -41
- package/docs/cn/use-as.md +10 -10
- package/docs/en/context-engineering.md +1 -1
- package/docs/en/final-expression-return.md +2 -2
- package/docs/en/generate.md +33 -37
- package/docs/en/language.md +67 -41
- package/docs/en/use-as.md +10 -10
- package/examples/changelog.as +1 -1
- package/examples/extract.as +1 -1
- package/examples/review.as +2 -2
- package/examples/summarize.as +1 -1
- package/examples/translate.as +1 -1
- package/package.json +1 -1
- package/tutorials/memory.as +4 -4
- package/tutorials/plan-execute.as +4 -4
- package/tutorials/react.as +5 -5
- package/tutorials/self-improve.as +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to AgentScript will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.1.5 - 2026-05-09
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Switched context budgets from `use expr < budget` to `use expr max budget`.
|
|
10
|
+
- Switched loop and for-in iteration limits to `max` syntax.
|
|
11
|
+
- Restored `<` as an ordinary numeric comparison operator.
|
|
12
|
+
- Required comma separators between object literal fields.
|
|
13
|
+
- Updated current docs, examples, tutorials, fixtures, and tests for the new syntax.
|
|
14
|
+
|
|
5
15
|
## 0.1.4 - 2026-05-08
|
|
6
16
|
|
|
7
17
|
### Added
|
package/README.md
CHANGED
|
@@ -6,8 +6,10 @@
|
|
|
6
6
|
> Zero runtime dependencies. TypeScript-powered.
|
|
7
7
|
|
|
8
8
|
```agentscript
|
|
9
|
-
use scratch.summary
|
|
10
|
-
generate({
|
|
9
|
+
use scratch.summary max 2k as observations
|
|
10
|
+
generate({
|
|
11
|
+
input: "Answer from observations"
|
|
12
|
+
}) -> {
|
|
11
13
|
ok boolean
|
|
12
14
|
text string
|
|
13
15
|
}
|
|
@@ -60,12 +62,14 @@ main agent FileSummarizer {
|
|
|
60
62
|
description "Read one local file and produce a useful structured summary."
|
|
61
63
|
|
|
62
64
|
main func(input { path string }) {
|
|
63
|
-
content = File.read({
|
|
65
|
+
content = File.read({
|
|
66
|
+
path: input.path
|
|
67
|
+
})
|
|
64
68
|
use input.path as source path
|
|
65
|
-
use content
|
|
69
|
+
use content max 8k as file content
|
|
66
70
|
|
|
67
71
|
generate({
|
|
68
|
-
input: "Summarize the file for a busy teammate"
|
|
72
|
+
input: "Summarize the file for a busy teammate",
|
|
69
73
|
max_output: 1000
|
|
70
74
|
}) -> {
|
|
71
75
|
title string
|
|
@@ -181,10 +185,10 @@ main agent ResearchAgent {
|
|
|
181
185
|
use input.question as user question
|
|
182
186
|
|
|
183
187
|
scratch = []
|
|
184
|
-
use scratch.summary
|
|
188
|
+
use scratch.summary max 2k as observations
|
|
185
189
|
|
|
186
190
|
done = false
|
|
187
|
-
loop until done
|
|
191
|
+
loop until done max 6 {
|
|
188
192
|
thought = reason(input.question, scratch)
|
|
189
193
|
obs = Search.search(thought.focus)
|
|
190
194
|
scratch.add(obs)
|
|
@@ -196,8 +200,10 @@ main agent ResearchAgent {
|
|
|
196
200
|
|
|
197
201
|
func answer(question, scratch) {
|
|
198
202
|
use question as user question
|
|
199
|
-
use scratch.summary
|
|
200
|
-
generate({
|
|
203
|
+
use scratch.summary max 2k as observations
|
|
204
|
+
generate({
|
|
205
|
+
input: "Answer using only the observations"
|
|
206
|
+
}) -> {
|
|
201
207
|
ok boolean
|
|
202
208
|
text string
|
|
203
209
|
error string
|
|
@@ -281,4 +287,4 @@ Zero runtime dependencies. Built with TypeScript.
|
|
|
281
287
|
|
|
282
288
|
## License
|
|
283
289
|
|
|
284
|
-
MIT
|
|
290
|
+
MIT
|
package/dist/parser/parser.js
CHANGED
|
@@ -175,7 +175,7 @@ class Parser {
|
|
|
175
175
|
parseUse() {
|
|
176
176
|
const start = this.consume("use").range.start;
|
|
177
177
|
const value = this.parseLogicalOr();
|
|
178
|
-
const budget = this.match("
|
|
178
|
+
const budget = this.match("max") ? this.parseBudget() : undefined;
|
|
179
179
|
const label = this.match("as") ? this.parseUseLabel() : undefined;
|
|
180
180
|
return {
|
|
181
181
|
kind: "UseStmt",
|
|
@@ -228,7 +228,7 @@ class Parser {
|
|
|
228
228
|
const item = this.consumeIdentifier("Expected for item name");
|
|
229
229
|
this.consume("in");
|
|
230
230
|
const iterable = this.parseLogicalOr();
|
|
231
|
-
this.consume("
|
|
231
|
+
this.consume("max");
|
|
232
232
|
const maxIterations = this.parsePositiveInteger("Expected for iteration count");
|
|
233
233
|
const body = this.parseBlock();
|
|
234
234
|
return {
|
|
@@ -245,7 +245,7 @@ class Parser {
|
|
|
245
245
|
const start = this.consume("loop").range.start;
|
|
246
246
|
this.consume("until");
|
|
247
247
|
const condition = this.parseLogicalOr();
|
|
248
|
-
this.consume("
|
|
248
|
+
this.consume("max");
|
|
249
249
|
const maxIterations = this.parsePositiveInteger("Expected loop iteration count");
|
|
250
250
|
const body = this.parseBlock();
|
|
251
251
|
return {
|
|
@@ -299,7 +299,10 @@ class Parser {
|
|
|
299
299
|
return this.parseBinaryExpression(() => this.parseEquality(), "and");
|
|
300
300
|
}
|
|
301
301
|
parseEquality() {
|
|
302
|
-
return this.parseBinaryExpression(() => this.
|
|
302
|
+
return this.parseBinaryExpression(() => this.parseComparison(), "==", "!=");
|
|
303
|
+
}
|
|
304
|
+
parseComparison() {
|
|
305
|
+
return this.parseBinaryExpression(() => this.parseUnary(), "<");
|
|
303
306
|
}
|
|
304
307
|
parseBinaryExpression(parseOperand, ...operators) {
|
|
305
308
|
let expr = parseOperand();
|
|
@@ -481,7 +484,7 @@ class Parser {
|
|
|
481
484
|
else if (key === "debug" && value.kind === "BooleanExpr") {
|
|
482
485
|
debug = value;
|
|
483
486
|
}
|
|
484
|
-
this.
|
|
487
|
+
this.consumePropertySeparator("}");
|
|
485
488
|
}
|
|
486
489
|
this.consume("}");
|
|
487
490
|
return {
|
|
@@ -511,7 +514,7 @@ class Parser {
|
|
|
511
514
|
value,
|
|
512
515
|
range: { start: propStart, end: value.range.end }
|
|
513
516
|
});
|
|
514
|
-
this.
|
|
517
|
+
this.consumePropertySeparator("}");
|
|
515
518
|
}
|
|
516
519
|
this.consume("}");
|
|
517
520
|
return {
|
|
@@ -520,6 +523,11 @@ class Parser {
|
|
|
520
523
|
range: { start, end: this.previous().range.end }
|
|
521
524
|
};
|
|
522
525
|
}
|
|
526
|
+
consumePropertySeparator(terminator) {
|
|
527
|
+
if (this.check(terminator))
|
|
528
|
+
return;
|
|
529
|
+
this.consume(",");
|
|
530
|
+
}
|
|
523
531
|
parseList() {
|
|
524
532
|
const start = this.consume("[").range.start;
|
|
525
533
|
const items = this.parseCommaSeparatedUntil("]", () => this.parseExpression());
|
package/dist/parser/tokenizer.js
CHANGED
|
@@ -97,8 +97,16 @@ export class Evaluator {
|
|
|
97
97
|
return this.valuesEqual(await this.evaluate(expr.left, scope), await this.evaluate(expr.right, scope));
|
|
98
98
|
case "!=":
|
|
99
99
|
return !this.valuesEqual(await this.evaluate(expr.left, scope), await this.evaluate(expr.right, scope));
|
|
100
|
+
case "<":
|
|
101
|
+
return this.evaluateLessThan(await this.evaluate(expr.left, scope), await this.evaluate(expr.right, scope), expr.range);
|
|
100
102
|
}
|
|
101
103
|
}
|
|
104
|
+
evaluateLessThan(left, right, range) {
|
|
105
|
+
if (typeof left !== "number" || typeof right !== "number") {
|
|
106
|
+
throw new RuntimeError("operator '<' requires number operands", range);
|
|
107
|
+
}
|
|
108
|
+
return left < right;
|
|
109
|
+
}
|
|
102
110
|
valuesEqual(left, right) {
|
|
103
111
|
return runtimeValuesEqual(left, right);
|
|
104
112
|
}
|
|
@@ -47,8 +47,8 @@ agent 调用
|
|
|
47
47
|
变量引用
|
|
48
48
|
字段访问
|
|
49
49
|
索引访问
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
对象字面量
|
|
51
|
+
列表字面量
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
例如:
|
|
@@ -175,10 +175,10 @@ return none
|
|
|
175
175
|
|
|
176
176
|
```agentscript
|
|
177
177
|
func summarize(content) {
|
|
178
|
-
use content
|
|
178
|
+
use content max 8k
|
|
179
179
|
|
|
180
180
|
generate({
|
|
181
|
-
input: "Summarize the content"
|
|
181
|
+
input: "Summarize the content",
|
|
182
182
|
max_output: 1000
|
|
183
183
|
}) -> {
|
|
184
184
|
title string
|
package/docs/cn/generate.md
CHANGED
|
@@ -21,12 +21,12 @@ generate({ input: "Answer using the selected context." }) -> {
|
|
|
21
21
|
|
|
22
22
|
```agentscript
|
|
23
23
|
generate({
|
|
24
|
-
input: "Classify the issue"
|
|
25
|
-
max_output: 300
|
|
26
|
-
attempts: 2
|
|
27
|
-
temperature: 0.2
|
|
28
|
-
think: "medium"
|
|
29
|
-
strict: true
|
|
24
|
+
input: "Classify the issue",
|
|
25
|
+
max_output: 300,
|
|
26
|
+
attempts: 2,
|
|
27
|
+
temperature: 0.2,
|
|
28
|
+
think: "medium",
|
|
29
|
+
strict: true,
|
|
30
30
|
debug: false
|
|
31
31
|
}) -> {
|
|
32
32
|
category string
|
|
@@ -40,7 +40,7 @@ generate({
|
|
|
40
40
|
generate({ input: "Draft a response." })
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
没有声明 shape 时,runtime 不应注入 schema,也不应要求 provider 返回结构化 JSON
|
|
43
|
+
没有声明 shape 时,runtime 不应注入 schema,也不应要求 provider 返回结构化 JSON。自由形式的 `generate` 是允许的,但不推荐用于 agent workflow;优先声明明确的输出 shape,便于 retry、validation、trace 和下游 agent 调用保持可审计。
|
|
44
44
|
|
|
45
45
|
## 配置字段
|
|
46
46
|
|
|
@@ -110,7 +110,7 @@ Selected context 来自可见的 `use` 声明:
|
|
|
110
110
|
|
|
111
111
|
```agentscript
|
|
112
112
|
use input.question as user question
|
|
113
|
-
use scratch.summary
|
|
113
|
+
use scratch.summary max 2k as observations
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
渲染出的 prompt section 可以是:
|
|
@@ -162,7 +162,7 @@ Runtime 会在可能时请求 provider 返回结构化输出,并校验返回
|
|
|
162
162
|
|
|
163
163
|
```agentscript
|
|
164
164
|
generate({
|
|
165
|
-
input: "Answer briefly"
|
|
165
|
+
input: "Answer briefly",
|
|
166
166
|
max_output: 300
|
|
167
167
|
}) -> {
|
|
168
168
|
answer string
|
|
@@ -178,10 +178,10 @@ max_output = provider-side generation budget requested by AgentScript
|
|
|
178
178
|
它和 `use` 的输入上下文预算分开:
|
|
179
179
|
|
|
180
180
|
```agentscript
|
|
181
|
-
use docs.summary
|
|
181
|
+
use docs.summary max 4k
|
|
182
182
|
|
|
183
183
|
generate({
|
|
184
|
-
input: "Answer from the selected docs"
|
|
184
|
+
input: "Answer from the selected docs",
|
|
185
185
|
max_output: 800
|
|
186
186
|
}) -> {
|
|
187
187
|
answer string
|
|
@@ -191,18 +191,18 @@ generate({
|
|
|
191
191
|
区别:
|
|
192
192
|
|
|
193
193
|
```text
|
|
194
|
-
use ...
|
|
194
|
+
use ... max 4k = 输入上下文预算
|
|
195
195
|
max_output: 800 = 输出生成预算
|
|
196
196
|
```
|
|
197
197
|
|
|
198
198
|
## `attempts`
|
|
199
199
|
|
|
200
|
-
`attempts`
|
|
200
|
+
`attempts` 控制 runtime 获取有效结构化结果的尝试次数。`attempts` 是最大总尝试次数,包含第一次尝试。
|
|
201
201
|
|
|
202
202
|
```agentscript
|
|
203
203
|
generate({
|
|
204
|
-
input: "Extract metadata"
|
|
205
|
-
max_output: 500
|
|
204
|
+
input: "Extract metadata",
|
|
205
|
+
max_output: 500,
|
|
206
206
|
attempts: 3
|
|
207
207
|
}) -> {
|
|
208
208
|
title string
|
|
@@ -242,8 +242,8 @@ attempts: 1
|
|
|
242
242
|
|
|
243
243
|
```agentscript
|
|
244
244
|
generate({
|
|
245
|
-
input: "Brainstorm alternatives"
|
|
246
|
-
max_output: 1000
|
|
245
|
+
input: "Brainstorm alternatives",
|
|
246
|
+
max_output: 1000,
|
|
247
247
|
temperature: 0.7
|
|
248
248
|
}) -> {
|
|
249
249
|
ideas list[string]
|
|
@@ -253,8 +253,8 @@ generate({
|
|
|
253
253
|
语义:
|
|
254
254
|
|
|
255
255
|
```text
|
|
256
|
-
|
|
257
|
-
|
|
256
|
+
如果选中的 provider/model 支持,则作为 sampling temperature 透传。
|
|
257
|
+
如果不支持,adapter 可以按照 capability policy 选择 ignore、warn 或 fail。
|
|
258
258
|
```
|
|
259
259
|
|
|
260
260
|
## `think`
|
|
@@ -264,11 +264,11 @@ If unsupported, adapter may ignore, warn, or fail according to capability policy
|
|
|
264
264
|
推荐支持:
|
|
265
265
|
|
|
266
266
|
```agentscript
|
|
267
|
-
think: false
|
|
268
|
-
think: true
|
|
269
|
-
think: "auto"
|
|
270
|
-
think: "low"
|
|
271
|
-
think: "medium"
|
|
267
|
+
think: false,
|
|
268
|
+
think: true,
|
|
269
|
+
think: "auto",
|
|
270
|
+
think: "low",
|
|
271
|
+
think: "medium",
|
|
272
272
|
think: "high"
|
|
273
273
|
```
|
|
274
274
|
|
|
@@ -287,8 +287,8 @@ true 请求 provider 默认 thinking/reasoning 模式
|
|
|
287
287
|
|
|
288
288
|
```agentscript
|
|
289
289
|
generate({
|
|
290
|
-
input: "Analyze the tradeoffs"
|
|
291
|
-
max_output: 1200
|
|
290
|
+
input: "Analyze the tradeoffs",
|
|
291
|
+
max_output: 1200,
|
|
292
292
|
think: "high"
|
|
293
293
|
}) -> {
|
|
294
294
|
decision string
|
|
@@ -297,20 +297,16 @@ generate({
|
|
|
297
297
|
}
|
|
298
298
|
```
|
|
299
299
|
|
|
300
|
-
`think` 是 provider/model capability hint
|
|
300
|
+
`think` 是 provider/model capability hint,不是所有模型都保证支持。如果不支持,adapter 可以按照 capability policy 选择 ignore、warn 或 fail。
|
|
301
301
|
|
|
302
|
-
|
|
302
|
+
## Provider hint 的 capability policy
|
|
303
303
|
|
|
304
|
-
|
|
305
|
-
ignore
|
|
306
|
-
warn
|
|
307
|
-
fail
|
|
308
|
-
```
|
|
304
|
+
`temperature` 和 `think` 都是 provider/model capability hint。不支持的 provider hint 默认在 debug mode 下 warn,否则 ignore。
|
|
309
305
|
|
|
310
|
-
|
|
306
|
+
Adapter 可以按照 runtime capability policy 对不支持的 hint 选择 ignore、warn 或 fail,但文档中的默认语义统一为:
|
|
311
307
|
|
|
312
308
|
```text
|
|
313
|
-
|
|
309
|
+
不支持的 provider hint 默认在 debug mode 下 warn,否则 ignore
|
|
314
310
|
```
|
|
315
311
|
|
|
316
312
|
## `strict`
|
|
@@ -319,8 +315,8 @@ warn in debug mode, otherwise ignore
|
|
|
319
315
|
|
|
320
316
|
```agentscript
|
|
321
317
|
generate({
|
|
322
|
-
input: "Classify the issue"
|
|
323
|
-
max_output: 300
|
|
318
|
+
input: "Classify the issue",
|
|
319
|
+
max_output: 300,
|
|
324
320
|
strict: true
|
|
325
321
|
}) -> {
|
|
326
322
|
category string
|
|
@@ -377,8 +373,8 @@ strict 是 AgentScript runtime 对输出契约的控制。
|
|
|
377
373
|
|
|
378
374
|
```agentscript
|
|
379
375
|
generate({
|
|
380
|
-
input: "Answer the question"
|
|
381
|
-
max_output: 800
|
|
376
|
+
input: "Answer the question",
|
|
377
|
+
max_output: 800,
|
|
382
378
|
debug: true
|
|
383
379
|
}) -> {
|
|
384
380
|
answer string
|
package/docs/cn/language.md
CHANGED
|
@@ -150,16 +150,18 @@ generate({ input: "Extract facts" }) -> {
|
|
|
150
150
|
|
|
151
151
|
Shape 不是完整的静态类型系统。
|
|
152
152
|
|
|
153
|
+
对象字面量使用 JSON-like 语法:字段写作 `key: value`,多字段之间必须用逗号分隔。
|
|
154
|
+
|
|
153
155
|
## 显式上下文(`use`)
|
|
154
156
|
|
|
155
157
|
`use` 选择在当前作用域及其子作用域中,后续 `generate` 可以包含哪些变量的值。
|
|
156
158
|
|
|
157
159
|
```agentscript
|
|
158
160
|
use input.question
|
|
159
|
-
use Requirements
|
|
160
|
-
use past_lessons
|
|
161
|
+
use Requirements max 4k
|
|
162
|
+
use past_lessons max 2k
|
|
161
163
|
use input.question as user
|
|
162
|
-
use docs.summary
|
|
164
|
+
use docs.summary max 4k as evidence
|
|
163
165
|
```
|
|
164
166
|
|
|
165
167
|
### 规则
|
|
@@ -168,9 +170,9 @@ use docs.summary < 4k as evidence
|
|
|
168
170
|
- 工具输出不会自动进入 prompt。
|
|
169
171
|
- Memory 查询结果不会自动进入 prompt。
|
|
170
172
|
- Trace 事件不会自动进入 prompt。
|
|
171
|
-
- `use value
|
|
173
|
+
- `use value max n` 应用上下文预算。
|
|
172
174
|
- `use value as label` 为选中的 context source 附加字面标签。
|
|
173
|
-
- `use value
|
|
175
|
+
- `use value max n as label` 先应用预算,再附加标签。
|
|
174
176
|
- `llm`、`tool`、`agent`、`memory` 绑定不能被 `use`。
|
|
175
177
|
- 函数绑定不能被 `use`。
|
|
176
178
|
- `use` 声明被子作用域继承。
|
|
@@ -181,7 +183,7 @@ use docs.summary < 4k as evidence
|
|
|
181
183
|
|
|
182
184
|
```agentscript
|
|
183
185
|
use docs as evidence
|
|
184
|
-
use docs.summary
|
|
186
|
+
use docs.summary max 4k as retrieved evidence
|
|
185
187
|
use input.question as user
|
|
186
188
|
```
|
|
187
189
|
|
|
@@ -189,7 +191,7 @@ use input.question as user
|
|
|
189
191
|
|
|
190
192
|
### 延迟求值
|
|
191
193
|
|
|
192
|
-
`use expr
|
|
194
|
+
`use expr max budget` 声明的是 context source,而不是当前值的快照。当 `generate` 构建 prompt 时,表达式会被重新求值。这意味着在 `use` 之后、`generate` 之前对变量的修改在生成时刻是可见的。
|
|
193
195
|
|
|
194
196
|
完整设计语义见 [`use ... as ...`](./use-as.md)。
|
|
195
197
|
|
|
@@ -199,9 +201,9 @@ use input.question as user
|
|
|
199
201
|
|
|
200
202
|
```agentscript
|
|
201
203
|
answer = generate({
|
|
202
|
-
input: "Answer using the selected context."
|
|
203
|
-
max_output: 800
|
|
204
|
-
attempts: 3
|
|
204
|
+
input: "Answer using the selected context.",
|
|
205
|
+
max_output: 800,
|
|
206
|
+
attempts: 3,
|
|
205
207
|
debug: true
|
|
206
208
|
}) -> {
|
|
207
209
|
ok boolean
|
|
@@ -214,13 +216,13 @@ answer = generate({
|
|
|
214
216
|
|
|
215
217
|
- `input`:每次生成的指令。必填。
|
|
216
218
|
- `max_output`:输出生成预算(数字或 `2k` 格式)。可选。
|
|
217
|
-
- `attempts`:JSON 解析失败或 shape
|
|
218
|
-
- `temperature`:provider sampling hint
|
|
219
|
-
- `think`:provider/model reasoning hint
|
|
219
|
+
- `attempts`:JSON 解析失败或 shape 不匹配时的尝试次数。它是包含第一次调用在内的最大总尝试次数。可选,默认 1。
|
|
220
|
+
- `temperature`:provider sampling hint。可选。不支持的 provider hint 默认在 debug mode 下 warn,否则 ignore。
|
|
221
|
+
- `think`:provider/model reasoning hint。可选。不支持的 provider hint 默认在 debug mode 下 warn,否则 ignore。
|
|
220
222
|
- `strict`:控制 shape validation 是否严格。可选,默认 false。
|
|
221
223
|
- `debug`:将完整 prompt 打印到 stderr。可选,默认 false。
|
|
222
224
|
- 可选的 `-> { ... }` 块声明期望的输出 shape。
|
|
223
|
-
- 不写 `-> { ... }` 时,`generate` 输出无约束:AgentScript 不会在 prompt 中加入返回 schema,不会要求 provider 使用结构化输出,也不会对返回值做类型强制转换或 shape
|
|
225
|
+
- 不写 `-> { ... }` 时,`generate` 输出无约束:AgentScript 不会在 prompt 中加入返回 schema,不会要求 provider 使用结构化输出,也不会对返回值做类型强制转换或 shape 校验。自由形式的 `generate` 是允许的,但不推荐用于 agent workflow。
|
|
224
226
|
- Provider 错误(认证、网络、超时、模型不存在)直接失败,不做重试。
|
|
225
227
|
- Shape 校验包含类型强制转换(如 `"true"` -> `true`,`"42"` -> `42`)。
|
|
226
228
|
|
|
@@ -238,14 +240,14 @@ if answer.ok and not input.dry_run {
|
|
|
238
240
|
}
|
|
239
241
|
```
|
|
240
242
|
|
|
241
|
-
|
|
243
|
+
支持的运算符:`==`、`!=`、`<`、`and`、`or`、`not`。Context budget 和循环上限使用 `max`,因此 `<` 恢复为类似 `==` 的普通比较运算符。
|
|
242
244
|
|
|
243
245
|
### Loop until
|
|
244
246
|
|
|
245
247
|
```agentscript
|
|
246
248
|
done = false
|
|
247
249
|
|
|
248
|
-
loop until done
|
|
250
|
+
loop until done max 6 {
|
|
249
251
|
observation = observe(input)
|
|
250
252
|
done = observation.ok
|
|
251
253
|
}
|
|
@@ -269,7 +271,7 @@ repeat * 3 {
|
|
|
269
271
|
### For in
|
|
270
272
|
|
|
271
273
|
```agentscript
|
|
272
|
-
for step in plan.steps
|
|
274
|
+
for step in plan.steps max 12 {
|
|
273
275
|
result = Executor(step)
|
|
274
276
|
results.add(result)
|
|
275
277
|
}
|
|
@@ -289,7 +291,7 @@ summary = items.summary
|
|
|
289
291
|
- `list[index]` 只读。index 必须是非负整数。
|
|
290
292
|
- `list.add(value)` 修改原列表。恰好接受一个参数。
|
|
291
293
|
- `.length` 返回列表长度。
|
|
292
|
-
- `.summary` 返回列表的 JSON-safe 运行时视图。它不是 LLM 生成的摘要,也不是语义压缩;如果需要控制 prompt 大小,应通过 `use scratch.summary
|
|
294
|
+
- `.summary` 返回列表的 JSON-safe 运行时视图。它不是 LLM 生成的摘要,也不是语义压缩;如果需要控制 prompt 大小,应通过 `use scratch.summary max 2k` 这类显式 context budget 裁剪。
|
|
293
295
|
|
|
294
296
|
## 工具
|
|
295
297
|
|
|
@@ -307,9 +309,9 @@ import tool Http from "https://api.example.com"
|
|
|
307
309
|
|
|
308
310
|
```agentscript
|
|
309
311
|
files = Find.run({
|
|
310
|
-
path: "."
|
|
311
|
-
name: "*.ts"
|
|
312
|
-
type: "file"
|
|
312
|
+
path: ".",
|
|
313
|
+
name: "*.ts",
|
|
314
|
+
type: "file",
|
|
313
315
|
max: 50
|
|
314
316
|
})
|
|
315
317
|
```
|
|
@@ -318,9 +320,9 @@ files = Find.run({
|
|
|
318
320
|
|
|
319
321
|
```agentscript
|
|
320
322
|
matches = Grep.run({
|
|
321
|
-
path: "src"
|
|
322
|
-
pattern: "TODO"
|
|
323
|
-
include: "*.ts"
|
|
323
|
+
path: "src",
|
|
324
|
+
pattern: "TODO",
|
|
325
|
+
include: "*.ts",
|
|
324
326
|
max: 100
|
|
325
327
|
})
|
|
326
328
|
```
|
|
@@ -329,8 +331,8 @@ matches = Grep.run({
|
|
|
329
331
|
|
|
330
332
|
```agentscript
|
|
331
333
|
lines = Sed.run({
|
|
332
|
-
path: "src/main.as"
|
|
333
|
-
start: 1
|
|
334
|
+
path: "src/main.as",
|
|
335
|
+
start: 1,
|
|
334
336
|
max: 20
|
|
335
337
|
})
|
|
336
338
|
```
|
|
@@ -338,10 +340,21 @@ lines = Sed.run({
|
|
|
338
340
|
### File
|
|
339
341
|
|
|
340
342
|
```agentscript
|
|
341
|
-
content = File.read({
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
343
|
+
content = File.read({
|
|
344
|
+
path: "README.md"
|
|
345
|
+
})
|
|
346
|
+
entries = File.list({
|
|
347
|
+
path: "src"
|
|
348
|
+
})
|
|
349
|
+
result = File.write({
|
|
350
|
+
path: "output.md",
|
|
351
|
+
content: "# Result"
|
|
352
|
+
})
|
|
353
|
+
result = File.patch({
|
|
354
|
+
path: "file.as",
|
|
355
|
+
search: "old",
|
|
356
|
+
replace: "new"
|
|
357
|
+
})
|
|
345
358
|
result = File.undo(effects)
|
|
346
359
|
```
|
|
347
360
|
|
|
@@ -350,14 +363,24 @@ result = File.undo(effects)
|
|
|
350
363
|
### Env
|
|
351
364
|
|
|
352
365
|
```agentscript
|
|
353
|
-
home = Env.get({
|
|
366
|
+
home = Env.get({
|
|
367
|
+
name: "HOME"
|
|
368
|
+
})
|
|
354
369
|
```
|
|
355
370
|
|
|
356
371
|
### Http
|
|
357
372
|
|
|
358
373
|
```agentscript
|
|
359
|
-
response = Http.get({
|
|
360
|
-
|
|
374
|
+
response = Http.get({
|
|
375
|
+
url: "/api/data",
|
|
376
|
+
headers: { Authorization: "Bearer ..." },
|
|
377
|
+
timeout: 10000
|
|
378
|
+
})
|
|
379
|
+
response = Http.post({
|
|
380
|
+
url: "/api/submit",
|
|
381
|
+
body: { key: "value" },
|
|
382
|
+
timeout: 10000
|
|
383
|
+
})
|
|
361
384
|
```
|
|
362
385
|
|
|
363
386
|
HTTP 请求限制在 import URI 的 origin 内。
|
|
@@ -387,7 +410,7 @@ import file Requirements from "./requirements.md"
|
|
|
387
410
|
import file Config from "./config.json"
|
|
388
411
|
|
|
389
412
|
func answer(input) {
|
|
390
|
-
use Requirements
|
|
413
|
+
use Requirements max 4k
|
|
391
414
|
use Config
|
|
392
415
|
generate({ input: "Answer from the referenced file." }) -> {
|
|
393
416
|
ok boolean
|
|
@@ -402,18 +425,18 @@ func answer(input) {
|
|
|
402
425
|
|
|
403
426
|
```agentscript
|
|
404
427
|
Lessons.add({
|
|
405
|
-
kind: "lesson"
|
|
406
|
-
text: reflection.insight
|
|
428
|
+
kind: "lesson",
|
|
429
|
+
text: reflection.insight,
|
|
407
430
|
goal: input.goal
|
|
408
431
|
})
|
|
409
432
|
|
|
410
433
|
past = Lessons.query({
|
|
411
|
-
kind: "lesson"
|
|
412
|
-
text: input.goal
|
|
434
|
+
kind: "lesson",
|
|
435
|
+
text: input.goal,
|
|
413
436
|
limit: 5
|
|
414
437
|
})
|
|
415
438
|
|
|
416
|
-
use past
|
|
439
|
+
use past max 2k
|
|
417
440
|
```
|
|
418
441
|
|
|
419
442
|
### 规则
|
|
@@ -437,8 +460,11 @@ main agent Controller {
|
|
|
437
460
|
main func(input) {
|
|
438
461
|
plan = Planner(input)
|
|
439
462
|
results = []
|
|
440
|
-
for step in plan.steps
|
|
441
|
-
result = Executor({
|
|
463
|
+
for step in plan.steps max 10 {
|
|
464
|
+
result = Executor({
|
|
465
|
+
goal: input.goal,
|
|
466
|
+
step: step
|
|
467
|
+
})
|
|
442
468
|
results.add(result)
|
|
443
469
|
}
|
|
444
470
|
results.summary
|