@chatpanel/events 0.101.0 → 0.103.1
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/adapters.js +1 -83
- package/adaptive-tool-policy.js +1 -45
- package/agent.js +2 -255
- package/attribution.js +1 -132
- package/backup-envelope.js +1 -221
- package/board-tool.js +2 -165
- package/budget.js +1 -116
- package/capability.js +1 -126
- package/citations.js +5 -127
- package/client-prefs.js +1 -148
- package/context-attachments.js +8 -144
- package/cowriter-router.js +1 -83
- package/cowriter-writer.js +19 -193
- package/cowriter.js +1 -190
- package/curate.js +3 -509
- package/distance.js +1 -124
- package/engine.js +1 -131
- package/entitlement.js +1 -332
- package/entity.js +1 -354
- package/event.js +1 -175
- package/extraction.js +4 -293
- package/failover.js +1 -93
- package/find-tool.js +1 -66
- package/flowchart.js +2 -644
- package/gate.js +1 -74
- package/harness.js +4 -101
- package/index.js +1 -345
- package/invariants.js +1 -174
- package/job.js +3 -147
- package/kernel.js +1 -255
- package/knowledge-derive.js +1 -267
- package/knowledge.js +3 -230
- package/library.js +11 -280
- package/loop.js +1 -132
- package/manifest.js +1 -107
- package/markdown-authoring.js +11 -288
- package/markdown-render.js +0 -0
- package/mcp-client.js +8 -358
- package/mcp-dispatch.js +1 -52
- package/mcp-errors.js +1 -106
- package/mcp-manager.js +1 -127
- package/media-transcript.js +8 -531
- package/meeting-analyzers.js +1 -83
- package/meeting-insights.js +7 -164
- package/meeting-shape.js +1 -282
- package/meeting-text.js +5 -94
- package/memory.js +2 -638
- package/model-candidates.js +1 -358
- package/model-health.js +1 -182
- package/model-ledger.js +1 -228
- package/model-picker.js +1 -188
- package/note-actions.js +15 -246
- package/note-graph.js +1 -158
- package/note-links.js +1 -68
- package/note-mentions.js +8 -114
- package/note-plan.js +9 -107
- package/note-research.js +1 -135
- package/observability.js +1 -119
- package/omni.js +1 -125
- package/order.js +1 -78
- package/package.json +1 -4
- package/pdf-layout.js +7 -253
- package/project-run.js +20 -444
- package/project.js +1 -170
- package/promotion.js +1 -171
- package/queue.js +1 -98
- package/reach.js +1 -23
- package/recipe-tool.js +2 -161
- package/recipe.js +1 -264
- package/record-list.js +2 -110
- package/recruit.js +3 -456
- package/redaction-tokens.js +1 -61
- package/ref.js +1 -55
- package/registry.js +1 -240
- package/route-graph.js +1 -115
- package/route-strategies.js +2 -232
- package/router.js +2 -880
- package/rrf.js +1 -89
- package/rules.js +1 -142
- package/schedule.js +1 -663
- package/scm-connection.js +1 -180
- package/scopes.js +1 -12
- package/scorecard.js +1 -335
- package/search-engines.js +1 -81
- package/skill-manifest.js +1 -330
- package/skill-scan.js +3 -209
- package/skill-sources.js +1 -162
- package/skill-vars.js +2 -252
- package/slash-commands.js +1 -158
- package/source-gate.js +1 -92
- package/sources-retrieval.js +5 -186
- package/sources.js +1 -273
- package/store.js +1 -171
- package/structured.js +4 -901
- package/subject-kinds.js +1 -5
- package/subject-name.js +1 -96
- package/sync-plan.js +1 -213
- package/synthesis.js +3 -123
- package/tags.js +1 -203
- package/team-board.js +6 -337
- package/team-cache.js +2 -63
- package/team-observe.js +1 -118
- package/team-org.js +1 -348
- package/team-plan.js +4 -131
- package/team-record.js +1 -225
- package/team-run.js +9 -652
- package/team-subtask.js +2 -191
- package/team-task.js +2 -124
- package/team-tool.js +2 -196
- package/team-trail.js +2 -73
- package/team-worklog.js +2 -149
- package/team.js +1 -302
- package/text-search.js +1 -155
- package/theme.js +17 -154
- package/titles.js +4 -285
- package/tool-discovery.js +1 -87
- package/tool-dispatch.js +5 -230
- package/tool-groups.js +1 -81
- package/tool-hints.js +10 -185
- package/tool-loop-guard.js +4 -182
- package/tool-need.js +2 -124
- package/tool-result.js +2 -438
- package/tool-round.js +0 -0
- package/tool-schema.js +1 -155
- package/tool-traits.js +1 -182
- package/toolset.js +2 -88
- package/trajectory.js +1 -530
- package/turn-loop.js +4 -440
- package/upcast.js +1 -37
- package/vault.js +2 -250
- package/view.js +1 -88
- package/voice-intents.js +2 -1488
- package/voice-speaker.js +1 -98
- package/weather-tool.js +1 -65
- package/weather.js +2 -211
- package/web-search-tool.js +14 -102
- package/web-search.js +1 -160
- package/widget.js +1 -153
package/mcp-manager.js
CHANGED
|
@@ -1,127 +1 @@
|
|
|
1
|
-
|
|
2
|
-
// turns the user's configured servers into tool providers for the registry.
|
|
3
|
-
// Never throws — a server that won't connect is skipped so it can't break a chat.
|
|
4
|
-
|
|
5
|
-
import { McpClient, mcpProvider } from './mcp-client.js';
|
|
6
|
-
|
|
7
|
-
const clients = new Map(); // key -> { client, sig, name }
|
|
8
|
-
|
|
9
|
-
const keyOf = (s) => s.id || s.url || s.command;
|
|
10
|
-
const sigOf = (s) => JSON.stringify([s.url, s.headers || {}, s.command, s.args, s.env || {}, s.remoteMode || 'auto']);
|
|
11
|
-
|
|
12
|
-
// Should this remote (http) server be reached via the bridge (server-side fetch,
|
|
13
|
-
// no browser Origin) rather than a direct fetch? mode: 'auto' (bridge when the
|
|
14
|
-
// bridge is running, else direct), 'bridge' (always), 'direct' (never).
|
|
15
|
-
const remoteViaBridge = (s, bridgeAvailable) =>
|
|
16
|
-
!s.command && ((s.remoteMode || 'auto') === 'bridge' || ((s.remoteMode || 'auto') === 'auto' && !!bridgeAvailable));
|
|
17
|
-
|
|
18
|
-
// Build an McpClient from a server config: stdio (local command, via the bridge),
|
|
19
|
-
// or http (Streamable HTTP) connected directly OR proxied through the bridge.
|
|
20
|
-
// `bridgeToken` and `fetchImpl` ride through to the client: the desktop authenticates to the
|
|
21
|
-
// bridge with the per-install token (an extension is authorized by its origin), and a test
|
|
22
|
-
// hands in a fetch.
|
|
23
|
-
function clientFor(s, bridgeUrl, bridgeAvailable, { bridgeToken = '', fetchImpl = null } = {}) {
|
|
24
|
-
if (s.command) {
|
|
25
|
-
return new McpClient({ transport: 'stdio', id: s.id, command: s.command, args: s.args, env: s.env, bridgeUrl, bridgeToken, fetchImpl });
|
|
26
|
-
}
|
|
27
|
-
return new McpClient({ url: s.url, headers: s.headers || {}, bridgeUrl, viaBridge: remoteViaBridge(s, bridgeAvailable), bridgeToken, fetchImpl });
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async function withTimeout(fn, ms) {
|
|
31
|
-
const ctrl = new AbortController();
|
|
32
|
-
const t = setTimeout(() => ctrl.abort(), ms);
|
|
33
|
-
try {
|
|
34
|
-
return await fn(ctrl.signal);
|
|
35
|
-
} finally {
|
|
36
|
-
clearTimeout(t);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// A connect that is still running is not started again. Without this, every turn during a
|
|
41
|
-
// slow first connect launches another one, and the slow server gets slower.
|
|
42
|
-
const inflight = new Map();
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Connect (or reuse) one server. Never rejects — a broken server is reported and skipped,
|
|
46
|
-
* because one bad entry must not take the others down.
|
|
47
|
-
*/
|
|
48
|
-
function connectTask(s, { onError, timeoutMs, bridgeUrl, bridgeAvailable, bridgeToken, fetchImpl }) {
|
|
49
|
-
const key = keyOf(s);
|
|
50
|
-
const sig = sigOf(s);
|
|
51
|
-
let entry = clients.get(key);
|
|
52
|
-
if (entry && entry.sig !== sig) { clients.delete(key); entry = null; } // config edited → reconnect
|
|
53
|
-
if (entry) return Promise.resolve(entry.client.tools.length ? mcpProvider(entry.client, entry.name) : null);
|
|
54
|
-
if (inflight.has(key)) return inflight.get(key);
|
|
55
|
-
|
|
56
|
-
const task = (async () => {
|
|
57
|
-
try {
|
|
58
|
-
const client = clientFor(s, bridgeUrl, bridgeAvailable);
|
|
59
|
-
// stdio servers spawn a process on the bridge (often `npx`, which may download on
|
|
60
|
-
// first run) — give them much longer than HTTP servers. Bridge-proxied http adds a
|
|
61
|
-
// hop (and may front a slow upstream) → a bit more.
|
|
62
|
-
const ms = s.command ? 45000 : (remoteViaBridge(s, bridgeAvailable) ? 20000 : timeoutMs);
|
|
63
|
-
await withTimeout((signal) => client.connect(signal), ms);
|
|
64
|
-
const fresh = { client, sig, name: s.name || s.url || s.command };
|
|
65
|
-
clients.set(key, fresh);
|
|
66
|
-
return client.tools.length ? mcpProvider(client, fresh.name) : null;
|
|
67
|
-
} catch (e) {
|
|
68
|
-
clients.delete(key);
|
|
69
|
-
onError?.(s, e);
|
|
70
|
-
return null;
|
|
71
|
-
} finally {
|
|
72
|
-
inflight.delete(key);
|
|
73
|
-
}
|
|
74
|
-
})();
|
|
75
|
-
inflight.set(key, task);
|
|
76
|
-
return task;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* The tool providers available NOW, waiting at most `budgetMs` for connections.
|
|
81
|
-
*
|
|
82
|
-
* A turn used to await every connect, and an stdio server is allowed 45 seconds because
|
|
83
|
-
* `npx` may download on first run. So one cold server held the whole first message for
|
|
84
|
-
* forty-five seconds before the model saw a single byte — measured, twice, in a user's
|
|
85
|
-
* exported log (mcpMs 45002).
|
|
86
|
-
*
|
|
87
|
-
* The connect timeout was never the problem: a server that legitimately takes 45s to start
|
|
88
|
-
* should still be allowed to. What was wrong is that the USER waited for it. The connect
|
|
89
|
-
* now continues in the background and the turn proceeds without that server, which arrives
|
|
90
|
-
* for the next turn. A tool that shows up a message late is a far smaller cost than a
|
|
91
|
-
* product that appears frozen on first use.
|
|
92
|
-
*/
|
|
93
|
-
export async function getMcpProviders(servers, { onError, timeoutMs = 8000, bridgeUrl, bridgeAvailable = false, budgetMs = 4000, bridgeToken = '', fetchImpl = null } = {}) {
|
|
94
|
-
const enabled = (servers || []).filter((s) => s && s.enabled !== false && (s.url || s.command));
|
|
95
|
-
if (!enabled.length) return [];
|
|
96
|
-
|
|
97
|
-
// Record each result as it lands, so when the budget expires we can take whatever is
|
|
98
|
-
// ready without cancelling anything still in flight.
|
|
99
|
-
const ready = new Array(enabled.length).fill(null);
|
|
100
|
-
const tasks = enabled.map((s, i) => connectTask(s, { onError, timeoutMs, bridgeUrl, bridgeAvailable, bridgeToken, fetchImpl })
|
|
101
|
-
.then((p) => { ready[i] = p; return p; }));
|
|
102
|
-
|
|
103
|
-
if (budgetMs > 0) {
|
|
104
|
-
let timer;
|
|
105
|
-
await Promise.race([
|
|
106
|
-
Promise.all(tasks),
|
|
107
|
-
new Promise((res) => { timer = setTimeout(res, budgetMs); }),
|
|
108
|
-
]);
|
|
109
|
-
clearTimeout(timer);
|
|
110
|
-
} else {
|
|
111
|
-
await Promise.all(tasks);
|
|
112
|
-
}
|
|
113
|
-
return ready.filter(Boolean);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Test a single server config (used by Settings "Test" button). Returns the
|
|
117
|
-
// tool list on success; throws on failure.
|
|
118
|
-
export async function testMcpServer(server, { timeoutMs = 8000, bridgeUrl, bridgeAvailable = false, bridgeToken = '', fetchImpl = null } = {}) {
|
|
119
|
-
const client = clientFor(server, bridgeUrl, bridgeAvailable, { bridgeToken, fetchImpl });
|
|
120
|
-
const ms = server.command ? 45000 : (remoteViaBridge(server, bridgeAvailable) ? 20000 : timeoutMs);
|
|
121
|
-
await withTimeout((signal) => client.connect(signal), ms);
|
|
122
|
-
return client.tools;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export function resetMcp() {
|
|
126
|
-
clients.clear();
|
|
127
|
-
}
|
|
1
|
+
import{McpClient as w,mcpProvider as p}from"./mcp-client.js";const g=new Map,k=e=>e.id||e.url||e.command,v=e=>JSON.stringify([e.url,e.headers||{},e.command,e.args,e.env||{},e.remoteMode||"auto"]),h=(e,n)=>!e.command&&((e.remoteMode||"auto")==="bridge"||(e.remoteMode||"auto")==="auto"&&!!n);function M(e,n,l,{bridgeToken:r="",fetchImpl:c=null}={}){return e.command?new w({transport:"stdio",id:e.id,command:e.command,args:e.args,env:e.env,bridgeUrl:n,bridgeToken:r,fetchImpl:c}):new w({url:e.url,headers:e.headers||{},bridgeUrl:n,viaBridge:h(e,l),bridgeToken:r,fetchImpl:c})}async function P(e,n){const l=new AbortController,r=setTimeout(()=>l.abort(),n);try{return await e(l.signal)}finally{clearTimeout(r)}}const y=new Map;function x(e,{onError:n,timeoutMs:l,bridgeUrl:r,bridgeAvailable:c,bridgeToken:m,fetchImpl:u}){const o=k(e),i=v(e);let a=g.get(o);if(a&&a.sig!==i&&(g.delete(o),a=null),a)return Promise.resolve(a.client.tools.length?p(a.client,a.name):null);if(y.has(o))return y.get(o);const s=(async()=>{try{const t=M(e,r,c),d=e.command?45e3:h(e,c)?2e4:l;await P(T=>t.connect(T),d);const f={client:t,sig:i,name:e.name||e.url||e.command};return g.set(o,f),t.tools.length?p(t,f.name):null}catch(t){return g.delete(o),n?.(e,t),null}finally{y.delete(o)}})();return y.set(o,s),s}async function O(e,{onError:n,timeoutMs:l=8e3,bridgeUrl:r,bridgeAvailable:c=!1,budgetMs:m=4e3,bridgeToken:u="",fetchImpl:o=null}={}){const i=(e||[]).filter(t=>t&&t.enabled!==!1&&(t.url||t.command));if(!i.length)return[];const a=new Array(i.length).fill(null),s=i.map((t,d)=>x(t,{onError:n,timeoutMs:l,bridgeUrl:r,bridgeAvailable:c,bridgeToken:u,fetchImpl:o}).then(f=>(a[d]=f,f)));if(m>0){let t;await Promise.race([Promise.all(s),new Promise(d=>{t=setTimeout(d,m)})]),clearTimeout(t)}else await Promise.all(s);return a.filter(Boolean)}async function C(e,{timeoutMs:n=8e3,bridgeUrl:l,bridgeAvailable:r=!1,bridgeToken:c="",fetchImpl:m=null}={}){const u=M(e,l,r,{bridgeToken:c,fetchImpl:m}),o=e.command?45e3:h(e,r)?2e4:n;return await P(i=>u.connect(i),o),u.tools}function S(){g.clear()}export{O as getMcpProviders,S as resetMcp,C as testMcpServer};
|