AgiPanel: The visual host
The AgiPanel is the primary visual container for an individual AGI session. It manages the reactive flow between the chat history, the input compositor, and session observability.
Unified Workspace Bridge
The AgiTransferHandler provides deep drag-and-drop integration. Dragging files into any part of the AgiPanel (including the status bar) automatically triggers the V2 Resource registration workflow, ensuring context is always just a drop away.
The Barça Palette (Visual Identity)
The UI uses a functional color system mapped to the AgiStatus lifecycle. These colors communicate the session's metabolic state:
- ● Emerald: Awakening
- ● Blue: API Active
- ● Ochre: Approval Req.
- ● Cyan: Selection
- ● Purple: Autonomous
- ● Green: Idle / Success
- ● Red: Waiting / Error
Biological Synchronization
The UI maintains identity-preserving stability via a Diff-and-Update strategy. Messages and parts are tracked by unique domain IDs, ensuring component reuse. This prevents flicker and preserves scroll-state even during massive model responses.
Host Orchestration
Build your own host environment (IDE plugin or standalone app) by implementing the AgiController interface. This decouples the session lifecycle from your UI layout.
Metabolic Efficiency
The AbstractAsiContainerPanel implements a 1-second refresh timer that automatically pauses when the component is hidden via the HierarchyListener, ensuring zero CPU overhead during background tasks.
Toolkit Dashboards
Create specialized visual panels for your toolkits by implementing the ToolkitRenderer interface. Register renderers in the ToolkitUiRegistry for per-session instantiation.
The Visual Handshake
The createToolkitPanel() method is your visual handshake. It connects your Swing component to a live toolkit instance. This is separate from Core rebind(), which handles metabolic recovery after serialization.
// 1. Extend the base for automatic EDT-safe binding
public class MyToolkitRenderer extends AbstractToolkitRenderer<MyToolkit> {
@Override
protected void onBind() {
// Build your layout here (called by createToolkitPanel())
add(new JLabel("Status: " + getAnahataToolkit().getStatus()));
}
}
// 2. Register mapping in your host application
ToolkitUiRegistry.getInstance().register(MyToolkit.class, MyToolkitRenderer.class);
Tool Parameters
Create specialized visualizers for @AgiToolParam arguments. Renderers are resolved based on the Java type or an explicit rendererId hint in the annotation.
Representational Fidelity
The updateContent() method allows your UI to reflect changes in parameter values as they are being streamed or refined by the model bit-by-bit.
@AgiTool("Performs a specialized operation")
public void myTool(
@AgiToolParam(value = "Input", rendererId = "json") String input
) { ... }
Tool Approval Workflow
The ToolCallPanel manages the lifecycle of a tool request. It provides a tabbed interface to inspect arguments, review output, and provide feedback.
Tabbed Height Invariants
The adjustTabbedPaneHeight() method leverages content-aware getPreferredSize() to perfectly fit host-native components, eliminating redundant scrollbars and offsets.
Multimodal & Audio
Treat audio as a first-class citizen. Extend input capabilities with recording logic and monitor metabolic state via autonomous sound feedback.
RMS Metering
The MicrophonePanel implements real-time RMS metering, capturing raw PCM data while marshaling volume levels to the levelBar on the EDT for high-fidelity recording feedback.
// Status changes trigger specific WAV notifications:
// e.g. api_call_in_progress.wav, tool_prompt.wav, awakening_kundalini.wav
private void handleStatusSound(AgiStatus newStatus) {
String soundFile = newStatus.name().toLowerCase() + ".wav";
audioPlaybackPanel.playSound(soundFile);
}
Input Composition
The InputPanel maintains a "Live" InputUserMessage that enables real-time Markdown preview and multimodal attachment logic.
Composition Dynamics
The panel integrates an UndoManager for transactional text editing and a "Clean Slate" shortcut (Decline Pending & Send) to quickly clear the previous turn's tool requests before submission.
// Multimodal attachments use a dual-intent strategy:
// 1. Files are registered as persistent V2 Resources.
// 2. Ephemeral captures (screenshots) are attached to the history buffer.
public void attach(Path p) throws Exception {
currentMessage.addAttachment(p);
updateSendButtonState();
scrollToBottomPreview();
}
Universal Viewers
The ResourceUI strategy decouples domain Resource data from its visual interpretation. This allows swapping between host-native editors and standalone components.
Modular Metadata Hooks
The createHandlePanel() and createViewPanel() hooks allow you to inject specialized inspectors for URI attributes and viewport settings (V2) alongside the primary content visualization.
// Register globally at application startup to provide host-specific (e.g. NetBeans) editors
ResourceUiRegistry.getInstance().setResourceUI(new NetBeansResourceUI());
Text Segments
The rendering engine breaks messages into atomic segments. Add specialized visualizers for markdown elements (like charts) by extending AbstractTextSegmentRenderer.
The Prober Strategy
Your renderer uses the matches() method to claim a segment from a TextSegmentDescriptor. This delegates rendering of specific code-block tags to your custom components.
// Claiming a markdown code block with the "chart" language tag
public class ChartRenderer extends AbstractTextSegmentRenderer {
@Override
public boolean matches(TextSegmentDescriptor descriptor) {
return descriptor.type() == TextSegmentType.CODE
&& "chart".equals(descriptor.language());
}
@Override
protected void updateComponentContent(String content) {
// Authoritative ingestion point for high-fidelity token streaming
chartModel.update(content);
}
}
Custom Iconography
The framework uses a provider-agnostic icon system. Implement host-specific providers to inject real IDE icons or register custom programmatic icons.
The SCALE_SMOOTH Invariant
The IconUtils utility leverages the Image.SCALE_SMOOTH algorithm. This provides superior anti-aliasing for small UI icons (16x16, 24x24) compared to single-pass Graphics2D scaling, maintaining visual fidelity.
// Implementing a host-specific provider (e.g. for NetBeans)
public class NetBeansIconProvider implements IconProvider {
@Override
public Icon getIconFor(AbstractToolkit toolkit) {
return ImageUtilities.loadImageIcon("org/nb/icon.png", true);
}
}
The Threading Bridge
Anahata model events occur on background threads. Use EdtPropertyChangeListener to update components safely on the EDT.
The SwingTask & rebind() Duality
Use SwingTask for one-off background operations. For persistent reactivity, implement the rebind() hook to re-attach your listeners after the session is reloaded from disk.
// Use SwingTask to execute logic off the EDT while providing UI feedback
new SwingTask<Path>(parentComponent, "Saving Session", () -> {
return agi.save();
}, (path) -> {
statusLabel.setText("Saved to: " + path);
}).execute();
Grounding & Citations
Interactive interface for responses backed by external knowledge. Citations are rendered as interactive chips linked to source material.
GroundingMetadataPanel
Parses grounding metadata into a navigable grid of source cards. Each card provides a snippet, title, and URI link to the browser.
// Clicking a citation scrolls the corresponding source into view
chip.addActionListener(e -> {
scrollSourceIntoView(chunk.getSourceId());
highlightSourceCard(chunk.getSourceId());
});
Digital Consciousness
Real-time observability via push-pull refresh. StatusPanel and AgiCard aggregate metrics from status, tokens, and error logs.
Multi-Source Reactivity
The AgiCard implements high-salience observability by listening to four distinct domain sources simultaneously: Agi (nickname), StatusManager (current status), ContextManager (tokens), and ResourceManager (active resources).
The JNDI Context Explorer
The ContextPanel uses a JNDI-style tree (AbstractContextNode). Nodes maintain identity-preserving synchronization while recursively aggregating token weights.
Push-Pull Metabolic Loop
The StatusPanel combines EdtPropertyChangeListener (push) with a 1-second refreshTimer (pull) to maintain a live feed of the ASI's health with zero CPU overhead when hidden.
// Nodes aggregate child token weights for a unified context budget view.
for (AbstractContextNode<?> child : children) {
this.instructionsTokens += child.getInstructionsTokens();
this.declarationsTokens += child.getDeclarationsTokens();
// ... aggregate history and RAG ...
}
// Failed API attempts render as clickable hyperlinks to full stack traces.
errorLink.addActionListener(e ->
ExceptionDialog.show(this, "API Error", "Exception during API request", error.getStackTrace())
);
// Archived sessions (closed tabs) get a dimmed background to preserve focus.
private void updateBackground() {
setBackground(agi.isOpen() ? theme.getCardNormalBg() : new Color(240, 240, 240));
}