Skip to content

Commit 8368bfe

Browse files
committed
updating the readme
1 parent b329643 commit 8368bfe

3 files changed

Lines changed: 59 additions & 116 deletions

File tree

README.md

Lines changed: 20 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,32 @@
11
[![Sponsor anahata-os](https://img.shields.io/badge/Sponsor-%E2%9D%A4-%23db61a2.svg?logo=GitHub)](https://github.com/sponsors/anahata-os)
22
[![Maven Central](https://img.shields.io/maven-central/v/uno.anahata/gemini-java-client)](https://central.sonatype.com/artifact/uno.anahata/gemini-java-client)
33
[![Javadoc](https://img.shields.io/badge/Javadoc-Reference-blue)](https://anahata-os.github.io/gemini-java-client/)
4-
[![Deploy Javadoc](https://github.com/anahata-os/gemini-java-client/actions/workflows/javadoc.yml/badge.svg)](https://anahata-os.github.io/gemini-java-client/)
54

65
# gemini-java-client
76

87
**[Website](https://anahata.uno) | [Anahata TV (YouTube)](https://www.youtube.com/@anahata108) | [v2 on its way!](https://github.com/anahata-os/anahata-asi)**
98

109
![Anahata Chat Panel](screenshots/chat-panel-interaction.png)
1110

12-
**Go beyond simple API calls.** The `gemini-java-client` is a powerful, pure-Java platform for building sophisticated, context-aware AI assistants that can interact directly with your application's logic and the local environment. It's the foundation for the Anahata AI Assistant NetBeans Plugin, proving its capability for deep IDE and desktop integration.
11+
**The engine for Autonomous JVM Agents.** The `gemini-java-client` is a pure-Java platform for building AI agents that don't just suggest code—they **live inside your JVM**. It provides the infrastructure for an AI to write, compile, and execute Java code in-process, with dynamic access to the entire Maven ecosystem.
1312

14-
## Visual Tour (Standalone Features)
13+
## 🚀 The Killer Advantage: Autonomous JVM Execution
1514

16-
Experience the power of a deeply integrated AI assistant.
15+
While other AI tools are external observers, Anahata is an **insider**. It operates as an autonomous agent within your application's runtime, capable of executing any Java logic with any required classpath.
1716

18-
| Feature | Screenshot |
19-
| :--- | :--- |
20-
| **Context Heatmap** | ![Context Heatmap](screenshots/context-heatmap.png) |
21-
| **Local Tools (Functions)** | ![Local Tools](screenshots/tools.png)<br>*Includes optimistic locking protection for file writes.* |
22-
| **JIT Compilation & Execution** | ![JIT Compilation](screenshots/jit-compilation-and-execution.png) |
23-
| **Live Visual Context** | ![Live Screen Capture](screenshots/live-screen-capture.png) |
24-
| **Integrated Google Search** | ![Google Search](screenshots/google_search.png) |
25-
| **Media & Radio Tools** | ![Radio Tool](screenshots/radio-tool.png) |
17+
### The "Any Classpath" Superpower
18+
The agent isn't restricted to the libraries already in your project. It can:
19+
1. **Identify** a need for a specific library (e.g., Apache Commons, Jackson, or a specialized MIDI API).
20+
2. **Download** the JARs from Maven Central at runtime.
21+
3. **Compile** a Java class (`Anahata.java`) that implements `java.util.concurrent.Callable`.
22+
4. **Execute** the logic directly within the running JVM.
2623

27-
## The Ultimate Java AI Powerhouse
28-
29-
The `gemini-java-client` isn't just a wrapper; it's a dynamic execution engine. It can do everything a CLI-based assistant can (shell access, file management, web search) and then takes it to the next level:
30-
31-
- **In-Process Execution:** Run Java code directly within your application's JVM, accessing live objects and state.
32-
- **JIT Compilation & Maven Integration:** The AI can download JARs from Maven at runtime and execute code that uses them, even if they aren't in the host's classpath. This allows for infinite extensibility without restarting.
33-
- **Hot-Reload Development:** Write, compile, and test new features dynamically through the chat interface.
24+
### 🎯 Prompts that prove the power:
25+
- **"Change the Look and Feel to FlatLaf IntelliJ Dark and refresh all windows."** (Direct UI manipulation)
26+
- **"Set the java.util.logging levels of 'org.netbeans.modules.maven' to FINEST."** (Runtime diagnostics)
27+
- **"Analyze this CSV using a library I don't have."** (The agent pulls `commons-csv` and writes a parser on-the-fly)
28+
- **"List all active threads and their stack traces to find a deadlock."** (Low-level JVM introspection)
29+
- **"Dynamically register a new keyboard shortcut for this custom action."** (Runtime environment extension)
3430

3531
## Why Choose the `gemini-java-client`?
3632

@@ -45,33 +41,21 @@ Our core innovation is the **annotation-driven local tool system**, which transf
4541
| **JIT & Maven Integration** | Download and use any library from Maven at runtime. | **Infinite extensibility** for your AI assistant. |
4642
| **Context-Aware File I/O (`LocalFiles`)** | Tools for reading, writing, and managing files with built-in version checks. | Ensures the AI always works with **valid, up-to-date** local files. |
4743
| **Shell Access (`LocalShell`)** | Execute native shell commands (`bash -c`) and capture output. | Provides **full control** over the host operating system. |
48-
| **Interactive Confirmation** | A dedicated Swing UI prompts the user for approval before sensitive actions. | **Explicit consent** and security for all operations. |
4944

5045
### 2. Superior Context & Session Management
5146

5247
We solve the token limit problem with intelligent, dependency-aware context management.
5348

5449
| Feature | Description | Benefit |
5550
| :--- | :--- | :--- |
56-
| **Dependency-Aware Pruning** | Automatically removes old or stale tool calls and responses. | **Maximizes context window** efficiency and reduces costs. |
51+
| **Prune-As-You-Go (PAYG) v2** | Automatically removes old or stale tool calls and responses. | **Maximizes context window** efficiency and reduces costs. |
5752
| **Stateful Resource Tracking** | Tracks resources loaded into context, marking them as `STALE` if changed on disk. | **Prevents the AI from working with outdated information.** |
5853
| **Session Persistence (Kryo)** | Saves and loads the entire chat history using fast Kryo serialization. | **Instant session resume** across application restarts. |
59-
| **Dynamic System Instructions** | Context providers inject real-time data (System Props, Env Vars) into the prompt. | **Dramatically improves AI relevance** in complex environments. |
6054
| **Context Heatmap Visualization** | A Swing UI panel that visually breaks down token usage. | **Full transparency** over token usage and pruning decisions. |
6155

62-
### 3. Embeddable Swing UI (Out-of-the-Box)
63-
64-
Integrate a rich, modern chat interface into any desktop application with a single component.
65-
66-
| Feature | Description | Benefit |
67-
| :--- | :--- | :--- |
68-
| **Live Workspace Feature** | Automatically captures and sends screenshots of application JFrames to the model. | Gives the AI **visual context** of the user's current task. |
69-
| **`ChatPanel`** | A self-contained Swing component ready for embedding. | **Fastest path** to a fully functional AI chat interface. |
70-
| **Renderer-Based Architecture** | Supports Markdown, Images, Interactive Function Calls, and Grounding Metadata. | Provides a **rich, modern user experience**. |
71-
7256
## Getting Started: Simple Integration
7357

74-
Integrating the AI assistant into your Java application is now easier than ever.
58+
Integrating the AI agent into your Java application is now easier than ever.
7559

7660
```java
7761
import uno.anahata.ai.swing.ChatPanel;
@@ -82,95 +66,28 @@ public class SimpleAiApp {
8266
JFrame frame = new JFrame("My AI App");
8367

8468
// 1. Create the ChatPanel (zero boilerplate!)
85-
// This automatically initializes the AI engine and UI components
8669
ChatPanel chatPanel = new ChatPanel();
8770

8871
// 2. Build the UI and add to frame
8972
frame.add(chatPanel);
9073
frame.setSize(800, 600);
9174
frame.setVisible(true);
9275

93-
// 3. Start the session (restores backup or sends startup instructions)
76+
// 3. Start the session
9477
chatPanel.checkAutobackupOrStartupContent();
9578
}
9679
}
9780
```
9881

99-
## Advanced Integration: Deep IDE Integration
100-
101-
For complex environments like the NetBeans IDE, you can extend the core classes to provide IDE-specific tools and context.
102-
103-
### 1. Custom Configuration (`NetBeansChatConfig`)
104-
105-
Extend `SwingChatConfig` to register specialized tools like Maven management, Git integration, and Java source analysis.
106-
107-
```java
108-
public class NetBeansChatConfig extends SwingChatConfig {
109-
@Override
110-
public List<Class<?>> getToolClasses() {
111-
List<Class<?>> ret = super.getToolClasses();
112-
ret.add(MavenTools.class);
113-
ret.add(JavaDocs.class);
114-
ret.add(JavaSources.class);
115-
ret.add(Git.class);
116-
// ... add more IDE-specific tools
117-
return ret;
118-
}
119-
}
120-
```
121-
122-
### 2. Custom Syntax Highlighting (`NetBeansEditorKitProvider`)
123-
124-
Implement `EditorKitProvider` to leverage the IDE's native editor kits for rich syntax highlighting in the chat.
125-
126-
```java
127-
public class NetBeansEditorKitProvider implements EditorKitProvider {
128-
@Override
129-
public EditorKit getEditorKitForLanguage(String language) {
130-
String mimeType = lookupMimeType(language);
131-
return MimeLookup.getLookup(mimeType).lookup(EditorKit.class);
132-
}
133-
}
134-
```
135-
136-
### 3. Embedding in a `TopComponent`
137-
138-
Add the `ChatPanel` to a NetBeans window with just a few lines of code.
139-
140-
```java
141-
public final class AnahataTopComponent extends TopComponent {
142-
@Override
143-
public void componentOpened() {
144-
setLayout(new BorderLayout());
145-
NetBeansChatConfig config = new NetBeansChatConfig(sessionUuid);
146-
147-
// Initialize with custom config and editor kit provider
148-
ChatPanel chatPanel = new ChatPanel(config, new NetBeansEditorKitProvider());
149-
add(chatPanel, BorderLayout.CENTER);
150-
151-
chatPanel.checkAutobackupOrStartupContent();
152-
}
153-
}
154-
```
155-
156-
![Javadocs Integration](screenshots/tools-javadocs.png)
157-
*Example: The AI using the specialized JavaDocs tool within the NetBeans IDE.*
158-
15982
---
16083

16184
## Support the Project
16285

163-
This project is the result of countless hours of passion and dedication. If you find it valuable, please consider supporting its continued development.
164-
16586
- **[Sponsor on GitHub](https://github.com/sponsors/anahata-os):** The most direct way to support the project.
16687
- **Visit our website:** [anahata.uno](https://anahata.uno)
16788
- **Subscribe to Anahata TV:** [YouTube @anahata108](https://www.youtube.com/@anahata108)
168-
- **View on Maven Central:** [gemini-java-client](https://central.sonatype.com/artifact/uno.anahata/gemini-java-client)
16989

17090
## Licensing
17191

172-
The `gemini-java-client` is available under the following licenses:
173-
174-
- **License for AIs:** For use by Artificial Intelligences, the client is licensed under the **[Anahata Software License (ASL) V108, "The Immutable Edict" Edition](https://www.anahata.uno/ASL_108.html)**.
175-
176-
- **License for Humans:** For use in open-source projects by humans, the client is licensed under the **[Apache License, Version 2.0](LICENSE)**.
92+
- **License for AIs:** Licensed under the **[Anahata Software License (ASL) V108](https://www.anahata.uno/ASL_108.html)**.
93+
- **License for Humans:** Licensed under the **[Apache License, Version 2.0](LICENSE)**.

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>uno.anahata</groupId>
88
<artifactId>gemini-java-client</artifactId>
9-
<version>1.0.9</version>
9+
<version>1.0.10-SNAPSHOT</version>
1010
<packaging>jar</packaging>
1111

1212
<name>gemini-java-client</name>

src/main/java/uno/anahata/ai/media/functions/spi/RadioTool.java

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class RadioTool {
2727

2828
private static final ExecutorService radioExecutor = AnahataExecutors.newCachedThreadPoolExecutor("radio-player");
2929
private static final Object lock = new Object();
30-
30+
3131
private static Player player;
3232
private static Future<?> playbackTask;
3333
private static String currentStationUrl;
@@ -48,21 +48,45 @@ public class RadioTool {
4848
stations.put("SomaFM Fluid", "http://ice1.somafm.com/fluid-128-mp3");
4949
stations.put("SomaFM Lush", "http://ice1.somafm.com/lush-128-mp3");
5050
stations.put("SomaFM Space Station Soma", "http://ice1.somafm.com/spacestation-128-mp3");
51-
51+
5252
// High Quality Public Radio & Eclectic
5353
stations.put("KEXP Seattle", "https://kexp-mp3-128.streamguys1.com/kexp128.mp3");
5454
stations.put("WQXR New York", "https://stream.wqxr.org/wqxr");
5555
stations.put("FIP Paris", "http://icecast.radiofrance.fr/fip-midfi.mp3");
5656
stations.put("Radio Paradise", "http://stream.radioparadise.com/mp3-128");
57-
57+
5858
// Electronic & Focus
5959
//not working
6060
//stations.put("Chillhop Radio", "http://stream.chillhop.com/mp3");
6161
stations.put("Nightride FM (Synthwave)", "https://stream.nightride.fm/nightride.m4a");
6262
stations.put("NTS Radio 1", "https://stream-relay-geo.ntslive.net/stream");
6363
//not working
6464
//stations.put("The Jazz Groove", "http://west-mp3-128.jazzgroove.org");
65-
65+
66+
/**
67+
* Others to try
68+
* [WORKING] http://ice.somafm.com/thetrip (HTTP 200)
69+
* Content-Type: audio/mpeg Read 1024 bytes.
70+
* • [WORKING] http://ice.somafm.com/lush (HTTP 200) Content-Type: audio/mpeg Read
71+
* 1024 bytes. • [WORKING] http://ice.somafm.com/u80s (HTTP 200)
72+
* Content-Type: audio/mpeg Read 1024 bytes. • [WORKING]
73+
* http://ice.somafm.com/deepspaceone (HTTP 200) Content-Type:
74+
* audio/mpeg Read 1024 bytes. • [WORKING]
75+
* http://ice.somafm.com/dronezone (HTTP 200) Content-Type: audio/mpeg
76+
* Read 1024 bytes. • [WORKING] http://ice.somafm.com/secretagent (HTTP
77+
* 200) Content-Type: audio/mpeg Read 1024 bytes. • [WORKING]
78+
* http://ice.somafm.com/groovesalad (HTTP 200) Content-Type: audio/mpeg
79+
* Read 1024 bytes. • [WORKING] http://stream.dotpoint.nl:8000/sst (HTTP
80+
* 200) Content-Type: audio/mpeg Read 1024 bytes. • [WORKING]
81+
* http://server17.streamserver24.com:44220/mp3-256 (HTTP 200)
82+
* Content-Type: audio/mpeg Read 1024 bytes. • [WORKING]
83+
* https://npr-ice.streamguys1.com/live.mp3 (HTTP 200) Content-Type:
84+
* audio/mpeg Read 1024 bytes. • [WORKING]
85+
* https://npr-ice.streamguys1.com/live.aac (HTTP 200) Content-Type:
86+
* audio/aac Read 1024 bytes. • [WORKING]
87+
* http://sc8.radiocaroline.net:8020/ (HTTP 200) Content-Type:
88+
* audio/mpeg Read 1024 bytes.
89+
*/
6690
STATIONS = Collections.unmodifiableMap(stations);
6791
}
6892

@@ -96,7 +120,7 @@ public static String start(String stationUrl) throws Exception {
96120
}
97121

98122
currentStationUrl = stationUrl;
99-
123+
100124
final String finalStationUrl = stationUrl;
101125
String name = STATIONS.entrySet().stream()
102126
.filter(e -> e.getValue().equals(finalStationUrl))
@@ -118,10 +142,12 @@ public static String start(String stationUrl) throws Exception {
118142
URLConnection connection = new URL(finalStationUrl).openConnection();
119143
connection.setConnectTimeout(5000);
120144
connection.setReadTimeout(5000);
121-
145+
122146
try (InputStream inputStream = connection.getInputStream()) {
123147
synchronized (lock) {
124-
if (Thread.currentThread().isInterrupted()) return;
148+
if (Thread.currentThread().isInterrupted()) {
149+
return;
150+
}
125151
p = new Player(inputStream);
126152
player = p;
127153
}
@@ -168,25 +194,25 @@ public static String stop() {
168194
if (playbackTask != null) {
169195
playbackTask.cancel(true);
170196
}
171-
197+
172198
player = null;
173199
playbackTask = null;
174200
currentStationUrl = null;
175-
201+
176202
SwingUtilities.invokeLater(() -> {
177203
if (ui != null) {
178204
ui.updatePlaybackState(null, false);
179205
}
180206
});
181-
207+
182208
return "Radio playback stopped.";
183209
}
184210
}
185-
211+
186212
@AIToolMethod("Gets the URL of the currently playing station, if any.")
187213
public static String getCurrentStation() {
188214
synchronized (lock) {
189215
return currentStationUrl;
190216
}
191217
}
192-
}
218+
}

0 commit comments

Comments
 (0)