Skip to content

Commit 287c739

Browse files
HDDS-14816. Add Recon AI Assistant backend foundation with Google Gemini integration.
1 parent b0b2a25 commit 287c739

19 files changed

Lines changed: 8684 additions & 1 deletion

hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/ReconControllerModule.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ protected void configure() {
129129
install(new ReconOmTaskBindingModule());
130130
install(new ReconDaoBindingModule());
131131
bind(ReconTaskStatusUpdaterManager.class).in(Singleton.class);
132+
install(new org.apache.hadoop.ozone.recon.chatbot.ChatbotModule());
132133

133134
bind(ReconTaskController.class)
134135
.to(ReconTaskControllerImpl.class).in(Singleton.class);

hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/ReconRestServletModule.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ public class ReconRestServletModule extends ServletModule {
5454
"v1").build().toString();
5555
public static final String API_PACKAGE = "org.apache.hadoop.ozone.recon.api";
5656

57+
public static final String CHATBOT_API_PACKAGE = "org.apache.hadoop.ozone.recon.chatbot.api";
58+
5759
private static final Logger LOG =
5860
LoggerFactory.getLogger(ReconRestServletModule.class);
5961

@@ -65,7 +67,7 @@ public ReconRestServletModule(ConfigurationSource conf) {
6567

6668
@Override
6769
protected void configureServlets() {
68-
configureApi(BASE_API_PATH, API_PACKAGE);
70+
configureApi(BASE_API_PATH, API_PACKAGE, CHATBOT_API_PACKAGE);
6971
}
7072

7173
private void configureApi(String baseApiPath, String... packages) {
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
* <p>
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* <p>
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.hadoop.ozone.recon.chatbot;
19+
20+
import org.apache.hadoop.hdds.annotation.InterfaceAudience;
21+
import org.apache.hadoop.hdds.annotation.InterfaceStability;
22+
23+
/**
24+
* Configuration keys for Recon Chatbot service.
25+
*/
26+
@InterfaceAudience.Private
27+
@InterfaceStability.Unstable
28+
public final class ChatbotConfigKeys {
29+
30+
private ChatbotConfigKeys() {
31+
// No instances
32+
}
33+
34+
public static final String OZONE_RECON_CHATBOT_PREFIX = "ozone.recon.chatbot.";
35+
36+
// ── Feature toggle ──────────────────────────────────────────
37+
public static final String OZONE_RECON_CHATBOT_ENABLED = OZONE_RECON_CHATBOT_PREFIX + "enabled";
38+
public static final boolean OZONE_RECON_CHATBOT_ENABLED_DEFAULT = false;
39+
40+
// ── Provider selection ──────────────────────────────────────
41+
/** Active default provider: openai, gemini, anthropic. */
42+
public static final String OZONE_RECON_CHATBOT_PROVIDER = OZONE_RECON_CHATBOT_PREFIX + "provider";
43+
public static final String OZONE_RECON_CHATBOT_PROVIDER_DEFAULT = "gemini";
44+
45+
// ── Default model ───────────────────────────────────────────
46+
public static final String OZONE_RECON_CHATBOT_DEFAULT_MODEL = OZONE_RECON_CHATBOT_PREFIX + "default.model";
47+
public static final String OZONE_RECON_CHATBOT_DEFAULT_MODEL_DEFAULT = "gemini-2.5-flash";
48+
49+
// ── HTTP timeout for provider calls ─────────────────────────
50+
public static final String OZONE_RECON_CHATBOT_TIMEOUT_MS = OZONE_RECON_CHATBOT_PREFIX + "timeout.ms";
51+
public static final int OZONE_RECON_CHATBOT_TIMEOUT_MS_DEFAULT = 120000;
52+
53+
// ── Per-provider API keys (resolved via JCEKS / CredentialHelper) ──
54+
public static final String OZONE_RECON_CHATBOT_OPENAI_API_KEY = OZONE_RECON_CHATBOT_PREFIX + "openai.api.key";
55+
public static final String OZONE_RECON_CHATBOT_GEMINI_API_KEY = OZONE_RECON_CHATBOT_PREFIX + "gemini.api.key";
56+
public static final String OZONE_RECON_CHATBOT_ANTHROPIC_API_KEY = OZONE_RECON_CHATBOT_PREFIX
57+
+ "anthropic.api.key";
58+
59+
// ── Per-provider base URL overrides (optional) ──────────────
60+
public static final String OZONE_RECON_CHATBOT_OPENAI_BASE_URL = OZONE_RECON_CHATBOT_PREFIX + "openai.base.url";
61+
public static final String OZONE_RECON_CHATBOT_OPENAI_BASE_URL_DEFAULT = "https://api.openai.com";
62+
63+
public static final String OZONE_RECON_CHATBOT_GEMINI_BASE_URL = OZONE_RECON_CHATBOT_PREFIX + "gemini.base.url";
64+
public static final String OZONE_RECON_CHATBOT_GEMINI_BASE_URL_DEFAULT = "https://generativelanguage.googleapis.com";
65+
66+
public static final String OZONE_RECON_CHATBOT_ANTHROPIC_BASE_URL = OZONE_RECON_CHATBOT_PREFIX
67+
+ "anthropic.base.url";
68+
public static final String OZONE_RECON_CHATBOT_ANTHROPIC_BASE_URL_DEFAULT = "https://api.anthropic.com";
69+
70+
// ── Execution policy ────────────────────────────────────────
71+
public static final String OZONE_RECON_CHATBOT_EXEC_MAX_RECORDS = OZONE_RECON_CHATBOT_PREFIX
72+
+ "exec.max.records";
73+
public static final int OZONE_RECON_CHATBOT_EXEC_MAX_RECORDS_DEFAULT = 1000;
74+
75+
public static final String OZONE_RECON_CHATBOT_EXEC_MAX_PAGES = OZONE_RECON_CHATBOT_PREFIX + "exec.max.pages";
76+
public static final int OZONE_RECON_CHATBOT_EXEC_MAX_PAGES_DEFAULT = 5;
77+
78+
public static final String OZONE_RECON_CHATBOT_EXEC_PAGE_SIZE = OZONE_RECON_CHATBOT_PREFIX + "exec.page.size";
79+
public static final int OZONE_RECON_CHATBOT_EXEC_PAGE_SIZE_DEFAULT = 200;
80+
81+
public static final String OZONE_RECON_CHATBOT_EXEC_REQUIRE_SAFE_SCOPE = OZONE_RECON_CHATBOT_PREFIX
82+
+ "exec.require.safe.scope";
83+
public static final boolean OZONE_RECON_CHATBOT_EXEC_REQUIRE_SAFE_SCOPE_DEFAULT = true;
84+
85+
// ── Agent configuration ─────────────────────────────────────
86+
public static final String OZONE_RECON_CHATBOT_MAX_TOOL_CALLS = OZONE_RECON_CHATBOT_PREFIX + "max.tool.calls";
87+
public static final int OZONE_RECON_CHATBOT_MAX_TOOL_CALLS_DEFAULT = 5;
88+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
* <p>
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* <p>
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.hadoop.ozone.recon.chatbot;
19+
20+
import com.google.inject.AbstractModule;
21+
import com.google.inject.Scopes;
22+
import org.apache.hadoop.ozone.recon.chatbot.agent.ChatbotAgent;
23+
import org.apache.hadoop.ozone.recon.chatbot.agent.ToolExecutor;
24+
import org.apache.hadoop.ozone.recon.chatbot.api.ChatbotEndpoint;
25+
import org.apache.hadoop.ozone.recon.chatbot.llm.LLMProvider;
26+
import org.apache.hadoop.ozone.recon.chatbot.llm.LLMProviderRouter;
27+
import org.apache.hadoop.ozone.recon.chatbot.security.CredentialHelper;
28+
29+
/**
30+
* Guice module for Chatbot dependency injection.
31+
*/
32+
public class ChatbotModule extends AbstractModule {
33+
34+
@Override
35+
protected void configure() {
36+
// Bind credential helper (JCEKS key management)
37+
bind(CredentialHelper.class).in(Scopes.SINGLETON);
38+
39+
// Bind LLM provider — router delegates to direct providers
40+
bind(LLMProvider.class).to(LLMProviderRouter.class).in(Scopes.SINGLETON);
41+
42+
// Bind agent components
43+
bind(ToolExecutor.class).in(Scopes.SINGLETON);
44+
bind(ChatbotAgent.class).in(Scopes.SINGLETON);
45+
46+
// Bind API endpoint
47+
bind(ChatbotEndpoint.class).in(Scopes.SINGLETON);
48+
}
49+
}

0 commit comments

Comments
 (0)