@unson/brainbase-mcp 0.46.0 → 0.46.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.
|
@@ -3,6 +3,8 @@ import type { AuthorizationServerMetadata, OAuthClientInformationMixed, OAuthTok
|
|
|
3
3
|
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
4
4
|
import { type MeetingSourceAccessDetail, type MeetingSourceCallTool, type MeetingSourceFailure, type MeetingSourceFailureReason, type MeetingSourceMeeting, type MeetingSourceProvider, type MeetingSourceSegment, type TactiqTranscriptBudget, type TactiqTranscriptRead } from './meeting-source-reader.js';
|
|
5
5
|
import type { OrganizationConnectionBinding, OrganizationConnectionProviderAdapter } from './organization-connection.js';
|
|
6
|
+
export declare const MEETING_SOURCE_LIST_REVISION = 2;
|
|
7
|
+
export declare const MEETING_SOURCE_RELIST_LOOKBACK_MS: number;
|
|
6
8
|
export type MeetingSourceCapability = 'meetings:list' | 'transcript:read';
|
|
7
9
|
export type MeetingSourceConnectionStatus = 'pending' | 'connected' | 'reauth_required' | 'disabled' | 'revoked';
|
|
8
10
|
export interface MeetingSourceConnectionRecord {
|
|
@@ -156,6 +158,8 @@ export interface MeetingSourceSyncState {
|
|
|
156
158
|
provider: MeetingSourceProvider;
|
|
157
159
|
syncEnabled: boolean;
|
|
158
160
|
listedThrough: string | null;
|
|
161
|
+
/** List-reader revision that produced listedThrough; older cursors are re-listed once. */
|
|
162
|
+
listRevision?: number;
|
|
159
163
|
pending: MeetingSourcePendingMeeting[];
|
|
160
164
|
unobtainable: Array<{
|
|
161
165
|
meetingId: string;
|
|
@@ -12,6 +12,8 @@ import { createTactiqTranscriptBudget, listMeetings, probeTranscript, readTransc
|
|
|
12
12
|
*/
|
|
13
13
|
const HOUR_MS = 60 * 60 * 1000;
|
|
14
14
|
const DAY_MS = 24 * HOUR_MS;
|
|
15
|
+
export const MEETING_SOURCE_LIST_REVISION = 2;
|
|
16
|
+
export const MEETING_SOURCE_RELIST_LOOKBACK_MS = 30 * DAY_MS;
|
|
15
17
|
const PROVIDERS = ['plaud', 'tactiq'];
|
|
16
18
|
const CAPABILITIES = ['meetings:list', 'transcript:read'];
|
|
17
19
|
const STATUSES = ['pending', 'connected', 'reauth_required', 'disabled', 'revoked'];
|
|
@@ -405,11 +407,15 @@ export async function syncMeetingSourceConnection(input) {
|
|
|
405
407
|
state.lastAttemptAt = started.toISOString();
|
|
406
408
|
const callTool = (name, args) => input.runtime.callTool(connection, name, args);
|
|
407
409
|
const until = input.window ? input.window.until : started.toISOString();
|
|
408
|
-
const
|
|
409
|
-
? input.
|
|
410
|
-
:
|
|
411
|
-
|
|
412
|
-
|
|
410
|
+
const normalSince = state.listedThrough
|
|
411
|
+
? Date.parse(state.listedThrough) - (input.overlapMs ?? DAY_MS)
|
|
412
|
+
: started.getTime() - (input.initialLookbackMs ?? 7 * DAY_MS);
|
|
413
|
+
const sinceMs = !input.window
|
|
414
|
+
&& state.listedThrough
|
|
415
|
+
&& (state.listRevision ?? 1) < MEETING_SOURCE_LIST_REVISION
|
|
416
|
+
? Math.min(normalSince, started.getTime() - MEETING_SOURCE_RELIST_LOOKBACK_MS)
|
|
417
|
+
: normalSince;
|
|
418
|
+
const since = input.window ? input.window.since : new Date(sinceMs).toISOString();
|
|
413
419
|
const finish = async (failure, delivered) => {
|
|
414
420
|
if (failure) {
|
|
415
421
|
state.lastError = { ...failure, at: now().toISOString() };
|
|
@@ -529,8 +535,11 @@ export async function syncMeetingSourceConnection(input) {
|
|
|
529
535
|
if (!listed.complete) {
|
|
530
536
|
failure ??= { reason: 'incomplete', message: 'The meeting list could not be read completely for the period' };
|
|
531
537
|
}
|
|
532
|
-
else if (!input.window
|
|
533
|
-
state.listedThrough
|
|
538
|
+
else if (!input.window) {
|
|
539
|
+
if (!state.listedThrough || Date.parse(until) > Date.parse(state.listedThrough)) {
|
|
540
|
+
state.listedThrough = until;
|
|
541
|
+
}
|
|
542
|
+
state.listRevision = MEETING_SOURCE_LIST_REVISION;
|
|
534
543
|
}
|
|
535
544
|
return finish(failure, delivered);
|
|
536
545
|
}
|
|
@@ -153,7 +153,7 @@ async function listPlaud(callTool, since, until, utcOffsetMinutes, pageSize) {
|
|
|
153
153
|
const meetings = [];
|
|
154
154
|
let complete = false;
|
|
155
155
|
for (let page = 1; page <= MAX_PAGES; page += 1) {
|
|
156
|
-
const items =
|
|
156
|
+
const items = plaudListItems(await invoke(callTool, 'list_files', { date_from: dateFrom, date_to: dateTo, page, page_size: pageSize }));
|
|
157
157
|
for (const item of items) {
|
|
158
158
|
const meeting = plaudMeeting(item, utcOffsetMinutes);
|
|
159
159
|
if (!meeting)
|
|
@@ -401,10 +401,25 @@ function payloadOf(result) {
|
|
|
401
401
|
return record.structuredContent;
|
|
402
402
|
if (Array.isArray(record.content)) {
|
|
403
403
|
const text = contentText(record);
|
|
404
|
-
|
|
404
|
+
const parsed = parseJson(text);
|
|
405
|
+
if (parsed !== null)
|
|
406
|
+
return parsed;
|
|
407
|
+
const wrapped = unwrapUntrustedUserData(text);
|
|
408
|
+
return wrapped.found ? wrapped.value : text;
|
|
405
409
|
}
|
|
406
410
|
return result;
|
|
407
411
|
}
|
|
412
|
+
function unwrapUntrustedUserData(text) {
|
|
413
|
+
const opening = /<(untrusted-user-data-[0-9a-f]+)\s+source="[^"]*">/.exec(text);
|
|
414
|
+
if (!opening)
|
|
415
|
+
return { found: false };
|
|
416
|
+
const start = opening.index + opening[0].length;
|
|
417
|
+
const end = text.lastIndexOf(`</${opening[1]}>`);
|
|
418
|
+
if (end < start)
|
|
419
|
+
return { found: false };
|
|
420
|
+
const inner = text.slice(start, end).trim();
|
|
421
|
+
return { found: true, value: parseJson(inner) ?? inner };
|
|
422
|
+
}
|
|
408
423
|
function contentText(record) {
|
|
409
424
|
if (!Array.isArray(record.content))
|
|
410
425
|
return '';
|
|
@@ -414,6 +429,18 @@ function contentText(record) {
|
|
|
414
429
|
.map((item) => item.text)
|
|
415
430
|
.join('\n');
|
|
416
431
|
}
|
|
432
|
+
function plaudListItems(payload) {
|
|
433
|
+
if (Array.isArray(payload))
|
|
434
|
+
return payload;
|
|
435
|
+
const record = asRecord(payload);
|
|
436
|
+
if (record) {
|
|
437
|
+
for (const key of ['data', 'files', 'items', 'results', 'records', 'recordings']) {
|
|
438
|
+
if (Array.isArray(record[key]))
|
|
439
|
+
return record[key];
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
throw new UnexpectedShapeError('Plaud list_files returned a response in an unknown shape');
|
|
443
|
+
}
|
|
417
444
|
function extractList(payload) {
|
|
418
445
|
if (Array.isArray(payload))
|
|
419
446
|
return payload;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unson/brainbase-mcp",
|
|
3
|
-
"version": "0.46.
|
|
3
|
+
"version": "0.46.1",
|
|
4
4
|
"description": "Local-first Brainbase judgment OS that lets supported AI agents reuse a user's approved goals, priorities, decisions, and judgment criteria.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -586,7 +586,7 @@
|
|
|
586
586
|
"build:world": "node scripts/build-world-vendor.mjs"
|
|
587
587
|
},
|
|
588
588
|
"dependencies": {
|
|
589
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
589
|
+
"@modelcontextprotocol/sdk": "^1.32.0",
|
|
590
590
|
"graphology": "0.26.0",
|
|
591
591
|
"js-yaml": "^4.1.1",
|
|
592
592
|
"sigma": "3.0.3",
|
|
@@ -620,5 +620,5 @@
|
|
|
620
620
|
"url": "https://github.com/Unson-LLC/brainbase/issues"
|
|
621
621
|
},
|
|
622
622
|
"homepage": "https://github.com/Unson-LLC/brainbase#readme",
|
|
623
|
-
"gitHead": "
|
|
623
|
+
"gitHead": "514e31c00aeb6906c01cb5df51cf9bea0f62eee2"
|
|
624
624
|
}
|