4040 * </ul>
4141 *
4242 * <h3>构造器选择</h3>
43- * <p>提供 8 个重载覆盖三类场景 :</p>
43+ * <p>提供多种构造器覆盖三类场景 :</p>
4444 * <ul>
4545 * <li>仅 HTTP / 仅 CLI:传入单个子配置,禁用另一子系统</li>
4646 * <li>HTTP + CLI:传入两个子配置,子系统都按各自 {@code enabled} 决定</li>
@@ -71,6 +71,7 @@ public class OpenClawClient implements AutoCloseable {
7171 private final OpenClawToolInvokeClient toolsInvokeClient ;
7272 private final OpenClawCli cli ;
7373 private final OpenClawGatewayWsClient wsClient ;
74+ private final OkHttpClient ownedHttpClient ;
7475
7576 // ============================================================
7677 // 构造器(单配置 / 双配置 / 组合配置 × 自动或强制)
@@ -80,35 +81,44 @@ public class OpenClawClient implements AutoCloseable {
8081 * 仅 HTTP 子系统(CLI 禁用)。自动创建默认 {@link ObjectMapper} 与 {@link OkHttpClient}。
8182 */
8283 public OpenClawClient (OpenClawHttpClientConfig httpConfig ) {
83- this (httpConfig , new OpenClawCliConfig (), new ObjectMapper (), new OkHttpClient ());
84+ this (httpConfig , new OpenClawCliConfig (), new ObjectMapper (),
85+ OpenClawOkHttpClientFactory .create (httpConfig ), true );
86+ }
87+
88+ /**
89+ * 仅 HTTP 子系统,使用调用方管理的共享 {@link OkHttpClient}。
90+ * <p>适用于直接注入 Spring 容器中由 okhttp3-extension/starter 配置的客户端。</p>
91+ */
92+ public OpenClawClient (OpenClawHttpClientConfig httpConfig , OkHttpClient httpClient ) {
93+ this (httpConfig , new ObjectMapper (), httpClient );
8494 }
8595
8696 /**
8797 * 仅 HTTP 子系统(CLI 禁用),强制注入共享 {@link ObjectMapper} 与 {@link OkHttpClient}。
8898 */
8999 public OpenClawClient (OpenClawHttpClientConfig httpConfig , ObjectMapper objectMapper , OkHttpClient httpClient ) {
90- this (httpConfig , new OpenClawCliConfig (), objectMapper , httpClient );
100+ this (httpConfig , new OpenClawCliConfig (), objectMapper , httpClient , false );
91101 }
92102
93103 /**
94104 * 仅 CLI 子系统(HTTP 禁用)。自动创建默认 {@link ObjectMapper} 与 {@link OkHttpClient}。
95105 */
96106 public OpenClawClient (OpenClawCliConfig cliConfig ) {
97- this (new OpenClawHttpClientConfig (), cliConfig , new ObjectMapper (), new OkHttpClient ());
107+ this (new OpenClawHttpClientConfig (), cliConfig , new ObjectMapper (), new OkHttpClient (), true );
98108 }
99109
100110 /**
101111 * 仅 CLI 子系统(HTTP 禁用),强制注入共享 {@link ObjectMapper} 与 {@link OkHttpClient}。
102112 */
103113 public OpenClawClient (OpenClawCliConfig cliConfig , ObjectMapper objectMapper , OkHttpClient httpClient ) {
104- this (new OpenClawHttpClientConfig (), cliConfig , objectMapper , httpClient );
114+ this (new OpenClawHttpClientConfig (), cliConfig , objectMapper , httpClient , false );
105115 }
106116
107117 /**
108118 * HTTP + CLI 子系统。自动创建默认 {@link ObjectMapper} 与 {@link OkHttpClient}。
109119 */
110120 public OpenClawClient (OpenClawHttpClientConfig httpConfig , OpenClawCliConfig cliConfig ) {
111- this (httpConfig , cliConfig , new ObjectMapper (), new OkHttpClient () );
121+ this (httpConfig , cliConfig , new ObjectMapper (), OpenClawOkHttpClientFactory . create ( httpConfig ), true );
112122 }
113123
114124 /**
@@ -121,10 +131,16 @@ public OpenClawClient(OpenClawHttpClientConfig httpConfig, OpenClawCliConfig cli
121131 */
122132 public OpenClawClient (OpenClawHttpClientConfig httpConfig , OpenClawCliConfig cliConfig ,
123133 ObjectMapper objectMapper , OkHttpClient httpClient ) {
134+ this (httpConfig , cliConfig , objectMapper , httpClient , false );
135+ }
136+
137+ private OpenClawClient (OpenClawHttpClientConfig httpConfig , OpenClawCliConfig cliConfig ,
138+ ObjectMapper objectMapper , OkHttpClient httpClient , boolean ownsHttpClient ) {
124139 Objects .requireNonNull (httpConfig , "httpConfig" );
125140 Objects .requireNonNull (cliConfig , "cliConfig" );
126141 Objects .requireNonNull (objectMapper , "objectMapper" );
127142 Objects .requireNonNull (httpClient , "httpClient" );
143+ this .ownedHttpClient = ownsHttpClient ? httpClient : null ;
128144
129145 boolean httpEnabled = httpConfig .isEnabled ();
130146 boolean cliEnabled = cliConfig .isEnabled ();
@@ -165,7 +181,16 @@ public OpenClawClient(OpenClawClientConfig config) {
165181 this (Objects .requireNonNull (config , "config" ).getHttp (),
166182 config .getCli (),
167183 new ObjectMapper (),
168- new OkHttpClient ());
184+ OpenClawOkHttpClientFactory .create (config .getHttp ()),
185+ true );
186+ }
187+
188+ /**
189+ * 使用组合配置和调用方管理的共享 {@link OkHttpClient}。
190+ * <p>SDK 关闭时不会关闭、清空或重建该客户端的连接池和调度器。</p>
191+ */
192+ public OpenClawClient (OpenClawClientConfig config , OkHttpClient httpClient ) {
193+ this (config , new ObjectMapper (), httpClient );
169194 }
170195
171196 /**
@@ -175,7 +200,8 @@ public OpenClawClient(OpenClawClientConfig config, ObjectMapper objectMapper, Ok
175200 this (Objects .requireNonNull (config , "config" ).getHttp (),
176201 config .getCli (),
177202 objectMapper ,
178- httpClient );
203+ httpClient ,
204+ false );
179205 }
180206
181207 /**
@@ -198,6 +224,7 @@ public OpenClawClient(OpenClawHttpClientConfig httpConfig,
198224 this .toolsInvokeClient = toolsInvokeClient ;
199225 this .cli = cli ;
200226 this .wsClient = wsClient ;
227+ this .ownedHttpClient = null ;
201228 }
202229
203230 /**
@@ -386,6 +413,16 @@ public OpenClawChatClient chat() {
386413 return chatClient ;
387414 }
388415
416+ /**
417+ * 获取 HTTP 子系统实际使用的 {@link OkHttpClient}。
418+ * <p>通过注入构造器传入时返回同一个实例,其生命周期仍由调用方管理。</p>
419+ *
420+ * @return HTTP 子系统使用的 OkHttpClient;HTTP 子系统禁用时返回 {@code null}
421+ */
422+ public OkHttpClient getOkHttpClient () {
423+ return Objects .nonNull (chatClient ) ? chatClient .getHttpClient () : null ;
424+ }
425+
389426 /**
390427 * 获取 Embeddings 客户端。
391428 */
@@ -618,6 +655,7 @@ public void close() {
618655 closeQuietly (responsesClient );
619656 closeQuietly (toolsInvokeClient );
620657 closeQuietly (wsClient );
658+ OpenClawOkHttpClientFactory .shutdown (ownedHttpClient );
621659 }
622660
623661 /**
0 commit comments