@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.
Files changed (77) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/INSTALL.md +92 -0
  3. package/LICENSE +21 -0
  4. package/README.md +246 -0
  5. package/dist/ast/constants.js +1 -0
  6. package/dist/ast/format.js +41 -0
  7. package/dist/ast/types.js +1 -0
  8. package/dist/bin/agentscript.js +234 -0
  9. package/dist/bin/input.js +19 -0
  10. package/dist/bin/repl.js +290 -0
  11. package/dist/index.js +26 -0
  12. package/dist/parser/errors.js +8 -0
  13. package/dist/parser/parser.js +661 -0
  14. package/dist/parser/tokenizer.js +246 -0
  15. package/dist/providers/llm/anthropic.js +36 -0
  16. package/dist/providers/llm/index.js +3 -0
  17. package/dist/providers/llm/ollama.js +19 -0
  18. package/dist/providers/llm/openai.js +31 -0
  19. package/dist/providers/llm/protocol.js +45 -0
  20. package/dist/providers/llm/shared.js +147 -0
  21. package/dist/providers/llm/types.js +1 -0
  22. package/dist/providers/llm/uri.js +24 -0
  23. package/dist/providers/memory/file.js +44 -0
  24. package/dist/providers/memory/host.js +66 -0
  25. package/dist/providers/memory/index.js +1 -0
  26. package/dist/providers/memory/shared.js +56 -0
  27. package/dist/providers/memory/sqlite.js +98 -0
  28. package/dist/providers/mock/index.js +32 -0
  29. package/dist/providers/tools/env.js +11 -0
  30. package/dist/providers/tools/file.js +99 -0
  31. package/dist/providers/tools/host.js +34 -0
  32. package/dist/providers/tools/http.js +40 -0
  33. package/dist/providers/tools/index.js +2 -0
  34. package/dist/providers/tools/scheme.js +16 -0
  35. package/dist/providers/tools/shared.js +92 -0
  36. package/dist/providers/tools/shell.js +80 -0
  37. package/dist/runtime/context.js +160 -0
  38. package/dist/runtime/errors.js +14 -0
  39. package/dist/runtime/evaluator.js +276 -0
  40. package/dist/runtime/generate.js +175 -0
  41. package/dist/runtime/guards.js +39 -0
  42. package/dist/runtime/input.js +38 -0
  43. package/dist/runtime/interpreter.js +314 -0
  44. package/dist/runtime/json.js +59 -0
  45. package/dist/runtime/loader.js +146 -0
  46. package/dist/runtime/scope.js +47 -0
  47. package/dist/runtime/shape.js +132 -0
  48. package/dist/runtime/trace.js +54 -0
  49. package/dist/runtime/truth.js +13 -0
  50. package/dist/runtime/types.js +1 -0
  51. package/dist/runtime/uri.js +10 -0
  52. package/dist/semantic/analyzer.js +519 -0
  53. package/dist/semantic/diagnostics.js +16 -0
  54. package/dist/utils/assert.js +3 -0
  55. package/docs/cn/context-engineering.md +389 -0
  56. package/docs/cn/language.md +478 -0
  57. package/docs/design-history/v0-design.md +365 -0
  58. package/docs/design-history/v0-implement.md +274 -0
  59. package/docs/design-history/v1-design.md +323 -0
  60. package/docs/design-history/v1-implement.md +267 -0
  61. package/docs/design-history/v2-design.md +387 -0
  62. package/docs/design-history/v2-implement.md +399 -0
  63. package/docs/en/context-engineering.md +332 -0
  64. package/docs/en/language.md +478 -0
  65. package/examples/changelog.as +29 -0
  66. package/examples/extract.as +29 -0
  67. package/examples/review.as +38 -0
  68. package/examples/summarize.as +28 -0
  69. package/examples/translate.as +33 -0
  70. package/package.json +59 -0
  71. package/tutorials/cli.as +22 -0
  72. package/tutorials/helloworld.as +14 -0
  73. package/tutorials/memory.as +19 -0
  74. package/tutorials/plan-execute.as +155 -0
  75. package/tutorials/react.as +98 -0
  76. package/tutorials/repl.as +31 -0
  77. package/tutorials/self-improve.as +60 -0
