@schlenkr/ragents 0.1.18 → 0.1.20
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/apps/server/src/host-api.json +6 -2
- package/apps/server/src/host-api.ts +3 -2
- package/apps/server/src/host-web.ts +3 -0
- package/apps/server/src/plugin-support/actor-programs/contract.ts +0 -3
- package/apps/server/src/plugin-support/removed-layout.ts +94 -0
- package/apps/server/src/ragents/engine.ts +2 -1
- package/apps/server/src/title-compactor.ts +5 -7
- package/apps/web/dist/assets/highlighted-body-KPVGNVTW-k67VKdbw.js +1 -0
- package/apps/web/dist/assets/main-CVjIz7BS.js +674 -0
- package/apps/web/dist/help/guide-clients.html +22 -42
- package/apps/web/dist/help/guide-clients.md +24 -45
- package/apps/web/dist/help/guide-functions.html +1 -1
- package/apps/web/dist/help/guide-functions.md +1 -1
- package/apps/web/dist/help/guide-getting-started.html +14 -22
- package/apps/web/dist/help/guide-getting-started.md +17 -24
- package/apps/web/dist/help/guide-ideas.html +1 -1
- package/apps/web/dist/help/guide-ideas.md +1 -1
- package/apps/web/dist/help/guide-plugins.html +1 -1
- package/apps/web/dist/help/guide-plugins.md +1 -1
- package/apps/web/dist/help/guide-programs.html +1 -1
- package/apps/web/dist/help/guide-programs.md +1 -1
- package/apps/web/dist/help/index.html +12 -79
- package/apps/web/dist/help/mini-app.css +8 -502
- package/apps/web/dist/host-web.json +28 -23
- package/apps/web/dist/index.html +2 -3
- package/apps/web/dist/run-panel.html +3 -4
- package/apps/web/src/Overview.tsx +4 -143
- package/apps/web/src/PluginChat.tsx +22 -116
- package/apps/web/src/PluginRegistry.tsx +4 -9
- package/apps/web/src/RunPreparationChat.tsx +4 -1
- package/apps/web/src/host-modules.ts +2 -0
- package/apps/web/src/main.tsx +23 -3
- package/apps/web/src/panel/RunLine.tsx +5 -2
- package/apps/web/src/panel/RunsPage.tsx +6 -6
- package/apps/web/src/panel/StartPage.tsx +6 -5
- package/apps/web/src/panel/contract.ts +3 -0
- package/apps/web/src/panel/page-props.ts +2 -0
- package/apps/web/src/run-apps.ts +34 -0
- package/apps/web/src/run-overview.ts +0 -27
- package/apps/web/src/run-panel/PanelContributions.tsx +41 -0
- package/apps/web/src/run-panel/RunPanelApp.tsx +172 -91
- package/apps/web/src/run-panel/RunPanelMenu.tsx +4 -3
- package/apps/web/src/run-panel/RunPanelWorkspace.tsx +8 -2
- package/apps/web/src/run-panel/clipboard.ts +17 -14
- package/apps/web/src/run-panel/host-contract.ts +8 -9
- package/apps/web/src/run-panel/host.ts +5 -31
- package/apps/web/src/run-panel/input-bridge.ts +15 -7
- package/bundles/ragents.activity/ragents-bundle.json +2 -2
- package/bundles/ragents.actor-programs/prompt.hbs +4 -5
- package/bundles/ragents.actor-programs/ragents-bundle.json +4 -14
- package/bundles/ragents.actor-programs/server/index.js +2 -14
- package/bundles/ragents.actor-programs/server/index.js.map +2 -2
- package/bundles/ragents.actor-programs/web/classes.json +1 -1
- package/bundles/ragents.actor-programs/web/index.js +1 -3
- package/bundles/ragents.actor-programs/web/index.js.map +4 -4
- package/bundles/ragents.ask/ragents-bundle.json +2 -2
- package/bundles/ragents.browser/ragents-bundle.json +2 -2
- package/bundles/ragents.documents/ragents-bundle.json +2 -2
- package/bundles/ragents.lsp-fsharp/ragents-bundle.json +2 -2
- package/bundles/ragents.lsp-roslyn/ragents-bundle.json +2 -2
- package/bundles/ragents.lsp-typescript/ragents-bundle.json +2 -2
- package/bundles/ragents.model-relay/ragents-bundle.json +2 -2
- package/bundles/ragents.orchestration/ragents-bundle.json +15 -41
- package/bundles/ragents.orchestration/server/index.js +10 -249
- package/bundles/ragents.orchestration/server/index.js.map +4 -4
- package/bundles/ragents.orchestration/web/chunks/chunk-KU7O6MEX.js +2 -0
- package/bundles/ragents.orchestration/web/chunks/chunk-KU7O6MEX.js.map +7 -0
- package/bundles/ragents.orchestration/web/classes.json +1 -1
- package/bundles/ragents.orchestration/web/exports/web/program-slot.js +1 -1
- package/bundles/ragents.orchestration/web/index.js +10 -18
- package/bundles/ragents.orchestration/web/index.js.map +4 -4
- package/bundles/ragents.overseer/ragents-bundle.json +3 -3
- package/bundles/ragents.overseer/server/index.js +0 -1
- package/bundles/ragents.overseer/server/index.js.map +2 -2
- package/bundles/ragents.processes/ragents-bundle.json +2 -2
- package/bundles/ragents.product/ragents-bundle.json +2 -2
- package/bundles/ragents.profile-distribution/ragents-bundle.json +2 -2
- package/bundles/ragents.reference/ragents-bundle.json +3 -3
- package/bundles/ragents.reference/run-scripts/balcony-wizard/RUN.md +1 -1
- package/bundles/ragents.reference/run-scripts/balcony-wizard/src/server.ts +1 -2
- package/bundles/ragents.reference/run-scripts/balcony-wizard/tests/program.test.ts +6 -7
- package/bundles/ragents.reference/run-scripts/conversation-circle/RUN.md +3 -3
- package/bundles/ragents.reference/run-scripts/conversation-circle/src/server.ts +3 -13
- package/bundles/ragents.reference/run-scripts/conversation-circle/tests/helpers.ts +1 -1
- package/bundles/ragents.reference/run-scripts/conversation-circle/tests/program.test.ts +1 -6
- package/bundles/ragents.reference/run-scripts/learning-afternoon/src/server.ts +1 -15
- package/bundles/ragents.reference/run-scripts/learning-afternoon/tests/program.test.ts +1 -1
- package/bundles/ragents.reference/run-scripts/moderated-round/tests/helpers.ts +1 -1
- package/bundles/ragents.reference/run-scripts/quick-note/RUN.md +1 -1
- package/bundles/ragents.reference/run-scripts/quick-note/src/server.ts +1 -2
- package/bundles/ragents.reference/run-scripts/quick-note/tests/program.test.ts +0 -2
- package/bundles/ragents.reference/run-scripts/run-roster/RUN.md +2 -2
- package/bundles/ragents.reference/run-scripts/run-roster/src/server.ts +1 -2
- package/bundles/ragents.reference/run-scripts/run-roster/tests/program.test.ts +0 -2
- package/bundles/ragents.reference/run-scripts/shared-actor-list/src/server.ts +1 -1
- package/bundles/ragents.reference/run-scripts/shared-actor-list/tests/helpers.ts +1 -1
- package/bundles/ragents.reference/run-scripts/word-game/src/contract.ts +1 -1
- package/bundles/ragents.reference/run-scripts/word-game/src/server.ts +0 -1
- package/bundles/ragents.reference/run-scripts/word-game/tests/program.test.ts +1 -2
- package/bundles/ragents.reference/skills/80-actor-text-analysis/SKILL.md +1 -1
- package/bundles/ragents.reference/skills/90-actor-notes/SKILL.md +1 -1
- package/bundles/ragents.todo/ragents-bundle.json +2 -2
- package/bundles/ragents.transcript/ragents-bundle.json +2 -2
- package/bundles/ragents.watch/ragents-bundle.json +2 -2
- package/bundles/ragents.workspace/ragents-bundle.json +2 -2
- package/package.json +8 -8
- package/packages/agent/dist/core/agent-settings.d.ts +1 -1
- package/packages/agent/src/core/agent-settings.ts +2 -2
- package/packages/ai/dist/types.d.ts +2 -1
- package/packages/ai/src/api/ai-sdk.ts +15 -2
- package/packages/ai/src/types.ts +2 -1
- package/packages/ragents/src/runtime/journal.ts +4 -0
- package/plugins/ragents.actor-programs/prompt.hbs +4 -5
- package/plugins/ragents.actor-programs/server/access-projections.ts +1 -1
- package/plugins/ragents.actor-programs/server/index.ts +0 -2
- package/plugins/ragents.actor-programs/server/runtime.ts +2 -10
- package/plugins/ragents.actor-programs/web/ActorViewFrame.tsx +5 -20
- package/plugins/ragents.actor-programs/web/AppsPanel.tsx +3 -79
- package/plugins/ragents.actor-programs/web/EmbeddedApps.tsx +0 -9
- package/plugins/ragents.actor-programs/web/api.ts +0 -20
- package/plugins/ragents.actor-programs/web/context.ts +0 -3
- package/plugins/ragents.actor-programs/web/index.tsx +0 -9
- package/plugins/ragents.orchestration/ragents-plugin.json +1 -2
- package/plugins/ragents.orchestration/server/index.ts +1 -11
- package/plugins/ragents.orchestration/web/ActorChat.tsx +1 -1
- package/plugins/ragents.orchestration/web/ActorChatControls.tsx +1 -1
- package/plugins/ragents.orchestration/web/FlowInspector.tsx +2 -4
- package/plugins/ragents.orchestration/web/InspectionPanel.tsx +21 -0
- package/plugins/ragents.orchestration/web/index.tsx +13 -9
- package/plugins/ragents.orchestration/web/program-slot.ts +0 -3
- package/plugins/ragents.orchestration/web/run-panel/AddresseeControl.tsx +15 -36
- package/plugins/ragents.orchestration/web/run-panel/RunPanel.tsx +76 -451
- package/plugins/ragents.orchestration/web/run-panel/run-panel-actors.ts +0 -27
- package/plugins/ragents.orchestration/web/run-panel/run-panel-state.ts +7 -40
- package/plugins/ragents.overseer/server/coordinator-prompt.ts +0 -1
- package/plugins/ragents.reference/examples.ts +1 -2
- package/plugins/ragents.reference/run-scripts/balcony-wizard/RUN.md +1 -1
- package/plugins/ragents.reference/run-scripts/balcony-wizard/src/server.ts +1 -2
- package/plugins/ragents.reference/run-scripts/balcony-wizard/tests/program.test.ts +6 -7
- package/plugins/ragents.reference/run-scripts/conversation-circle/RUN.md +3 -3
- package/plugins/ragents.reference/run-scripts/conversation-circle/src/server.ts +3 -13
- package/plugins/ragents.reference/run-scripts/conversation-circle/tests/helpers.ts +1 -1
- package/plugins/ragents.reference/run-scripts/conversation-circle/tests/program.test.ts +1 -6
- package/plugins/ragents.reference/run-scripts/learning-afternoon/src/server.ts +1 -15
- package/plugins/ragents.reference/run-scripts/learning-afternoon/tests/program.test.ts +1 -1
- package/plugins/ragents.reference/run-scripts/moderated-round/tests/helpers.ts +1 -1
- package/plugins/ragents.reference/run-scripts/quick-note/RUN.md +1 -1
- package/plugins/ragents.reference/run-scripts/quick-note/src/server.ts +1 -2
- package/plugins/ragents.reference/run-scripts/quick-note/tests/program.test.ts +0 -2
- package/plugins/ragents.reference/run-scripts/run-roster/RUN.md +2 -2
- package/plugins/ragents.reference/run-scripts/run-roster/src/server.ts +1 -2
- package/plugins/ragents.reference/run-scripts/run-roster/tests/program.test.ts +0 -2
- package/plugins/ragents.reference/run-scripts/shared-actor-list/src/server.ts +1 -1
- package/plugins/ragents.reference/run-scripts/shared-actor-list/tests/helpers.ts +1 -1
- package/plugins/ragents.reference/run-scripts/word-game/src/contract.ts +1 -1
- package/plugins/ragents.reference/run-scripts/word-game/src/server.ts +0 -1
- package/plugins/ragents.reference/run-scripts/word-game/tests/program.test.ts +1 -2
- package/plugins/ragents.reference/skills/80-actor-text-analysis/SKILL.md +1 -1
- package/plugins/ragents.reference/skills/90-actor-notes/SKILL.md +1 -1
- package/plugins/ragents.reference/walkthroughs.ts +13 -14
- package/apps/web/dist/assets/highlighted-body-KPVGNVTW-BwD4uYEe.js +0 -1
- package/apps/web/dist/assets/main-KBrc5Q77.js +0 -11
- package/apps/web/dist/assets/mermaid-HWGCJPDP-CSCkaArr.js +0 -608
- package/apps/web/dist/assets/runPanel-BjG5NBKm.js +0 -26
- package/apps/web/src/App.tsx +0 -318
- package/apps/web/src/SessionList.tsx +0 -157
- package/apps/web/src/SurfaceShortcuts.tsx +0 -60
- package/apps/web/src/WorkspacePanel.tsx +0 -309
- package/apps/web/src/run-panel.tsx +0 -52
- package/bundles/ragents.orchestration/server/chunks/chunk-QS3WJ3D7.js +0 -11
- package/bundles/ragents.orchestration/server/chunks/chunk-QS3WJ3D7.js.map +0 -7
- package/bundles/ragents.orchestration/server/exports/server/contract.js +0 -9
- package/bundles/ragents.orchestration/server/exports/server/contract.js.map +0 -7
- package/bundles/ragents.orchestration/surface.hbs +0 -39
- package/bundles/ragents.orchestration/web/chunks/chunk-CFMJD5ZI.js +0 -2
- package/bundles/ragents.orchestration/web/chunks/chunk-CFMJD5ZI.js.map +0 -7
- package/bundles/ragents.orchestration/web/chunks/chunk-HOBLI364.js +0 -2
- package/bundles/ragents.orchestration/web/chunks/chunk-HOBLI364.js.map +0 -7
- package/bundles/ragents.orchestration/web/chunks/chunk-UCIMT2R4.js +0 -2
- package/bundles/ragents.orchestration/web/chunks/chunk-UCIMT2R4.js.map +0 -7
- package/bundles/ragents.orchestration/web/chunks/chunk-XGPPQCZR.js +0 -2
- package/bundles/ragents.orchestration/web/chunks/chunk-XGPPQCZR.js.map +0 -7
- package/bundles/ragents.orchestration/web/exports/web/surface-entities.js +0 -2
- package/bundles/ragents.orchestration/web/exports/web/surface-entities.js.map +0 -7
- package/bundles/ragents.orchestration/web/exports/web/tile-docking.js +0 -2
- package/bundles/ragents.orchestration/web/exports/web/tile-docking.js.map +0 -7
- package/plugins/ragents.actor-programs/web/ExpandIcon.tsx +0 -5
- package/plugins/ragents.actor-programs/web/FullscreenHost.tsx +0 -31
- package/plugins/ragents.orchestration/contract.ts +0 -51
- package/plugins/ragents.orchestration/server/contract.ts +0 -14
- package/plugins/ragents.orchestration/server/surface-tool.ts +0 -198
- package/plugins/ragents.orchestration/surface.hbs +0 -39
- package/plugins/ragents.orchestration/tiled-layout.ts +0 -55
- package/plugins/ragents.orchestration/web/ActorChatPreview.tsx +0 -29
- package/plugins/ragents.orchestration/web/ActorShortcut.tsx +0 -74
- package/plugins/ragents.orchestration/web/ActorSurfaceControls.tsx +0 -130
- package/plugins/ragents.orchestration/web/ActorTile.tsx +0 -23
- package/plugins/ragents.orchestration/web/Center.tsx +0 -133
- package/plugins/ragents.orchestration/web/SurfaceTiles.tsx +0 -47
- package/plugins/ragents.orchestration/web/TiledSurface.tsx +0 -280
- package/plugins/ragents.orchestration/web/actor-header-settings.ts +0 -41
- package/plugins/ragents.orchestration/web/run-panel/RunPanelSettings.tsx +0 -50
- package/plugins/ragents.orchestration/web/run-panel/run-panel-settings.ts +0 -47
- package/plugins/ragents.orchestration/web/run-panel/sheet-status.ts +0 -30
- package/plugins/ragents.orchestration/web/surface-entities.ts +0 -21
- package/plugins/ragents.orchestration/web/surface-view-settings.ts +0 -42
- package/plugins/ragents.orchestration/web/tile-docking.ts +0 -105
- package/plugins/ragents.orchestration/web/tiled-view-settings.ts +0 -74
- /package/apps/web/dist/assets/{mermaid-HWGCJPDP-BPn4aV2r.css → main-BPn4aV2r.css} +0 -0
|
@@ -3,16 +3,11 @@ import test from "node:test";
|
|
|
3
3
|
import program from "../src/server.ts";
|
|
4
4
|
import { setupContext, startInput } from "./helpers.ts";
|
|
5
5
|
|
|
6
|
-
test("topic and number of rounds control participants
|
|
6
|
+
test("topic and number of rounds control participants and task", async () => {
|
|
7
7
|
const { calls, context } = setupContext();
|
|
8
8
|
await program.onInput!(startInput({ topic: "Team breakfast", rounds: 3 }), context);
|
|
9
9
|
assert.deepEqual(calls.filter((call) => call.name === "agent_spawn").map((call) => (call.input as { handle: string }).handle), ["mira", "jon", "ada"]);
|
|
10
10
|
assert.deepEqual(calls.find((call) => call.name === "run_configure")?.input, { title: "Conversation circle: Team breakfast" });
|
|
11
|
-
const layout = calls.find((call) => call.name === "canvas_layout_replace")?.input as { root: unknown };
|
|
12
|
-
assert.deepEqual(layout.root, { direction: "vertical", weights: [1, 1], children: [
|
|
13
|
-
{ entity: "@mira" },
|
|
14
|
-
{ direction: "horizontal", weights: [1, 1], children: [{ entity: "@jon" }, { entity: "@ada" }] },
|
|
15
|
-
] });
|
|
16
11
|
assert.match(JSON.stringify(calls.at(-1)), /exactly 3 conversation rounds/);
|
|
17
12
|
assert.deepEqual(context.state.read(), { built: true });
|
|
18
13
|
const completedCalls = calls.length;
|
|
@@ -32,19 +32,12 @@ const contract = {
|
|
|
32
32
|
capabilities: ["actor_input"],
|
|
33
33
|
},
|
|
34
34
|
},
|
|
35
|
-
input: { capabilities: ["model_list", "agent_spawn", "
|
|
35
|
+
input: { capabilities: ["model_list", "agent_spawn", "run_configure", "actor_input", "event_subscribe", "event_unsubscribe", "event_query"] },
|
|
36
36
|
} as const;
|
|
37
37
|
|
|
38
38
|
const startMarker = "START_LEARNING_AFTERNOON";
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
type Tile = { entity: string } | { direction: "vertical"; weights: [number, number]; children: [Tile, Tile] };
|
|
42
|
-
|
|
43
|
-
function stackedTiles(entities: string[]): Tile {
|
|
44
|
-
const [first, ...rest] = entities;
|
|
45
|
-
return rest.length === 0 ? { entity: first! } : { direction: "vertical", weights: [1, rest.length], children: [{ entity: first! }, stackedTiles(rest)] };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
41
|
function boardWith(helpers: HelperState[]): LearningState {
|
|
49
42
|
const working = helpers.some((helper) => helper.status === "working");
|
|
50
43
|
return { phase: working ? "working" : helpers.some((helper) => helper.status === "error") ? "error" : "complete", helpers };
|
|
@@ -72,13 +65,6 @@ export default defineActor(contract, {
|
|
|
72
65
|
const actor = await context.functions.agent_spawn({ handle: `learning-${helper.id}`, displayName: helper.label, profile: profile.name, prompt, tools: [] });
|
|
73
66
|
return { ...helper, actorId: actor.id };
|
|
74
67
|
}));
|
|
75
|
-
await context.functions.canvas_layout_replace({
|
|
76
|
-
root: {
|
|
77
|
-
direction: "horizontal",
|
|
78
|
-
weights: [1, 1],
|
|
79
|
-
children: [{ entity: `app:@${context.actor.handle}/main` }, stackedTiles(helpers.map((helper) => `@learning-${helper.id}`))],
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
68
|
await context.functions.run_configure({ title: learningWorkflow.title, primaryActor: `@${context.actor.handle}` });
|
|
83
69
|
context.state.replace({ board: { phase: "ready", helpers } });
|
|
84
70
|
return;
|
|
@@ -19,7 +19,7 @@ function setup(options: { missingProfile?: boolean; failDispatch?: string; befor
|
|
|
19
19
|
const calls: { name: string; input: unknown }[] = [];
|
|
20
20
|
const history: CapabilityContracts["event_query"]["output"] = [];
|
|
21
21
|
const functions = Object.fromEntries([
|
|
22
|
-
"model_list", "agent_spawn", "
|
|
22
|
+
"model_list", "agent_spawn", "run_configure", "actor_input", "event_subscribe", "event_unsubscribe", "event_query",
|
|
23
23
|
].map((name) => [name, async (input: unknown) => {
|
|
24
24
|
calls.push({ name, input });
|
|
25
25
|
if (name === "model_list") return { profiles: options.missingProfile ? [] : [{ name: "standard", driver: "agent", description: "Test profile", turnTimeoutMs: null, isolateWorkspace: false, provider: "test", model: "test" }], models: [] };
|
|
@@ -2,7 +2,7 @@ import { createTestContext } from "@ragents/server/testing";
|
|
|
2
2
|
|
|
3
3
|
export const setupContext = (profiles = [{ name: "coordinator", driver: "agent" }, { name: "standard", driver: "agent" }]) => {
|
|
4
4
|
const calls: { name: string; input: unknown }[] = [];
|
|
5
|
-
const functions = Object.fromEntries(["model_list", "agent_spawn", "run_configure", "actor_input", "
|
|
5
|
+
const functions = Object.fromEntries(["model_list", "agent_spawn", "run_configure", "actor_input", "actor_program_activate"].map((name) => [name, (input: unknown) => {
|
|
6
6
|
calls.push({ name, input });
|
|
7
7
|
if (name === "agent_spawn") {
|
|
8
8
|
const handle = (input as { handle: string }).handle;
|
|
@@ -10,5 +10,5 @@ tags: Run scripts, Concept demo, TypeScript actors
|
|
|
10
10
|
|
|
11
11
|
The start value `{ "text": "..." }` is the note; without one, the script notes when it was
|
|
12
12
|
started. The script makes the shared notebook active with `actor_program_ensure`, sends it the
|
|
13
|
-
note
|
|
13
|
+
note and ends the start with
|
|
14
14
|
`context.finish`. Whether the roster check or this script comes first, the run has one notebook.
|
|
@@ -4,7 +4,7 @@ import { Type } from "typebox";
|
|
|
4
4
|
const contract = {
|
|
5
5
|
state: Type.Object({}, { additionalProperties: false }),
|
|
6
6
|
functions: {},
|
|
7
|
-
input: { capabilities: ["actor_program_ensure", "actor_input",
|
|
7
|
+
input: { capabilities: ["actor_program_ensure", "actor_input", ] },
|
|
8
8
|
} as const;
|
|
9
9
|
|
|
10
10
|
const noteOf = (input: unknown, now: string): string => {
|
|
@@ -23,7 +23,6 @@ export default defineActor(contract, {
|
|
|
23
23
|
const note = noteOf(start.input, context.std.now());
|
|
24
24
|
const notebook = await context.functions.actor_program_ensure({ name: "notebook" });
|
|
25
25
|
await context.functions.actor_input({ actor: `@${notebook.handle}`, content: note });
|
|
26
|
-
await context.functions.canvas_layout_place({ entity: "app:notebook/main" });
|
|
27
26
|
context.finish({ note, notebook: notebook.status }, { summary: `Noted: ${note}` });
|
|
28
27
|
},
|
|
29
28
|
});
|
|
@@ -11,7 +11,6 @@ const note = (status: "active" | "installed" = "installed") => {
|
|
|
11
11
|
const context = createTestContext<Record<string, never>>({ state: {}, functions: {
|
|
12
12
|
actor_program_ensure: record("actor_program_ensure", { actorId: "id-notebook", handle: "notebook", status }),
|
|
13
13
|
actor_input: record("actor_input", []),
|
|
14
|
-
canvas_layout_place: record("canvas_layout_place", { placed: status === "installed" }),
|
|
15
14
|
} });
|
|
16
15
|
return { calls, context };
|
|
17
16
|
};
|
|
@@ -22,7 +21,6 @@ test("sends the note to the shared notebook and reports it", async () => {
|
|
|
22
21
|
assert.deepEqual(calls.map((call) => [call.name, call.input]), [
|
|
23
22
|
["actor_program_ensure", { name: "notebook" }],
|
|
24
23
|
["actor_input", { actor: "@notebook", content: "Ask about the budget" }],
|
|
25
|
-
["canvas_layout_place", { entity: "app:notebook/main" }],
|
|
26
24
|
]);
|
|
27
25
|
assert.deepEqual(context.finished, [{ result: { note: "Ask about the budget", notebook: "installed" }, summary: "Noted: Ask about the budget" }]);
|
|
28
26
|
});
|
|
@@ -11,9 +11,9 @@ tags: Run scripts, Concept demo, TypeScript actors
|
|
|
11
11
|
The TypeScript program reads the participants with `actor_list` and ends each start with
|
|
12
12
|
`context.finish`. The owner reads the summary in the chat; a coordinator that starts it through
|
|
13
13
|
`run_script_start` receives summary and list as a message. Started inside a running run through the
|
|
14
|
-
run menu, `ragents script`, or the coordinator, it
|
|
14
|
+
run menu, `ragents script`, or the coordinator, it preserves the primary actor,
|
|
15
15
|
and a repeated start reuses the same actor. Started as a new run, it is the run's only participant.
|
|
16
16
|
|
|
17
17
|
It shares the notebook with the quick note script: `shared-programs: notebook` copies the plugin's
|
|
18
18
|
shared package into the run, `actor_program_ensure` makes it active once, and
|
|
19
|
-
|
|
19
|
+
Its visible view enters the app catalog automatically.
|
|
@@ -4,7 +4,7 @@ import { Type } from "typebox";
|
|
|
4
4
|
const contract = {
|
|
5
5
|
state: Type.Object({ reports: Type.Optional(Type.Number()) }, { additionalProperties: false }),
|
|
6
6
|
functions: {},
|
|
7
|
-
input: { capabilities: ["actor_list", "actor_program_ensure", "actor_input",
|
|
7
|
+
input: { capabilities: ["actor_list", "actor_program_ensure", "actor_input", ] },
|
|
8
8
|
} as const;
|
|
9
9
|
|
|
10
10
|
export default defineActor(contract, {
|
|
@@ -19,7 +19,6 @@ export default defineActor(contract, {
|
|
|
19
19
|
const summary = handles.length === 0 ? "No other participants yet." : `${handles.length} participant${handles.length === 1 ? "" : "s"}: ${handles.join(", ")}.`;
|
|
20
20
|
const notebook = await context.functions.actor_program_ensure({ name: "notebook" });
|
|
21
21
|
await context.functions.actor_input({ actor: `@${notebook.handle}`, content: `Roster: ${summary}` });
|
|
22
|
-
await context.functions.canvas_layout_place({ entity: "app:notebook/main" });
|
|
23
22
|
context.state.replace({ reports: (context.state.read().reports ?? 0) + 1 });
|
|
24
23
|
context.finish({ actors: others.map(({ handle, kind, lifecycle }) => ({ handle, kind, lifecycle })) }, { summary });
|
|
25
24
|
},
|
|
@@ -14,7 +14,6 @@ const roster = (actors: ReturnType<typeof actor>[], state: { reports?: number }
|
|
|
14
14
|
actor_list: record("actor_list", actors),
|
|
15
15
|
actor_program_ensure: record("actor_program_ensure", { actorId: "id-notebook", handle: "notebook", status: "active" as const }),
|
|
16
16
|
actor_input: record("actor_input", []),
|
|
17
|
-
canvas_layout_place: record("canvas_layout_place", { placed: true }),
|
|
18
17
|
} });
|
|
19
18
|
return { calls, context };
|
|
20
19
|
};
|
|
@@ -29,7 +28,6 @@ test("reports the other participants as result and summary and notes them in the
|
|
|
29
28
|
assert.deepEqual(calls.slice(1).map((call) => [call.name, call.input]), [
|
|
30
29
|
["actor_program_ensure", { name: "notebook" }],
|
|
31
30
|
["actor_input", { actor: "@notebook", content: "Roster: 2 participants: @coordinator, @helper." }],
|
|
32
|
-
["canvas_layout_place", { entity: "app:notebook/main" }],
|
|
33
31
|
]);
|
|
34
32
|
assert.deepEqual(context.state.read(), { reports: 1 });
|
|
35
33
|
});
|
|
@@ -56,7 +56,7 @@ export default defineActor(contract, {
|
|
|
56
56
|
await context.functions.actor_input({
|
|
57
57
|
actor: "@coordinator",
|
|
58
58
|
content: `The shared collection is called ${JSON.stringify(title)}. The run script has bound the program shared-list to @${helper.handle}. Its view is visible on the surface; the helper is currently adding the first entry with append_to_list. `
|
|
59
|
-
+ "
|
|
59
|
+
+ "Use the addressee selector to inspect its owner with chat and details. Open the mini-app from the app catalog. "
|
|
60
60
|
+ "Explain to the user in three sentences how to use the visible list, how to open the helper, and that the view and the function share the same list state.",
|
|
61
61
|
});
|
|
62
62
|
|
|
@@ -2,7 +2,7 @@ import { createTestContext } from "@ragents/server/testing";
|
|
|
2
2
|
|
|
3
3
|
export const setupContext = (profiles = [{ name: "coordinator", driver: "agent" }, { name: "standard", driver: "agent" }], suffix = "") => {
|
|
4
4
|
const calls: { name: string; input: unknown }[] = [];
|
|
5
|
-
const functions = Object.fromEntries(["model_list", "agent_spawn", "run_configure", "actor_input", "
|
|
5
|
+
const functions = Object.fromEntries(["model_list", "agent_spawn", "run_configure", "actor_input", "actor_program_activate"].map((name) => [name, (input: unknown) => {
|
|
6
6
|
calls.push({ name, input });
|
|
7
7
|
if (name === "agent_spawn") {
|
|
8
8
|
const handle = (input as { handle: string }).handle + suffix;
|
|
@@ -19,5 +19,5 @@ export const contract = {
|
|
|
19
19
|
capabilities: ["actor_input"],
|
|
20
20
|
},
|
|
21
21
|
},
|
|
22
|
-
input: { capabilities: ["model_list", "agent_spawn", "
|
|
22
|
+
input: { capabilities: ["model_list", "agent_spawn", "run_configure", "event_subscribe", "event_query", "actor_input"] },
|
|
23
23
|
} as const;
|
|
@@ -37,7 +37,6 @@ export default defineActor(contract, {
|
|
|
37
37
|
try {
|
|
38
38
|
if (!state.status) {
|
|
39
39
|
await context.functions.run_configure({ title: "Word game", primaryActor: context.actor.id });
|
|
40
|
-
await context.functions.canvas_layout_replace({ root: { entity: `app:@${context.actor.handle}/main` } });
|
|
41
40
|
const start = payloadOf(JSON.parse(input.content));
|
|
42
41
|
if (start.input !== null || !start.options || typeof start.options !== "object" || Array.isArray(start.options)
|
|
43
42
|
|| Object.keys(start).some((key) => key !== "input" && key !== "options")) {
|
|
@@ -26,7 +26,6 @@ function fixture(initialState: WordGameState = {}) {
|
|
|
26
26
|
return { id: `actor-${input.handle}`, handle: input.handle };
|
|
27
27
|
},
|
|
28
28
|
run_configure: async (input) => { calls.push({ name: "run_configure", input }); return null; },
|
|
29
|
-
canvas_layout_replace: async (input) => { calls.push({ name: "canvas_layout_replace", input }); return null; },
|
|
30
29
|
event_subscribe: async (input) => {
|
|
31
30
|
calls.push({ name: "event_subscribe", input });
|
|
32
31
|
return { subscriptionId: "subscription", sources: input.sourceActorIds ?? null };
|
|
@@ -190,7 +189,7 @@ test("a missing standard profile shows an error without creating participants",
|
|
|
190
189
|
await program.onInput(firstInput, context);
|
|
191
190
|
assert.equal(context.state.read().status, "error");
|
|
192
191
|
assert.match(context.state.read().error!, /role standard is missing/);
|
|
193
|
-
assert.deepEqual(calls.map((call) => call.name), ["run_configure", "
|
|
192
|
+
assert.deepEqual(calls.map((call) => call.name), ["run_configure", "model_list"]);
|
|
194
193
|
});
|
|
195
194
|
|
|
196
195
|
test("a restored state keeps counting the pending task and rebuilds nothing", async () => {
|
|
@@ -6,7 +6,7 @@ title: "Count characters, words, and lines"
|
|
|
6
6
|
description: "Shows how the chat and a mini-app use the same TypeScript function and the same call counter. Hiding keeps the actor state."
|
|
7
7
|
category: "Mini-apps"
|
|
8
8
|
order: 10
|
|
9
|
-
tags: "Use case, Concept demo, TypeScript actors, Actor functions, Actor state, Mini-apps,
|
|
9
|
+
tags: "Use case, Concept demo, TypeScript actors, Actor functions, Actor state, Mini-apps, View visibility"
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
I would like a text analysis with a text field, a count button, and understandable errors. A TypeScript actor counts characters, words, lines, and its calls without AI. Check "The world is big." and "And beautiful." as two lines: 6 words. The interface shows the same call counter. Hide it and show it again; the state is kept. Use shared layout and form building blocks: input and result side by side, stacked when space is tight.
|
|
@@ -6,7 +6,7 @@ title: "Hide notes and find them again"
|
|
|
6
6
|
description: "Shows an automatically placed mini-app with note selection. When hiding and showing it again, the actor and notes are kept."
|
|
7
7
|
category: "Mini-apps"
|
|
8
8
|
order: 90
|
|
9
|
-
tags: "Use case, Concept demo, TypeScript actors, Actor functions, Actor state, Mini-apps,
|
|
9
|
+
tags: "Use case, Concept demo, TypeScript actors, Actor functions, Actor state, Mini-apps, View visibility"
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
I would like a TypeScript actor for my notes. Its interface with input and counter should appear on the surface by itself: a searchable list of titles on the left, the selected note on the right. Add a first note through its function. Hide the interface briefly and show it again without deleting the actor or resetting notes. Leave it open for entering my next idea.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": 5,
|
|
3
3
|
"id": "ragents.todo",
|
|
4
|
-
"api":
|
|
4
|
+
"api": 10,
|
|
5
5
|
"hostNames": {
|
|
6
6
|
"server": {
|
|
7
7
|
"@ragents/engine": [
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
"revision": "5e18b249f3c8b53b61820ef05da59823d58163c6962e6d836dcb37c05034aad0",
|
|
36
|
-
"sourceRevision": "
|
|
36
|
+
"sourceRevision": "c889b621703da3c59cc7865f53d9f36dd4351d9e0f942d0b2808f38204133d2b",
|
|
37
37
|
"server": "server/index.js",
|
|
38
38
|
"web": {
|
|
39
39
|
"entry": "web/index.js",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": 5,
|
|
3
3
|
"id": "ragents.transcript",
|
|
4
|
-
"api":
|
|
4
|
+
"api": 10,
|
|
5
5
|
"hostNames": {
|
|
6
6
|
"server": {
|
|
7
7
|
"@ragents/engine": [
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"web": {}
|
|
24
24
|
},
|
|
25
25
|
"revision": "e3bb513053f6385f9d78d314d28302324095a5163c4e1563df6fc8b3251305f7",
|
|
26
|
-
"sourceRevision": "
|
|
26
|
+
"sourceRevision": "1afb89ce9536b65df330262bcd433740dc9751302927c6980e36586e613f5982",
|
|
27
27
|
"server": "server/index.js",
|
|
28
28
|
"exports": {
|
|
29
29
|
"server": {},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": 5,
|
|
3
3
|
"id": "ragents.watch",
|
|
4
|
-
"api":
|
|
4
|
+
"api": 10,
|
|
5
5
|
"hostNames": {
|
|
6
6
|
"server": {
|
|
7
7
|
"@ragents/engine": [
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"web": {}
|
|
26
26
|
},
|
|
27
27
|
"revision": "007ee50ab186e3070930f23e9795210fa36c723365657325d5440cc2f0b81d60",
|
|
28
|
-
"sourceRevision": "
|
|
28
|
+
"sourceRevision": "ab44c0018a79f489b654dc8c5590dfe53404a2b0d5343a4b35a67704a00ac944",
|
|
29
29
|
"server": "server/index.js",
|
|
30
30
|
"exports": {
|
|
31
31
|
"server": {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": 5,
|
|
3
3
|
"id": "ragents.workspace",
|
|
4
|
-
"api":
|
|
4
|
+
"api": 10,
|
|
5
5
|
"hostNames": {
|
|
6
6
|
"server": {
|
|
7
7
|
"@ragents/engine": [
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
}
|
|
138
138
|
},
|
|
139
139
|
"revision": "db9370b7b3449c44be49986b074806351b857c430963aa878e209d2d5c9ba4f8",
|
|
140
|
-
"sourceRevision": "
|
|
140
|
+
"sourceRevision": "fe0162a7be0847872f9dfea32816ad843897e4fcace4b176d23998a6e6f1c5b4",
|
|
141
141
|
"server": "server/index.js",
|
|
142
142
|
"web": {
|
|
143
143
|
"entry": "web/index.js",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schlenkr/ragents",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20",
|
|
4
4
|
"description": "RAgents host: server, engine, plugins and tools without a source checkout",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
@@ -71,14 +71,14 @@
|
|
|
71
71
|
"yaml": "2.9.0"
|
|
72
72
|
},
|
|
73
73
|
"optionalDependencies": {
|
|
74
|
-
"@schlenkr/ragents-tools-win32-x64": "0.1.
|
|
75
|
-
"@schlenkr/ragents-tools-win32-arm64": "0.1.
|
|
76
|
-
"@schlenkr/ragents-tools-darwin-x64": "0.1.
|
|
77
|
-
"@schlenkr/ragents-tools-darwin-arm64": "0.1.
|
|
78
|
-
"@schlenkr/ragents-tools-linux-x64": "0.1.
|
|
79
|
-
"@schlenkr/ragents-tools-linux-arm64": "0.1.
|
|
74
|
+
"@schlenkr/ragents-tools-win32-x64": "0.1.20",
|
|
75
|
+
"@schlenkr/ragents-tools-win32-arm64": "0.1.20",
|
|
76
|
+
"@schlenkr/ragents-tools-darwin-x64": "0.1.20",
|
|
77
|
+
"@schlenkr/ragents-tools-darwin-arm64": "0.1.20",
|
|
78
|
+
"@schlenkr/ragents-tools-linux-x64": "0.1.20",
|
|
79
|
+
"@schlenkr/ragents-tools-linux-arm64": "0.1.20"
|
|
80
80
|
},
|
|
81
81
|
"ragents": {
|
|
82
|
-
"hostVersion": "
|
|
82
|
+
"hostVersion": "e96d4691028bddeaecd76daca53e664da8bcd1d0"
|
|
83
83
|
}
|
|
84
84
|
}
|
|
@@ -6,7 +6,7 @@ export interface AgentSettings {
|
|
|
6
6
|
maxRetries: number;
|
|
7
7
|
baseDelayMs: number;
|
|
8
8
|
};
|
|
9
|
-
/**
|
|
9
|
+
/** Idle timeout (time without any received chunk) and retries of a single provider request; unset values leave the SDK defaults. */
|
|
10
10
|
providerRequest: {
|
|
11
11
|
timeoutMs: number;
|
|
12
12
|
maxRetries?: number;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export interface AgentSettings {
|
|
3
3
|
/** Retries after a retryable model error, with exponential backoff. */
|
|
4
4
|
retry: { enabled: boolean; maxRetries: number; baseDelayMs: number };
|
|
5
|
-
/**
|
|
5
|
+
/** Idle timeout (time without any received chunk) and retries of a single provider request; unset values leave the SDK defaults. */
|
|
6
6
|
providerRequest: { timeoutMs: number; maxRetries?: number; maxRetryDelayMs: number };
|
|
7
7
|
}
|
|
8
8
|
|
|
@@ -13,5 +13,5 @@ export interface AgentSettingsInput {
|
|
|
13
13
|
|
|
14
14
|
export const agentSettings = (input: AgentSettingsInput = {}): AgentSettings => ({
|
|
15
15
|
retry: { enabled: true, maxRetries: 3, baseDelayMs: 2000, ...input.retry },
|
|
16
|
-
providerRequest: { timeoutMs:
|
|
16
|
+
providerRequest: { timeoutMs: 600_000, maxRetryDelayMs: 60_000, ...input.providerRequest },
|
|
17
17
|
});
|
|
@@ -71,7 +71,8 @@ export interface StreamOptions {
|
|
|
71
71
|
*/
|
|
72
72
|
headers?: ProviderHeaders;
|
|
73
73
|
/**
|
|
74
|
-
*
|
|
74
|
+
* Timeout in milliseconds for providers/SDKs that support it. The openai-completions
|
|
75
|
+
* stream counts it as idle time: any received chunk restarts it, so an active stream never expires.
|
|
75
76
|
* For example, OpenAI and Anthropic SDK clients default to 10 minutes.
|
|
76
77
|
*/
|
|
77
78
|
timeoutMs?: number;
|
|
@@ -33,6 +33,16 @@ async function runStream(model: Model<"openai-completions">, context: Context, o
|
|
|
33
33
|
};
|
|
34
34
|
const controller = new AbortController();
|
|
35
35
|
const signal = options?.signal ? AbortSignal.any([options.signal, controller.signal]) : controller.signal;
|
|
36
|
+
let idleTimer: ReturnType<typeof setTimeout> | undefined;
|
|
37
|
+
let idleExpired = false;
|
|
38
|
+
const restartIdleTimer = () => {
|
|
39
|
+
clearTimeout(idleTimer);
|
|
40
|
+
if (options?.timeoutMs === undefined) return;
|
|
41
|
+
idleTimer = setTimeout(() => {
|
|
42
|
+
idleExpired = true;
|
|
43
|
+
controller.abort();
|
|
44
|
+
}, options.timeoutMs);
|
|
45
|
+
};
|
|
36
46
|
try {
|
|
37
47
|
const retention = options?.cacheRetention ?? (getProviderEnvValue("AGENT_CACHE_RETENTION", options?.env) === "long" ? "long" : "short");
|
|
38
48
|
const cacheControl = retention !== "none" && (model.compat?.cacheControlFormat === "anthropic" || model.id.startsWith("anthropic/"))
|
|
@@ -67,7 +77,6 @@ async function runStream(model: Model<"openai-completions">, context: Context, o
|
|
|
67
77
|
maxRetries: options?.maxRetries ?? 0,
|
|
68
78
|
streamRetries: 0,
|
|
69
79
|
abortSignal: signal,
|
|
70
|
-
timeout: options?.timeoutMs,
|
|
71
80
|
stopWhen: stepCountIs(1),
|
|
72
81
|
includeRawChunks: true,
|
|
73
82
|
onError: () => {},
|
|
@@ -83,7 +92,9 @@ async function runStream(model: Model<"openai-completions">, context: Context, o
|
|
|
83
92
|
let rawThinkingIndex: number | undefined;
|
|
84
93
|
let hasFinishReason = false;
|
|
85
94
|
let finished = false;
|
|
95
|
+
restartIdleTimer();
|
|
86
96
|
for await (const part of result.fullStream) {
|
|
97
|
+
restartIdleTimer();
|
|
87
98
|
switch (part.type) {
|
|
88
99
|
case "raw": {
|
|
89
100
|
const chunk = part.rawValue as { id?: string; model?: string; choices?: Array<{ finish_reason?: string | null; delta?: {
|
|
@@ -216,9 +227,11 @@ async function runStream(model: Model<"openai-completions">, context: Context, o
|
|
|
216
227
|
} catch (error) {
|
|
217
228
|
controller.abort();
|
|
218
229
|
output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
|
219
|
-
|
|
230
|
+
const failure = idleExpired ? new Error(`Timeout: no data from the provider for ${options?.timeoutMs} ms`) : error;
|
|
231
|
+
output.errorMessage = formatProviderError(normalizeProviderError(failure), model.provider === "relay" ? `Relay ${model.baseUrl}` : undefined);
|
|
220
232
|
events.push({ type: "error", reason: output.stopReason, error: output });
|
|
221
233
|
} finally {
|
|
234
|
+
clearTimeout(idleTimer);
|
|
222
235
|
events.end();
|
|
223
236
|
}
|
|
224
237
|
}
|
package/packages/ai/src/types.ts
CHANGED
|
@@ -89,7 +89,8 @@ export interface StreamOptions {
|
|
|
89
89
|
*/
|
|
90
90
|
headers?: ProviderHeaders;
|
|
91
91
|
/**
|
|
92
|
-
*
|
|
92
|
+
* Timeout in milliseconds for providers/SDKs that support it. The openai-completions
|
|
93
|
+
* stream counts it as idle time: any received chunk restarts it, so an active stream never expires.
|
|
93
94
|
* For example, OpenAI and Anthropic SDK clients default to 10 minutes.
|
|
94
95
|
*/
|
|
95
96
|
timeoutMs?: number;
|
|
@@ -62,6 +62,7 @@ export type JournalLoadFailure = Readonly<{
|
|
|
62
62
|
}>;
|
|
63
63
|
|
|
64
64
|
type JournalOptions = {
|
|
65
|
+
validateRecord?: (record: CommandRecord) => void;
|
|
65
66
|
onLoadError?: (failure: JournalLoadFailure) => void;
|
|
66
67
|
onListenerError?: (error: unknown) => void;
|
|
67
68
|
onStaleLock?: (message: string) => void;
|
|
@@ -260,6 +261,7 @@ export class Journal {
|
|
|
260
261
|
readonly #listeners = new Set<(events: JournalEvent[]) => void>();
|
|
261
262
|
readonly #pendingPublications: JournalEvent[][] = [];
|
|
262
263
|
readonly #runs = new Map<RunId, RunLog>();
|
|
264
|
+
readonly #validateRecord: ((record: CommandRecord) => void) | undefined;
|
|
263
265
|
readonly #loadFailures = new Map<string, JournalLoadFailure>();
|
|
264
266
|
readonly #onLoadError: (failure: JournalLoadFailure) => void;
|
|
265
267
|
readonly #creationCommands = new Map<string, CommandRecord>();
|
|
@@ -279,6 +281,7 @@ export class Journal {
|
|
|
279
281
|
constructor(path: string, services: RuntimeServices, options: JournalOptions = {}) {
|
|
280
282
|
this.#path = path === ":memory:" ? null : path;
|
|
281
283
|
this.#services = services;
|
|
284
|
+
this.#validateRecord = options.validateRecord;
|
|
282
285
|
this.#onListenerError = options.onListenerError ?? ((error) => console.error("Journal listener failed:", error));
|
|
283
286
|
this.#onLoadError = options.onLoadError ?? ((failure) => console.error(`Journal ${failure.runId} (${failure.path}) is not available: ${failure.message}`));
|
|
284
287
|
this.#onStaleLock = options.onStaleLock ?? ((message) => console.warn(message));
|
|
@@ -561,6 +564,7 @@ export class Journal {
|
|
|
561
564
|
for (const record of records) {
|
|
562
565
|
this.assertRunAvailable(record.runId);
|
|
563
566
|
assertRunId(record.runId);
|
|
567
|
+
this.#validateRecord?.(record);
|
|
564
568
|
const ids = commandIds.get(record.runId) ?? new Set<string>();
|
|
565
569
|
|
|
566
570
|
if (ids.has(record.command.id) || this.#runs.get(record.runId)?.commands.has(record.command.id))
|
|
@@ -68,11 +68,10 @@ The actor enforces completion and extensions; see learning-afternoon.
|
|
|
68
68
|
Use `FlowDiagram` for other graphs (star layout, fit, actions). Keep local IDs stable.
|
|
69
69
|
See `controls`. For custom SVG use `SvgEdge`, Tailwind utilities, responsive `viewBox` and
|
|
70
70
|
accessible descriptions.
|
|
71
|
-
Address view visibility with `package-name/view-key`, `@handle/view-key` or a unique title
|
|
72
|
-
|
|
73
|
-
The host sizes
|
|
74
|
-
|
|
75
|
-
`actor_view_set_visibility` and cannot be changed by layouts.
|
|
71
|
+
Address view visibility with `package-name/view-key`, `@handle/view-key` or a unique title.
|
|
72
|
+
Visible apps enter the catalog automatically: browser tabs beside Chat, editor tabs in VS Code.
|
|
73
|
+
The host sizes each view. Use the addressee selector to inspect an app's owner.
|
|
74
|
+
`actor_view_set_visibility` controls whether a view is available.
|
|
76
75
|
|
|
77
76
|
Tests call `program.functions.<name>(input, context)` or `program.onInput(input, context)`.
|
|
78
77
|
`createTestContext` from `@ragents/server/testing` supplies state and explicit typed `functions` mocks.
|
|
@@ -10,7 +10,7 @@ const visibleProgram = (state: JsonValue): JsonValue => {
|
|
|
10
10
|
if (!program) return state;
|
|
11
11
|
const views = Array.isArray(program.views) ? program.views.map((value) => {
|
|
12
12
|
const view = record(value);
|
|
13
|
-
return view ? { id: view.id, key: view.key, title: view.title, visible: view.visible
|
|
13
|
+
return view ? { id: view.id, key: view.key, title: view.title, visible: view.visible } : value;
|
|
14
14
|
}) : [];
|
|
15
15
|
return {
|
|
16
16
|
version: 1,
|
|
@@ -3,7 +3,6 @@ import type { PluginHost, RAgentsPlugin } from "@ragents/engine";
|
|
|
3
3
|
import type { PluginModule } from "@ragents/host/plugin-support/plugin-module.js";
|
|
4
4
|
import { runtimeProviderToken, runGuardToken } from "@ragents/host/ragents/host-services.js";
|
|
5
5
|
import { askServiceToken } from "@ragents/plugins/ragents.ask/server/contract.js";
|
|
6
|
-
import { surfacePlacementToken } from "@ragents/plugins/ragents.orchestration/server/contract.js";
|
|
7
6
|
import { agentToolsFrom } from "./agent-tools.js";
|
|
8
7
|
import { createActorProgramMethods } from "./methods.js";
|
|
9
8
|
import { createMiniAppFrameRoutes, miniAppsApiPrefix } from "./routes.js";
|
|
@@ -28,7 +27,6 @@ const actorProgramsPlugin = (pluginHost: PluginHost): RAgentsPlugin => ({
|
|
|
28
27
|
return !script ? undefined : script.handle === name ? script.files : script.programs.find((program) => program.name === name)?.files;
|
|
29
28
|
},
|
|
30
29
|
sharedPackage: (name) => pluginHost.actorPackages.get(name),
|
|
31
|
-
placeView: (context, runId, entity) => { host.service(surfacePlacementToken).place(context, runId, { entity }); },
|
|
32
30
|
});
|
|
33
31
|
host.provide(actorProgramsToken, runtime);
|
|
34
32
|
const diagnostics = createProjectDiagnostics({
|
|
@@ -150,8 +150,6 @@ export interface ActorProgramRuntimeOptions {
|
|
|
150
150
|
scriptSources: (entryId: string, name: string) => readonly ActorProgramSource[] | undefined;
|
|
151
151
|
/** A shared actor package of the profile, by name. */
|
|
152
152
|
sharedPackage: (name: string) => { pluginId: string; files: readonly ActorProgramSource[] } | undefined;
|
|
153
|
-
/** Places a surface entity next to the run's layout unless the layout already shows it. */
|
|
154
|
-
placeView: (context: CommandContext, runId: string, entity: string) => void;
|
|
155
153
|
}
|
|
156
154
|
type Recognized = { start: JsonValue } | { result: JsonValue };
|
|
157
155
|
export class ActorProgramRuntime implements ActorProgramsService, ActorProgramExecutor {
|
|
@@ -525,9 +523,6 @@ export class ActorProgramRuntime implements ActorProgramsService, ActorProgramEx
|
|
|
525
523
|
const recorded = this.#script(runId).packages[handle];
|
|
526
524
|
if (!recorded)
|
|
527
525
|
throw new Error(`The package ${handle} was not installed by a run script.`);
|
|
528
|
-
const view = program.views[0];
|
|
529
|
-
if (start.embedded && view)
|
|
530
|
-
this.#options.placeView(this.operatorContext(runId, "place"), runId, `app:${view.id}`);
|
|
531
526
|
const state = this.#script(runId);
|
|
532
527
|
const record = state.packages[handle]!;
|
|
533
528
|
const count = record.count + 1;
|
|
@@ -750,7 +745,7 @@ export class ActorProgramRuntime implements ActorProgramsService, ActorProgramEx
|
|
|
750
745
|
const clientFile = `view-${view.id}.mjs`;
|
|
751
746
|
clients.push({ file: clientFile, javaScript: client.javaScript });
|
|
752
747
|
views.push({ id: `${name}--${view.id}`, key: view.id, title: view.title ?? pkg.title, visible: previous?.views.find((item) => item.key === view.id)?.visible ?? true,
|
|
753
|
-
|
|
748
|
+
html: `<!doctype html><html class="${FRAME_DOCUMENT_CLASS}"><head><meta charset="utf-8"></head><body class="${FRAME_BODY_CLASS}"><div id="root" class="${FRAME_ROOT_CLASS}"></div></body></html>`, styles, clientFile });
|
|
754
749
|
}
|
|
755
750
|
const viewSources = [...new Set((pkg.views ?? []).map((view) => path.dirname(path.resolve(directory, view.client))))];
|
|
756
751
|
const frameStyles = viewSources.length > 0 ? await buildTailwind(viewSources) : "";
|
|
@@ -857,9 +852,6 @@ export class ActorProgramRuntime implements ActorProgramsService, ActorProgramEx
|
|
|
857
852
|
const actor = this.resolveActor(runId, context.actorId, `@${name}`);
|
|
858
853
|
definition.actorId = actor.id;
|
|
859
854
|
definition.actorHandle = actor.handle;
|
|
860
|
-
for (const view of definition.views)
|
|
861
|
-
for (const placement of view.placements)
|
|
862
|
-
placement.anchorActorId = actor.id;
|
|
863
855
|
for (const fn of definition.functions)
|
|
864
856
|
if (fn.tool?.targets)
|
|
865
857
|
fn.tool.targets = fn.tool.targets.map((target) => target === "pending" ? actor.id : target);
|
|
@@ -909,7 +901,7 @@ export class ActorProgramRuntime implements ActorProgramsService, ActorProgramEx
|
|
|
909
901
|
}
|
|
910
902
|
apps(runId: string): ActorViewListing[] {
|
|
911
903
|
return this.programs(runId).flatMap((program) => program.views.map((view) => ({ id: view.id, actorId: program.actorId, actorHandle: program.actorHandle, title: view.title, description: program.description, revision: program.revision,
|
|
912
|
-
actions: program.functions.map(({ id, label, description, confirmation }) => ({ id, label, description, confirmation })),
|
|
904
|
+
actions: program.functions.map(({ id, label, description, confirmation }) => ({ id, label, description, confirmation })), visible: view.visible, state: this.data(runId, program.actorId), invocations: this.#invocations(runId).invocations.filter((invocation) => invocation.actorId === program.actorId && invocation.revision === program.revision) })));
|
|
913
905
|
}
|
|
914
906
|
runLocalTools(runId: string) {
|
|
915
907
|
if (!this.runtime().listRuns().some(run => run.id === runId))
|