UNPKG

@fusedashlabs/ui9000-workspace

Version:

UI9000 workspace MCP. One tool, show_workspace, draws a chart from your table. Set TYPESAFE_API_KEY to let Jev choose the chart.

185 lines (184 loc) • 9.37 kB
import type { EngineCatalog } from '../spec/engine-catalog.js'; import type { DataProfile } from '../spec/data-profile.js'; import { type WorkspaceSpec } from '../spec/workspace-spec.js'; import { type ClassifiedColumn } from '../profiler/roles.js'; import { type Table } from '../profiler/table.js'; import { type SignDataLink } from './data-channel.js'; import { type IngestOptions, type StoredDataset } from './ingest-table.js'; import { type Trace, type TraceProposal } from '../trace/trace.js'; import { type JevChartRequest, type JevChartResponse } from '../jev/chart-choice.js'; export declare const SHOW_WORKSPACE_NAME = "show_workspace"; export declare const SHOW_WORKSPACE_CODES: readonly ["invalid_args", "rows_in_args", "invalid_ingest", "dataset_not_found", "unknown_intent", "missing_context", "missing_signer", "signer_failed", "leaky_handle", "missing_binds", "no_winner", "chart_unbuilt", "invalid_spec", "map_unrenderable"]; export type ShowWorkspaceCode = (typeof SHOW_WORKSPACE_CODES)[number]; export type ShowWorkspaceOk = { ok: true; spec: WorkspaceSpec; summary: string; /** Why this chart was drawn. The model should say it to the user. */ chartWhy?: string; /** Closer chart from the column reading. The drawn chart stays the one named. */ suggestion?: string; suggestionWhy?: string; /** FuseDash chartType for the hosted MCP App. Absent when the View cannot render. */ chartType?: string; /** Opaque id for the ingested table. Pass it on the next intent instead of csv. */ datasetId?: string; rowCount?: number; columns?: string[]; trace: Trace; traceId: string; /** Present only when a catalog action is held. A preview, not an execution. */ proposal?: TraceProposal; }; export type ShowWorkspaceFail = { ok: false; code: ShowWorkspaceCode; reason: string; }; export type ShowWorkspaceResult = ShowWorkspaceOk | ShowWorkspaceFail; export type ShowWorkspaceContext = { catalog: EngineCatalog; profile: DataProfile; /** Dataset payload for the handle. Never copied into the MCP result. */ payload?: unknown; /** Column names / control labels — not row objects. Used to satisfy catalog dataRoles. */ fields?: readonly string[]; /** * Profiler classification. When set, binds map catalog roles to those columns * (category→team, metric→incidents) instead of CSV order. */ classified?: readonly ClassifiedColumn[]; /** * Tests inject a stub. Production omits this so `attachDataHandle` calls * migrate `signDataLink`. A non-function value is `missing_signer`. */ signDataLink?: SignDataLink; /** Hosted/production: csv + datasetId only. */ allowRemoteSources?: boolean; maxBytes?: number; cwd?: string; /** Optional jail for csv paths. See MCP_DATASET_ROOT. */ datasetRoot?: string; fetchImpl?: IngestOptions['fetchImpl']; loadDataset?: (id: string) => StoredDataset | undefined | Promise<StoredDataset | undefined>; /** Stdio session: keep the last ingested table for later `{ intent }` calls. */ rememberTable?: (table: Table) => void; /** * Column names from the previous call on this session. Reapplied when the * caller reuses the table and omits `columns`. A new csv/url/path without * `columns` clears it. */ selectedColumns?: readonly string[]; rememberColumns?: (names: readonly string[] | undefined) => void; /** * Production sets this from TYPESAFE_API_KEY. Tests inject a stub. * Absent: a named chart still draws, and an unnamed chart uses decide(). */ askJev?: (request: JevChartRequest) => Promise<JevChartResponse>; }; export declare const SHOW_WORKSPACE_INPUT_SCHEMA: { readonly type: "object"; readonly additionalProperties: false; readonly required: readonly ["intent"]; readonly properties: { readonly intent: { readonly type: "string"; readonly enum: readonly ["spatial", "comparison", "summary", "form", "evidence", "graph"]; readonly description: "Closed objective. One of spatial, comparison, summary, form, evidence, graph. Do not invent values."; }; readonly csv: { readonly type: "string"; readonly description: "Pasted CSV including the header row. Use this when the user attached or pasted a table. Empty string means omit."; }; readonly url: { readonly type: "string"; readonly description: "http(s) URL to a CSV. Local/dev only — rejected on hosted/production. Empty string means omit."; }; readonly path: { readonly type: "string"; readonly description: "Local CSV path (absolute, or relative to cwd). Local/dev only. Empty string means omit."; }; readonly datasetId: { readonly type: "string"; readonly description: "Id returned by an earlier show_workspace on this table. Use instead of csv/url/path."; }; readonly columns: { readonly type: "array"; readonly items: { readonly type: "string"; }; readonly description: "Step 1. Column names the user asked to chart. Omit to use the whole table. Names only, not cell values."; }; readonly utterance: { readonly type: "string"; readonly description: "The user's words, for Jev. Pass the request as they wrote it. Empty string means omit."; }; readonly requestedChart: { readonly type: "string"; readonly description: "Step 3. The chart the user asked for, in their words or an id from a previous reply. Omit when they did not name a chart. On a new table, a known chart the utterance does not name is ignored. An unknown name is kept. A datasetId call with no new csv, url, or path keeps the id."; }; readonly confirm: { readonly type: "boolean"; readonly description: "Ignored. The next call draws the chart the user picks. Pass it as requestedChart with the same datasetId."; }; }; }; /** * ~2–3 KB. Lists intents, not the 20 engine component ids. * The model may send a CSV source; it must not send chart `data[]` rows. */ export declare const SHOW_WORKSPACE_DESCRIPTION: string; export declare const SHOW_WORKSPACE_TOOL: { name: string; description: string; inputSchema: { readonly type: "object"; readonly additionalProperties: false; readonly required: readonly ["intent"]; readonly properties: { readonly intent: { readonly type: "string"; readonly enum: readonly ["spatial", "comparison", "summary", "form", "evidence", "graph"]; readonly description: "Closed objective. One of spatial, comparison, summary, form, evidence, graph. Do not invent values."; }; readonly csv: { readonly type: "string"; readonly description: "Pasted CSV including the header row. Use this when the user attached or pasted a table. Empty string means omit."; }; readonly url: { readonly type: "string"; readonly description: "http(s) URL to a CSV. Local/dev only — rejected on hosted/production. Empty string means omit."; }; readonly path: { readonly type: "string"; readonly description: "Local CSV path (absolute, or relative to cwd). Local/dev only. Empty string means omit."; }; readonly datasetId: { readonly type: "string"; readonly description: "Id returned by an earlier show_workspace on this table. Use instead of csv/url/path."; }; readonly columns: { readonly type: "array"; readonly items: { readonly type: "string"; }; readonly description: "Step 1. Column names the user asked to chart. Omit to use the whole table. Names only, not cell values."; }; readonly utterance: { readonly type: "string"; readonly description: "The user's words, for Jev. Pass the request as they wrote it. Empty string means omit."; }; readonly requestedChart: { readonly type: "string"; readonly description: "Step 3. The chart the user asked for, in their words or an id from a previous reply. Omit when they did not name a chart. On a new table, a known chart the utterance does not name is ignored. An unknown name is kept. A datasetId call with no new csv, url, or path keeps the id."; }; readonly confirm: { readonly type: "boolean"; readonly description: "Ignored. The next call draws the chart the user picks. Pass it as requestedChart with the same datasetId."; }; }; }; }; export declare function handleShowWorkspace(args: unknown, context: ShowWorkspaceContext): Promise<ShowWorkspaceResult>; /** A later call that reuses datasetId and does not paste a new table. */ export declare function isDatasetFollowUp(raw: Record<string, unknown>): boolean;