@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,55 @@
|
|
|
1
|
+
export interface AgenticoDict {
|
|
2
|
+
modelLabel: string;
|
|
3
|
+
modelsLoading: string;
|
|
4
|
+
noModelsAvailable: string;
|
|
5
|
+
noProviderConnected: string;
|
|
6
|
+
selectModelPlaceholder: string;
|
|
7
|
+
orchestratorStarterHint: string;
|
|
8
|
+
orchestratorStarterPlaceholder: string;
|
|
9
|
+
destinationPickerTitle: string;
|
|
10
|
+
destinationApplying: string;
|
|
11
|
+
destinationNoScope: string;
|
|
12
|
+
exportJson: string;
|
|
13
|
+
/** `{id}` = destination id */
|
|
14
|
+
unknownDestination: string;
|
|
15
|
+
orchestratorUnavailable: string;
|
|
16
|
+
orchestratorContinueWithoutAi: string;
|
|
17
|
+
/** `{label}` = subagent label */
|
|
18
|
+
orchestratorPreparing: string;
|
|
19
|
+
/** `{label}` = subagent label */
|
|
20
|
+
orchestratorCollecting: string;
|
|
21
|
+
thinking: string;
|
|
22
|
+
stopped: string;
|
|
23
|
+
toolRequest: string;
|
|
24
|
+
modelRequestError: string;
|
|
25
|
+
noProviderResponse: string;
|
|
26
|
+
noActiveSession: string;
|
|
27
|
+
requestInProgress: string;
|
|
28
|
+
invalidResponse: string;
|
|
29
|
+
responseReceived: string;
|
|
30
|
+
noProviderAvailable: string;
|
|
31
|
+
tooManyToolTurns: string;
|
|
32
|
+
aiDisabledFallback: string;
|
|
33
|
+
continueWithoutAiFallback: string;
|
|
34
|
+
/** `{label}` = subagent label */
|
|
35
|
+
newInstance: string;
|
|
36
|
+
chatHistory: string;
|
|
37
|
+
newChat: string;
|
|
38
|
+
searchChats: string;
|
|
39
|
+
messagePlaceholder: string;
|
|
40
|
+
unsavedConversationConfirm: string;
|
|
41
|
+
noSavedChats: string;
|
|
42
|
+
noResults: string;
|
|
43
|
+
retry: string;
|
|
44
|
+
/** User message sent to the model by the retry button */
|
|
45
|
+
retryMessage: string;
|
|
46
|
+
continueWithoutAi: string;
|
|
47
|
+
resumeWithAi: string;
|
|
48
|
+
openPanel: string;
|
|
49
|
+
closePanel: string;
|
|
50
|
+
}
|
|
51
|
+
declare module '@llmnative/react' {
|
|
52
|
+
interface I18nDict {
|
|
53
|
+
agentico: AgenticoDict;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import './i18n/types';
|
|
2
|
+
export type { AgentDefinition, AgentTool, LatestAttachmentsRef } from './domain/agentDefinition';
|
|
3
|
+
export type { SubagentCommand, SubagentManifest, SubagentComponentContext } from './domain/subagentManifest';
|
|
4
|
+
export { defineSubagent } from './domain/defineSubagent';
|
|
5
|
+
export { registerSubagents, getSubagentRegistry, findSubagentManifest } from './domain/subagentRegistry';
|
|
6
|
+
export { registerCrossAgentTools, createCrossAgentTools, type CrossAgentToolContext, type CrossAgentToolFactory } from './domain/crossAgentTools';
|
|
7
|
+
export { toJsonSchema, toMcpTool, type McpTool } from './domain/mcpTool';
|
|
8
|
+
export { renderSubagentCli, renderRegistryCli } from './domain/cli/renderManifestCli';
|
|
9
|
+
export { applyMicroPrompts, MICRO_PROMPT_REGISTRY, SUMMARY_MICRO_PROMPT } from './domain/microPrompts';
|
|
10
|
+
export type { MicroPrompt } from './domain/microPrompts';
|
|
11
|
+
export { configureAgenticoPrompts, getAgenticoPrompts, resetAgenticoPrompts, agenticoPromptsEn, agenticoPromptsIt, type AgenticoPrompts, } from './domain/prompts';
|
|
12
|
+
export { extractErrorMessage } from './domain/extractErrorMessage';
|
|
13
|
+
export { extractJsonBlock } from './domain/extractJsonBlock';
|
|
14
|
+
export type { ResultDestination, DestinationContext, ResultDestinationOutcome } from './domain/resultDestination';
|
|
15
|
+
export { jsonExportDestination, JSON_EXPORT_DESTINATION_ID } from './domain/jsonExportDestination';
|
|
16
|
+
export { registerDestinations, getDestinationRegistry } from './domain/destinationRegistry';
|
|
17
|
+
export { configureEntityChatStore, saveEntityChat, getEntityChat, listEntityChats, removeEntityChat, type EntityChatSnapshot, } from './domain/entityChatStore';
|
|
18
|
+
export { agenticoTranslations, agenticoEn, agenticoIt, agenticoDe, useAgenticoI18n, type AgenticoDict } from './i18n';
|
|
19
|
+
export { Agentico, AGENTICO_WIDTH } from './presentation/Agentico';
|
|
20
|
+
export { AgenticoToggle } from './presentation/AgenticoToggle';
|
|
21
|
+
export { AgenticoProvider, useAgentico, ORCHESTRATOR_TASK_ID, type AgenticoScope, type AgenticoTask, type ComponentAnchor, } from './presentation/AgenticoContext';
|
|
22
|
+
export { useAgent, type AgentActivityEntry, type AgentConversation, type UseAgentResult } from './presentation/useAgent';
|
|
23
|
+
export { useAgenticoPageContext } from './presentation/useAgenticoPageContext';
|
|
24
|
+
export { useSubagentComponentContext } from './presentation/useSubagentComponentContext';
|
|
25
|
+
export { registerSubagentReports, getSubagentReport, type EditableReportModule, type SubagentReportModule, type SubagentSelection, } from './presentation/reports/subagentReportRegistry';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { AgentActivityEntry } from './useAgent';
|
|
3
|
+
/** Il log di attività di un agente, usato dal pannello globale (Agentico) — ogni agente ora
|
|
4
|
+
* ci passa attraverso, il pannello embedded legacy (AgentFollowUp) è stato ritirato una volta
|
|
5
|
+
* migrato anche l'ultimo consumer (import HTML/JSX, vedi ComponentEditPage.tsx). Un solo posto
|
|
6
|
+
* per l'icon-system e la logica "sto pensando" transitorio/collassabile. */
|
|
7
|
+
export declare function AgentActivityLog({ activity }: {
|
|
8
|
+
activity: AgentActivityEntry[];
|
|
9
|
+
}): React.JSX.Element | null;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { AgentControlState } from './useAgent';
|
|
3
|
+
/** Switch + select modello per un agente useAgent — nato per evitare una duplicazione identica
|
|
4
|
+
* tra due modali di import legacy (tema in SiteEditorPage, HTML/JSX in ComponentEditPage),
|
|
5
|
+
* entrambe da allora ritirate in favore del flusso chat-only via Agentico (SubagentRunner,
|
|
6
|
+
* sempre AI-on, nessuno switch pre-run) — vedi il piano di unificazione. Nessun chiamante
|
|
7
|
+
* attuale nel CMS, tenuto come primitiva riusabile se un futuro flusso avesse di nuovo bisogno
|
|
8
|
+
* di uno switch AI on/off + selezione modello prima di eseguire. Accetta `AgentControlState`
|
|
9
|
+
* (non `UseAgentResult<T>` intero): non ha
|
|
10
|
+
* bisogno di conoscere il tipo di risposta del chiamante, solo lo stato di gating/selezione —
|
|
11
|
+
* TypeScript accetta struttalmente un `UseAgentResult<T>` qui senza cast.
|
|
12
|
+
*
|
|
13
|
+
* Switch a sinistra (non a destra come una prima versione, che schiacciava label/hint in una
|
|
14
|
+
* colonna stretta quando il testo "nessun provider" — non troncabile per `shrink-0` — occupava
|
|
15
|
+
* quasi tutta la larghezza): `min-w-0`+`truncate` qui tengono il testo su una riga sola, con
|
|
16
|
+
* `title` per il testo completo al passaggio del mouse se troncato. */
|
|
17
|
+
export declare function AgentControls({ agent, label, hint, disabledHint, forceSwitchDisabled, }: {
|
|
18
|
+
agent: AgentControlState;
|
|
19
|
+
label: string;
|
|
20
|
+
hint?: string;
|
|
21
|
+
disabledHint?: string;
|
|
22
|
+
/** Blocca lo switch acceso senza possibilità di spegnerlo (es. JSX che richiede AI
|
|
23
|
+
* obbligatoriamente) — il chiamante resta comunque responsabile di forzare
|
|
24
|
+
* `agent.setEnabled(true)`, questo prop riguarda solo l'interazione dello switch. */
|
|
25
|
+
forceSwitchDisabled?: boolean;
|
|
26
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/** Larghezza fissa del pannello — passata anche come `rightInset` alle Modal che devono
|
|
3
|
+
* lasciargli spazio invece di sovrapporlo (vedi Modal.rightInset nel framework). */
|
|
4
|
+
export declare const AGENTICO_WIDTH = 420;
|
|
5
|
+
/** Agentico — il pannello globale, persistente e non-overlay per le sessioni agente — affianca
|
|
6
|
+
* il CMS (che si stringe) invece di coprirlo, cosi la modale che ha avviato l'agente resta
|
|
7
|
+
* aperta e utilizzabile accanto. Header: titolo dell'UNICO task attivo (mai una tab bar — "una
|
|
8
|
+
* chat unica", decisione esplicita: avviarne uno nuovo sostituisce quello in corso, vedi
|
|
9
|
+
* AgenticoContext.openTask) — NESSUNA ×: si apre/chiude solo con AgenticoToggle (nell'Header del
|
|
10
|
+
* CMS, o come `closeSlot` di una Modal right), la stessa icona ovunque, mai una propria qui.
|
|
11
|
+
* Body: lo stesso log di attività del pannello embedded (AgentActivityLog), o un placeholder
|
|
12
|
+
* neutro se non c'è ancora nessun task — il pannello può restare aperto vuoto, non sparisce da
|
|
13
|
+
* solo quando il task finisce. Footer: il composer di follow-up (vedi AgenticoComposer sopra),
|
|
14
|
+
* nascosto quando non c'è un task attivo.
|
|
15
|
+
*
|
|
16
|
+
* Solo la sessione aperta in questa sessione browser (registry in memoria via AgenticoContext)
|
|
17
|
+
* — nessuna persistenza cross-sessione (Fase 3, deferita).
|
|
18
|
+
*
|
|
19
|
+
* Nota sul naming: "Agentico" è il nome dell'orchestratore — questo pannello, il suo contesto
|
|
20
|
+
* (AgenticoContext), il suo toggle (AgenticoToggle) — non degli agenti verticali che esegue
|
|
21
|
+
* (theme-import, html-to-liquid, ...), che restano nel proprio dominio senza questo
|
|
22
|
+
* prefisso: sono contenuto che Agentico orchestra, non parte della sua identità. */
|
|
23
|
+
export declare function Agentico(): React.JSX.Element;
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { AIModelDescriptor, DataProviderAdapter, StorageProviderAdapter } from '@llmnative/react';
|
|
3
|
+
import type { AgentActivityEntry, AgentConversation } from './useAgent';
|
|
4
|
+
import type { ResultDestination } from '../domain/resultDestination';
|
|
5
|
+
import type { SubagentUsageCard } from '../domain/subagentUsageCard';
|
|
6
|
+
import { type EntityChatSnapshot } from '../domain/entityChatStore';
|
|
7
|
+
/** Where results are saved and chats are kept: the host's current tenant, company, workspace…
|
|
8
|
+
* `null` while the host has none selected — destinations then refuse to save. */
|
|
9
|
+
export interface AgenticoScope {
|
|
10
|
+
id: string;
|
|
11
|
+
dataProvider: DataProviderAdapter;
|
|
12
|
+
storageProvider: StorageProviderAdapter | null;
|
|
13
|
+
}
|
|
14
|
+
/** Cattura la conversazione di un task subagent già esistente da "continuare" invece di forkare
|
|
15
|
+
* — vedi startOrchestrator sotto. `taskId` viene riusato dal nuovo SubagentRunner (invece di un
|
|
16
|
+
* uuid fresco) cosi il task esistente si aggiorna in place; `activity` (precedingActivity +
|
|
17
|
+
* agent.activity del vecchio task, già concatenati) viene prepesa al transcript del nuovo giro —
|
|
18
|
+
* l'utente legge tutto come UNA chat continua, mai due sessioni scollegate per lo stesso
|
|
19
|
+
* subagent. */
|
|
20
|
+
export interface PendingCarryOver {
|
|
21
|
+
taskId: string;
|
|
22
|
+
activity: AgentActivityEntry[];
|
|
23
|
+
}
|
|
24
|
+
/** Id fisso del task dell'orchestratore Agentico — al massimo UNA conversazione orchestratore
|
|
25
|
+
* per volta, come per qualunque altro task (vedi AgenticoTask sotto: un solo task alla volta in
|
|
26
|
+
* tutta l'app, mai una tab bar da switchare). Un id fisso permette a startOrchestrator() di
|
|
27
|
+
* riconoscere "ce n'è già uno aperto" senza dover tenere un riferimento separato. */
|
|
28
|
+
export declare const ORCHESTRATOR_TASK_ID = "agentico-orchestrator";
|
|
29
|
+
/** Una sessione agente aperta nel pannello globale — riferimento vivo all'oggetto restituito
|
|
30
|
+
* da useAgent() nel componente che l'ha avviata (NON una copia: quel componente deve restare
|
|
31
|
+
* montato perché questo riferimento resti valido, vedi Agentico.tsx). Solo le sessioni aperte in
|
|
32
|
+
* questa sessione browser — nessuna persistenza su Firestore (Fase 3, deferita).
|
|
33
|
+
*
|
|
34
|
+
* Al massimo UN task alla volta in tutta l'app (decisione esplicita: "una chat unica", niente
|
|
35
|
+
* tab multiple per run paralleli) — avviarne uno nuovo mentre un altro è in corso lo sostituisce
|
|
36
|
+
* (vedi openTask sotto), mai lo affianca. */
|
|
37
|
+
export interface AgenticoTask<TResult = unknown> {
|
|
38
|
+
id: string;
|
|
39
|
+
/** Titolo mostrato nell'header del pannello — es. l'URL importato, il nome del componente. */
|
|
40
|
+
title: string;
|
|
41
|
+
/** Nome icona (@llmnative/react Icon) mostrata nell'header — 'bot' per l'orchestratore
|
|
42
|
+
* (OrchestratorRunner, stessa identità di AgenticoToggle), manifest.icon per un subagent
|
|
43
|
+
* (SubagentRunner). */
|
|
44
|
+
icon: string;
|
|
45
|
+
/** SOLO sul task dell'orchestratore — id del subagent verso cui la pagina/componente che ha
|
|
46
|
+
* avviato questa conversazione era scoped (catturato da OrchestratorRunner al mount, da
|
|
47
|
+
* sidebar.scopedSubagentId). Permette a un indice come redirects/IndexList.tsx di mostrare
|
|
48
|
+
* "in corso" per QUESTO subagent anche prima dell'handoff (mentre l'orchestratore sta ancora
|
|
49
|
+
* raccogliendo parametri/chiamando tool di raccolta dati). Assente sui task dei subagent
|
|
50
|
+
* stessi (quelli sono già inequivocabilmente scoped dal proprio id
|
|
51
|
+
* `subagent-${subagentId}-...`). */
|
|
52
|
+
scopedSubagentId?: string;
|
|
53
|
+
/** Presente SOLO dopo un commitEntityChat riuscito su questo task — questa conversazione è
|
|
54
|
+
* genuinamente su disco (vedi entityChatStore), non solo in memoria. Usato dal bottone
|
|
55
|
+
* "nuova chat" (vedi Agentico.tsx) per decidere se avvertire l'utente prima di scartarla:
|
|
56
|
+
* senza salvataggio andrebbe persa per sempre (nessun "torna indietro", scelta esplicita). */
|
|
57
|
+
savedToDisk?: boolean;
|
|
58
|
+
agent: AgentConversation<TResult> & {
|
|
59
|
+
hasProviders: boolean;
|
|
60
|
+
selectedModel: string;
|
|
61
|
+
setSelectedModel: (id: string) => void;
|
|
62
|
+
modelsByProvider: Record<string, AIModelDescriptor[]>;
|
|
63
|
+
};
|
|
64
|
+
onApplied: (result: TResult) => void;
|
|
65
|
+
/** Transcript di UNA conversazione precedente da mostrare "prima" di `agent.activity` nello
|
|
66
|
+
* stesso log, senza soluzione di continuità — usato dal task del subagent per prependere la
|
|
67
|
+
* conversazione dell'orchestratore che lo ha invocato (vedi OrchestratorRunner/SubagentRunner):
|
|
68
|
+
* l'utente deve vivere Agentico come UNA chat discorsiva unica, mai accorgersi che ci sono
|
|
69
|
+
* due "attori" distinti dietro le quinte. */
|
|
70
|
+
precedingActivity?: AgentActivityEntry[];
|
|
71
|
+
/** Contenuto extra renderizzato nel body del pannello, sotto il log di attività (es.
|
|
72
|
+
* ResultDestinationPicker una volta che un subagent ha prodotto un risultato senza un
|
|
73
|
+
* componente vivo ad ascoltarlo — vedi SubagentRunner). Deve restare dentro il pannello
|
|
74
|
+
* Agentico, non un elemento reso altrove nell'albero: chi possiede il task
|
|
75
|
+
* (SubagentRunner/OrchestratorRunner) è montato come sibling PRIMA del pannello visibile in
|
|
76
|
+
* Agentico.tsx (per sopravvivere al toggle di isOpen), quindi il proprio JSX di ritorno
|
|
77
|
+
* finirebbe fuori dal pannello se non passato tramite questo slot esplicito. */
|
|
78
|
+
panelExtra?: React.ReactNode;
|
|
79
|
+
/** Presente SOLO sul task di un ManualEntryRunner — quando impostato, AgenticoComposer
|
|
80
|
+
* (Agentico.tsx) instrada il testo digitato QUI invece che ad `agent.sendMessage`: niente
|
|
81
|
+
* chiamata AI, `onSubmit` costruisce i TParams dal testo grezzo e avvia il subagent con
|
|
82
|
+
* l'AI disabilitata (vedi SubagentManifest.manualEntry). `prompt` è il messaggio statico
|
|
83
|
+
* mostrato quando non c'è ancora nessuna attività (invece del solito pageContext/hint). */
|
|
84
|
+
manualEntry?: {
|
|
85
|
+
prompt: string;
|
|
86
|
+
onSubmit: (rawText: string) => void;
|
|
87
|
+
};
|
|
88
|
+
/** Quante voci di `precedingActivity + agent.activity` (in ordine, vedi Agentico.tsx)
|
|
89
|
+
* precedono `panelExtra` nella timeline — cioè QUANTE erano già maturate quando il
|
|
90
|
+
* risultato mostrato in panelExtra è stato prodotto. Senza questo indice, panelExtra veniva
|
|
91
|
+
* sempre reso dopo l'INTERO log corrente, quindi ogni messaggio di follow-up successivo
|
|
92
|
+
* (es. un retry finito in errore) appariva SOPRA un risultato che in realtà era arrivato
|
|
93
|
+
* PRIMA — invertendo la cronologia di una chat che l'utente si aspetta scorra
|
|
94
|
+
* top=vecchio/bottom=nuovo (bug segnalato). Assente = comportamento invariato, sempre in
|
|
95
|
+
* fondo (equivalente a passare la lunghezza corrente del log). */
|
|
96
|
+
panelExtraAnchorIndex?: number;
|
|
97
|
+
/** Chiamato quando questo task viene sostituito da uno nuovo (vedi openTask) o quando
|
|
98
|
+
* l'utente lo interrompe — SEMPRE definito da chi possiede il task
|
|
99
|
+
* (OrchestratorRunner/SubagentRunner), mai un fallback generico su closeTask: quel
|
|
100
|
+
* componente resta montato anche a task chiuso, quindi il proprio effect che ri-registra il
|
|
101
|
+
* task a ogni cambiamento di agent.activity/running lo RIAPRIREBBE da solo (es.
|
|
102
|
+
* l'aggiornamento "Interrotto dall'utente" dopo uno stop()) se non gli si dice
|
|
103
|
+
* esplicitamente di smettere — vedi il ref `dismissedRef` in entrambi i chiamanti. */
|
|
104
|
+
onDismiss: () => void;
|
|
105
|
+
}
|
|
106
|
+
/** Un punto di ancoraggio semantico subagent↔componente attivo in questo momento — vedi
|
|
107
|
+
* useSubagentComponentContext (presentation/hooks) per come si registra, e
|
|
108
|
+
* SubagentManifest.componentContexts per dove vivono i testi (agenticoHint/userMessage). */
|
|
109
|
+
export interface ComponentAnchor {
|
|
110
|
+
subagentId: string;
|
|
111
|
+
componentKey: string;
|
|
112
|
+
/** Chiamato da SubagentRunner quando arriva un risultato per `subagentId` mentre questo
|
|
113
|
+
* anchor è montato — il componente/pagina popola se stesso, mai un salvataggio automatico.
|
|
114
|
+
* `meta` è il TParams con cui il subagent è stato lanciato (es. `{ url }` per theme).
|
|
115
|
+
* `taskId` è l'id del task Agentico che ha prodotto questo risultato — un componente che
|
|
116
|
+
* vuole poter persistere la chat al proprio salvataggio (vedi commitEntityChat sotto) lo
|
|
117
|
+
* tiene da parte, altrimenti può ignorarlo. */
|
|
118
|
+
onResult?: (result: unknown, meta: Record<string, unknown>, taskId: string) => void;
|
|
119
|
+
/** Fatti live su QUESTA istanza dell'entità aperta (es. "Il tema aperto si chiama
|
|
120
|
+
* ducatimilano.it"), aggiunti in coda all'`agenticoHint` statico del manifest (vedi
|
|
121
|
+
* anchorTexts) — l'`agenticoHint` è prosa fissa scritta una volta nel manifest, non può
|
|
122
|
+
* sapere quale entità specifica è aperta ORA. Assente = comportamento invariato (solo il
|
|
123
|
+
* testo statico). Vedi useSubagentComponentContext per come un componente lo valorizza. */
|
|
124
|
+
contextInfo?: string;
|
|
125
|
+
/** Id dell'entità a cui QUESTA istanza è vincolata (es. l'hostId di RedirectsEditor) — a
|
|
126
|
+
* differenza di `contextInfo` (prosa, solo per il prompt), è un valore STRUTTURATO che
|
|
127
|
+
* SubagentRunner inoltra a `ResultDestination.apply()` (vedi `meta.pinnedEntityId`) perché una
|
|
128
|
+
* destinazione con logica di identità propria (es. redirectsSaveDestination, che calcola
|
|
129
|
+
* l'hostId di destinazione dal risultato) possa rifiutare un salvataggio il cui hostId
|
|
130
|
+
* risolto NON combacia — un backstop deterministico, non affidato solo all'istruzione nel
|
|
131
|
+
* prompt (che può comunque essere ignorata dal modello). Assente = nessun controllo
|
|
132
|
+
* aggiuntivo, comportamento invariato (es. RedirectsIndexList, che non è vincolato a un solo
|
|
133
|
+
* host). */
|
|
134
|
+
pinnedEntityId?: string;
|
|
135
|
+
}
|
|
136
|
+
interface AgenticoContextValue {
|
|
137
|
+
/** The host scope passed to <AgenticoProvider scope>. */
|
|
138
|
+
scope: AgenticoScope | null;
|
|
139
|
+
task: AgenticoTask | null;
|
|
140
|
+
/** Visibilità del pannello — completamente indipendente dal task (vedi AgenticoToggle:
|
|
141
|
+
* icona persistente stile "estensione del browser"). Nessuna chiamata a `openTask` la forza
|
|
142
|
+
* mai a true: un fetch/run() NON apre da solo il pannello (solo l'icona anima per segnalare
|
|
143
|
+
* che l'agente sta lavorando) — solo l'utente, cliccando il toggle, decide di vederlo. */
|
|
144
|
+
isOpen: boolean;
|
|
145
|
+
/** Crea o sostituisce il task attivo (upsert idempotente se stesso id, altrimenti sostituisce:
|
|
146
|
+
* un task con un id DIVERSO da quello corrente ne causa la chiusura esplicita via
|
|
147
|
+
* `onDismiss()` prima di installare il nuovo — mai due conversazioni vive insieme, vedi
|
|
148
|
+
* AgenticoTask). Richiamalo a ogni render, l'oggetto `agent` è nuovo a ogni render dell'hook
|
|
149
|
+
* useAgent. */
|
|
150
|
+
openTask: <TResult>(task: AgenticoTask<TResult>) => void;
|
|
151
|
+
closeTask: (id: string) => void;
|
|
152
|
+
/** Mostra/nasconde il pannello — l'unica azione che tocca `isOpen` insieme a `openPanel`
|
|
153
|
+
* (vedi commento su `isOpen`). Usato da AgenticoToggle. */
|
|
154
|
+
toggleOpen: () => void;
|
|
155
|
+
/** Goal in attesa che un OrchestratorRunner catturi al mount e lanci — settato SOLO se non
|
|
156
|
+
* esiste già un task orchestratore (vedi startOrchestrator). `null` quando non c'è nessun
|
|
157
|
+
* avvio in sospeso. */
|
|
158
|
+
pendingGoal: string | null;
|
|
159
|
+
/** Cambia a ogni conversazione orchestratore avviata per davvero — usato solo come React
|
|
160
|
+
* `key` sull'elemento <OrchestratorRunner>, mai letto per altro. */
|
|
161
|
+
orchestratorRunId: string | null;
|
|
162
|
+
/** Chiamato da ToolsPage ("Usa agent" su una card), dall'input vuoto del pannello Agentico, o
|
|
163
|
+
* da una pagina che vuole avviare una conversazione già scoped (es. SiteEditorPage) — apre il
|
|
164
|
+
* pannello e, se non c'è già una conversazione orchestratore in corso, la avvia con questo
|
|
165
|
+
* goal. Se ce n'è già una, la porta semplicemente a fuoco: NON inietta il nuovo goal in
|
|
166
|
+
* quella conversazione (limite noto, accettato per l'MVP).
|
|
167
|
+
* `options.scopedSubagentId` — presente quando il chiamante sa GIÀ, senza bisogno di AI,
|
|
168
|
+
* quale subagent servirà (es. il bottone "Importa HTML/JSX", sempre `html-to-liquid`) — a
|
|
169
|
+
* differenza dello scoping derivato da un componentAnchor (vedi `scopedSubagentId` sotto,
|
|
170
|
+
* che richiede un ancoraggio live), questo vale per un click one-shot che non monta alcun
|
|
171
|
+
* anchor. Usato SOLO per abilitare il percorso "Continua senza AI" → manuale (vedi
|
|
172
|
+
* startManualEntry/ManualEntryRunner) quando l'orchestratore stesso non riesce a partire:
|
|
173
|
+
* senza sapere il target, quel bottone non potrebbe offrire altro che il messaggio generico
|
|
174
|
+
* di fallback dell'orchestratore (non un vero handoff, non può indovinare l'intento). */
|
|
175
|
+
startOrchestrator: (goal: string, options?: {
|
|
176
|
+
extraDestinations?: ResultDestination[];
|
|
177
|
+
attachments?: File[];
|
|
178
|
+
model?: string;
|
|
179
|
+
scopedSubagentId?: string;
|
|
180
|
+
}) => void;
|
|
181
|
+
/** Destinazioni scoped alla pagina che ha avviato l'ultimo startOrchestrator() con
|
|
182
|
+
* `options.extraDestinations` — catturate da OrchestratorRunner al momento dell'handoff e
|
|
183
|
+
* inoltrate al SubagentRunner che monta, insieme a `pendingGoal`. `undefined` per i
|
|
184
|
+
* chiamanti che non ne passano. */
|
|
185
|
+
pendingExtraDestinations: ResultDestination[] | undefined;
|
|
186
|
+
/** File allegati al messaggio che ha avviato l'ultima conversazione orchestratore — catturati
|
|
187
|
+
* da OrchestratorRunner al mount, insieme a `pendingGoal`. */
|
|
188
|
+
pendingAttachments: File[] | undefined;
|
|
189
|
+
/** Modello scelto dall'utente nel composer "starter", prima ancora che esista una sessione
|
|
190
|
+
* useAgent — catturato da OrchestratorRunner al mount, insieme a `pendingGoal`. */
|
|
191
|
+
pendingModel: string | undefined;
|
|
192
|
+
/** Vedi PendingCarryOver — catturato da OrchestratorRunner al mount insieme a pendingGoal,
|
|
193
|
+
* `null` quando startOrchestrator() non ha trovato nessun task da continuare. */
|
|
194
|
+
pendingCarryOver: PendingCarryOver | null;
|
|
195
|
+
/** Vedi `options.scopedSubagentId` di startOrchestrator sopra — catturato da OrchestratorRunner
|
|
196
|
+
* al mount, insieme agli altri pending*. `undefined` = nessun target esplicito (comportamento
|
|
197
|
+
* invariato, l'orchestratore deriva lo scope SOLO da un componentAnchor live, se presente). */
|
|
198
|
+
pendingScopedSubagentId: string | undefined;
|
|
199
|
+
/** Testo "dove si trova l'utente adesso" per contestualizzare l'orchestratore — se ci sono
|
|
200
|
+
* ancoraggi componente↔subagent attivi (vedi componentAnchors sotto) deriva da quelli
|
|
201
|
+
* (agenticoHint, combinato se ne sono attivi più di uno di subagent diversi), altrimenti
|
|
202
|
+
* ripiega sul vecchio meccanismo a stack per-pagina (useAgenticoPageContext, ancora usato da
|
|
203
|
+
* pagine non migrate a componentContexts). Letto una sola volta da OrchestratorRunner al
|
|
204
|
+
* momento di run(). */
|
|
205
|
+
pageContext: string | null;
|
|
206
|
+
/** Card strutturata (campi richiesti/opzionali) — SOLO dal vecchio meccanismo a stack
|
|
207
|
+
* per-pagina (mai per un anchor component-based, che usa invece `anchoredUserMessages` sotto,
|
|
208
|
+
* un semplice messaggio invece di un modulo a campi). `null` quando non applicabile. */
|
|
209
|
+
pageContextCard: SubagentUsageCard | null;
|
|
210
|
+
/** Registra/rimuove (text === null) il contesto di UNA pagina/pannello identificata da `id`
|
|
211
|
+
* — usare tramite l'hook useAgenticoPageContext, non direttamente. Vedi pageContext sopra per
|
|
212
|
+
* come si combina con componentAnchors. */
|
|
213
|
+
setPageContext: (id: string, text: string | null, card?: SubagentUsageCard | null) => void;
|
|
214
|
+
/** Id del subagent a cui l'orchestratore deve restare scoped — deriva da componentAnchors
|
|
215
|
+
* quando esattamente UN subagent è ancorato, altrimenti (0 o >1 subagent distinti) ripiega
|
|
216
|
+
* sul vecchio pageContextCard/`null`. Sostituisce il vecchio `pageContextCard?.subagentId`
|
|
217
|
+
* come UNICA fonte per OrchestratorRunner/startOrchestrator. */
|
|
218
|
+
scopedSubagentId: string | null;
|
|
219
|
+
/** Ancoraggi componente↔subagent attualmente montati, deduplicati per subagentId (l'ultimo
|
|
220
|
+
* registrato per uno stesso subagent vince) — usato da SubagentRunner per instradare un
|
|
221
|
+
* risultato al componente vivo invece di mostrare sempre ResultDestinationPicker. */
|
|
222
|
+
componentAnchors: ComponentAnchor[];
|
|
223
|
+
/** Messaggi utente (SubagentComponentContext.userMessage) per gli anchor attivi — mostrati
|
|
224
|
+
* da Agentico.tsx al posto della vecchia card a campi quando ci sono anchor component-based.
|
|
225
|
+
* Vuoto se nessun anchor attivo, o se un anchor non ha un componentContexts corrispondente
|
|
226
|
+
* (es. SiteEditorPage, che ascolta un risultato senza fornire un proprio messaggio). */
|
|
227
|
+
anchoredUserMessages: string[];
|
|
228
|
+
/** Registra/rimuove (anchor === null) un ancoraggio componente↔subagent identificato da `id`
|
|
229
|
+
* — usare tramite l'hook useSubagentComponentContext, non direttamente. */
|
|
230
|
+
registerComponentAnchor: (id: string, anchor: ComponentAnchor | null) => void;
|
|
231
|
+
/** Apre il pannello incondizionatamente — a differenza di toggleOpen(), non dipende dal
|
|
232
|
+
* valore corrente di isOpen. */
|
|
233
|
+
openPanel: () => void;
|
|
234
|
+
/** Persiste (sovrascrivendo un'eventuale chat già salvata per la STESSA entità, vedi
|
|
235
|
+
* entityChatStore) la conversazione del task `taskId`, keyed su `${scopeId}:${subagentId}:
|
|
236
|
+
* ${entityId}` — chiamato da un componente (es. ThemeEditor) subito dopo un salvataggio
|
|
237
|
+
* riuscito. No-op se `taskId` è assente (nessuna estrazione coinvolta in questo salvataggio,
|
|
238
|
+
* es. edit manuale — un'eventuale chat già salvata in precedenza per questa entità resta
|
|
239
|
+
* intatta) o se il task `taskId` non è più quello corrente (l'utente ha aperto un'altra
|
|
240
|
+
* conversazione nel frattempo — niente si salva, per non attaccare a un'entità la chat
|
|
241
|
+
* sbagliata). */
|
|
242
|
+
commitEntityChat: (subagentId: string, entityId: string, taskId: string | null | undefined, scopeId: string | undefined, params: Record<string, unknown>, title: string) => void;
|
|
243
|
+
/** Riprende una chat salvata (vedi entityChatStore) — apre il pannello e monta un
|
|
244
|
+
* SubagentRunner con `resumeSeed` valorizzato invece di un run/handoff dall'orchestratore
|
|
245
|
+
* (vedi Agentico.tsx). Sostituisce (mai affianca) qualunque task corrente, stesso principio
|
|
246
|
+
* di startOrchestrator/openTask — una chat unica alla volta in tutta l'app. */
|
|
247
|
+
resumeEntityChat: (subagentId: string, entityId: string, snapshot: EntityChatSnapshot) => void;
|
|
248
|
+
/** Presente = un resumeEntityChat() è in sospeso, letto da Agentico.tsx per montare il
|
|
249
|
+
* SubagentRunner col resumeSeed giusto — analogo a pendingGoal per l'orchestratore. */
|
|
250
|
+
pendingResume: {
|
|
251
|
+
subagentId: string;
|
|
252
|
+
entityId: string;
|
|
253
|
+
snapshot: EntityChatSnapshot;
|
|
254
|
+
} | null;
|
|
255
|
+
/** Cambia a ogni resumeEntityChat() — usato solo come React `key` sul SubagentRunner di
|
|
256
|
+
* resume (vedi Agentico.tsx), stesso principio di orchestratorRunId. */
|
|
257
|
+
resumeRunId: string | null;
|
|
258
|
+
/** Presente = un startManualEntry() è in sospeso, letto da Agentico.tsx per montare un
|
|
259
|
+
* ManualEntryRunner per QUESTO subagent — percorso "senza AI" per quando l'orchestratore
|
|
260
|
+
* stesso non riesce a partire ma il target è già noto (vedi
|
|
261
|
+
* SubagentManifest.manualEntry/pendingScopedSubagentId). Analogo a pendingGoal/pendingResume. */
|
|
262
|
+
pendingManualEntry: {
|
|
263
|
+
subagentId: string;
|
|
264
|
+
extraDestinations?: ResultDestination[];
|
|
265
|
+
} | null;
|
|
266
|
+
/** Cambia a ogni startManualEntry() — React `key` sul ManualEntryRunner, stesso principio di
|
|
267
|
+
* orchestratorRunId/resumeRunId. */
|
|
268
|
+
manualEntryRunId: string | null;
|
|
269
|
+
/** Avvia il percorso "senza AI" per un subagent già noto — chiamato dal bottone "Continua
|
|
270
|
+
* senza AI" quando la conversazione orchestratore è scoped e non può proseguire (vedi
|
|
271
|
+
* Agentico.tsx). Congeda subito il task orchestratore corrente, stesso principio di un vero
|
|
272
|
+
* handoff AI-driven (OrchestratorRunner.handleResult). */
|
|
273
|
+
startManualEntry: (subagentId: string, extraDestinations?: ResultDestination[]) => void;
|
|
274
|
+
/** Presente = un resumeWithAI() è in sospeso, letto da Agentico.tsx per montare un vero
|
|
275
|
+
* SubagentRunner (AI abilitata) per QUESTO subagent con QUESTI parametri — il "contrario" di
|
|
276
|
+
* startManualEntry: dopo aver lavorato nel percorso senza AI, l'utente può far raffinare
|
|
277
|
+
* dall'AI lo stesso input, invece di restare bloccato lì per sempre. */
|
|
278
|
+
pendingResumeWithAI: {
|
|
279
|
+
subagentId: string;
|
|
280
|
+
params: Record<string, unknown>;
|
|
281
|
+
extraDestinations?: ResultDestination[];
|
|
282
|
+
} | null;
|
|
283
|
+
/** Cambia a ogni resumeWithAI() — React `key` sul SubagentRunner risultante, stesso principio
|
|
284
|
+
* di manualEntryRunId. */
|
|
285
|
+
resumeWithAIRunId: string | null;
|
|
286
|
+
/** Passa da un task ManualEntryRunner (senza AI) a un vero SubagentRunner (AI abilitata) per
|
|
287
|
+
* lo STESSO subagent, riusando `params` (gli ultimi usati con successo nel percorso senza
|
|
288
|
+
* AI) come punto di partenza — mai una conversazione persa, solo il canale che cambia.
|
|
289
|
+
* Generico per costruzione: nessuna conoscenza di QUALE subagent, funziona per ogni
|
|
290
|
+
* manifest con `manualEntry` dichiarato, non solo html-to-liquid. */
|
|
291
|
+
resumeWithAI: (subagentId: string, params: Record<string, unknown>, extraDestinations?: ResultDestination[]) => void;
|
|
292
|
+
/** Congeda il task corrente — usato da un componente che ha già stabilito (in base al
|
|
293
|
+
* proprio subagentId/entità) che il task visibile non è il suo (vedi ThemeEditor/
|
|
294
|
+
* ThemeIndexList). Regola unica, nessuna eccezione: quale chat si vede dipende SOLO dal
|
|
295
|
+
* componente/entità a cui si è agganciati in questo momento — niente puntatori "torna
|
|
296
|
+
* indietro", niente eccezione per un task ancora in corso (deliberatamente semplice,
|
|
297
|
+
* raffinabile in seguito). No-op se non c'è alcun task. */
|
|
298
|
+
dismissForeignTask: () => void;
|
|
299
|
+
}
|
|
300
|
+
export declare function AgenticoProvider({ children, scope }: {
|
|
301
|
+
children: React.ReactNode;
|
|
302
|
+
scope?: AgenticoScope | null;
|
|
303
|
+
}): React.JSX.Element;
|
|
304
|
+
export declare function useAgentico(): AgenticoContextValue;
|
|
305
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/** L'unica icona che apre/chiude il pannello agente globale, Agentico (Agentico.tsx) — stile
|
|
3
|
+
* icona-estensione-del-browser: sempre nello stesso angolo, sempre lo stesso significato, sia
|
|
4
|
+
* che tu stia guardando il CMS a schermo pieno (nell'Header) sia che ci sia una modale right
|
|
5
|
+
* aperta sopra (come `closeSlot` di quella Modal, al posto della sua ×). Un'unica istanza di
|
|
6
|
+
* questo componente — mai una ricreata ad hoc — cosi il comportamento resta identico ovunque
|
|
7
|
+
* compaia. `ActionButton` del framework (non un <button> a mano) per ereditare `cursor-pointer`
|
|
8
|
+
* e lo stato hover/focus-visible già standard su ogni bottone del CMS dalla classe condivisa
|
|
9
|
+
* `.btn` — solo sfondo/dimensione sono nostri via className, nessuna variante colore predefinita
|
|
10
|
+
* si adatta a un'icona-toggle isolata come questa.
|
|
11
|
+
*
|
|
12
|
+
* Animata (icona pulsante) quando l'unico task attivo ha l'agente al lavoro — anche se il
|
|
13
|
+
* pannello è chiuso, cosi si vede che sta succedendo qualcosa senza doverlo aprire apposta
|
|
14
|
+
* (l'agente NON apre più da solo il pannello durante un run(), vedi AgenticoContext). */
|
|
15
|
+
export declare function AgenticoToggle({ className }: {
|
|
16
|
+
className?: string;
|
|
17
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { SubagentManifest } from '../domain/subagentManifest';
|
|
2
|
+
import type { ResultDestination } from '../domain/resultDestination';
|
|
3
|
+
/** Percorso "senza AI" per un subagent già scoped (un solo target possibile, niente da
|
|
4
|
+
* instradare — vedi SubagentManifest.manualEntry e AgenticoContext.startManualEntry), montato
|
|
5
|
+
* quando l'orchestratore stesso non riesce a partire (AI giù) ma il chiamante sa già a priori
|
|
6
|
+
* quale subagent servirà. Mostra il prompt statico del manifest; sul primo testo inviato
|
|
7
|
+
* dall'utente costruisce i TParams DIRETTAMENTE dal testo grezzo (`manualEntry.fromRawText`) e
|
|
8
|
+
* chiama `agent.run()` con l'AI disabilitata a priori — `buildContext` (sempre deterministico)
|
|
9
|
+
* gira comunque, ma la chiamata AI viene saltata del tutto (vedi useAgent.run, ramo
|
|
10
|
+
* `!enabled`), zero round-trip di rete, zero possibilità di fallire per un provider giù.
|
|
11
|
+
*
|
|
12
|
+
* Il risultato è mostrato in anteprima (report del subagent se registrato, altrimenti
|
|
13
|
+
* `GenericResultPreview`) più `ResultDestinationPicker` — STESSO identico schema di
|
|
14
|
+
* SubagentRunner, mai un apply automatico appena arriva il risultato (bug segnalato: prima
|
|
15
|
+
* consegnava subito a un anchor live o alla prima extraDestination, senza che l'utente vedesse
|
|
16
|
+
* nulla prima). Un componentAnchor live (es. ThemeEditor per theme) è trattato come una
|
|
17
|
+
* destinazione in più tra quelle proposte (vedi liveAnchorDestination.ts), non un canale a
|
|
18
|
+
* parte. */
|
|
19
|
+
export declare function ManualEntryRunner({ manifest, extraDestinations, }: {
|
|
20
|
+
manifest: SubagentManifest<any, any, any>;
|
|
21
|
+
extraDestinations?: ResultDestination[];
|
|
22
|
+
}): null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/** Monta la conversazione dell'orchestratore Agentico — il "meta-agente" che legge il catalogo
|
|
3
|
+
* CLI dei subagent (deterministico, nessuna chiamata LLM, vedi createOrchestratorAgentDefinition
|
|
4
|
+
* buildContext) e conversa con l'utente finché non ha raccolto abbastanza parametri per invocare
|
|
5
|
+
* un subagent reale. Quando arriva un risultato `{ kind: 'handoff' }` monta un SubagentRunner per
|
|
6
|
+
* quel subagent, gli passa il transcript dell'orchestratore com'era in quel momento
|
|
7
|
+
* (`precedingActivity`) e chiude subito il proprio task — l'utente vede UNA chat continua che
|
|
8
|
+
* scivola dalla raccolta parametri all'esecuzione del subagent, mai due task da switchare a
|
|
9
|
+
* mano (decisione esplicita, vedi piano). */
|
|
10
|
+
export declare function OrchestratorRunner({ userGoal }: {
|
|
11
|
+
userGoal: string;
|
|
12
|
+
}): React.JSX.Element | null;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SubagentManifest } from '../domain/subagentManifest';
|
|
3
|
+
import type { ResultDestination } from '../domain/resultDestination';
|
|
4
|
+
/** Mostrata da SubagentRunner una volta che il subagent ha prodotto un risultato — un bottone
|
|
5
|
+
* per destinazione dichiarata dal manifest (`destinationIds`) più "Esporta come JSON", sempre
|
|
6
|
+
* disponibile per qualunque risultato (vedi jsonExportDestination). Le destinazioni tenant-scoped
|
|
7
|
+
* (theme, component-library) scrivono SOLO nel tenant attualmente attivo — vedi
|
|
8
|
+
* DestinationContext, nessuna scelta di un tenant diverso qui (decisione esplicita, vedi piano). */
|
|
9
|
+
export declare function ResultDestinationPicker({ manifest, result, meta, taskId, initiallyApplied, onApplied, extraDestinations, }: {
|
|
10
|
+
manifest: SubagentManifest<any, any, any>;
|
|
11
|
+
result: unknown;
|
|
12
|
+
meta: Record<string, unknown>;
|
|
13
|
+
/** Id del task Agentico che ha prodotto questo risultato — passato a `commitEntityChat`
|
|
14
|
+
* quando un apply esplicito (click qui) restituisce un `id` (vedi sotto). Assente = nessuna
|
|
15
|
+
* persistenza dello storico per questo click (nessun task noto da cui pescare uno snapshot),
|
|
16
|
+
* comportamento invariato per un eventuale chiamante futuro senza un task Agentico dietro. */
|
|
17
|
+
taskId?: string;
|
|
18
|
+
/** Destinazioni già applicate in precedenza (es. riaprendo un'esecuzione dallo storico) —
|
|
19
|
+
* mostrate subito come spuntate invece di far credere che vadano riapplicate da zero. */
|
|
20
|
+
initiallyApplied?: string[];
|
|
21
|
+
/** Chiamato dopo un apply riuscito — usato da SubagentRunner per aggiornare la voce di
|
|
22
|
+
* storico (appliedDestinationIds), assente quando il chiamante non ne ha bisogno (es. una
|
|
23
|
+
* destinazione già storicizzata che si vuole solo ri-esportare). */
|
|
24
|
+
onApplied?: (destinationId: string) => void;
|
|
25
|
+
/** Destinazioni scoped alla pagina/istanza corrente (es. "Applica a questo Site aperto"),
|
|
26
|
+
* mai registrate nel destinationRegistry condiviso perché chiudono su stato React di UNA
|
|
27
|
+
* pagina specifica — mostrate accanto a quelle del registry, non al loro posto. */
|
|
28
|
+
extraDestinations?: ResultDestination[];
|
|
29
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { AIConversationTurn } from '@llmnative/react';
|
|
2
|
+
import { type AgentActivityEntry } from './useAgent';
|
|
3
|
+
import type { SubagentManifest } from '../domain/subagentManifest';
|
|
4
|
+
import type { ResultDestination } from '../domain/resultDestination';
|
|
5
|
+
/** Monta il vero subagent (useAgent(manifest.definition)) e lo esegue una volta al mount con i
|
|
6
|
+
* parametri già raccolti dall'orchestratore Agentico — nessun passo utente aggiuntivo, la
|
|
7
|
+
* conversazione di raccolta parametri è già avvenuta a monte (vedi Agentico.tsx). Si registra
|
|
8
|
+
* nel pannello Agentico con id stabile via useRef + cleanup closeTask allo smontaggio, con il
|
|
9
|
+
* transcript dell'orchestratore (`precedingActivity`) prepeso al proprio log — l'utente vede
|
|
10
|
+
* UNA chat continua, mai due task distinti da switchare (vedi OrchestratorRunner).
|
|
11
|
+
*
|
|
12
|
+
* Con `resumeSeed` valorizzato, il primo giro chiama `agent.resume(...)` invece di
|
|
13
|
+
* `agent.run(...)` — riprende una chat già salvata (vedi entityChatStore/
|
|
14
|
+
* AgenticoContext.resumeEntityChat) invece di avviarne una nuova. Tutto il resto (consegna del
|
|
15
|
+
* risultato ai componentAnchors, ResultDestinationPicker di riserva, registrazione del task) è
|
|
16
|
+
* IDENTICO a un run normale — un follow-up dopo un resume produce un risultato esattamente come
|
|
17
|
+
* un follow-up dopo un run, nessuna duplicazione di logica per il caso "ripreso". */
|
|
18
|
+
export declare function SubagentRunner({ manifest, params, extraDestinations, precedingActivity, taskId: taskIdProp, resumeSeed, model, }: {
|
|
19
|
+
manifest: SubagentManifest<any, any, any>;
|
|
20
|
+
params: Record<string, unknown>;
|
|
21
|
+
/** Destinazioni scoped alla pagina che ha avviato questo run (es. "Applica a questo Site
|
|
22
|
+
* aperto") — inoltrate tale e quali a ResultDestinationPicker, vedi quel file. */
|
|
23
|
+
extraDestinations?: ResultDestination[];
|
|
24
|
+
/** Transcript dell'orchestratore all'handoff — vedi AgenticoTask.precedingActivity. Non ha
|
|
25
|
+
* senso insieme a `resumeSeed` (una chat ripresa non ha un orchestratore a monte in questo
|
|
26
|
+
* giro) — semplicemente non passato dal chiamante in quel caso. */
|
|
27
|
+
precedingActivity?: AgentActivityEntry[];
|
|
28
|
+
/** Id di tab da RIUSARE invece di generarne uno fresco — vedi PendingCarryOver
|
|
29
|
+
* (AgenticoContext.tsx)/OrchestratorRunner.tsx: quando presente, questo run "continua" una
|
|
30
|
+
* tab già esistente (stessa posizione, stesso id) invece di aprirne una seconda per lo
|
|
31
|
+
* stesso subagent. Assente = comportamento invariato, id fresco per ogni run. */
|
|
32
|
+
taskId?: string;
|
|
33
|
+
/** Presente = riprendi una chat già salvata invece di avviarne una nuova (vedi
|
|
34
|
+
* AgenticoContext.resumeEntityChat) — `params` deve comunque essere la stessa forma raccolta
|
|
35
|
+
* originariamente (manifest.toParams(params) viene chiamato in entrambi i casi). */
|
|
36
|
+
resumeSeed?: {
|
|
37
|
+
history: AIConversationTurn[];
|
|
38
|
+
activity: AgentActivityEntry[];
|
|
39
|
+
};
|
|
40
|
+
/** Modello scelto nel composer "starter" a monte (OrchestratorRunner.tsx's modelRef) — questo
|
|
41
|
+
* componente monta la sua PROPRIA istanza di useAgent/useAIModelCatalog, indipendente da
|
|
42
|
+
* quella dell'orchestratore che ha appena fatto l'handoff, quindi senza propagarlo qui
|
|
43
|
+
* esplicitamente `agent.selectedModel` si auto-inizializzerebbe al default del provider
|
|
44
|
+
* invece di continuare con la scelta dell'utente (stesso bug, stessa causa, di
|
|
45
|
+
* OrchestratorRunner — vedi il commento lì). Non passato per un `resumeSeed` — lì non c'è una
|
|
46
|
+
* scelta "di questo giro" da propagare, si continua semplicemente la chat salvata così com'era. */
|
|
47
|
+
model?: string;
|
|
48
|
+
}): null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SubagentManifest } from '../domain/subagentManifest';
|
|
2
|
+
/** Etichetta breve mostrata nell'header di Agentico/nello storico chat per un task — Agentico
|
|
3
|
+
* stesso non conosce la forma di TParams di nessun subagent specifico (nessun `params.url`/
|
|
4
|
+
* `params.siteHostname` hard-codato qui): ogni manifest dichiara il proprio
|
|
5
|
+
* `deriveHistoryTitle` se ha un campo sensato da mostrare (vedi
|
|
6
|
+
* SubagentManifest.deriveHistoryTitle), altrimenti si ripiega sul nome generico del subagent
|
|
7
|
+
* (`manifest.label`) — mai un tentativo di indovinare quale campo di `params` sia "il titolo".
|
|
8
|
+
* File a sé (non dentro SubagentRunner.tsx/ResultDestinationPicker.tsx) perché entrambi lo
|
|
9
|
+
* consumano — tenerlo in uno dei due avrebbe creato un import circolare tra loro. */
|
|
10
|
+
export declare function deriveHistoryTitle(manifest: SubagentManifest<any, any, any>, params: Record<string, unknown>): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ComponentAnchor } from './AgenticoContext';
|
|
2
|
+
import type { ResultDestination } from '../domain/resultDestination';
|
|
3
|
+
/** Consegna a un componentAnchor live (es. ThemeEditor per theme) trattata come UNA destinazione
|
|
4
|
+
* qualunque tra quelle proposte da ResultDestinationPicker — non più un canale a parte con
|
|
5
|
+
* consegna automatica silenziosa (bug segnalato: il risultato finiva nel componente PRIMA che
|
|
6
|
+
* l'utente vedesse alcuna anteprima o cliccasse alcunché). Stesso schema per ogni subagent, con
|
|
7
|
+
* o senza AI: risultato → anteprima in chat → click esplicito → applica. Nessun `id` restituito
|
|
8
|
+
* (l'entità non è ancora persistita finché l'utente non salva lui stesso nel componente aperto —
|
|
9
|
+
* `commitEntityChat` si occupa di quel momento separatamente, dal Save del componente stesso). */
|
|
10
|
+
export declare function buildLiveAnchorDestination(matching: ComponentAnchor[], meta: Record<string, unknown>, taskId: string): ResultDestination | null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/** Anteprima di riserva per un subagent SENZA un report registrato (oggi: theme, redirects) —
|
|
3
|
+
* mostrata nella stessa identica posizione/momento di un vero `SubagentReportModule.Report`
|
|
4
|
+
* (prima del bottone "Applica"), cosi ogni subagent, con o senza report dedicato, con o senza
|
|
5
|
+
* AI, passa dallo STESSO schema "vedi il risultato → poi applica", mai un apply automatico
|
|
6
|
+
* silenzioso. Un JSON grezzo non è bello quanto uno swatch di colori o una griglia editabile,
|
|
7
|
+
* ma è sempre meglio di applicare alla cieca — un report dedicato resta la via preferita quando
|
|
8
|
+
* ne vale la pena scriverne uno (vedi subagentReportRegistry.tsx). */
|
|
9
|
+
export declare function GenericResultPreview({ result }: {
|
|
10
|
+
result: unknown;
|
|
11
|
+
}): React.JSX.Element;
|