LinkSense
開発者ガイド

インタラクティブなアプリケーションを構築する

名前でリソース宣言を生成し、マニフェストを設定し、リソースを照合しアプリを共有し、その後タスクを送信し、SDKでビジネスイベントを受け取ります。

このページは自動翻訳されています。 英語の原文を見る。

インタラクティブアプリケーションは、ワークフローフォーム、可視化、コントロールをLinkSense内に収めます。 あなたのコードはサンドボックスのないiframe上で動作し、LinkSenseチャットは右側の別のペインに配置され、タスクの進行状況、フォーム、承認、添付ファイル、アーティファクトが保持されます。 ユーザーは仕切りをドラッグして両方のペインのサイズを変えることができ、チャットはアプリのUIをカバーしません。

組み込み会話開発

組み込みのlinksense-interactive-app-builderスキルは、linksense_core.open_application_developmentを使って現在の通常のタスクでプロジェクトを作成または起動します。 既存のデプロイ可能なディレクトリを提供するか、プラットフォームにSDKスターターを生成させることができます。 linksense_core.inspect_application_developmentファイルの同期を行い、プレビュー状態、ソース検証失敗、ブラウザの診断を返します。 両ツールは通常のコラボレーションモードでは所有者の積極的な開発ターンに限定されています。どちらもアプリケーションのインストールも公開もしません。

ソースはタスクワークスペース内の別のディレクトリに存在します。 開いたパネルは1.5秒ごとに境界された静的ディレクトリをチェックします。 安定したスナップショットはZIPインポートと同じパッケージ検証を通過し、不可変プレビューパッケージとなります。 隠しファイル、シンボリックリンク、プライベートファイル、node_modulesはこのディレクトリの外に置いてください。 フレームワークソースはそれと並存し、コンパイルされた静的出力が登録ディレクトリに書き込まれます。

新規開発タスクはオーナーの「制作アプリ」プロジェクトに属し、オンデマンドで作成され、プロジェクト間を移動することはできません。 既存の開発は元のプロジェクトとファイルを保持します。 返source_directoryに編集してビルドし、~を現在のユーザーのホームに展開します。 通常のチャットがアプリを最初に作成した際、アクティブターンは元のワーキングディレクトリを保持します。返されたソースの場所はすでに専用プロジェクトに属しており、その後のターンはそのプロジェクトワークスペースを使用します。 既存の静的ディレクトリをインポートすると、そのデプロイ可能なファイルを新しい開発にコピーし、元のディレクトリは変更されません。ビルドソースは自動的に移動するわけではありません。

プレビューでは本物のSDKを別のアプリケーションタスクで実行します。 アクティブなテストは、終了まで元のパッケージを保持します。 Configure Capabilitiesはプラグイン、スキル、ナレッジベース、MCPサーバーの検索、追加、削除をサポートしており、まだ依存関係のないアプリケーションも含まれます。 セーブチェックはリソースの所有権と可用性を確認し、実際のリソースUUIDや名前をソースmanifest.jsonにdependencies.plugins、skills、knowledge_bases、mcp_serversに書き込み、プレビューを再構築します。 その他のマニフェストフィールドやコードファイルも保存されています。 インストールとアップデートは同じ構成でパッケージ化します。 エディターが開いた後にソースが変更された場合、保存レポートが競合となり、設定の再読み込みが必要です。 スクリプトエラーや未処理の約束拒否はデバッグログに現れ、バージョンごとのレポート数20に限定され、サーバー上で編集されます。 診断テキストは信頼できないアプリケーション出力として扱いましょう。

インストールはレビュー済みソースダイジェストを送信します。 サーバーはソースとリソースを再度確認し、アプリケーションバージョンとプロジェクトインストール状態を一つのトランザクションで保存します。 インストール済みバージョンは後のプレビューの変更に依存しません。 継続開発は既存アプリケーションでも機能します。初回使用は現在の静的パッケージからファイルを復元します。後の利用者たちは元のプロジェクトを再開します。 インポートされたパッケージに存在しないビルドソースは復元できません。

アプリのアイコン、名前、説明

現在の開発プロジェクトのメタデータを編集するにはlinksense_core.update_application_metadataに連絡してください。 まずはsource_hashを検査し、その後descriptionまたはiconのnameを提示してください。 省略されたフィールドは保存されます。description: null説明をクリアする。

アイコンは{ "type": "preset", "preset": "book-open" }または{ "type": "file", "path": "uploads/logo.png" }を受け入れます。 このタスクのワークスペースに対して実際の画像パスを使ってください。 絶対パス、隠れたパス、シンムリンクは拒否されます。 ツールとエディターの両方がPNG、JPEG、WebPのいずれかを受け入れており、最大512 KiBおよび片面1024ピクセルまで対応可能です。 プラットフォームは画像をアプリディレクトリにコピーし、そのマニフェストを更新し、元の画像、コード、リソースの選択を保持します。 アイコンは一時的な添付URLに依存しません。

開発ヘッダーのアイコンボタンと、My Applicationsのドラフトの「アプリ詳細編集」アクションは同じセーブフローを使っています。 それらを適用するために草稿編集を公開しましょう。 インストールされたアプリケーションの編集は現在のメタデータを変更します。共有版やリスト版は再公開が必要です。

パッケージ構成

manifest.jsonとindex.htmlを直接含むルートのZIPを作成します。

manifest.json
index.html
app.js
styles.css
assets/
  logo.png

アーカイブは最大10 MiBまで、最大30 MiBまで拡張、最大200ファイルのみ、5 MiBを超える個別ファイルはありません。 依存ディレクトリ、キャッシュ、シンボリックリンク、サーバーコード、認証情報は含めないでください。 .DS_Storeや.gitのような隠しファイルやディレクトリ、文字の大小文字だけ異なるファイルパスはインポート失敗の原因となります。

サポートされる拡張機能は、.html、.css、.js、.mjs、.json、.map、.txt、.png、.jpg、.jpeg、.webp、.gif、.svg、.ico、.woff、.woff2です。 ビルドツールを使用する場合は、生成された静的ファイルのみをパッケージ化し、./app.jsや./assets/logo.pngなどのバンドルされたアセットの相対参照を設定してください。 フォント、スクリプト、スタイル、画像は外部CDNからバンドルまたはロード可能です。

マニフェスト

manifest.jsonアプリケーションの識別子、必要なリソース、タスク指示、SDK権限、ビジネスイベント契約を記述します。 LinkSenseはインポート時に検証し、タスク作成時に採用されたパッケージを記録し、実行時には対応するバージョンの権限やイベント定義を使用します。 公開されたサービスは、以下に説明するように、後の実行時に新しいバージョンを採用することができます。

