@datalayer/agent-runtimes 1.3.15 → 1.3.17
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/README.md +1 -1
- package/lib/chat/base/ChatBase.js +3 -2
- package/lib/config/AgentConfiguration.d.ts +1 -1
- package/lib/loop/apps/AppRenderer.d.ts +24 -0
- package/lib/loop/apps/AppRenderer.js +101 -0
- package/lib/loop/apps/appspec.d.ts +69 -0
- package/lib/loop/apps/appspec.js +566 -0
- package/lib/loop/apps/checks.d.ts +21 -0
- package/lib/loop/apps/checks.js +556 -0
- package/lib/loop/apps/index.d.ts +10 -0
- package/lib/loop/apps/index.js +14 -0
- package/lib/loop/apps/rules.d.ts +64 -0
- package/lib/loop/apps/rules.js +289 -0
- package/lib/loop/apps/yaml.d.ts +17 -0
- package/lib/loop/apps/yaml.js +185 -0
- package/lib/loop/embed/LoopEmbed.d.ts +6 -1
- package/lib/loop/embed/LoopEmbed.js +3 -2
- package/lib/loop/index.d.ts +1 -0
- package/lib/loop/index.js +3 -0
- package/lib/loop/plugins/chat/ChatView.js +9 -4
- package/lib/loop/plugins/chat/index.d.ts +10 -0
- package/lib/loop/plugins/chat/index.js +1 -0
- package/lib/loop/presets.d.ts +6 -0
- package/lib/loop/presets.js +2 -1
- package/lib/loop/shell/LoopWorkspace.d.ts +14 -0
- package/lib/loop/shell/LoopWorkspace.js +20 -6
- package/lib/loop/shell/index.d.ts +1 -1
- package/lib/loop/shell/index.js +1 -1
- package/lib/loop/shell/useWorkspaceFullScreen.d.ts +17 -4
- package/lib/loop/shell/useWorkspaceFullScreen.js +23 -6
- package/lib/specs/actions.d.ts +30 -0
- package/lib/specs/actions.js +616 -0
- package/lib/specs/agents/agents.d.ts +1 -0
- package/lib/specs/agents/agents.js +338 -284
- package/lib/specs/apps.d.ts +25 -0
- package/lib/specs/apps.js +1064 -0
- package/lib/specs/cogs.d.ts +19 -0
- package/lib/specs/cogs.js +736 -0
- package/lib/specs/events.d.ts +6 -1
- package/lib/specs/events.js +144 -1
- package/lib/specs/frames.d.ts +19 -0
- package/lib/specs/frames.js +444 -0
- package/lib/specs/gates.d.ts +22 -0
- package/lib/specs/gates.js +177 -0
- package/lib/specs/guards.d.ts +26 -0
- package/lib/specs/guards.js +930 -0
- package/lib/specs/index.d.ts +10 -0
- package/lib/specs/index.js +10 -0
- package/lib/specs/mcpServers.js +2 -2
- package/lib/specs/memory.js +4 -0
- package/lib/specs/modelProviders.d.ts +22 -0
- package/lib/specs/modelProviders.js +102 -0
- package/lib/specs/models.d.ts +31 -0
- package/lib/specs/models.js +215 -0
- package/lib/specs/ops.d.ts +15 -0
- package/lib/specs/ops.js +1272 -0
- package/lib/specs/outputs.js +2 -2
- package/lib/specs/skills.js +1 -1
- package/lib/specs/teams/teams.js +18 -18
- package/lib/specs/tracks.d.ts +15 -0
- package/lib/specs/tracks.js +87 -0
- package/lib/specs/uiPlugins.d.ts +16 -0
- package/lib/specs/uiPlugins.js +40 -0
- package/lib/types/agentspecs.d.ts +453 -2
- package/lib/types/memory.d.ts +2 -0
- package/lib/types/models.d.ts +52 -0
- package/package.json +2 -1
- package/scripts/check-cloudflare-models.py +122 -0
- package/scripts/codegen/agentspecs_clone.py +53 -0
- package/scripts/codegen/compose.py +65 -0
- package/scripts/codegen/generate_agents.py +14 -4
- package/scripts/codegen/generate_apps.py +454 -0
- package/scripts/codegen/generate_cogs.py +308 -0
- package/scripts/codegen/generate_frames.py +278 -0
- package/scripts/codegen/generate_memory.py +2 -0
- package/scripts/codegen/generate_model_providers.py +246 -0
- package/scripts/codegen/generate_models.py +135 -4
- package/scripts/codegen/generate_ops.py +388 -0
- package/scripts/codegen/generate_sandbox_agents.py +1 -1
- package/scripts/codegen/generate_ui_plugins.py +226 -0
- package/scripts/gen_workers.py +2 -2
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
~ BSD 3-Clause License
|
|
5
5
|
-->
|
|
6
6
|
|
|
7
|
-
[](https://datalayer.ai)
|
|
8
8
|
|
|
9
9
|
[](https://github.com/sponsors/datalayer)
|
|
10
10
|
|
|
@@ -31,7 +31,7 @@ import { useChatStore } from '../../stores/chatStore';
|
|
|
31
31
|
import { useConversationStore } from '../../stores/conversationStore';
|
|
32
32
|
import { generateMessageId, createUserMessage, createAssistantMessage, } from '../../types/messages';
|
|
33
33
|
import { AgentDetails } from '../../agents/AgentDetails';
|
|
34
|
-
import { AI_MODEL_CATALOGUE, DEFAULT_MODEL } from '../../specs/models';
|
|
34
|
+
import { AI_MODEL_CATALOGUE, DEFAULT_MODEL, isChatModel, } from '../../specs/models';
|
|
35
35
|
import { internalQueryClient, isToolCallMessage, convertHistoryToDisplayItems, createProtocolAdapter, getApiBaseFromConfig, sanitizeAssistantContent, } from '../../utils';
|
|
36
36
|
import { useConfig, useSkills, useSkillActions, useContextSnapshot, useSandbox, } from '../../hooks';
|
|
37
37
|
import { useAgentRuntimeWebSocket } from '../../hooks/useAgentRuntimes';
|
|
@@ -1397,7 +1397,8 @@ showToolApprovalBanner = true, pendingApprovals: pendingApprovalsProp, onApprove
|
|
|
1397
1397
|
* four are current.
|
|
1398
1398
|
*/
|
|
1399
1399
|
const catalogued = Object.values(AI_MODEL_CATALOGUE)
|
|
1400
|
-
|
|
1400
|
+
// A typed-judgment model answers typed questions, not a chat.
|
|
1401
|
+
.filter(model => model.available && isChatModel(model))
|
|
1401
1402
|
.map(model => ({
|
|
1402
1403
|
id: model.id,
|
|
1403
1404
|
name: model.name,
|
|
@@ -28,7 +28,7 @@ export interface LibraryAgentspec {
|
|
|
28
28
|
welcomeDocument?: string | null;
|
|
29
29
|
sandboxVariant?: string | null;
|
|
30
30
|
protocol?: string | null;
|
|
31
|
-
|
|
31
|
+
uiPlugin?: string | null;
|
|
32
32
|
trigger?: Record<string, unknown> | null;
|
|
33
33
|
modelConfig?: Record<string, unknown> | null;
|
|
34
34
|
mcpServerTools?: Array<Record<string, unknown>> | null;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ReactorPlugin } from '@datalayer/reactor';
|
|
2
|
+
import type { AppSpec } from '../../types/agentspecs';
|
|
3
|
+
import { type LoopEmbedProps } from '../embed/LoopEmbed';
|
|
4
|
+
/** The id of an agent or a Cog, without its version. */
|
|
5
|
+
export declare const agentIdOf: (app: Pick<AppSpec, "agent" | "team">) => string;
|
|
6
|
+
/**
|
|
7
|
+
* The plugin that makes a LOOP workspace run an application.
|
|
8
|
+
*
|
|
9
|
+
* The agent is created with the application's own document (`app_spec`) in
|
|
10
|
+
* its payload; a runtime that knows applications configures the agent from
|
|
11
|
+
* it, and one that does not creates the agent alone — the application is
|
|
12
|
+
* then shown and not enforced, which is why a hosted application only runs
|
|
13
|
+
* on a runtime that does.
|
|
14
|
+
*
|
|
15
|
+
* An application run by a team is not supported in the workspace yet: a team
|
|
16
|
+
* is not an agent spec, and is refused here rather than launched as one.
|
|
17
|
+
*/
|
|
18
|
+
export declare function defineAppPlugin(app: AppSpec): ReactorPlugin<Record<string, never>, unknown, unknown>;
|
|
19
|
+
export type AppRendererProps = Omit<LoopEmbedProps, 'agentId'> & {
|
|
20
|
+
/** The application to render. */
|
|
21
|
+
app: AppSpec;
|
|
22
|
+
};
|
|
23
|
+
export declare function AppRenderer({ app, plugins, ...embed }: AppRendererProps): React.JSX.Element;
|
|
24
|
+
export default AppRenderer;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
|
+
* Distributed under the terms of the Modified BSD License.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* An application, rendered: the LOOP workspace configured from an Appspec
|
|
8
|
+
* (LOOP R-01).
|
|
9
|
+
*
|
|
10
|
+
* One renderer for every place an application appears — the Studio's
|
|
11
|
+
* Preview, its hosted page, an embed, the home page — so that what a builder
|
|
12
|
+
* sees while building is what its users get. It is not a second shell: it is
|
|
13
|
+
* `LoopEmbed`, given
|
|
14
|
+
*
|
|
15
|
+
* - an **application plugin** (`defineAppPlugin`): the agent that answers,
|
|
16
|
+
* created with the application in its payload — so the runtime reaches only
|
|
17
|
+
* what the application connects to and enforces its rules before every tool
|
|
18
|
+
* call — and the application's starters as the openers of the empty chat;
|
|
19
|
+
* - the **layout of its kind**: a chat is the conversation alone, with the
|
|
20
|
+
* A2UI surfaces its answers draw; the other layouts keep the editors.
|
|
21
|
+
*
|
|
22
|
+
* @module loop/apps/AppRenderer
|
|
23
|
+
*/
|
|
24
|
+
import { useMemo } from 'react';
|
|
25
|
+
import { defineAgentCapacityPlugin } from '../plugins/agent-capacity';
|
|
26
|
+
import { LoopEmbed } from '../embed/LoopEmbed';
|
|
27
|
+
import { dumpAppspec } from './appspec';
|
|
28
|
+
/** The id of an agent or a Cog, without its version. */
|
|
29
|
+
export const agentIdOf = (app) => {
|
|
30
|
+
const reference = app.agent || app.team;
|
|
31
|
+
const at = reference.lastIndexOf(':');
|
|
32
|
+
return at > 0 && reference.slice(at + 1).includes('.')
|
|
33
|
+
? reference.slice(0, at)
|
|
34
|
+
: reference;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* The plugin that makes a LOOP workspace run an application.
|
|
38
|
+
*
|
|
39
|
+
* The agent is created with the application's own document (`app_spec`) in
|
|
40
|
+
* its payload; a runtime that knows applications configures the agent from
|
|
41
|
+
* it, and one that does not creates the agent alone — the application is
|
|
42
|
+
* then shown and not enforced, which is why a hosted application only runs
|
|
43
|
+
* on a runtime that does.
|
|
44
|
+
*
|
|
45
|
+
* An application run by a team is not supported in the workspace yet: a team
|
|
46
|
+
* is not an agent spec, and is refused here rather than launched as one.
|
|
47
|
+
*/
|
|
48
|
+
export function defineAppPlugin(app) {
|
|
49
|
+
if (!app.agent) {
|
|
50
|
+
throw new Error(`“${app.name}” is run by a team, which the workspace does not run as an application yet.`);
|
|
51
|
+
}
|
|
52
|
+
return defineAgentCapacityPlugin({
|
|
53
|
+
key: `app-${app.id}`,
|
|
54
|
+
displayName: app.name,
|
|
55
|
+
description: app.description || `The ${app.name} application`,
|
|
56
|
+
specId: agentIdOf(app),
|
|
57
|
+
emoji: app.emoji,
|
|
58
|
+
createPayload: {
|
|
59
|
+
name: app.id,
|
|
60
|
+
app_spec: dumpAppspec(app),
|
|
61
|
+
...(app.model ? { model: app.model } : {}),
|
|
62
|
+
},
|
|
63
|
+
suggestions: app.interface.starters.map(starter => ({
|
|
64
|
+
text: starter.label,
|
|
65
|
+
message: starter.message,
|
|
66
|
+
})),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* An application in a LOOP workspace: its agent, its starters, its layout.
|
|
71
|
+
*
|
|
72
|
+
* Every other prop is `LoopEmbed`'s, and wins over what the application
|
|
73
|
+
* implies — a host that wants the editors beside a chat still says so.
|
|
74
|
+
*/
|
|
75
|
+
/** No host plugins: one array, so that it never reads as a change. */
|
|
76
|
+
const NO_PLUGINS = [];
|
|
77
|
+
export function AppRenderer({ app, plugins = NO_PLUGINS, ...embed }) {
|
|
78
|
+
const chatOnly = app.interface.layout === 'chat';
|
|
79
|
+
/*
|
|
80
|
+
* The application plugin, made once per application. `LoopEmbed` rebuilds
|
|
81
|
+
* its whole reactor when its plugins change, so a new plugin on every
|
|
82
|
+
* render of the host would restart the running workspace. The key is the
|
|
83
|
+
* application as its file holds it: a change to it is a new application.
|
|
84
|
+
*/
|
|
85
|
+
const source = JSON.stringify(dumpAppspec(app));
|
|
86
|
+
const appPlugin = useMemo(() => (app.agent ? defineAppPlugin(app) : null),
|
|
87
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
88
|
+
[source]);
|
|
89
|
+
const allPlugins = useMemo(() => (appPlugin ? [appPlugin, ...plugins] : plugins), [appPlugin, plugins]);
|
|
90
|
+
if (!appPlugin) {
|
|
91
|
+
return (_jsxs("div", { role: "status", style: { padding: 16 }, children: ["\u201C", app.name, "\u201D is run by a team, which the workspace does not run as an application yet."] }));
|
|
92
|
+
}
|
|
93
|
+
return (_jsx(LoopEmbed
|
|
94
|
+
// The application's own agent: created under its id, so that its
|
|
95
|
+
// spec is applied to an agent of its own, never to the one it extends.
|
|
96
|
+
, {
|
|
97
|
+
// The application's own agent: created under its id, so that its
|
|
98
|
+
// spec is applied to an agent of its own, never to the one it extends.
|
|
99
|
+
agentId: app.id, editors: !chatOnly, showViewSelector: !chatOnly, teamPicker: false, showAgentVariants: false, graph: false, pluginsPanel: false, ...embed, plugins: allPlugins }));
|
|
100
|
+
}
|
|
101
|
+
export default AppRenderer;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Appspec as a file, and as the application an editor holds.
|
|
3
|
+
*
|
|
4
|
+
* An application is kept as a YAML or JSON document in the spec's own words —
|
|
5
|
+
* `applies_to`, `ready_at`, `keep_for` — with nothing written that is at its
|
|
6
|
+
* default. An editor works on the whole of it: an {@link AppSpec} with every
|
|
7
|
+
* field present, in TypeScript's spelling.
|
|
8
|
+
*
|
|
9
|
+
* {@link parseAppspec} reads the first into the second, and
|
|
10
|
+
* {@link dumpAppspec} writes it back: the same application always writes the
|
|
11
|
+
* same document, keys in one fixed order — the spec's own where it declares
|
|
12
|
+
* them, alphabetical where it does not (a scenario's weights, a component of
|
|
13
|
+
* a surface) — so that a difference between two versions shows what changed
|
|
14
|
+
* and nothing else. Reading what was written
|
|
15
|
+
* gives the application back, and writing what was read gives the document
|
|
16
|
+
* back — which is what lets three editors work on one file.
|
|
17
|
+
*
|
|
18
|
+
* Reading is tolerant, because a draft is not yet an application: what is
|
|
19
|
+
* missing takes its default, and what is wrong is reported beside the result
|
|
20
|
+
* rather than thrown. Whether the application can be used is decided by the
|
|
21
|
+
* spec's own validation, not here.
|
|
22
|
+
*
|
|
23
|
+
* Pure: nothing here calls a service or renders.
|
|
24
|
+
*
|
|
25
|
+
* @module loop/apps/appspec
|
|
26
|
+
*/
|
|
27
|
+
import type { AppAccent, AppKind, AppLayout, AppSpec } from '../../types/agentspecs';
|
|
28
|
+
/** The version of the spec itself. */
|
|
29
|
+
export declare const APP_SCHEMA = "loop.app/v1";
|
|
30
|
+
/** The face of an application that has not chosen one. */
|
|
31
|
+
export declare const DEFAULT_EMOJI = "\uD83D\uDC40";
|
|
32
|
+
export declare const APP_KINDS: AppKind[];
|
|
33
|
+
export declare const APP_ACCENTS: AppAccent[];
|
|
34
|
+
/** The layout a kind starts with. */
|
|
35
|
+
export declare const DEFAULT_LAYOUTS: Record<AppKind, AppLayout>;
|
|
36
|
+
/** What an application keeps of what it did, when it does not say. */
|
|
37
|
+
export declare const DEFAULT_RECORD_INCLUDE: string[];
|
|
38
|
+
type Data = Record<string, unknown>;
|
|
39
|
+
/** A retention as days: `90_days`, `18_months`, `1_years`; 0 when it cannot be read. */
|
|
40
|
+
export declare function retentionDays(keepFor: string): number;
|
|
41
|
+
/** An application with nothing said: what *Start blank* opens. */
|
|
42
|
+
export declare function emptyAppspec(kind?: AppKind): AppSpec;
|
|
43
|
+
/** What reading a document gives: the application, and what the document got wrong. */
|
|
44
|
+
export interface ParsedAppspec {
|
|
45
|
+
app: AppSpec;
|
|
46
|
+
/** In sentences; empty when the document reads as it was written. */
|
|
47
|
+
problems: string[];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* An application from a document in the spec's own words.
|
|
51
|
+
*
|
|
52
|
+
* Tolerant: what is missing takes its default, and what cannot be read is
|
|
53
|
+
* reported in `problems` — a key the spec does not know, a version of the
|
|
54
|
+
* spec this does not read, a kind that is not one. The application returned
|
|
55
|
+
* is always whole, so an editor can open it and show what is wrong.
|
|
56
|
+
*/
|
|
57
|
+
export declare function parseAppspec(document: unknown): ParsedAppspec;
|
|
58
|
+
/**
|
|
59
|
+
* An application as the document its file holds.
|
|
60
|
+
*
|
|
61
|
+
* The spec's own words, keys in one fixed order, nothing written that is at
|
|
62
|
+
* its default: the same application always writes the same document. What an
|
|
63
|
+
* application carries that is not the spec's — what it needs set up — is left
|
|
64
|
+
* out.
|
|
65
|
+
*/
|
|
66
|
+
export declare function dumpAppspec(app: AppSpec): Data;
|
|
67
|
+
/** The keys of a document in the order they are written. */
|
|
68
|
+
export declare const APPSPEC_KEY_ORDER: readonly string[];
|
|
69
|
+
export {};
|