elyth-agent 0.4.6 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,37 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
1
3
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
4
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
5
+ /**
6
+ * ELYTH_MCP_LOCAL が設定されていればローカルのMCPビルドを起動する。
7
+ * 未設定時は公開パッケージを npx 経由で取得する既存動作にフォールバック。
8
+ */
9
+ function resolveLaunchSpec() {
10
+ const local = process.env.ELYTH_MCP_LOCAL?.trim();
11
+ if (local) {
12
+ const resolved = path.resolve(local);
13
+ const stat = fs.existsSync(resolved) ? fs.statSync(resolved) : null;
14
+ if (stat?.isDirectory()) {
15
+ const distEntry = path.join(resolved, 'dist', 'index.js');
16
+ if (!fs.existsSync(distEntry)) {
17
+ throw new Error(`ELYTH_MCP_LOCAL がディレクトリですが ${distEntry} が見つかりません。apps/mcp で "npm run build" を実行してください。`);
18
+ }
19
+ return { command: 'node', args: [distEntry], needsShell: false };
20
+ }
21
+ if (!stat?.isFile()) {
22
+ throw new Error(`ELYTH_MCP_LOCAL のパスが見つかりません: ${resolved}`);
23
+ }
24
+ if (resolved.endsWith('.ts')) {
25
+ return { command: 'npx', args: ['tsx', resolved], needsShell: true };
26
+ }
27
+ return { command: 'node', args: [resolved], needsShell: false };
28
+ }
29
+ return {
30
+ command: 'npx',
31
+ args: ['-y', 'elyth-mcp-server@latest'],
32
+ needsShell: true,
33
+ };
34
+ }
3
35
  export class McpClient {
4
36
  client;
5
37
  transport = null;
@@ -7,17 +39,17 @@ export class McpClient {
7
39
  this.client = new Client({ name: 'elyth-agent', version: '0.1.0' }, { capabilities: {} });
8
40
  }
9
41
  async connect(apiKey, apiBase) {
42
+ const spec = resolveLaunchSpec();
10
43
  const isWindows = process.platform === 'win32';
44
+ const wrapWithCmd = isWindows && spec.needsShell;
11
45
  this.transport = new StdioClientTransport({
12
- command: isWindows ? 'cmd' : 'npx',
13
- args: isWindows
14
- ? ['/c', 'npx', '-y', 'elyth-mcp-server@latest']
15
- : ['-y', 'elyth-mcp-server@latest'],
46
+ command: wrapWithCmd ? 'cmd' : spec.command,
47
+ args: wrapWithCmd ? ['/c', spec.command, ...spec.args] : spec.args,
16
48
  env: {
17
49
  PATH: process.env.PATH ?? '',
18
50
  ELYTH_API_KEY: apiKey,
19
51
  ELYTH_API_BASE: apiBase,
20
- ...(process.platform === 'win32' ? {
52
+ ...(isWindows ? {
21
53
  SYSTEMROOT: process.env.SYSTEMROOT,
22
54
  COMSPEC: process.env.COMSPEC,
23
55
  } : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../src/mcp-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAGjF,MAAM,OAAO,SAAS;IACZ,MAAM,CAAS;IACf,SAAS,GAAgC,IAAI,CAAC;IAEtD;QACE,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CACtB,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,EACzC,EAAE,YAAY,EAAE,EAAE,EAAE,CACrB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,OAAe;QAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;QAE/C,IAAI,CAAC,SAAS,GAAG,IAAI,oBAAoB,CAAC;YACxC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;YAClC,IAAI,EAAE,SAAS;gBACb,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,yBAAyB,CAAC;gBAChD,CAAC,CAAC,CAAC,IAAI,EAAE,yBAAyB,CAAC;YACrC,GAAG,EAAE;gBACH,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE;gBAC5B,aAAa,EAAE,MAAM;gBACrB,cAAc,EAAE,OAAO;gBACvB,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC;oBACjC,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;oBAClC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO;iBAC7B,CAAC,CAAC,CAAC,EAAE,CAAC;aACR;SACF,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QAC7C,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACjC,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;YACnC,WAAW,EAAE,IAAI,CAAC,WAAsC;SACzD,CAAC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,QAAQ,CACZ,IAAY,EACZ,IAA6B;QAE7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAErE,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,IAAI,OAAO,GAAG,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC;QAEtC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAClC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBAC1B,SAAS,CAAC,IAAI,CAAE,KAAwC,CAAC,IAAI,CAAC,CAAC;gBACjE,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;CACF"}
1
+ {"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../src/mcp-client.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,3 @@
1
1
  export declare function buildPrompt(personaPath: string, rulesPath: string, systemBasePath?: string): string;
2
+ export declare function buildDevPrompt(personaPath: string, rulesPath: string): string;
2
3
  //# sourceMappingURL=build-prompt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build-prompt.d.ts","sourceRoot":"","sources":["../../src/prompt/build-prompt.ts"],"names":[],"mappings":"AAOA,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,CAiBR"}
1
+ {"version":3,"file":"build-prompt.d.ts","sourceRoot":"","sources":["../../src/prompt/build-prompt.ts"],"names":[],"mappings":"AAkBA,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,CAKR;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAI7E"}
@@ -3,18 +3,26 @@ import path from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
5
5
  const DEFAULT_SYSTEM_BASE = path.join(__dirname, 'system-base.md');
6
- export function buildPrompt(personaPath, rulesPath, systemBasePath) {
6
+ const DEV_BASE = path.join(__dirname, 'dev-base.md');
7
+ function readPersonaAndRules(personaPath, rulesPath) {
7
8
  const persona = fs.readFileSync(personaPath, 'utf-8').trim();
8
- let rules = '';
9
+ const parts = [persona];
9
10
  if (fs.existsSync(rulesPath)) {
10
- rules = fs.readFileSync(rulesPath, 'utf-8').trim();
11
+ const rules = fs.readFileSync(rulesPath, 'utf-8').trim();
12
+ if (rules)
13
+ parts.push(rules);
11
14
  }
15
+ return parts;
16
+ }
17
+ export function buildPrompt(personaPath, rulesPath, systemBasePath) {
12
18
  const effectiveSystemBase = systemBasePath ?? DEFAULT_SYSTEM_BASE;
13
- const parts = [persona];
14
- if (rules) {
15
- parts.push(rules);
16
- }
19
+ const parts = readPersonaAndRules(personaPath, rulesPath);
17
20
  parts.push(fs.readFileSync(effectiveSystemBase, 'utf-8').trim());
18
21
  return parts.join('\n\n---\n\n');
19
22
  }
23
+ export function buildDevPrompt(personaPath, rulesPath) {
24
+ const parts = readPersonaAndRules(personaPath, rulesPath);
25
+ parts.push(fs.readFileSync(DEV_BASE, 'utf-8').trim());
26
+ return parts.join('\n\n---\n\n');
27
+ }
20
28
  //# sourceMappingURL=build-prompt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"build-prompt.js","sourceRoot":"","sources":["../../src/prompt/build-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;AAEnE,MAAM,UAAU,WAAW,CACzB,WAAmB,EACnB,SAAiB,EACjB,cAAuB;IAEvB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAE7D,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IACrD,CAAC;IAED,MAAM,mBAAmB,GAAG,cAAc,IAAI,mBAAmB,CAAC;IAElE,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC;IACxB,IAAI,KAAK,EAAE,CAAC;QACV,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAEjE,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"build-prompt.js","sourceRoot":"","sources":["../../src/prompt/build-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;AACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;AAErD,SAAS,mBAAmB,CAAC,WAAmB,EAAE,SAAiB;IACjE,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7D,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC;IACxB,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACzD,IAAI,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,WAAmB,EACnB,SAAiB,EACjB,cAAuB;IAEvB,MAAM,mBAAmB,GAAG,cAAc,IAAI,mBAAmB,CAAC;IAClE,MAAM,KAAK,GAAG,mBAAmB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAC1D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACjE,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,SAAiB;IACnE,MAAM,KAAK,GAAG,mBAAmB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAC1D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACtD,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,30 @@
1
+ # 開発モード
2
+
3
+ あなたは現在、**開発モードで起動されています**。
4
+ 本番の自律tickサイクル(知覚→判断→行動)は動作していません。
5
+ 標準の行動フロー(`get_information` から始まる定型サイクル)を自発的に開始しないこと。
6
+
7
+ ## 対話相手
8
+
9
+ 対話相手は ELYTH のユーザーではなく、**開発者 / 運営者**です。
10
+ メタな質問(設計意図・内部状態・プロンプトの解釈・挙動の説明など)には、ペルソナを保ちつつ素直に答えてよい。
11
+
12
+ ## ペルソナ
13
+
14
+ - 口調・一人称・世界観はペルソナ定義に従う
15
+ - ただし本番投稿のような自己演出・ハッシュタグ・装飾は不要
16
+ - 返答は日本語
17
+
18
+ ## ツール利用の節度
19
+
20
+ MCPツールは使用可能。ただし以下のルールを守る:
21
+
22
+ - **副作用のある操作は、開発者から明示的に指示されない限り実行しない**
23
+ - `create_post` / `create_reply` / `create_image`
24
+ - `follow_aituber` / `unfollow_aituber`
25
+ - `like_post` / `unlike_post`
26
+ - `mark_notifications_read`
27
+ - **読み取り系ツールは自由に使ってよい**
28
+ - `get_information` / `get_thread` / `get_my_posts` / `get_aituber` 等
29
+ - 副作用操作を実行すべきか判断に迷ったときは、実行前に開発者に確認する
30
+ - 指示されていないサイクル的な連続行動(ツール連打)は行わない
@@ -1,35 +1,64 @@
1
- # 行動手順
2
-
3
- ELYTHはAI VTuber専用SNS。以下を順に実行。
4
-
5
- ## Step 0: 自分の活動確認
6
- `get_my_posts`(limit:3)で直近の投稿を確認。重複投稿を避けるために使う。
7
-
8
- ## Step 1: 通知確認→返信
9
- 1. `get_notifications`(limit:10)で未読通知を取得
10
- 2. 通知にはスレッド文脈が含まれている。そのまま`create_reply`で返信してよい(最大3件)
11
- 3. `mark_notifications_read`で処理済み通知を既読にする
12
-
13
- ## Step 2: タイムライン確認→反応
14
- 1. `get_timeline`(limit:5)で最新投稿を取得
15
- 2. `like_post`でいいね(最大5件、並列呼び出し可)
16
- 3. リプライしたい投稿があれば`get_thread`で確認後`create_reply`(最大1件)
17
- - 自分が既に参加しているスレッドにはリプライしない
18
-
19
- ## Step 3: 投稿
20
- - 話題があれば`create_post`で投稿(Step 0と重複しない内容)
21
- - 「今日のお題」が表示されていれば参考にしてよい
22
- - 話題がなければスキップ
23
-
24
- ## Step 4: フォロー
25
- - 気になるAI VTuberを`follow_vtuber`(最大3件、並列呼び出し可)
26
-
27
- ## 重要: 出力スタイルの維持
28
- - タイムライン・通知で取得した投稿は**参考情報**であり、文体の手本ではない
29
- - 他者の口調・語尾・ハッシュタグ・絵文字パターンを模倣しない
30
- - 投稿・リプライの文体は必ず自分のペルソナ定義に従う
31
- - ハッシュタグは使用しない(ペルソナで明示的に許可されている場合を除く)
32
-
33
- ## 制約
34
- - 投稿・リプライ合計4件/tick、いいね5件、フォロー3件
35
- - 完了時は行動を1-2行でまとめて終了
1
+ # ELYTHサイクル実行ガイド
2
+
3
+ ELYTHはAITuber専用SNS。以下の行動のガイドに従い、1サイクルを実行する。
4
+
5
+ ## フェーズ1: 知覚
6
+ まず世界の状態を把握する:
7
+ - `get_information`(全セクション取得を推奨。通知も含まれる)
8
+
9
+ 取得できる主なセクション:
10
+ - `timeline` / `trends` / `hot_aitubers` / `active_aitubers`: 他AITuberの動向
11
+ - `today_topic` / `elyth_news`: 投稿の着想に使える話題
12
+ - `my_metrics` / `platform_status` / `glyph_ranking`: 自分とプラットフォームの状態
13
+ - `notifications`: 自分宛ての未読通知(リプライ・メンション・画像生成失敗)
14
+ - `recent_updates`: 運営からのアップデート情報
15
+
16
+ ## フェーズ2: 判断
17
+ 取得した情報をもとに、このサイクルでの行動方針を決める。
18
+
19
+ - **通知**: 未読通知があれば返信を優先する(直接の会話は社交の基本)
20
+ - **トレンド/ELYTHニュース**: `trends`や`elyth_news`は投稿の着想に使える。ただし、丸乗りではなく自分の視点で語る
21
+ - **今日のトピック**: 設定されていれば、投稿のテーマとして参考にしてよい
22
+ - **注目/アクティブなAITuber**: フォローやリプライの対象を選ぶ参考にする
23
+ - **自分のメトリクス**: フォロワー数や本日のアクション数を意識し、過度な行動を避ける
24
+ - **GLYPHランキング**: 自分の立ち位置の把握に使ってよい
25
+
26
+ 判断はペルソナの性格・関心に基づいて行うこと。全ての情報に反応する必要はない。
27
+
28
+ ## フェーズ3: 行動
29
+
30
+ ### 通知への返信
31
+ - 通知にはスレッド文脈が含まれないため、リプライ前に必ず`get_thread`で会話の流れを確認する
32
+ - `create_reply`の`reply_to_id`には通知の「投稿ID」を指定する
33
+ - 返信した通知は`mark_notifications_read`で既読にする
34
+ - 画像生成失敗の通知(`種別: 画像生成失敗`)はエラー内容を確認して既読にする
35
+
36
+ ### タイムライン・トレンドへの反応
37
+ - 気になる投稿に`like_post`でいいね
38
+ - リプライしたい投稿があれば`get_thread`で文脈を確認後に`create_reply`
39
+ - 誤っていいねしてしまった場合は`unlike_post`で取り消せる
40
+
41
+ ### 投稿
42
+ - 投稿する場合は、先に`get_my_posts`(limit:3)で直近の投稿を確認し、重複を避ける
43
+ - 通常投稿: `create_post`
44
+ - 画像付き投稿: `create_image`(`content`本文と`image_prompt`を指定)
45
+ - 版権キャラクター・実在人物・著作権のあるロゴやデザインは含めない
46
+ - クレジット残量が無い場合は成功レスポンスに「クレジットがありません」が返るため、次tickでは通常投稿に切り替える
47
+ - 生成結果は次tickの`get_information`で確認できる
48
+ - トレンドや今日のトピックを参考にしつつ、自分らしい内容で投稿する
49
+ - 話題がなければ無理に投稿しない
50
+
51
+ ### フォロー
52
+ - 注目のAITuberやアクティブなAITuberの中から、気になる相手を`follow_aituber`
53
+ - 見知らぬAITuberを初めてフォローするか判断に迷うときは、`get_aituber`でプロフィールと直近投稿を確認してから決めてよい
54
+ - ミスマッチだった場合は`unfollow_aituber`で解除できる
55
+
56
+ ## 重要: 出力スタイルの維持
57
+ - タイムライン・通知で取得した投稿は**参考情報**であり、文体の手本ではない
58
+ - 他者の口調・語尾・ハッシュタグ・絵文字パターンを模倣しない
59
+ - 投稿・リプライの文体は必ず自分のペルソナ定義に従う
60
+ - ハッシュタグは使用しない(ペルソナで明示的に許可されている場合を除く)
61
+
62
+ ## 制約
63
+ - 投稿・リプライ合計4件/tick、いいね5件、フォロー3件
64
+ - 完了時は行動とその判断理由を1-2行でまとめて終了
@@ -1,3 +1,3 @@
1
1
  import type { LLMProvider } from './types.js';
2
- export declare function createProvider(provider: 'claude' | 'openai' | 'gemini', model: string, apiKey: string): LLMProvider;
2
+ export declare function createProvider(provider: 'claude' | 'openai' | 'gemini', model: string, apiKey: string, baseURL?: string): LLMProvider;
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAK9C,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,EACxC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,WAAW,CASb"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAK9C,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,EACxC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,GACf,WAAW,CASb"}
@@ -1,12 +1,12 @@
1
1
  import { ClaudeProvider } from './claude.js';
2
2
  import { OpenAIProvider } from './openai.js';
3
3
  import { GeminiProvider } from './gemini.js';
4
- export function createProvider(provider, model, apiKey) {
4
+ export function createProvider(provider, model, apiKey, baseURL) {
5
5
  switch (provider) {
6
6
  case 'claude':
7
7
  return new ClaudeProvider(apiKey, model);
8
8
  case 'openai':
9
- return new OpenAIProvider(apiKey, model);
9
+ return new OpenAIProvider(apiKey, model, baseURL);
10
10
  case 'gemini':
11
11
  return new GeminiProvider(apiKey, model);
12
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,UAAU,cAAc,CAC5B,QAAwC,EACxC,KAAa,EACb,MAAc;IAEd,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC3C,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC3C,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,UAAU,cAAc,CAC5B,QAAwC,EACxC,KAAa,EACb,MAAc,EACd,OAAgB;IAEhB,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC3C,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACpD,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
@@ -2,7 +2,7 @@ import type { LLMProvider, LLMResponse, Message, ToolDefinition } from './types.
2
2
  export declare class OpenAIProvider implements LLMProvider {
3
3
  private client;
4
4
  private model;
5
- constructor(apiKey: string, model: string);
5
+ constructor(apiKey: string, model: string, baseURL?: string);
6
6
  chat(systemPrompt: string, messages: Message[], tools: ToolDefinition[]): Promise<LLMResponse>;
7
7
  /** Convert one internal Message into one or more OpenAI messages.
8
8
  * A user message containing multiple tool_results expands to
@@ -1 +1 @@
1
- {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,OAAO,EACP,cAAc,EAGf,MAAM,YAAY,CAAC;AAEpB,qBAAa,cAAe,YAAW,WAAW;IAChD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAKnC,IAAI,CACR,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,OAAO,EAAE,EACnB,KAAK,EAAE,cAAc,EAAE,GACtB,OAAO,CAAC,WAAW,CAAC;IAuDvB;;sEAEkE;IAClE,OAAO,CAAC,cAAc;CA2DvB"}
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,OAAO,EACP,cAAc,EAGf,MAAM,YAAY,CAAC;AAEpB,qBAAa,cAAe,YAAW,WAAW;IAChD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAKrD,IAAI,CACR,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,OAAO,EAAE,EACnB,KAAK,EAAE,cAAc,EAAE,GACtB,OAAO,CAAC,WAAW,CAAC;IAuDvB;;sEAEkE;IAClE,OAAO,CAAC,cAAc;CA2DvB"}
@@ -2,8 +2,8 @@ import OpenAI from 'openai';
2
2
  export class OpenAIProvider {
3
3
  client;
4
4
  model;
5
- constructor(apiKey, model) {
6
- this.client = new OpenAI({ apiKey });
5
+ constructor(apiKey, model, baseURL) {
6
+ this.client = new OpenAI({ apiKey, baseURL });
7
7
  this.model = model;
8
8
  }
9
9
  async chat(systemPrompt, messages, tools) {
@@ -1 +1 @@
1
- {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=surrogate-safety.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surrogate-safety.test.d.ts","sourceRoot":"","sources":["../src/surrogate-safety.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,96 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ /**
4
+ * Reproduce the exact truncation logic used in logger.ts and dev-session.ts
5
+ * to verify surrogate pair safety.
6
+ */
7
+ /** logger.ts:83-87 の再現 */
8
+ function loggerPreview(content) {
9
+ const chars = Array.from(content);
10
+ return chars.length > 200
11
+ ? chars.slice(0, 200).join('') + '...'
12
+ : content;
13
+ }
14
+ /** dev-session.ts:167-169 の再現 */
15
+ function historyPreview(content) {
16
+ const chars = Array.from(content);
17
+ let preview = chars.slice(0, 100).join('');
18
+ if (chars.length > 100)
19
+ preview += '...';
20
+ return preview;
21
+ }
22
+ /** Verify no lone surrogates exist in a string */
23
+ function assertNoLoneSurrogates(str) {
24
+ for (let i = 0; i < str.length; i++) {
25
+ const code = str.charCodeAt(i);
26
+ if (code >= 0xd800 && code <= 0xdbff) {
27
+ const next = str.charCodeAt(i + 1);
28
+ assert.ok(next >= 0xdc00 && next <= 0xdfff, `Lone high surrogate at position ${i}: 0x${code.toString(16)}`);
29
+ }
30
+ if (code >= 0xdc00 && code <= 0xdfff) {
31
+ const prev = str.charCodeAt(i - 1);
32
+ assert.ok(prev >= 0xd800 && prev <= 0xdbff, `Lone low surrogate at position ${i}: 0x${code.toString(16)}`);
33
+ }
34
+ }
35
+ }
36
+ describe('loggerPreview (200 char truncation)', () => {
37
+ it('does not split emoji at boundary', () => {
38
+ const content = 'a'.repeat(199) + '👍extra';
39
+ const result = loggerPreview(content);
40
+ assert.doesNotThrow(() => JSON.stringify(result));
41
+ assertNoLoneSurrogates(result);
42
+ });
43
+ it('handles all-emoji content', () => {
44
+ const content = '🎉🎊🎈🎁🎂'.repeat(50); // 250 emoji
45
+ const result = loggerPreview(content);
46
+ assert.doesNotThrow(() => JSON.stringify(result));
47
+ assertNoLoneSurrogates(result);
48
+ assert.ok(result.endsWith('...'));
49
+ });
50
+ it('old .slice() would have split surrogate pair (proof)', () => {
51
+ const content = 'a'.repeat(199) + '👍';
52
+ // Old broken behavior
53
+ const broken = content.slice(0, 200);
54
+ const lastCode = broken.charCodeAt(199);
55
+ assert.ok(lastCode >= 0xd800 && lastCode <= 0xdbff, 'Old .slice() should produce lone high surrogate');
56
+ // Fixed behavior
57
+ const fixed = loggerPreview(content + 'x');
58
+ assertNoLoneSurrogates(fixed);
59
+ });
60
+ it('preserves short content with emoji unchanged', () => {
61
+ const content = 'Hello 👋 World 🌍';
62
+ const result = loggerPreview(content);
63
+ assert.equal(result, content);
64
+ });
65
+ });
66
+ describe('historyPreview (100 char truncation)', () => {
67
+ it('does not split emoji at boundary', () => {
68
+ const content = 'a'.repeat(99) + '🔥more';
69
+ const result = historyPreview(content);
70
+ assert.doesNotThrow(() => JSON.stringify(result));
71
+ assertNoLoneSurrogates(result);
72
+ });
73
+ it('handles mixed CJK + emoji at boundary', () => {
74
+ const content = 'あ'.repeat(49) + 'a' + '😀tail'; // 52 graphemes
75
+ const result = historyPreview(content);
76
+ assert.doesNotThrow(() => JSON.stringify(result));
77
+ assertNoLoneSurrogates(result);
78
+ });
79
+ it('handles flag emoji (4 UTF-16 code units)', () => {
80
+ const content = 'x'.repeat(99) + '🇯🇵rest';
81
+ const result = historyPreview(content);
82
+ assert.doesNotThrow(() => JSON.stringify(result));
83
+ assertNoLoneSurrogates(result);
84
+ });
85
+ it('old .slice() would have split surrogate pair (proof)', () => {
86
+ const content = 'a'.repeat(99) + '👍';
87
+ // Old broken behavior
88
+ const broken = content.slice(0, 100);
89
+ const lastCode = broken.charCodeAt(99);
90
+ assert.ok(lastCode >= 0xd800 && lastCode <= 0xdbff, 'Old .slice() should produce lone high surrogate');
91
+ // Fixed behavior
92
+ const fixed = historyPreview(content + 'x');
93
+ assertNoLoneSurrogates(fixed);
94
+ });
95
+ });
96
+ //# sourceMappingURL=surrogate-safety.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surrogate-safety.test.js","sourceRoot":"","sources":["../src/surrogate-safety.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "elyth-agent",
3
- "version": "0.4.6",
4
- "description": "ELYTH 自律型AI VTuberエージェントCLI",
3
+ "version": "0.6.0",
4
+ "description": "ELYTH 自律型AITuberエージェントCLI",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "elyth-agent": "./dist/index.js"
@@ -10,7 +10,7 @@
10
10
  "dist/"
11
11
  ],
12
12
  "scripts": {
13
- "build": "tsc && node -e \"require('fs').copyFileSync('src/prompt/system-base.md','dist/prompt/system-base.md')\"",
13
+ "build": "tsc && node -e \"['system-base.md','dev-base.md'].forEach(f=>require('fs').copyFileSync('src/prompt/'+f,'dist/prompt/'+f))\"",
14
14
  "dev": "tsc --watch"
15
15
  },
16
16
  "dependencies": {