Skip to content

Instantly share code, notes, and snippets.

@HerringtonDarkholme
Last active February 1, 2026 05:06
Show Gist options
  • Select an option

  • Save HerringtonDarkholme/c954d00d421a96707509cd42d9e7bc88 to your computer and use it in GitHub Desktop.

Select an option

Save HerringtonDarkholme/c954d00d421a96707509cd42d9e7bc88 to your computer and use it in GitHub Desktop.
AI Lang
Error in user YAML: (<unknown>): found character that cannot start any token while scanning for the next token at line 6 column 10
---
id: ai-lang-specification
title: AiLang - A Contextual Interface Definition Language for AI Agents
summary: AiLang is a declarative format that unifies tool interfaces, type systems, capability controls, domain knowledge, and usage examples into a single, AI-readable document. It enables agents to understand not just what tools exist, but when to use them, how to handle failures, and what contextual knowledge is required for effective operation. Features hierarchical detail levels for efficient context management.
loading: manual
keywords: specification, interface-definition, type-system, capability-model, ai-tools, runtime, tooling, context-management, detail-levels
related: @import(./manifesto.md), @import(./send_tweet.md)
version: 0.3.0
---

AiLang Specification

AiLang is an interface definition language designed specifically for AI agents. Unlike traditional IDLs that focus solely on API signatures, AiLang embeds context, capabilities, error handling strategies, and domain knowledge directly into tool definitions.

Design Philosophy

Traditional tool interfaces for AI agents suffer from three critical problems:

  1. Context Fragmentation: Tool signatures exist separately from usage guidelines, error handling advice, and domain knowledge
  2. Capability Blindness: No formal mechanism to declare required permissions or user consent
  3. Example Poverty: Lack of concrete examples showing proper tool composition and error recovery

AiLang solves these by making context first-class: every tool definition carries its complete operational context, making AI agents more capable and safer.

Document Structure

An AiLang document consists of four primary sections:

1. Frontmatter (YAML)

Metadata describing the document's identity, loading behavior, and relationships.

2. Prose (Markdown)

Human and AI-readable context, guidelines, domain knowledge, and usage patterns.

3. Definitions (<define> blocks)

Formal declarations of types, errors, capabilities, and tools.

4. Examples (<example> blocks)

Concrete usage demonstrations showing tool composition, error handling, and workflows.

// ============================================================================
// Meta-Types: Defining the Language Itself
// ============================================================================

type Identifier = string.regex(/^[a-z][a-zA-Z0-9_]*$/)
type TypeName = string.regex(/^[A-Z][a-zA-Z0-9_]*$/)
type ImportPath = string.regex(/^(\.\/|\.\.\/|@)[a-zA-Z0-9_\/\.\-]+$/)

// Frontmatter metadata fields
type FrontmatterMetadata = {
  id: Identifier,
  title: string.maxLength(120),
  summary: string.maxLength(500),
  loading: LoadingStrategy,
  keywords: List<string>,
  related: List<ImportPath>,
  version?: SemVer
}

enum LoadingStrategy {
  OnDemand,    // Load only when explicitly requested by agent
  ByRule,      // Load based on context matching rules
  Manual,      // Require explicit user approval before loading
  Eager        // Load immediately when agent starts
}

// ============================================================================
// Type System
// ============================================================================

// Primitive refinement types
type RefinedString = string
  .minLength(n: int)
  .maxLength(n: int)
  .regex(pattern: Regex)
  .email()
  .url()
  .uuid()
  .nonEmpty()

type RefinedNumber = number
  .min(n: number)
  .max(n: number)
  .positive()
  .negative()
  .integer()

// Composite types
type Option<T> = Some(T) | None
type Result<T, E> = Ok(T) | Err(E)
type List<T> = [T]
type Dict<K, V> = Map<K, V>

// Union types
type MediaAttachment = Image | Video | Audio | Document

// Structural types with validation
type Email = string.email().nonEmpty()
type URL = string.url()
type Timestamp = number.positive().integer()

// ============================================================================
// Capability System
// ============================================================================

// Capabilities represent permissions that must be granted before tool execution
capability NetworkAccess {
  ask = "Allow network access for API calls and data fetching"
  scope = choice("session" | "persistent" | "once"),
  restrictions?: List<DomainRestriction>
}

capability FileSystemWrite {
  ask = "Allow writing files to disk"
  scope = choice("session" | "persistent"),
  paths?: List<PathPattern>
}

capability UserNotification {
  ask = "Allow sending notifications to user"
  scope = choice("session" | "persistent")
}

// Capabilities can be composed
capability FullDataAccess = FileSystemWrite & NetworkAccess

// ============================================================================
// Error System
// ============================================================================

// Errors carry recovery strategies and UI guidance
error NetworkError {
  message = "Network request failed"
  recovery = "Retry with exponential backoff. If persistent, check network connectivity."
  retryable = true
}

error AuthenticationError(service: string) {
  message = "Authentication failed for ${service}"
  recovery = "Request user to re-authenticate. Check if credentials are expired."
  retryable = false
}

error ValidationError(field: string, expected: string) {
  message = "Field '${field}' validation failed. Expected: ${expected}"
  recovery = "Fix the input data and retry the operation."
  retryable = true
}

error RateLimitError(resetAt: Timestamp) {
  message = "Rate limit exceeded. Resets at ${resetAt}"
  recovery = "Wait until ${resetAt} before retrying. Consider batching requests."
  retryable = true,
  retryAfter = resetAt
}

// ============================================================================
// Tool Definitions
// ============================================================================

// Tools are functions with explicit error handling and capability requirements
tool httpGet(
  // The URL to fetch
  url: URL,
  // Optional headers to include
  headers?: Dict<string, string>,
  // Timeout in milliseconds
  timeout?: number.positive().default(30000)
) -> string
  requires NetworkAccess
  throws NetworkError, AuthenticationError, RateLimitError

tool writeFile(
  // Path where file should be written
  path: string.nonEmpty(),
  // Content to write
  content: string,
  // Whether to create parent directories
  createDirs?: bool.default(false)
) -> void
  requires FileSystemWrite
  throws ValidationError, FileSystemError

tool notifyUser(
  // Notification title
  title: string.maxLength(60),
  // Notification body
  body: string.maxLength(200),
  // Priority level
  priority?: choice("low" | "normal" | "high").default("normal")
) -> void
  requires UserNotification
  throws NotificationError

Type System Features

Refinement Types

AiLang uses refinement types to add runtime validation constraints to base types:

type Username = string.minLength(3).maxLength(20).regex(/^[a-z0-9_]+$/)
type Age = number.positive().integer().max(150)
type Email = string.email().nonEmpty()

Algebraic Data Types

Support for sum types (unions) and product types (structs):

type Result<T, E> = Ok(T) | Err(E)
type User = { id: UUID, email: Email, name: string }

Generic Types

Parameterized types for reusability:

type Option<T> = Some(T) | None
type List<T> = [T]

Capability Model

Capabilities represent permissions that must be granted before tool execution. They serve three purposes:

  1. Explicit Consent: Users know exactly what permissions agents require
  2. Scope Control: Permissions can be session-limited or persistent
  3. Audit Trail: All capability grants are logged for security review
