@llmnative/agentico 0.3.0 → 0.4.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.
- package/README.md +84 -83
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +472 -289
- package/dist/index.mjs.map +1 -1
- package/dist/types/i18n/types.d.ts +8 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/presentation/AgentActivityLog.d.ts +26 -2
- package/dist/types/presentation/Agentico.d.ts +14 -4
- package/dist/types/presentation/AgenticoResizeHandle.d.ts +17 -0
- package/dist/types/presentation/panelWidth.d.ts +32 -0
- package/llms.txt +43 -41
- package/package.json +1 -1
|
@@ -55,6 +55,14 @@ export interface AgenticoDict {
|
|
|
55
55
|
resumeWithAi: string;
|
|
56
56
|
openPanel: string;
|
|
57
57
|
closePanel: string;
|
|
58
|
+
/** Accessible name of the edge that resizes the panel. */
|
|
59
|
+
resizePanel: string;
|
|
60
|
+
/** Tooltip of that edge. */
|
|
61
|
+
resizePanelHint: string;
|
|
62
|
+
/** Accessible name of the questions docked at the bottom of the panel. */
|
|
63
|
+
pendingQuestions: string;
|
|
64
|
+
/** Stops the turn while its questions are docked (the composer, with its stop button, is hidden). */
|
|
65
|
+
stop: string;
|
|
58
66
|
}
|
|
59
67
|
declare module '@llmnative/react' {
|
|
60
68
|
interface I18nDict {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -17,7 +17,8 @@ export { jsonExportDestination, JSON_EXPORT_DESTINATION_ID } from './domain/json
|
|
|
17
17
|
export { registerDestinations, getDestinationRegistry } from './domain/destinationRegistry';
|
|
18
18
|
export { configureEntityChatStore, saveEntityChat, getEntityChat, listEntityChats, removeEntityChat, entityChatTaskId, type EntityChatSnapshot, } from './domain/entityChatStore';
|
|
19
19
|
export { agenticoTranslations, agenticoEn, agenticoIt, agenticoDe, useAgenticoI18n, type AgenticoDict } from './i18n';
|
|
20
|
-
export { Agentico, AGENTICO_WIDTH } from './presentation/Agentico';
|
|
20
|
+
export { Agentico, AGENTICO_WIDTH, type AgenticoProps } from './presentation/Agentico';
|
|
21
|
+
export { AGENTICO_MIN_WIDTH, AGENTICO_MAX_WIDTH, AGENTICO_WIDTH_STORAGE_KEY, type AgenticoPanelSize } from './presentation/panelWidth';
|
|
21
22
|
export { AgenticoToggle } from './presentation/AgenticoToggle';
|
|
22
23
|
export { AgenticoProvider, useAgentico, ORCHESTRATOR_TASK_ID, type AgenticoScope, type AgenticoTask, type ComponentAnchor, } from './presentation/AgenticoContext';
|
|
23
24
|
export { useAgent, type AgentActivityEntry, type AgentConversation, type UseAgentResult } from './presentation/useAgent';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentActivityEntry } from './useAgent';
|
|
2
|
-
import type { AgentQuestionAnswer } from '../domain/messageParts';
|
|
2
|
+
import type { AgentQuestionAnswer, AgentQuestionsPart } from '../domain/messageParts';
|
|
3
3
|
/** What the log needs to let the person answer questions (CR-004): the entries of the live
|
|
4
4
|
* conversation (`canAnswer`) and where the answers go. Without it, unanswered questions are shown
|
|
5
5
|
* disabled. */
|
|
@@ -7,6 +7,25 @@ export interface AgentActivityLogQuestions {
|
|
|
7
7
|
canAnswer: (entryId: string) => boolean;
|
|
8
8
|
onAnswer: (entryId: string, partId: string, answers: AgentQuestionAnswer[]) => Promise<unknown>;
|
|
9
9
|
}
|
|
10
|
+
/** The questions part shown docked at the bottom of the panel instead of in the thread (CR-005). */
|
|
11
|
+
export interface DockedQuestions {
|
|
12
|
+
entry: AgentActivityEntry;
|
|
13
|
+
part: AgentQuestionsPart;
|
|
14
|
+
}
|
|
15
|
+
/** The questions waiting for an answer in the latest message of the agent (CR-005): the last
|
|
16
|
+
* questions part without answers of the last entry, when that entry is a message in parts of a turn
|
|
17
|
+
* that did not stop or fail, and the person can answer it. Otherwise nothing is docked and the
|
|
18
|
+
* questions stay in the thread (read-only once answered). */
|
|
19
|
+
export declare function findDockedQuestions(activity: readonly AgentActivityEntry[], canAnswer: (entryId: string) => boolean): DockedQuestions | null;
|
|
20
|
+
/** A questions part of the agent with `ChatQuestions`: answerable while the entry is live and it has
|
|
21
|
+
* no answers, read-only with its answers, disabled otherwise. */
|
|
22
|
+
export declare function QuestionsPart({ entry, part, questions, autoFocus, className }: {
|
|
23
|
+
entry: AgentActivityEntry;
|
|
24
|
+
part: AgentQuestionsPart;
|
|
25
|
+
questions?: AgentActivityLogQuestions;
|
|
26
|
+
autoFocus?: boolean;
|
|
27
|
+
className?: string;
|
|
28
|
+
}): import("react").JSX.Element;
|
|
10
29
|
/** Il log di attività di un agente, usato dal pannello globale (Agentico) — ogni agente ora
|
|
11
30
|
* ci passa attraverso, il pannello embedded legacy (AgentFollowUp) è stato ritirato una volta
|
|
12
31
|
* migrato anche l'ultimo consumer (import HTML/JSX, vedi ComponentEditPage.tsx). Un solo posto
|
|
@@ -15,7 +34,12 @@ export interface AgentActivityLogQuestions {
|
|
|
15
34
|
* One `<li>` per turn (CR-004): the message of the person, sticky at the top while its turn
|
|
16
35
|
* scrolls, then what the agent did and said. Entries before the first message of the person
|
|
17
36
|
* (an opening without text) form a turn of their own, without a bubble. */
|
|
18
|
-
export declare function AgentActivityLog({ activity, questions }: {
|
|
37
|
+
export declare function AgentActivityLog({ activity, questions, docked, pinUserMessages }: {
|
|
19
38
|
activity: AgentActivityEntry[];
|
|
20
39
|
questions?: AgentActivityLogQuestions;
|
|
40
|
+
/** Questions docked at the bottom of the panel (CR-005): left out of the thread. */
|
|
41
|
+
docked?: DockedQuestions | null;
|
|
42
|
+
/** The message of the person sticks at the top while its turn scrolls (default). Off while
|
|
43
|
+
* questions are docked, so the thread has more room. */
|
|
44
|
+
pinUserMessages?: boolean;
|
|
21
45
|
}): import("react").JSX.Element | null;
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { AGENTICO_WIDTH, type AgenticoPanelSize } from './panelWidth';
|
|
3
|
+
export { AGENTICO_WIDTH };
|
|
4
|
+
/** Props of the panel (CR-005): its width, which the person changes by dragging its inner edge. */
|
|
5
|
+
export interface AgenticoProps {
|
|
6
|
+
/** Width when nothing is stored, and after a double click on the edge. Default `AGENTICO_WIDTH` (420 px). */
|
|
7
|
+
defaultWidth?: number;
|
|
8
|
+
/** Narrowest width, in px. Default 320. */
|
|
9
|
+
minWidth?: number;
|
|
10
|
+
/** Widest width: px, or a share of the viewport (`'60vw'`, the default). */
|
|
11
|
+
maxWidth?: AgenticoPanelSize;
|
|
12
|
+
/** The current width, whenever it changes (e.g. for the `rightInset` of a Modal beside the panel). */
|
|
13
|
+
onWidthChange?: (width: number) => void;
|
|
14
|
+
}
|
|
5
15
|
/** Agentico — il pannello globale, persistente e non-overlay per le sessioni agente — affianca
|
|
6
16
|
* il CMS (che si stringe) invece di coprirlo, cosi la modale che ha avviato l'agente resta
|
|
7
17
|
* aperta e utilizzabile accanto. Header: titolo dell'UNICO task attivo (mai una tab bar — "una
|
|
@@ -20,4 +30,4 @@ export declare const AGENTICO_WIDTH = 420;
|
|
|
20
30
|
* (AgenticoContext), il suo toggle (AgenticoToggle) — non degli agenti verticali che esegue
|
|
21
31
|
* (theme-import, html-to-liquid, ...), che restano nel proprio dominio senza questo
|
|
22
32
|
* prefisso: sono contenuto che Agentico orchestra, non parte della sua identità. */
|
|
23
|
-
export declare function Agentico(): React.JSX.Element;
|
|
33
|
+
export declare function Agentico({ defaultWidth, minWidth, maxWidth, onWidthChange }?: AgenticoProps): React.JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/** The inner edge of the Agentico column (CR-005), the one facing the page: dragged with the
|
|
3
|
+
* pointer it resizes the panel; focused, the arrow keys do (Shift for bigger steps, Home/End for
|
|
4
|
+
* the minimum/maximum); a double click goes back to the default width. The framework has no
|
|
5
|
+
* splitter primitive, so this one is drawn with theme tokens only: a thin line in the primary
|
|
6
|
+
* colour on hover, focus and while dragging. The panel sits on the right, so moving the edge to
|
|
7
|
+
* the left makes it wider. */
|
|
8
|
+
export declare function AgenticoResizeHandle({ width, min, max, onResize, onCommit, onReset }: {
|
|
9
|
+
width: number;
|
|
10
|
+
min: number;
|
|
11
|
+
max: number;
|
|
12
|
+
/** A new width while it changes (clamped by the caller). */
|
|
13
|
+
onResize: (width: number) => void;
|
|
14
|
+
/** The width the person settled on: stored. */
|
|
15
|
+
onCommit: (width: number) => void;
|
|
16
|
+
onReset: () => void;
|
|
17
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Default width of the panel, in px. Also the `rightInset` a host can give a Modal that must leave it room. */
|
|
2
|
+
export declare const AGENTICO_WIDTH = 420;
|
|
3
|
+
/** Default minimum width of the panel, in px. */
|
|
4
|
+
export declare const AGENTICO_MIN_WIDTH = 320;
|
|
5
|
+
/** Default maximum width of the panel: a share of the viewport. */
|
|
6
|
+
export declare const AGENTICO_MAX_WIDTH = "60vw";
|
|
7
|
+
/** Where the width chosen by the person is kept, per browser. */
|
|
8
|
+
export declare const AGENTICO_WIDTH_STORAGE_KEY = "agentico:panel-width";
|
|
9
|
+
/** One arrow key press, in px (with Shift: four times as much). */
|
|
10
|
+
export declare const AGENTICO_WIDTH_STEP = 16;
|
|
11
|
+
/** A width in px, or a share of the viewport (`'60vw'`). */
|
|
12
|
+
export type AgenticoPanelSize = number | `${number}vw`;
|
|
13
|
+
/** A size in px: a number as it is, `'<n>vw'` as that share of `viewportWidth`. */
|
|
14
|
+
export declare function resolvePanelSize(size: AgenticoPanelSize, viewportWidth: number): number;
|
|
15
|
+
/** `width` kept between `min` and `max` (a max below the min gives way to the min). */
|
|
16
|
+
export declare function clampPanelWidth(width: number, min: number, max: number): number;
|
|
17
|
+
export interface PanelWidthOptions {
|
|
18
|
+
defaultWidth?: number;
|
|
19
|
+
minWidth?: number;
|
|
20
|
+
maxWidth?: AgenticoPanelSize;
|
|
21
|
+
onWidthChange?: (width: number) => void;
|
|
22
|
+
}
|
|
23
|
+
/** The width of the panel: the stored one or the default, clamped to the current viewport. `set`
|
|
24
|
+
* changes it (clamped), `commit` stores it, `reset` goes back to the default and forgets it. */
|
|
25
|
+
export declare function usePanelWidth({ defaultWidth, minWidth, maxWidth, onWidthChange }: PanelWidthOptions): {
|
|
26
|
+
width: number;
|
|
27
|
+
min: number;
|
|
28
|
+
max: number;
|
|
29
|
+
set: (next: number) => void;
|
|
30
|
+
commit: (next: number) => void;
|
|
31
|
+
reset: () => void;
|
|
32
|
+
};
|
package/llms.txt
CHANGED
|
@@ -1,41 +1,43 @@
|
|
|
1
|
-
# @llmnative/agentico
|
|
2
|
-
|
|
3
|
-
> Agentic chat orchestrator for @llmnative/react apps. A persistent panel: the orchestrator
|
|
4
|
-
> collects parameters in conversation and hands the work to host-registered subagents. Every
|
|
5
|
-
> subagent has a deterministic fallback. Agentico knows nothing concrete about the host.
|
|
6
|
-
|
|
7
|
-
## Host responsibilities (startup)
|
|
8
|
-
|
|
9
|
-
- `registerSubagents(manifests)` — SubagentManifest: id, label, icon, description, indexPath, commands (name, summary, Zod inputSchema, describeOutput), definition (AgentDefinition), toParams, destinationIds, optional crossAgentToolIds, withCollected, manualEntry, componentContexts, chatEntityId (chat saved at every turn under that entity), onlyWhenAnchored (offered by the orchestrator only when scoped to it).
|
|
10
|
-
- `registerDestinations({ id: ResultDestination })` — apply(result, { scopeId, dataProvider, storageProvider, proxyFetch }, meta).
|
|
11
|
-
- `registerSubagentReports({ subagentId: SubagentReportModule })`.
|
|
12
|
-
- `registerSubagentControls({ subagentId: useControls })` — a hook of the host per task (props: params, taskId, running, close) returning `{ actions?: ChatbotAction[] (with onClick), content?: ReactNode }`, memoized: actions in the prompt, content above it.
|
|
13
|
-
- `SubagentManifest.onArchive(entityId, params)` / `confirmArchive(entityId, params)` — archiving a chat from the history (hover icon).
|
|
14
|
-
- `registerCrossAgentTools((ctx) => AgentTool[])` — ctx: attachmentsRef, collected (per-conversation scratchpad), proxyFetch.
|
|
15
|
-
- `configureAgenticoPrompts(partial)` — model-facing pack; `agenticoPromptsEn` (default) / `agenticoPromptsIt`.
|
|
16
|
-
- `configureEntityChatStore({ storageKey })`.
|
|
17
|
-
- i18n: merge `agenticoTranslations.<locale>` into `<App i18n={{ translations }}>`; override any `agentico.*` key.
|
|
18
|
-
|
|
19
|
-
## Mount
|
|
20
|
-
|
|
21
|
-
```tsx
|
|
22
|
-
<AgenticoProvider scope={{ id, dataProvider, storageProvider } | null}>
|
|
23
|
-
<AgenticoToggle />
|
|
24
|
-
<Agentico />
|
|
25
|
-
</AgenticoProvider>
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- `
|
|
33
|
-
- `
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
1
|
+
# @llmnative/agentico
|
|
2
|
+
|
|
3
|
+
> Agentic chat orchestrator for @llmnative/react apps. A persistent panel: the orchestrator
|
|
4
|
+
> collects parameters in conversation and hands the work to host-registered subagents. Every
|
|
5
|
+
> subagent has a deterministic fallback. Agentico knows nothing concrete about the host.
|
|
6
|
+
|
|
7
|
+
## Host responsibilities (startup)
|
|
8
|
+
|
|
9
|
+
- `registerSubagents(manifests)` — SubagentManifest: id, label, icon, description, indexPath, commands (name, summary, Zod inputSchema, describeOutput), definition (AgentDefinition), toParams, destinationIds, optional crossAgentToolIds, withCollected, manualEntry, componentContexts, chatEntityId (chat saved at every turn under that entity), onlyWhenAnchored (offered by the orchestrator only when scoped to it).
|
|
10
|
+
- `registerDestinations({ id: ResultDestination })` — apply(result, { scopeId, dataProvider, storageProvider, proxyFetch }, meta).
|
|
11
|
+
- `registerSubagentReports({ subagentId: SubagentReportModule })`.
|
|
12
|
+
- `registerSubagentControls({ subagentId: useControls })` — a hook of the host per task (props: params, taskId, running, close) returning `{ actions?: ChatbotAction[] (with onClick), content?: ReactNode }`, memoized: actions in the prompt, content above it.
|
|
13
|
+
- `SubagentManifest.onArchive(entityId, params)` / `confirmArchive(entityId, params)` — archiving a chat from the history (hover icon).
|
|
14
|
+
- `registerCrossAgentTools((ctx) => AgentTool[])` — ctx: attachmentsRef, collected (per-conversation scratchpad), proxyFetch.
|
|
15
|
+
- `configureAgenticoPrompts(partial)` — model-facing pack; `agenticoPromptsEn` (default) / `agenticoPromptsIt`.
|
|
16
|
+
- `configureEntityChatStore({ storageKey })`.
|
|
17
|
+
- i18n: merge `agenticoTranslations.<locale>` into `<App i18n={{ translations }}>`; override any `agentico.*` key.
|
|
18
|
+
|
|
19
|
+
## Mount
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
<AgenticoProvider scope={{ id, dataProvider, storageProvider } | null}>
|
|
23
|
+
<AgenticoToggle />
|
|
24
|
+
<Agentico />
|
|
25
|
+
</AgenticoProvider>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`<Agentico defaultWidth? minWidth? maxWidth? onWidthChange? />` (0.4.0): the column is resized by dragging its inner edge (a `role="separator"`: arrows by 16 px, Shift ×4, Home/End, double click = default), clamped to `minWidth` (320) … `maxWidth` (px or `'<n>vw'`, default `'60vw'`), stored per browser under `agentico:panel-width`. Defaults `AGENTICO_WIDTH` (420), `AGENTICO_MIN_WIDTH`, `AGENTICO_MAX_WIDTH`. Unanswered questions of the latest agent message (turn not stopped/failed) are docked at the bottom in place of the composer (scroll inside, Stop while the turn runs), the person's message is not pinned meanwhile; once answered they are back in the thread, read-only. Questions of a reloaded chat are answerable (docked) too.
|
|
29
|
+
|
|
30
|
+
## Hooks
|
|
31
|
+
|
|
32
|
+
- `useAgentico()` — panel state, `startOrchestrator(goal, opts)`, `startSubagent(subagentId, params, { taskId?, openingMessage? })` (use `entityChatTaskId(subagentId, entityId)` as taskId), `resumeEntityChat`, `commitEntityChat(subagentId, entityId, taskId, scopeId, params, title)`, `scope`.
|
|
33
|
+
- `useAgenticoPageContext(text, card?)` — what the user is looking at.
|
|
34
|
+
- `useSubagentComponentContext(subagentId, componentKey)` — anchor a component to a subagent.
|
|
35
|
+
- `useAgent(definition)` — run an AgentDefinition directly.
|
|
36
|
+
|
|
37
|
+
## AgentDefinition
|
|
38
|
+
|
|
39
|
+
buildContext (always runs) · buildPrompt · buildFollowUpPrompt · parseResponse (null → fallback) · fallback (required) · describeFallback? · getTools? · microPromptIds? · executor?
|
|
40
|
+
|
|
41
|
+
`executor.turn({ params, context, text, first, signal, model?, onText(whole reply so far), onStep({ id, label, status }) }) → { text, result? }`; `executor.models(params)` / `defaultModel(params)` put the models of the executor in the composer: the turns go to the host instead of the AI provider; `text` is what the person typed (opening message on the first turn). The conversation is `remote: true`: no attachments, no fallback; the picker shows `remoteModels`.
|
|
42
|
+
|
|
43
|
+
Message parts (0.3.0): the turn also has `onText(text, { id?, done? })` (without id: the one reply, kept below steps and reasoning; with id: a text part of its own), `onReasoning(text, { id?, done?, duration? })` (whole text so far; shown closed, "Reasoned for N s", duration measured if not given), `onQuestions(questions, { id? }) → Promise<answers>` (questions `{ id?, header?, question, options?: [{ label, description? }], multiple?, recommended?, custom? }`; answers `[{ id?, header?, values: string[] }]`). Answers given while the turn runs resolve that promise; given later (or after a reload) they start a new turn with `text: ''` and `answers: { id, answers }` (id = the questions part id, default `questions-N`). Parts are kept in `AgentActivityEntry.parts` (`text` | `reasoning` | `tool` | `questions`, `detail` = the text) and saved with the chat; old chats without parts show `detail`. Rendered with `ChatMarkdown`, `ChatReasoning`, steps grouped in a `Tree`, `ChatQuestions` (needs `@llmnative/react` 1.34). `useAgent().answerQuestions(entryId, partId, answers)`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llmnative/agentico",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Agentic chat orchestrator for @llmnative/react apps: a persistent panel that talks with the user and hands the work to host-registered subagents.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|