Skip to content

Commit b11b20e

Browse files
Copilotedburns
andauthored
Port 4 reference implementation commits: per-session auth, idle timeout, defaultAgent.excludedTools, permission kind values
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/34e41e1a-798d-4058-87fa-d6e929b2f783 Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
1 parent f3e709c commit b11b20e

20 files changed

Lines changed: 788 additions & 45 deletions

.lastmerge

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
922959f4a7b83509c3620d4881733c6c5677f00c
1+
dd2dcbc439256acfb9feb2cff07c0b9c820091b8

src/main/java/com/github/copilot/sdk/CliServerManager.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ ProcessInfo startCliServer() throws IOException, InterruptedException {
8383
args.add("--no-auto-login");
8484
}
8585

86+
if (options.getSessionIdleTimeoutSeconds() != null && options.getSessionIdleTimeoutSeconds() > 0) {
87+
args.add("--session-idle-timeout");
88+
args.add(String.valueOf(options.getSessionIdleTimeoutSeconds()));
89+
}
90+
8691
List<String> command = resolveCliCommand(cliPath, args);
8792

8893
var pb = new ProcessBuilder(command);

src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ static CreateSessionRequest buildCreateRequest(SessionConfig config, String sess
118118
request.setIncludeSubAgentStreamingEvents(config.getIncludeSubAgentStreamingEvents());
119119
request.setMcpServers(config.getMcpServers());
120120
request.setCustomAgents(config.getCustomAgents());
121+
request.setDefaultAgent(config.getDefaultAgent());
121122
request.setAgent(config.getAgent());
122123
request.setInfiniteSessions(config.getInfiniteSessions());
123124
request.setSkillDirectories(config.getSkillDirectories());
@@ -135,6 +136,7 @@ static CreateSessionRequest buildCreateRequest(SessionConfig config, String sess
135136
if (config.getOnElicitationRequest() != null) {
136137
request.setRequestElicitation(true);
137138
}
139+
request.setGitHubToken(config.getGitHubToken());
138140

139141
return request;
140142
}
@@ -194,6 +196,7 @@ static ResumeSessionRequest buildResumeRequest(String sessionId, ResumeSessionCo
194196
request.setIncludeSubAgentStreamingEvents(config.getIncludeSubAgentStreamingEvents());
195197
request.setMcpServers(config.getMcpServers());
196198
request.setCustomAgents(config.getCustomAgents());
199+
request.setDefaultAgent(config.getDefaultAgent());
197200
request.setAgent(config.getAgent());
198201
request.setSkillDirectories(config.getSkillDirectories());
199202
request.setDisabledSkills(config.getDisabledSkills());
@@ -209,6 +212,7 @@ static ResumeSessionRequest buildResumeRequest(String sessionId, ResumeSessionCo
209212
if (config.getOnElicitationRequest() != null) {
210213
request.setRequestElicitation(true);
211214
}
215+
request.setGitHubToken(config.getGitHubToken());
212216

213217
return request;
214218
}

src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public class CopilotClientOptions {
5252
private Supplier<CompletableFuture<List<ModelInfo>>> onListModels;
5353
private int port;
5454
private TelemetryConfig telemetry;
55+
private Integer sessionIdleTimeoutSeconds;
5556
private Boolean useLoggedInUser;
5657
private boolean useStdio = true;
5758

@@ -430,6 +431,37 @@ public CopilotClientOptions setTelemetry(TelemetryConfig telemetry) {
430431
return this;
431432
}
432433

434+
/**
435+
* Gets the server-wide idle timeout for sessions in seconds.
436+
*
437+
* @return the session idle timeout in seconds, or {@code null} to disable
438+
* (sessions live indefinitely)
439+
* @since 1.3.0
440+
*/
441+
public Integer getSessionIdleTimeoutSeconds() {
442+
return sessionIdleTimeoutSeconds;
443+
}
444+
445+
/**
446+
* Sets the server-wide idle timeout for sessions in seconds.
447+
* <p>
448+
* Sessions without activity for this duration are automatically cleaned up. Set
449+
* to {@code 0} or leave as {@code null} to disable (sessions live
450+
* indefinitely).
451+
* <p>
452+
* This option is only used when the SDK spawns the CLI process; it is ignored
453+
* when connecting to an external server via {@link #setCliUrl(String)}.
454+
*
455+
* @param sessionIdleTimeoutSeconds
456+
* the idle timeout in seconds, or {@code null} to disable
457+
* @return this options instance for method chaining
458+
* @since 1.3.0
459+
*/
460+
public CopilotClientOptions setSessionIdleTimeoutSeconds(Integer sessionIdleTimeoutSeconds) {
461+
this.sessionIdleTimeoutSeconds = sessionIdleTimeoutSeconds;
462+
return this;
463+
}
464+
433465
/**
434466
* Returns whether to use the logged-in user for authentication.
435467
*
@@ -508,6 +540,7 @@ public CopilotClientOptions clone() {
508540
copy.logLevel = this.logLevel;
509541
copy.onListModels = this.onListModels;
510542
copy.port = this.port;
543+
copy.sessionIdleTimeoutSeconds = this.sessionIdleTimeoutSeconds;
511544
copy.telemetry = this.telemetry;
512545
copy.useLoggedInUser = this.useLoggedInUser;
513546
copy.useStdio = this.useStdio;

src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ public final class CreateSessionRequest {
7979
@JsonProperty("customAgents")
8080
private List<CustomAgentConfig> customAgents;
8181

82+
@JsonProperty("defaultAgent")
83+
private DefaultAgentConfig defaultAgent;
84+
8285
@JsonProperty("agent")
8386
private String agent;
8487

@@ -106,6 +109,9 @@ public final class CreateSessionRequest {
106109
@JsonProperty("modelCapabilities")
107110
private ModelCapabilitiesOverride modelCapabilities;
108111

112+
@JsonProperty("gitHubToken")
113+
private String gitHubToken;
114+
109115
/** Gets the model name. @return the model */
110116
public String getModel() {
111117
return model;
@@ -278,6 +284,18 @@ public void setCustomAgents(List<CustomAgentConfig> customAgents) {
278284
this.customAgents = customAgents;
279285
}
280286

287+
/** Gets the default agent config. @return the default agent config */
288+
public DefaultAgentConfig getDefaultAgent() {
289+
return defaultAgent;
290+
}
291+
292+
/**
293+
* Sets the default agent config. @param defaultAgent the default agent config
294+
*/
295+
public void setDefaultAgent(DefaultAgentConfig defaultAgent) {
296+
this.defaultAgent = defaultAgent;
297+
}
298+
281299
/** Gets the pre-selected agent name. @return the agent name */
282300
public String getAgent() {
283301
return agent;
@@ -382,4 +400,17 @@ public ModelCapabilitiesOverride getModelCapabilities() {
382400
public void setModelCapabilities(ModelCapabilitiesOverride modelCapabilities) {
383401
this.modelCapabilities = modelCapabilities;
384402
}
403+
404+
/** Gets the GitHub token for per-session authentication. @return the token */
405+
public String getGitHubToken() {
406+
return gitHubToken;
407+
}
408+
409+
/**
410+
* Sets the GitHub token for per-session authentication. @param gitHubToken the
411+
* token
412+
*/
413+
public void setGitHubToken(String gitHubToken) {
414+
this.gitHubToken = gitHubToken;
415+
}
385416
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
*--------------------------------------------------------------------------------------------*/
4+
5+
package com.github.copilot.sdk.json;
6+
7+
import java.util.Collections;
8+
import java.util.List;
9+
10+
import com.fasterxml.jackson.annotation.JsonInclude;
11+
import com.fasterxml.jackson.annotation.JsonProperty;
12+
13+
/**
14+
* Configuration for the default agent (the built-in agent that handles turns
15+
* when no custom agent is selected).
16+
* <p>
17+
* Use {@link #setExcludedTools(List)} to hide specific tools from the default
18+
* agent while keeping them available to custom sub-agents.
19+
*
20+
* <h2>Example Usage</h2>
21+
*
22+
* <pre>{@code
23+
* var config = new SessionConfig().setTools(List.of(secretTool))
24+
* .setDefaultAgent(new DefaultAgentConfig().setExcludedTools(List.of("secret_tool")));
25+
* }</pre>
26+
*
27+
* @see SessionConfig#setDefaultAgent(DefaultAgentConfig)
28+
* @since 1.3.0
29+
*/
30+
@JsonInclude(JsonInclude.Include.NON_NULL)
31+
public class DefaultAgentConfig {
32+
33+
@JsonProperty("excludedTools")
34+
private List<String> excludedTools;
35+
36+
/**
37+
* Gets the list of tool names excluded from the default agent.
38+
*
39+
* @return the list of excluded tool names, or {@code null} if not set
40+
*/
41+
public List<String> getExcludedTools() {
42+
return excludedTools == null ? null : Collections.unmodifiableList(excludedTools);
43+
}
44+
45+
/**
46+
* Sets the list of tool names to exclude from the default agent.
47+
* <p>
48+
* These tools remain available to custom sub-agents that reference them in
49+
* their {@link CustomAgentConfig#setTools(List)} list.
50+
*
51+
* @param excludedTools
52+
* the list of tool names to exclude from the default agent
53+
* @return this config for method chaining
54+
*/
55+
public DefaultAgentConfig setExcludedTools(List<String> excludedTools) {
56+
this.excludedTools = excludedTools;
57+
return this;
58+
}
59+
}

src/main/java/com/github/copilot/sdk/json/PermissionRequestResultKind.java

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,37 +19,29 @@
1919
*
2020
* <h2>Well-known kinds</h2>
2121
* <ul>
22-
* <li>{@link #APPROVED} — the permission was approved.</li>
23-
* <li>{@link #DENIED_BY_RULES} — the permission was denied by policy
24-
* rules.</li>
25-
* <li>{@link #DENIED_COULD_NOT_REQUEST_FROM_USER} — the permission was denied
26-
* because no approval rule was found and the user could not be prompted.</li>
27-
* <li>{@link #DENIED_INTERACTIVELY_BY_USER} — the permission was denied
28-
* interactively by the user.</li>
22+
* <li>{@link #APPROVED} — the permission was approved for this one
23+
* instance.</li>
24+
* <li>{@link #REJECTED} — the permission was denied interactively by the
25+
* user.</li>
26+
* <li>{@link #USER_NOT_AVAILABLE} — the permission was denied because user
27+
* confirmation was unavailable.</li>
28+
* <li>{@link #NO_RESULT} — no permission decision was made.</li>
2929
* </ul>
3030
*
3131
* @see PermissionRequestResult
3232
* @since 1.1.0
3333
*/
3434
public final class PermissionRequestResultKind {
3535

36-
/** The permission was approved. */
37-
public static final PermissionRequestResultKind APPROVED = new PermissionRequestResultKind("approved");
38-
39-
/** The permission was denied by policy rules. */
40-
public static final PermissionRequestResultKind DENIED_BY_RULES = new PermissionRequestResultKind(
41-
"denied-by-rules");
42-
43-
/**
44-
* The permission was denied because no approval rule was found and the user
45-
* could not be prompted.
46-
*/
47-
public static final PermissionRequestResultKind DENIED_COULD_NOT_REQUEST_FROM_USER = new PermissionRequestResultKind(
48-
"denied-no-approval-rule-and-could-not-request-from-user");
36+
/** The permission was approved for this one instance. */
37+
public static final PermissionRequestResultKind APPROVED = new PermissionRequestResultKind("approve-once");
4938

5039
/** The permission was denied interactively by the user. */
51-
public static final PermissionRequestResultKind DENIED_INTERACTIVELY_BY_USER = new PermissionRequestResultKind(
52-
"denied-interactively-by-user");
40+
public static final PermissionRequestResultKind REJECTED = new PermissionRequestResultKind("reject");
41+
42+
/** The permission was denied because user confirmation was unavailable. */
43+
public static final PermissionRequestResultKind USER_NOT_AVAILABLE = new PermissionRequestResultKind(
44+
"user-not-available");
5345

5446
/**
5547
* Leaves the pending permission request unanswered.
@@ -66,6 +58,24 @@ public final class PermissionRequestResultKind {
6658
*/
6759
public static final PermissionRequestResultKind NO_RESULT = new PermissionRequestResultKind("no-result");
6860

61+
/**
62+
* @deprecated Use {@link #REJECTED} instead.
63+
*/
64+
@Deprecated
65+
public static final PermissionRequestResultKind DENIED_INTERACTIVELY_BY_USER = REJECTED;
66+
67+
/**
68+
* @deprecated Use {@link #USER_NOT_AVAILABLE} instead.
69+
*/
70+
@Deprecated
71+
public static final PermissionRequestResultKind DENIED_COULD_NOT_REQUEST_FROM_USER = USER_NOT_AVAILABLE;
72+
73+
/**
74+
* @deprecated Use {@link #USER_NOT_AVAILABLE} instead.
75+
*/
76+
@Deprecated
77+
public static final PermissionRequestResultKind DENIED_BY_RULES = USER_NOT_AVAILABLE;
78+
6979
private final String value;
7080

7181
/**

src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,15 @@ public class ResumeSessionConfig {
5656
private Boolean includeSubAgentStreamingEvents;
5757
private Map<String, McpServerConfig> mcpServers;
5858
private List<CustomAgentConfig> customAgents;
59+
private DefaultAgentConfig defaultAgent;
5960
private String agent;
6061
private List<String> skillDirectories;
6162
private List<String> disabledSkills;
6263
private InfiniteSessionConfig infiniteSessions;
6364
private Consumer<SessionEvent> onEvent;
6465
private List<CommandDefinition> commands;
6566
private ElicitationHandler onElicitationRequest;
67+
private String gitHubToken;
6668

6769
/**
6870
* Gets the AI model to use.
@@ -520,6 +522,31 @@ public ResumeSessionConfig setCustomAgents(List<CustomAgentConfig> customAgents)
520522
return this;
521523
}
522524

525+
/**
526+
* Gets the default agent configuration.
527+
*
528+
* @return the default agent configuration, or {@code null} if not set
529+
*/
530+
public DefaultAgentConfig getDefaultAgent() {
531+
return defaultAgent;
532+
}
533+
534+
/**
535+
* Sets the default agent configuration.
536+
* <p>
537+
* Use {@link DefaultAgentConfig#setExcludedTools(List)} to hide specific tools
538+
* from the default agent while keeping them available to custom sub-agents.
539+
*
540+
* @param defaultAgent
541+
* the default agent configuration
542+
* @return this config for method chaining
543+
* @see DefaultAgentConfig
544+
*/
545+
public ResumeSessionConfig setDefaultAgent(DefaultAgentConfig defaultAgent) {
546+
this.defaultAgent = defaultAgent;
547+
return this;
548+
}
549+
523550
/**
524551
* Gets the name of the custom agent to activate at session start.
525552
*
@@ -684,6 +711,33 @@ public ResumeSessionConfig setOnElicitationRequest(ElicitationHandler onElicitat
684711
return this;
685712
}
686713

714+
/**
715+
* Gets the GitHub token for per-session authentication.
716+
*
717+
* @return the GitHub token, or {@code null} if not set
718+
* @since 1.3.0
719+
*/
720+
public String getGitHubToken() {
721+
return gitHubToken;
722+
}
723+
724+
/**
725+
* Sets the GitHub token for per-session authentication.
726+
* <p>
727+
* When provided, the runtime resolves this token into a full GitHub identity
728+
* and stores it on the session for content exclusion, model routing, and quota
729+
* checks.
730+
*
731+
* @param gitHubToken
732+
* the GitHub token for per-session authentication
733+
* @return this config for method chaining
734+
* @since 1.3.0
735+
*/
736+
public ResumeSessionConfig setGitHubToken(String gitHubToken) {
737+
this.gitHubToken = gitHubToken;
738+
return this;
739+
}
740+
687741
/**
688742
* Creates a shallow clone of this {@code ResumeSessionConfig} instance.
689743
* <p>
@@ -718,13 +772,15 @@ public ResumeSessionConfig clone() {
718772
copy.includeSubAgentStreamingEvents = this.includeSubAgentStreamingEvents;
719773
copy.mcpServers = this.mcpServers != null ? new java.util.HashMap<>(this.mcpServers) : null;
720774
copy.customAgents = this.customAgents != null ? new ArrayList<>(this.customAgents) : null;
775+
copy.defaultAgent = this.defaultAgent;
721776
copy.agent = this.agent;
722777
copy.skillDirectories = this.skillDirectories != null ? new ArrayList<>(this.skillDirectories) : null;
723778
copy.disabledSkills = this.disabledSkills != null ? new ArrayList<>(this.disabledSkills) : null;
724779
copy.infiniteSessions = this.infiniteSessions;
725780
copy.onEvent = this.onEvent;
726781
copy.commands = this.commands != null ? new ArrayList<>(this.commands) : null;
727782
copy.onElicitationRequest = this.onElicitationRequest;
783+
copy.gitHubToken = this.gitHubToken;
728784
return copy;
729785
}
730786
}

0 commit comments

Comments
 (0)