// An agent needs to fetch data from an API and save it locally

tool fetchAndSave(apiUrl: URL, outputPath: string) -> Result<void, Error>
  requires NetworkAccess, FileSystemWrite
  throws NetworkError, ValidationError, FileSystemError {

  // Implementation would go here
}

// When invoked, user sees:
// "Agent requests permissions:"
// ✓ NetworkAccess: "Allow network access for API calls and data fetching"
// ✓ FileSystemWrite: "Allow writing files to disk"

Error Handling Philosophy

Errors in AiLang are not just type signatures - they carry recovery strategies:

// Traditional approach (poor for AI):
tool sendEmail(...) throws NetworkError

// AiLang approach (rich context):
error NetworkError {
  message = "Network request failed"
  recovery = "Retry with exponential backoff. If persistent, check network connectivity."
  retryable = true
}

// Agent can now intelligently handle the error:
try {
  sendEmail(recipient, subject, body)
} catch NetworkError {
  // Agent knows to retry with backoff
  wait(exponentialBackoff(attemptNumber))
  retry()
}

Module System

AiLang supports importing definitions and skills from other documents:

// Import specific definitions
from emailSkill import sendEmail, Email

// Import entire module
import authModule from "./auth.md"

// Use imported tools
tool sendNotification(...) {
  authModule.requireAuth()
  sendEmail(...)
}

Context Management and Detail Levels

Context management is a critical feature of AiLang, designed specifically for AI agents operating within limited context windows. Documents can be loaded at different detail levels, allowing agents to start with lightweight summaries and progressively load more information as needed.

The Context Challenge

AI agents face a fundamental constraint: limited context windows. A comprehensive skill document might contain:

  • Detailed type definitions
  • Full tool signatures with all parameters
  • Extensive error handling documentation
  • Multiple examples and use cases
  • Domain knowledge and best practices

Loading everything at once wastes valuable context space. AiLang solves this with hierarchical detail levels.

Detail Levels for Documents

Documents support five detail levels that control what information is extracted and loaded:

enum DetailLevel {
  Minimal,      // Level 0: Only metadata (title, summary, id)
  Compact,      // Level 1: Metadata + concise tool signatures
  Standard,     // Level 2: Metadata + full tool signatures + key prose
  Detailed,     // Level 3: Standard + examples + error handling
  Complete      // Level 4: Everything including all prose and documentation
}

type LoadConfig = {
  level: DetailLevel,
  // Include specific sections even if level wouldn't normally include them
  include?: List<choice("metadata" | "types" | "tools" | "errors" | "capabilities" | "examples" | "prose")>,
  // Exclude specific sections even if level would normally include them
  exclude?: List<choice("metadata" | "types" | "tools" | "errors" | "capabilities" | "examples" | "prose")>
}

tool loadDocumentWithLevel(
  path: string,
  level: DetailLevel,
  config?: LoadConfig
) -> ParsedDocument

Level 0: Minimal - Metadata Only

Extract only frontmatter for quick scanning and discovery.

// Load just metadata for quick overview
doc = loadDocumentWithLevel("./skills/email-sender.md", level=Minimal)

// Available information:
print(doc.metadata.id)        // "email-sender"
print(doc.metadata.title)     // "Email Sending and Automation Skill"
print(doc.metadata.summary)   // "Send emails with templates, scheduling..."
print(doc.metadata.keywords)  // ["email", "automation", "smtp"]

// Use case: Building a skill index/catalog
skillIndex = []
for (skillPath in discoverSkills("./skills")) {
  metadata = loadDocumentWithLevel(skillPath, level=Minimal).metadata
  skillIndex.push({
    id: metadata.id,
    title: metadata.title,
    summary: metadata.summary
  })
}

Output:

{
  id: "email-sender",
  title: "Email Sending and Automation Skill",
  summary: "Send emails with templates, scheduling, and tracking. Supports SMTP, SendGrid, and AWS SES."
}

Level 1: Compact - Concise Signatures

Include tool names and parameters without types, errors, or capabilities.

// Load compact signatures for tool discovery
doc = loadDocumentWithLevel("./skills/email-sender.md", level=Compact)

// Tool definitions at compact level:
for (tool in doc.tools) {
  // Only name and parameter names are included
  params = tool.parameters.map(p => p.name).join(", ")
  print(`${tool.name}(${params})`)
}

Output:

sendEmail(recipient, subject, body, attachments)
scheduleEmail(recipient, subject, body, sendAt)
sendBulkEmail(recipients, subject, body)

Concise Signature Format:

tool sendEmail(recipient, subject, body, attachments)
tool scheduleEmail(recipient, subject, body, sendAt)

Level 2: Standard - Full Signatures

Include complete type signatures with parameters, return types, errors, and capabilities.

// Load full signatures for understanding requirements
doc = loadDocumentWithLevel("./skills/email-sender.md", level=Standard)

for (tool in doc.tools) {
  print(`${tool.name}: ${tool.signature}`)
  print(`  Requires: ${tool.requires.join(", ")}`)
  print(`  Throws: ${tool.throws.join(", ")}`)
}

Output:

sendEmail(recipient: Email, subject: string, body: string, attachments?: List<Attachment>) -> EmailReceipt
  Requires: SendEmailCapability, NetworkAccess
  Throws: NetworkError, InvalidEmailError, SMTPError, RateLimitError

scheduleEmail(recipient: Email, subject: string, body: string, sendAt: Timestamp) -> ScheduledEmailID
  Requires: SendEmailCapability, SchedulerAccess
  Throws: InvalidTimestampError, SchedulerError

Full Signature Format:

tool sendEmail(
  recipient: Email,
  subject: string,
  body: string,
  attachments?: List<Attachment>
) -> EmailReceipt
  requires SendEmailCapability, NetworkAccess
  throws NetworkError, InvalidEmailError, SMTPError, RateLimitError

Level 3: Detailed - With Examples and Context

Include tool definitions, key documentation prose, examples, and error handling strategies.

// Load with examples for understanding usage patterns
doc = loadDocumentWithLevel("./skills/email-sender.md", level=Detailed)

// Now includes:
// - Full tool signatures
// - Error definitions with recovery strategies
// - Type definitions
// - Examples
// - Key prose sections (not all prose)

print("Tool: sendEmail")
print("Examples:")
for (example in doc.examples.filter(e => e.toolName == "sendEmail")) {
  print(example.code)
}

print("\nError handling:")
for (error in doc.errors) {
  print(`${error.name}: ${error.recovery}`)
}

Output includes:

Tool: sendEmail

Examples:
  sendEmail(
    recipient = "user@example.com",
    subject = "Welcome!",
    body = "Thanks for signing up..."
  )

  // With attachments
  sendEmail(
    recipient = "client@company.com",
    subject = "Q4 Report",
    body = "Please find attached...",
    attachments = [
      { path: "./report.pdf", type: "application/pdf" }
    ]
  )

Error handling:
  NetworkError: Retry with exponential backoff up to 3 times
  RateLimitError: Wait until resetAt before retrying
  InvalidEmailError: Validate email format before calling

Level 4: Complete - Everything

Load the entire document including all prose, documentation, design notes, and contextual information.

