Skip to content

Commit 605da96

Browse files
Halcyonhal9Copilot
andcommitted
SDK: add includeCurrentDatetime flag to suppress datetime injection
Adds an opt-in `includeCurrentDatetime?: boolean` session/resume option across all language bindings (Node, Python, Go, .NET, Rust, Java). When `false`, the SDK forwards `includeCurrentDatetime: false` to the runtime, which suppresses the injected `<current_datetime>` tag on model-facing user messages. Defaults to true for backwards compatibility. This is the SDK-side counterpart to copilot-agent-runtime PR github/copilot-agent-runtime#8130, which is what actually does the suppression work in the runtime. The combination is needed when short prompts (e.g. session-name summarisation) are confused by datetime context, or when the user's own prompt contains a date/time that collides with the injected tag. Surface added per language: - Node: `SessionConfigBase.includeCurrentDatetime?: boolean` - Python: `create_session(..., include_current_datetime=...)` and `resume_session(..., include_current_datetime=...)` - Go: `SessionConfig.IncludeCurrentDatetime` / `ResumeSessionConfig.IncludeCurrentDatetime` (*bool) - .NET: `SessionConfigBase.IncludeCurrentDatetime` (bool?) - Rust: `SessionConfig.include_current_datetime` / `ResumeSessionConfig.include_current_datetime` plus `with_include_current_datetime` builder + wire fields - Java: `SessionConfig.includeCurrentDatetime` / `ResumeSessionConfig.includeCurrentDatetime` plus `SessionRequestBuilder.includeCurrentDatetime`, wire fields, and clone/jackson/builder unit tests The wire field name is `includeCurrentDatetime` everywhere, matching the runtime PR's request schema. Verified locally with CONTRIBUTING.md test commands: - nodejs: `npm test` 416 / 7 skipped; `npm run lint` 0 errors - python: unit 145, ruff clean, e2e 283 / 7 pre-existing auth fails / 6 skipped (failures unrelated to this change) - go: `go test ./...` all pass; `golangci-lint run` 1 pre-existing govet in `definetool.go:210` - dotnet: `dotnet test` 463 / 2 skipped - rust: `cargo test --features test-support` all + 18 doctests pass - java: custom E2E driver against gpt-5.2 (Halcyonhal9/lumi2 fork) Refs: github/copilot-agent-runtime#8130 Co-authored-by: Copilot <[email protected]>
1 parent a77e8ec commit 605da96

17 files changed

Lines changed: 373 additions & 5 deletions

File tree

dotnet/src/Client.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,8 @@ public async Task<CopilotSession> CreateSessionAsync(SessionConfig config, Cance
618618
GitHubToken: config.GitHubToken,
619619
RemoteSession: config.RemoteSession,
620620
Cloud: config.Cloud,
621-
InstructionDirectories: config.InstructionDirectories);
621+
InstructionDirectories: config.InstructionDirectories,
622+
IncludeCurrentDatetime: config.IncludeCurrentDatetime);
622623

623624
var rpcTimestamp = Stopwatch.GetTimestamp();
624625
var response = await InvokeRpcAsync<CreateSessionResponse>(
@@ -778,7 +779,8 @@ public async Task<CopilotSession> ResumeSessionAsync(string sessionId, ResumeSes
778779
GitHubToken: config.GitHubToken,
779780
RemoteSession: config.RemoteSession,
780781
ContinuePendingWork: config.ContinuePendingWork,
781-
InstructionDirectories: config.InstructionDirectories);
782+
InstructionDirectories: config.InstructionDirectories,
783+
IncludeCurrentDatetime: config.IncludeCurrentDatetime);
782784

783785
var rpcTimestamp = Stopwatch.GetTimestamp();
784786
var response = await InvokeRpcAsync<ResumeSessionResponse>(
@@ -1866,7 +1868,8 @@ internal record CreateSessionRequest(
18661868
string? GitHubToken = null,
18671869
RemoteSessionMode? RemoteSession = null,
18681870
CloudSessionOptions? Cloud = null,
1869-
IList<string>? InstructionDirectories = null);
1871+
IList<string>? InstructionDirectories = null,
1872+
bool? IncludeCurrentDatetime = null);
18701873

