Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 34 additions & 9 deletions book/src/week4-01-agent-loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ A coding agent needs a small control loop around that function: ask for one
response, decide whether it is a final answer or an action, record what
happened, and continue when an action produces an observation.

Start with one prediction: if the model first requests a disabled tool and then
returns malformed JSON, which requests reach the workspace, which errors enter
the next model input, and which configured budget can stop the run first? The
event trace at the end of this chapter lets you check every part of that answer.

The model never edits a file directly. It emits text. Ordinary Python validates
that text before handing a parsed action to a workspace object. This separation
makes the loop deterministic to test even when no model weights are loaded.
Expand All @@ -22,6 +27,11 @@ session, or production scheduler.

## Files and Public Surface

The repository is a final Day 9 declaration scaffold. Future agent modules and
exports are already visible, but their implementation surfaces are not part of
Day 1. Most later bodies are TODO stubs; Day 9 also contains one explicitly
supplied constructor check. Implement only the following surfaces:

Implement the TODO bodies in these Day 1 starter files:

| File | Public names | Responsibility |
Expand All @@ -30,20 +40,29 @@ Implement the TODO bodies in these Day 1 starter files:
| `src/tiny_llm/agent/protocol.py` | `AgentError`, `FinalAction`, `ToolAction`, `parse_action`, `build_system_prompt` | Represent and validate one final answer or one enabled tool request. |
| `src/tiny_llm/agent/loop.py` | `AgentLimits`, `AgentEvent`, `AgentRun`, `run_agent` | Bound a run, propagate observations, and retain an inspectable trace. |

`generate_response()` remains part of the public Day 1 surface even though the
focused test uses scripted strings. It renders the messages with the course
tokenizer, decodes at most `max_tokens` with a fresh cache, stops at EOS, and
releases every cache in a `finally` block.
`generate_response()` remains part of the public Day 1 surface. It renders the
messages with the course tokenizer, decodes at most `max_tokens` with a fresh
cache, stops at EOS, and releases every cache in a `finally` block.

Run the cumulative learner checkpoint from the repository root:
The current supplied Day 1 test uses scripted response strings and does not
call `generate_response()`. The current `pdm run agent` CLI also uses its own
MLX-LM generation adapter. Implement the helper as specified, but do not read a
green Day 1 checkpoint or a successful CLI run as behavioral proof of this one
function. A focused course-model witness is pending with the cumulative Week 4
runner.

Copy the supplied learner test, then run the **day-local** checkpoint from the
repository root:

```bash
pdm run copy-test --week 4 --day 1
pdm run test --week 4 --day 1
```

This command copies the supplied Day 1 test into `tests/` before running it.
Before you implement the TODOs, the implementation-dependent cases across nine
task groups are expected to fail. No model download is required.
`copy-test` refreshes the learner copy from the supplied checkpoint. Before you
implement the TODOs, the implementation-dependent cases across nine task
groups are expected to fail. No model download is required. This command does
not run later days.

Course maintainers can check the supplied implementation without copying the
learner test:
Expand Down Expand Up @@ -174,7 +193,13 @@ and repeated-action limits, every run has an explicit terminal reason.
When Day 1 is green, inspect the focused test rather than only its final pass:
confirm the initial system/user pair, one dispatched `read_file`, the exact
observation in the next model input, the completed final event, and each
budgeted stop reason.
budgeted stop reason. Revisit your opening prediction: a disabled or malformed
request must not reach the workspace, and the exact error must remain visible
to the following model turn.

This checkpoint proves the scripted protocol and loop. It does not yet prove
`generate_response()` or the Weeks 1--3 model/cache handoff; keep that boundary
explicit until the cumulative product witness is supplied.

You now have a validated, bounded model → action → observation loop. Continue
with [Day 2: Inspect a Workspace](week4-02-tools.md) to replace the fake tool
Expand Down
41 changes: 29 additions & 12 deletions book/src/week4-02-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,31 +41,37 @@ validation command, and a simple receipt log. Keeping those effects out of Day

## Files and Public Surface

The published starter is the cumulative Day 9 declaration scaffold. Receipt,
checkpoint, compaction, and later modules are therefore visible already, but
their implementation work belongs to later chapters. Day 2 owns only the
workspace relationships below.

Implement the TODO bodies in:

