@rong/agentscript 0.1.1 → 0.1.2
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 +13 -12
- package/dist/parser/parser.js +1 -2
- package/dist/providers/llm/anthropic.js +2 -1
- package/dist/providers/llm/ollama.js +5 -2
- package/dist/providers/llm/openai.js +7 -4
- package/dist/providers/mock/index.js +1 -1
- package/dist/runtime/context.js +5 -3
- package/dist/runtime/generate.js +4 -2
- package/dist/runtime/interpreter.js +7 -7
- package/dist/semantic/analyzer.js +3 -1
- package/docs/cn/context-engineering.md +7 -7
- package/docs/cn/final-expression-return.md +197 -0
- package/docs/cn/language.md +7 -6
- package/docs/design-history/v0-design.md +5 -5
- package/docs/design-history/v1-design.md +2 -2
- package/docs/design-history/v2-design.md +3 -3
- package/docs/en/context-engineering.md +6 -6
- package/docs/en/final-expression-return.md +197 -0
- package/docs/en/language.md +7 -6
- package/examples/changelog.as +1 -1
- package/examples/extract.as +1 -1
- package/examples/review.as +1 -1
- package/examples/summarize.as +1 -1
- package/examples/translate.as +1 -1
- package/package.json +1 -1
- package/tutorials/cli.as +1 -1
- package/tutorials/helloworld.as +1 -1
- package/tutorials/memory.as +1 -1
- package/tutorials/plan-execute.as +6 -6
- package/tutorials/react.as +6 -6
- package/tutorials/repl.as +1 -1
- package/tutorials/self-improve.as +2 -2
package/README.md
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
> **Agent context as code.**
|
|
4
4
|
> `use` declares what the model can see.
|
|
5
|
-
> `generate` defines the only LLM call site and
|
|
5
|
+
> `generate` defines the only LLM call site and optional output shape.
|
|
6
6
|
> Zero runtime dependencies. TypeScript-powered.
|
|
7
7
|
|
|
8
8
|
```agentscript
|
|
9
9
|
use scratch.summary < 2k
|
|
10
|
-
|
|
10
|
+
generate({ input: "Answer from observations" }) -> {
|
|
11
11
|
ok boolean
|
|
12
12
|
text string
|
|
13
13
|
}
|
|
@@ -64,7 +64,7 @@ main agent FileSummarizer {
|
|
|
64
64
|
use input.path
|
|
65
65
|
use content < 8k
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
generate({
|
|
68
68
|
input: "Summarize the file for a busy teammate"
|
|
69
69
|
limit: 1000
|
|
70
70
|
}) -> {
|
|
@@ -93,7 +93,7 @@ Expected output (with mock LLM):
|
|
|
93
93
|
|
|
94
94
|
With `--real-llm`, the fields are populated by the model.
|
|
95
95
|
|
|
96
|
-
The block after `generate` is
|
|
96
|
+
The optional block after `generate` is an output schema, not ordinary object construction.
|
|
97
97
|
|
|
98
98
|
## What problem it solves
|
|
99
99
|
|
|
@@ -113,7 +113,7 @@ It is a small language for one thing:
|
|
|
113
113
|
|
|
114
114
|
> making LLM prompt context explicit, scoped, typed, traceable, and compilable.
|
|
115
115
|
|
|
116
|
-
It gives you two things that general-purpose languages don't: a first-class `use` keyword that declares *which* data enters the LLM prompt, and a first-class `generate` expression that defines
|
|
116
|
+
It gives you two things that general-purpose languages don't: a first-class `use` keyword that declares *which* data enters the LLM prompt, and a first-class `generate` expression that defines an LLM call with an optional output contract. Everything else — variables, functions, agents, imports, loops — exists to support this core workflow. Scopes enforce context boundaries naturally: what's `use`d in one function stays there; child scopes inherit but never leak upward. Functions can also return their final top-level expression directly, which keeps typical LLM workflows concise.
|
|
117
117
|
|
|
118
118
|
## How it works
|
|
119
119
|
|
|
@@ -161,7 +161,7 @@ AgentScript doesn't hardcode agent patterns as keywords. You compose them from t
|
|
|
161
161
|
| **Reflection / Self-Improvement** | `tutorials/self-improve.as` | Query past lessons → generate → reflect → persist new lessons |
|
|
162
162
|
| **Multi-Agent** | `tutorials/plan-execute.as` | Independent agents with isolated context boundaries |
|
|
163
163
|
|
|
164
|
-
Every pattern is explicit — which data enters the prompt, which tools each agent can use, and which output shape each LLM call must satisfy.
|
|
164
|
+
Every pattern is explicit — which data enters the prompt, which tools each agent can use, and which output shape each LLM call must satisfy when one is declared.
|
|
165
165
|
|
|
166
166
|
## Language at a glance
|
|
167
167
|
|
|
@@ -191,13 +191,13 @@ main agent ResearchAgent {
|
|
|
191
191
|
done = enough(input.question, scratch)
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
answer(input.question, scratch)
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
func answer(question, scratch) {
|
|
198
198
|
use question
|
|
199
199
|
use scratch.summary < 2k
|
|
200
|
-
|
|
200
|
+
generate({ input: "Answer using only the observations" }) -> {
|
|
201
201
|
ok boolean
|
|
202
202
|
text string
|
|
203
203
|
error string
|
|
@@ -209,10 +209,11 @@ main agent ResearchAgent {
|
|
|
209
209
|
## Key ideas
|
|
210
210
|
|
|
211
211
|
1. **`use` is explicit context** — nothing enters the LLM prompt unless `use`d
|
|
212
|
-
2. **`generate` is the only LLM call site** — with a required input instruction and
|
|
213
|
-
3. **
|
|
214
|
-
4. **
|
|
215
|
-
5. **
|
|
212
|
+
2. **`generate` is the only LLM call site** — with a required input instruction and optional output shape
|
|
213
|
+
3. **Final expression return keeps flows concise** — a function returns its final top-level expression
|
|
214
|
+
4. **Scope is context boundary** — functions, agents, and blocks isolate prompt visibility
|
|
215
|
+
5. **Tools, memory, and files are imported resources** — with auditable access
|
|
216
|
+
6. **Trace is built in** — every `generate` and `use` is recorded for debugging
|
|
216
217
|
|
|
217
218
|
## Why not just Python or TypeScript?
|
|
218
219
|
|
package/dist/parser/parser.js
CHANGED
|
@@ -408,8 +408,7 @@ class Parser {
|
|
|
408
408
|
this.consume("(");
|
|
409
409
|
const options = this.parseGenerateOptions();
|
|
410
410
|
this.consume(")");
|
|
411
|
-
this.
|
|
412
|
-
const returnShape = this.parseShapeObject();
|
|
411
|
+
const returnShape = this.match("->") ? this.parseShapeObject() : undefined;
|
|
413
412
|
return {
|
|
414
413
|
kind: "GenerateExpr",
|
|
415
414
|
options,
|
|
@@ -19,7 +19,8 @@ export async function callAnthropic(request, parsed, options, fetchImpl, timeout
|
|
|
19
19
|
"x-api-key": apiKey,
|
|
20
20
|
"anthropic-version": "2023-06-01",
|
|
21
21
|
});
|
|
22
|
-
|
|
22
|
+
const text = readAnthropicText(response);
|
|
23
|
+
return request.returnShape ? parseJsonText(text) : text;
|
|
23
24
|
}
|
|
24
25
|
function readAnthropicText(value) {
|
|
25
26
|
if (!value || typeof value !== "object" || Array.isArray(value) || !Array.isArray(value.content)) {
|
|
@@ -4,16 +4,19 @@ export async function callOllama(request, parsed, fetchImpl, timeoutMs, baseUrl)
|
|
|
4
4
|
model: parsed.model,
|
|
5
5
|
stream: false,
|
|
6
6
|
think: false,
|
|
7
|
-
format: request.builtContext.returnSchema,
|
|
8
7
|
messages: [
|
|
9
8
|
{ role: "system", content: request.builtContext.system },
|
|
10
9
|
{ role: "user", content: request.builtContext.finalUserMessage },
|
|
11
10
|
],
|
|
12
11
|
};
|
|
12
|
+
if (request.builtContext.returnSchema) {
|
|
13
|
+
body.format = request.builtContext.returnSchema;
|
|
14
|
+
}
|
|
13
15
|
const maxTokens = budgetToTokenLimit(request);
|
|
14
16
|
if (maxTokens) {
|
|
15
17
|
body.options = { num_predict: maxTokens };
|
|
16
18
|
}
|
|
17
19
|
const response = await postJson(fetchImpl, `${baseUrl}/api/chat`, body, timeoutMs);
|
|
18
|
-
|
|
20
|
+
const text = readPath(response, ["message", "content"]);
|
|
21
|
+
return request.returnShape ? parseJsonText(text) : text;
|
|
19
22
|
}
|
|
@@ -11,15 +11,17 @@ export async function callOpenAI(request, parsed, options, fetchImpl, timeoutMs,
|
|
|
11
11
|
{ role: "system", content: request.builtContext.system },
|
|
12
12
|
{ role: "user", content: request.builtContext.finalUserMessage },
|
|
13
13
|
],
|
|
14
|
-
|
|
14
|
+
};
|
|
15
|
+
if (request.builtContext.returnSchema) {
|
|
16
|
+
body.response_format = {
|
|
15
17
|
type: "json_schema",
|
|
16
18
|
json_schema: {
|
|
17
19
|
name: "agentscript_generate",
|
|
18
20
|
strict: true,
|
|
19
21
|
schema: request.builtContext.returnSchema,
|
|
20
22
|
},
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
23
25
|
const maxTokens = budgetToTokenLimit(request);
|
|
24
26
|
if (maxTokens) {
|
|
25
27
|
body.max_completion_tokens = maxTokens;
|
|
@@ -27,5 +29,6 @@ export async function callOpenAI(request, parsed, options, fetchImpl, timeoutMs,
|
|
|
27
29
|
const response = await postJson(fetchImpl, `${baseUrl}/chat/completions`, body, timeoutMs, {
|
|
28
30
|
authorization: `Bearer ${apiKey}`,
|
|
29
31
|
});
|
|
30
|
-
|
|
32
|
+
const text = readPath(response, ["choices", 0, "message", "content"]);
|
|
33
|
+
return request.returnShape ? parseJsonText(text) : text;
|
|
31
34
|
}
|
|
@@ -2,7 +2,7 @@ import { sanitizeForJson } from "../../runtime/json.js";
|
|
|
2
2
|
import { buildValueFromShape } from "../../runtime/shape.js";
|
|
3
3
|
export class MockLlmProvider {
|
|
4
4
|
async generate(request) {
|
|
5
|
-
return buildValueFromShape(request.returnShape);
|
|
5
|
+
return request.returnShape ? buildValueFromShape(request.returnShape) : null;
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
export class MockToolProvider {
|
package/dist/runtime/context.js
CHANGED
|
@@ -4,7 +4,7 @@ export function buildContext(input) {
|
|
|
4
4
|
const instruction = sanitizeForJson(input.instruction);
|
|
5
5
|
const instructionText = renderJson(instruction);
|
|
6
6
|
const system = buildSystemPrompt(input.agentName, input.identity);
|
|
7
|
-
const returnSchema = shapeToSchema(input.returnShape);
|
|
7
|
+
const returnSchema = input.returnShape ? shapeToSchema(input.returnShape) : undefined;
|
|
8
8
|
return {
|
|
9
9
|
agentName: input.agentName,
|
|
10
10
|
model: input.model,
|
|
@@ -76,7 +76,9 @@ function buildFinalUserMessage(context, instructionText, returnSchema) {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
sections.push("Instruction:", instructionText);
|
|
79
|
-
|
|
79
|
+
if (returnSchema) {
|
|
80
|
+
sections.push("Return JSON matching this schema:", renderJson(returnSchema));
|
|
81
|
+
}
|
|
80
82
|
return sections.join("\n");
|
|
81
83
|
}
|
|
82
84
|
function renderJson(value) {
|
|
@@ -153,7 +155,7 @@ export function builtContextToJson(context) {
|
|
|
153
155
|
clippedSize: item.clippedSize,
|
|
154
156
|
})),
|
|
155
157
|
instruction: context.instruction,
|
|
156
|
-
returnSchema: context.returnSchema,
|
|
158
|
+
returnSchema: context.returnSchema ?? null,
|
|
157
159
|
budget: budgetToJson(context.budget),
|
|
158
160
|
finalUserMessage: context.finalUserMessage,
|
|
159
161
|
};
|
package/dist/runtime/generate.js
CHANGED
|
@@ -58,8 +58,10 @@ export class GenerateRuntime {
|
|
|
58
58
|
continue;
|
|
59
59
|
}
|
|
60
60
|
try {
|
|
61
|
-
const result = coerceValueToShape(rawResult, expr.returnShape);
|
|
62
|
-
|
|
61
|
+
const result = expr.returnShape ? coerceValueToShape(rawResult, expr.returnShape) : rawResult;
|
|
62
|
+
if (expr.returnShape) {
|
|
63
|
+
validateValueAgainstShape(result, expr.returnShape, expr.range);
|
|
64
|
+
}
|
|
63
65
|
this.trace.push({
|
|
64
66
|
kind: "generate",
|
|
65
67
|
data: {
|
|
@@ -151,11 +151,8 @@ class Interpreter {
|
|
|
151
151
|
this.callDepth += 1;
|
|
152
152
|
const scope = await this.buildFunctionScope(agent, fn, args);
|
|
153
153
|
try {
|
|
154
|
-
const signal = await this.executeBlock(fn.body, scope);
|
|
155
|
-
|
|
156
|
-
throw new RuntimeError(`Function '${agent.name}.${name}' completed without return`, fn.range);
|
|
157
|
-
}
|
|
158
|
-
return signal.value;
|
|
154
|
+
const signal = await this.executeBlock(fn.body, scope, true);
|
|
155
|
+
return signal?.value ?? null;
|
|
159
156
|
}
|
|
160
157
|
finally {
|
|
161
158
|
this.callDepth -= 1;
|
|
@@ -194,8 +191,11 @@ class Interpreter {
|
|
|
194
191
|
findFunction(agent, name) {
|
|
195
192
|
return agent.functions.find((fn) => fn.name === name);
|
|
196
193
|
}
|
|
197
|
-
async executeBlock(statements, scope) {
|
|
198
|
-
for (const stmt of statements) {
|
|
194
|
+
async executeBlock(statements, scope, allowFinalExpressionReturn = false) {
|
|
195
|
+
for (const [index, stmt] of statements.entries()) {
|
|
196
|
+
if (allowFinalExpressionReturn && index === statements.length - 1 && stmt.kind === "ExprStmt") {
|
|
197
|
+
return { kind: "return", value: await this.evaluator.evaluate(stmt.expr, scope) };
|
|
198
|
+
}
|
|
199
199
|
const result = await this.executeStatement(stmt, scope);
|
|
200
200
|
if (result)
|
|
201
201
|
return result;
|
|
@@ -366,7 +366,9 @@ class Analyzer {
|
|
|
366
366
|
this.checkExpression(expr.options.input, scope);
|
|
367
367
|
}
|
|
368
368
|
this.checkGenerateInput(expr);
|
|
369
|
-
|
|
369
|
+
if (expr.returnShape) {
|
|
370
|
+
this.checkShapeObject(expr.returnShape);
|
|
371
|
+
}
|
|
370
372
|
this.checkGenerateConfig("model", expr, scope);
|
|
371
373
|
this.checkGenerateConfig("role", expr, scope);
|
|
372
374
|
this.checkGenerateConfig("description", expr, scope);
|
|
@@ -32,7 +32,7 @@ func answer(question, scratch) {
|
|
|
32
32
|
use question
|
|
33
33
|
use scratch.summary < 2k
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
generate({
|
|
36
36
|
input: "Answer the question using collected facts"
|
|
37
37
|
limit: 800
|
|
38
38
|
}) -> {
|
|
@@ -61,7 +61,7 @@ main func(input) {
|
|
|
61
61
|
scratch.add({ fact: "A" })
|
|
62
62
|
scratch.add({ fact: "B" })
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
generate({ input: "Answer from scratch" }) -> {
|
|
65
65
|
text string
|
|
66
66
|
}
|
|
67
67
|
}
|
|
@@ -119,12 +119,12 @@ AgentScript 中的作用域不仅是变量可见性规则,也是 prompt contex
|
|
|
119
119
|
```agentscript
|
|
120
120
|
func caller(input) {
|
|
121
121
|
use input.goal
|
|
122
|
-
|
|
122
|
+
helper(input)
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
func helper(input) {
|
|
126
126
|
use input.detail
|
|
127
|
-
|
|
127
|
+
generate({ input: "Work on detail" }) -> {
|
|
128
128
|
ok boolean
|
|
129
129
|
}
|
|
130
130
|
}
|
|
@@ -235,10 +235,10 @@ Instruction 是本次 LLM 调用的局部任务,不应混入长期 context。
|
|
|
235
235
|
|
|
236
236
|
### Output contract
|
|
237
237
|
|
|
238
|
-
Output contract 来自 `
|
|
238
|
+
Output contract 来自 `generate` 表达式上可选的 `-> { ... }` shape。
|
|
239
239
|
|
|
240
240
|
```agentscript
|
|
241
|
-
|
|
241
|
+
generate({ input: "Answer" }) -> {
|
|
242
242
|
ok boolean
|
|
243
243
|
text string
|
|
244
244
|
error string
|
|
@@ -260,7 +260,7 @@ use scratch.summary < 2k
|
|
|
260
260
|
`generate({ limit: budget }) { ... }` 是 generation budget。
|
|
261
261
|
|
|
262
262
|
```agentscript
|
|
263
|
-
|
|
263
|
+
generate({
|
|
264
264
|
input: "Summarize"
|
|
265
265
|
limit: 500
|
|
266
266
|
}) -> {
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# AgentScript 隐式返回规范草案
|
|
2
|
+
|
|
3
|
+
本文档描述 AgentScript 函数的隐式返回规则草案。
|
|
4
|
+
|
|
5
|
+
## 1. 基本规则
|
|
6
|
+
|
|
7
|
+
函数体最后一个顶层表达式可以作为函数返回值。
|
|
8
|
+
|
|
9
|
+
```agentscript
|
|
10
|
+
func answer(input) {
|
|
11
|
+
use input.question
|
|
12
|
+
|
|
13
|
+
generate({ input: "Answer the question" }) -> {
|
|
14
|
+
ok boolean
|
|
15
|
+
answer string
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
等价于:
|
|
21
|
+
|
|
22
|
+
```agentscript
|
|
23
|
+
func answer(input) {
|
|
24
|
+
use input.question
|
|
25
|
+
|
|
26
|
+
return generate({ input: "Answer the question" }) -> {
|
|
27
|
+
ok boolean
|
|
28
|
+
answer string
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
这个规则称为:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
final expression return
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 2. 可隐式返回的表达式
|
|
40
|
+
|
|
41
|
+
允许最后一行隐式返回以下表达式形式:
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
generate(...) -> shape
|
|
45
|
+
普通函数调用
|
|
46
|
+
agent 调用
|
|
47
|
+
变量引用
|
|
48
|
+
字段访问
|
|
49
|
+
索引访问
|
|
50
|
+
object literal
|
|
51
|
+
list literal
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
例如:
|
|
55
|
+
|
|
56
|
+
```agentscript
|
|
57
|
+
func run(input) {
|
|
58
|
+
Worker(input)
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```agentscript
|
|
63
|
+
func get_result(result) {
|
|
64
|
+
result.value
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```agentscript
|
|
69
|
+
func observe(action) {
|
|
70
|
+
{
|
|
71
|
+
facts: [action.summary],
|
|
72
|
+
source: action.source
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 3. 不可隐式返回的语句
|
|
78
|
+
|
|
79
|
+
下面这些不是表达式,不参与隐式返回:
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
use 声明
|
|
83
|
+
赋值语句
|
|
84
|
+
import
|
|
85
|
+
loop
|
|
86
|
+
repeat
|
|
87
|
+
for
|
|
88
|
+
if/else,早期版本可先不表达式化
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
例如:
|
|
92
|
+
|
|
93
|
+
```agentscript
|
|
94
|
+
func bad(input) {
|
|
95
|
+
use input.question
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
这里没有返回表达式,函数返回 `none`,或由 semantic analyzer 给出 warning。
|
|
100
|
+
|
|
101
|
+
赋值也不返回:
|
|
102
|
+
|
|
103
|
+
```agentscript
|
|
104
|
+
func f() {
|
|
105
|
+
x = answer()
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
如果要返回,需要写:
|
|
110
|
+
|
|
111
|
+
```agentscript
|
|
112
|
+
func f() {
|
|
113
|
+
x = answer()
|
|
114
|
+
x
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## 4. 显式 `return` 优先
|
|
119
|
+
|
|
120
|
+
显式 `return` 仍然合法,并且在复杂控制流中推荐使用。
|
|
121
|
+
|
|
122
|
+
```agentscript
|
|
123
|
+
func answer(input) {
|
|
124
|
+
if input.dry_run {
|
|
125
|
+
return {
|
|
126
|
+
ok: false,
|
|
127
|
+
answer: "dry run"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
generate({ input: "Answer" }) -> {
|
|
132
|
+
ok boolean
|
|
133
|
+
answer string
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## 5. 无返回值
|
|
139
|
+
|
|
140
|
+
如果函数没有显式 `return`,最后一行也不是可返回表达式,则返回:
|
|
141
|
+
|
|
142
|
+
```agentscript
|
|
143
|
+
none
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
可以显式写:
|
|
147
|
+
|
|
148
|
+
```agentscript
|
|
149
|
+
return none
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
用于表达“此函数只产生副作用”。
|
|
153
|
+
|
|
154
|
+
## 6. 推荐风格
|
|
155
|
+
|
|
156
|
+
对于典型 LLM 调用,推荐省略 `return`:
|
|
157
|
+
|
|
158
|
+
```agentscript
|
|
159
|
+
func summarize(content) {
|
|
160
|
+
use content < 8k
|
|
161
|
+
|
|
162
|
+
generate({
|
|
163
|
+
input: "Summarize the content"
|
|
164
|
+
limit: 1000
|
|
165
|
+
}) -> {
|
|
166
|
+
title string
|
|
167
|
+
summary string
|
|
168
|
+
key_points list[string]
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
对于分支、提前退出、错误处理,推荐使用显式 `return`:
|
|
174
|
+
|
|
175
|
+
```agentscript
|
|
176
|
+
func answer(input) {
|
|
177
|
+
if not input.question {
|
|
178
|
+
return {
|
|
179
|
+
ok: false,
|
|
180
|
+
answer: ""
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
use input.question
|
|
185
|
+
|
|
186
|
+
generate({ input: "Answer the question" }) -> {
|
|
187
|
+
ok boolean
|
|
188
|
+
answer string
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## 一句话定义
|
|
194
|
+
|
|
195
|
+
```text
|
|
196
|
+
A function returns the value of its final top-level expression when no explicit return is reached.
|
|
197
|
+
```
|
package/docs/cn/language.md
CHANGED
|
@@ -27,7 +27,7 @@ main agent Assistant {
|
|
|
27
27
|
question string
|
|
28
28
|
}) {
|
|
29
29
|
use input.question
|
|
30
|
-
|
|
30
|
+
generate({ input: "Answer the question" }) -> {
|
|
31
31
|
ok boolean
|
|
32
32
|
answer string
|
|
33
33
|
}
|
|
@@ -138,7 +138,7 @@ func careful(input) {
|
|
|
138
138
|
Shape 用于输入校验和 `generate` 输出校验:
|
|
139
139
|
|
|
140
140
|
```agentscript
|
|
141
|
-
|
|
141
|
+
generate({ input: "Extract facts" }) -> {
|
|
142
142
|
ok boolean
|
|
143
143
|
title string
|
|
144
144
|
items list[json]
|
|
@@ -177,7 +177,7 @@ use past_lessons < 2k
|
|
|
177
177
|
|
|
178
178
|
## Generate
|
|
179
179
|
|
|
180
|
-
`generate` 调用当前模型,需要 `input`
|
|
180
|
+
`generate` 调用当前模型,需要 `input` 指令。返回 shape 是可选的。
|
|
181
181
|
|
|
182
182
|
```agentscript
|
|
183
183
|
answer = generate({
|
|
@@ -198,7 +198,8 @@ answer = generate({
|
|
|
198
198
|
- `limit`:生成预算(数字或 `2k` 格式)。可选。
|
|
199
199
|
- `attempts`:JSON 解析失败或 shape 不匹配时的重试次数。可选,默认 1。
|
|
200
200
|
- `debug`:将完整 prompt 打印到 stderr。可选,默认 false。
|
|
201
|
-
- `-> { ... }` 块声明期望的输出 shape。
|
|
201
|
+
- 可选的 `-> { ... }` 块声明期望的输出 shape。
|
|
202
|
+
- 不写 `-> { ... }` 时,`generate` 输出无约束:AgentScript 不会在 prompt 中加入返回 schema,不会要求 provider 使用结构化输出,也不会对返回值做类型强制转换或 shape 校验。
|
|
202
203
|
- Provider 错误(认证、网络、超时、模型不存在)直接失败,不做重试。
|
|
203
204
|
- Shape 校验包含类型强制转换(如 `"true"` -> `true`,`"42"` -> `42`)。
|
|
204
205
|
|
|
@@ -365,7 +366,7 @@ import file Config from "./config.json"
|
|
|
365
366
|
func answer(input) {
|
|
366
367
|
use Requirements < 4k
|
|
367
368
|
use Config
|
|
368
|
-
|
|
369
|
+
generate({ input: "Answer from the referenced file." }) -> {
|
|
369
370
|
ok boolean
|
|
370
371
|
answer string
|
|
371
372
|
}
|
|
@@ -417,7 +418,7 @@ main agent Controller {
|
|
|
417
418
|
result = Executor({ goal: input.goal, step: step })
|
|
418
419
|
results.add(result)
|
|
419
420
|
}
|
|
420
|
-
|
|
421
|
+
results.summary
|
|
421
422
|
}
|
|
422
423
|
}
|
|
423
424
|
```
|
|
@@ -50,13 +50,13 @@ main agent ResearchAgent {
|
|
|
50
50
|
question string
|
|
51
51
|
}) {
|
|
52
52
|
use input.question
|
|
53
|
-
|
|
53
|
+
answer(input.question)
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
func answer(question) {
|
|
57
57
|
use question
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
generate({ input: "Answer the question" }) -> {
|
|
60
60
|
ok boolean
|
|
61
61
|
text string
|
|
62
62
|
}
|
|
@@ -103,7 +103,7 @@ agent A {
|
|
|
103
103
|
model Strong
|
|
104
104
|
description "Use a stronger model for this function."
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
generate({ input: "Answer carefully" }) -> {
|
|
107
107
|
text string
|
|
108
108
|
}
|
|
109
109
|
}
|
|
@@ -130,7 +130,7 @@ V0 运行时数据以 JSON 为核心:
|
|
|
130
130
|
`generate` 返回 shape 使用轻量标注:
|
|
131
131
|
|
|
132
132
|
```agentscript
|
|
133
|
-
|
|
133
|
+
generate({ input: "Extract facts" }) -> {
|
|
134
134
|
facts list[string]
|
|
135
135
|
source string
|
|
136
136
|
meta json
|
|
@@ -149,7 +149,7 @@ func compose(question, scratch) {
|
|
|
149
149
|
use question
|
|
150
150
|
use scratch.summary < 2k
|
|
151
151
|
|
|
152
|
-
|
|
152
|
+
generate({ input: "Answer using only the context" }) -> {
|
|
153
153
|
ok boolean
|
|
154
154
|
text string
|
|
155
155
|
}
|
|
@@ -113,7 +113,7 @@ for item in list < n {
|
|
|
113
113
|
V1 不需要专门的 `plan` 类型。推荐结构:
|
|
114
114
|
|
|
115
115
|
```agentscript
|
|
116
|
-
|
|
116
|
+
generate({ input: "Create a short executable plan" }) -> {
|
|
117
117
|
steps list[json]
|
|
118
118
|
}
|
|
119
119
|
```
|
|
@@ -278,7 +278,7 @@ func answer(input) {
|
|
|
278
278
|
use Requirements < 4k
|
|
279
279
|
use input.question
|
|
280
280
|
|
|
281
|
-
|
|
281
|
+
generate({ input: "Answer from the referenced file" }) -> {
|
|
282
282
|
ok boolean
|
|
283
283
|
text string
|
|
284
284
|
}
|
|
@@ -210,7 +210,7 @@ agent Reflector {
|
|
|
210
210
|
main func(input) {
|
|
211
211
|
use input
|
|
212
212
|
|
|
213
|
-
|
|
213
|
+
generate({
|
|
214
214
|
input: "Extract one reusable lesson from this run.",
|
|
215
215
|
attempts: 3
|
|
216
216
|
}) -> {
|
|
@@ -286,13 +286,13 @@ main agent Learner {
|
|
|
286
286
|
ok: result.ok
|
|
287
287
|
})
|
|
288
288
|
|
|
289
|
-
|
|
289
|
+
result
|
|
290
290
|
}
|
|
291
291
|
|
|
292
292
|
func reflect(run) {
|
|
293
293
|
use run
|
|
294
294
|
|
|
295
|
-
|
|
295
|
+
generate({
|
|
296
296
|
input: "Extract one reusable lesson from this run.",
|
|
297
297
|
attempts: 3
|
|
298
298
|
}) -> {
|
|
@@ -30,7 +30,7 @@ func answer(question, scratch) {
|
|
|
30
30
|
use question
|
|
31
31
|
use scratch.summary < 2k
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
generate({
|
|
34
34
|
input: "Answer the question using collected facts"
|
|
35
35
|
limit: 800
|
|
36
36
|
}) -> {
|
|
@@ -55,7 +55,7 @@ main func(input) {
|
|
|
55
55
|
scratch.add({ fact: "A" })
|
|
56
56
|
scratch.add({ fact: "B" })
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
generate({ input: "Answer from scratch" }) -> {
|
|
59
59
|
text string
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -99,12 +99,12 @@ Each function call creates an independent context boundary.
|
|
|
99
99
|
```agentscript
|
|
100
100
|
func caller(input) {
|
|
101
101
|
use input.goal
|
|
102
|
-
|
|
102
|
+
helper(input)
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
func helper(input) {
|
|
106
106
|
use input.detail
|
|
107
|
-
|
|
107
|
+
generate({ input: "Work on detail" }) -> {
|
|
108
108
|
ok boolean
|
|
109
109
|
}
|
|
110
110
|
}
|
|
@@ -207,10 +207,10 @@ The instruction is the per-call task. `limit`, `attempts`, and `debug` are local
|
|
|
207
207
|
|
|
208
208
|
### Output contract
|
|
209
209
|
|
|
210
|
-
Comes from
|
|
210
|
+
Comes from the optional `-> { ... }` shape on a `generate` expression.
|
|
211
211
|
|
|
212
212
|
```agentscript
|
|
213
|
-
|
|
213
|
+
generate({ input: "Answer" }) -> {
|
|
214
214
|
ok boolean
|
|
215
215
|
text string
|
|
216
216
|
error string
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# AgentScript Final Expression Return
|
|
2
|
+
|
|
3
|
+
This document describes the implicit return rule for AgentScript functions.
|
|
4
|
+
|
|
5
|
+
## 1. Basic rule
|
|
6
|
+
|
|
7
|
+
The final top-level expression in a function body can be used as the function return value.
|
|
8
|
+
|
|
9
|
+
```agentscript
|
|
10
|
+
func answer(input) {
|
|
11
|
+
use input.question
|
|
12
|
+
|
|
13
|
+
generate({ input: "Answer the question" }) -> {
|
|
14
|
+
ok boolean
|
|
15
|
+
answer string
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
This is equivalent to:
|
|
21
|
+
|
|
22
|
+
```agentscript
|
|
23
|
+
func answer(input) {
|
|
24
|
+
use input.question
|
|
25
|
+
|
|
26
|
+
return generate({ input: "Answer the question" }) -> {
|
|
27
|
+
ok boolean
|
|
28
|
+
answer string
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This rule is called:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
final expression return
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 2. Expressions that can be implicitly returned
|
|
40
|
+
|
|
41
|
+
The final line can implicitly return these expression forms:
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
generate(...) -> shape
|
|
45
|
+
regular function call
|
|
46
|
+
agent call
|
|
47
|
+
variable reference
|
|
48
|
+
field access
|
|
49
|
+
index access
|
|
50
|
+
object literal
|
|
51
|
+
list literal
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Examples:
|
|
55
|
+
|
|
56
|
+
```agentscript
|
|
57
|
+
func run(input) {
|
|
58
|
+
Worker(input)
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```agentscript
|
|
63
|
+
func get_result(result) {
|
|
64
|
+
result.value
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```agentscript
|
|
69
|
+
func observe(action) {
|
|
70
|
+
{
|
|
71
|
+
facts: [action.summary],
|
|
72
|
+
source: action.source
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 3. Statements that cannot be implicitly returned
|
|
78
|
+
|
|
79
|
+
The following constructs are not expressions and do not participate in final expression return:
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
use declaration
|
|
83
|
+
assignment statement
|
|
84
|
+
import
|
|
85
|
+
loop
|
|
86
|
+
repeat
|
|
87
|
+
for
|
|
88
|
+
if/else, which can remain non-expression syntax in early versions
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Example:
|
|
92
|
+
|
|
93
|
+
```agentscript
|
|
94
|
+
func bad(input) {
|
|
95
|
+
use input.question
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
This function has no return expression. It returns `none`, or the semantic analyzer may report a warning.
|
|
100
|
+
|
|
101
|
+
Assignment also does not return a value:
|
|
102
|
+
|
|
103
|
+
```agentscript
|
|
104
|
+
func f() {
|
|
105
|
+
x = answer()
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
To return the assigned value, write:
|
|
110
|
+
|
|
111
|
+
```agentscript
|
|
112
|
+
func f() {
|
|
113
|
+
x = answer()
|
|
114
|
+
x
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## 4. Explicit `return` takes priority
|
|
119
|
+
|
|
120
|
+
Explicit `return` remains valid and is recommended for complex control flow.
|
|
121
|
+
|
|
122
|
+
```agentscript
|
|
123
|
+
func answer(input) {
|
|
124
|
+
if input.dry_run {
|
|
125
|
+
return {
|
|
126
|
+
ok: false,
|
|
127
|
+
answer: "dry run"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
generate({ input: "Answer" }) -> {
|
|
132
|
+
ok boolean
|
|
133
|
+
answer string
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## 5. No return value
|
|
139
|
+
|
|
140
|
+
If a function has no explicit `return` and its final line is not a returnable expression, it returns:
|
|
141
|
+
|
|
142
|
+
```agentscript
|
|
143
|
+
none
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
This can also be written explicitly:
|
|
147
|
+
|
|
148
|
+
```agentscript
|
|
149
|
+
return none
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Use this form to express that a function only produces side effects.
|
|
153
|
+
|
|
154
|
+
## 6. Recommended style
|
|
155
|
+
|
|
156
|
+
For typical LLM calls, omit `return`:
|
|
157
|
+
|
|
158
|
+
```agentscript
|
|
159
|
+
func summarize(content) {
|
|
160
|
+
use content < 8k
|
|
161
|
+
|
|
162
|
+
generate({
|
|
163
|
+
input: "Summarize the content"
|
|
164
|
+
limit: 1000
|
|
165
|
+
}) -> {
|
|
166
|
+
title string
|
|
167
|
+
summary string
|
|
168
|
+
key_points list[string]
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
For branches, early exits, and error handling, use explicit `return`:
|
|
174
|
+
|
|
175
|
+
```agentscript
|
|
176
|
+
func answer(input) {
|
|
177
|
+
if not input.question {
|
|
178
|
+
return {
|
|
179
|
+
ok: false,
|
|
180
|
+
answer: ""
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
use input.question
|
|
185
|
+
|
|
186
|
+
generate({ input: "Answer the question" }) -> {
|
|
187
|
+
ok boolean
|
|
188
|
+
answer string
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## One-sentence definition
|
|
194
|
+
|
|
195
|
+
```text
|
|
196
|
+
A function returns the value of its final top-level expression when no explicit return is reached.
|
|
197
|
+
```
|
package/docs/en/language.md
CHANGED
|
@@ -27,7 +27,7 @@ main agent Assistant {
|
|
|
27
27
|
question string
|
|
28
28
|
}) {
|
|
29
29
|
use input.question
|
|
30
|
-
|
|
30
|
+
generate({ input: "Answer the question" }) -> {
|
|
31
31
|
ok boolean
|
|
32
32
|
answer string
|
|
33
33
|
}
|
|
@@ -138,7 +138,7 @@ Runtime values are JSON-oriented:
|
|
|
138
138
|
Shapes are used for input validation and `generate` output validation:
|
|
139
139
|
|
|
140
140
|
```agentscript
|
|
141
|
-
|
|
141
|
+
generate({ input: "Extract facts" }) -> {
|
|
142
142
|
ok boolean
|
|
143
143
|
title string
|
|
144
144
|
items list[json]
|
|
@@ -177,7 +177,7 @@ use past_lessons < 2k
|
|
|
177
177
|
|
|
178
178
|
## Generate
|
|
179
179
|
|
|
180
|
-
`generate` calls the current model and requires an `input` instruction
|
|
180
|
+
`generate` calls the current model and requires an `input` instruction. A return shape is optional.
|
|
181
181
|
|
|
182
182
|
```agentscript
|
|
183
183
|
answer = generate({
|
|
@@ -198,7 +198,8 @@ answer = generate({
|
|
|
198
198
|
- `limit` is the generation budget (number or `2k` style). Optional.
|
|
199
199
|
- `attempts` controls retry for JSON parse errors or shape mismatch. Optional, defaults to 1.
|
|
200
200
|
- `debug` prints the full prompt to stderr. Optional, defaults to false.
|
|
201
|
-
- The `-> { ... }` block declares the expected output shape.
|
|
201
|
+
- The optional `-> { ... }` block declares the expected output shape.
|
|
202
|
+
- Without `-> { ... }`, the generate output is unconstrained: AgentScript does not add a return schema to the prompt, does not request provider structured output, and does not coerce or validate the returned value.
|
|
202
203
|
- Provider errors (auth, network, timeout, missing model) fail directly without retry.
|
|
203
204
|
- Shape validation includes coercion (e.g. `"true"` -> `true`, `"42"` -> `42`).
|
|
204
205
|
|
|
@@ -365,7 +366,7 @@ import file Config from "./config.json"
|
|
|
365
366
|
func answer(input) {
|
|
366
367
|
use Requirements < 4k
|
|
367
368
|
use Config
|
|
368
|
-
|
|
369
|
+
generate({ input: "Answer from the referenced file." }) -> {
|
|
369
370
|
ok boolean
|
|
370
371
|
answer string
|
|
371
372
|
}
|
|
@@ -417,7 +418,7 @@ main agent Controller {
|
|
|
417
418
|
result = Executor({ goal: input.goal, step: step })
|
|
418
419
|
results.add(result)
|
|
419
420
|
}
|
|
420
|
-
|
|
421
|
+
results.summary
|
|
421
422
|
}
|
|
422
423
|
}
|
|
423
424
|
```
|
package/examples/changelog.as
CHANGED
|
@@ -16,7 +16,7 @@ main agent ChangelogWriter {
|
|
|
16
16
|
use input.diff_path
|
|
17
17
|
use diff < 10k
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
generate({ input: "Write a changelog from this git diff", limit: 1200 }) -> {
|
|
20
20
|
title string
|
|
21
21
|
highlights list[string]
|
|
22
22
|
breaking_changes list[string]
|
package/examples/extract.as
CHANGED
|
@@ -17,7 +17,7 @@ main agent ApiExtractor {
|
|
|
17
17
|
use input.url
|
|
18
18
|
use response < 8k
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
generate({ input: "Extract normalized data from the API response", limit: 1200 }) -> {
|
|
21
21
|
records list[json]
|
|
22
22
|
fields list[string]
|
|
23
23
|
warnings list[string]
|
package/examples/review.as
CHANGED
|
@@ -26,7 +26,7 @@ main agent CodeReviewAssistant {
|
|
|
26
26
|
use todos < 4k
|
|
27
27
|
use fixmes < 4k
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
generate({ input: "Turn TODO and FIXME scan results into prioritized repair suggestions", limit: 1200 }) -> {
|
|
30
30
|
summary string
|
|
31
31
|
findings list[string]
|
|
32
32
|
suggested_fixes list[string]
|
package/examples/summarize.as
CHANGED
|
@@ -16,7 +16,7 @@ main agent FileSummarizer {
|
|
|
16
16
|
use input.path
|
|
17
17
|
use content < 8k
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
generate({ input: "Summarize the file for a busy teammate", limit: 1000 }) -> {
|
|
20
20
|
title string
|
|
21
21
|
summary string
|
|
22
22
|
key_points list[string]
|
package/examples/translate.as
CHANGED
|
@@ -21,7 +21,7 @@ main agent MarkdownTranslator {
|
|
|
21
21
|
use input.target_language
|
|
22
22
|
use files < 4k
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
generate({ input: "Create a practical markdown translation plan", limit: 1000 }) -> {
|
|
25
25
|
target_language string
|
|
26
26
|
files list[string]
|
|
27
27
|
glossary_notes list[string]
|
package/package.json
CHANGED
package/tutorials/cli.as
CHANGED
package/tutorials/helloworld.as
CHANGED
package/tutorials/memory.as
CHANGED
|
@@ -44,7 +44,7 @@ main agent PlanAndExecute {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
finish(input.goal, results)
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
func run_step(goal, step, previous) {
|
|
@@ -60,7 +60,7 @@ main agent PlanAndExecute {
|
|
|
60
60
|
result: result
|
|
61
61
|
})
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
{
|
|
64
64
|
ok: verdict.ok,
|
|
65
65
|
reason: verdict.reason,
|
|
66
66
|
result: {
|
|
@@ -75,7 +75,7 @@ main agent PlanAndExecute {
|
|
|
75
75
|
use goal
|
|
76
76
|
use results.summary < 2k
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
generate({ input: "Create the final answer from executed steps", limit: 800 }) -> {
|
|
79
79
|
ok boolean
|
|
80
80
|
text string
|
|
81
81
|
error string
|
|
@@ -93,7 +93,7 @@ agent Planner {
|
|
|
93
93
|
use input.problem
|
|
94
94
|
use input.previous < 1k
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
generate({ input: "Create a three step plan", limit: 600 }) -> {
|
|
97
97
|
step1 string
|
|
98
98
|
step2 string
|
|
99
99
|
step3 string
|
|
@@ -121,7 +121,7 @@ agent Executor {
|
|
|
121
121
|
|
|
122
122
|
use observation
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
generate({ input: "Report the result of this step", limit: 500 }) -> {
|
|
125
125
|
ok boolean
|
|
126
126
|
output json
|
|
127
127
|
error string
|
|
@@ -139,7 +139,7 @@ agent Verifier {
|
|
|
139
139
|
use input.step
|
|
140
140
|
use input.result
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
generate({ input: "Verify this step result", limit: 300 }) -> {
|
|
143
143
|
ok boolean
|
|
144
144
|
reason string
|
|
145
145
|
}
|
package/tutorials/react.as
CHANGED
|
@@ -25,14 +25,14 @@ main agent ResearchAgent {
|
|
|
25
25
|
done = enough(input.question, scratch)
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
answer(input.question, scratch)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
func reason(question, scratch) {
|
|
32
32
|
use question
|
|
33
33
|
use scratch.summary < 1k
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
generate({ input: "Choose the next search focus", limit: 300 }) -> {
|
|
36
36
|
focus string
|
|
37
37
|
why string
|
|
38
38
|
}
|
|
@@ -42,7 +42,7 @@ main agent ResearchAgent {
|
|
|
42
42
|
raw_query = Search.query(question, thought)
|
|
43
43
|
raw_result = Search.search(raw_query)
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
{
|
|
46
46
|
query: raw_query.summary,
|
|
47
47
|
result: {
|
|
48
48
|
summary: raw_result.summary,
|
|
@@ -60,7 +60,7 @@ main agent ResearchAgent {
|
|
|
60
60
|
|
|
61
61
|
use raw
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
generate({ input: "Summarize the useful observation", limit: 400 }) -> {
|
|
64
64
|
facts list[string]
|
|
65
65
|
source string
|
|
66
66
|
}
|
|
@@ -74,14 +74,14 @@ main agent ResearchAgent {
|
|
|
74
74
|
done boolean
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
verdict.done
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
func answer(question, scratch) {
|
|
81
81
|
use question
|
|
82
82
|
use scratch.summary < 2k
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
generate({ input: "Answer using only the observations", limit: 800 }) -> {
|
|
85
85
|
ok boolean
|
|
86
86
|
text string
|
|
87
87
|
error string
|
package/tutorials/repl.as
CHANGED
|
@@ -40,13 +40,13 @@ main agent SelfImprover {
|
|
|
40
40
|
ok: result.ok
|
|
41
41
|
})
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
result
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
func reflect(run) {
|
|
47
47
|
use run
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
generate({
|
|
50
50
|
input: "Extract one durable lesson that could improve a future run.",
|
|
51
51
|
attempts: 3
|
|
52
52
|
}) -> {
|