最小構成

最初のバージョンが入力のみを収集して作業を開始する場合は、この構成から始めてください。 明確にtasks:writeを要求しています。その他のオプションフィールドはデフォルトを使用します:

manifest.json
{
  "schema_version": 1,
  "id": "research-workbench",
  "name": "Research workbench",
  "version": "1.0.0",
  "sdk_version": 1,
  "permissions": ["tasks:write"]
}

このファイルをindex.htmlと一緒にパッケージ化してください。 ページは作業の送信や中断を許可しますが、ビジネスイベントは禁止されているため、ユーザーはネイティブのLinkSenseチャットペインで結果を閲覧できます。

最上位フィールド参照

以下のストリング制限は、リードとトライの空白をトリミングした後に適用されます。 マニフェストのルートおよび個々のcustom_events定義は未知の場を拒否します。 author、homepage、model、mcp_server_idsなどのフィールドを追加しないでください。

フィールド種類と制限必須/デフォルト意味と効果推奨される実践
schema_version整数。1のみ対応必須プラットフォームによる解析方法を決めるManifestファイル形式のバージョンです。1のままにしてください。アプリケーションをリリースする際は、このフィールドではなくversionを変更します。
id文字列、1–120文字;^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$に一致必須パッケージ内のアプリケーション識別子(例:research-workbench)です。プラットフォームが割り当てるアプリケーションUUIDではありません。安定した小文字名にハイフンで区切られた単語を使い、更新ごとに変更せず、バージョン番号は省略してください。 同じidをインポートしても自動的にアプリケーションが上書きされるわけではありません。ターゲットアプリケーションのメニューから更新してください。
name文字列、1–160文字必須アプリケーションリストなどの場所でユーザーに表示される名前;インポートやパッケージアップデートは、この情報をアプリケーション名に書き込んでいます。「リサーチワークベンチ」のような短く認知度の高いビジネス名を使い、バージョンや専門用語をまとめて使わないでください。
versionx.x.x形式の文字列必須アプリケーションバージョンラベル;同じレーベルのアップデートは、パッケージとリリースのレコードが別々に存在します。更新時にバージョンを維持または上げることはできますが、下げることはできません。
description文字列またはnull;最大4,000文字任意;nullユーザー向けのアプリケーション概要;インポートと更新をアプリケーション説明に書き込むことができます。 これはタスク指示ではありません。ユースケース、期待される入力、出力について説明してください。 指定できるのは単一の文字列であり、翻訳オブジェクトではありません。
instructions文字列またはnull;最大20,000文字任意;nullアプリケーションレベルのタスク指示。 実行時には、宣言されたイベント名、記述、ペイロードスキーマも付加されます。安定したビジネス目標、出力要件、イベントトリガーを記述してください。 この投稿のフォーム入力をtasks.run().promptに入れてください。 このフィールドを省略するかnullを使うとプラットフォームの基本命令が選択されます。空文字列はそうではありません。
icon文字列またはnull;1–500文字のパス任意;nullパッケージ内の画像へのパス(アプリケーションアイコンとして使用);外部画像URLではありません。assets/logo.pngのような相対経路を使いましょう。 PNG、JPEG、WebPに対応しており、1次元あたり最大512 KiBおよび8,192ピクセルまで対応しています。 圧縮した正方形の画像を推奨します。 パスは/から始まることも、..を含むこともできません。 画像とicon_presetを省略しても、更新時には既存のアイコンが保持されます。 プリセットを選ぶには、iconをnullに設定し、icon_presetを指定してください。
icon_presetbook-open、sparkles、code-xmlなどのプリセットアイコン識別子オプション画像が提供されていない場合はプリセットを選択します。また、カスタム画像のフォールバックにもなります。エディターまたはメタデータツールを使ってサポートする値を選択してください。
entry文字列。サポートされているのは"index.html"のみです任意;"index.html"iframeで開いたエントリードキュメント;ZIPの根に存在しなければなりません。デフォルトはそのままにしておく。 完全なURLやネストされたエントリドキュメント、フロントエンドルートは使わないでください。
sdk_version整数;サポートされているのは1のみです必須ページで使用されるLinkSense SDKプロトコルバージョン。下記の完全な経路を使って/sdk/v1.jsを装填します。 SDKの文字列バージョン"1.0.0"は使わないでください。
permissions権限文字列の配列;最大6、重複なし任意;以下の元の5つの許可(files:writeを除く)ページが呼び出せるSDK機能を制御します。現在のユーザーのリソースアクセスを拡大するわけではありません。必要なものを明確にリストアップしましょう。 ["tasks:write"]は作業開始のみに使ってください。 []はこれらの機能を求めていません。フィールドを省略すると、files:writeを除く元の5つの権限を要求します。
custom_eventsイベント定義の配列;最大でも50、名前は独特です任意;[]タスクがアプリケーションに表示および復元のために提供できる構造化されたビジネスデータを宣言します。まずは「セクション準備完了」などの意味のあるイベントから始めましょう。チャットデルタやツールログを中心にイベントを設計しないでください。

必要な資源の申告とマッチング

フィールド種類と制限必須/デフォルト意味と行動推奨される実践
dependenciesplugins、skills、mcp_servers、knowledge_bases配列を持つオブジェクト任意;各配列はデフォルトで[]各エントリーは { "id": "resource UUID", "name": "display name" }。 最大50プラグインとスキルを組み合わせ、MCPサーバー 20、ナレッジベース20。リソースUUIDでマッチングし、名前やスラッグで合わないでください。 名前は表示用のヒントで、1–160文字です。 プラグインやスキル間でのUUIDの重複も拒否されます。

リソース宣言を名前で生成します

アプリ開発時にリソースUUIDを手動で調べる必要はありません:

  1. マイアプリケーション → アプリケーションを作成を開き、操作可能なアプリをインポートカードの右下にあるリソース宣言一覧をクリックします。
  2. 名前で検索し、アプリに必要なリソースを選択してください。 各カテゴリーはより広い画面で2つの列を使用し、独自のすべて選択コントロールがあります。 プラグイン、スキル、MCPサーバー、ナレッジベースの選択は他のカテゴリには影響しません。 検索時には、検索結果をすべて選択はそのカテゴリの現在の結果のみに影響し、他の選択は保持されます。
  3. dependencies の JSON をコピーをクリックします。 コピーしたdependenciesフィールドをnameとversionの隣でmanifest.jsonに追加します。 既存の依存関係フィールドを置き換えます。ファイル全体を上書きしないでください。

このツールは、所有している利用可能なリソースの名前やUUIDを入力します。 アプリの作成、リソースのコピー、認証情報のエクスポート、アクセスの付与は行いません。 他のユーザーや環境は、パッケージをインポートする際にリソースをマッチングする必要がある場合があります。 宣言の上限を超える場合は、コピー前に選択範囲を減らしてください。

リソース行は名前のみを表示します。 丸みを帯びた枠付きの行のどこかをクリックすると、選択または解除できます。 各カテゴリ見出しは、そのリストの選択したカウントを示しています。フッターは常に選択の総数を示します。 広い画面では左側のリソースを選択し、右側に常に表示される宣言のプレビューを表示し、選択に応じて更新されます。 小さい画面では、これらのセクションは縦に積み重ねられます。 コピーが失敗した場合はプレビューテキストを選択して手動でコピーしてください。

リソースが不足している場合は、あなたの現在の口座が所有していること、そして利用可能であることを確認しましょう。 閲覧可能なリソースや、他の人が共有したリソースはリストにありません。 何も選択されていない場合はコピーが無効になります。アプリにそのようなリソースが不要ならdependencies省略してください。

生成されたオブジェクトには4つのリソース配列すべてが含まれます。選択されていないカテゴリは空の配列です。 以下のUUIDはあくまで例です:

dependencies.json
{
  "dependencies": {
    "plugins": [{ "id": "10000000-0000-4000-8000-000000000001", "name": "Document tools" }],
    "skills": [{ "id": "20000000-0000-4000-8000-000000000001", "name": "Procurement review" }],
    "mcp_servers": [{ "id": "30000000-0000-4000-8000-000000000001", "name": "Procurement system" }],
    "knowledge_bases": [{ "id": "40000000-0000-4000-8000-000000000001", "name": "Procurement policies" }]
  }
}

パッケージに宣言を追加します

リソース宣言一覧はdependenciesを含むJSONオブジェクトを生成し、完全なアプリ構成を生成しません。 そのフィールドを既存のmanifest.jsonに統合し、追加のdependenciesオブジェクトを入れ子したり、既存の指示や権限、イベントを削除したりせずに行えます。 例えば、スキルとナレッジベースを選択した後:

manifest-with-dependencies.json
{
  "schema_version": 1,
  "id": "policy-assistant",
  "name": "Policy assistant",
  "version": "1.0.0",
  "sdk_version": 1,
  "permissions": ["tasks:write"],
  "dependencies": {
    "plugins": [],
    "skills": [{ "id": "20000000-0000-4000-8000-000000000001", "name": "Policy review" }],
    "mcp_servers": [],
    "knowledge_bases": [{ "id": "40000000-0000-4000-8000-000000000001", "name": "Company policies" }]
  }
}

サンプルUUIDをリソース宣言リストで生成される値に置き換え、ファイル名をmanifest.jsonし、さらに THE index.html やその他の静的ファイルでパッケージ化します。 リソース名は表示用のヒントに過ぎず、同じ名前が必ずしも同じリソースを識別するわけではありません。 UUIDを名前で置き換えないでください。

構成質問に答える何をしないのか
dependenciesアプリにはどのプラグイン、スキル、MCPサーバー、ナレッジベースが必要ですか?リソースをインストールしたりコピーしたり、認証情報を携帯したり、リソースへのアクセスを許可したりしてください。
permissionsアプリケーションページはどのSDKメソッドを呼び出せるのでしょうか?リソース宣言を置き換えたり、リソースを自動的にバインドしたりします。
インポート後のリソース設定この口座が所有する実際の資源は、申告を満たすものは何でしょうか?元のパッケージのUUIDを変更するか、公開されたバージョンを直接変更してください。

タスクのみを提出するアプリは、たとえスキルや知識ベースが必要であってもtasks:writeだけをリクエストできます。 リソースリストを読み取る必要がある場合にのみリソース読み取り権限を追加してください。

リソースのインポートと設定

インポートプレビューは、UUIDをインポート者が所有する正しい種類の利用可能なリソースとのみ照合します。 パッケージインポートまたは更新ダイアログで、同じタイプの他の所有リソースにマッチしていないエントリをマッピングします。 元の宣言および未解決の州は保持されます。 すべての宣言は、ドラフトを実行または公開する前に解決されなければなりません。 宣言はリソースをコピーしたり、認証情報を含んだり、アクセス権を与えたりしません。 無効化または削除されたリソースも対処しなければなりません。

  1. 操作可能なアプリをインポートで郵便番号を選択し、その申告されたリソースを確認してください。
  2. 名前の横に黄色の丸で囲まれた感嘆符があるということは、利用可能なリソースがまだ設定されていることを意味します。 右側のピッカーで同じ種類のリソースを検索して選択してください。 緑色に丸をつけたチェックマークとは設定済みです。
  3. 選択を変更するには、ピッカーの右端にあるクリアアイコンを使い、再度選択します。 クリアリングはリソースやその宣言を削除するものではありません。
  4. リソースの設定が完了したら、インポートまたは更新をクリックします。 リソースが不足している場合は、ダイアログの指示に従って設定を完了し、再試行してください。

更新、共有、掲載

パッケージの更新は、変更されていないタイプ/UUIDペアに対して、明示的な空選択を含むマッピングを保持します。 新しい宣言は自動マッチングを試みます。削除された宣言は拘束力がありません。 マッピングはドラフトに属し、パッケージUUIDを書き換えるものではありません。 公開されたバージョンは独自のリソーススナップショットを保持し、新しいバージョンが共有またはリストアップされるまで不完全なドラフトの影響を受けません。

開発版およびパッケージの更新は、作成者のみが有効です。 パッケージ、リソースバインディング、リリースレコード、インストールの変更が一つのトランザクションで行われます。 失敗すると部分的な構成は残りません。 保存して共有するか、センターの出品を別途更新してください;受信者は手動で新しいバージョンをインストールします。

インタラクティブアプリはオンラインサービスとして共有またはリストアップのみ可能であり、コピーやインストールはできません。 ユーザーはリマッピングせずに作成者のバウンドされたリソースを使用します。認証情報はサーバーに残ります。 標準アプリは許可があればインストール可能です。 既存のインタラクティブコピーは独立したアプリとして残りますが、ソースからコピーされた更新を受け取ることはありません。 過去の設置のみの助成金は自動的にサービス助成金にはなりません。作成者は共有権限を変更しなければなりません。 dependenciesのない既存のパッケージは読みやすく、使いやすく残ります。

権限の選択

権限は対応するSDKメソッドを可能にします。 プラグインをインストールしたり、リソースアクセスを付与したりしません。 タスクは作成者によって割り当てられたリソースを使用し、ページ内のユーザーが提供した任意のリソースIDではありません。 許可なしの通話はLINKSENSE_SDK_PERMISSION_DENIEDで失敗します。

許可をSDKメソッド返送されたデータまたは効果リクエストのタイミング
user.profile:readcontext.getCurrentUser()現在のユーザーのid、name、avatar_url、language。ユーザー情報の表示やインターフェース言語の選択時;そうでなければ省略してください。
capabilities:readresources.listCapabilities()スキルとプラグインの要約:id、name、type、description、status、can_select、logo_url。現在のユーザーのスキルやプラグインの概要を表示する。 リストを読んでもアプリケーションの設定されたリソースは変わりません。
knowledge_bases:readresources.listKnowledgeBases()ナレッジベースの要約:id、name、description、lifecycle_status、availability_status。現在のユーザーのナレッジベースの要約を表示します。 アプリケーションタスクは、このリストとは独立して作成者が設定したナレッジベースを使用します。
mcp_servers:readresources.listMcpServers()MCPのサービス概要:id、name、status、transport;住所も資格もありません。接続情報を表示する際に。 この許可は直接MCP通話を公開せず、tasks.run() mcp_server_idsも受け入れません。
tasks:writetasks.run(input), tasks.interrupt(turnId), tasks.getState(), tasks.onStateChange(...)現在のアプリケーションタスクで作業を提出するか、指定されたターンの中断を要求します。生成、送信、停止のコントロール。 受け入れ失敗や作業中の競合を処理しましょう。
files:writefiles.upload(file), files.list(), files.remove(fileId)このアプリケーションタスクの添付ファイルをアップロードし一覧表示してください。未提出ファイルを削除してください。アップロード時には明確にこの許可を求めてください。 古い申請にはデフォルトで付与されません。

ready()、events.on(...)、chat.show()/hide()/toggle()は追加の許可は不要です。 メソッド名を新しい権限文字列として追加しないでください。 リソースリストメソッドは{ items: [...] }を返します。 リードメソッドは要旨を露出し、パスワード、トークン、MCPの認証情報、能力ソース、ナレッジベースの内容は公開しません。

執筆指示

descriptionユーザーがアプリケーションを使うかどうかを判断するのに役立ちます。instructionsタスクの実行を導き、tasks.run().promptこの提出が何を達成すべきかを明記しています。 これらは分けて保管し、申請のガイダンスとフォーム入力が独立して変わるようにしましょう。

instructionsを以下のように整理する:

  1. 事業目標:解決すべき問題と、その範囲外に含まれているもの。
  2. 成果物:必要な結論、セクション、または出力、そしてユーザーに欠けている情報を求めるタイミング。
  3. イベントトリガー:各イベントをいつ送信するか、そしてそれが1つのレコードを表すのか完全なスナップショットを表すのか。
  4. チャットの責任:ネイティブチャットでのフォームや承認のコミュニケーションと処理;適切なビジネスデータのみをアプリケーションに送信してください。

以下の完全な例は、各研究セクションが準備完了した後にイベントを送信します。 「必要に応じてイベントを送信する」といった曖昧なルールは避け、秘密情報や固定ユーザー識別、特定の提出物のすべての値を長寿命命令に含めないこと。

カスタムイベントフィールド参照

各custom_events項目には以下のフィールドがあります。 イベント名は一致^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$、linksense.、conversation.、turn.、item.で始まることはできません。

フィールド種類と制限必須/デフォルト意味と効果推奨される実践
custom_events[].name文字列、1–120文字、上記の命名ルールに従います。パッケージ内で唯一無二です必須宣言、タスクのエミッション、リスナーをつなぐ正確な名前events.on(name, handler)。ビジネスドメインと、research.section_readyのようなすでに起こったアクションを使いましょう。 3か所すべてで綴りを合わせ、updateのような曖昧な名前は避けてください。
custom_events[].description文字列は、1–2,000文字;トリミング後の非空必須イベントをいつ発信し、そのデータが何を意味するかを説明します。契約とともに実行中のモデルに供給されます。トリガー、細分度、そして「準備できたら完全なセクション要約を送信する」などの意味論を更新してください。同じセクションIDが以前の内容に置き換わる」と述べています。
custom_events[].schema_version整数、1–1,000任意;1イベントに随えて提供されたこのイベントのデータ契約のバージョン;マニフェスト形式やパッケージ版とは独立しています。フィールドの種類、意味、または必要なルールが変更されたときにインクリメントし、ハンドラーとパッケージを同時に更新version。 古いデータを自動で変換するわけではありません。
custom_events[].payload_schemaJSON Schema オブジェクト;トップレベルのtypeは明確に"object"必須許可されたイベントデータを定義します。 スキーマはインポート時にコンパイルされ、ペイロードは排出時にチェックされ、無効なデータは提供されません。JSONスキーマ2020-12を使い、型と必須フィールドを指定し、バウンディング文字列と配列を配置します。 未定義データを除外する方がadditionalProperties: false。

執筆payload_schema

LinkSenseは既存のAjv 2020バリデーターを使ってイベント契約を締結しています。 以下の一般的なキーワードは、ほとんどの小規模事業イベントをカバーしています。 オプションおよび追加のフィールド行動についてはJSON スキーマオブジェクト参照、方言サポートについてはAjvのJSON Schemaドキュメントを参照してください。

キーワード意味と効果推奨される実践
$schemaオプションのJSON Schema方言宣言;含まれる場合は、https://json-schema.org/draft/2020-12/schemaを使いましょう。2020-12を明確に宣言し、編集者やプラットフォームが契約を一貫して解釈できるようにしましょう。
typeデータ型を制約します。 イベントの根はobjectでなければなりません。フィールドはstring、number、integer、boolean、array、objectなどのタイプを使うことがあります。すべてのフィールドに型を与え、ネストされたオブジェクト構造を完全に定義します。
propertiesオブジェクトフィールドとその制約を記述します。財産を申告するだけでは必須ではありません。インターフェースに必要なビジネスフィールドのみを、安定名を用いて含めてください。
required存在しなければならないフィールド名の配列。 これがなければ、propertiesのフィールドは任意となります。結果の表示や計算に必要なフィールドを要求すること;オプションフィールドの空状態を定義します。
additionalProperties契約外のフィールドが受け入れられるかどうかを制御します。デフォルトで許可されています。通常は false に設定されており、入れ子状オブジェクトでも別々に設定されます。
descriptionペイロードのビジネス分野を説明しています。データ生成の指針となる単位、ソース、識別子の安定性を記述すること;これは検証ルールではありません。
minLength / maxLength文字列の長さを制約します。タイトルや要約のUIに適した制限を設定すること;必須テキストは一般的にminLength: 1が必要です。
enum値を指定された集合に制限します。ステータスや優先度としてhigh、medium、lowなどの安定コードを使用し、表示用に翻訳します。
items / maxItems配列要素と最大アイテム数を定義します。バウンドテーブルの行とリスト;大きな成果を小さく意味のあるビジネスイベントに分割しましょう。

スキーマ自体やJSON.stringify(payload)が生成した文字列ではなく、スキーマに合致するJSONオブジェクトを送ってください。 各ペイロードにはJSON.stringify(payload).length <= 65,536の制限もあります。 イベントはその制限より大きく下に抑え、ファイルや長いレポートはLinkSenseのアーティファクトとして提供してください。

完全な構成例

このバージョンでは研究を開始し、セクションイベントを受け取るため、要求はtasks:writeのみです。 ユーザー情報やリソースリストは読み取っていません。ピッカーを追加する際に対応する権限を追加してください。

manifest.json
{
  "schema_version": 1,
  "id": "research-workbench",
  "name": "Research workbench",
  "version": "1.0.0",
  "description": "Collect research criteria and display structured progress.",
  "instructions": "Research the topic in the user's current submission. Ask for missing information in native chat first. After completing each independently useful section, use emit_application_event to send research.section_ready with a stable section_id, title, and summary. When updating a section, reuse its section_id and send the complete summary. Give the full research conclusions in native chat. Do not send chat deltas, reasoning, or tool progress as business events.",
  "icon": null,
  "entry": "index.html",
  "sdk_version": 1,
  "permissions": ["tasks:write"],
  "custom_events": [
    {
      "name": "research.section_ready",
      "description": "Send a complete summary when an independently useful research section is ready. A new event with the same section_id replaces that section's displayed content.",
      "schema_version": 1,
      "payload_schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "additionalProperties": false,
        "required": ["section_id", "title", "summary"],
        "properties": {
          "section_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "description": "Stable section identifier within one research turn; preserve it when updating the section."
          },
          "title": { "type": "string", "minLength": 1, "maxLength": 160 },
          "summary": { "type": "string", "minLength": 1, "maxLength": 2000 }
        }
      }
    }
  ]
}

この契約に一致するイベントペイロード:

research.section_ready.payload.json
{
  "section_id": "market-overview",
  "title": "Market overview",
  "summary": "This section outlines the main participants, changing demand, and scope of research in the target market."
}

section_idはアプリケーションのビジネス識別子であり、プラットフォーム生成のイベントidではありません。 タスクはLinkSenseのemit_application_eventツールを通じて情報を送{ name, payload }します。 ページはevents.on(...)を通じて受け取ります。SDKにはiframe自体がビジネスイベントを公開するevents.emit()方法はありません。

4種類のバージョン情報の区別

価値それが何かいつ変更すべきか
トップレベルのschema_versionマニフェスト形式現在はプラットフォームがサポートするフォーマットに従い、1に固定されています。
sdk_versionSDKプロトコル現在は1で固定されており、SDK v1スクリプトと一致しています。
versionアプリケーションリリースパッケージ全体更新によりラベルは維持または増強されることがあります。各セーブデータが別々のレコードを生成します。
custom_events[].schema_version1件のビジネスイベント契約構造や意味が変わったら増分し、新しいパッケージ版で公開します。

公開されたアプリケーションは新しいバージョンを採用します

クリエイターは、現在のインストールを所有権のもとで、Application Centerから最初に始めたタスクを含む過去のタスクで使用します。 リスティングを削除しても、クリエイター自身のアクティブなアプリケーションがブロックされるわけではありません。 他のユーザーは元の共有またはセンターアクセスチェックを保持します。 削除されたセンターのリストには、背景のない中央表示で「この申請はアプリケーションセンターから削除されました」と表示されます。会話履歴は依然として表示され、その後の実行はブロックされます。 アプリケーション自体を無効化または削除すると、その所有者もブロックされます。

組織共有やアプリケーションセンターを通じて使用されるオンラインサービスでは、アクセスチャネルと実行境界によって異なります。

  • 組織共有センターとアプリケーションセンターは提出したバージョンを保持します。 クリエイターは更新を再共有または再掲載しなければならず、受信者は手動でインストールします。
  • 新しいタスクやその後の既存タスクのターンは、アンインストールされたクリエイターのアップデートではなく、現在のユーザーのインストール済みバージョンを使用します。
  • 同じユーザーがそのアプリケーションで定期的にタスクを実行または開始している間に、更新の保存やインストールがブロックされます。 開発デバッグは別の環境を使用します。
  • 過去のタスクを開いたり更新したりすると、現在記録されたパッケージが読み込まれます。 それは作成時に採用されたパッケージか、後の実行で採用された新しいパッケージである場合もあります。 ページの復元はタスクの実行や自動アップグレードにはなりません。

これらのルールは公開されたオンラインサービスにも適用されます。 未公開のアプリケーションドラフトや開発プレビューが自動的に共有バージョンに従うことを意味しているわけではありません。

歴史的な出来事や結果は新しい契約に書き換えられません。1つのタスクには複数のschema_version値を持つイベントが含まれます。 新しいパッケージハンドラは、古いペイロードを新しい構造として扱うのではなく、過去のイベントバージョンを認識しなければなりません。 公開前に、新しいタスクを作成するテストを行い、古いタスクだけを再開し、古いタスクで再度実行し、タスクが実行中の更新を公開するテストを行ってください。

SDKを読み込んでください

<script src="/api/v1/interactive-app-runtime/sdk/v1.js?v=1.1.0"></script>
<script type="module" src="./app.js"></script>

SDKはwindow.LinkSenseとして公開されています。 ビジネスイベントリスナーはapp.js早い段階で登録し、準備が整うまで待ってからやり取りを許可してください:

const sections = new Map()
const unsubscribe = LinkSense.events.on("research.section_ready", (event) => {
  const key = `${event.turn_id}:${event.payload.section_id}`
  sections.set(key, event.payload)
  renderSections([...sections.values()])
})

await LinkSense.ready()

アプリケーションにrenderSectionsを実装してください。 出力をレンダリングし、textContentまたはフレームワークテキスト補間でレンダリングし、タスク出力を直接割り当てるのを避けinnerHTML。 ターンIDとセクションIDを組み合わせることで、他のターンの結果を上書きせずにセクションの前回の要約を置き換えます。 コンポーネントがアンマウントされたらunsubscribe()に連絡してください。

コンテキストやリソースを読むには、まず権限を追加し、その後メソッドを呼び出しready()。 例えば、knowledge_bases:readを加えた後、const { items } = await LinkSense.resources.listKnowledgeBases()を使ってオプションを取得します。

ランタイムはインライン<script>ブロック、イベントハンドラ属性、バンドルされたスクリプト、外部スクリプトをサポートします。 SDKには上記のプラットフォームURLを使い、バンドルされたアプリケーションスクリプトには相関パスを使います。 LinkSenseの外でHTMLを開くとホストのハンドシェイクが起きないため、ready()は完成しません。 純粋なUIはローカルで開発できますが、SDK統合はインポートされたアプリケーションが必要です。

作品を提出してください

const receipt = await LinkSense.tasks.run({
  prompt: "Complete the competitive analysis and emit research.section_ready for each section.",
})
パラメータ意味と限界推奨される実践
prompt必須;トリミング後の1–200,000文字;現在のタスクリクエスト。検証済みのフォーム値から、明確なトピック、制約、成果物を用意して構築します。 文脈なしに値を提出するのは避けてください。
capability_idsオプションのデフォルト[];スキルIDやプラグインID 50まで。アプリケーションタスクは設定されたスキルとプラグインを使用します。 このパラメータはアプリケーションリソースを上書きすることはできず、通常は省略すべきです。
knowledge_base_idsオプションのデフォルト[];最大で知識ベースのUUID 20まで。アプリケーションタスクは設定されたナレッジベースを使用します。 このパラメータはアプリケーションリソースを上書きすることはできず、通常は省略すべきです。
file_idsオプションで、デフォルトは[];最大100つのユニークなファイルUUIDまで。files.upload()またはfiles.list()で返送されたステージIDを選んだ。添付されているのはこれらのファイルだけで、チャットドラフトは除きます。
idempotency_key任意;前後の空白を除去した後で1–120文字。通常はホストに任せます。 もし提供された場合は、論理的な提出を1つ特定してください。異なるリクエスト間で固定値を再利用しないでください。

送信すると、LinkSenseはすぐにチャットペインを開き、メッセージを送信中と表示します。 受理されると、保留中のメッセージは永続メッセージと照合されます。 tasks.run()チャット履歴の更新や調査結果を待たずにサーバーの受諾書を返送します。 同じ機内提出の繰り返しの呼びかけは、1つのリクエストを共有しています。アプリケーションは提出時に生成ボタンを無効にし、失敗を処理するべきです。

現在のチャット幅で5行を超えるアプリケーション送信メッセージは、デフォルトでフォールドされ、下部にフェードが表示されます。 矢印アイコンボタンは、全コンテンツの展開や収縮を行えます。 完全なプロンプトは送信され、保存され、コピーされます。 手動で入力されたチャットメッセージは影響を受けません。

ネイティブのLinkSenseチャットでは、メッセージのストリーミング、推論、ツールの進行状況が表示されます。これらはiframeには複製されません。 アプリケーションは宣言されたビジネスイベントのみを受け取り、以下のコールバックフィールドで行われます:

コールバックフィールド意味と使用法
id重複除去のための安定したプラットフォーム生成イベントID;事業記録IDではありません。
nameイベント名はマニフェストで宣言されています。
schema_versionそのイベントの定義に基づくスキーマバージョンです。
payloadビジネスオブジェクトはイベントスキーマに対して検証されました。
turn_idイベントを生み出したタスクターンの識別;結果と複数の提出物を分離します。
sequenceタスクのイベントストリーム内での位置(順序付けに用いられます);ビジネスイベントには必ずしも連続した価値があるわけではありません。
created_at表示用のイベントタイムスタンプ。

再接続後に同じ出来事が再び起こることもあります。 SDKはイベントidごとに重複を除去し、アプリケーションの更新も冪等性であるべきです。 受理領収書は依頼が受理されたことを意味するのであって、作業が完了したことではありません。 作業を止めるには、await LinkSense.tasks.interrupt(receipt.turn_id);チャットを隠すことは中断ではありません。

タスクの再入力とイベントの復元

別のタスクに切り替えた後、ユーザーはタスクサイドバーや検索結果からインタラクティブアプリケーションを再開できます。 LinkSenseは、そのタスクのために現在記録されたアプリケーションのパッケージを読み込み、すべての永続的なカスタムイベントをsequence順に再生し、その後ライブイベントを継続します。 公開されたサービスが次の実行で新しいパッケージを採用すると、タスクを再開するとそのパッケージが使われます。 ページを開くだけで録画されたバージョンは変わりません。 ページを復元してもタスクを再実行せず、モデルに再度データを出力してもらうことはありません。

SDKは、アプリケーションがリスナーを登録する前に到達したイベントをバッファリングし、安定したイベントIDで重複を除去します。 ビジネスイベントリスナーを早期に登録し、ハンドラーを冪子に保ち、コールバックからUIを再構築できるようにします。 カスタムイベントで表現されていない未提出のフォームドラフトは自動的に永続化されません。

タスクステートクエリとサブスクリプション(SDK 1.2.0)

tasks.getState()現在の応募に関する最新の状況を読みます。 tasks.onStateChange(handler, onError?)は変更を購読し、非購読機能を返します。 両者とも既存のtasks:write許可を使用しています。マニフェストのsdk_versionとSDKのURL /api/v1/interactive-app-runtime/sdk/v1.js変更せずに。 クエリは既存の入会記録、ターン記録、保留申請記録を読みます。彼らは決して作品を提出しません。

州のフィールド意味
statusidle:課題なし;starting:受理、開始;running:実行;waiting_for_input:ネイティブチャットで質問や計画に答えること;completed:終了;failed:失敗;interrupted:止まった。
turn_id現在の入場許可、または最新のターンID、またはアイドル時のnull。 入学に失敗した場合、ネイティブターンなしでIDを持つことがあります。
file_idsこのリクエスト/ターンに関連付けられたアプリケーション添付ID 開始リクエストは、まだstaged中のファイルを予約することがあります。
can_submit新たな投稿が試みられるかどうか。 キューワークもこの状況をfalseします。 これはロックではありません。他のウィンドウによる競合も処理します。
interrupt_requestedサーバーが停止リクエストを記録したかどうか、実行停止の確認ではないか。

最初のスナップショットを読む前に、ビジネスイベントおよび州リスナーを登録してください。 そのリードが成功するまで、そしてリード失敗の後はサブミッションを無効にしてください。 SDKにすでに状態がある場合、新しいリスナーは即座に最新状態を受け取ります。過去のライフサイクル状態は再生されません。 ページインスタンスのリビジョンは、遅延したクエリ応答が新しいプッシュを置き換えるのを防ぎます。アプリケーションはこれらの改訂を永続しません。 onErrorは読み取り失敗を受け取ります。その後の成功したリードや、handlerへの配信再開を促します。 フォーカス、ネットワーク再接続、ライフサイクル通知がスナップショットを更新します。忙しいタスクも定期的に照合されます。 これらのアクションはいずれも実行をリトライしません。

task-state.js
await LinkSense.ready()
let current = null
let submitting = false
const button = document.querySelector('[type="submit"]')
button.disabled = true
function render(state) {
  current = state
  button.disabled = submitting || !state.can_submit
  // Translate state.status using the app's locale and group results by state.turn_id.
}
function unavailable() {
  current = null
  button.disabled = true
  // Show a localized status-unavailable message and allow reopening the page.
}
const unsubscribe = LinkSense.tasks.onStateChange(render, unavailable)
await LinkSense.tasks.getState().catch(unavailable)
window.addEventListener('pagehide', unsubscribe, { once: true })
// Check current?.can_submit and submitting on submit; only user actions call tasks.run.

tasks.run()受領書は、完成ではなく受け入れを意味します。 中断を要求した後は、interruptedまたは別の終端状態が到達するまで実際の状態の表示を続けます。 ビジネスイベントは完了後に再プレイ可能です。引き続き受領し、イベントidごとに重複を減らし、turn_idごとにグループ化して複数の投稿が区別されるようにしてください。

ファイルリストをfiles.list()で復元し、スナップショットfile_idsを送信済み/進行中としてマークしてください。 承認されたスタートで予約された段階ファイルや、バウンドされたファイルの再提出や削除はしないでください。 未提出のフォームドラフトはこのAPIの外にあります。 派生の開始・実行ラベルをデータベースやlocalStorageに保存する必要はありません。

既存のアプリケーションは、マニフェストの変更や再インポートなしで現在のメソッドを維持します。 アプリケーション自身のコントロールを復元するには、これらのメソッドを使ったコードに更新し、通常の更新フローで公開・インストールを行います。 既存の会話は録音されたパッケージ版を読み込みます。リフレッシュは古いパッケージを書き換えるものではありません。 既存のタスクで実際に採用されているバージョンを確認してください。 プラットフォームは公開されたアプリケーションソースを自動的に編集しません。

チャットコントロール

ユーザーはデスクトップでチャットペインのサイズを変更し、いつでも表示または非表示が可能です。 アプリケーションは可視性の変更も要求できます:

await LinkSense.chat.show()
await LinkSense.chat.hide()
await LinkSense.chat.toggle()

パネルを隠しても作業は止まりません。 LinkSenseフォーム、承認、エラーに対応したいときは、ユーザーに再度開くよう依頼してください。

ネットワークアクセス、ダウンロード、信頼境界

  • インタラクティブアプリケーションにはiframe sandboxがなく、ランタイムリソースはCSP、Permissions-Policy、X-Frame-Optionsを送りません。 アプリケーションはfetch、XMLHttpRequest、WebSocket、EventSourceを直接利用し、外部リソースを読み込み、HTMLフォームを送信し、新しいウィンドウを開き、マニフェスト権限を追加せずにファイルのダウンロードが可能です。
  • ダウンロードは通常のファイルリンク、download属性、またはfetchで取得したファイルから作成されたBlob URLを使用できます。 クロスオリジンdownload属性、ポップアップ、自動ダウンロードは引き続きブラウザのルールに従います。サードパーティのサーバーはContent-Disposition: attachmentでダウンロードを提供できます。
  • ブラウザのCORS、HTTPS混合コンテンツルール、許可プロンプトは依然として適用されます。 外部ホストや展開ゲートウェイからの権限ポリシーもデバイスの機能を制限することがあります。 サードパーティAPIはLinkSenseのページの発信を許可すべきです。HTTPSページはHTTPS APIとWSS接続を使うべきです。 サーバー側の接続は、ユーザーのブラウザからの接続を確立するものではありません。
  • 信頼できるパッケージと外部スクリプトのみをインポートしてください。 アプリケーションはホストの発信元を共有し、もはやセキュリティ隔離境界ではありません。親ページ、同一起源ストレージ、非HttpOnlyクッキーにアクセスでき、現在のユーザーとしてLinkSense APIを要求することも可能です。 HttpOnly クッキーはJavaScript上で読み取れません。 長寿命トークンやサードパーティのサービス秘密をフロントエンドファイルにバンドルしてはいけません。
  • 既存のアプリケーションは、APIとWebのアップデートの両方を展開しページを再読み込みした後、新しいポリシーを使用します。再インポートや過去のマニフェストの変更は不要です。 アプリケーション自体が宣言したCSPや外部プロキシからの追加ポリシーは引き続き適用されます。
  • すべてのSDK呼び出しはManifest権限とサーバー側の認可と照らされます。
  • カスタムイベントペイロードはManifest JSONスキーマに一致しなければなりません。
  • チャットコンテンツ、推論、ツールログ、認証情報、大きなファイルにはカスタムイベントを使用しないでください。 ファイルをLinkSenseのアーティファクトとして配信してください。

インポートと更新

プラグインセンター → アプリケーション → アプリケーションを作成 → 操作可能なアプリをインポート開け。 インポート後、有効化、無効化、標準アプリケーションのように共有します。 アプリケーションパッケージを更新を使って新しいバージョンをインポートしてください。

最初のバージョンは以下の順番で構築します:

  1. まずは最小限のマニフェスト、1つのフォーム、tasks.run()から入力からチャット結果までの流れを完成させます。
  2. 1つの有用なビジネスイベントを定義し、そのスキーマ、エミッションルール、ページリスナーを実装します。
  3. タスクを切り離して再起動することで再生されたイベントの結果が復元されるか確認し、リソースピッカーやビジュアライゼーションを追加してください。
  4. リリース前に読み込み、空の結果、提出、失敗、許可拒否、重複投稿をチェックしてください。 チャットのペインがリサイズされるとレイアウトも調整されるべきです。
  5. パッケージのversion、イベントコントラクト、ハンドラをまとめて更新し、新規タスクと既存のタスクを別々にチェックしましょう。

リポジトリのexamples/interactive-research-brief/ディレクトリには、Manifest、フォーム、リソース選択、イベント表示を含む完全な静的例があり、拡張参照として利用できます。

トラブルシューティング

症状まず確認してください解決
インポートが無効なパッケージを報告しますZIPルート、不明フィールド、バージョンタイプ、重複権限やイベント、ファイルやアイコンの制限などです。最小構成と比較してください。 文字列"1"ではなく数値1を使い、index.htmlとmanifest.jsonを直接根に配置してください。
イベントスキーマはインポートを阻止しますpayload_schema.type、スキーマ方言、そして可解な参照。オブジェクトルートと自己完結型スキーマを持つ2020-12を使い、実行時に外部$refターゲットをダウンロードすることに頼らないでください。
アップデートでは、より低いバージョンが報告されていますパッケージ版が既存の最高バージョンより下かどうか。同じかそれ以上のx.x.xバージョンを使ってください。
アイコンのインポートに失敗しますSVG、GIF、外部URLのいずれかを指すかicon。有効なPNG、JPEG、またはWebPのバンドルを使いましょう。 SVGページアセットのサポートはSVGアプリケーションアイコンのサポートを意味しません。
スクリプト、リクエスト、またはアセットが失敗しますブラウザエラー、CORS、HTTPS混合コンテンツ、アセットパス、ユーザーのネットワークからの接続性をチェックしましょう。直接接続や外部スクリプトも許可されています。 サードパーティサービスを設定してページの発信元を許可し、HTTPS/WSSを使用し、アセットパスを正しく設定し、アプリケーションやプロキシによって追加されたCSPがあるか確認してください。
SDKは準備ができていないか許可が拒否されたと報告していますready()完成済みで必要な許可が出ているかどうか。初期化後にコントロールを有効にしてください。 実際の呼び出しに必要な権限を追加し、新しいパッケージを公開し、新しいタスクで検証します。
チャットでは結果が出ますが、アプリケーションはビジネスデータを一切受け取りません宣言、命令、リスナー内のイベント名の一致;排出ツールの使用;ペイロードの妥当性。正確なトリガーを設定し、必要な項目、タイプ、長さ、追加フィールドを確認し、リスナーを早期に登録します。
再開は重複したり、ドラフトを失ったりしますすべてのイベントが新しい記録として追加されるか、送信されなかったドラフトが保存された結果として扱われるかは別として扱われます。イベントIDで重複を減らし、ビジネスIDで更新します。 ページメモリに頼ってドラフトを復元するのではなく、永続イベントからインターフェースを再構築しましょう。

参照ファイルのアップロード

ファイルメソッドはSDK 1.1.0で利用可能です。プロトコルsdk_version 1のままです。 パッケージを更新する際は、上記のv1.js?v=1.1.0スクリプトURLを使って、長期間不変の長期キャッシュされたSDKを回避できます。

マニフェスト権限に明示的にfiles:writeを追加してください;タスク提出もtasks:writeが必要です。 アプリケーションはファイルピッカー、ドロップエリア、ファイルリスト、アップロードステートを所有しています。 SDKはUIを作成するものではありません。 ブラウザFileオブジェクトをホストに渡します。Base64としてエンコードしたり、プラットフォームAPIを直接呼び出したり、カスタムイベントで送信したりしないでください。

await LinkSense.ready()
const file = document.querySelector('input[type="file"]').files[0]
const uploaded = await LinkSense.files.upload(file)
const receipt = await LinkSense.tasks.run({
  prompt: "Analyze this reference and summarize the key findings.",
  file_ids: [uploaded.id],
})
方法結果と挙動
files.upload(file)1つのFileをアップロードしてメタデータを返します。 複数のファイルについては別々に電話してください。 アップロードしてもタスクは起動しません。
files.list()このアプリケーションタスクのステージ化およびバインド済みファイルを含む{ items }、ページを再開した後も含まれます。
files.remove(fileId)未提出の申請添付ファイルを削除してください。{ removed: true }返せ。 すでに提出された、または入学を承認されているファイルは削除できません。

ファイルメタデータにはid、filename、mime_type、size_bytes、status、turn_idのみが含まれています。 stagedファイルを選択して提出することができます。boundファイルはターンに属します。 再開時は必要なファイルを表示しますが、次の提出用にステージファイルだけを選択してください。 プラットフォームはファイルやフォームフィールド間のアプリケーション固有のマッピングを復元しません。

アップロードはプラットフォームの既存のファイルあたりのサイズと会話あたりのファイル数制限を利用します。 アプリケーションはacceptや独自の検証で型をさらに制限できます。 複数のアップロードは独立して成功または失敗します。成功したファイルを保持し、失敗したファイルの再試行や削除を許可し、選択したすべてのファイルが準備完了した場合にのみ送信を可能にします。 拒否されたSDKの約束をローカライズされたフィードバックで処理しましょう。 ホストはアップロードや削除の途中でタスクの提出を拒否します。 タスクの提出が失敗した場合、ユーザーが再試行するためにステージ化されたファイルを保持します。

省略file_idsまたは[]を通過してもファイルは提出されません。 アプリケーションの添付ファイルとネイティブチャットドラフトは別々に管理されます。アプリケーションは現在のタスクの段階的な添付ファイルのみを提出でき、チャットはそれらを自動的に消費しません。 承認された添付ファイルは提出されたターンに属し、チャット履歴に表示され、既存のランナーの添付コンテキストを通過します。 新しい添付ファイルとして再びバインドファイルを提出しないでください。 同じidempotency_keyを同じ論理的投稿で再利用すること;ファイル選択を変更するときは新しいキーを使いましょう。

既存のパッケージは再インポートせずにテキストを送信し続けます。 アップロードを有効にするには、更新されたパッケージでfiles:writeを宣言し、対応する共有またはリストされたバージョンを更新してください。 アップロード検証時は新しいタスクを優先してください。 既存の共有またはリストタスクは、次の実行時に新しいパッケージを採用した後にのみ新しい権限を使用します。 リフレッシュだけでは権限は更新されません。アップロードはそのタスクのために現在記録されたパッケージを使用します。

複数選択、再試行、削除、復元、明示的なファイルID提出については、examples/interactive-research-brief/を参照してください。

この機能を展開する前に、pnpm db:migrate:deployを実行してアタッチメント-ソースデータベースの制約を拡張し、その後APIとフロントエンドのバージョンをマッチングしてデプロイしてください。 移行は既存のすべてのソース値、添付ファイル、フィールド定義を保持します。 new-originの添付ファイルが書かれた後は、そのoriginを解析できないAPIバージョンにロールバックしたり、古いAPIと新しいAPIインスタンスを混在させたりしないでください。

すべてのファイルタイプのアップロードでINTERNAL_ERRORが返され、サーバーログでconversation_files_source_check制約違反が報告された場合は、デプロイメントに20260918210000_allow_interactive_application_uploadsが含まれ、適用されているかを確認してください。 修理後にアップロードをやり直してください;アプリケーションの再インポートは不要です。 pnpm test:interactive-files:postgresアプリケーションデータベースに接続せずに、一時的なPostgreSQLコンテナ内で過去のアップグレードや新規インストールを検証します。 このチェックはCIでも動作し、Dockerが必要です。