What's new in TypeScript

Development update — 6 September 2026. These improvements are verified in local TypeScript SDK builds; this is not a package release announcement or a claim of parity across every language SDK.

  • Responsive cancellation: abort a run while an async stop condition is pending, then continue the same session. Read the cancellation contract.
  • Typed rate-limit events: inspect provider, model, HTTP status, and retry timing without automatically retrying a rate-limited session. Handle rate limits.
  • Verified packaged runtime: refreshed bundled CLI targets and an installed-package check covering stop/resume, cancellation, and HTTP 429. Check runtime compatibility.

Why we built this

Autohand Code started in the CLI. Teams then asked for editor integrations, so we added ACP and a JSON protocol for external clients. The next request was more direct: teams wanted the agent loop inside product surfaces, internal tools, terminals, dashboards, and deployment flows.

The Code Agent SDK is that embedding layer. Start an agent, stream every event, handle permission requests, and keep session state close to the app that owns the workflow.

main.ts

import { AutohandSDK } from '@autohandai/agent-sdk';

async function main() {
  const sdk = new AutohandSDK({ cwd: '.', debug: true });
  await sdk.start();

  for await (const event of sdk.streamPrompt({
    message: 'List the main source files and tell me what looks risky.'
  })) {
    if (event.type === 'message_update') {
      process.stdout.write(event.delta);
    }
  }

  await sdk.stop();
}

main();

main.py

import asyncio
from autohand_sdk import AutohandSDK

async def main():
    async with AutohandSDK(cwd='.') as sdk:
        async for event in sdk.stream_prompt('List the main source files and tell me what looks risky.'):
            if event['type'] == 'message_update':
                print(event.get('delta', ''), end='')

asyncio.run(main())

main.go

package main

import (
    "context"
    "fmt"
    "log"

    autohand "github.com/autohandai/agent-sdk-go"
)

func main() {
    ctx := context.Background()
    sdk := autohand.NewSDK(&autohand.Config{CWD: "."})

    if err := sdk.Start(ctx); err != nil {
        log.Fatal(err)
    }
    defer sdk.Close()

    events, err := sdk.StreamPrompt(ctx, &autohand.PromptParams{
        Message: "List the main source files and tell me what looks risky.",
    })
    if err != nil {
        log.Fatal(err)
    }

    for event := range events {
        if e, ok := event.(autohand.MessageUpdateEvent); ok {
            fmt.Print(e.Delta)
        }
    }
}

Main.java

import ai.autohand.sdk.sdk.Agent;
import ai.autohand.sdk.sdk.AgentOptions;
import ai.autohand.sdk.types.Events;

public final class Main {
    public static void main(String[] args) throws Exception {
        Agent agent = Agent.create(AgentOptions.builder()
            .cwd(".")
            .instructions("Be concise and specific.")
            .build());

        var run = agent.send("List the main source files and tell me what looks risky.");
        run.stream(event -> {
            if (event instanceof Events.MessageUpdateEvent mue) {
                System.out.print(mue.delta());
            }
        });
        agent.close();
    }
}

main.swift

import AgentSDK
import Foundation

let provider = OpenAIProvider(apiKey: "sk-...")
let agent = Agent(
    name: "Reviewer",
    instructions: "Be concise and specific.",
    tools: [.readFile, .bash],
    model: ModelID("gpt-4o"),
    provider: provider
)

let stream = Runner.runStream(
    agent: agent,
    prompt: "List the main source files and tell me what looks risky."
)

for try await event in stream {
    if event.type == .content, let data = event.data {
        print(data, terminator: "")
    }
}

main.rs

use autohand_sdk::{Agent, Config, Result};

#[tokio::main]
async fn main() -> Result<()> {
    let mut agent = Agent::create(
        Config::from_env()
            .with_cwd(".")
            .with_instructions("Review code with senior Rust judgement."),
    )
    .await?;

    let result = agent
        .run("List the main source files and tell me what looks risky.")
        .await?;

    println!("{}", result.text);
    agent.close().await?;
    Ok(())
}

main.rb

