@llmnative/agentico 0.1.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/LICENSE +201 -0
- package/README.md +78 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1995 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types/domain/agentDefinition.d.ts +83 -0
- package/dist/types/domain/cli/renderManifestCli.d.ts +7 -0
- package/dist/types/domain/crossAgentTools.d.ts +13 -0
- package/dist/types/domain/defineSubagent.d.ts +5 -0
- package/dist/types/domain/destinationRegistry.d.ts +5 -0
- package/dist/types/domain/entityChatStore.d.ts +48 -0
- package/dist/types/domain/extractErrorMessage.d.ts +1 -0
- package/dist/types/domain/extractJsonBlock.d.ts +1 -0
- package/dist/types/domain/jsonExportDestination.d.ts +3 -0
- package/dist/types/domain/mcpTool.d.ts +9 -0
- package/dist/types/domain/microPrompts.d.ts +20 -0
- package/dist/types/domain/orchestrator/agenticoOrchestratorAgent.d.ts +34 -0
- package/dist/types/domain/orchestrator/prompt.d.ts +17 -0
- package/dist/types/domain/prompts.d.ts +29 -0
- package/dist/types/domain/resultDestination.d.ts +24 -0
- package/dist/types/domain/subagentManifest.d.ts +172 -0
- package/dist/types/domain/subagentRegistry.d.ts +11 -0
- package/dist/types/domain/subagentUsageCard.d.ts +37 -0
- package/dist/types/i18n/de.d.ts +2 -0
- package/dist/types/i18n/en.d.ts +2 -0
- package/dist/types/i18n/index.d.ts +20 -0
- package/dist/types/i18n/it.d.ts +2 -0
- package/dist/types/i18n/types.d.ts +55 -0
- package/dist/types/index.d.ts +25 -0
- package/dist/types/presentation/AgentActivityLog.d.ts +9 -0
- package/dist/types/presentation/AgentControls.d.ts +26 -0
- package/dist/types/presentation/Agentico.d.ts +23 -0
- package/dist/types/presentation/AgenticoContext.d.ts +305 -0
- package/dist/types/presentation/AgenticoToggle.d.ts +17 -0
- package/dist/types/presentation/ManualEntryRunner.d.ts +22 -0
- package/dist/types/presentation/OrchestratorRunner.d.ts +12 -0
- package/dist/types/presentation/ResultDestinationPicker.d.ts +29 -0
- package/dist/types/presentation/SubagentRunner.d.ts +48 -0
- package/dist/types/presentation/deriveHistoryTitle.d.ts +10 -0
- package/dist/types/presentation/liveAnchorDestination.d.ts +10 -0
- package/dist/types/presentation/reports/GenericResultPreview.d.ts +11 -0
- package/dist/types/presentation/reports/subagentReportRegistry.d.ts +58 -0
- package/dist/types/presentation/useAIModelCatalog.d.ts +9 -0
- package/dist/types/presentation/useAgent.d.ts +140 -0
- package/dist/types/presentation/useAgenticoPageContext.d.ts +12 -0
- package/dist/types/presentation/useSubagentComponentContext.d.ts +44 -0
- package/llms.txt +35 -0
- package/package.json +79 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ComponentType } from 'react';
|
|
2
|
+
/** Booleano = includi/escludi (colori, font — un solo valore risolto per chiave, niente tra cui
|
|
3
|
+
* scegliere). Stringa = candidato scelto per uno slot con più opzioni recuperate (logo/favicon/
|
|
4
|
+
* OG image — '' significa "Nessuno"). Vedi LiquidResultReport per l'uso concreto (theme non ha
|
|
5
|
+
* più un report qui: il risultato popola direttamente il ThemeEditor aperto, vedi
|
|
6
|
+
* SubagentRunner.componentAnchors — nessuna selezione intermedia). */
|
|
7
|
+
export type SubagentSelection = Record<string, boolean | string>;
|
|
8
|
+
/** Un subagent "a selezione" (branding, html-to-liquid): il risultato è generato UNA volta,
|
|
9
|
+
* l'utente sceglie solo quali campi/candidati includere prima di spedirlo a una destinazione —
|
|
10
|
+
* mai una modifica diretta del contenuto del risultato. */
|
|
11
|
+
export interface SelectionReportModule<TResult = any> {
|
|
12
|
+
kind: 'selection';
|
|
13
|
+
Report: ComponentType<{
|
|
14
|
+
result: TResult;
|
|
15
|
+
selection: SubagentSelection;
|
|
16
|
+
onChange: (key: string, value: boolean | string) => void;
|
|
17
|
+
}>;
|
|
18
|
+
/** Solo le chiavi per campi effettivamente presenti nel risultato — l'assenza di una chiave
|
|
19
|
+
* significa "nessuna checkbox per questo campo", non "deselezionato". Parte sempre a true
|
|
20
|
+
* (comportamento opt-out, come il vecchio flusso di import pre-AI). */
|
|
21
|
+
defaultSelection(result: TResult): SubagentSelection;
|
|
22
|
+
/** Copia di result con i campi deselezionati azzerati/filtrati — usata SOLO per alimentare
|
|
23
|
+
* ResultDestinationPicker, mai per il Report stesso (che mostra sempre il result grezzo +
|
|
24
|
+
* stato checkbox, altrimenti un campo deselezionato sparirebbe invece di restare spuntabile). */
|
|
25
|
+
applySelection(result: TResult, selection: SubagentSelection): TResult;
|
|
26
|
+
}
|
|
27
|
+
/** Un subagent "editabile": il risultato STESSO è l'oggetto che l'utente continua a modificare
|
|
28
|
+
* nel tempo (righe di una griglia, non un opt-in/opt-out su campi noti a priori) — non c'è nulla
|
|
29
|
+
* da "filtrare" prima di una destinazione. Il `Report` di un modulo così presuppone SEMPRE un
|
|
30
|
+
* `<Form>` vivo intorno a sé (i suoi campi editabili sono `Input`/`Select` legati a
|
|
31
|
+
* `useFormContext`) — per questo NON va registrato qui se quel Form lo possiede già un componente
|
|
32
|
+
* component-anchor sempre montato (es. redirects: `RedirectsEditor` monta il proprio Report
|
|
33
|
+
* dentro il proprio `<Form>` con un import diretto, mai tramite questo registro). Registrarlo qui
|
|
34
|
+
* lo esporrebbe ANCHE al fallback "nessun anchor vivo" di SubagentRunner (vedi sotto), che lo
|
|
35
|
+
* renderizza SENZA alcun Form intorno — crash reale osservato (`useFormContext must be used
|
|
36
|
+
* within a FormContext.Provider`, root-caused a redirects registrato qui mentre l'utente naviga
|
|
37
|
+
* via dall'editor senza salvare: un task ancora vivo con un risultato in sospeso, nessun anchor
|
|
38
|
+
* per riceverlo, fallback che monta il Report nudo). Un modulo "editabile" appartiene qui SOLO se
|
|
39
|
+
* il subagent NON garantisce un componente-anchor sempre vivo per ricevere il risultato. */
|
|
40
|
+
export interface EditableReportModule<TResult = any> {
|
|
41
|
+
kind: 'editable';
|
|
42
|
+
Report: ComponentType<{
|
|
43
|
+
result: TResult;
|
|
44
|
+
onResultChange: (next: TResult) => void;
|
|
45
|
+
}>;
|
|
46
|
+
}
|
|
47
|
+
/** Registro presentation-side per id di subagent (stesso principio filesystem-first/id-keyed di
|
|
48
|
+
* destinationRegistry.ts) — MAI un campo su SubagentManifest: quel
|
|
49
|
+
* contratto vive nel domain layer, presentation-agnostico per design (nessun file in domain/
|
|
50
|
+
* importa React in questo repo), mentre un report è JSX puro. Un subagent senza voce qui
|
|
51
|
+
* semplicemente non mostra nessun report nel fallback "nessun anchor vivo" di SubagentRunner —
|
|
52
|
+
* comportamento identico a oggi per redirects (il suo report vive SOLO dentro RedirectsEditor,
|
|
53
|
+
* mai qui, vedi il commento su EditableReportModule sopra), mai un errore.
|
|
54
|
+
* Estendere per un futuro subagent: un modulo + una riga qui SOLO se non ha un componente-anchor
|
|
55
|
+
* sempre vivo che possa possedere il proprio Form. */
|
|
56
|
+
export type SubagentReportModule<TResult = any> = SelectionReportModule<TResult> | EditableReportModule<TResult>;
|
|
57
|
+
export declare function registerSubagentReports(reports: Record<string, SubagentReportModule>): void;
|
|
58
|
+
export declare function getSubagentReport(subagentId: string): SubagentReportModule | undefined;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AIModelDescriptor } from '@llmnative/react';
|
|
2
|
+
export interface UseAIModelCatalogResult {
|
|
3
|
+
hasProviders: boolean;
|
|
4
|
+
modelsByProvider: Record<string, AIModelDescriptor[]>;
|
|
5
|
+
modelsLoading: boolean;
|
|
6
|
+
selectedModel: string;
|
|
7
|
+
setSelectedModel: (id: string) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function useAIModelCatalog(): UseAIModelCatalogResult;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { AIConversationTurn, AIModelDescriptor } from '@llmnative/react';
|
|
2
|
+
import type { AgentDefinition } from '../domain/agentDefinition';
|
|
3
|
+
/** Una voce del log di attività — o un messaggio dell'utente (il testo di sendMessage(),
|
|
4
|
+
* mostrato subito com'è, mai "sto pensando" perché non è il modello a scriverlo), o una tool
|
|
5
|
+
* call (etichetta SEMPRE deterministica/locale, vedi AgentTool.describeInvocation: mai testo
|
|
6
|
+
* generato chiedendo al modello di narrare se stesso, name+input sono già strutturati nella
|
|
7
|
+
* risposta del provider — stesso approccio degli IDE agentici, che renderizzano le tool call
|
|
8
|
+
* dal client, non dal testo del modello), o un turno "sto pensando" (una chiamata al modello,
|
|
9
|
+
* testo libero in `detail` — QUESTO è l'unico testo scritto davvero dal modello nel log,
|
|
10
|
+
* collassato a una riga dal chiamante). */
|
|
11
|
+
export interface AgentActivityEntry {
|
|
12
|
+
id: string;
|
|
13
|
+
/** 'user' = il testo passato a sendMessage(), mostrato come bolla di chat (vedi
|
|
14
|
+
* AgentActivityLog). 'thinking' = una chiamata al modello (etichetta transitoria, vedi
|
|
15
|
+
* AgentActivityLog: "Sto pensando…" mentre gira, sostituita da un'anteprima di `detail` a
|
|
16
|
+
* risposta arrivata — mai testo che persiste invariato). 'tool' = una tool call,
|
|
17
|
+
* etichetta sempre statica (AgentTool.describeInvocation). */
|
|
18
|
+
kind: 'user' | 'thinking' | 'tool';
|
|
19
|
+
label: string;
|
|
20
|
+
status: 'running' | 'done' | 'error' | 'stopped';
|
|
21
|
+
/** Sui turni "sto pensando" — il testo che il modello ha scritto in quel turno (commento
|
|
22
|
+
* prima di un tool_calls, o la risposta finale). Sui messaggi utente — il testo inviato
|
|
23
|
+
* a sendMessage(), integrale (non troncato, non collassabile: è già quello che l'utente
|
|
24
|
+
* ha scritto, non c'è "ragionamento" da nascondere dietro un collapse). */
|
|
25
|
+
detail?: string;
|
|
26
|
+
/** Solo sui turni "sto pensando" che hanno richiesto tool_calls SENZA testo libero
|
|
27
|
+
* (`detail` assente) — le frasi discorsive (deterministiche, vedi AgentTool.describeIntent)
|
|
28
|
+
* sullo SCOPO GENERALE dei tool che quel turno sta per invocare (mai i parametri della
|
|
29
|
+
* chiamata specifica, quelli sono già sulla riga della tool call sotto — vedi
|
|
30
|
+
* describeIntent per il perché) cosi la UI dice qualcosa di concreto invece del generico
|
|
31
|
+
* "Richiesta di eseguire dei tool" (vedi thinkingDisplayLabel in AgentActivityLog.tsx). */
|
|
32
|
+
toolNames?: string[];
|
|
33
|
+
/** Solo su 'user' — nomi dei file allegati a QUESTO messaggio (run()/sendMessage()
|
|
34
|
+
* opts.attachments), mostrati come pillole sopra il testo (vedi AgentActivityLog) — senza,
|
|
35
|
+
* l'utente non ha modo di verificare "ho davvero attaccato quel file?" scorrendo indietro,
|
|
36
|
+
* doveva fidarsi a memoria (bug osservato: un allegato sembrava "sparito" perché non
|
|
37
|
+
* c'era traccia visiva che fosse mai arrivato). */
|
|
38
|
+
attachmentNames?: string[];
|
|
39
|
+
}
|
|
40
|
+
/** Stato di gating/selezione — non generico, condiviso dal componente <AgentControls />
|
|
41
|
+
* (che non ha bisogno di conoscere TParams/TResult, solo di disegnare switch + select). */
|
|
42
|
+
export interface AgentControlState {
|
|
43
|
+
enabled: boolean;
|
|
44
|
+
setEnabled: (v: boolean) => void;
|
|
45
|
+
hasProviders: boolean;
|
|
46
|
+
selectedModel: string;
|
|
47
|
+
setSelectedModel: (id: string) => void;
|
|
48
|
+
modelsByProvider: Record<string, AIModelDescriptor[]>;
|
|
49
|
+
modelsLoading: boolean;
|
|
50
|
+
}
|
|
51
|
+
export interface UseAgentResult<TParams, TResult> extends AgentControlState {
|
|
52
|
+
running: boolean;
|
|
53
|
+
error: string | null;
|
|
54
|
+
/** true dopo che run() ha eseguito almeno un turno con AI abilitata — solo allora la
|
|
55
|
+
* conversazione ha una history su cui sendMessage() può continuare. */
|
|
56
|
+
canContinue: boolean;
|
|
57
|
+
/** Log delle tool call della sessione corrente, più recenti in fondo — azzerato a ogni
|
|
58
|
+
* run(), accumulato attraverso i sendMessage() successivi. */
|
|
59
|
+
activity: AgentActivityEntry[];
|
|
60
|
+
/** Esegue il controller (sempre) e, se abilitato e disponibile un provider, il prompt
|
|
61
|
+
* dell'agente. Ritorna `null` solo se il controller stesso fallisce (es. fetch di rete) —
|
|
62
|
+
* in ogni altro caso ritorna almeno il fallback deterministico dell'agente. Avvia una
|
|
63
|
+
* nuova sessione conversazionale (azzera la history di eventuali run precedenti).
|
|
64
|
+
* `opts.attachments` — file allegati dall'utente al messaggio di apertura, convertiti in
|
|
65
|
+
* `AIAttachment` (`PromptUtils.fileToAttachment`) e passati al provider — è il provider
|
|
66
|
+
* stesso (react/src/providers/ai/*) a decidere se un mimetype testuale va decodificato e
|
|
67
|
+
* inserito come blocco di testo o trattato come documento nativo (CR-071bis): questo hook
|
|
68
|
+
* non fa più quella distinzione, per non duplicare una logica che deve restare unica e
|
|
69
|
+
* per-provider dentro il framework. `opts.model` — sovrascrive
|
|
70
|
+
* `selectedModel` SOLO per questa chiamata (mai una `setSelectedModel` seguita subito da
|
|
71
|
+
* `run()`: lo stato React non sarebbe ancora committato nello stesso tick — vedi Chatbot
|
|
72
|
+
* in Agentico.tsx, che riporta il modello scelto nel payload di ogni submit invece di
|
|
73
|
+
* affidarsi a un `setSelectedModel` sincrono). `opts.openingMessage` — testo da mostrare
|
|
74
|
+
* SUBITO come bolla "Tu" in cima all'activity log (stesso trattamento del testo di
|
|
75
|
+
* sendMessage(), vedi sotto): senza, il messaggio che ha avviato la conversazione (es. il
|
|
76
|
+
* goal scritto nel composer "starter" di Agentico, magari con un allegato) non appariva mai
|
|
77
|
+
* nel log — solo i turni di sendMessage() successivi lo facevano, rendendo il primo
|
|
78
|
+
* messaggio "invisibile" e facile da dimenticare fosse mai stato inviato (bug osservato).
|
|
79
|
+
* Opzionale perché non ogni chiamante di run() è una chat (es. i subagent lanciati da
|
|
80
|
+
* modale/form come theme/html-to-liquid non hanno un "messaggio utente" testuale da
|
|
81
|
+
* mostrare). */
|
|
82
|
+
run: (params: TParams, opts?: {
|
|
83
|
+
attachments?: File[];
|
|
84
|
+
model?: string;
|
|
85
|
+
openingMessage?: string;
|
|
86
|
+
}) => Promise<TResult | null>;
|
|
87
|
+
/** Continua la conversazione avviata da run() con un messaggio dell'utente — il modello
|
|
88
|
+
* può invocare i tool dell'agente con i parametri suggeriti nel messaggio. Richiede che
|
|
89
|
+
* run() sia già stato eseguito con AI abilitata (altrimenti `error` viene impostato).
|
|
90
|
+
* `opts` — stesso trattamento di run(), vedi sopra. */
|
|
91
|
+
sendMessage: (text: string, opts?: {
|
|
92
|
+
attachments?: File[];
|
|
93
|
+
model?: string;
|
|
94
|
+
}) => Promise<TResult | null>;
|
|
95
|
+
/** Interrompe il turno in corso (run() o sendMessage()) — annulla la chiamata AI
|
|
96
|
+
* attualmente in volo. Nessun effetto se non c'è nulla in corso. Le tool call già in
|
|
97
|
+
* esecuzione in quel momento completano comunque (sono fetch brevi); il turno si ferma
|
|
98
|
+
* al prossimo checkpoint (subito se si stava aspettando il modello, altrimenti dopo che
|
|
99
|
+
* il round di tool in corso ha finito). */
|
|
100
|
+
stop: () => void;
|
|
101
|
+
/** Ricarica una sessione già esistente (vedi entityChatStore/AgenticoContext.resumeEntityChat)
|
|
102
|
+
* invece di iniziarne una nuova — NON invia alcun prompt al modello, si limita a ricostruire
|
|
103
|
+
* context/tools (via buildContext/getTools, come run()) e a installare `seed.history`/
|
|
104
|
+
* `seed.activity` cosi un sendMessage() successivo continui esattamente come se la
|
|
105
|
+
* conversazione non fosse mai stata interrotta. `params` deve avere la stessa forma con cui
|
|
106
|
+
* la sessione originale era stata avviata (lo stesso TParams grezzo salvato nello snapshot). */
|
|
107
|
+
resume: (params: TParams, seed: {
|
|
108
|
+
history: AIConversationTurn[];
|
|
109
|
+
activity: AgentActivityEntry[];
|
|
110
|
+
}) => Promise<void>;
|
|
111
|
+
/** Esegue direttamente il fallback deterministico dell'agente, bypassando l'AI — per il
|
|
112
|
+
* bottone "Continua senza AI" mostrato accanto a "Riprova" quando la chiamata al modello
|
|
113
|
+
* fallisce (rete/provider giù, non una risposta non valida: quel caso ricade già da solo
|
|
114
|
+
* sul fallback dentro runTurn). Richiede che run() sia già stato eseguito almeno una volta
|
|
115
|
+
* in questa sessione (altrimenti non c'è `params`/`context` da cui derivarlo) — `null` se
|
|
116
|
+
* chiamato prima. Sincrono: `AgentDefinition.fallback` non è mai una Promise (è sempre
|
|
117
|
+
* derivato da `buildContext`, già risolto a questo punto). */
|
|
118
|
+
runFallback: () => TResult | null;
|
|
119
|
+
/** Foto corrente, serializzabile, della conversazione — `history` (turni grezzi
|
|
120
|
+
* `AIConversationTurn[]`, dato puro senza funzioni/riferimenti al provider) più `activity`
|
|
121
|
+
* (lo stesso log mostrato in UI). Usata da AgenticoContext.commitEntityChat per persistere
|
|
122
|
+
* la chat che ha prodotto un'entità appena salvata (vedi entityChatStore) — a differenza di
|
|
123
|
+
* `activity` da solo, `history` è ciò che serve per un vero resume (un nuovo giro può
|
|
124
|
+
* continuare la conversazione col modello, non solo mostrarne il transcript in sola
|
|
125
|
+
* lettura). `null` se run() non è mai stato eseguito in questa sessione. Una funzione, non
|
|
126
|
+
* un valore memoizzato: deve leggere `sessionRef`/`activity` correnti al momento della
|
|
127
|
+
* chiamata (tipicamente un click su Salva, molto dopo l'ultimo turno), mai una chiusura
|
|
128
|
+
* stantia catturata al mount. */
|
|
129
|
+
snapshot: () => {
|
|
130
|
+
history: AIConversationTurn[];
|
|
131
|
+
activity: AgentActivityEntry[];
|
|
132
|
+
} | null;
|
|
133
|
+
}
|
|
134
|
+
/** Solo la fetta di UseAgentResult che serve a un consumer del pannello globale (Agentico.tsx)
|
|
135
|
+
* per continuare una conversazione già avviata da run() — TParams non compare in nessuno dei
|
|
136
|
+
* membri qui sotto, quindi `never` è innocuo. */
|
|
137
|
+
export type AgentConversation<TResult> = Pick<UseAgentResult<never, TResult>, 'canContinue' | 'running' | 'error' | 'activity' | 'sendMessage' | 'stop' | 'runFallback' | 'snapshot'>;
|
|
138
|
+
export declare function useAgent<TParams, TContext, TResult>(definition: AgentDefinition<TParams, TContext, TResult>, options?: {
|
|
139
|
+
defaultEnabled?: boolean;
|
|
140
|
+
}): UseAgentResult<TParams, TResult>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SubagentUsageCard } from '../domain/subagentUsageCard';
|
|
2
|
+
/** Registra "dove si trova l'utente adesso" per Agentico — stesso pattern effect-based di
|
|
3
|
+
* usePageBreadcrumb/usePageLeading (PageActionsContext.tsx): si registra al mount, si toglie da
|
|
4
|
+
* solo allo smontaggio. Più istanze possono essere montate insieme (es. ToolsPage generico +
|
|
5
|
+
* ToolHistoryPanel specifico sopra) — vince l'ultima registrata, vedi AgenticoContext.setPageContext.
|
|
6
|
+
* `text === null` non registra nulla (utile per un contesto calcolato che a volte non è pronto).
|
|
7
|
+
* `card` — opzionale, SOLO per la UI del pannello Agentico (vedi Agentico.tsx): quando presente
|
|
8
|
+
* rimpiazza il paragrafo di prosa con una card strutturata (campi richiesti/opzionali), mentre
|
|
9
|
+
* `text` resta comunque quello che arriva al prompt dell'orchestratore (vedi
|
|
10
|
+
* AgenticoContext.pageContext) — due destinazioni diverse dello stesso "dove si trova l'utente",
|
|
11
|
+
* mai lo stesso testo forzato a servire entrambe. */
|
|
12
|
+
export declare function useAgenticoPageContext(text: string | null, card?: SubagentUsageCard | null): void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Registra "questo componente è il subagent X" per Agentico — chiamato DAL componente
|
|
2
|
+
* portabile stesso (es. ThemeIndexList/ThemeEditor), mai dalla pagina che lo ospita: chi monta
|
|
3
|
+
* il componente ottiene gratis il contesto/hint/scoping corretto, senza ricostruirlo pagina per
|
|
4
|
+
* pagina (vedi ../domain/subagentManifest.ts SubagentManifest.componentContexts per
|
|
5
|
+
* dove vivono `agenticoHint`/`userMessage`).
|
|
6
|
+
*
|
|
7
|
+
* `componentKey` deve combaciare con una chiave di `manifest.componentContexts` — se non
|
|
8
|
+
* combacia, l'anchor si registra comunque (per `onResult`) ma senza hint/messaggio (nessun
|
|
9
|
+
* crash, solo nessun aggancio di prosa per l'LLM/l'utente).
|
|
10
|
+
*
|
|
11
|
+
* `onResult`, opzionale — chiamato da SubagentRunner quando arriva un risultato per questo
|
|
12
|
+
* `subagentId` MENTRE questo componente è montato: il componente popola se stesso (Form/stato
|
|
13
|
+
* locale), mai un salvataggio automatico — l'utente resta libero di rivedere e premere Salva
|
|
14
|
+
* come per un edit manuale. `meta` è il TParams con cui il subagent è stato lanciato (es.
|
|
15
|
+
* `{ url }` per theme) — utile quando il risultato stesso non porta un dato che serve per
|
|
16
|
+
* popolare il componente (es. l'URL sorgente, per derivare un nome di default). `taskId` è l'id
|
|
17
|
+
* del task Agentico che ha prodotto questo risultato — un componente che vuole poter persistere
|
|
18
|
+
* la chat al proprio salvataggio (vedi AgenticoContext.commitEntityChat) lo tiene da parte in un
|
|
19
|
+
* ref, altrimenti può ignorarlo. Anche una pagina
|
|
20
|
+
* non-portabile (es. SiteEditorPage, per i soli campi di site-branding dentro lo stesso
|
|
21
|
+
* risultato) può chiamare questo hook con lo stesso `subagentId` di un componente già montato —
|
|
22
|
+
* più listener indipendenti sullo stesso risultato, ciascuno responsabile della propria fetta di
|
|
23
|
+
* dati. */
|
|
24
|
+
export declare function useSubagentComponentContext(subagentId: string, componentKey: string, onResult?: (result: unknown, meta: Record<string, unknown>, taskId: string) => void,
|
|
25
|
+
/** Fatti live sull'entità che QUESTA istanza ha aperta ORA (es. `Il tema aperto si chiama
|
|
26
|
+
* "ducatimilano.it".`) — accodati all'agenticoHint statico del manifest nel prompt
|
|
27
|
+
* dell'orchestratore (vedi AgenticoContext.anchorTexts), cosi un "estrai il tema" senza URL
|
|
28
|
+
* esplicito può dedurlo dal nome/hostname già noto invece di richiederlo sempre da capo.
|
|
29
|
+
* Assente/undefined = comportamento invariato. A differenza di `onResult` (in un ref, mai
|
|
30
|
+
* causa di ri-registrazione) QUESTO è una dipendenza vera dell'effect sotto: deve
|
|
31
|
+
* ri-registrare quando cambia (es. il nome dell'entità arriva dopo un fetch asincrono). */
|
|
32
|
+
contextInfo?: string,
|
|
33
|
+
/** `false` = non registra nulla (o smonta l'anchor già registrato) — per un componente che
|
|
34
|
+
* resta montato anche quando "non è più lui" ad ancorarsi (es. RedirectsIndexList, che non
|
|
35
|
+
* smonta quando mostra il dettaglio di un host: senza questo, il suo anchor 'indexList'
|
|
36
|
+
* resterebbe attivo ANCHE mentre RedirectsEditor registra 'editor' per lo stesso
|
|
37
|
+
* subagentId, consegnando un risultato a entrambi). Default `true` — comportamento invariato
|
|
38
|
+
* per chi non lo passa. */
|
|
39
|
+
enabled?: boolean,
|
|
40
|
+
/** Id dell'entità a cui QUESTA istanza è vincolata (es. l'hostId di RedirectsEditor) — vedi
|
|
41
|
+
* ComponentAnchor.pinnedEntityId per il perché (backstop deterministico contro un salvataggio
|
|
42
|
+
* su un'entità sbagliata, non solo un'istruzione nel prompt). Assente = nessun vincolo,
|
|
43
|
+
* comportamento invariato. */
|
|
44
|
+
pinnedEntityId?: string): void;
|
package/llms.txt
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
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.
|
|
10
|
+
- `registerDestinations({ id: ResultDestination })` — apply(result, { scopeId, dataProvider, storageProvider, proxyFetch }, meta).
|
|
11
|
+
- `registerSubagentReports({ subagentId: SubagentReportModule })`.
|
|
12
|
+
- `registerCrossAgentTools((ctx) => AgentTool[])` — ctx: attachmentsRef, collected (per-conversation scratchpad), proxyFetch.
|
|
13
|
+
- `configureAgenticoPrompts(partial)` — model-facing pack; `agenticoPromptsEn` (default) / `agenticoPromptsIt`.
|
|
14
|
+
- `configureEntityChatStore({ storageKey })`.
|
|
15
|
+
- i18n: merge `agenticoTranslations.<locale>` into `<App i18n={{ translations }}>`; override any `agentico.*` key.
|
|
16
|
+
|
|
17
|
+
## Mount
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
<AgenticoProvider scope={{ id, dataProvider, storageProvider } | null}>
|
|
21
|
+
<AgenticoToggle />
|
|
22
|
+
<Agentico />
|
|
23
|
+
</AgenticoProvider>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Hooks
|
|
27
|
+
|
|
28
|
+
- `useAgentico()` — panel state, `startOrchestrator(goal, opts)`, `commitEntityChat(subagentId, entityId, taskId, scopeId, params, title)`, `scope`.
|
|
29
|
+
- `useAgenticoPageContext(text, card?)` — what the user is looking at.
|
|
30
|
+
- `useSubagentComponentContext(subagentId, componentKey)` — anchor a component to a subagent.
|
|
31
|
+
- `useAgent(definition)` — run an AgentDefinition directly.
|
|
32
|
+
|
|
33
|
+
## AgentDefinition
|
|
34
|
+
|
|
35
|
+
buildContext (always runs) · buildPrompt · buildFollowUpPrompt · parseResponse (null → fallback) · fallback (required) · describeFallback? · getTools? · microPromptIds?
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@llmnative/agentico",
|
|
3
|
+
"version": "0.1.0",
|
|
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
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/types/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"llms.txt"
|
|
18
|
+
],
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "vite build && tsc -p tsconfig.build.json",
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"test:watch": "vitest",
|
|
25
|
+
"prepublishOnly": "npm run build",
|
|
26
|
+
"release:check": "node scripts/release/check-release.mjs"
|
|
27
|
+
},
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/sherpadvisorylab/llmnative-agentico.git"
|
|
31
|
+
},
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/sherpadvisorylab/llmnative-agentico/issues"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://github.com/sherpadvisorylab/llmnative-agentico#readme",
|
|
36
|
+
"keywords": [
|
|
37
|
+
"llmnative",
|
|
38
|
+
"agent",
|
|
39
|
+
"orchestrator",
|
|
40
|
+
"subagent",
|
|
41
|
+
"ai",
|
|
42
|
+
"react"
|
|
43
|
+
],
|
|
44
|
+
"author": "wolfgan",
|
|
45
|
+
"license": "Apache-2.0",
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=24.18.0 <25"
|
|
48
|
+
},
|
|
49
|
+
"packageManager": "npm@11.11.0",
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"@llmnative/react": "^1.20.0",
|
|
52
|
+
"react": "^19.2.0",
|
|
53
|
+
"react-dom": "^19.2.0",
|
|
54
|
+
"zod": "^3.24.1"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"zod-to-json-schema": "^3.24.1"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@llmnative/react": "^1.20.0",
|
|
61
|
+
"@phosphor-icons/react": "^2.1.10",
|
|
62
|
+
"@testing-library/jest-dom": "^7.0.1",
|
|
63
|
+
"@testing-library/react": "^16.3.3",
|
|
64
|
+
"@types/react": "^19.3.0",
|
|
65
|
+
"@types/react-dom": "^19.3.0",
|
|
66
|
+
"happy-dom": "^20.14.5",
|
|
67
|
+
"lucide-react": "^1.52.0",
|
|
68
|
+
"react": "^19.3.0",
|
|
69
|
+
"react-dom": "^19.3.0",
|
|
70
|
+
"react-router-dom": "^7.18.4",
|
|
71
|
+
"typescript": "^7.0.2",
|
|
72
|
+
"vite": "^8.3.2",
|
|
73
|
+
"vitest": "^5.0.3",
|
|
74
|
+
"zod": "^3.24.1"
|
|
75
|
+
},
|
|
76
|
+
"publishConfig": {
|
|
77
|
+
"access": "public"
|
|
78
|
+
}
|
|
79
|
+
}
|