affordance

Showcase

Things we built with Affordance and things we measured, each with its code and its numbers.

note     Kestrel day 8 diary: Tomas Lind joins as SRE
later    Who mentors Tomas Lind?
answer   Devi Rao mentors Tomas Lind.
Built with Affordance

We built OptMem, a long-term memory for AI agents, as a small Affordance app

A chat model forgets everything when a conversation ends. OptMem, a design by Victor Taelin, has the model keep one-line notes and read them back next time. Our version is 116 lines, and it answered 8 of 8 questions about facts from earlier conversations.

reading it directly121,314
as an RLM13,871
Tokens in the model's prompt for a 408,893-character log
Built with Affordance

We built a Recursive Language Model as one Affordance file

Models get worse at answering as their input gets longer. A Recursive Language Model keeps the long input out of the prompt and lets the model work on it with code. Ours got 5 of 6 questions right on a 408,893-character log. Reading the log directly, the same model finished none.

SGLang1,121 ms
with Affordance968 ms
Wait for the first word of a reply, prompts over 120,000 tokens
Benchmark

SGLang started replying 153 ms sooner on long prompts with Affordance preparing them

Before a model can start, its server turns the conversation into tokens. We replaced that step in SGLang with Affordance. On prompts over 120,000 tokens, the wait for the first word fell from 1,121 ms to 968 ms, and the model read exactly the same tokens.

Qwen3-8BQwen1.5-7B-ChatQwen2-7B-InstructQwen2.5-7B-InstructQwen2.5-Coder-7B-InstructQwQ-32BQwen3-4B-Instruct-2507Qwen3-Next-80B-A3B-InstructQwen3-4B-Thinking-2507Qwen3-Coder-30B-A3B-InstructQwen3.5-9BQwen3.6-27BQwen3.8-27BDeepSeek-V3.1deepseek-llm-7b-chatDeepSeek-V2.5DeepSeek-V3DeepSeek-V3-0324DeepSeek-R1DeepSeek-R1-0528DeepSeek-V3.1-TerminusDeepSeek-V4.1-FlashDeepSeek-V3.2DeepSeek-V4-FlashDeepSeek-V4-Progpt-oss-20b
Compatibility test

57 models' prompt formats rebuilt in Affordance, each matching the official one token for token

Every chat model expects its conversations in one exact format. We rebuilt the format of 57 models as Affordance apps and ran 963 test conversations through each one and through the model's official tools. The tokens matched every time.

trim a little each turn4,605 ms
trim a quarter at once492 ms
Time for one request, once the conversation is full
Benchmark

One line in a style sheet cut a long conversation's requests from 4.6 seconds to 0.5

A model server saves work when a prompt starts the same way as the last one. An agent with a full history breaks that on every turn by trimming a little off the front. We changed how it trims, with one line, and requests got nine times faster.

// How much of the window a prompt may fill before the next turn folds, and how many recent
// records are kept as they are.
const FULL = 0.8;
const KEEP = 12;
Built with Affordance

Running the pi coding agent on Affordance

pi is an open-source coding agent for the terminal. In our fork, the part that talks to the model is an Affordance app. Changing when pi summarizes a long conversation is now an edit to two numbers in a 41-line file.

state → context + actionsconversation → durable tasks
Comparison

Affordance vs. Pi Durable

Both can run durable agents. Affordance also renders the model's interface, down to the template and token IDs inside an inference server.

test grammar::tests::byte_level_map ... ok
[... 1355 tokens hidden ...]
test result: ok. 66 passed; 0 failed
Example

Showing a model the useful 98 tokens of a 1,440-token test log

When an agent runs your tests, the output can be thousands of tokens, and the model mostly needs the last line. This three-line rule keeps the start and the end of a command's output and says how much it left out.

export default function Main({ task }) {
  const log = useLog();
  useLoop(log); // ask the model, run its calls, repeat
  const { shell } = machineTools(harness.machine.get("home"));
  /** Give your final answer. This ends the task. */
  function answer({ text }: { text: string }) {
    harness.stop({ answer: text });
    return "done";
Example

A first agent in 23 lines, and a recording of it at work

An agent is a model that uses tools in a loop until a task is done. This is the smallest one Affordance writes for you: it can run shell commands and give an answer. The page walks through the file and shows one real run.

Qwen3.6   <|im_start|>system
GLM-5.3   [gMASK]<sop><|system|>Reasoning Effort: Max<
Llama 3.1 <|begin_of_text|><|start_header_id|>system<|
Example

One app, shown to three different models

Qwen, GLM and Llama each expect a prompt in their own format, and each has its own way of listing tools. This app is written once and names no model. The page shows what each of the three models reads.

$ ./tools/verify.sh
verification results:: 20 verified, 0 errors
Formal proof

A proof that a part of the prompt never goes over its token limit

If you give a part of the prompt a limit of 1,500 tokens, Affordance must never put 1,501 there, whatever the content is. We did not only test that. A proof checker confirms it for every possible input.