Node SDK を 5 分で動かす
@tansr/sdk は tansr カーネルの headless な言語バインディングです。prompt を入れるとイベントが流れ出てくる、UI 依存ゼロのライブラリです。クエリループ、ツールスケジューリング、権限エンジン、コンテキスト圧縮はすべてカーネル由来でコンパイル時にインライン化されており、手に入るのは tansr CLI と同じランタイムを、ライブラリの形態であなたのアプリに組み込んだものです。本ページは @tansr/sdk 0.19.0(2026-10-10 公開)に基づいて確認しています。プロセス内の createSession の使い方は 0.13.0 以降変わっていません。
アプリケーションプロンプトはどこで設定するか
Section titled “アプリケーションプロンプトはどこで設定するか”プラットフォームアプリの systemPrompt は共有の役割設定に、SDK の system はコードで管理する業務セグメントに使います。デフォルトの fallback では、明示した system([] を含む)がプラットフォームのセグメントを置き換えます。プラットフォームで prepend を選ぶと、先にプラットフォームのセグメントを保持し、その後に SDK のセグメントを追加します。[] でもプラットフォームのセグメントは保持されます。ホスト環境の説明は systemAppend に置いてください。デフォルトの上書きは発生しません。
Windows の Electron でも SDK はメインプロセスで実行し、renderer が送るのはユーザー入力です。アプリケーションプロンプトとポリシー機能は @tansr/sdk 0.13.0 以降で利用できます(プラットフォーム側は 2026-09-14 に本番公開済み)。読み取り専用の session.applicationPrompt で出所とポリシーを確認できますが、本文は返しません。プラットフォームのプロンプトとポリシーは次の新しいターンの前に更新され、現在実行中のターンは固定されます。元のセッションと履歴は保持され、セッションを作り直す必要はありません。完全な真理値表、プラットフォームの PUT / GET、実行できるサンプルはアプリケーションシステムプロンプトを参照してください。
タスクの実行中に要件を追加したいときは、同一ターンへの追加入力の getInputTarget / submitInput と受領確認の照会を使います。現在の実行を中断したり、新しいセッションを作ったりする必要はありません。初期版は memory テキストのみで、@tansr/sdk 0.13.0 / @tansr/serve 0.8.0 / CLI 0.6.0 以降で利用できます。
| 要件 | 値 |
|---|---|
| Node.js | ≥ 22.19 |
| Electron(該当する場合) | ≥ 39。SDK はメインプロセスで実行 |
| モジュール形式 | ESM only("type": "module"。CJS の require() は非対応) |
| TypeScript | target ≥ ES2022。Electron プロジェクトでは skipLibCheck: true を推奨 |
リリース物は単一ファイルの ESM bundle と単一ファイルの .d.ts です。サードパーティのランタイム依存は undici、zod、zod-to-json-schema のみ。オプション依存の @vscode/ripgrep はインストールに失敗しても自動でフォールバックするので、対処は不要です。
インストール
Section titled “インストール”npm install @tansr/sdk # 现行 0.19.00.18.0 以降、パッケージにはサブエントリ @tansr/sdk/extensions(アーカイブホスト / キャッシュホスト)と 9 か所の任意のシグネチャ追加が同梱されています。0.19.0 では、プラットフォームの非チャット操作クライアント createPlatformNonchatClient が独立したものとして加わりました(埋め込み / リランキング / ドキュメント / 音楽 / ボイス / リアルタイムセッションなどのプラットフォーム操作を明示的に HTTP で呼び出すもので、セッション履歴には入らず、ツールとしても組み込まれません)。いずれも追加のみで、本ページのルートエントリの使い方と挙動は変わりません。使わないなら読む必要はありません。エージェントをサーバー側に置き、Android / iOS / HarmonyOS や @tansr/api-client のような薄いクライアントから HTTP 経由で接続させるには、@tansr/serveを使います。新規の統合には統一呼び出し面 /api を使ってください。
認証情報:モデルの取得元は 3 段階、1 つ選ぶ
Section titled “認証情報:モデルの取得元は 3 段階、1 つ選ぶ”SDK がモデルをどこから取得するかで、必要な認証情報が決まります。
| 段階 | 渡すもの | 用途 |
|---|---|---|
| トークン方式 | { token, baseUrl } |
端末への配布(Electron / デスクトップ)。モデルカタログと機能フラグはプラットフォームがアプリ設定に応じて配信し、ローカル設定はゼロ |
| マネージド方式(BYOK) | model: 'エイリアス' + ローカルの .tansr/settings.json |
自分のサーバー / スクリプト。モデルの API キーを自分で用意 |
| 注入方式 | { client, model } をペアで |
テスト(スクリプト化したモデル)またはカスタム接続 |
3 方式は互いに排他で、混在させるとアセンブリ段階で invalid_options として拒否されます。このページではトークン方式を例にします。エージェントをエンドユーザーに届けるときの正しい形態だからです。
トークン方式の認証情報フローは「三者クローズドループ」です。
- コンソールでデスクトップアプリ(またはサーバーアプリ)を作成し、
appidとappkeyを取得します。appkey はあなたのサーバー側にだけ置きます。 - 端末アプリは自前のログイン状態であなたのサーバーにリクエストします。あなたのサーバーは appkey で
POST /v1/app-tokensを呼び出し、そのユーザー向けに短期のapp_userトークン(ttlSeconds60–86400)を発行し、{ token, expiresAt }だけを端末に返します。 - 端末アプリはこのトークンを SDK に渡します。
公式サンプル examples/token-server に、トークン発行エンドポイントの完全な書き方(リクエスト署名を含む)があります。appkey は決してあなたのサーバーの外に出さない——端末に配らない、ログに書かない、エラーレスポンスに入れない、リポジトリに入れない。
自分のマシンでスクリプトを動かすだけなら、まずマネージド方式でも構いません。.tansr/settings.json に provider を宣言し(API キーは環境変数名だけを書き、値は環境変数で渡す)、createSession({ model: 'main' }) を呼びます。
最初のセッション
Section titled “最初のセッション”import { createSession } from '@tansr/sdk';
// token 由你的服务端换发;baseUrl 是平台网关地址const session = await createSession({ token, baseUrl: 'https://api.tansr.com' });
session.send('帮我总结这份合同');
for await (const event of session.events) { if (event.type === 'msg.text.delta') process.stdout.write(event.text); if (event.type === 'turn.completed') break;}
session.close();要点:
createSessionは async です。常にawaitしてください。send()はアイドル時に新しいターンを開始します。実行中にもう一度send()すると、カーネルの注入バリアを経由して現在のターンに合流し、入力は失われません。eventsはターンをまたいで連続し、seqが単調増加するAsyncIterable<KernelEvent>です。複数のコンシューマーが同時にfor awaitでき、それぞれが全量を受け取ります。close()は冪等です。close()を呼ばないとfor awaitは自然に終了しません——これが「イベントストリームが止まったまま」の最も多い原因です。
イベントを見る
Section titled “イベントを見る”イベントはフラットな discriminated union なので、event.type で直接分岐できます。最初に動かすときは、型をすべて出力して 1 ターンの中で何が起きるかを見てみるのがおすすめです。
for await (const event of session.events) { console.log(event.seq, event.type);}おおよそ次のような並びが見えます:session.created → turn.started → いくつかの msg.block.start / msg.text.delta / msg.block.end →(ツール呼び出しがあれば)tool.proposed / tool.permission.decided / tool.started / tool.completed → cost.usage.updated → turn.completed。
UI を作るなら、イベントを手で組み立てないでください。createSessionView でイベントストリームを不変のビュースナップショットに還元し、createNarrator で人間が読めるログ行を生成します。どちらもパッケージに同梱されています。
最初によくつまずく点
Section titled “最初によくつまずく点”| 現象 | 原因と対処 |
|---|---|
invalid_options が投げられる |
3 方式のフィールドを混在させた、またはトークン方式で config / capabilities を渡した(トークン方式の機能フラグは常にプラットフォームが管理)。メッセージを読んでコードを直す |
assembly_failed が投げられる |
マネージド方式の設定が使えない、エイリアスの解決に失敗した、またはトークン方式で bundle の取得に失敗した。cause に下層のエラーが残る |
| ツールがすべて拒否される | permission.askUser を接続しておらず、ツールが読み取り専用でない——デフォルトは fail-closed。セッションとイベントストリームを参照 |
| イベントストリームが終了しない | session.close() を忘れている |
次のステップ
Section titled “次のステップ”- セッションとイベントストリーム:マルチターンのセマンティクス、イベントファミリー、SessionView への投影。
- チェックポイントと再開:永続化、再起動をまたいだ再開、手動の圧縮とスナップショット。
- プラットフォームアセンブリとバンドル:機能フラグ、ツールの 3 リング、トークン方式で配信されるもの。
- エラー処理と再試行:SDK のエラーコード、プラットフォームのエラーコード、再試行すべきものとすべきでないもの。
- SDK 2.0 拡張エントリ:0.18.x で公開済みの
@tansr/sdk/extensions、@tansr/serve/extensions、統一呼び出し面/apiの公開状況、境界、性能の開示。プロセス内統合に移行は不要です。
このページは役に立ちましたか?
フィードバックありがとうございます。この記事の改善に活かします。