// Load everything for deep context
doc = loadDocumentWithLevel("./skills/email-sender.md", level=Complete)

// Includes:
// - All of Level 3
// - Full markdown prose
// - Design rationale
// - Best practices sections
// - All documentation comments
// - Implementation notes

Progressive Loading Pattern

Agents should start minimal and progressively load more detail:

from context import getCurrentContextUsage, MAX_CONTEXT_SIZE

// Start with minimal level
currentLevel = Minimal
doc = loadDocumentWithLevel("./skills/email-sender.md", currentLevel)

// Agent decides it needs tool signatures
if (needsToolSignatures()) {
  currentLevel = Compact
  doc = loadDocumentWithLevel("./skills/email-sender.md", currentLevel)
}

// Agent needs to understand error handling
if (needsErrorContext()) {
  // Check context budget
  currentUsage = getCurrentContextUsage()
  if (currentUsage + estimateSize(Detailed) < MAX_CONTEXT_SIZE) {
    currentLevel = Detailed
    doc = loadDocumentWithLevel("./skills/email-sender.md", currentLevel)
  }
}

// Only load complete if absolutely necessary
if (needsFullContext() && hasContextBudget()) {
  currentLevel = Complete
  doc = loadDocumentWithLevel("./skills/email-sender.md", currentLevel)
}

Custom Level Configuration

Override default level behavior with custom include/exclude:

// Load Standard level but also include examples
doc = loadDocumentWithLevel(
  "./skills/email-sender.md",
  level = Standard,
  config = {
    include: ["examples"]
  }
)

// Load Detailed but exclude prose to save context
doc = loadDocumentWithLevel(
  "./skills/email-sender.md",
  level = Detailed,
  config = {
    exclude: ["prose"]
  }
)

// Load only specific sections
doc = loadDocumentWithLevel(
  "./skills/email-sender.md",
  level = Minimal,
  config = {
    include: ["tools", "errors"]  // Just tools and errors, no types or prose
  }
)

Detail Levels in Tool Definitions

Individual tool definitions can exist at different detail levels within a document:

<define>

```typescript

// COMPACT: Just name and params (for quick reference)
tool quickSearch(query)

// STANDARD: Full signature (typical definition)
tool sendEmail(
  recipient: Email,
  subject: string,
  body: string
) -> EmailReceipt
  requires SendEmailCapability
  throws NetworkError, InvalidEmailError

// DETAILED: Full signature + inline documentation
tool processPayment(
  // Customer ID from database
  userId: UUID,
  // Payment amount in cents (e.g., 1000 = $10.00)
  amountCents: number.positive().integer(),
  // Payment method token from payment processor
  paymentMethodToken: string.nonEmpty(),
  // Optional idempotency key for retry safety
  idempotencyKey?: UUID
) -> PaymentReceipt
  requires PaymentProcessingCapability, DatabaseRead
  throws PaymentDeclinedError, NetworkError, DuplicatePaymentError
  {
    // Additional context:
    // - Amount must be at least 50 cents ($0.50)
    // - PaymentMethodToken should be obtained from Stripe.js
    // - IdempotencyKey prevents duplicate charges on retry
    // - Throws DuplicatePaymentError if idempotencyKey was used before
  }
```

Context Budget Management

Tools for managing context usage:

type ContextBudget = {
  // Maximum context size in tokens
  maxTokens: number.positive(),
  // Currently used tokens
  usedTokens: number,
  // Reserved tokens for agent's working memory
  reservedTokens: number,
  // Available tokens for loading documents
  availableTokens: number
}

tool estimateDocumentSize(
  path: string,
  level: DetailLevel
) -> number

tool getCurrentContextBudget() -> ContextBudget

tool optimizeContextUsage(
  requiredSkills: List<string>,
  currentBudget: ContextBudget
) -> List<{ path: string, level: DetailLevel }>
// Agent needs multiple skills but has limited context
budget = getCurrentContextBudget()

skills = [
  "./skills/email-sender.md",
  "./skills/database-query.md",
  "./skills/file-processor.md"
]

// Estimate size at different levels
for (skill in skills) {
  minimal = estimateDocumentSize(skill, Minimal)
  compact = estimateDocumentSize(skill, Compact)
  standard = estimateDocumentSize(skill, Standard)

  print(`${skill}:`)
  print(`  Minimal: ${minimal} tokens`)
  print(`  Compact: ${compact} tokens`)
  print(`  Standard: ${standard} tokens`)
}

// Optimize: Load most-used skills at higher detail
loadPlan = optimizeContextUsage(skills, budget)

for (plan in loadPlan) {
  doc = loadDocumentWithLevel(plan.path, plan.level)
  print(`Loaded ${plan.path} at ${plan.level} level`)
}

Context-Aware Loading Strategy

Runtime automatically manages context budget:

runtime = createRuntime({
  contextManagement: {
    enabled: true,
    maxTokens: 200000,
    reservedTokens: 50000,  // Reserve for agent reasoning
    autoOptimize: true,
    // When context is full, downgrade loaded documents to lower detail levels
    autoDowngrade: true,
    // Priority order for downgrading
    downgradePriority: ["least-recently-used", "least-frequently-used"]
  }
})

// Runtime automatically manages detail levels
runtime.loadSkill("./skills/email-sender.md")  // Auto-determines level

// Runtime tracks usage
runtime.useTool("sendEmail", {...})  // Marks email-sender as recently used

// When context is tight, runtime downgrades less-used skills
runtime.loadSkill("./skills/new-skill.md")
// Runtime might downgrade database-query from Standard -> Compact to make room

Metadata for Context Management

Documents should include size hints in frontmatter:

---
id: email-sender
title: Email Sending Skill
summary: Send emails with templates and scheduling
size_hints:
  minimal: 150      # tokens
  compact: 500
  standard: 2000
  detailed: 5000
  complete: 12000
---

Best Practices for Context Management

  1. Start Minimal: Always begin with Minimal level for skill discovery
  2. Load on Demand: Only increase detail level when actually needed
  3. Prioritize Active Skills: Keep frequently-used skills at higher detail levels
  4. Monitor Budget: Track context usage and downgrade when necessary
  5. Cache Strategically: Cache parsed documents at different levels
  6. Progressive Examples: Put simple examples early, complex ones later
  7. Structured Prose: Use clear sections so partial loading makes sense

Detail Level Comparison

Level Metadata Tool Names Parameters Types Errors Capabilities Examples Prose Tokens (Estimate)
Minimal ~100-200
Compact ✓ (names only) ~500-1000
Standard ✓ (with types) ✓ (names) ○ (key only) ~2000-4000
Detailed ✓ (with docs) ✓ (with recovery) ○ (main sections) ~5000-10000
Complete ✓ (full docs) ✓ (full context) ✓ (everything) ~10000-50000+

Legend: ✓ Included | ○ Partial | ✗ Excluded

Loading Strategies

Documents can specify how they should be loaded:

  • on_demand: Load only when explicitly invoked by agent or referenced
  • by_rule: Load automatically when context matches predefined patterns
  • manual: Require explicit user approval before loading
  • eager: Load immediately when agent initializes