require "autohand_sdk"

AutohandSDK::Agent.open(
  cwd: ".",
  instructions: "Review code with staff-level Ruby judgement.",
  permission_mode: "interactive"
) do |agent|
  run = agent.send("List the main source files and tell me what looks risky.")

  run.stream.each do |event|
    print event["delta"] if event["type"] == "message_update"
  end

  result = run.wait
  puts result.fetch(:text)
end

Program.cs

using Autohand.CodeAgentSdk;

await using var agent = await Agent.CreateAsync(new AgentOptions
{
    WorkingDirectory = ".",
    Instructions = "Review code with staff-level C# judgement.",
});

var run = agent.Send("List the main source files and tell me what looks risky.");

await foreach (var item in run.StreamAsync())
{
    if (item is MessageUpdateEvent message)
    {
        Console.Write(message.Delta);
    }
}

var result = await run.WaitAsync();
Console.WriteLine(result.Text);

main.cpp

#include <autohand/sdk.hpp>
#include <iostream>

int main() {
  autohand::Agent agent(
      autohand::Config::from_environment()
          .with_cwd(".")
          .with_instructions("Review code with senior C++ judgement."));

  auto run = agent.send("List the main source files and tell me what looks risky.");

  run.stream([](const autohand::SdkEvent& event) {
    if (event.type == "message_update") {
      std::cout << event.text_delta();
    }
  });

  auto result = run.wait();
  std::cout << result.text << "\n";
  agent.close();
}

Language status

The SDK family now includes the CLI-backed wrappers for TypeScript, Python, Go, Java, Rust, Ruby, C#/.NET, and C++, plus the native Swift SDK.

TypeScript

TypeScript

Mainline SDK for Node.js, Bun apps, CLIs, and internal tooling.

Read the guide
Python

Python

Async-first wrapper with typed event parsing and clean lifecycle management.

Read the guide
Go

Go

Context-aware package with typed events and channel-based streaming.

Read the guide
Java

Java

JVM wrapper with builder-style configuration and sealed event types.

Read the guide
Swift

Swift

Native Swift concurrency with local tools, hooks, and agent loop strategies.

Read the guide
Rust

Rust

Tokio-based crate with typed events, stream-based runs, and JSON helpers.

Read the guide
Ruby

Ruby

Ruby gem with enumerator streams, Rails-friendly configuration, and JSON helpers.

Read the guide
C#/.NET

C#/.NET

.NET package with IAsyncEnumerable, CancellationToken, and System.Text.Json.

Read the guide
C++

C++

Modern C++20 package with CMake targets and typed event callbacks.

Read the guide

Core workflow

Every CLI-backed SDK page in this section follows the same runtime path.

  • Start or create an agent session.
  • Send a prompt or prompt params object.
  • Stream message_update, tool_*, and permission_request events.
  • Reply to approvals when the runtime pauses.
  • Wait for the final result or keep the session alive for the next run.

What you get

Events

Stream the runtime

Build terminal UIs, approval flows, logs, and structured automations from typed events instead of scraping plain text output.

Permissions

Control autonomy

Choose interactive review, restricted execution, or unattended runs, then answer approval requests from your own interface.

Sessions

Keep context alive

Reuse an agent across prompts, preserve history, and separate planning steps from execution inside the same application flow.

Runtime control

Operate the CLI through typed APIs

Reset conversations, hand off browser sessions, run auto-mode, answer approval protocols, attach history, manage MCP and learning, and inspect the live tool registry.

Open runtime controls
Tools

Extend the agent

Use built-in file, shell, git, and search tools, then add MCP or custom tools when your product needs domain-specific actions.

Next steps

Quickstart

Pick a language, install the SDK, and run a first prompt with current package names.

Open quickstart

Approvals

Wire the permission flow so your app can pause, ask, allow, or deny cleanly.

Read approvals

CLI runtime control

Use the full cross-language control surface for sessions, auto-mode, MCP, learning, tools, and context.

Read runtime controls

Language guides

Jump into the language-specific setup and event examples for your runtime.

Start with TypeScript