@dmsdc-ai/aigentry-deliberation 0.0.8 → 0.0.10

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.
@@ -154,10 +154,35 @@ class DevToolsMcpAdapter extends BrowserControlPort {
154
154
  }
155
155
  }
156
156
 
157
+ // If no matching tab found, try to open one automatically
158
+ if (!foundTab && targetHint.url) {
159
+ for (const endpoint of this.cdpEndpoints) {
160
+ try {
161
+ const baseUrl = endpoint.replace(/\/json\/list\/?$/, "");
162
+ const createUrl = `${baseUrl}/json/new?${encodeURIComponent(targetHint.url)}`;
163
+ const resp = await fetch(createUrl, {
164
+ method: "PUT",
165
+ signal: AbortSignal.timeout(5000),
166
+ });
167
+ if (resp.ok) {
168
+ const newTab = await resp.json();
169
+ if (newTab && newTab.webSocketDebuggerUrl) {
170
+ // Wait for page to initialize
171
+ await new Promise(r => setTimeout(r, 3000));
172
+ foundTab = { ...newTab, endpoint };
173
+ break;
174
+ }
175
+ }
176
+ } catch {
177
+ // endpoint not reachable or create failed
178
+ }
179
+ }
180
+ }
181
+
157
182
  if (!foundTab) {
158
183
  return makeResult(false, null, {
159
184
  code: "BIND_FAILED",
160
- message: `No matching browser tab found for provider "${provider}" (checked ${this.cdpEndpoints.length} endpoints)`,
185
+ message: `No matching browser tab found for provider "${provider}" (checked ${this.cdpEndpoints.length} endpoints). Ensure Chrome is running with --remote-debugging-port=9222 and a tab with ${targetHint.url || provider} is open.`,
161
186
  });
162
187
  }
163
188
 
package/index.js CHANGED
@@ -1171,26 +1171,29 @@ async function collectSpeakerCandidates({ include_cli = true, include_browser =
1171
1171
  candidate.cdp_ws_url = matches[0].webSocketDebuggerUrl;
1172
1172
  }
1173
1173
  }
1174
- }
1175
1174
 
1176
- // Auto-register well-known web LLMs that weren't already detected via browser scanning.
1177
- // This ensures web speakers are ALWAYS available regardless of browser detection success.
1178
- // If a browser tab for the same provider was already detected, skip auto-registration
1179
- // to avoid duplicates (e.g., detected "web-chatgpt-1" vs auto-registered "web-chatgpt").
1180
- const detectedProviders = new Set(
1181
- candidates.filter(c => c.type === "browser" && !c.auto_registered).map(c => c.provider)
1182
- );
1183
- for (const ws of DEFAULT_WEB_SPEAKERS) {
1184
- if (detectedProviders.has(ws.provider)) continue;
1185
- add({
1186
- speaker: ws.speaker,
1187
- type: "browser",
1188
- provider: ws.provider,
1189
- browser: "auto-registered",
1190
- title: ws.name,
1191
- url: ws.url,
1192
- auto_registered: true,
1193
- });
1175
+ // Auto-register well-known web LLMs that weren't already detected via browser scanning.
1176
+ // This ensures web speakers are ALWAYS available regardless of browser detection success.
1177
+ // If a browser tab for the same provider was already detected, skip auto-registration
1178
+ // to avoid duplicates (e.g., detected "web-chatgpt-1" vs auto-registered "web-chatgpt").
1179
+ const detectedProviders = new Set(
1180
+ candidates.filter(c => c.type === "browser" && !c.auto_registered).map(c => c.provider)
1181
+ );
1182
+ // CDP is reachable if we got any tabs from the endpoints (attach() handles auto-tab-creation)
1183
+ const cdpReachable = cdpTabs.length > 0 || cdpStatus.available;
1184
+ for (const ws of DEFAULT_WEB_SPEAKERS) {
1185
+ if (detectedProviders.has(ws.provider)) continue;
1186
+ add({
1187
+ speaker: ws.speaker,
1188
+ type: "browser",
1189
+ provider: ws.provider,
1190
+ browser: "auto-registered",
1191
+ title: ws.name,
1192
+ url: ws.url,
1193
+ auto_registered: true,
1194
+ cdp_available: cdpReachable,
1195
+ });
1196
+ }
1194
1197
  }
1195
1198
 
1196
1199
  return { candidates, browserNote };