---
id: database-admin
loading: manual  # Dangerous operations require explicit approval
---

// These tools can modify production data, so loading requires user consent
tool dropTable(name: string) -> void
  requires DatabaseAdminAccess, UserConfirmation

Best Practices

1. Co-locate Context with Definitions

Place usage guidelines, error handling advice, and domain knowledge in the same document as tool definitions.

2. Provide Rich Examples

Show not just successful cases, but error handling and tool composition:

from database import query, Transaction
from notification import notifyUser

// Example showing error handling and rollback
tool processPayment(userId: UUID, amount: number) -> Result<Receipt, Error> {
  transaction = Transaction.begin()

  try {
    user = query("SELECT * FROM users WHERE id = ?", [userId])
    receipt = chargeCard(user.paymentMethod, amount)
    transaction.commit()
    notifyUser("Payment Successful", "You were charged ${amount}")
    return Ok(receipt)
  } catch CardDeclinedError(reason) {
    transaction.rollback()
    notifyUser("Payment Failed", reason)
    return Err(CardDeclinedError(reason))
  } catch NetworkError {
    transaction.rollback()
    // Retry logic here
    return Err(NetworkError)
  }
}

3. Use Capability Hierarchies

Compose fine-grained capabilities into coarser ones:

capability ReadFiles {
  ask = "Allow reading files from disk"
}

capability WriteFiles {
  ask = "Allow writing files to disk"
}

capability FullFileAccess = ReadFiles & WriteFiles

tool syncFiles(...) -> void
  requires FullFileAccess  // Requests both read and write

4. Design Errors for Recovery

Include retry strategies, timeouts, and user-facing messages:

error RateLimitError(resetAt: Timestamp, remainingQuota: number) {
  message = "Rate limit exceeded. ${remainingQuota} requests remaining."
  recovery = "Wait until ${resetAt} before retrying. Consider reducing request frequency."
  retryable = true,
  retryAfter = resetAt,
  userMessage = "We've hit the API rate limit. Retrying in ${resetAt - now()} seconds."
}

Tooling Ecosystem

AiLang provides a comprehensive tooling suite to parse, validate, generate code, and integrate with development environments.

Parser and Extractor

The AiLang parser processes markdown documents and extracts structured information:

type ParsedDocument = {
  metadata: FrontmatterMetadata,
  prose: string,  // Markdown content outside special blocks
  definitions: List<Definition>,
  examples: List<Example>,
  rules: List<Rule>
}

type Definition = TypeDef | ErrorDef | CapabilityDef | ToolDef

type TypeDef = {
  name: TypeName,
  definition: TypeExpression,
  documentation?: string
}

type ToolDef = {
  name: Identifier,
  parameters: List<Parameter>,
  returnType: TypeExpression,
  requires: List<CapabilityName>,
  throws: List<ErrorName>,
  documentation?: string,
  detailLevel: choice("signature" | "full" | "contextual")
}

type Example = {
  id?: string,
  toolName?: Identifier,
  code: string,
  description?: string
}

// Parser tool
tool parseDocument(
  // Path to AiLang markdown file
  filePath: string,
  // Detail level for context management
  level?: DetailLevel.default(Standard)
) -> Result<ParsedDocument, ParseError>

tool parseDocumentFromString(
  // Raw markdown content
  content: string,
  // Detail level for context management
  level?: DetailLevel.default(Standard)
) -> Result<ParsedDocument, ParseError>

tool extractMetadata(
  // Raw markdown content
  content: string
) -> FrontmatterMetadata

tool extractDefinitions(
  // Raw markdown content
  content: string,
  // Detail level: Compact (names only), Standard (full sigs), Detailed (with docs)
  level?: DetailLevel.default(Standard)
) -> List<Definition>

tool extractExamples(
  // Raw markdown content
  content: string
) -> List<Example>

tool extractProse(
  // Raw markdown content
  content: string,
  // Include all prose (Complete) or only key sections (Detailed/Standard)
  level?: DetailLevel.default(Standard)
) -> string

Usage:

// Parse at Minimal level (metadata only) for quick discovery
minimalDoc = parseDocument("./skills/email-sender.md", level=Minimal)
print("Title: ${minimalDoc.metadata.title}")
print("Summary: ${minimalDoc.metadata.summary}")

// Parse at Compact level (tool names and params only)
compactDoc = parseDocument("./skills/email-sender.md", level=Compact)
for (def in compactDoc.definitions) {
  if (def is ToolDef) {
    params = def.parameters.map(p => p.name).join(', ')
    print("${def.name}(${params})")
  }
}

// Parse at Standard level (full signatures)
standardDoc = parseDocument("./skills/email-sender.md", level=Standard)
for (def in standardDoc.definitions) {
  if (def is ToolDef) {
    params = def.parameters.map(p => `${p.name}: ${p.type}`).join(', ')
    print("Tool: ${def.name}(${params}) -> ${def.returnType}")
    print("  Requires: ${def.requires.join(', ')}")
    print("  Throws: ${def.throws.join(', ')}")
  }
}

// Parse at Detailed level (includes examples and error recovery)
detailedDoc = parseDocument("./skills/email-sender.md", level=Detailed)
print("\nExamples:")
for (example in detailedDoc.examples) {
  print(example.code)
}

// Load related skills based on metadata.related
for (relatedPath in detailedDoc.metadata.related) {
  // Load related skills at lower detail level to save context
  loadSkill(relatedPath, level=Compact)
}
// Smart parsing based on context budget
import { estimateContextUsage } from "./context-manager"

currentContextUsage = estimateContextUsage()
availableContext = MAX_CONTEXT - currentContextUsage

// Choose appropriate detail level based on available context
level = availableContext > 10000 ? Detailed :
        availableContext > 5000 ? Standard :
        availableContext > 2000 ? Compact :
        Minimal

document = parseDocument("./skills/email-sender.md", level)
print(`Loaded at ${level} level (${availableContext} tokens available)`)

Validator

The validator ensures type safety, capability consistency, and semantic correctness:

type ValidationError = {
  severity: choice("error" | "warning" | "info"),
  message: string,
  location: SourceLocation,
  suggestion?: string
}

type SourceLocation = {
  file: string,
  line: number,
  column: number
}

type ValidationResult = {
  isValid: bool,
  errors: List<ValidationError>,
  warnings: List<ValidationError>
}

// Validator tool
tool validateDocument(
  document: ParsedDocument,
  // Validation strictness level
  strictness?: choice("strict" | "normal" | "loose").default("normal")
) -> ValidationResult

tool validateTypes(
  definitions: List<Definition>
) -> List<ValidationError>

tool validateCapabilities(
  tools: List<ToolDef>,
  capabilities: List<CapabilityDef>
) -> List<ValidationError>

tool validateErrorHandling(
  tools: List<ToolDef>,
  errors: List<ErrorDef>
) -> List<ValidationError>

Validation Rules:

  1. Type Consistency: All referenced types must be defined
  2. Capability Coverage: All requires must reference defined capabilities
  3. Error Coverage: All throws must reference defined errors
  4. Refinement Validity: Type refinements must be semantically valid
  5. Example Validity: Examples must type-check against tool signatures
  6. Import Resolution: All imports must resolve to valid documents
  7. Circular Dependency Detection: No circular imports