@@ -0,0 +1,132 @@
1
+ import { RuntimeError } from "./errors.js";
2
+ import { isObject, isRuntimeResource } from "./guards.js";
3
+ export function buildValueFromShape(shape) {
4
+ const result = {};
5
+ for (const field of shape.fields) {
6
+ result[field.name] = buildValueFromShapeType(field.type);
7
+ }
8
+ return result;
9
+ }
10
+ export function validateValueAgainstShape(value, shape, range) {
11
+ if (!isObject(value)) {
12
+ throw new RuntimeError("LLM result must be an object matching the generate return shape", range);
13
+ }
14
+ const allowedFields = new Set(shape.fields.map((field) => field.name));
15
+ for (const key of Object.keys(value)) {
16
+ if (!allowedFields.has(key)) {
17
+ throw new RuntimeError(`LLM result contains unexpected field '${key}'`, range);
18
+ }
19
+ }
20
+ for (const field of shape.fields) {
21
+ if (!(field.name in value)) {
22
+ throw new RuntimeError(`LLM result is missing required field '${field.name}'`, field.range);
23
+ }
24
+ validateValueAgainstShapeType(value[field.name], field.type, field.range);
25
+ }
26
+ }
27
+ export function coerceValueToShape(value, shape) {
28
+ if (!isObject(value)) {
29
+ return value;
30
+ }
31
+ const result = {};
32
+ for (const [key, item] of Object.entries(value)) {
33
+ const field = shape.fields.find((candidate) => candidate.name === key);
34
+ result[key] = field ? coerceValueToShapeType(item, field.type) : item;
35
+ }
36
+ return result;
37
+ }
38
+ const SHAPE_TYPE_CONFIG = {
39
+ string: {
40
+ default: "",
41
+ validate: (value, range, errorPrefix = "LLM result field") => {
42
+ if (typeof value !== "string")
43
+ throw new RuntimeError(`${errorPrefix} must be a string`, range);
44
+ }
45
+ },
46
+ number: {
47
+ default: 0,
48
+ validate: (value, range, errorPrefix = "LLM result field") => {
49
+ if (typeof value !== "number")
50
+ throw new RuntimeError(`${errorPrefix} must be a number`, range);
51
+ },
52
+ coerce: coerceStringToNumber
53
+ },
54
+ boolean: {
55
+ default: true,
56
+ validate: (value, range, errorPrefix = "LLM result field") => {
57
+ if (typeof value !== "boolean")
58
+ throw new RuntimeError(`${errorPrefix} must be a boolean`, range);
59
+ },
60
+ coerce: coerceStringToBoolean
61
+ },
62
+ json: {
63
+ default: {},
64
+ validate: (value, range, errorPrefix = "LLM result json field") => {
65
+ if (isRuntimeResource(value)) {
66
+ throw new RuntimeError(`${errorPrefix} cannot contain runtime resource bindings`, range);
67
+ }
68
+ },
69
+ },
70
+ list: {
71
+ default: [],
72
+ validate: (value, range, errorPrefix = "LLM result field") => {
73
+ if (!Array.isArray(value))
74
+ throw new RuntimeError(`${errorPrefix} must be a list`, range);
75
+ },
76
+ },
77
+ };
78
+ function coerceValueToShapeType(value, type) {
79
+ if (type.kind === "ListShapeType") {
80
+ if (!Array.isArray(value)) {
81
+ return value;
82
+ }
83
+ return value.map((item) => coerceValueToShapeType(item, type.itemType));
84
+ }
85
+ const config = SHAPE_TYPE_CONFIG[type.name];
86
+ return config?.coerce ? config.coerce(value) : value;
87
+ }
88
+ function coerceStringToNumber(value) {
89
+ if (typeof value !== "string") {
90
+ return value;
91
+ }
92
+ const trimmed = value.trim();
93
+ if (!/^-?(?:0|[1-9]\d*)(?:\.\d+)?$/.test(trimmed)) {
94
+ return value;
95
+ }
96
+ const parsed = Number(trimmed);
97
+ return Number.isFinite(parsed) ? parsed : value;
98
+ }
99
+ function coerceStringToBoolean(value) {
100
+ if (typeof value !== "string") {
101
+ return value;
102
+ }
103
+ const normalized = value.trim().toLowerCase();
104
+ if (normalized === "true") {
105
+ return true;
106
+ }
107
+ if (normalized === "false") {
108
+ return false;
109
+ }
110
+ return value;
111
+ }
112
+ export function validateValueAgainstShapeType(value, type, range, errorPrefix = "LLM result field") {
113
+ if (type.kind === "ListShapeType") {
114
+ if (!Array.isArray(value)) {
115
+ throw new RuntimeError(`${errorPrefix} must be a list`, range);
116
+ }
117
+ for (const item of value) {
118
+ validateValueAgainstShapeType(item, type.itemType, range, errorPrefix);
119
+ }
120
+ return;
121
+ }
122
+ const config = SHAPE_TYPE_CONFIG[type.name];
123
+ if (config) {
124
+ config.validate(value, range, errorPrefix);
125
+ }
126
+ }
127
+ function buildValueFromShapeType(type) {
128
+ if (type.kind === "ListShapeType") {
129
+ return [buildValueFromShapeType(type.itemType)];
130
+ }
131
+ return SHAPE_TYPE_CONFIG[type.name]?.default ?? {};
132
+ }
@@ -0,0 +1,54 @@
1
+ import { assertNever } from "../utils/assert.js";
2
+ export function formatTrace(trace) {
3
+ if (trace.length === 0) {
4
+ return "(empty trace)";
5
+ }
6
+ return trace.map((event) => formatEvent(event, 0)).join("\n");
7
+ }
8
+ function formatEvent(event, depth) {
9
+ const indent = " ".repeat(depth);
10
+ switch (event.kind) {
11
+ case "agent": {
12
+ const agent = readString(event.data.agent);
13
+ const fn = readString(event.data.function);
14
+ const nested = Array.isArray(event.data.trace) ? event.data.trace : [];
15
+ const header = `${indent}- agent ${agent}.${fn}`;
16
+ if (nested.length === 0)
17
+ return header;
18
+ return [header, ...nested.map((child) => formatEvent(child, depth + 1))].join("\n");
19
+ }
20
+ case "generate":
21
+ return `${indent}- generate ${summarize(event.data.instruction)}`;
22
+ case "tool": {
23
+ const tool = readString(event.data.tool);
24
+ const method = readString(event.data.method);
25
+ return `${indent}- tool ${tool}.${method}`;
26
+ }
27
+ case "memory": {
28
+ const memory = readString(event.data.memory);
29
+ const operation = readString(event.data.operation);
30
+ return `${indent}- memory ${memory}.${operation}`;
31
+ }
32
+ case "input":
33
+ return `${indent}- input ${readString(event.data.path)}`;
34
+ case "for":
35
+ return `${indent}- for ${readString(event.data.item)}[${summarize(event.data.index)}]`;
36
+ case "use":
37
+ return `${indent}- use ${summarize(event.data.source)}`;
38
+ default:
39
+ assertNever(event.kind);
40
+ }
41
+ }
42
+ function readString(value) {
43
+ return typeof value === "string" && value.length > 0 ? value : "?";
44
+ }
45
+ function summarize(value) {
46
+ if (typeof value === "string") {
47
+ return value.length > 72 ? `${value.slice(0, 69)}...` : value;
48
+ }
49
+ if (value === undefined) {
50
+ return "";
51
+ }
52
+ const json = JSON.stringify(value);
53
+ return json.length > 72 ? `${json.slice(0, 69)}...` : json;
54
+ }
@@ -0,0 +1,13 @@
1
+ export function isTruthy(value) {
2
+ if (value === null)
3
+ return false;
4
+ if (typeof value === "boolean")
5
+ return value;
6
+ if (typeof value === "number")
7
+ return value !== 0;
8
+ if (typeof value === "string")
9
+ return value.length > 0;
10
+ if (Array.isArray(value))
11
+ return value.length > 0;
12
+ return true;
13
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ export function uriScheme(uri) {
2
+ try {
3
+ const parsed = new URL(uri);
4
+ return parsed.protocol.endsWith(":") ? parsed.protocol.slice(0, -1) : parsed.protocol;
5
+ }
6
+ catch {
7
+ const match = /^([A-Za-z][A-Za-z0-9+.-]*):/.exec(uri);
8
+ return match?.[1] ?? "";
9
+ }
10
+ }