agent-from-zero 0.5.0 → 0.27.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.
@@ -0,0 +1,60 @@
1
+ // Structured tool-call validation. A model's tool arguments are probabilistic
2
+ // output: it will sometimes drop a required field, send a number as a string,
3
+ // or pass the wrong shape. The harness job is to constrain that output to the
4
+ // declared schema and, on mismatch, hand back a PRECISE repair instruction so
5
+ // the model fixes it on the next turn — instead of the tool crashing or doing
6
+ // the wrong thing silently.
7
+ //
8
+ // This is a deliberately small subset of JSON Schema — exactly what our tool
9
+ // definitions (and MCP servers') actually use: an object with typed properties
10
+ // and a `required` list. Not a general validator; just enough to catch the
11
+ // mistakes models really make, with messages they can act on.
12
+ // JSON Schema "type" → does this runtime value match it? Unknown/absent type
13
+ // matches anything (we don't over-constrain what the schema didn't constrain).
14
+ function typeMatches(value, type) {
15
+ switch (type) {
16
+ case undefined:
17
+ return true; // no declared type → anything goes
18
+ case "string":
19
+ return typeof value === "string";
20
+ case "number":
21
+ case "integer":
22
+ return typeof value === "number" && (type === "number" || Number.isInteger(value));
23
+ case "boolean":
24
+ return typeof value === "boolean";
25
+ case "array":
26
+ return Array.isArray(value);
27
+ case "object":
28
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29
+ default:
30
+ return true; // a type we don't model — don't reject on it
31
+ }
32
+ }
33
+ // Validate parsed arguments against a schema. Returns a list of human-readable
34
+ // problems; an empty list means the arguments are valid. Pure — no I/O.
35
+ export function validateArgs(schema, args) {
36
+ if (!schema)
37
+ return []; // no schema → nothing to check
38
+ const problems = [];
39
+ // The arguments must be a plain object — every tool takes a named-arg object.
40
+ if (typeof args !== "object" || args === null || Array.isArray(args)) {
41
+ return ["arguments must be a JSON object of named parameters"];
42
+ }
43
+ const obj = args;
44
+ // Every required parameter must be present and not null/undefined.
45
+ for (const name of schema.required ?? []) {
46
+ if (obj[name] === undefined || obj[name] === null) {
47
+ problems.push(`missing required parameter "${name}"`);
48
+ }
49
+ }
50
+ // Every PRESENT parameter that has a declared type must match it. (We only
51
+ // type-check what was provided — absence is the `required` check's job.)
52
+ for (const [name, spec] of Object.entries(schema.properties ?? {})) {
53
+ if (obj[name] === undefined || obj[name] === null)
54
+ continue; // not provided — skip (required handled above)
55
+ if (!typeMatches(obj[name], spec.type)) {
56
+ problems.push(`parameter "${name}" should be ${spec.type}, got ${Array.isArray(obj[name]) ? "array" : typeof obj[name]}`);
57
+ }
58
+ }
59
+ return problems;
60
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-from-zero",
3
- "version": "0.5.0",
3
+ "version": "0.27.0",
4
4
  "description": "Build a Claude Code-style CLI agent from scratch, with AI as your pair programmer — companion code for a 10-day tutorial (DeepSeek by default, any OpenAI-compatible model)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,7 +16,7 @@
16
16
  "eval": "tsx --env-file=.env eval/run.ts",
17
17
  "build": "tsc -p tsconfig.build.json",
18
18
  "prepare": "npm run build",
19
- "test": "tsx tests/tools.test.ts && tsx tests/permissions.test.ts && tsx tests/context.test.ts && tsx tests/hooks.test.ts"
19
+ "test": "tsx tests/tools.test.ts && tsx tests/permissions.test.ts && tsx tests/context.test.ts && tsx tests/hooks.test.ts && tsx tests/mcp.test.ts && tsx tests/judge.test.ts && tsx tests/memory.test.ts && tsx tests/cost.test.ts && tsx tests/validate.test.ts && tsx tests/plan.test.ts && tsx tests/diff.test.ts && tsx tests/undo.test.ts && tsx tests/tiering.test.ts && tsx tests/mcp-http.test.ts && tsx tests/changes.test.ts && tsx tests/mentions.test.ts && tsx tests/session.test.ts && tsx tests/ui.test.ts && tsx tests/approval.test.ts && tsx tests/form.test.ts && tsx tests/model.test.ts && tsx tests/reasoning.test.ts && tsx tests/skills.test.ts"
20
20
  },
21
21
  "engines": {
22
22
  "node": ">=20.6"