// Validate a document
result = validateDocument(parsedDocument, strictness="strict")

if (!result.isValid) {
  print("Validation failed with ${result.errors.length} errors:")

  for (error in result.errors) {
    print("  [${error.severity}] ${error.location.file}:${error.location.line}")
    print("    ${error.message}")
    if (error.suggestion) {
      print("    Suggestion: ${error.suggestion}")
    }
  }
} else {
  print("✓ Document is valid")
  if (result.warnings.length > 0) {
    print("  ${result.warnings.length} warnings:")
    for (warning in result.warnings) {
      print("  - ${warning.message}")
    }
  }
}

Code Generator

Generate runtime bindings for multiple target languages:

type TargetLanguage = choice("typescript" | "python" | "rust" | "go" | "json-schema")

type GeneratorConfig = {
  targetLanguage: TargetLanguage,
  outputDir: string,
  options: GeneratorOptions
}

type GeneratorOptions = {
  // Generate runtime validators
  generateValidators?: bool.default(true),
  // Generate type definitions
  generateTypes?: bool.default(true),
  // Generate capability enforcement
  generateCapabilities?: bool.default(true),
  // Generate error classes
  generateErrors?: bool.default(true),
  // Include documentation in generated code
  includeDocumentation?: bool.default(true),
  // Code style/formatting
  style?: JSONObject
}

tool generateCode(
  document: ParsedDocument,
  config: GeneratorConfig
) -> Result<List<GeneratedFile>, GeneratorError>

type GeneratedFile = {
  path: string,
  content: string,
  language: TargetLanguage
}

Generated Code Examples:

// Generate TypeScript bindings
result = generateCode(
  document = parsedDocument,
  config = {
    targetLanguage: "typescript",
    outputDir: "./generated",
    options: {
      generateValidators: true,
      generateCapabilities: true,
      style: { semi: true, quotes: "double" }
    }
  }
)

// Generated TypeScript output:
/*
// email-sender.generated.ts

import { z } from 'zod';

// Type definitions with runtime validation
export const EmailSchema = z.string().email().nonempty();
export type Email = z.infer<typeof EmailSchema>;

// Error classes with recovery strategies
export class NetworkError extends Error {
  readonly retryable = true;
  readonly recovery = "Retry with exponential backoff. If persistent, check network connectivity.";

  constructor(message: string) {
    super(message);
    this.name = "NetworkError";
  }
}

// Capability definitions
export enum Capability {
  SendEmail = "SendEmail",
  NetworkAccess = "NetworkAccess"
}

export interface CapabilityRequest {
  capability: Capability;
  ask: string;
  scope: "once" | "session" | "persistent";
}

// Tool interface
export interface SendEmailParams {
  recipient: Email;
  subject: string;
  body: string;
}

export async function sendEmail(
  params: SendEmailParams,
  runtime: AiLangRuntime
): Promise<Receipt> {
  // Validate parameters
  EmailSchema.parse(params.recipient);

  // Check capabilities
  await runtime.requireCapability(Capability.SendEmail);
  await runtime.requireCapability(Capability.NetworkAccess);

  try {
    // Tool implementation...
    const result = await runtime.execute("sendEmail", params);
    return result as Receipt;
  } catch (error) {
    // Error handling with recovery strategies
    if (error instanceof NetworkError) {
      await runtime.handleError(error);
      throw error;
    }
    throw error;
  }
}
*/
// Generate Python bindings
generateCode(
  document = parsedDocument,
  config = {
    targetLanguage: "python",
    outputDir: "./generated",
    options: { generateValidators: true }
  }
)

// Generated Python output:
/*
# email_sender_generated.py

from typing import List, Optional, Union
from dataclasses import dataclass
from pydantic import BaseModel, EmailStr, validator
from enum import Enum

# Type definitions with validation
class Email(BaseModel):
    value: EmailStr

    def __str__(self):
        return self.value

# Error classes
class NetworkError(Exception):
    """Network request failed"""
    retryable = True
    recovery = "Retry with exponential backoff. If persistent, check network connectivity."

# Capability enum
class Capability(Enum):
    SEND_EMAIL = "SendEmail"
    NETWORK_ACCESS = "NetworkAccess"

@dataclass
class CapabilityRequest:
    capability: Capability
    ask: str
    scope: str  # "once" | "session" | "persistent"

# Tool function
async def send_email(
    recipient: Email,
    subject: str,
    body: str,
    runtime: 'AiLangRuntime'
) -> 'Receipt':
    """Send an email to a recipient"""

    # Validate parameters
    recipient_validated = Email(value=recipient)

    # Check capabilities
    await runtime.require_capability(Capability.SEND_EMAIL)
    await runtime.require_capability(Capability.NETWORK_ACCESS)

    try:
        result = await runtime.execute("send_email", {
            "recipient": str(recipient_validated),
            "subject": subject,
            "body": body
        })
        return result
    except NetworkError as e:
        await runtime.handle_error(e)
        raise
*/

Language Server Protocol (LSP)

Provide IDE support with autocomplete, diagnostics, and hover information:

capability IDEIntegration {
  ask = "Allow IDE integration for development support"
  scope = "persistent"
}

tool startLanguageServer(
  // Port to listen on
  port?: number.positive().integer().default(7878),
  // Enable debug logging
  debug?: bool.default(false)
) -> LanguageServer
  requires IDEIntegration

type CompletionItem = {
  label: string,
  kind: choice("type" | "tool" | "capability" | "error" | "keyword"),
  documentation?: string,
  insertText?: string,
  detail?: string
}

tool getCompletions(
  document: string,
  position: { line: number, character: number }
) -> List<CompletionItem>

tool getDiagnostics(
  document: string
) -> List<ValidationError>

tool getHoverInfo(
  document: string,
  position: { line: number, character: number }
) -> string

tool gotoDefinition(
  document: string,
  position: { line: number, character: number }
) -> SourceLocation

LSP Features:

  1. Autocomplete: Type names, tool names, capabilities, built-in functions
  2. Diagnostics: Real-time validation and error reporting
  3. Hover: Show type information, documentation, examples
  4. Go to Definition: Jump to type/tool/capability definitions
  5. Find References: Find all usages of a definition
  6. Rename: Safely rename identifiers across files
  7. Code Actions: Quick fixes for common issues
  8. Semantic Highlighting: Context-aware syntax highlighting

Command Line Interface (CLI)

// CLI commands

tool ailang_parse(
  file: string,
  // Output format
  format?: choice("json" | "yaml" | "pretty").default("pretty")
) -> void

tool ailang_validate(
  file: string,
  strictness?: choice("strict" | "normal" | "loose").default("normal")
) -> void

tool ailang_generate(
  file: string,
  lang: TargetLanguage,
  output: string
) -> void

tool ailang_run(
  file: string,
  // Execute examples in the document
  example?: string
) -> void

tool ailang_install(
  // Package name or URL
  package: string
) -> void

tool ailang_search(
  // Search term
  query: string,
  // Search in descriptions, types, tools
  in?: choice("all" | "tools" | "types" | "capabilities")
) -> void

CLI Usage:

