From 5926ccfb32ea695cbe72fda6efe94bcc0a82f0f1 Mon Sep 17 00:00:00 2001 From: rrader2890 Date: Mon, 13 Jul 2026 21:23:07 -0400 Subject: [PATCH] feat: brains resource for the marketplace registry (v0.6.0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds `tf.brains` — CRUD over the Brain Card registry (create / list / get / update / delete against /projects/:id/brains), plus Brain / BrainCard / Brain{Visibility,Status} / Create|UpdateBrainRequest / ListBrainsParams types. Mirrors the existing resource pattern. Consumption of a published brain is over the hosted MCP endpoint (/brains/:brainId/mcp-server/http) — an MCP connection, not a REST call — so it stays outside this resource. Typecheck + build green. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 29 ++++++++++++++++ package.json | 2 +- src/client.ts | 3 ++ src/index.ts | 13 ++++++++ src/resources/brains.ts | 66 +++++++++++++++++++++++++++++++++++++ src/types/brain.ts | 73 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 src/resources/brains.ts create mode 100644 src/types/brain.ts diff --git a/README.md b/README.md index e9b64e3..648cdd3 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,35 @@ const tf = new ThinkFleetMemory({ | `runMonitorTick()` | `POST /projects/:id/lattice/monitor/tick` | | `getMonitorStatus()` | `GET /projects/:id/lattice/monitor/status` | +### `tf.brains` — marketplace registry + +Register, version, and manage the brains a project publishes (a brain = a Brain +Card manifest + a stable `externalId` slug). Once a brain is `PUBLISHED` + +`PUBLIC`, any caller consumes it over the hosted MCP endpoint +(`/brains/:brainId/mcp-server/http`) — an MCP connection, not a REST call, so it +lives outside this resource. + +| Method | Endpoint | +| -------------------------- | ----------------------------------------- | +| `create(body)` | `POST /projects/:id/brains` | +| `list(params?)` | `GET /projects/:id/brains` | +| `get(brainId)` | `GET /projects/:id/brains/:brainId` | +| `update(brainId, body)` | `PATCH /projects/:id/brains/:brainId` | +| `delete(brainId)` | `DELETE /projects/:id/brains/:brainId` | + +```ts +const brain = await tf.brains.create({ + externalId: 'sec-edgar-financials', + name: 'SEC EDGAR Financials', + domain: 'finance', + card: { provenance: [{ source: 'SEC EDGAR', license: 'public-domain' }] }, +}) +await tf.brains.update(brain.id, { visibility: 'PUBLIC', status: 'PUBLISHED' }) + +const page = await tf.brains.list({ limit: 20 }) +for (const b of page.data) console.log(b.externalId, b.status) +``` + --- ## Predict anything (v2) diff --git a/package.json b/package.json index d3b028a..9700913 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@thinkfleet/memory-sdk", - "version": "0.5.0", + "version": "0.6.0", "description": "TypeScript SDK for app.memmesh.ai — admin + project memory CRUD, semantic search, feedback, and Lattice behavioral patterns", "type": "module", "main": "./dist/index.cjs", diff --git a/src/client.ts b/src/client.ts index a73579f..8a48af5 100644 --- a/src/client.ts +++ b/src/client.ts @@ -2,6 +2,7 @@ import { HttpClient } from './core/http-client.js' import type { RequestInterceptor, ResponseInterceptor } from './core/types.js' import { AlertsResource } from './resources/alerts.js' import { BehaviorsResource } from './resources/behaviors.js' +import { BrainsResource } from './resources/brains.js' import { ComplianceResource } from './resources/compliance.js' import { ContextResource } from './resources/context.js' import { EventsResource } from './resources/events.js' @@ -64,6 +65,7 @@ export class ThinkFleetMemory { readonly health: HealthResource readonly financial: FinancialResource readonly typed: TypedAttributesResource + readonly brains: BrainsResource constructor(options: ThinkFleetMemoryOptions) { if (!options.apiKey) { @@ -95,5 +97,6 @@ export class ThinkFleetMemory { this.health = new HealthResource(http) this.financial = new FinancialResource(http) this.typed = new TypedAttributesResource(http) + this.brains = new BrainsResource(http) } } diff --git a/src/index.ts b/src/index.ts index fba1f61..d22d1f2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -110,6 +110,19 @@ export type { } from './resources/learning.js' export { HealthResource } from './resources/health.js' export { FinancialResource } from './resources/financial.js' +export { BrainsResource } from './resources/brains.js' + +// Types — brain marketplace +export type { + Brain, + BrainCard, + BrainProvenance, + BrainVisibility, + BrainStatus, + CreateBrainRequest, + UpdateBrainRequest, + ListBrainsParams, +} from './types/brain.js' // Types — financial export type { diff --git a/src/resources/brains.ts b/src/resources/brains.ts new file mode 100644 index 0000000..06ab46d --- /dev/null +++ b/src/resources/brains.ts @@ -0,0 +1,66 @@ +import type { HttpClient } from '../core/http-client.js' +import type { RequestOptions, SeekPage } from '../core/types.js' +import type { + Brain, + CreateBrainRequest, + ListBrainsParams, + UpdateBrainRequest, +} from '../types/brain.js' + +/** + * Brains — the marketplace registry. + * + * Register, version, and manage the brains a project publishes. A brain carries + * a Brain Card manifest (ontology, provenance, coverage, eval, pricing) and a + * stable `externalId` slug. Once a brain is `PUBLISHED` + `PUBLIC`, any caller + * can consume it over the hosted MCP endpoint + * (`/brains/{brainId}/mcp-server/http`); consumption is an MCP connection, not a + * REST call, so it lives outside this resource. + * + * @example + * ```ts + * const brain = await tf.brains.create({ + * externalId: 'sec-edgar-financials', + * name: 'SEC EDGAR Financials', + * domain: 'finance', + * version: '2026.07.0', + * card: { provenance: [{ source: 'SEC EDGAR', license: 'public-domain' }] }, + * }) + * await tf.brains.update(brain.id, { visibility: 'PUBLIC', status: 'PUBLISHED' }) + * + * const page = await tf.brains.list({ limit: 20 }) + * for (const b of page.data) console.log(b.externalId, b.status) + * ``` + */ +export class BrainsResource { + constructor(private readonly http: HttpClient) {} + + /** Register a new brain in the project's catalog. */ + async create(body: CreateBrainRequest, options?: RequestOptions): Promise { + return this.http.post('/brains', body, options) + } + + /** List the project's brains (cursor-paginated). */ + async list(params?: ListBrainsParams, options?: RequestOptions): Promise> { + return this.http.get>( + '/brains', + params as Record | undefined, + options, + ) + } + + /** Fetch one brain by id. */ + async get(brainId: string, options?: RequestOptions): Promise { + return this.http.get(`/brains/${brainId}`, undefined, options) + } + + /** Update / version a brain (name, version, visibility, status, card, …). */ + async update(brainId: string, body: UpdateBrainRequest, options?: RequestOptions): Promise { + return this.http.patch(`/brains/${brainId}`, body, options) + } + + /** Delete a brain from the catalog. */ + async delete(brainId: string, options?: RequestOptions): Promise { + await this.http.delete<{ success: boolean }>(`/brains/${brainId}`, options) + } +} diff --git a/src/types/brain.ts b/src/types/brain.ts new file mode 100644 index 0000000..7d7c44f --- /dev/null +++ b/src/types/brain.ts @@ -0,0 +1,73 @@ +import type { BaseModel } from './common.js' + +/** + * Brain marketplace types. + * + * A Brain is a publishable/consumable unit of memory: a Brain Card manifest + * plus a stable `externalId` slug the Mesh Router addresses it by. This SDK + * covers the registry (create / list / get / update / delete). Consumption of a + * published brain happens over the hosted MCP endpoint + * (`/api/v1/projects/{projectId}/brains/{brainId}/mcp-server/http`), which an + * MCP client connects to directly — it is not a REST call. + */ + +export type BrainVisibility = 'PUBLIC' | 'UNLISTED' | 'PRIVATE' +export type BrainStatus = 'DRAFT' | 'PUBLISHED' | 'ARCHIVED' + +/** Provenance of the facts in a brain — where they came from and under what license. */ +export interface BrainProvenance { + source: string + license: string + url?: string +} + +/** The Brain Card manifest (stored on the brain, surfaced in the catalog). */ +export interface BrainCard { + ontologyRef?: string + provenance?: BrainProvenance[] + changelogRef?: string + coverage?: { subjects?: number; facts?: number; freshness?: string } + evaluation?: { benchmark?: string; score?: number } + predictEnabled?: boolean + pricing?: { model?: string; unit?: string } +} + +export interface Brain extends BaseModel { + projectId: string + /** Stable slug the Router addresses the brain by (unique per project). */ + externalId: string + name: string + domain: string | null + /** Brain Interface contract version the brain conforms to (e.g. "v1"). */ + brainInterface: string + version: string + visibility: BrainVisibility + status: BrainStatus + rightsAttested: boolean + card: BrainCard | null +} + +export interface CreateBrainRequest { + externalId: string + name: string + domain?: string + version?: string + visibility?: BrainVisibility + rightsAttested?: boolean + card?: BrainCard +} + +export interface UpdateBrainRequest { + name?: string + domain?: string + version?: string + visibility?: BrainVisibility + status?: BrainStatus + rightsAttested?: boolean + card?: BrainCard +} + +export interface ListBrainsParams { + limit?: number + cursor?: string +}