owner-clone-ai-mcp 1.78.1 → 1.78.2
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.
- package/lib/api.js +39 -4
- package/package.json +1 -1
package/lib/api.js
CHANGED
|
@@ -6,6 +6,43 @@ const API_KEY = process.env.OCR_API_KEY;
|
|
|
6
6
|
// (配布物 manifest.json / install.ps1 / 案内はすべて api.ownercloneai.com 指定済み)。
|
|
7
7
|
const BASE_URL = (process.env.OCR_BASE_URL || 'https://api.ownercloneai.com').replace(/\/$/, '');
|
|
8
8
|
|
|
9
|
+
// ── エラー応答を「AIがそのまま読んで判断できる」文に組み立てる ────────────────
|
|
10
|
+
// ⚠️ 2026-10-01: 以前は json.error と json.detail しか見ておらず、
|
|
11
|
+
// サーバーが返している updated_at / changed / meta_only / hint を**捨てていた**。
|
|
12
|
+
// そのため B-5(409の往復をなくす)の情報が AI に届かず、
|
|
13
|
+
// 結局 get_video_project を取り直す往復が必要なままだった。
|
|
14
|
+
// ⚠️ 汎用にする: 既知のキーだけでなく、未知の付加フィールドも落とさず載せる。
|
|
15
|
+
// 将来サーバーが新しい手がかりを足しても、パッケージの改修なしで AI に届く。
|
|
16
|
+
const PRIMARY_KEYS = ['error', 'message', 'detail'];
|
|
17
|
+
// 値が長くなりすぎるもの(本体データ)は載せない。手がかりだけを渡す
|
|
18
|
+
const SKIP_KEYS = ['timeline', 'deck', 'tracks', 'slides', 'chapters', 'items', 'rows'];
|
|
19
|
+
|
|
20
|
+
function formatValue(v) {
|
|
21
|
+
if (Array.isArray(v)) return v.length ? v.join(', ') : '(なし)';
|
|
22
|
+
if (v && typeof v === 'object') return JSON.stringify(v);
|
|
23
|
+
return String(v);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function buildApiError(json, status) {
|
|
27
|
+
if (!json || typeof json !== 'object') return new Error(`API error ${status}`);
|
|
28
|
+
const head = json.detail
|
|
29
|
+
? `${json.error || 'エラー'}: ${json.detail}`
|
|
30
|
+
: (json.error || json.message || `API error ${status}`);
|
|
31
|
+
const extras = [];
|
|
32
|
+
for (const [k, v] of Object.entries(json)) {
|
|
33
|
+
if (PRIMARY_KEYS.includes(k) || SKIP_KEYS.includes(k)) continue;
|
|
34
|
+
if (v === undefined || v === null || v === '') continue;
|
|
35
|
+
extras.push(`${k}: ${formatValue(v)}`);
|
|
36
|
+
}
|
|
37
|
+
// hint はサーバーが「次に何をすべきか」を書いた文。最後に独立した行で出す
|
|
38
|
+
const hint = typeof json.hint === 'string' ? json.hint : null;
|
|
39
|
+
const body = extras.filter(x => !x.startsWith('hint: ')).join(' / ');
|
|
40
|
+
const err = new Error([head, body, hint].filter(Boolean).join('\n'));
|
|
41
|
+
err.status = status;
|
|
42
|
+
err.body = json; // プログラムから読みたいときのために原本も残す
|
|
43
|
+
return err;
|
|
44
|
+
}
|
|
45
|
+
|
|
9
46
|
async function callApi(path, options = {}) {
|
|
10
47
|
// ⚠️ 2026-09-30: `callApi(path, 'POST', body)` という別流儀で書かれた2箇所が静かに壊れていた
|
|
11
48
|
// (domains/slides.js の save_brand_theme / apply_brand_theme)。文字列を options として
|
|
@@ -30,11 +67,9 @@ async function callApi(path, options = {}) {
|
|
|
30
67
|
});
|
|
31
68
|
const json = await res.json();
|
|
32
69
|
if (!res.ok) {
|
|
33
|
-
|
|
34
|
-
const msg = json && json.detail ? `${json.error || 'エラー'}: ${json.detail}` : (json.error || `API error ${res.status}`);
|
|
35
|
-
throw new Error(msg);
|
|
70
|
+
throw buildApiError(json, res.status);
|
|
36
71
|
}
|
|
37
72
|
return json;
|
|
38
73
|
}
|
|
39
74
|
|
|
40
|
-
module.exports = { callApi };
|
|
75
|
+
module.exports = { callApi, buildApiError };
|