@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 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 < 2k as observations
10
- generate({ input: "Answer from observations" }) -> {
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({ path: input.path })
65
+ content = File.read({
66
+ path: input.path
67
+ })
64
68
  use input.path as source path
65
- use content < 8k as file 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 < 2k as observations
188
+ use scratch.summary max 2k as observations
185
189
 
186
190
  done = false
187
- loop until done < 6 {
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 < 2k as observations
200
- generate({ input: "Answer using only the observations" }) -> {
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
@@ -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("<") ? this.parseBudget() : undefined;
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.parseUnary(), "==", "!=");
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.match(",");
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.match(",");
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());
@@ -25,7 +25,8 @@ const KEYWORDS = new Set([
25
25
  "number",
26
26
  "boolean",
27
27
  "json",
28
- "list"
28
+ "list",
29
+ "max"
29
30
  ]);
30
31
  const SYMBOLS = new Set([
31
32
  "{",
@@ -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
  }
@@ -67,7 +67,7 @@ Agent 调用形成更强的边界。被调用 Agent 不会看到 caller 的 prom
67
67
 
68
68
  ```agentscript
69
69
  result = Worker({
70
- goal: input.goal
70
+ goal: input.goal,
71
71
  previous: results.summary
72
72
  })
73
73
  ```
@@ -47,8 +47,8 @@ agent 调用
47
47
  变量引用
48
48
  字段访问
49
49
  索引访问
50
- object literal
51
- list literal
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 < 8k
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
@@ -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 < 2k as observations
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 < 4k
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 ... < 4k = 输入上下文预算
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
- If supported by the selected provider/model, pass through as sampling temperature.
257
- If unsupported, adapter may ignore, warn, or fail according to capability policy.
256
+ 如果选中的 provider/model 支持,则作为 sampling temperature 透传。
257
+ 如果不支持,adapter 可以按照 capability policy 选择 ignorewarn 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
- 如果 provider 不支持,runtime 可按策略处理:
302
+ ## Provider hint 的 capability policy
303
303
 
304
- ```text
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
- warn in debug mode, otherwise ignore
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
@@ -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 < 4k
160
- use past_lessons < 2k
161
+ use Requirements max 4k
162
+ use past_lessons max 2k
161
163
  use input.question as user
162
- use docs.summary < 4k as evidence
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 < n` 应用上下文预算。
173
+ - `use value max n` 应用上下文预算。
172
174
  - `use value as label` 为选中的 context source 附加字面标签。
173
- - `use value < n as label` 先应用预算,再附加标签。
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 < 4k as retrieved evidence
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 < budget` 声明的是 context source,而不是当前值的快照。当 `generate` 构建 prompt 时,表达式会被重新求值。这意味着在 `use` 之后、`generate` 之前对变量的修改在生成时刻是可见的。
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 不匹配时的重试次数。可选,默认 1。
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
- 支持的运算符:`==`、`!=`、`and`、`or`、`not`。`<` 不是通用比较运算符——它只能用于预算和循环上限。
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 < 6 {
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 < 12 {
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 < 2k` 这类显式 context budget 裁剪。
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({ path: "README.md" })
342
- entries = File.list({ path: "src" })
343
- result = File.write({ path: "output.md", content: "# Result" })
344
- result = File.patch({ path: "file.as", search: "old", replace: "new" })
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({ name: "HOME" })
366
+ home = Env.get({
367
+ name: "HOME"
368
+ })
354
369
  ```
355
370
 
356
371
  ### Http
357
372
 
358
373
  ```agentscript
359
- response = Http.get({ url: "/api/data", headers: { Authorization: "Bearer ..." }, timeout: 10000 })
360
- response = Http.post({ url: "/api/submit", body: { key: "value" }, timeout: 10000 })
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 < 4k
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 < 2k
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 < 10 {
441
- result = Executor({ goal: input.goal, step: step })
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