@aparte/plugin-subagents 0.0.0-stage → 1.6.0

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.
@@ -0,0 +1,44 @@
1
+ /**
2
+ * How a sub-agent's conversation is drawn: core's own segment renderers, one row per
3
+ * segment, patched in place.
4
+ *
5
+ * Not `<aparte-chat-bubble>`: a bubble is ONE message of a chat, and it draws the chrome of
6
+ * one — a name and a time over the content, an avatar slot, the app's action bar
7
+ * (`setBubbleActions` reaches every bubble: Retry and Edit on a sub-agent's text would
8
+ * dispatch for a message that does not exist), the `‹1/2›` picker, the app's whole frame
9
+ * (`setBubbleShellRenderer`), `role="article"` named "Message from Assistant", and the
10
+ * waiting dots. None of it can be switched off without changing core, and hiding it from a
11
+ * stylesheet would out-specify core's recipes. What a conversation needs from the bubble is
12
+ * its row loop alone — and that is the renderer contract: `render`, then `setup`; `update`
13
+ * on a change (following the element when the renderer replaced its own); `relabel` on a
14
+ * language switch; `cleanup` when the row goes. So this is that loop, and nothing else.
15
+ *
16
+ * A row is found by its segment's id and patched when its segment is a new object (a
17
+ * segment list replaces the object it changes, and only that one), so a token costs the
18
+ * one row it lands in. A row whose renderer is no longer the one in effect is drawn again.
19
+ */
20
+ import { type AparteConfig, type AparteSegment } from '@aparte/core';
21
+ /** The rows of one conversation, inside `container`. */
22
+ export declare class LaneDrawing {
23
+ readonly container: HTMLElement;
24
+ private readonly rows;
25
+ constructor(container: HTMLElement);
26
+ /** How many rows are drawn. */
27
+ get size(): number;
28
+ /**
29
+ * Draw `segments`, in order: a new segment gets a row, a changed one is patched, one that
30
+ * left loses its row. `live`: the sub-agent still works, so what it adds is arriving.
31
+ */
32
+ sync(segments: readonly AparteSegment[], config: AparteConfig, live: boolean): void;
33
+ /** Every row re-reads what it takes from the config (a language switch). */
34
+ relabel(config: AparteConfig): void;
35
+ /** Every row goes: each renderer cleans up what it drew. */
36
+ clear(config: AparteConfig): void;
37
+ private draw;
38
+ private patch;
39
+ /** The row for `id` among the container's own children — never a decoy in a row's prose. */
40
+ private childOf;
41
+ private release;
42
+ private cleanup;
43
+ }
44
+ //# sourceMappingURL=drawing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawing.d.ts","sourceRoot":"","sources":["../src/drawing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAIH,KAAK,YAAY,EACjB,KAAK,aAAa,EAErB,MAAM,cAAc,CAAC;AAoDtB,wDAAwD;AACxD,qBAAa,WAAW;IAGR,QAAQ,CAAC,SAAS,EAAE,WAAW;IAF3C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0B;gBAE1B,SAAS,EAAE,WAAW;IAE3C,+BAA+B;IAC/B,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;OAGG;IACH,IAAI,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IA2BnF,4EAA4E;IAC5E,OAAO,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAQnC,4DAA4D;IAC5D,KAAK,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAOjC,OAAO,CAAC,IAAI;IAeZ,OAAO,CAAC,KAAK;IA4Bb,4FAA4F;IAC5F,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,OAAO;CASlB"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `@aparte/plugin-subagents` — a sub-agent's work, shown as one line.
3
+ *
4
+ * Core keeps a sub-agent's events out of the reply (its text is not the reply's, its calls
5
+ * are not the reply's rows) and lets a plugin observe them. This plugin draws them: the call
6
+ * that opened a sub-agent becomes its line — name, task, what it is doing now, "3 tools ·
7
+ * 12 s", and its state — and the sub-agent's conversation is kept on that call, saved with
8
+ * the conversation and never sent to the model. A sub-agent no call opened gets the same
9
+ * line, from a segment of the plugin's own. Its conversation can be shown under the line
10
+ * (`subagentTranscript`, `details: 'transcript'`) or anywhere else
11
+ * (`<aparte-subagent-view>`).
12
+ */
13
+ export { setupSubagents } from './setup.js';
14
+ export { subagentOf, subagentStatus } from './status.js';
15
+ export { subagentTranscript } from './transcript.js';
16
+ export { AparteSubagentView } from './aparte-subagent-view.js';
17
+ export type { SubagentViewSource } from './aparte-subagent-view.js';
18
+ export { SUBAGENT_SEGMENT_TYPE } from './types.js';
19
+ export type { AparteSubagent, AparteSubagentStatus, AparteSubagentSegment, SubagentsOptions, AparteSubagentStartEventDetail, AparteSubagentEndEventDetail, } from './types.js';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,YAAY,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,YAAY,EACR,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,8BAA8B,EAC9B,4BAA4B,GAC/B,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ import { A, S, s, a, b, c } from "./setup-CaTzFtu8.js";
2
+ export {
3
+ A as AparteSubagentView,
4
+ S as SUBAGENT_SEGMENT_TYPE,
5
+ s as setupSubagents,
6
+ a as subagentOf,
7
+ b as subagentStatus,
8
+ c as subagentTranscript
9
+ };
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * `@aparte/plugin-subagents` — the DOM-free entry, for Node and SSR.
3
+ *
4
+ * Everything the browser entry exports but the element is DOM-free at import: the observer
5
+ * and the line are plain functions, the `subagent` segment's renderer only builds DOM when a
6
+ * chat draws it — in a browser — and `subagentTranscript` returns `''` without a document. So `setupSubagents()` here installs the same three pieces, and a
7
+ * conversation rendered on a server reads its sub-agents' state through `subagentOf` and
8
+ * `subagentStatus`. `scripts/check-node-import.mjs` asserts this entry imports without a DOM.
9
+ */
10
+ export { setupSubagents } from './setup.js';
11
+ export { subagentOf, subagentStatus } from './status.js';
12
+ export { subagentTranscript } from './transcript.js';
13
+ export type { AparteSubagentView, SubagentViewSource } from './aparte-subagent-view.js';
14
+ export { SUBAGENT_SEGMENT_TYPE } from './types.js';
15
+ export type { AparteSubagent, AparteSubagentStatus, AparteSubagentSegment, SubagentsOptions, AparteSubagentStartEventDetail, AparteSubagentEndEventDetail, } from './types.js';
16
+ //# sourceMappingURL=index.node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.node.d.ts","sourceRoot":"","sources":["../src/index.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGrD,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,YAAY,EACR,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,8BAA8B,EAC9B,4BAA4B,GAC/B,MAAM,YAAY,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { S, s, a, b, c } from "./setup-CaTzFtu8.js";
2
+ export {
3
+ S as SUBAGENT_SEGMENT_TYPE,
4
+ s as setupSubagents,
5
+ a as subagentOf,
6
+ b as subagentStatus,
7
+ c as subagentTranscript
8
+ };
9
+ //# sourceMappingURL=index.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.node.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The lanes: each sub-agent's conversation, kept apart from the reply and saved on the
3
+ * segment that stands for it.
4
+ *
5
+ * Core keeps a sub-agent's events out of the reply and hands every event of the run to the
6
+ * observers of `observeRunEvents`. This observer gives each sub-agent a lane: a segment list
7
+ * (`createSegmentList`) written by a stream adapter of core's own (`createStreamAdapter`), fed
8
+ * the sub-agent's events with their `agentId` taken off, so the lane holds exactly what a
9
+ * reply would — text, reasoning, its tool calls, stamped the same way.
10
+ *
11
+ * A lane lives on its ANCHOR, the segment that stands for the sub-agent: the call that opened
12
+ * it (`tool-<toolCallId>`, in a field `subagent`), or — with no call, or for the second
13
+ * sub-agent of one call — a `subagent` segment of the plugin's own, added to the reply. A
14
+ * sub-agent of a sub-agent follows the same two rules inside its parent's lane. The anchor is
15
+ * written once per animation frame while text streams, and at once for everything a person
16
+ * must see or the conversation must keep: a new segment, a tool's state, the sub-agent's end,
17
+ * the run's end or pause — the conversation is saved on those, so the lane is on the segment
18
+ * before anyone saves it.
19
+ *
20
+ * Memory is per reply, emptied when its run ends (done, stopped, failed), kept across a pause
21
+ * (the run resumes into the same reply), and capped.
22
+ */
23
+ import { type AparteRunEventContext, type AparteSegment, type AparteStreamRunEvent } from '@aparte/core';
24
+ /** A sub-agent's anchor, just written: which chat, which reply, which agent, and the segment as it is now. */
25
+ export interface LaneWrite {
26
+ readonly target: object;
27
+ readonly targetId?: string;
28
+ readonly messageId: string;
29
+ readonly agentId: string;
30
+ readonly anchor: AparteSegment;
31
+ }
32
+ /**
33
+ * Hear every sub-agent's anchor as it is written — once a frame while it streams, at once
34
+ * for everything else. What `<aparte-subagent-view>` follows a live sub-agent with.
35
+ */
36
+ export declare function watchLaneWrites(fn: (write: LaneWrite) => void): () => void;
37
+ /** The observer of one setup, and what forgets everything it follows. */
38
+ export declare function createLanes(): {
39
+ observe: (event: AparteStreamRunEvent, ctx: AparteRunEventContext) => void;
40
+ dispose: () => void;
41
+ };
42
+ //# sourceMappingURL=lanes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lanes.d.ts","sourceRoot":"","sources":["../src/lanes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAIH,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAGlB,KAAK,oBAAoB,EAG5B,MAAM,cAAc,CAAC;AAuBtB,8GAA8G;AAC9G,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;CAClC;AAKD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI,CAG1E;AAqGD,yEAAyE;AACzE,wBAAgB,WAAW,IAAI;IAAE,OAAO,EAAE,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAgdjI"}
package/dist/line.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * A sub-agent's line: core's tool row, named by what ran it.
3
+ *
4
+ * The plugin gives core a tool-line provider (`setToolLineProvider`): for a call that carries
5
+ * a sub-agent — the call that opened it, or the call the plugin's own segment stands in for —
6
+ * it says the sub-agent's name and its task, and on a second line, from the sub-agent's start to
7
+ * its end, what it is on ("Starting…", then its latest call) and once it is over what it did
8
+ * ("3 tools · 12s"). The second line is there the whole time, so the row keeps its height: one
9
+ * that grew a line when the sub-agent began acting and lost it at its end moved every row under
10
+ * it twice, and a count that grew beside the task moved the task. Core reads it AFTER the app's
11
+ * `registerToolDisplay`, field by field, so the app's label, summary and details always win. It
12
+ * is asked at every draw, update and relabel and stores nothing: the counts and the words follow
13
+ * the reader's language.
14
+ */
15
+ import { type AparteToolCallSegment, type AparteToolLine } from '@aparte/core';
16
+ import type { SubagentsOptions } from './types.js';
17
+ /** Mark a call built to draw a `subagent` segment with core's row. */
18
+ export declare function markStandIn(segment: AparteToolCallSegment): AparteToolCallSegment;
19
+ /**
20
+ * The provider: the line of every call that carries a sub-agent, `undefined` for any other
21
+ * call (core's own line then).
22
+ */
23
+ export declare function createLineProvider(options?: SubagentsOptions): (segment: AparteToolCallSegment) => AparteToolLine | undefined;
24
+ //# sourceMappingURL=line.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"line.d.ts","sourceRoot":"","sources":["../src/line.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAMH,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACtB,MAAM,cAAc,CAAC;AAItB,OAAO,KAAK,EAAwC,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAKzF,sEAAsE;AACtE,wBAAgB,WAAW,CAAC,OAAO,EAAE,qBAAqB,GAAG,qBAAqB,CAGjF;AA8ED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,gBAAqB,GAAG,CAAC,OAAO,EAAE,qBAAqB,KAAK,cAAc,GAAG,SAAS,CAwDjI"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The line of a sub-agent no call opened: core's own tool row, drawn for a stand-in call.
3
+ *
4
+ * A sub-agent announced without a call (an AG-UI `SUBAGENT_STARTED` with no parent call), or
5
+ * the second one a call opens, has no row of its own in the reply, so the plugin adds a
6
+ * `subagent` segment for it. That segment is drawn by core's `tool_call` renderer, handed a
7
+ * call that stands for the agent: its name is the agent's (so `registerToolDisplay('<agent
8
+ * name>', …)` reaches it — label, icon, `quiet`, `hidden`, `details`), its status says the
9
+ * agent's. The renderer returns the row's own root — no wrapper — and forwards `setup`,
10
+ * `update`, `relabel` and `cleanup` to core's, so the line reads and behaves exactly like a
11
+ * call's sub-agent line.
12
+ */
13
+ import { type AparteSegmentRenderer, type AparteToolCallSegment } from '@aparte/core';
14
+ import { type AparteSubagentSegment } from './types.js';
15
+ /** The tool name a sub-agent with no name stands in under. */
16
+ export declare const UNNAMED_AGENT = "subagent";
17
+ /** The call that stands for a `subagent` segment on core's row: same id, the agent's name, its status. */
18
+ export declare function standInCall(segment: AparteSubagentSegment): AparteToolCallSegment;
19
+ export declare const subagentRenderer: AparteSegmentRenderer<AparteSubagentSegment>;
20
+ //# sourceMappingURL=segment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segment.d.ts","sourceRoot":"","sources":["../src/segment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAGH,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC7B,MAAM,cAAc,CAAC;AAItB,OAAO,EAAyB,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAE/E,8DAA8D;AAC9D,eAAO,MAAM,aAAa,aAAa,CAAC;AAExC,0GAA0G;AAC1G,wBAAgB,WAAW,CAAC,OAAO,EAAE,qBAAqB,GAAG,qBAAqB,CAkBjF;AAgBD,eAAO,MAAM,gBAAgB,EAAE,qBAAqB,CAAC,qBAAqB,CAsBzE,CAAC"}