@@ -1222,7 +1225,8 @@ function formatSpeakerCandidatesReport({ candidates, browserNote }) {
1222
1225
 
1223
1226
  out += "\n### Web LLM (자동 등록)\n";
1224
1227
  out += `${autoReg.map(c => {
1225
- return `- \`${c.speaker}\` ${c.title} (${c.url})`;
1228
+ const icon = c.cdp_available ? "⚡자동" : "📋클립보드";
1229
+ return `- \`${c.speaker}\` [${icon}] — ${c.title} (${c.url})`;
1226
1230
  }).join("\n")}\n`;
1227
1231
 
1228
1232
  if (browserNote) {
@@ -1330,11 +1334,25 @@ function resolveTransportForSpeaker(state, speaker) {
1330
1334
  return { transport, profile, reason: null };
1331
1335
  }
1332
1336
 
1337
+ // CLI-specific invocation flags for non-interactive execution
1338
+ const CLI_INVOCATION_HINTS = {
1339
+ claude: { cmd: "claude", flags: '-p --output-format text', example: 'claude -p --output-format text "프롬프트"' },
1340
+ codex: { cmd: "codex", flags: 'exec', example: 'codex exec "프롬프트"' },
1341
+ gemini: { cmd: "gemini", flags: '', example: 'gemini "프롬프트"' },
1342
+ aider: { cmd: "aider", flags: '--message', example: 'aider --message "프롬프트"' },
1343
+ cursor: { cmd: "cursor", flags: '', example: 'cursor "프롬프트"' },
1344
+ };
1345
+
1333
1346
  function formatTransportGuidance(transport, state, speaker) {
1334
1347
  const sid = state.id;
1335
1348
  switch (transport) {
1336
- case "cli_respond":
1337
- return `CLI speaker입니다. \`deliberation_respond(session_id: "${sid}", speaker: "${speaker}", content: "...")\`로 직접 응답하세요.`;
1349
+ case "cli_respond": {
1350
+ const hint = CLI_INVOCATION_HINTS[speaker] || null;
1351
+ const invocationGuide = hint
1352
+ ? `\n\n**CLI 호출 방법:** \`${hint.example}\`\n(플래그: \`${hint.cmd} ${hint.flags}\`)`
1353
+ : "";
1354
+ return `CLI speaker입니다. \`deliberation_respond(session_id: "${sid}", speaker: "${speaker}", content: "...")\`로 직접 응답하세요.${invocationGuide}`;
1355
+ }
1338
1356
  case "clipboard":
1339
1357
  return `브라우저 LLM speaker입니다. CDP 자동 연결 시도 중... Chrome이 이미 CDP 없이 실행 중이면 재시작이 필요할 수 있습니다.`;
1340
1358
  case "browser_auto":