# Parse and display document structure
ailang parse email-sender.md --format=json

# Validate a document
ailang validate email-sender.md --strictness=strict

# Generate TypeScript bindings
ailang generate email-sender.md --lang=typescript --output=./generated

# Run an example from the document
ailang run email-sender.md --example=sendWelcomeEmail

# Install a skill package
ailang install @ailang/github-workflow

# Search for tools across installed packages
ailang search "send email" --in=tools

Package Manager

type Package = {
  name: string.regex(/^(@[a-z0-9-]+\/)?[a-z0-9-]+$/),
  version: SemVer,
  description: string,
  author: string,
  repository?: URL,
  license: string,
  keywords: List<string>,
  dependencies: Dict<string, SemVer>,
  main: string  // Entry point file
}

tool installPackage(
  packageName: string
) -> Result<Package, InstallError>

tool publishPackage(
  packageDir: string
) -> Result<void, PublishError>

tool searchPackages(
  query: string,
  tags?: List<string>
) -> List<Package>

Package Structure:

my-skill/
├── ailang.json          # Package manifest
├── README.md            # Documentation
├── main.md              # Entry point skill
├── lib/
│   ├── helpers.md       # Helper tools
│   └── types.md         # Shared types
└── examples/
    └── usage.md         # Usage examples

ailang.json:

{
  "name": "@myorg/email-automation",
  "version": "1.0.0",
  "description": "Email automation skill with scheduling and templates",
  "author": "Your Name",
  "license": "MIT",
  "keywords": ["email", "automation", "templates"],
  "main": "main.md",
  "dependencies": {
    "@ailang/builtin": "^1.0.0",
    "@ailang/scheduling": "^2.1.0"
  }
}

IDE Integration

Support for popular editors:

VS Code Extension:

  • Syntax highlighting for AiLang markdown
  • IntelliSense powered by LSP
  • Live validation with inline diagnostics
  • Quick fixes and refactoring
  • Integrated documentation viewer
  • Example runner

JetBrains Plugin:

  • Full IDE integration
  • Code completion and navigation
  • Refactoring tools
  • Built-in validator

Vim/Neovim:

  • Syntax files
  • LSP integration via nvim-lspconfig
  • ALE/Syntastic support

Runtime System

The AiLang runtime enforces capabilities, validates types, handles errors, and manages skill loading.

Execution Model

type RuntimeConfig = {
  // Capability enforcement mode
  capabilityMode: choice("strict" | "permissive" | "audit"),
  // Type validation mode
  validationMode: choice("strict" | "runtime" | "none"),
  // Error handling strategy
  errorStrategy: choice("throw" | "return" | "log"),
  // Module cache directory
  cacheDir?: string.default("./.ailang/cache"),
  // Enable performance monitoring
  enableMonitoring?: bool.default(false)
}

type Runtime = {
  config: RuntimeConfig,
  capabilities: CapabilityRegistry,
  moduleLoader: ModuleLoader,
  typeValidator: TypeValidator,
  errorHandler: ErrorHandler
}

// Initialize runtime
tool createRuntime(
  config: RuntimeConfig
) -> Runtime

// Execute a tool with capability checking
tool executeToolWithRuntime(
  runtime: Runtime,
  toolName: Identifier,
  params: JSONObject
) -> Result<JSONValue, Error>
  requires ToolExecution

Capability Enforcement

The runtime enforces capability requirements before tool execution:

from runtime import createRuntime, executeToolWithRuntime

// Initialize runtime with strict capability enforcement
runtime = createRuntime({
  capabilityMode: "strict",
  validationMode: "runtime",
  errorStrategy: "throw"
})

// Register capability grant callback
runtime.capabilities.onCapabilityRequest((request: CapabilityRequest) => {
  // Show UI prompt to user
  granted = promptUser(
    title = "Capability Request",
    message = request.ask,
    options = ["Allow Once", "Allow for Session", "Allow Always", "Deny"]
  )

  if (granted.includes("Allow")) {
    scope = granted.includes("Once") ? "once" :
            granted.includes("Session") ? "session" :
            "persistent"

    runtime.capabilities.grant(request.capability, scope)
    return true
  }

  return false
})

// Try to execute a tool
try {
  result = executeToolWithRuntime(
    runtime,
    toolName = "sendEmail",
    params = {
      recipient: "user@example.com",
      subject: "Hello",
      body: "World"
    }
  )

  print("Email sent: ${result}")

} catch CapabilityDeniedError(capability) {
  print("User denied capability: ${capability}")
} catch ValidationError(field, reason) {
  print("Validation failed for ${field}: ${reason}")
}

Capability Registry:

type CapabilityRegistry = {
  // Check if capability is granted
  isGranted(capability: string) -> bool,

  // Request capability grant from user
  request(capability: CapabilityRequest) -> bool,

  // Grant a capability with scope
  grant(capability: string, scope: string) -> void,

  // Revoke a capability
  revoke(capability: string) -> void,

  // List all granted capabilities
  listGranted() -> List<CapabilityGrant>,

  // Audit log of capability usage
  getAuditLog() -> List<CapabilityAuditEntry>
}

type CapabilityGrant = {
  capability: string,
  grantedAt: Timestamp,
  scope: choice("once" | "session" | "persistent"),
  usageCount: number
}

type CapabilityAuditEntry = {
  capability: string,
  action: choice("requested" | "granted" | "denied" | "used" | "revoked"),
  timestamp: Timestamp,
  context: JSONObject
}

Type Validation Runtime

Validate types at runtime using generated validators:

from runtime import TypeValidator

validator = TypeValidator()

// Define type with refinements
EmailType = validator.defineType({
  name: "Email",
  base: "string",
  refinements: [
    { kind: "email" },
    { kind: "nonEmpty" }
  ]
})

// Validate at runtime
result = validator.validate("user@example.com", EmailType)
if (result.isValid) {
  print("✓ Valid email")
} else {
  print("✗ Validation failed: ${result.errors.join(', ')}")
}

// Complex type validation
UserType = validator.defineType({
  name: "User",
  base: "struct",
  fields: {
    id: { type: "number", refinements: [{ kind: "positive" }, { kind: "integer" }] },
    email: { type: "Email" },
    age: { type: "number", refinements: [{ kind: "min", value: 0 }, { kind: "max", value: 150 }] },
    tags: { type: "List", elementType: "string" }
  }
})

user = {
  id: 123,
  email: "user@example.com",
  age: 30,
  tags: ["developer", "ai-enthusiast"]
}

result = validator.validate(user, UserType)
// result.isValid == true

Error Handling Runtime

The runtime provides intelligent error handling with recovery strategies:

type ErrorHandler = {
  // Register error type with recovery strategy
  registerError(error: ErrorDef) -> void,

  // Handle error with automatic recovery
  handleError(error: Error, context: JSONObject) -> Result<void, Error>,

  // Get recovery strategy for error type
  getRecoveryStrategy(errorType: string) -> string,

  // Log error for debugging
  logError(error: Error, context: JSONObject) -> void
}
from runtime import ErrorHandler

errorHandler = ErrorHandler()