| File | Public names | Responsibility |
| --- | --- | --- |
| `src/tiny_llm/agent/workspace.py` | `ToolPolicy`, `Workspace` | Bound one directory and expose `list_files` plus `read_file`. |
| `src/tiny_llm/agent/__init__.py` | Day 1 API plus `ToolPolicy`, `Workspace` | Make the cumulative checkpoint importable. |
| `src/tiny_llm/agent/__init__.py` | Day 1 API plus `ToolPolicy`, `Workspace` | Complete the Day 2 exports within the final scaffold. |

`ToolPolicy` has three fields, in order:
The Day 2-owned prefix of `ToolPolicy` has three fields, in order:

```python
root: Path
max_file_bytes: int = 64 * 1024
max_list_entries: int = 200
```

`Workspace` exposes:
Day 2 implements this prefix of `Workspace`:

- `available_tools`, always `{"list_files", "read_file"}`;
- `resolve_path(raw, must_exist=True)`;
- `list_files(raw=".")`;
- `read_file(raw)`; and
- `execute(action)`.

The starter declarations are the contract. Do not add write, command, approval,
receipt, session, checkpoint, or rewind APIs yet.
The starter declarations are the contract. Do not implement or depend on the
visible write, command, approval, receipt, checkpoint, compaction, steering,
evaluation, branching, or evidence-retrieval declarations yet.

## Task 1: Normalize One Workspace Root

Expand Down Expand Up @@ -159,24 +165,26 @@ Inspect `result.events`: the first two events contain the parsed tool actions
and exact observations, and the third contains the final answer. The same tool
result appears in the next model input as `Tool result:\n...`.

## Run the Cumulative Checkpoint
## Run the Day 2 Checkpoint

From the repository root, run:
From the repository root, copy the supplied test explicitly, then run it:

```bash
pdm run copy-test --week 4 --day 2
pdm run test --week 4 --day 2
```

This copies the cumulative Day 2 learner test into `tests/` and runs it against
`tiny_llm`. Before you implement the TODOs, the implementation-dependent cases
across six task groups are expected to fail. During course development, check
the supplied implementation without copying the learner test:
Before you implement the TODOs, the implementation-dependent cases across eight
task groups are expected to fail. `copy-test` refreshes the learner copy from
the supplied checkpoint. The test is day-local; it does not rerun Day 1.
During course development, check the
supplied implementation without copying the learner test:

```bash
pdm run test-refsol --week 4 --day 2
```

The cumulative course-code guard compares the starter and reference public
The course-code guard compares the starter and reference public
signatures, dataclass fields, package exports, and solution-free method bodies.

## Explore with a Real Model
Expand All @@ -198,6 +206,10 @@ corresponding free disk space. If MLX is unavailable or the weights cannot be
loaded, the command exits before the agent calls a workspace tool; it does not
substitute scripted output.

This CLI uses a supplied MLX-LM generation adapter. It exercises your Day 1
loop and Day 2 workspace, but it does not call the learner-owned
`generate_response()` helper or prove the Weeks 1--3 course model/cache path.

Create a tiny read-only workspace, then give the model one goal:

