homeprojectsblogbookscontactmima

RΞASON

RΞASON is a programming language (a Typescript superset) created for building great LLM apps.

The vision for RΞASON was to allow LLMs to interop with your code itself. It accomplish it through its structured output and agents API.

That said, it also helps with two key aspects of modern LLM apps: streaming & observability.

In short, RΞASON ships with a custom compiler that:
1. Performs whole-program analysis over the TypeScript AST.
2. Lifts types and JSDoc into a runtime metadata graph.
3. Uses that graph to auto-derive structured output schemas, agent definitions, and tool signatures.

skills

AI
LLM
Framework creation
Compilers
Typescript

Unique design

Here's a quick example of how you'd get structured output in RΞASON:



You create a normal TS interface describing what you want and just pass that as a generic to the reason() function. RΞASON then uses that interface to inform the LLM what object to return.


import { reason } from 'tryreason' interface Joke { /** Use this property to indicate the age rating of the joke */ rating: number; joke: string; /** Use this property to explain the joke to those who did not understood it */ explanation: string; } const joke = await reason<Joke>('tell me a really spicy joke') // `joke` will be: { "joke": "I'd tell you a chemistry joke but I know I wouldn't get a reaction.", "rating": 18, "explanation": "This joke is a play on words. The term 'reaction' refers to both a chemical process and a response from someone. The humor comes from the double meaning, implying that the joke might not be funny enough to elicit a response." }

For those unfamiliar with Typescript, it's impossible to read its types at runtime; they are completely stripped during transpilation to Javascript. RΞASON is able to circumvent this limitation because it has its own internal compiler that makes type information accessible in runtime.

You may have noticed that there are comments that look a like descriptions above each field to guide the LLM, and that is correct! RΞASON also uses the comments as the description for each field.


Agents

Another example of RΞASON interoping with your code is when creating an agent:


// src/agents/web-agent.ts: import { useAgent } from 'tryreason' import sum from '../tools/sum-tool' import subtract from '../tools/subtract-tool' import multiply from '../tools/multiply-tool' import divide from '../tools/divide-tool' export const tools = [ sum, subtract, multiply, divide, ] /** * You are a helpful math assistant. * You only have access to the four basic math operations (addition, subtraction, multiplication, and division). * * You *MUST* follow all math rules when answering the user's question. * For instance, you cannot divide by zero and you have to follow the order of operations. */ export default async function WebAgent(userMessage: string) { const agent = await useAgent() return agent.run(userMessage) }

In most frameworks, you define tools twice (function + schema).


In RΞASON, the function is the tool — its signature + JSDoc drive the schema automatically. Reason’s compiler inspects the function signature and JSDoc to generate a JSON Schema definition that is passed to the LLM as the tool schema.


Under the hood, Reason has its own compiler that walks throught TypeScript AST.


At compile time, it:


    *
  • walks the AST of your TypeScript files,
  • *
  • extracts types + JSDoc comments,
  • *
  • and emits runtime metadata that the LLM runtime uses for structured output and tools.


Outcome

In hindsight I got some things very right and others very wrong:


* Using Typescript types instead of manually defining a JSON schema.
* RΞASON handles streaming to clients in a very convient way that rarely gets in the way of the engineer.

* Creating a compiler is unsurprisingly hard; this plus my lack of time during the project made RΞASON finnicky and with lots of seemingly arbitrary limitations.
* RΞASON requires a standalone Node.js environment to run: you cannot use it in a Next.js API route or in a Cloudflare Worker.

That said, I'm happy with how RΞASON turned out; as it stands, it is a small experimental programming language that I routinely use for my own LLM usecases.