// Register error with recovery strategy
errorHandler.registerError({
  name: "RateLimitError",
  message: "Rate limit exceeded",
  recovery: "Wait until ${resetAt} before retrying. Use exponential backoff.",
  retryable: true,
  retryAfter: "resetAt"  // Field name containing retry timestamp
})

// Automatic error handling
try {
  result = callAPI("https://api.example.com/data")
} catch RateLimitError(resetAt) {
  // Runtime automatically handles based on recovery strategy
  handled = errorHandler.handleError(error, { resetAt })

  if (handled.isOk()) {
    // Error was handled (e.g., waited and retried)
    result = handled.unwrap()
  } else {
    // Recovery failed, propagate error
    throw handled.error
  }
}

Module Loading System

Load and cache AiLang documents with dependency resolution:

type ModuleLoader = {
  // Load a module by path or package name
  load(path: string, level?: DetailLevel) -> Result<ParsedDocument, LoadError>,

  // Load with specific loading strategy
  loadWithStrategy(path: string, strategy: LoadingStrategy, level?: DetailLevel) -> Result<ParsedDocument, LoadError>,

  // Resolve dependencies with context-aware detail levels
  resolveDependencies(
    document: ParsedDocument,
    // Detail level for dependencies (typically lower than main document)
    dependencyLevel?: DetailLevel.default(Compact)
  ) -> Result<List<ParsedDocument>, LoadError>,

  // Get from cache at specific detail level
  getFromCache(path: string, level?: DetailLevel) -> Option<ParsedDocument>,

  // Upgrade already-loaded module to higher detail level
  upgradeDetail(path: string, newLevel: DetailLevel) -> Result<ParsedDocument, LoadError>,

  // Downgrade loaded module to lower detail level (free up context)
  downgradeDetail(path: string, newLevel: DetailLevel) -> Result<ParsedDocument, LoadError>,

  // Clear cache
  clearCache() -> void,

  // Get cache statistics by detail level
  getCacheStats() -> Dict<DetailLevel, CacheStats>
}

type LoadError = ModuleNotFoundError | CircularDependencyError | ParseError | ContextBudgetExceededError
from runtime import ModuleLoader

loader = ModuleLoader({
  cacheDir: "./.ailang/cache",
  enableCaching: true,
  contextManagement: {
    enabled: true,
    autoAdjustLevels: true
  }
})

// Load main skill at Detailed level (need examples and context)
mainSkill = loader.load("./skills/email-automation.md", level=Detailed)

if (mainSkill.isOk()) {
  document = mainSkill.unwrap()

  // Automatically resolve and load dependencies at lower detail level
  // Dependencies loaded at Compact by default to save context
  dependencies = loader.resolveDependencies(document, dependencyLevel=Compact)

  for (dep in dependencies.unwrap()) {
    print("Loaded dependency: ${dep.metadata.id} at Compact level")

    // Check loading strategy
    if (dep.metadata.loading == "manual") {
      // Request user approval
      approved = promptUser(
        title = "Load Skill",
        message = "Skill '${dep.metadata.title}' requires manual approval.\n\n${dep.metadata.summary}",
        options = ["Allow", "Deny"]
      )

      if (!approved) {
        print("User denied loading: ${dep.metadata.id}")
        continue
      }
    }

    // Register tools from dependency
    for (toolDef in dep.definitions.filter(d => d is ToolDef)) {
      runtime.registerTool(toolDef)
    }
  }
}

// Later, if we need more detail about a dependency
httpSkill = loader.upgradeDetail("./skills/http-client.md", Standard)
print("Upgraded http-client to Standard level (now includes types and errors)")

// If context is tight, downgrade less-used skills
loader.downgradeDetail("./skills/old-skill.md", Minimal)
print("Downgraded old-skill to Minimal level to free up context")
from runtime import ModuleLoader, ContextMonitor

loader = ModuleLoader({
  contextManagement: {
    enabled: true,
    maxTokens: 100000,
    autoAdjustLevels: true,
    strategy: "adaptive"
  }
})

monitor = ContextMonitor()

// Load skills with automatic context management
skills = [
  "./skills/email-automation.md",
  "./skills/database-query.md",
  "./skills/file-processor.md",
  "./skills/http-client.md"
]

for (skill in skills) {
  // Loader automatically chooses detail level based on available context
  result = loader.load(skill)  // level determined automatically

  if (result.isOk()) {
    doc = result.unwrap()
    actualLevel = doc.metadata.loadedAtLevel
    print(`Loaded ${skill} at ${actualLevel} level`)
  }
}

// Monitor context usage
usage = monitor.getUsage()
print(`\nContext usage: ${usage.used} / ${usage.max} tokens (${usage.percentage}%)`)
print(`Skills loaded:`)
for ([path, level] in usage.loadedSkills) {
  print(`  ${path}: ${level} level (${usage.sizeBySkill[path]} tokens)`)
}

// As agent uses tools, loader adjusts detail levels
runtime.useTool("sendEmail", {...})  // email-automation marked as active

// Loader might automatically:
// 1. Upgrade email-automation from Compact -> Standard (frequently used)
// 2. Downgrade file-processor from Standard -> Compact (rarely used)
// 3. Keep http-client at Standard (dependency of email-automation)

print("\nAfter usage optimization:")
for ([path, level] in loader.getCurrentLevels()) {
  print(`  ${path}: ${level} level`)
}

Caching and Optimization

type CacheStrategy = choice("none" | "memory" | "disk" | "hybrid")

type CacheConfig = {
  strategy: CacheStrategy,
  // Cache TTL in seconds
  ttl?: number.positive().default(3600),
  // Maximum cache size in bytes
  maxSize?: number.positive().default(100_000_000),  // 100MB
  // Cache invalidation strategy
  invalidation: choice("ttl" | "lru" | "manual")
}

// Document cache for parsed and validated documents
type DocumentCache = {
  get(path: string) -> Option<ParsedDocument>,
  set(path: string, document: ParsedDocument) -> void,
  invalidate(path: string) -> void,
  clear() -> void,
  stats() -> CacheStats
}

type CacheStats = {
  hits: number,
  misses: number,
  hitRate: number,
  size: number,
  entryCount: number
}

Monitoring and Debugging

capability Monitoring {
  ask = "Allow monitoring and performance tracking"
  scope = "session"
}

type RuntimeMonitor = {
  // Track tool execution
  onToolExecute(callback: (toolName: string, params: JSONObject, startTime: Timestamp) -> void),

  // Track tool completion
  onToolComplete(callback: (toolName: string, result: JSONValue, duration: number) -> void),

  // Track errors
  onError(callback: (error: Error, context: JSONObject) -> void),

  // Track capability requests
  onCapabilityRequest(callback: (capability: CapabilityRequest) -> void),

  // Get execution metrics
  getMetrics() -> RuntimeMetrics
}

type RuntimeMetrics = {
  totalToolExecutions: number,
  averageExecutionTime: number,
  errorRate: number,
  capabilityDenialRate: number,
  cacheHitRate: number,
  toolMetrics: Dict<string, ToolMetrics>
}

type ToolMetrics = {
  executionCount: number,
  totalDuration: number,
  averageDuration: number,
  errorCount: number,
  lastExecutedAt: Timestamp
}
from runtime import createRuntime, RuntimeMonitor