```bash
Expand Down Expand Up @@ -230,4 +242,9 @@ enabling any effect tool.
When this checkpoint is green, continue to [Day 3: Edit, Validate, and
Record](week4-03-safe-editing.md).

The final Week 4 capstone will eventually compose this read-only inspection
with the later checkpoint, compaction, steering, evaluation, branching, and
bounded-evidence mechanisms. That orchestration is not present in the current
CLI yet.

{{#include copyright.md}}
39 changes: 31 additions & 8 deletions book/src/week4-03-safe-editing.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ read file -> propose exact edit -> operator approves -> recheck bytes
The important idea is not broad autonomy. It is an explicit boundary between a
model proposal and a local side effect.

Before running the focused cycle, predict three facts: how many approvals and
receipts exist after a denied effect, whether stale-read detection changes any
file bytes, and which evidence remains after a validation command returns a
nonzero status. The workspace, receipt log, and event trace let you check those
answers independently of the model's final sentence.

## The Teaching Boundary

Use this checkpoint with one trusted operator, one Python process, and a
Expand All @@ -29,13 +35,18 @@ stops at this receipt boundary.

## Files and Public Surface

Implement the TODO bodies in these cumulative starter files:
Later checkpoint, compaction, steering, evaluation, branching, and evidence
modules are already declared in the cumulative Day 9 scaffold. Their later-day
implementation work is out of scope. Day 3 owns only the following Day 1--3
surfaces:

Implement the TODO bodies in these starter files:

| File | Public names | Responsibility |
| --- | --- | --- |
| `src/tiny_llm/agent/workspace.py` | `ToolPolicy`, `Workspace` | Authorize reads, approved edits, and one exact validation command. |
| `src/tiny_llm/agent/receipts.py` | `EffectReceipt`, `ReceiptStore` | Represent effects and optionally append verified JSONL records. |
| `src/tiny_llm/agent/__init__.py` | cumulative Day 1--3 API | Export the two receipt types. |
| `src/tiny_llm/agent/__init__.py` | Day 1--3 names within the final scaffold | Export the two receipt types. |

`ToolPolicy` keeps its first three Day 2 fields and adds:

Expand Down Expand Up @@ -178,17 +189,20 @@ edit receipt names `app.py`; the validation receipt has an empty artifact tuple.
The final answer is still a model statement, so the validation status in the
trace is the evidence that matters.

## Run the Cumulative Checkpoint
## Run the Day 3 Checkpoint

From the repository root, copy and run the learner checkpoint:
From the repository root, copy and run the learner checkpoint explicitly:

```bash
pdm run copy-test --week 4 --day 3
pdm run test --week 4 --day 3
```

Before you implement the TODOs, the copied test is expected to fail because the
new starter methods return `None`. Keep those failures until you solve each
task; do not import `tiny_llm_ref` from the starter.
new starter methods return `None`. `copy-test` refreshes the learner copy from
the supplied checkpoint. Keep those failures until you solve each task; do not
import `tiny_llm_ref` from the starter. This is a day-local test, not a
cumulative Days 1--3 runner.

Course maintainers can check the supplied implementation without copying the
learner test:
Expand All @@ -197,8 +211,9 @@ learner test:
pdm run test-refsol --week 4 --day 3
```

The cumulative course-code guard checks exact public signatures, dataclass
fields, package exports, TODO-only starter bodies, and absence of future APIs.
The course-code guard checks exact public signatures, dataclass fields,
package exports, and TODO-only starter bodies across the final declaration
scaffold.

## Explore the Full Cycle with a Real Model

Expand All @@ -219,6 +234,10 @@ memory, or the weights are unavailable, model loading fails before any tool
call; do not treat a scripted checkpoint as evidence that this live run
occurred.

As on Day 2, this CLI's supplied MLX-LM adapter bypasses the learner-owned
`generate_response()` helper. It does exercise your loop, workspace,
approval, effect, and receipt paths.

Pre-create the workspace, an existing file, and one focused validation fixture:

```bash
Expand Down Expand Up @@ -271,4 +290,8 @@ effects. Continue with [Day 4: Checkpoint and Resume](week4-04-sessions.md) to
save one complete observation boundary and restore it through a fresh scripted
model without turning Day 3 into production infrastructure.

Day 3 is currently the last mechanism exposed by the real-model CLI. Days
4--9 use deterministic library checkpoints until the supplied Week 4 capstone
connects them into one runnable product path.

{{#include copyright.md}}
30 changes: 23 additions & 7 deletions book/src/week4-04-sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,30 @@ exactly-once effect system.

## Files and Public Surface

The final scaffold already declares compaction, steering, evaluation,
branching, and evidence APIs. Leave those future TODO bodies alone. Day 4 owns
only the checkpoint model and the two loop entry points below:

Implement the TODO-only surfaces in:

| File | Public names | Responsibility |
| --- | --- | --- |
| `src/tiny_llm/agent/checkpoint.py` | `ModelCheckpoint`, `AgentCheckpoint`, `create_checkpoint` | Represent and validate one in-memory conversation/model snapshot. |
| `src/tiny_llm/agent/loop.py` | `run_to_checkpoint`, `resume_agent` | Stop after a complete observation, then continue with a fresh model. |
| `src/tiny_llm/agent/__init__.py` | the names above | Export the cumulative Day 4 API. |
| `src/tiny_llm/agent/__init__.py` | the names above | Complete the Day 4 exports within the final scaffold. |

Run the learner checkpoint from the repository root:
Copy and run the learner checkpoint from the repository root:

```bash
pdm run copy-test --week 4 --day 4
pdm run test --week 4 --day 4
```

Before you implement the TODOs, all seven Day 4 tasks are expected to fail.
The test uses a scripted model, fake cache metadata, a temporary workspace, and
one exact Python validation command. It does not load model weights.
one exact Python validation command. It does not load model weights. The test
is day-local and does not rerun Days 1--3; `copy-test` refreshes the learner
copy from the supplied checkpoint.

Course maintainers can check the supplied implementation without copying the
learner test:
Expand Down Expand Up @@ -172,10 +179,11 @@ effects completed.

## Task 7: Keep the Boundary Small

The Day 4 starter adds only `checkpoint.py` and two loop entry points. Do not add
session IDs, parent pointers, branches, rewind methods, compaction summaries,
steering queues, disk cache files, or later-day modules. If the in-memory
checkpoint is lost, start a new run.
Day 4 implements only `checkpoint.py` and two loop entry points. Future modules
are already declared in the final scaffold, but do not implement or depend on
them here. Do not add session IDs, parent pointers, rewind methods, steering
queues, disk cache files, or another checkpoint representation. If the
in-memory checkpoint is lost, start a new run.

## Checkpoint

Expand All @@ -184,7 +192,15 @@ scripted model from the same conversation and fake-cache position. Inspect the
checkpoint's messages and model fields, then confirm that the pre-checkpoint
edit and command remain single completed effects.

At this point, predict what resume is allowed to do: the next model response
may request a new action, but no action already represented by the saved
observation should run again. The approval and receipt counts in the focused
scenario are the falsifying evidence.

Continue with [Day 5: Compact Completed Work](week4-05-compaction.md) to derive
a smaller model-visible transcript while keeping the exact effect receipts.
The current Day 5 checkpoint receives a transcript and receipts directly; it
is not yet wired into this resume path. The pending Week 4 capstone supplies
that composition.

{{#include copyright.md}}
25 changes: 21 additions & 4 deletions book/src/week4-05-compaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ harness still retains the exact action and result.

## The Starter Surface

Day 5 adds one small module:
The cumulative Day 9 scaffold already contains later steering, evaluation,
branching, and evidence declarations. Leave those future TODO bodies alone.
Day 5 owns one small module:

| File | Public names | Purpose |
| --- | --- | --- |
| `src/tiny_llm/agent/compaction.py` | `CompactionResult`, `compact_completed_interactions` | Derive a smaller model-visible transcript from completed, receipted effects. |
| `src/tiny_llm/agent/__init__.py` | the names above | Export the cumulative Day 5 API. |
| `src/tiny_llm/agent/__init__.py` | the names above | Complete the Day 5 exports within the final scaffold. |

Copy the learner test, then run it:

Expand All @@ -37,6 +39,8 @@ pdm run test-refsol --week 4 --day 5
```

Before you implement the TODOs, all six Day 5 tasks are expected to fail.
The command runs only the Day 5 test. `copy-test` refreshes the learner copy
from the supplied checkpoint.

## Start From the Existing Transcript

Expand All @@ -53,6 +57,11 @@ model. A completed effect has this shape:
The compactor does not invent a second event log. It receives this transcript
plus the Day 3 `EffectReceipt` values already produced by the workspace.

Before implementing it, predict which older interaction in the focused
fixture is eligible to compact, which recent interaction must stay verbatim,
and whether `saved_tokens` must be positive. The returned messages, exact
counter values, and unchanged receipts let you falsify that prediction.

## Task 1: Require Exact Receipt Evidence

A pair is eligible only when all three facts match one supplied receipt:
Expand Down Expand Up @@ -119,8 +128,10 @@ def count_tokens(messages):

Build the proposed compact view, count it again, and accept it only when the
exact counter decreases. `CompactionResult` reports `tokens_before`,
`tokens_after`, and `saved_tokens`. The focused tests inject the Day 4 fake
model's simple counter, so they do not load or download a model.
`tokens_after`, and `saved_tokens`. The focused tests inject their own
deterministic character counter, which sums the message-content lengths. It is
distinct from Day 4's cached-prefix counter and does not load or download a
model.

## Task 5: Preserve the Source of Truth

Expand Down Expand Up @@ -178,4 +189,10 @@ model call. Continue with [Day 6: Inspect and Steer a Paused
Agent](week4-06-steering.md) to inspect one checkpoint, add one visible operator
message, and resume without replaying completed work.

The current Day 6 path resumes the Day 4 transcript; it does not yet consume
`CompactionResult.messages`. The pending cumulative capstone will carry this
compacted view into the later control path. Until then, Day 5's token counts
prove only deterministic transcript accounting, not latency, throughput,
quality, or memory-capacity improvement.

{{#include copyright.md}}
Loading
Loading