18711874
internal record ToolDefinition(
18721875
string Name,
@@ -1928,7 +1931,8 @@ internal record ResumeSessionRequest(
19281931
string? GitHubToken = null,
19291932
RemoteSessionMode? RemoteSession = null,
19301933
bool? ContinuePendingWork = null,
1931-
IList<string>? InstructionDirectories = null);
1934+
IList<string>? InstructionDirectories = null,
1935+
bool? IncludeCurrentDatetime = null);
19321936

19331937
internal record ResumeSessionResponse(
19341938
string SessionId,

dotnet/src/Types.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2214,6 +2214,7 @@ protected SessionConfigBase(SessionConfigBase? other)
22142214
OnUserInputRequest = other.OnUserInputRequest;
22152215
Provider = other.Provider;
22162216
EnableSessionTelemetry = other.EnableSessionTelemetry;
2217+
IncludeCurrentDatetime = other.IncludeCurrentDatetime;
22172218
ReasoningEffort = other.ReasoningEffort;
22182219
CreateSessionFsProvider = other.CreateSessionFsProvider;
22192220
GitHubToken = other.GitHubToken;
@@ -2292,6 +2293,12 @@ protected SessionConfigBase(SessionConfigBase? other)
22922293
/// </summary>
22932294
public bool? EnableSessionTelemetry { get; set; }
22942295

2296+
/// <summary>
2297+
/// When false, suppresses current_datetime injection in the model-facing user message.
2298+
/// Defaults to true (datetime is included) when null.
2299+
/// </summary>
2300+
public bool? IncludeCurrentDatetime { get; set; }
2301+
22952302
/// <summary>Handler for permission requests from the server.</summary>
22962303
public Func<PermissionRequest, PermissionInvocation, Task<PermissionDecision>>? OnPermissionRequest { get; set; }
22972304

go/client.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,7 @@ func (c *Client) CreateSession(ctx context.Context, config *SessionConfig) (*Ses
612612
req.ExcludedTools = config.ExcludedTools
613613
req.Provider = config.Provider
614614
req.EnableSessionTelemetry = config.EnableSessionTelemetry
615+
req.IncludeCurrentDatetime = config.IncludeCurrentDatetime
615616
req.ModelCapabilities = config.ModelCapabilities
616617
req.WorkingDirectory = config.WorkingDirectory
617618
req.MCPServers = config.MCPServers
@@ -796,6 +797,7 @@ func (c *Client) ResumeSessionWithOptions(ctx context.Context, sessionID string,
796797
req.Tools = config.Tools
797798
req.Provider = config.Provider
798799
req.EnableSessionTelemetry = config.EnableSessionTelemetry
800+
req.IncludeCurrentDatetime = config.IncludeCurrentDatetime
799801
req.ModelCapabilities = config.ModelCapabilities
800802
req.AvailableTools = config.AvailableTools
801803
req.ExcludedTools = config.ExcludedTools

go/types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,10 @@ type SessionConfig struct {
870870
// regardless of this setting. This is independent of the OpenTelemetry
871871
// configuration in ClientOptions.Telemetry.
872872
EnableSessionTelemetry *bool
873+
// IncludeCurrentDatetime includes the current local datetime in model-facing user messages.
874+
// When false, suppresses the injected <current_datetime> tag. When nil, defaults
875+
// to true for backwards compatibility.
876+
IncludeCurrentDatetime *bool
873877
// ModelCapabilities overrides individual model capabilities resolved by the runtime.
874878
// Only non-nil fields are applied over the runtime-resolved capabilities.
875879
ModelCapabilities *rpc.ModelCapabilitiesOverride
@@ -1084,6 +1088,10 @@ type ResumeSessionConfig struct {
10841088
// regardless of this setting. This is independent of the OpenTelemetry
10851089
// configuration in ClientOptions.Telemetry.
10861090
EnableSessionTelemetry *bool
1091+
// IncludeCurrentDatetime includes the current local datetime in model-facing user messages.
1092+
// When false, suppresses the injected <current_datetime> tag. When nil, defaults
1093+
// to true for backwards compatibility.
1094+
IncludeCurrentDatetime *bool
10871095
// ModelCapabilities overrides individual model capabilities resolved by the runtime.
10881096
// Only non-nil fields are applied over the runtime-resolved capabilities.
10891097
ModelCapabilities *rpc.ModelCapabilitiesOverride
@@ -1374,6 +1382,7 @@ type createSessionRequest struct {
13741382
ExcludedTools []string `json:"excludedTools,omitempty"`
13751383
Provider *ProviderConfig `json:"provider,omitempty"`
13761384
EnableSessionTelemetry *bool `json:"enableSessionTelemetry,omitempty"`
1385+
IncludeCurrentDatetime *bool `json:"includeCurrentDatetime,omitempty"`
13771386
ModelCapabilities *rpc.ModelCapabilitiesOverride `json:"modelCapabilities,omitempty"`
13781387
RequestPermission *bool `json:"requestPermission,omitempty"`
13791388
RequestUserInput *bool `json:"requestUserInput,omitempty"`
@@ -1428,6 +1437,7 @@ type resumeSessionRequest struct {
14281437
ExcludedTools []string `json:"excludedTools,omitempty"`
14291438
Provider *ProviderConfig `json:"provider,omitempty"`
14301439
EnableSessionTelemetry *bool `json:"enableSessionTelemetry,omitempty"`
1440+
IncludeCurrentDatetime *bool `json:"includeCurrentDatetime,omitempty"`
14311441
ModelCapabilities *rpc.ModelCapabilitiesOverride `json:"modelCapabilities,omitempty"`
14321442
RequestPermission *bool `json:"requestPermission,omitempty"`
14331443
RequestUserInput *bool `json:"requestUserInput,omitempty"`

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ static CreateSessionRequest buildCreateRequest(SessionConfig config, String sess
112112
request.setExcludedTools(config.getExcludedTools());
113113
request.setProvider(config.getProvider());
114114
config.getEnableSessionTelemetry().ifPresent(request::setEnableSessionTelemetry);
115+
config.getIncludeCurrentDatetime().ifPresent(request::setIncludeCurrentDatetime);
115116
if (config.getOnUserInputRequest() != null) {
116117
request.setRequestUserInput(true);
117118
}
@@ -203,6 +204,7 @@ static ResumeSessionRequest buildResumeRequest(String sessionId, ResumeSessionCo
203204
request.setExcludedTools(config.getExcludedTools());
204205
request.setProvider(config.getProvider());
205206
config.getEnableSessionTelemetry().ifPresent(request::setEnableSessionTelemetry);
207+
config.getIncludeCurrentDatetime().ifPresent(request::setIncludeCurrentDatetime);
206208
if (config.getOnUserInputRequest() != null) {
207209
request.setRequestUserInput(true);
208210
}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ public final class CreateSessionRequest {
5555
@JsonProperty("enableSessionTelemetry")
5656
private Boolean enableSessionTelemetry;
5757

58+
@JsonProperty("includeCurrentDatetime")
59+
private Boolean includeCurrentDatetime;
60+
5861
@JsonProperty("requestPermission")
5962
private Boolean requestPermission;
6063

@@ -241,6 +244,25 @@ public void clearEnableSessionTelemetry() {
241244
this.enableSessionTelemetry = null;
242245
}
243246

247+
/** Gets include current datetime flag. @return the flag */
248+
public Boolean getIncludeCurrentDatetime() {
249+
return includeCurrentDatetime;
250+
}
251+
252+
/**
253+
* Sets include current datetime flag. @param includeCurrentDatetime the flag
254+
*/
255+
public void setIncludeCurrentDatetime(Boolean includeCurrentDatetime) {
256+
this.includeCurrentDatetime = includeCurrentDatetime;
257+
}
258+
259+
/**
260+
* Clears the includeCurrentDatetime setting, reverting to the default behavior.
261+
*/
262+
public void clearIncludeCurrentDatetime() {
263+
this.includeCurrentDatetime = null;
264+
}
265+
244266
/** Gets request permission flag. @return the flag */
245267
public Boolean getRequestPermission() {
246268
return requestPermission;

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public class ResumeSessionConfig {
4646
private List<String> excludedTools;
4747
private ProviderConfig provider;
4848
private Boolean enableSessionTelemetry;
49+
private Boolean includeCurrentDatetime;
4950
private String reasoningEffort;
5051
private ModelCapabilitiesOverride modelCapabilities;
5152
private PermissionHandler onPermissionRequest;
@@ -279,6 +280,46 @@ public ResumeSessionConfig clearEnableSessionTelemetry() {
279280
return this;
280281
}
281282

283+
/**
284+
* Gets whether the current local datetime is included in model-facing user
285+
* messages.
286+
*
287+
* @return an {@link java.util.Optional} containing {@code true} to include the
288+
* current datetime or {@code false} to suppress it, or
289+
* {@link java.util.Optional#empty()} to use the runtime default
290+
*/
291+
@JsonIgnore
292+
public Optional<Boolean> getIncludeCurrentDatetime() {
293+
return Optional.ofNullable(includeCurrentDatetime);
294+
}
295+
296+
/**
297+
* Sets whether to include the current local datetime in model-facing user
298+
* messages.
299+
* <p>
300+
* When {@code false}, suppresses the injected {@code <current_datetime>} tag.
301+
* Default: {@code true}.
302+
*
303+
* @param includeCurrentDatetime
304+
* {@code true} to include the current datetime, {@code false} to
305+
* suppress it, or {@code null} to use the runtime default
306+
* @return this config for method chaining
307+
*/
308+
public ResumeSessionConfig setIncludeCurrentDatetime(Boolean includeCurrentDatetime) {
309+
this.includeCurrentDatetime = includeCurrentDatetime;
310+
return this;
311+
}
312+
313+
/**
314+
* Clears the includeCurrentDatetime setting, reverting to the default behavior.
315+
*
316+
* @return this instance for method chaining
317+
*/
318+
public ResumeSessionConfig clearIncludeCurrentDatetime() {
319+
this.includeCurrentDatetime = null;
320+
return this;
321+
}
322+
282323
/**
283324
* Gets the reasoning effort level.
284325
*
@@ -937,6 +978,7 @@ public ResumeSessionConfig clone() {
937978
copy.excludedTools = this.excludedTools != null ? new ArrayList<>(this.excludedTools) : null;
938979
copy.provider = this.provider;
939980
copy.enableSessionTelemetry = this.enableSessionTelemetry;
981+
copy.includeCurrentDatetime = this.includeCurrentDatetime;
940982
copy.reasoningEffort = this.reasoningEffort;
941983
copy.modelCapabilities = this.modelCapabilities;
942984
copy.onPermissionRequest = this.onPermissionRequest;

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ public final class ResumeSessionRequest {
5656
@JsonProperty("enableSessionTelemetry")
5757
private Boolean enableSessionTelemetry;
5858

59+
@JsonProperty("includeCurrentDatetime")
60+
private Boolean includeCurrentDatetime;
61+
5962
@JsonProperty("requestPermission")
6063
private Boolean requestPermission;
6164

@@ -245,6 +248,25 @@ public void clearEnableSessionTelemetry() {
245248
this.enableSessionTelemetry = null;
246249
}
247250

251+
/** Gets include current datetime flag. @return the flag */
252+
public Boolean getIncludeCurrentDatetime() {
253+
return includeCurrentDatetime;
254+
}
255+
256+
/**
257+
* Sets include current datetime flag. @param includeCurrentDatetime the flag
258+
*/
259+
public void setIncludeCurrentDatetime(Boolean includeCurrentDatetime) {
260+
this.includeCurrentDatetime = includeCurrentDatetime;
261+
}
262+
263+
/**
264+
* Clears the includeCurrentDatetime setting, reverting to the default behavior.
265+
*/
266+
public void clearIncludeCurrentDatetime() {
267+
this.includeCurrentDatetime = null;
268+
}
269+
248270
/** Gets request permission flag. @return the flag */
249271
public Boolean getRequestPermission() {
250272
return requestPermission;

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public class SessionConfig {
4848
private List<String> excludedTools;
4949
private ProviderConfig provider;
5050
private Boolean enableSessionTelemetry;
51+
private Boolean includeCurrentDatetime;
5152
private PermissionHandler onPermissionRequest;
5253
private UserInputHandler onUserInputRequest;
5354
private SessionHooks hooks;
@@ -334,6 +335,46 @@ public SessionConfig clearEnableSessionTelemetry() {
334335
return this;
335336
}
336337

338+
/**
339+
* Gets whether the current local datetime is included in model-facing user
340+
* messages.
341+
*
342+
* @return an {@link java.util.Optional} containing {@code true} to include the
343+
* current datetime or {@code false} to suppress it, or
344+
* {@link java.util.Optional#empty()} to use the runtime default
345+
*/
346+
@JsonIgnore
347+
public Optional<Boolean> getIncludeCurrentDatetime() {
348+
return Optional.ofNullable(includeCurrentDatetime);
349+
}
350+
351+
/**
352+
* Sets whether to include the current local datetime in model-facing user
353+
* messages.
354+
* <p>
355+
* When {@code false}, suppresses the injected {@code <current_datetime>} tag.
356+
* Default: {@code true}.
357+
*
358+
* @param includeCurrentDatetime
359+
* {@code true} to include the current datetime, {@code false} to
360+
* suppress it, or {@code null} to use the runtime default
361+
* @return this config instance for method chaining
362+
*/
363+
public SessionConfig setIncludeCurrentDatetime(Boolean includeCurrentDatetime) {
364+
this.includeCurrentDatetime = includeCurrentDatetime;
365+
return this;
366+
}
367+
368+
/**
369+
* Clears the includeCurrentDatetime setting, reverting to the default behavior.
370+
*
371+
* @return this instance for method chaining
372+
*/
373+
public SessionConfig clearIncludeCurrentDatetime() {
374+
this.includeCurrentDatetime = null;
375+
return this;
376+
}
377+
337378
/**
338379
* Gets the permission request handler.
339380
*
@@ -1033,6 +1074,7 @@ public SessionConfig clone() {
10331074
copy.excludedTools = this.excludedTools != null ? new ArrayList<>(this.excludedTools) : null;
10341075
copy.provider = this.provider;
10351076
copy.enableSessionTelemetry = this.enableSessionTelemetry;
1077+
copy.includeCurrentDatetime = this.includeCurrentDatetime;
10361078
copy.onPermissionRequest = this.onPermissionRequest;
10371079
copy.onUserInputRequest = this.onUserInputRequest;
10381080
copy.hooks = this.hooks;

java/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,25 @@ void sessionConfigEnableSessionTelemetryDefaultIsNull() {
215215
assertTrue(cloned.getEnableSessionTelemetry().isEmpty());
216216
}
217217

218+
@Test
219+
void sessionConfigIncludeCurrentDatetimeCopied() {
220+
SessionConfig original = new SessionConfig();
221+
original.setIncludeCurrentDatetime(false);
222+
223+
SessionConfig cloned = original.clone();
224+
225+
assertFalse(cloned.getIncludeCurrentDatetime().orElse(true));
226+
}
227+
228+
@Test
229+
void sessionConfigIncludeCurrentDatetimeDefaultIsNull() {
230+
SessionConfig original = new SessionConfig();
231+
232+
SessionConfig cloned = original.clone();
233+
234+
assertTrue(cloned.getIncludeCurrentDatetime().isEmpty());
235+
}
236+
218237
@Test
219238
void resumeSessionConfigEnableSessionTelemetryCopied() {
220239
ResumeSessionConfig original = new ResumeSessionConfig();
@@ -234,6 +253,25 @@ void resumeSessionConfigEnableSessionTelemetryDefaultIsNull() {
234253
assertTrue(cloned.getEnableSessionTelemetry().isEmpty());
235254
}
236255

256+
@Test
257+
void resumeSessionConfigIncludeCurrentDatetimeCopied() {
258+
ResumeSessionConfig original = new ResumeSessionConfig();
259+
original.setIncludeCurrentDatetime(false);
260+
261+
ResumeSessionConfig cloned = original.clone();
262+
263+
assertFalse(cloned.getIncludeCurrentDatetime().orElse(true));
264+
}
265+
266+
@Test
267+
void resumeSessionConfigIncludeCurrentDatetimeDefaultIsNull() {
268+
ResumeSessionConfig original = new ResumeSessionConfig();
269+
270+
ResumeSessionConfig cloned = original.clone();
271+
272+
assertTrue(cloned.getIncludeCurrentDatetime().isEmpty());
273+
}
274+
237275
@Test
238276
void clonePreservesNullFields() {
239277
CopilotClientOptions opts = new CopilotClientOptions();

0 commit comments

Comments
 (0)