runtime = createRuntime({
  enableMonitoring: true
})

monitor = runtime.monitor

// Track tool executions
monitor.onToolExecute((toolName, params, startTime) => {
  console.log(`[${startTime}] Executing ${toolName}`)
})

monitor.onToolComplete((toolName, result, duration) => {
  console.log(`[COMPLETE] ${toolName} took ${duration}ms`)

  // Alert on slow executions
  if (duration > 5000) {
    alert(`Tool ${toolName} is slow: ${duration}ms`)
  }
})

monitor.onError((error, context) => {
  console.error(`[ERROR] ${error.name}: ${error.message}`)
  console.error(`Context: ${JSON.stringify(context)}`)

  // Send to error tracking service
  sendToSentry(error, context)
})

// Periodic metrics reporting
setInterval(() => {
  metrics = monitor.getMetrics()

  print("=== Runtime Metrics ===")
  print(`Total tool executions: ${metrics.totalToolExecutions}`)
  print(`Average execution time: ${metrics.averageExecutionTime}ms`)
  print(`Error rate: ${metrics.errorRate * 100}%`)
  print(`Cache hit rate: ${metrics.cacheHitRate * 100}%`)

  // Per-tool metrics
  for ([toolName, toolMetrics] in Object.entries(metrics.toolMetrics)) {
    print(`\n${toolName}:`)
    print(`  Executions: ${toolMetrics.executionCount}`)
    print(`  Avg duration: ${toolMetrics.averageDuration}ms`)
    print(`  Error count: ${toolMetrics.errorCount}`)
  }
}, 60000)  // Every minute

Runtime Configuration Examples

// Development configuration - permissive, detailed logging
devRuntime = createRuntime({
  capabilityMode: "permissive",  // Auto-grant capabilities
  validationMode: "strict",      // Strict type validation
  errorStrategy: "throw",        // Throw errors for debugging
  enableMonitoring: true
})

// Production configuration - secure, optimized
prodRuntime = createRuntime({
  capabilityMode: "strict",      // Always request user approval
  validationMode: "runtime",     // Validate at runtime only
  errorStrategy: "return",       // Return errors as values
  enableMonitoring: true
})

// Testing configuration - isolated, no side effects
testRuntime = createRuntime({
  capabilityMode: "audit",       // Log but don't enforce
  validationMode: "strict",      // Strict validation
  errorStrategy: "log",          // Log errors, don't throw
  enableMonitoring: false
})

Future Directions

  1. Formal Verification: Generate runtime validators from type definitions
  2. Cross-Language Compilation: Compile AiLang to TypeScript, Python, Rust tool bindings
  3. Capability Inference: Automatically infer required capabilities from tool implementations
  4. Interactive Refinement: Allow agents to propose new tool definitions based on task needs
  5. Versioning and Migration: Support evolving tool interfaces with backward compatibility
  6. WebAssembly Runtime: Compile AiLang to WASM for portable, sandboxed execution
  7. Distributed Execution: Support for executing tools across multiple nodes
  8. Visual Debugging: Interactive debugger with step-through execution
  9. Performance Profiling: Identify bottlenecks and optimization opportunities
  10. Auto-documentation: Generate comprehensive API docs from AiLang files

Comparison to Other IDLs

Feature AiLang OpenAPI gRPC JSON Schema
Type System ✓ Rich refinements ✓ Basic ✓ Basic ✓ Basic
Error Handling ✓ Recovery strategies ○ Status codes ○ Status codes ✗ None
Capability Model ✓ Explicit ✗ None ✗ None ✗ None
Examples ✓ Embedded ○ External ✗ None ○ External
Domain Context ✓ Prose + Definitions ✗ None ✗ None ✗ None
AI-Native ✓ Designed for agents ✗ Human-centric ✗ Machine-centric ✗ Validation-only
// Complete workflow example: Building a content publishing system

from http import httpGet, httpPost
from storage import writeFile, readFile
from ai import generateSummary, improveWriting

type Article = {
  title: string.maxLength(120).nonEmpty(),
  body: string.minLength(100).nonEmpty(),
  author: Email,
  tags: List<string>,
  publishedAt?: Timestamp
}

capability PublishContent {
  ask = "Allow publishing content to your blog"
  scope = "session"
}

error DuplicateArticleError(existingId: UUID) {
  message = "Article with similar title already exists: ${existingId}"
  recovery = "Either update the existing article or choose a different title."
  retryable = false
}

tool publishArticle(article: Article) -> Result<UUID, Error>
  requires PublishContent, NetworkAccess
  throws NetworkError, DuplicateArticleError, ValidationError {

  // Improve writing quality
  improved = improveWriting(article.body)

  // Generate summary
  summary = generateSummary(improved)

  // Check for duplicates
  existing = httpGet("https://api.blog.com/articles?title=" + article.title)
  if (existing.count > 0) {
    return Err(DuplicateArticleError(existing[0].id))
  }

  // Publish
  response = httpPost(
    "https://api.blog.com/articles",
    {
      ...article,
      body: improved,
      summary: summary,
      publishedAt: now()
    }
  )

  // Save backup locally
  writeFile(
    "./backups/${response.id}.json",
    JSON.stringify(response)
  )

  return Ok(response.id)
}

Implementation Status

Component Status Description
Language Specification ✓ Complete Core syntax, types, capabilities, errors, context management
Context Management ✓ Complete Detail levels (Minimal, Compact, Standard, Detailed, Complete)
Parser ○ Planned Markdown parser with detail-level extraction
Validator ○ Planned Type checking and semantic validation
Code Generator ○ Planned TypeScript, Python, Rust bindings
LSP Server ○ Planned IDE integration support
CLI Tools ○ Planned Command-line utilities
Runtime ○ Planned Capability enforcement, context-aware module loading
Context Budget Manager ○ Planned Automatic context optimization and level adjustment
Package Manager ○ Planned Skill package distribution
Standard Library ○ In Progress Built-in types, errors, capabilities
Example Skills ✓ Complete GitHub, ETL, Social Media examples

Legend: ✓ Complete | ● In Progress | ○ Planned | ✗ Not Started

Getting Started (Future)

Once tooling is implemented, the typical workflow will be:

# Install AiLang CLI
npm install -g ailang

# Create a new skill
ailang init my-skill

# Validate your skill
ailang validate my-skill/main.md

# Generate TypeScript bindings
ailang generate my-skill/main.md --lang=typescript --output=./src

# Run examples
ailang run my-skill/main.md --example=demo

# Publish to package registry
ailang publish my-skill/

Status: Draft Specification v0.3.0 Last Updated: 2026-01-31 Contributors: Your vision for AI-native interface definitions License: To be determined

Changelog:

  • v0.3.0 (2026-01-31): Added critical context management system with 5 detail levels (Minimal, Compact, Standard, Detailed, Complete) for efficient context window usage. Updated parser, module loader, and runtime to support context-aware loading. This addresses the core requirement from manifesto.md for variable-detail tool definitions.
  • v0.2.0 (2026-01-31): Added comprehensive tooling ecosystem and runtime system sections
  • v0.1.0 (2026-01-31): Initial specification with type system, capabilities, errors, and examples
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment