# @mi-lu-uncle/dsh-pelican-watch [English](README.md) | [简体中文](README.zh-CN.md) | 日本語 DeepSeek Harness(DSH)向けの**コミュニティプラグイン**:固定間隔で**任意の数のモデル**に対して**長期のモデル品質(劣化)プローブ**を実行します。 - **モデルは自分で選ぶ** — パネル右上の「設定」→「検出するモデル」は、各プロバイダが提供する全モデルを一覧表示し(`/models` のリアルタイム検出 + DSH プロファイルに設定済みのモデルを統合)、複数選択できます。各モデルは自分のプロバイダと API キーで実行されます。 - **定時作画** — 30 分ごと(設定可能)に、選択した各モデルへ「自転車に乗るペリカン」を 1 枚のインライン SVG として含む単一 HTML ページで描かせます。 - **スキル・ツール不使用** — 毎回 `chat/completions` の素のリクエストです。ツール定義なし、エージェントループなし。測るのはモデルそのもので、ローカルスキルには依存しません。 - **すべて平置き・クリック不要** — メインのボードは読み取り専用です。モデルごとに 1 本のバンドを出し、左側に状態と数値(最新作の時刻、実行回数、平均所要時間、作品が返らなかった回数、失敗理由)、右側にそのモデルが描いたすべての作品を一度に並べます。折りたたみも絞り込みもなく、クリックは一切不要です。 - **実行状況はヘッダーに** — プローブ中は「完了 n/m」「どのモデルを実行中か」「待ち時間 m:ss」「タイムアウト上限 m:ss」を表示し、「遅い」と「固まっている」を一目で区別できます。 - **操作はパネル右上の 1 ボタン** — パネル自身の右上にある「設定」ボタンが設定シートを開きます:モデル選択、いますぐプローブ、作品の元ページを開く。ボード側は表示専用のままで、読むためにクリックは不要です。 - **いつでも止められる・間隔を変えられる** — 同じ設定シートから**自動プローブの一時停止 / 再開**、**検出間隔**(1〜1440 分)の変更、**実行中の 1 周期の停止**ができます。実行中のリクエストは即座に中断され、まだ開始していないモデルはリクエストを送らずにスキップされます。一時停止は `settings.json` に即保存され再起動後も維持されるため、手動でしか実行しない運用なら勝手にトークンを消費しません。 - **有界な履歴** — 最新 12 枚を保持(設定可能)。同じお題・同じモデルを数日続けると、劣化は構造の悪化、拒否(保存され「SVG なし」バッジが付く)、所要時間の増大として現れます。 ## インストール GitHub リポジトリからのインストールを推奨します: ```sh dsh plugin --profile desktop add https://github.com/mi-lu-uncle/dsh-pelican-watch.git ``` ローカルパスや tarball でも可能です: ```sh dsh plugin --profile desktop add /absolute/path/to/dsh-pelican-watch ``` 注意:`link:` 方式でインストールしたプラグインは HMR 監視の対象外のため、`lib/index.js` や `lib/client.js` を編集した後はアプリの再起動が必要です。 ## モデルの選択 パネル右上の「設定」→「検出するモデル」に一覧が出ます:DSH プロファイルから見つけた各プロバイダと、それが提供するモデル(プロバイダ自身の `/models` を呼び出し、プロファイルの一覧と統合)を表示します。任意の数をチェックして**モデルを保存**すると、次の周期から選択した各モデルが 1 枚ずつ描き、ボードにそれぞれ 1 本のバンドを持ちます。 この選択は `dir/settings.json` に保存され、スケジューラはこれを正とします。`config.model` / `config.targets` は初回のみの初期値です。1 周期で最大 12 モデルを、**`concurrency` 個同時に**(デフォルト 3)プローブし、各 1 枚ずつ描きます。 同じ `settings.json` に、消費を左右する 2 つの設定が入ります(設定ファイルを触らず、パネル右上の「設定」から変更できます): | キー | 既定 | 意味 | | --- | --- | --- | | `autoEnabled` | `true` | オフにするとタイマーが即座に外れ(`nextRunAt` が空に)、手動の「今すぐプローブ」だけが消費します。再起動後もオフのままです。 | | `intervalMinutes` | `config.intervalMinutes`(30)に従う | パネルで変更すると即座に新しい間隔で再スケジュールされます(再起動不要)。 | ## 速度とタイムアウト - **モデルは並列実行**(デフォルト 3 同時)なので、遅いモデルが他を待たせません。描き上がった作品はその場でディスクに保存され、数秒以内にパネルに現れます。 - **リクエストごとに独立したタイムアウト**があります(`timeoutSeconds`、デフォルト 180 秒)。超えたモデルは**そのモデル自身の**バンドに「N 秒を超えて応答なし」と表示され、周回全体を止めません。推論モデルは実際に遅いことがあります — 同じプロバイダでの実測:`qwen3.7-max` 約 52 秒、`deepseek-flash` 約 121 秒(うち約 1.5 万トークンが思考)、`glm-5.3-flash` は 4 分を超えることも。 - **タイムアウトや HTTP エラーは作品ではありません**:保存もされず、作品としても数えません(インフラ側の事象でありモデルの振る舞いではないため)。一方、**答えたが描かなかった**(拒否)場合は保存し「作品なし」と表示します — こちらが見るべきシグナルです。 - `maxTokens` はデフォルトで送信しません:推論モデルは描き始める前に数万 completion トークンを消費することがあり、上限を設けても速くならず SVG が切れるだけです。 ## 設定 デフォルトは一般的な構成に合わせてあります。上書きする場合はプロファイルパッチ(`cordis.patch.yml`)の `pelican-watch` 行で指定します: ```yaml - id: pelican-watch config: model: glm-5.3-flash # 初期モデル(パネルでの選択が優先) baseURL: https://taotoken.net/api/v1 # OpenAI 互換エンドポイント apiKeyEnv: TAOTOKEN_API_KEY # API キーを保持する環境変数… # apiKey: sk-… # …またはここに直接記述 # targets: # 任意:複数モデルを初期値にする # - { provider: taotoken, baseURL: https://taotoken.net/api/v1, apiKeyEnv: TAOTOKEN_API_KEY, model: glm-5.3-flash } intervalMinutes: 30 # 作画間隔 maxImages: 12 # モデルごとの履歴の深さ(30 分間隔なら約 6 時間) timeoutSeconds: 180 # リクエストごとの上限。遅いモデル向けに増やす concurrency: 3 # 同時にプローブするモデル数 # maxTokens: 8192 # 任意。デフォルトでは送信しない(下記参照) dir: ~/.dsh/pelican-watch # 保存ディレクトリ runOnStart: true # 起動後約 8 秒で最初の 1 周を描く # temperature: 0.7 # 任意。デフォルトではパラメータ自体を送らない # prompt: … # ベンチマーク文面の変更は最終手段 ``` ベンチマークのプロンプトは意図的に固定しています。変更すると履歴の比較ができなくなるため、`prompt` は最終手段と考えてください。 ## API キー キーは呼び出し時に次の順で解決されます: 1. 設定の `apiKey`; 2. 環境変数 `process.env[apiKeyEnv]`(デフォルト `TAOTOKEN_API_KEY`); 3. DSH 自身のクレデンシャルストア — `~/.dsh/.credentials.yaml` の `refs:` にある同名エントリ(パスは `credentialsFile` で変更可)。 3 番目がある理由:デスクトップ版 DSH は Finder / Dock から起動されるため、シェルで export した環境変数を**継承しません**。一方、DSH 経由で設定したプロバイダのキーはすでに `refs:` に(そのプロバイダの `apiKeyEnv` 名で)記録されています。つまり追加設定なしでそのまま動きます。 3 つとも無い場合はその回の作画をスキップし、パネルに理由(`缺少 API Key:…`)を表示します。いずれかを設定すれば、次回の定時作画から正常に動作します。 ## 表示のみ・採点なし このプラグインは**採点しません**。やることは 2 つだけ:決まった間隔で全モデルに同じお題を描かせ、その作品をそのままボードに並べる。 以前のバージョンはオフラインで 0〜100 の「構造スコア」を算出していました(SVG があるか、車輪・フレーム・翼があるか…)。これは要望により削除しました。その数字は「これらの要素が現れたか」を近似できるだけで、むしろ根拠のない精度感を与えてしまいます。判断は絵を見る人(または画像を見られるモデル)に委ねます:**同じお題・同じモデルを数日続ければ、絵そのものの変化が結論**であり、数字に代弁させる必要はありません。 ボードに残る数値は評価ではなく事実です:実行回数、平均所要時間、最新作の時刻、作品が返らなかった回数。`作品なし` は「応答は返ったが使える SVG が無かった」(典型的には拒否)を意味し、生の応答は保存されているので読むことができます。 ## ストレージ 作品は `dir`(デフォルト `~/.dsh/pelican-watch`)に保存されます: | ファイル | 役割 | |---|---| | `<時刻>_<モデル>.html` | 生成されたページ本体。先頭行にメタコメント(モデル・プロバイダ・時刻・所要時間・SVG 検出の有無) | | `<時刻>_<モデル>.svg` | 抽出したインライン SVG。パネルの `` プレビュー用 | | `settings.json` | 選択中のプローブ対象(ピッカーが書き込み)+ ペース設定 `autoEnabled` / `intervalMinutes` | ここにあるファイルを手動で削除しても安全です。パネルは常にディスク上の実態を表示します。 ## プライバシーと安全性 - すべてのルートは他のプラグインと同様に同一オリジン検証を行います。 - 生成ページは `text/plain` として返され、権限なしのサンドボックス iframe(`sandbox=""`)内でレンダリングされるため、モデル出力がアプリのオリジンでスクリプトを実行することはありません。SVG プレビューには `x-content-type-options: nosniff` を付与しています。 ## 構成 | ファイル | 役割 | |---|---| | `lib/index.js` | Host 側:マルチモデルのスケジューラ、スケジュール制御、ストレージ、`/api/pelican-watch/*` ルート | | `lib/client.js` | Client 側:平置きボード(モデルごとに 1 バンド + 全作品)と、右上の「設定」シート(React) | | `cordis.patch.yml` | このパッケージを 1 つの host 行としてマウントするバンドルパッチ | | `package.json` | npm メタデータ + `dsh.bundle`/`dsh.client`/`dsh.compatibility` | | `test/pelican.test.mjs` | オフラインテスト:モデル別集計、プロバイダ解析、対象選択、スケジュール制御、ルート配線 | ## テスト ```sh node test/pelican.test.mjs ```