@@ -2620,8 +2638,15 @@ server.tool(
2620
2638
  const turnId = state.pending_turn_id || generateTurnId();
2621
2639
  const port = getBrowserPort();
2622
2640
 
2623
- // Step 1: Attach
2624
- const attachResult = await port.attach(resolved, { provider });
2641
+ // Step 1: Attach (pass URL from participant profile for auto-tab-creation)
2642
+ const speakerProfile = (state.participant_profiles || []).find(
2643
+ p => normalizeSpeaker(p.speaker) === normalizeSpeaker(speaker)
2644
+ );
2645
+ const attachHint = {
2646
+ provider: speakerProfile?.provider || provider,
2647
+ url: speakerProfile?.url || undefined,
2648
+ };
2649
+ const attachResult = await port.attach(resolved, attachHint);
2625
2650
  if (!attachResult.ok) {
2626
2651
  return { content: [{ type: "text", text: `❌ 브라우저 탭 바인딩 실패: ${attachResult.error.message}\n\n**에러 코드:** ${attachResult.error.code}\n**도메인:** ${attachResult.error.domain}\n\nCDP 디버깅 포트가 활성화된 브라우저가 실행 중인지 확인하세요.\n\`google-chrome --remote-debugging-port=9222\`\n\n${PRODUCT_DISCLAIMER}` }] };
2627
2652
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dmsdc-ai/aigentry-deliberation",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "description": "MCP Deliberation Server — Multi-session AI deliberation with smart speaker ordering and persona roles",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -0,0 +1,19 @@
1
+ {
2
+ "provider": "copilot",
3
+ "version": "1.0.0",
4
+ "domains": ["copilot.microsoft.com"],
5
+ "selectors": {
6
+ "inputSelector": "textarea#searchbox, textarea[placeholder*='message'], #userInput",
7
+ "sendButton": "button[aria-label='Submit'], button[aria-label='Send'], button.submit-button",
8
+ "responseSelector": ".ac-textBlock, .response-message-content",
9
+ "responseContainer": "[data-content='ai-message'], .response-message",
10
+ "streamingIndicator": ".typing-indicator, .is-streaming"
11
+ },
12
+ "timing": {
13
+ "inputDelayMs": 100,
14
+ "sendDelayMs": 300,
15
+ "pollIntervalMs": 500,
16
+ "streamingTimeoutMs": 45000
17
+ },
18
+ "notes": "Microsoft Copilot web selectors - verify via DOM inspection if selectors change"
19
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "provider": "deepseek",
3
+ "version": "1.0.0",
4
+ "domains": ["chat.deepseek.com", "deepseek.com"],
5
+ "selectors": {
6
+ "inputSelector": "textarea#chat-input, textarea[placeholder*='Message'], textarea[placeholder*='Send a message']",
7
+ "sendButton": "button[aria-label='Send'], div[role='button'].ds-icon-button",
8
+ "responseSelector": ".markdown-body, .ds-markdown",
9
+ "responseContainer": ".chat-message-content",
10
+ "streamingIndicator": ".chat-message--streaming, .typing-indicator"
11
+ },
12
+ "timing": {
13
+ "inputDelayMs": 100,
14
+ "sendDelayMs": 300,
15
+ "pollIntervalMs": 500,
16
+ "streamingTimeoutMs": 60000
17
+ },
18
+ "notes": "DeepSeek web selectors - verify via DOM inspection if selectors change"
19
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "provider": "mistral",
3
+ "version": "1.0.0",
4
+ "domains": ["chat.mistral.ai", "mistral.ai"],
5
+ "selectors": {
6
+ "inputSelector": "textarea[placeholder*='Message'], textarea[placeholder*='Ask'], div[contenteditable='true']",
7
+ "sendButton": "button[aria-label='Send'], button[type='submit']",
8
+ "responseSelector": ".prose, .markdown-body",
9
+ "responseContainer": ".message-assistant, [data-role='assistant']",
10
+ "streamingIndicator": ".animate-pulse, [data-streaming='true']"
11
+ },
12
+ "timing": {
13
+ "inputDelayMs": 100,
14
+ "sendDelayMs": 300,
15
+ "pollIntervalMs": 500,
16
+ "streamingTimeoutMs": 45000
17
+ },
18
+ "notes": "Mistral Le Chat web selectors - verify via DOM inspection if selectors change"
19
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "provider": "perplexity",
3
+ "version": "1.0.0",
4
+ "domains": ["perplexity.ai", "www.perplexity.ai"],
5
+ "selectors": {
6
+ "inputSelector": "textarea[placeholder*='Ask'], textarea[placeholder*='ask'], textarea#ppl-query",
7
+ "sendButton": "button[aria-label='Submit'], button[aria-label='Send'], button.bg-super",
8
+ "responseSelector": ".prose, .markdown-content",
9
+ "responseContainer": "[data-testid='answer-content'], .answer-content",
10
+ "streamingIndicator": ".animate-pulse, [data-testid='streaming-indicator']"
11
+ },
12
+ "timing": {
13
+ "inputDelayMs": 100,
14
+ "sendDelayMs": 300,
15
+ "pollIntervalMs": 500,
16
+ "streamingTimeoutMs": 45000
17
+ },
18
+ "notes": "Perplexity web selectors - verify via DOM inspection if selectors change"
19
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "provider": "poe",
3
+ "version": "1.0.0",
4
+ "domains": ["poe.com"],
5
+ "selectors": {
6
+ "inputSelector": "textarea[class*='GrowingTextArea'], textarea[placeholder*='Talk to']",
7
+ "sendButton": "button[class*='SendButton'], button[aria-label='Send message']",
8
+ "responseSelector": ".Markdown_markdownContainer__Tz3HQ, .Message_botMessageBubble__CPGMI .Markdown_markdownContainer__Tz3HQ",
9
+ "responseContainer": ".Message_botMessageBubble__CPGMI",
10
+ "streamingIndicator": ".Message_botMessageBubble__CPGMI .ChatMessage_streamingBotMessage__wDBTh"
11
+ },
12
+ "timing": {
13
+ "inputDelayMs": 100,
14
+ "sendDelayMs": 300,
15
+ "pollIntervalMs": 500,
16
+ "streamingTimeoutMs": 45000
17
+ },
18
+ "notes": "Poe web selectors - verify via DOM inspection if selectors change. Poe uses hashed class names that may change between deployments."
19
+ }