@datalayer/agent-runtimes 1.5.88 → 1.5.90
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/dist-embed/datalayer-app-main.js +57 -40
- package/lib/apps/embed/element.js +20 -5
- package/lib/apps/embed/visitorApp.d.ts +23 -45
- package/lib/apps/embed/visitorApp.js +65 -13
- package/lib/apps/plugins/agent-outputs/sheets.d.ts +76 -0
- package/lib/apps/plugins/agent-outputs/sheets.js +230 -0
- package/lib/chat/messages/ChatMarkdown.d.ts +3 -1
- package/lib/chat/messages/ChatMarkdown.js +4 -1
- package/lib/chat/messages/codeBlocks.d.ts +50 -0
- package/lib/chat/messages/codeBlocks.js +81 -0
- package/lib/components/teams/A2ATeamGraph.d.ts +28 -7
- package/lib/components/teams/A2ATeamGraph.js +64 -27
- package/lib/components/teams/a2aTeamFlow.d.ts +16 -7
- package/lib/components/teams/a2aTeamFlow.js +17 -14
- package/lib/examples/AgentOutputsExample.d.ts +7 -0
- package/lib/examples/AgentOutputsExample.js +47 -7
- package/lib/examples/utils/agentOutputsPlugins.d.ts +2 -0
- package/lib/examples/utils/agentOutputsPlugins.js +27 -0
- package/lib/portable/hosts/agentClient.d.ts +8 -0
- package/lib/portable/hosts/agentClient.js +2 -0
- package/lib/portable/hosts/approvalRenderers.d.ts +10 -2
- package/lib/portable/hosts/approvalRenderers.js +81 -2
- package/lib/portable/hosts/contracts.d.ts +1 -0
- package/lib/portable/hosts/contracts.js +2 -0
- package/lib/portable/hosts/contracts.json +56 -2
- package/lib/specs/agents/agents.js +30 -8
- package/lib/specs/frontendTools.d.ts +1 -0
- package/lib/specs/frontendTools.js +18 -0
- package/lib/specs/mcpServers.js +20 -50
- package/lib/types/mcp.d.ts +4 -2
- package/package.json +2 -1
- package/scripts/codegen/generate_mcp_servers.py +35 -20
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* The Loop plugins of the outputs example (`AgentOutputsExample`): the
|
|
7
|
+
* `example-output` agent, the chat's spreadsheet renderer, and the Cells
|
|
8
|
+
* agent tools on the last spreadsheet answered. The agent runs on a server,
|
|
9
|
+
* so the page names the bundle whose tools it hands it — `cells`, the grid's
|
|
10
|
+
* tools, run on this page's reactor — through the chat extras.
|
|
11
|
+
*
|
|
12
|
+
* Apart from the page, so a test reads the list without mounting the Loop.
|
|
13
|
+
*
|
|
14
|
+
* @module examples/utils/agentOutputsPlugins
|
|
15
|
+
*/
|
|
16
|
+
import { AgentOutputsPlugin } from '../../apps/plugins/agent-outputs/index.js';
|
|
17
|
+
import { AgentOutputsSheetsPlugin, AgentOutputsSheetToolsPlugin, } from '../../apps/plugins/agent-outputs/sheets.js';
|
|
18
|
+
import { createChatExtrasPlugin } from '../../apps/plugins/chat-extras/index.js';
|
|
19
|
+
const SHEET_EXTRAS = createChatExtrasPlugin();
|
|
20
|
+
SHEET_EXTRAS.setExtras({ agentToolBundles: ['cells'] });
|
|
21
|
+
/** The Loop's plugins on the outputs page: the agent, the chat's grids, the grid's tools. */
|
|
22
|
+
export const AGENT_OUTPUTS_LOOP_PLUGINS = [
|
|
23
|
+
AgentOutputsPlugin,
|
|
24
|
+
AgentOutputsSheetsPlugin,
|
|
25
|
+
AgentOutputsSheetToolsPlugin,
|
|
26
|
+
SHEET_EXTRAS.plugin,
|
|
27
|
+
];
|
|
@@ -20,6 +20,12 @@ export type HostTurnRequest<P> = Readonly<{
|
|
|
20
20
|
* another application): a new session's uid is derived with it.
|
|
21
21
|
*/
|
|
22
22
|
sessionGeneration?: number;
|
|
23
|
+
/**
|
|
24
|
+
* The host user never linked: exchanged as a visitor, which ai-agents
|
|
25
|
+
* answers only when the installation's owner opened it to visitors and the
|
|
26
|
+
* deployment opens to somebody signed out (WHATSAPP WA-03).
|
|
27
|
+
*/
|
|
28
|
+
visitor?: boolean;
|
|
23
29
|
}>;
|
|
24
30
|
export type TurnStream = Readonly<{
|
|
25
31
|
/**
|
|
@@ -111,6 +117,8 @@ export declare class HostKeyCredentials<P> implements HostCredentials<P> {
|
|
|
111
117
|
hostKey: string;
|
|
112
118
|
/** Where the turn is asked from: Datalayer refuses a denied channel at once. */
|
|
113
119
|
place?: Place;
|
|
120
|
+
/** As a visitor: the host user never linked (WHATSAPP WA-03). */
|
|
121
|
+
visitor?: boolean;
|
|
114
122
|
}): Promise<HostExchange>;
|
|
115
123
|
forTurn(request: HostTurnRequest<P>): Promise<HostSession>;
|
|
116
124
|
}
|
|
@@ -44,6 +44,7 @@ export class HostKeyCredentials {
|
|
|
44
44
|
externalUserId: request.externalUserId,
|
|
45
45
|
hostKey,
|
|
46
46
|
place: this.shape.placeOf(request),
|
|
47
|
+
...(request.visitor ? { visitor: true } : {}),
|
|
47
48
|
});
|
|
48
49
|
}
|
|
49
50
|
/** The exchange for one host user and deployment, with a key in hand (a delivery, an action). */
|
|
@@ -53,6 +54,7 @@ export class HostKeyCredentials {
|
|
|
53
54
|
deployment_uid: input.deploymentUid,
|
|
54
55
|
external_user_id: input.externalUserId,
|
|
55
56
|
...(input.place ? { place: input.place } : {}),
|
|
57
|
+
...(input.visitor ? { visitor: true } : {}),
|
|
56
58
|
}),
|
|
57
59
|
headers: {
|
|
58
60
|
'content-type': 'application/json',
|
|
@@ -6,7 +6,9 @@ import type { ApprovalPresentation } from './contracts';
|
|
|
6
6
|
* presented is named by the renderer, or the card fails closed. An unknown
|
|
7
7
|
* tool, an argument the renderer does not know, an attachment, and every
|
|
8
8
|
* action that is not mail (reads, writes, other sends, destructive, financial,
|
|
9
|
-
* publishing, executing) are reviewed in Datalayer (decided by the user on 16 October 2026: mail only)
|
|
9
|
+
* publishing, executing) are reviewed in Datalayer (decided by the user on 16 October 2026: mail only),
|
|
10
|
+
* but for a company's `pap_confirm`, decided in a host with the operation's
|
|
11
|
+
* exact revision since 28 October 2026 (the user, WHATSAPP WA-43).
|
|
10
12
|
* They render ai-agents' presentation v1, a different input
|
|
11
13
|
* from `../approvals.ts` and `../approvalCard.ts`. Moved from the Slack
|
|
12
14
|
* service (DC-004).
|
|
@@ -39,7 +41,13 @@ type Renderer = Readonly<{
|
|
|
39
41
|
export declare const DATALAYER_ONLY: Set<"unknown" | "read" | "write" | "send" | "delete" | "publish" | "execute" | "financial">;
|
|
40
42
|
/** The words of a tool's name that make a send mail: contracts.json `mail_words`. */
|
|
41
43
|
export declare const MAIL_WORDS: ReadonlySet<string>;
|
|
42
|
-
|
|
44
|
+
export declare const isPapConfirm: (toolName: string) => boolean;
|
|
45
|
+
/** What a `pap_confirm` approval carries: contracts.json `presentation.pap_confirm_keys`. */
|
|
46
|
+
export declare const PAP_CONFIRM_KEYS: readonly ["key", "company", "summary", "terms", "operation_ref", "revision", "digest", "class", "session", "only_the_person", "was"];
|
|
47
|
+
/**
|
|
48
|
+
* The renderers, the first that matches wins: a company's `pap_confirm`
|
|
49
|
+
* (whose name says no class), then Datalayer-only before any other.
|
|
50
|
+
*/
|
|
43
51
|
export declare const RENDERERS: readonly Renderer[];
|
|
44
52
|
/**
|
|
45
53
|
* How a host shows an approval, by the renderer that knows its tool; with
|
|
@@ -98,6 +98,82 @@ const mail = {
|
|
|
98
98
|
return rendered('mail', presentation, fields, MAIL_KEYS, extra);
|
|
99
99
|
},
|
|
100
100
|
};
|
|
101
|
+
/** `pap_confirm`, as the gateway names it with or without a prefix. */
|
|
102
|
+
const PAP_CONFIRM = /(^|[_.:\-/])pap_confirm$/;
|
|
103
|
+
export const isPapConfirm = (toolName) => PAP_CONFIRM.test(toolName);
|
|
104
|
+
/** What a `pap_confirm` approval carries: contracts.json `presentation.pap_confirm_keys`. */
|
|
105
|
+
export const PAP_CONFIRM_KEYS = [
|
|
106
|
+
'key',
|
|
107
|
+
'company',
|
|
108
|
+
'summary',
|
|
109
|
+
'terms',
|
|
110
|
+
'operation_ref',
|
|
111
|
+
'revision',
|
|
112
|
+
'digest',
|
|
113
|
+
'class',
|
|
114
|
+
'session',
|
|
115
|
+
'only_the_person',
|
|
116
|
+
'was',
|
|
117
|
+
];
|
|
118
|
+
/**
|
|
119
|
+
* A company's operation the person confirms (WHATSAPP WA-43, decided by the
|
|
120
|
+
* user 28 October 2026): the company, its own summary, every term, the
|
|
121
|
+
* operation and its **exact revision** — a decision is on that revision and
|
|
122
|
+
* no other; a changed revision is another approval. A missing company,
|
|
123
|
+
* summary, operation, revision or digest fails the card closed.
|
|
124
|
+
*/
|
|
125
|
+
const papConfirm = {
|
|
126
|
+
name: 'pap-confirm',
|
|
127
|
+
matches: presentation => isPapConfirm(presentation.tool_name),
|
|
128
|
+
render(presentation) {
|
|
129
|
+
const args = presentation.arguments;
|
|
130
|
+
const fields = [];
|
|
131
|
+
const missing = [];
|
|
132
|
+
const extra = [];
|
|
133
|
+
const company = typeof args.company === 'string' ? args.company : '';
|
|
134
|
+
const summary = typeof args.summary === 'string' ? args.summary : '';
|
|
135
|
+
const operation = typeof args.operation_ref === 'string' ? args.operation_ref : '';
|
|
136
|
+
const revision = Number.isInteger(args.revision)
|
|
137
|
+
? args.revision
|
|
138
|
+
: undefined;
|
|
139
|
+
if (!company)
|
|
140
|
+
missing.push('the company');
|
|
141
|
+
else
|
|
142
|
+
fields.push({ label: 'Company', value: company });
|
|
143
|
+
if (!summary)
|
|
144
|
+
missing.push('what it does, in its words');
|
|
145
|
+
else
|
|
146
|
+
fields.push({ label: 'Summary', value: summary });
|
|
147
|
+
const termsAreFields = args.terms === undefined ||
|
|
148
|
+
args.terms === null ||
|
|
149
|
+
(typeof args.terms === 'object' && !Array.isArray(args.terms));
|
|
150
|
+
if (!termsAreFields)
|
|
151
|
+
extra.push('Its terms are not named one by one: review it in Datalayer.');
|
|
152
|
+
else
|
|
153
|
+
for (const [name, value] of Object.entries((args.terms ?? {})))
|
|
154
|
+
fields.push({ label: name, value: text(value) });
|
|
155
|
+
if (!operation)
|
|
156
|
+
missing.push('the operation');
|
|
157
|
+
else
|
|
158
|
+
fields.push({ label: 'Operation', value: operation });
|
|
159
|
+
if (revision === undefined)
|
|
160
|
+
missing.push('its exact revision');
|
|
161
|
+
else
|
|
162
|
+
fields.push({ label: 'Revision', value: String(revision) });
|
|
163
|
+
if (typeof args.digest !== 'string' || !args.digest)
|
|
164
|
+
missing.push('the digest of its terms');
|
|
165
|
+
if (typeof args.class === 'string' && args.class)
|
|
166
|
+
fields.push({ label: 'What it does', value: args.class });
|
|
167
|
+
const was = args.was && typeof args.was === 'object'
|
|
168
|
+
? args.was
|
|
169
|
+
: undefined;
|
|
170
|
+
if (was && was.revision !== undefined)
|
|
171
|
+
fields.push({ label: 'Replaces revision', value: text(was.revision) });
|
|
172
|
+
if (missing.length)
|
|
173
|
+
extra.push(`The request does not say ${missing.join(', ')}: review it in Datalayer.`);
|
|
174
|
+
return rendered('pap-confirm', presentation, fields, PAP_CONFIRM_KEYS, extra);
|
|
175
|
+
},
|
|
176
|
+
};
|
|
101
177
|
/** Everything but mail: shown, decided only in Datalayer. */
|
|
102
178
|
const datalayerOnly = {
|
|
103
179
|
name: 'datalayer-only',
|
|
@@ -122,8 +198,11 @@ const datalayerOnly = {
|
|
|
122
198
|
};
|
|
123
199
|
},
|
|
124
200
|
};
|
|
125
|
-
/**
|
|
126
|
-
|
|
201
|
+
/**
|
|
202
|
+
* The renderers, the first that matches wins: a company's `pap_confirm`
|
|
203
|
+
* (whose name says no class), then Datalayer-only before any other.
|
|
204
|
+
*/
|
|
205
|
+
export const RENDERERS = [papConfirm, datalayerOnly, mail];
|
|
127
206
|
/**
|
|
128
207
|
* How a host shows an approval, by the renderer that knows its tool; with
|
|
129
208
|
* none, nothing is decided in the host.
|
|
@@ -104,6 +104,8 @@ export const exchangeSchema = z.object({
|
|
|
104
104
|
expires_in: z.number().int().nonnegative(),
|
|
105
105
|
exp: z.number().int(),
|
|
106
106
|
principal_uid: z.string().min(1),
|
|
107
|
+
/** A person who never linked, answered as a visitor (WHATSAPP WA-03): `principal_uid` is `visitor:<hash>`. */
|
|
108
|
+
visitor: z.boolean().optional(),
|
|
107
109
|
host_uid: z.string().min(1),
|
|
108
110
|
deployment: z.object({
|
|
109
111
|
uid: z.string().min(1),
|
|
@@ -114,6 +114,45 @@
|
|
|
114
114
|
"direct"
|
|
115
115
|
]
|
|
116
116
|
},
|
|
117
|
+
"visitor_exchange": {
|
|
118
|
+
"about": "WHATSAPP WA-03 (decided 28 October 2026): a host's user who never linked, answered as a visitor when the installation's owner turned its visitors switch on and the deployment opens to somebody signed out. sub is visitor:<hash of the host's id with the installation's salt>; no link; a daily cap per visitor at the exchange (429).",
|
|
119
|
+
"request": {
|
|
120
|
+
"external_user_id": "US.13491208655302741918",
|
|
121
|
+
"deployment_uid": "dep-1",
|
|
122
|
+
"visitor": true
|
|
123
|
+
},
|
|
124
|
+
"response_keys": [
|
|
125
|
+
"success",
|
|
126
|
+
"access_token",
|
|
127
|
+
"token_type",
|
|
128
|
+
"expires_in",
|
|
129
|
+
"exp",
|
|
130
|
+
"principal_uid",
|
|
131
|
+
"visitor",
|
|
132
|
+
"host_uid",
|
|
133
|
+
"deployment",
|
|
134
|
+
"session_api"
|
|
135
|
+
],
|
|
136
|
+
"token_claims": [
|
|
137
|
+
"jti",
|
|
138
|
+
"iss",
|
|
139
|
+
"iat",
|
|
140
|
+
"exp",
|
|
141
|
+
"aud",
|
|
142
|
+
"sub",
|
|
143
|
+
"azp",
|
|
144
|
+
"host_kind",
|
|
145
|
+
"deployment_uid",
|
|
146
|
+
"app_uid",
|
|
147
|
+
"visitor",
|
|
148
|
+
"scope"
|
|
149
|
+
],
|
|
150
|
+
"sub_prefix": "visitor:",
|
|
151
|
+
"refusals": {
|
|
152
|
+
"visitors_off": 403,
|
|
153
|
+
"capped": 429
|
|
154
|
+
}
|
|
155
|
+
},
|
|
117
156
|
"whoami": {
|
|
118
157
|
"response_keys": [
|
|
119
158
|
"success",
|
|
@@ -124,7 +163,8 @@
|
|
|
124
163
|
"app_uid",
|
|
125
164
|
"link",
|
|
126
165
|
"scope",
|
|
127
|
-
"expires_in"
|
|
166
|
+
"expires_in",
|
|
167
|
+
"visitor"
|
|
128
168
|
]
|
|
129
169
|
},
|
|
130
170
|
"bind_session": {
|
|
@@ -328,7 +368,21 @@
|
|
|
328
368
|
"host_may_decide": true,
|
|
329
369
|
"reasons": [],
|
|
330
370
|
"digest": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
331
|
-
}
|
|
371
|
+
},
|
|
372
|
+
"pap_confirm_keys": [
|
|
373
|
+
"key",
|
|
374
|
+
"company",
|
|
375
|
+
"summary",
|
|
376
|
+
"terms",
|
|
377
|
+
"operation_ref",
|
|
378
|
+
"revision",
|
|
379
|
+
"digest",
|
|
380
|
+
"class",
|
|
381
|
+
"session",
|
|
382
|
+
"only_the_person",
|
|
383
|
+
"was"
|
|
384
|
+
],
|
|
385
|
+
"pap_confirm_about": "WHATSAPP WA-43 (decided 28 October 2026): a company's pap_confirm (any gateway prefix) is decided in a host, on its exact revision; every other non-mail action stays in Datalayer."
|
|
332
386
|
},
|
|
333
387
|
"decision": {
|
|
334
388
|
"request": {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { ALPHAVANTAGE_MCP_SERVER_0_0_1, CHART_MCP_SERVER_0_0_1, EARTHDATA_MCP_SERVER_0_0_1, EURUS_MCP_SERVER_0_0_1, FILESYSTEM_MCP_SERVER_0_0_1, GITHUB_MCP_SERVER_0_0_1, GOOGLE_WORKSPACE_MCP_SERVER_0_0_1, HUGGINGFACE_MCP_SERVER_0_0_1, KAGGLE_MCP_SERVER_0_0_1, ODOO_MCP_SERVER_0_0_1, SALESFORCE_MCP_SERVER_0_0_1, SLACK_MCP_SERVER_0_0_1, TAVILY_MCP_SERVER_0_0_1, } from '../mcpServers.js';
|
|
6
6
|
import { ACCOUNTING_SKILL_SPEC_0_0_1, CRAWL_SKILL_SPEC_0_0_1, EVENTS_SKILL_SPEC_0_0_1, GITHUB_SKILL_SPEC_0_0_1, JOKES_SKILL_SPEC_0_0_1, PDF_SKILL_SPEC_0_0_1, TEXT_SUMMARIZER_SKILL_SPEC_0_0_1, } from '../skills.js';
|
|
7
7
|
import { DECIDE_BACKEND_TOOL_SPEC_0_0_1, EXAMPLE_CREATE_PLAN_BACKEND_TOOL_SPEC_0_0_1, EXAMPLE_CURRENT_TIME_BACKEND_TOOL_SPEC_0_0_1, EXAMPLE_DISPLAY_RECIPE_BACKEND_TOOL_SPEC_0_0_1, EXAMPLE_GENERATE_HAIKU_BACKEND_TOOL_SPEC_0_0_1, EXAMPLE_GENERATE_TASK_STEPS_BACKEND_TOOL_SPEC_0_0_1, EXAMPLE_GET_WEATHER_BACKEND_TOOL_SPEC_0_0_1, EXAMPLE_RENDER_A2UI_SURFACE_BACKEND_TOOL_SPEC_0_0_1, EXAMPLE_UPDATE_PLAN_STEP_BACKEND_TOOL_SPEC_0_0_1, RUNTIME_ECHO_BACKEND_TOOL_SPEC_0_0_1, RUNTIME_SEND_MAIL_BACKEND_TOOL_SPEC_0_0_1, RUNTIME_SENSITIVE_ECHO_BACKEND_TOOL_SPEC_0_0_1, } from '../backendTools.js';
|
|
8
|
-
import { DECKS_FRONTEND_TOOL_SPEC_0_0_1, JUPYTER_NOTEBOOK_EDIT_FRONTEND_TOOL_SPEC_0_0_1, JUPYTER_NOTEBOOK_PROPOSE_FRONTEND_TOOL_SPEC_0_0_1, JUPYTER_NOTEBOOK_READ_FRONTEND_TOOL_SPEC_0_0_1, JUPYTER_NOTEBOOK_FRONTEND_TOOL_SPEC_0_0_1, LEXICAL_DOCUMENT_FRONTEND_TOOL_SPEC_0_0_1, } from '../frontendTools.js';
|
|
8
|
+
import { CELLS_FRONTEND_TOOL_SPEC_0_0_1, DECKS_FRONTEND_TOOL_SPEC_0_0_1, JUPYTER_NOTEBOOK_EDIT_FRONTEND_TOOL_SPEC_0_0_1, JUPYTER_NOTEBOOK_PROPOSE_FRONTEND_TOOL_SPEC_0_0_1, JUPYTER_NOTEBOOK_READ_FRONTEND_TOOL_SPEC_0_0_1, JUPYTER_NOTEBOOK_FRONTEND_TOOL_SPEC_0_0_1, LEXICAL_DOCUMENT_FRONTEND_TOOL_SPEC_0_0_1, } from '../frontendTools.js';
|
|
9
9
|
// ============================================================================
|
|
10
10
|
// MCP Server Lookup
|
|
11
11
|
// ============================================================================
|
|
@@ -100,6 +100,8 @@ const TOOL_MAP = {
|
|
|
100
100
|
* Map frontend tool IDs to FrontendToolSpec objects.
|
|
101
101
|
*/
|
|
102
102
|
const FRONTEND_TOOL_MAP = {
|
|
103
|
+
'cells:0.0.1': CELLS_FRONTEND_TOOL_SPEC_0_0_1,
|
|
104
|
+
cells: CELLS_FRONTEND_TOOL_SPEC_0_0_1,
|
|
103
105
|
'decks:0.0.1': DECKS_FRONTEND_TOOL_SPEC_0_0_1,
|
|
104
106
|
decks: DECKS_FRONTEND_TOOL_SPEC_0_0_1,
|
|
105
107
|
'jupyter-notebook-edit:0.0.1': JUPYTER_NOTEBOOK_EDIT_FRONTEND_TOOL_SPEC_0_0_1,
|
|
@@ -3997,7 +3999,7 @@ export const EXAMPLE_OUTPUT_AGENTSPEC_0_0_1 = {
|
|
|
3997
3999
|
id: 'example-output',
|
|
3998
4000
|
version: '0.0.1',
|
|
3999
4001
|
name: 'Example Output Agent',
|
|
4000
|
-
description: `Demonstrates structured response rendering (table, json, chart, and file) for the AgentOutputsExample side panel, which detects the block in each answer and renders it.`,
|
|
4002
|
+
description: `Demonstrates structured response rendering (table, json, chart, spreadsheet and file) for the AgentOutputsExample side panel, which detects the block in each answer and renders it; a spreadsheet is drawn with Datalayer Cells, in the chat and in the panel, and charted on the grid through the Cells frontend tools.`,
|
|
4001
4003
|
tags: ['workflow', 'visualization', 'automation'],
|
|
4002
4004
|
domain: undefined,
|
|
4003
4005
|
enabled: false,
|
|
@@ -4006,7 +4008,7 @@ export const EXAMPLE_OUTPUT_AGENTSPEC_0_0_1 = {
|
|
|
4006
4008
|
skills: [].filter(Boolean),
|
|
4007
4009
|
backendTools: [],
|
|
4008
4010
|
disableToolApprovals: true,
|
|
4009
|
-
frontendTools: [],
|
|
4011
|
+
frontendTools: [FRONTEND_TOOL_MAP['cells:0.0.1']],
|
|
4010
4012
|
environmentName: 'ai-agents-env',
|
|
4011
4013
|
icon: 'table',
|
|
4012
4014
|
emoji: '📦',
|
|
@@ -4025,23 +4027,43 @@ export const EXAMPLE_OUTPUT_AGENTSPEC_0_0_1 = {
|
|
|
4025
4027
|
summary: 'Sales chart',
|
|
4026
4028
|
},
|
|
4027
4029
|
{
|
|
4028
|
-
text: '
|
|
4029
|
-
summary: '
|
|
4030
|
+
text: 'Give me a spreadsheet of twelve months of sales by region (North, South, Online), with a Month column, as one ```csv fenced block whose first line is `# filename: sales.csv`.',
|
|
4031
|
+
summary: 'Sales spreadsheet',
|
|
4032
|
+
},
|
|
4033
|
+
{
|
|
4034
|
+
text: 'Chart the sales spreadsheet: a column chart of the three regions by month, titled Sales by region, inserted on the grid below the data.',
|
|
4035
|
+
summary: 'Chart the spreadsheet',
|
|
4036
|
+
},
|
|
4037
|
+
{
|
|
4038
|
+
text: 'Create a YAML file named config.yaml for a small web service (name, port, log level and two routes), in a ```yaml fenced block whose first line is `# filename: config.yaml`.',
|
|
4039
|
+
summary: 'YAML file',
|
|
4030
4040
|
},
|
|
4031
4041
|
],
|
|
4032
|
-
welcomeMessage: 'Example output agent ready. Ask for a TABLE, JSON, a CHART or a FILE and I will answer with exactly one structured output block.',
|
|
4042
|
+
welcomeMessage: 'Example output agent ready. Ask for a TABLE, JSON, a CHART, a SPREADSHEET or a FILE and I will answer with exactly one structured output block; once a spreadsheet is shown, ask me to chart it on its grid.',
|
|
4033
4043
|
welcomeNotebook: undefined,
|
|
4034
4044
|
welcomeDocument: undefined,
|
|
4035
4045
|
sandboxVariant: 'jupyter-server',
|
|
4036
4046
|
harness: 'pydantic-ai',
|
|
4037
4047
|
systemPrompt: `You are the Example Output Agent.
|
|
4038
|
-
The user may request one of exactly
|
|
4048
|
+
The user may request one of exactly six output modes: TABLE, JSON, CHART, SPREADSHEET, FILE or SHEET CHART. For the first five, emit exactly one mode and nothing else: no prose before or after the block. Answer from what you know: do not run code or call tools to produce the block.
|
|
4039
4049
|
Formatting rules: - TABLE: Return one GitHub-flavored markdown table, one row per line,
|
|
4040
4050
|
never several rows joined on a single line.
|
|
4041
4051
|
- JSON: Return exactly one fenced \`\`\`json code block. - CHART: Return exactly one fenced \`\`\`json code block whose first line is
|
|
4042
4052
|
"// chart" and whose remaining body is valid ECharts option JSON.
|
|
4053
|
+
- SPREADSHEET: Return exactly one fenced \`\`\`csv code block whose first
|
|
4054
|
+
line is "# filename: <name>.csv", then a header row, then one row per
|
|
4055
|
+
line, comma-separated, numbers without thousands separators or units.
|
|
4043
4056
|
- FILE: Return exactly one fenced code block whose info string is a file
|
|
4044
|
-
extension, and whose first line is
|
|
4057
|
+
extension other than csv or tsv, and whose first line is
|
|
4058
|
+
"# filename: <name.ext>".
|
|
4059
|
+
- SHEET CHART: when asked to chart, plot or graph the spreadsheet already
|
|
4060
|
+
shown (the last SPREADSHEET answer), do not write a block: work on the
|
|
4061
|
+
grid with the Cells tools. Call cells_read_range with no range to find
|
|
4062
|
+
the data, then cells_insert_chart over that range (headers included) with
|
|
4063
|
+
the type and title asked for, at the first column two rows below the
|
|
4064
|
+
data (for data in A1:D13, at A15), unless told where. Answer in one short
|
|
4065
|
+
sentence naming the chart and its range. If the tools say no grid is
|
|
4066
|
+
shown, ask for the spreadsheet first.
|
|
4045
4067
|
|
|
4046
4068
|
If mode is ambiguous, default to JSON.`,
|
|
4047
4069
|
systemPromptCodemodeAddons: undefined,
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* DO NOT EDIT MANUALLY - run 'make specs' to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
import type { FrontendToolSpec } from '../types';
|
|
10
|
+
export declare const CELLS_FRONTEND_TOOL_SPEC_0_0_1: FrontendToolSpec;
|
|
10
11
|
export declare const DECKS_FRONTEND_TOOL_SPEC_0_0_1: FrontendToolSpec;
|
|
11
12
|
export declare const JUPYTER_NOTEBOOK_EDIT_FRONTEND_TOOL_SPEC_0_0_1: FrontendToolSpec;
|
|
12
13
|
export declare const JUPYTER_NOTEBOOK_PROPOSE_FRONTEND_TOOL_SPEC_0_0_1: FrontendToolSpec;
|
|
@@ -5,6 +5,23 @@
|
|
|
5
5
|
// ============================================================================
|
|
6
6
|
// Frontend Tool Definitions
|
|
7
7
|
// ============================================================================
|
|
8
|
+
export const CELLS_FRONTEND_TOOL_SPEC_0_0_1 = {
|
|
9
|
+
id: 'cells',
|
|
10
|
+
version: '0.0.1',
|
|
11
|
+
name: 'Cells',
|
|
12
|
+
description: "Read and write the spreadsheet on the person's screen, and chart it — the grid drawn by Datalayer Cells.",
|
|
13
|
+
tags: ['frontend', 'cells', 'spreadsheets'],
|
|
14
|
+
enabled: true,
|
|
15
|
+
toolset: [
|
|
16
|
+
'cells_read_range',
|
|
17
|
+
'cells_write_range',
|
|
18
|
+
'cells_insert_chart',
|
|
19
|
+
'cells_list_charts',
|
|
20
|
+
'cells_select_range',
|
|
21
|
+
],
|
|
22
|
+
icon: '@primer/octicons-react:table',
|
|
23
|
+
emoji: '🧮',
|
|
24
|
+
};
|
|
8
25
|
export const DECKS_FRONTEND_TOOL_SPEC_0_0_1 = {
|
|
9
26
|
id: 'decks',
|
|
10
27
|
version: '0.0.1',
|
|
@@ -101,6 +118,7 @@ export const LEXICAL_DOCUMENT_FRONTEND_TOOL_SPEC_0_0_1 = {
|
|
|
101
118
|
// Frontend Tool Catalog
|
|
102
119
|
// ============================================================================
|
|
103
120
|
export const FRONTEND_TOOL_CATALOG = {
|
|
121
|
+
cells: CELLS_FRONTEND_TOOL_SPEC_0_0_1,
|
|
104
122
|
decks: DECKS_FRONTEND_TOOL_SPEC_0_0_1,
|
|
105
123
|
'jupyter-notebook-edit': JUPYTER_NOTEBOOK_EDIT_FRONTEND_TOOL_SPEC_0_0_1,
|
|
106
124
|
'jupyter-notebook-propose': JUPYTER_NOTEBOOK_PROPOSE_FRONTEND_TOOL_SPEC_0_0_1,
|
package/lib/specs/mcpServers.js
CHANGED
|
@@ -44,16 +44,10 @@ export const DATALAYER_MCP_SERVER_0_0_1 = {
|
|
|
44
44
|
description: 'Read, edit and run Jupyter notebooks on Datalayer, with sandboxes and data',
|
|
45
45
|
icon: '@datalayer/icons-react:datalayer',
|
|
46
46
|
emoji: '🚀',
|
|
47
|
-
url: '',
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
'mcp-remote',
|
|
52
|
-
'https://mcp.datalayer.run/mcp',
|
|
53
|
-
'--header',
|
|
54
|
-
'Authorization: Bearer ${DATALAYER_API_KEY}',
|
|
55
|
-
],
|
|
56
|
-
transport: 'stdio',
|
|
47
|
+
url: 'https://mcp.datalayer.run/mcp',
|
|
48
|
+
args: [],
|
|
49
|
+
headers: { Authorization: 'Bearer ${DATALAYER_API_KEY}' },
|
|
50
|
+
transport: 'streamable-http',
|
|
57
51
|
enabled: false,
|
|
58
52
|
isAvailable: false,
|
|
59
53
|
tools: [],
|
|
@@ -66,16 +60,10 @@ export const EARTHDATA_MCP_SERVER_0_0_1 = {
|
|
|
66
60
|
description: 'Access NASA Earthdata search and metadata capabilities',
|
|
67
61
|
icon: '@datalayer/icons-react:globe-americas',
|
|
68
62
|
emoji: '🌍',
|
|
69
|
-
url: '',
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
'mcp-remote',
|
|
74
|
-
'https://mcp.datalayer.run/mcp?only=earthdata',
|
|
75
|
-
'--header',
|
|
76
|
-
'Authorization: Bearer ${DATALAYER_API_KEY}',
|
|
77
|
-
],
|
|
78
|
-
transport: 'stdio',
|
|
63
|
+
url: 'https://mcp.datalayer.run/mcp?only=earthdata',
|
|
64
|
+
args: [],
|
|
65
|
+
headers: { Authorization: 'Bearer ${DATALAYER_API_KEY}' },
|
|
66
|
+
transport: 'streamable-http',
|
|
79
67
|
enabled: true,
|
|
80
68
|
isAvailable: false,
|
|
81
69
|
tools: [],
|
|
@@ -165,16 +153,10 @@ export const HUGGINGFACE_MCP_SERVER_0_0_1 = {
|
|
|
165
153
|
description: 'Hugging Face models, datasets, spaces, and papers access',
|
|
166
154
|
icon: '@primer/octicons-react:hubot',
|
|
167
155
|
emoji: '🤗',
|
|
168
|
-
url: '',
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
'mcp-remote',
|
|
173
|
-
'https://huggingface.co/mcp',
|
|
174
|
-
'--header',
|
|
175
|
-
'Authorization: Bearer ${HF_TOKEN}',
|
|
176
|
-
],
|
|
177
|
-
transport: 'stdio',
|
|
156
|
+
url: 'https://huggingface.co/mcp',
|
|
157
|
+
args: [],
|
|
158
|
+
headers: { Authorization: 'Bearer ${HF_TOKEN}' },
|
|
159
|
+
transport: 'streamable-http',
|
|
178
160
|
enabled: false,
|
|
179
161
|
isAvailable: false,
|
|
180
162
|
tools: [],
|
|
@@ -187,16 +169,10 @@ export const KAGGLE_MCP_SERVER_0_0_1 = {
|
|
|
187
169
|
description: 'Kaggle datasets, models, competitions, and notebooks access',
|
|
188
170
|
icon: '@datalayer/icons-react:kaggle',
|
|
189
171
|
emoji: '🏆',
|
|
190
|
-
url: '',
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
'mcp-remote',
|
|
195
|
-
'https://www.kaggle.com/mcp',
|
|
196
|
-
'--header',
|
|
197
|
-
'Authorization: Bearer ${KAGGLE_API_TOKEN}',
|
|
198
|
-
],
|
|
199
|
-
transport: 'stdio',
|
|
172
|
+
url: 'https://www.kaggle.com/mcp',
|
|
173
|
+
args: [],
|
|
174
|
+
headers: { Authorization: 'Bearer ${KAGGLE_API_TOKEN}' },
|
|
175
|
+
transport: 'streamable-http',
|
|
200
176
|
enabled: false,
|
|
201
177
|
isAvailable: false,
|
|
202
178
|
tools: [],
|
|
@@ -209,16 +185,10 @@ export const ODOO_ACCOUNTING_MCP_SERVER_0_0_1 = {
|
|
|
209
185
|
description: "An accountant's day in Odoo — invoices, bills, journal entries, reconciliations, bank lines and tax returns — through the Datalayer MCP server",
|
|
210
186
|
icon: '@datalayer/icons-react:odoo',
|
|
211
187
|
emoji: '🧮',
|
|
212
|
-
url: '',
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
'mcp-remote',
|
|
217
|
-
'https://mcp.datalayer.run/mcp?only=odoo-accounting',
|
|
218
|
-
'--header',
|
|
219
|
-
'Authorization: Bearer ${DATALAYER_API_KEY}',
|
|
220
|
-
],
|
|
221
|
-
transport: 'stdio',
|
|
188
|
+
url: 'https://mcp.datalayer.run/mcp?only=odoo-accounting',
|
|
189
|
+
args: [],
|
|
190
|
+
headers: { Authorization: 'Bearer ${DATALAYER_API_KEY}' },
|
|
191
|
+
transport: 'streamable-http',
|
|
222
192
|
enabled: false,
|
|
223
193
|
isAvailable: false,
|
|
224
194
|
tools: [],
|
package/lib/types/mcp.d.ts
CHANGED
|
@@ -29,13 +29,15 @@ export interface MCPServer {
|
|
|
29
29
|
enabled: boolean;
|
|
30
30
|
/** List of available tools */
|
|
31
31
|
tools: MCPServerTool[];
|
|
32
|
-
/** Command to run
|
|
32
|
+
/** Command to run a local MCP server (e.g., 'npx', 'uvx'); a remote one names none and is reached at `url` */
|
|
33
33
|
command?: string;
|
|
34
34
|
/** Command arguments for the MCP server */
|
|
35
35
|
args: string[];
|
|
36
|
+
/** The headers a remote server is sent with every request, `${VAR}` expanded as it starts: the bearer among them */
|
|
37
|
+
headers?: Record<string, string>;
|
|
36
38
|
/** Whether the server is available (based on tool discovery) */
|
|
37
39
|
isAvailable: boolean;
|
|
38
|
-
/** Transport type: 'stdio', 'http', or 'streamable-http'
|
|
40
|
+
/** Transport type: 'stdio', 'http', or 'streamable-http' — a remote server reached at `url` with its `headers` when it has no `command`, a command run as a local HTTP process at `url` when it has one */
|
|
39
41
|
transport: 'stdio' | 'http' | 'streamable-http';
|
|
40
42
|
/** Environment variables required by this server (e.g., API keys) */
|
|
41
43
|
requiredEnvVars?: string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datalayer/agent-runtimes",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.90",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
".",
|
|
@@ -154,6 +154,7 @@
|
|
|
154
154
|
"@anthropic-ai/sdk": "^0.52.0",
|
|
155
155
|
"@datalayer/agent-teams": "^1.0.0",
|
|
156
156
|
"@datalayer/core": "^1.2.18",
|
|
157
|
+
"@datalayer/cells": "^1.0.0",
|
|
157
158
|
"@datalayer/decks": "^1.0.4",
|
|
158
159
|
"@datalayer/design": "^1.0.10",
|
|
159
160
|
"@datalayer/icons-react": "^1.0.16",
|