Skip to content

Commit b8306db

Browse files
feat(session): add upgrade API
Sync-Source-Commit: 0cfb8c56638ebb5e40c8046acddfc9bf6e367ddb Hand-Written-Reason: No Ark-APIs provenance marker; treated as a hand-written source commit. Release-Version: 0.10.0
1 parent 8af3ed7 commit b8306db

5 files changed

Lines changed: 136 additions & 8 deletions

File tree

‎src/main/java/com/volcengine/ark/runtime/models/session/AgentWithUpgrades.java‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -265,15 +265,15 @@ public AgentWithUpgrades addToolsItem(Map<String, Object> toolsItem) {
265265
*/
266266
@javax.annotation.Nullable
267267
@JsonProperty(value = JSON_PROPERTY_TOOLS, required = false)
268-
@JsonInclude(value = JsonInclude.Include.NON_EMPTY)
268+
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
269269

270270
public List<Map<String, Object>> getTools() {
271271
return tools;
272272
}
273273

274274

275275
@JsonProperty(value = JSON_PROPERTY_TOOLS, required = false)
276-
@JsonInclude(value = JsonInclude.Include.NON_EMPTY)
276+
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
277277
public void setTools(@javax.annotation.Nullable List<Map<String, Object>> tools) {
278278
this.tools = tools;
279279
}
@@ -298,15 +298,15 @@ public AgentWithUpgrades addMcpServersItem(Map<String, Object> mcpServersItem) {
298298
*/
299299
@javax.annotation.Nullable
300300
@JsonProperty(value = JSON_PROPERTY_MCP_SERVERS, required = false)
301-
@JsonInclude(value = JsonInclude.Include.NON_EMPTY)
301+
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
302302

303303
public List<Map<String, Object>> getMcpServers() {
304304
return mcpServers;
305305
}
306306

307307

308308
@JsonProperty(value = JSON_PROPERTY_MCP_SERVERS, required = false)
309-
@JsonInclude(value = JsonInclude.Include.NON_EMPTY)
309+
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
310310
public void setMcpServers(@javax.annotation.Nullable List<Map<String, Object>> mcpServers) {
311311
this.mcpServers = mcpServers;
312312
}
@@ -331,15 +331,15 @@ public AgentWithUpgrades addSkillsItem(Map<String, Object> skillsItem) {
331331
*/
332332
@javax.annotation.Nullable
333333
@JsonProperty(value = JSON_PROPERTY_SKILLS, required = false)
334-
@JsonInclude(value = JsonInclude.Include.NON_EMPTY)
334+
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
335335

336336
public List<Map<String, Object>> getSkills() {
337337
return skills;
338338
}
339339

340340

341341
@JsonProperty(value = JSON_PROPERTY_SKILLS, required = false)
342-
@JsonInclude(value = JsonInclude.Include.NON_EMPTY)
342+
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
343343
public void setSkills(@javax.annotation.Nullable List<Map<String, Object>> skills) {
344344
this.skills = skills;
345345
}

‎src/main/java/com/volcengine/ark/runtime/models/session/CreateSessionUpgradeRequest.java‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,15 @@ public CreateSessionUpgradeRequest addVaultIdsItem(String vaultIdsItem) {
123123
*/
124124
@javax.annotation.Nullable
125125
@JsonProperty(value = JSON_PROPERTY_VAULT_IDS, required = false)
126-
@JsonInclude(value = JsonInclude.Include.NON_EMPTY)
126+
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
127127

128128
public List<String> getVaultIds() {
129129
return vaultIds;
130130
}
131131

132132

133133
@JsonProperty(value = JSON_PROPERTY_VAULT_IDS, required = false)
134-
@JsonInclude(value = JsonInclude.Include.NON_EMPTY)
134+
@JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
135135
public void setVaultIds(@javax.annotation.Nullable List<String> vaultIds) {
136136
this.vaultIds = vaultIds;
137137
}

‎src/main/java/com/volcengine/ark/runtime/service/ArkApi.java‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import com.volcengine.ark.runtime.models.responses.ResponsesRequest;
5050
import com.volcengine.ark.runtime.models.session.CreateSessionRequest;
5151
import com.volcengine.ark.runtime.models.session.CreateSessionResourceRequest;
52+
import com.volcengine.ark.runtime.models.session.CreateSessionUpgradeRequest;
5253
import com.volcengine.ark.runtime.models.session.DeleteSessionResponse;
5354
import com.volcengine.ark.runtime.models.session.ListSessionEventsResponse;
5455
import com.volcengine.ark.runtime.models.session.ListSessionResourcesResponse;
@@ -382,6 +383,9 @@ Single<ListSessionsResponse> listSessions(@Query("agent_id") String agentId,
382383
@POST("/api/v3/sessions/{sessionId}")
383384
Single<Session> updateSession(@Path("sessionId") String sessionId, @Body UpdateSessionRequest request, @HeaderMap Map<String, String> customHeaders);
384385

386+
@POST("/api/v3/sessions/{sessionId}/upgrades")
387+
Single<Session> upgradeSession(@Path("sessionId") String sessionId, @Body CreateSessionUpgradeRequest request, @HeaderMap Map<String, String> customHeaders);
388+
385389
@DELETE("/api/v3/sessions/{sessionId}")
386390
Single<DeleteSessionResponse> deleteSession(@Path("sessionId") String sessionId, @HeaderMap Map<String, String> customHeaders);
387391

‎src/main/java/com/volcengine/ark/runtime/service/ArkService.java‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
import com.volcengine.ark.runtime.models.responses.ResponsesRequest;
6969
import com.volcengine.ark.runtime.models.session.CreateSessionRequest;
7070
import com.volcengine.ark.runtime.models.session.CreateSessionResourceRequest;
71+
import com.volcengine.ark.runtime.models.session.CreateSessionUpgradeRequest;
7172
import com.volcengine.ark.runtime.models.session.DeleteSessionResponse;
7273
import com.volcengine.ark.runtime.models.session.ListSessionEventsResponse;
7374
import com.volcengine.ark.runtime.models.session.ListSessionResourcesResponse;
@@ -830,6 +831,10 @@ public Session updateSession(String sessionId, UpdateSessionRequest request) {
830831
return execute(api.updateSession(sessionId, request, new HashMap<>()));
831832
}
832833

834+
public Session upgradeSession(String sessionId, CreateSessionUpgradeRequest request) {
835+
return execute(api.upgradeSession(sessionId, request, new HashMap<>()));
836+
}
837+
833838
public DeleteSessionResponse deleteSession(String sessionId) {
834839
return execute(api.deleteSession(sessionId, new HashMap<>()));
835840
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Copyright (c) 2026 ByteDance Ltd. and/or its affiliates.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package com.volcengine.ark.runtime.service;
5+
6+
import static org.junit.Assert.assertEquals;
7+
import static org.junit.Assert.assertFalse;
8+
import static org.junit.Assert.assertSame;
9+
import static org.junit.Assert.assertTrue;
10+
11+
import com.volcengine.ark.runtime.models.session.AgentWithUpgrades;
12+
import com.volcengine.ark.runtime.models.session.CreateSessionUpgradeRequest;
13+
import com.volcengine.ark.runtime.models.session.Session;
14+
import io.reactivex.Single;
15+
import java.lang.annotation.Annotation;
16+
import java.lang.reflect.InvocationHandler;
17+
import java.lang.reflect.Method;
18+
import java.lang.reflect.Proxy;
19+
import java.util.Collections;
20+
import java.util.Map;
21+
import org.junit.Test;
22+
import retrofit2.http.POST;
23+
import retrofit2.http.Path;
24+
25+
public class ArkServiceSessionUpgradeTest {
26+
@Test
27+
public void upgradeSessionPassesRequestAndReturnsSession() {
28+
CapturingArkApi handler = new CapturingArkApi();
29+
ArkService service = new ArkService(api(handler));
30+
CreateSessionUpgradeRequest request = request();
31+
32+
Session out = service.upgradeSession("sess-1", request);
33+
34+
assertEquals("sess-1", out.getId());
35+
assertEquals("sess-1", handler.args[0]);
36+
assertSame(request, handler.args[1]);
37+
assertTrue(((Map<?, ?>) handler.args[2]).isEmpty());
38+
}
39+
40+
@Test
41+
public void upgradeSessionApiKeepsPostContract() throws Exception {
42+
Method method = ArkApi.class.getMethod(
43+
"upgradeSession",
44+
String.class,
45+
CreateSessionUpgradeRequest.class,
46+
Map.class
47+
);
48+
49+
assertEquals("/api/v3/sessions/{sessionId}/upgrades", method.getAnnotation(POST.class).value());
50+
assertEquals("sessionId", findAnnotation(method.getParameterAnnotations()[0], Path.class).value());
51+
}
52+
53+
@Test
54+
public void upgradeSessionPreservesExplicitEmptyArrays() throws Exception {
55+
String json = ArkService.defaultObjectMapper().writeValueAsString(request());
56+
57+
assertTrue(json.contains("\"tools\":[]"));
58+
assertTrue(json.contains("\"vault_ids\":[]"));
59+
assertFalse(json.contains("initial_events"));
60+
}
61+
62+
private static CreateSessionUpgradeRequest request() {
63+
AgentWithUpgrades agent = AgentWithUpgrades.builder()
64+
.type(AgentWithUpgrades.TypeEnum.AGENT_WITH_UPGRADES)
65+
.id("agent-1")
66+
.tools(Collections.emptyList())
67+
.build();
68+
return CreateSessionUpgradeRequest.builder()
69+
.agent(agent)
70+
.vaultIds(Collections.emptyList())
71+
.build();
72+
}
73+
74+
private static ArkApi api(CapturingArkApi handler) {
75+
return (ArkApi) Proxy.newProxyInstance(
76+
ArkApi.class.getClassLoader(),
77+
new Class<?>[] {ArkApi.class},
78+
handler
79+
);
80+
}
81+
82+
private static <T extends Annotation> T findAnnotation(Annotation[] annotations, Class<T> type) {
83+
for (Annotation annotation : annotations) {
84+
if (type.isInstance(annotation)) {
85+
return type.cast(annotation);
86+
}
87+
}
88+
throw new AssertionError("missing annotation " + type.getSimpleName());
89+
}
90+
91+
private static final class CapturingArkApi implements InvocationHandler {
92+
private Object[] args;
93+
94+
@Override
95+
public Object invoke(Object proxy, Method method, Object[] args) {
96+
if (method.getDeclaringClass() == Object.class) {
97+
return objectMethod(proxy, method, args);
98+
}
99+
if (!"upgradeSession".equals(method.getName())) {
100+
throw new AssertionError("unexpected API call: " + method.getName());
101+
}
102+
this.args = args;
103+
return Single.just(new Session().id("sess-1"));
104+
}
105+
106+
private Object objectMethod(Object proxy, Method method, Object[] args) {
107+
if ("toString".equals(method.getName())) {
108+
return "capturing ArkApi proxy";
109+
}
110+
if ("hashCode".equals(method.getName())) {
111+
return System.identityHashCode(proxy);
112+
}
113+
if ("equals".equals(method.getName())) {
114+
return proxy == args[0];
115+
}
116+
throw new AssertionError("unexpected Object method: " + method.getName());
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)