diff --git a/docs/troubleshooting/compatibility.md b/docs/troubleshooting/compatibility.md
index 1a322b88c..44632ab6a 100644
--- a/docs/troubleshooting/compatibility.md
+++ b/docs/troubleshooting/compatibility.md
@@ -86,7 +86,9 @@ The Copilot SDK communicates with the CLI via JSON-RPC protocol. Features must b
| **Experimental** | | |
| Agent management | `session.rpc.agent.*` | List, select, deselect, get current agent |
| Fleet mode | `session.rpc.fleet.start()` | Parallel sub-agent execution |
-| Manual compaction | `session.rpc.compaction.compact()` | Trigger compaction on demand |
+| Manual compaction | `session.rpc.history.compact()` | Trigger compaction on demand |
+| History truncation | `session.rpc.history.truncate()` | Remove events from a point onward |
+| Session forking | `server.rpc.sessions.fork()` | Fork a session at a point in history |
### ❌ Not Available in SDK (CLI-Only)
@@ -222,7 +224,7 @@ const session = await client.createSession({
});
// Manual compaction (experimental)
-const result = await session.rpc.compaction.compact();
+const result = await session.rpc.history.compact();
console.log(`Removed ${result.tokensRemoved} tokens, ${result.messagesRemoved} messages`);
```
diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs
index 86d3daf2e..b06b68676 100644
--- a/dotnet/src/Generated/Rpc.cs
+++ b/dotnet/src/Generated/Rpc.cs
@@ -263,6 +263,28 @@ internal class SessionFsSetProviderRequest
public SessionFsSetProviderRequestConventions Conventions { get; set; }
}
+/// RPC data type for SessionsFork operations.
+[Experimental(Diagnostics.Experimental)]
+public class SessionsForkResult
+{
+ /// The new forked session's ID.
+ [JsonPropertyName("sessionId")]
+ public string SessionId { get; set; } = string.Empty;
+}
+
+/// RPC data type for SessionsFork operations.
+[Experimental(Diagnostics.Experimental)]
+internal class SessionsForkRequest
+{
+ /// Source session ID to fork from.
+ [JsonPropertyName("sessionId")]
+ public string SessionId { get; set; } = string.Empty;
+
+ /// Optional event ID boundary. When provided, the fork includes only events before this ID (exclusive). When omitted, all events are included.
+ [JsonPropertyName("toEventId")]
+ public string? ToEventId { get; set; }
+}
+
/// RPC data type for SessionLog operations.
public class SessionLogResult
{
@@ -1030,32 +1052,6 @@ internal class SessionExtensionsReloadRequest
public string SessionId { get; set; } = string.Empty;
}
-/// RPC data type for SessionCompactionCompact operations.
-[Experimental(Diagnostics.Experimental)]
-public class SessionCompactionCompactResult
-{
- /// Whether compaction completed successfully.
- [JsonPropertyName("success")]
- public bool Success { get; set; }
-
- /// Number of tokens freed by compaction.
- [JsonPropertyName("tokensRemoved")]
- public double TokensRemoved { get; set; }
-
- /// Number of messages removed during compaction.
- [JsonPropertyName("messagesRemoved")]
- public double MessagesRemoved { get; set; }
-}
-
-/// RPC data type for SessionCompactionCompact operations.
-[Experimental(Diagnostics.Experimental)]
-internal class SessionCompactionCompactRequest
-{
- /// Target session identifier.
- [JsonPropertyName("sessionId")]
- public string SessionId { get; set; } = string.Empty;
-}
-
/// RPC data type for SessionToolsHandlePendingToolCall operations.
public class SessionToolsHandlePendingToolCallResult
{
@@ -1264,6 +1260,54 @@ internal class SessionShellKillRequest
public SessionShellKillRequestSignal? Signal { get; set; }
}
+/// RPC data type for SessionHistoryCompact operations.
+[Experimental(Diagnostics.Experimental)]
+public class SessionHistoryCompactResult
+{
+ /// Whether compaction completed successfully.
+ [JsonPropertyName("success")]
+ public bool Success { get; set; }
+
+ /// Number of tokens freed by compaction.
+ [JsonPropertyName("tokensRemoved")]
+ public double TokensRemoved { get; set; }
+
+ /// Number of messages removed during compaction.
+ [JsonPropertyName("messagesRemoved")]
+ public double MessagesRemoved { get; set; }
+}
+
+/// RPC data type for SessionHistoryCompact operations.
+[Experimental(Diagnostics.Experimental)]
+internal class SessionHistoryCompactRequest
+{
+ /// Target session identifier.
+ [JsonPropertyName("sessionId")]
+ public string SessionId { get; set; } = string.Empty;
+}
+
+/// RPC data type for SessionHistoryTruncate operations.
+[Experimental(Diagnostics.Experimental)]
+public class SessionHistoryTruncateResult
+{
+ /// Number of events that were removed.
+ [JsonPropertyName("eventsRemoved")]
+ public double EventsRemoved { get; set; }
+}
+
+/// RPC data type for SessionHistoryTruncate operations.
+[Experimental(Diagnostics.Experimental)]
+internal class SessionHistoryTruncateRequest
+{
+ /// Target session identifier.
+ [JsonPropertyName("sessionId")]
+ public string SessionId { get; set; } = string.Empty;
+
+ /// Event ID to truncate to. This event and all events after it are removed from the session.
+ [JsonPropertyName("eventId")]
+ public string EventId { get; set; } = string.Empty;
+}
+
/// RPC data type for SessionFsReadFile operations.
public class SessionFsReadFileResult
{
@@ -1648,6 +1692,7 @@ internal ServerRpc(JsonRpc rpc)
Account = new ServerAccountApi(rpc);
Mcp = new ServerMcpApi(rpc);
SessionFs = new ServerSessionFsApi(rpc);
+ Sessions = new ServerSessionsApi(rpc);
}
/// Calls "ping".
@@ -1671,6 +1716,9 @@ public async Task PingAsync(string? message = null, CancellationToke
/// SessionFs APIs.
public ServerSessionFsApi SessionFs { get; }
+
+ /// Sessions APIs.
+ public ServerSessionsApi Sessions { get; }
}
/// Provides server-scoped Models APIs.
@@ -1754,6 +1802,25 @@ public async Task SetProviderAsync(string initialCwd
}
}
+/// Provides server-scoped Sessions APIs.
+[Experimental(Diagnostics.Experimental)]
+public class ServerSessionsApi
+{
+ private readonly JsonRpc _rpc;
+
+ internal ServerSessionsApi(JsonRpc rpc)
+ {
+ _rpc = rpc;
+ }
+
+ /// Calls "sessions.fork".
+ public async Task ForkAsync(string sessionId, string? toEventId = null, CancellationToken cancellationToken = default)
+ {
+ var request = new SessionsForkRequest { SessionId = sessionId, ToEventId = toEventId };
+ return await CopilotClient.InvokeRpcAsync(_rpc, "sessions.fork", [request], cancellationToken);
+ }
+}
+
/// Provides typed session-scoped RPC methods.
public class SessionRpc
{
@@ -1774,12 +1841,12 @@ internal SessionRpc(JsonRpc rpc, string sessionId)
Mcp = new McpApi(rpc, sessionId);
Plugins = new PluginsApi(rpc, sessionId);
Extensions = new ExtensionsApi(rpc, sessionId);
- Compaction = new CompactionApi(rpc, sessionId);
Tools = new ToolsApi(rpc, sessionId);
Commands = new CommandsApi(rpc, sessionId);
Ui = new UiApi(rpc, sessionId);
Permissions = new PermissionsApi(rpc, sessionId);
Shell = new ShellApi(rpc, sessionId);
+ History = new HistoryApi(rpc, sessionId);
}
/// Model APIs.
@@ -1812,9 +1879,6 @@ internal SessionRpc(JsonRpc rpc, string sessionId)
/// Extensions APIs.
public ExtensionsApi Extensions { get; }
- /// Compaction APIs.
- public CompactionApi Compaction { get; }
-
/// Tools APIs.
public ToolsApi Tools { get; }
@@ -1830,6 +1894,9 @@ internal SessionRpc(JsonRpc rpc, string sessionId)
/// Shell APIs.
public ShellApi Shell { get; }
+ /// History APIs.
+ public HistoryApi History { get; }
+
/// Calls "session.log".
public async Task LogAsync(string message, SessionLogRequestLevel? level = null, bool? ephemeral = null, string? url = null, CancellationToken cancellationToken = default)
{
@@ -2177,27 +2244,6 @@ public async Task ReloadAsync(CancellationToken c
}
}
-/// Provides session-scoped Compaction APIs.
-[Experimental(Diagnostics.Experimental)]
-public class CompactionApi
-{
- private readonly JsonRpc _rpc;
- private readonly string _sessionId;
-
- internal CompactionApi(JsonRpc rpc, string sessionId)
- {
- _rpc = rpc;
- _sessionId = sessionId;
- }
-
- /// Calls "session.compaction.compact".
- public async Task CompactAsync(CancellationToken cancellationToken = default)
- {
- var request = new SessionCompactionCompactRequest { SessionId = _sessionId };
- return await CopilotClient.InvokeRpcAsync(_rpc, "session.compaction.compact", [request], cancellationToken);
- }
-}
-
/// Provides session-scoped Tools APIs.
public class ToolsApi
{
@@ -2312,6 +2358,34 @@ public async Task KillAsync(string processId, SessionShe
}
}
+/// Provides session-scoped History APIs.
+[Experimental(Diagnostics.Experimental)]
+public class HistoryApi
+{
+ private readonly JsonRpc _rpc;
+ private readonly string _sessionId;
+
+ internal HistoryApi(JsonRpc rpc, string sessionId)
+ {
+ _rpc = rpc;
+ _sessionId = sessionId;
+ }
+
+ /// Calls "session.history.compact".
+ public async Task CompactAsync(CancellationToken cancellationToken = default)
+ {
+ var request = new SessionHistoryCompactRequest { SessionId = _sessionId };
+ return await CopilotClient.InvokeRpcAsync(_rpc, "session.history.compact", [request], cancellationToken);
+ }
+
+ /// Calls "session.history.truncate".
+ public async Task TruncateAsync(string eventId, CancellationToken cancellationToken = default)
+ {
+ var request = new SessionHistoryTruncateRequest { SessionId = _sessionId, EventId = eventId };
+ return await CopilotClient.InvokeRpcAsync(_rpc, "session.history.truncate", [request], cancellationToken);
+ }
+}
+
/// Handles `sessionFs` client session API methods.
public interface ISessionFsHandler
{
@@ -2496,8 +2570,6 @@ public static void RegisterClientSessionApiHandlers(JsonRpc rpc, FuncPayload indicating the session is fully idle with no background tasks in flight.
+/// Payload indicating the session is idle with no background agents in flight.
/// Represents the session.idle event.
public partial class SessionIdleEvent : SessionEvent
{
@@ -1209,7 +1209,7 @@ public partial class SessionErrorData
public string? Url { get; set; }
}
-/// Payload indicating the session is fully idle with no background tasks in flight.
+/// Payload indicating the session is idle with no background agents in flight.
public partial class SessionIdleData
{
/// True when the preceding agentic loop was cancelled via abort signal.
@@ -1391,7 +1391,7 @@ public partial class SessionTruncationData
/// Session rewind details including target event and count of removed events.
public partial class SessionSnapshotRewindData
{
- /// Event ID that was rewound to; all events after this one were removed.
+ /// Event ID that was rewound to; this event and all after it were removed.
[JsonPropertyName("upToEventId")]
public required string UpToEventId { get; set; }
@@ -1780,6 +1780,11 @@ public partial class AssistantMessageData
[JsonPropertyName("interactionId")]
public string? InteractionId { get; set; }
+ /// GitHub request tracing ID (x-github-request-id header) for correlating with server-side logs.
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("requestId")]
+ public string? RequestId { get; set; }
+
/// Tool call ID of the parent tool invocation when this event originates from a sub-agent.
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("parentToolCallId")]
diff --git a/dotnet/test/AgentAndCompactRpcTests.cs b/dotnet/test/AgentAndCompactRpcTests.cs
index 5f40d4e2b..12ed3a308 100644
--- a/dotnet/test/AgentAndCompactRpcTests.cs
+++ b/dotnet/test/AgentAndCompactRpcTests.cs
@@ -135,7 +135,7 @@ public async Task Should_Compact_Session_History_After_Messages()
await session.SendAndWaitAsync(new MessageOptions { Prompt = "What is 2+2?" });
// Compact the session
- var result = await session.Rpc.Compaction.CompactAsync();
+ var result = await session.Rpc.History.CompactAsync();
Assert.NotNull(result);
}
}
diff --git a/dotnet/test/SessionFsTests.cs b/dotnet/test/SessionFsTests.cs
index b985e15af..202abf323 100644
--- a/dotnet/test/SessionFsTests.cs
+++ b/dotnet/test/SessionFsTests.cs
@@ -211,7 +211,7 @@ public async Task Should_Succeed_With_Compaction_While_Using_SessionFs()
var contentBefore = await ReadAllTextSharedAsync(eventsPath);
Assert.DoesNotContain("checkpointNumber", contentBefore);
- await session.Rpc.Compaction.CompactAsync();
+ await session.Rpc.History.CompactAsync();
await WaitForConditionAsync(() => compactionEvent is not null, TimeSpan.FromSeconds(30));
Assert.True(compactionEvent!.Data.Success);
diff --git a/go/generated_session_events.go b/go/generated_session_events.go
index 4647679fa..0599e7fcc 100644
--- a/go/generated_session_events.go
+++ b/go/generated_session_events.go
@@ -692,7 +692,7 @@ type SessionErrorData struct {
func (*SessionErrorData) sessionEventData() {}
-// Payload indicating the session is fully idle with no background tasks in flight
+// Payload indicating the session is idle with no background agents in flight
type SessionIdleData struct {
// True when the preceding agentic loop was cancelled via abort signal
Aborted *bool `json:"aborted,omitempty"`
@@ -818,7 +818,7 @@ func (*SessionTruncationData) sessionEventData() {}
// Session rewind details including target event and count of removed events
type SessionSnapshotRewindData struct {
- // Event ID that was rewound to; all events after this one were removed
+ // Event ID that was rewound to; this event and all after it were removed
UpToEventID string `json:"upToEventId"`
// Number of events that were removed by the rewind
EventsRemoved float64 `json:"eventsRemoved"`
@@ -1044,6 +1044,8 @@ type AssistantMessageData struct {
OutputTokens *float64 `json:"outputTokens,omitempty"`
// CAPI interaction ID for correlating this message with upstream telemetry
InteractionID *string `json:"interactionId,omitempty"`
+ // GitHub request tracing ID (x-github-request-id header) for correlating with server-side logs
+ RequestID *string `json:"requestId,omitempty"`
// Tool call ID of the parent tool invocation when this event originates from a sub-agent
ParentToolCallID *string `json:"parentToolCallId,omitempty"`
}
diff --git a/go/internal/e2e/agent_and_compact_rpc_test.go b/go/internal/e2e/agent_and_compact_rpc_test.go
index cbd52a326..dca773b5b 100644
--- a/go/internal/e2e/agent_and_compact_rpc_test.go
+++ b/go/internal/e2e/agent_and_compact_rpc_test.go
@@ -281,7 +281,7 @@ func TestSessionCompactionRpc(t *testing.T) {
}
// Compact the session
- result, err := session.RPC.Compaction.Compact(t.Context())
+ result, err := session.RPC.History.Compact(t.Context())
if err != nil {
t.Fatalf("Failed to compact session: %v", err)
}
diff --git a/go/internal/e2e/session_fs_test.go b/go/internal/e2e/session_fs_test.go
index d08607ba4..4d006a856 100644
--- a/go/internal/e2e/session_fs_test.go
+++ b/go/internal/e2e/session_fs_test.go
@@ -233,7 +233,7 @@ func TestSessionFs(t *testing.T) {
t.Fatalf("Expected events file to not contain checkpointNumber before compaction")
}
- compactionResult, err := session.RPC.Compaction.Compact(t.Context())
+ compactionResult, err := session.RPC.History.Compact(t.Context())
if err != nil {
t.Fatalf("Failed to compact session: %v", err)
}
diff --git a/go/rpc/generated_rpc.go b/go/rpc/generated_rpc.go
index 97d886e48..6782f499d 100644
--- a/go/rpc/generated_rpc.go
+++ b/go/rpc/generated_rpc.go
@@ -236,6 +236,21 @@ type SessionFSSetProviderParams struct {
SessionStatePath string `json:"sessionStatePath"`
}
+// Experimental: SessionsForkResult is part of an experimental API and may change or be removed.
+type SessionsForkResult struct {
+ // The new forked session's ID
+ SessionID string `json:"sessionId"`
+}
+
+// Experimental: SessionsForkParams is part of an experimental API and may change or be removed.
+type SessionsForkParams struct {
+ // Source session ID to fork from
+ SessionID string `json:"sessionId"`
+ // Optional event ID boundary. When provided, the fork includes only events before this ID
+ // (exclusive). When omitted, all events are included.
+ ToEventID *string `json:"toEventId,omitempty"`
+}
+
type SessionModelGetCurrentResult struct {
// Currently active model identifier
ModelID *string `json:"modelId,omitempty"`
@@ -570,16 +585,6 @@ type SessionExtensionsDisableParams struct {
type SessionExtensionsReloadResult struct {
}
-// Experimental: SessionCompactionCompactResult is part of an experimental API and may change or be removed.
-type SessionCompactionCompactResult struct {
- // Number of messages removed during compaction
- MessagesRemoved float64 `json:"messagesRemoved"`
- // Whether compaction completed successfully
- Success bool `json:"success"`
- // Number of tokens freed by compaction
- TokensRemoved float64 `json:"tokensRemoved"`
-}
-
type SessionToolsHandlePendingToolCallResult struct {
// Whether the tool call result was handled successfully
Success bool `json:"success"`
@@ -750,6 +755,28 @@ type SessionShellKillParams struct {
Signal *Signal `json:"signal,omitempty"`
}
+// Experimental: SessionHistoryCompactResult is part of an experimental API and may change or be removed.
+type SessionHistoryCompactResult struct {
+ // Number of messages removed during compaction
+ MessagesRemoved float64 `json:"messagesRemoved"`
+ // Whether compaction completed successfully
+ Success bool `json:"success"`
+ // Number of tokens freed by compaction
+ TokensRemoved float64 `json:"tokensRemoved"`
+}
+
+// Experimental: SessionHistoryTruncateResult is part of an experimental API and may change or be removed.
+type SessionHistoryTruncateResult struct {
+ // Number of events that were removed
+ EventsRemoved float64 `json:"eventsRemoved"`
+}
+
+// Experimental: SessionHistoryTruncateParams is part of an experimental API and may change or be removed.
+type SessionHistoryTruncateParams struct {
+ // Event ID to truncate to. This event and all events after it are removed from the session.
+ EventID string `json:"eventId"`
+}
+
type SessionFSReadFileResult struct {
// File content as UTF-8 string
Content string `json:"content"`
@@ -1103,6 +1130,21 @@ func (a *ServerSessionFsApi) SetProvider(ctx context.Context, params *SessionFSS
return &result, nil
}
+// Experimental: ServerSessionsApi contains experimental APIs that may change or be removed.
+type ServerSessionsApi serverApi
+
+func (a *ServerSessionsApi) Fork(ctx context.Context, params *SessionsForkParams) (*SessionsForkResult, error) {
+ raw, err := a.client.Request("sessions.fork", params)
+ if err != nil {
+ return nil, err
+ }
+ var result SessionsForkResult
+ if err := json.Unmarshal(raw, &result); err != nil {
+ return nil, err
+ }
+ return &result, nil
+}
+
// ServerRpc provides typed server-scoped RPC methods.
type ServerRpc struct {
common serverApi // Reuse a single struct instead of allocating one for each service on the heap.
@@ -1112,6 +1154,7 @@ type ServerRpc struct {
Account *ServerAccountApi
Mcp *ServerMcpApi
SessionFs *ServerSessionFsApi
+ Sessions *ServerSessionsApi
}
func (a *ServerRpc) Ping(ctx context.Context, params *PingParams) (*PingResult, error) {
@@ -1134,6 +1177,7 @@ func NewServerRpc(client *jsonrpc2.Client) *ServerRpc {
r.Account = (*ServerAccountApi)(&r.common)
r.Mcp = (*ServerMcpApi)(&r.common)
r.SessionFs = (*ServerSessionFsApi)(&r.common)
+ r.Sessions = (*ServerSessionsApi)(&r.common)
return r
}
@@ -1593,22 +1637,6 @@ func (a *ExtensionsApi) Reload(ctx context.Context) (*SessionExtensionsReloadRes
return &result, nil
}
-// Experimental: CompactionApi contains experimental APIs that may change or be removed.
-type CompactionApi sessionApi
-
-func (a *CompactionApi) Compact(ctx context.Context) (*SessionCompactionCompactResult, error) {
- req := map[string]any{"sessionId": a.sessionID}
- raw, err := a.client.Request("session.compaction.compact", req)
- if err != nil {
- return nil, err
- }
- var result SessionCompactionCompactResult
- if err := json.Unmarshal(raw, &result); err != nil {
- return nil, err
- }
- return &result, nil
-}
-
type ToolsApi sessionApi
func (a *ToolsApi) HandlePendingToolCall(ctx context.Context, params *SessionToolsHandlePendingToolCallParams) (*SessionToolsHandlePendingToolCallResult, error) {
@@ -1752,6 +1780,38 @@ func (a *ShellApi) Kill(ctx context.Context, params *SessionShellKillParams) (*S
return &result, nil
}
+// Experimental: HistoryApi contains experimental APIs that may change or be removed.
+type HistoryApi sessionApi
+
+func (a *HistoryApi) Compact(ctx context.Context) (*SessionHistoryCompactResult, error) {
+ req := map[string]any{"sessionId": a.sessionID}
+ raw, err := a.client.Request("session.history.compact", req)
+ if err != nil {
+ return nil, err
+ }
+ var result SessionHistoryCompactResult
+ if err := json.Unmarshal(raw, &result); err != nil {
+ return nil, err
+ }
+ return &result, nil
+}
+
+func (a *HistoryApi) Truncate(ctx context.Context, params *SessionHistoryTruncateParams) (*SessionHistoryTruncateResult, error) {
+ req := map[string]any{"sessionId": a.sessionID}
+ if params != nil {
+ req["eventId"] = params.EventID
+ }
+ raw, err := a.client.Request("session.history.truncate", req)
+ if err != nil {
+ return nil, err
+ }
+ var result SessionHistoryTruncateResult
+ if err := json.Unmarshal(raw, &result); err != nil {
+ return nil, err
+ }
+ return &result, nil
+}
+
// SessionRpc provides typed session-scoped RPC methods.
type SessionRpc struct {
common sessionApi // Reuse a single struct instead of allocating one for each service on the heap.
@@ -1766,12 +1826,12 @@ type SessionRpc struct {
Mcp *McpApi
Plugins *PluginsApi
Extensions *ExtensionsApi
- Compaction *CompactionApi
Tools *ToolsApi
Commands *CommandsApi
UI *UIApi
Permissions *PermissionsApi
Shell *ShellApi
+ History *HistoryApi
}
func (a *SessionRpc) Log(ctx context.Context, params *SessionLogParams) (*SessionLogResult, error) {
@@ -1812,12 +1872,12 @@ func NewSessionRpc(client *jsonrpc2.Client, sessionID string) *SessionRpc {
r.Mcp = (*McpApi)(&r.common)
r.Plugins = (*PluginsApi)(&r.common)
r.Extensions = (*ExtensionsApi)(&r.common)
- r.Compaction = (*CompactionApi)(&r.common)
r.Tools = (*ToolsApi)(&r.common)
r.Commands = (*CommandsApi)(&r.common)
r.UI = (*UIApi)(&r.common)
r.Permissions = (*PermissionsApi)(&r.common)
r.Shell = (*ShellApi)(&r.common)
+ r.History = (*HistoryApi)(&r.common)
return r
}
diff --git a/nodejs/package-lock.json b/nodejs/package-lock.json
index e51474b78..84754e70f 100644
--- a/nodejs/package-lock.json
+++ b/nodejs/package-lock.json
@@ -9,7 +9,7 @@
"version": "0.1.8",
"license": "MIT",
"dependencies": {
- "@github/copilot": "^1.0.20-1",
+ "@github/copilot": "^1.0.21",
"vscode-jsonrpc": "^8.2.1",
"zod": "^4.3.6"
},
@@ -663,26 +663,26 @@
}
},
"node_modules/@github/copilot": {
- "version": "1.0.20-1",
- "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.20-1.tgz",
- "integrity": "sha512-a34M4P6XcKFy1sDubqn54qakQxeWwA44vKaOh3oNZT8vgna9R4ap2NYGnM8fn7XDAdlJ9QgW6Xt7dfPGwKkt/A==",
+ "version": "1.0.21",
+ "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.21.tgz",
+ "integrity": "sha512-P+nORjNKAtl92jYCG6Qr1Rsw2JoyScgeQSkIR6O2WB37WS5JVdA4ax1WVualMbfuc9V58CPHX6fwyNpkI89FkQ==",
"license": "SEE LICENSE IN LICENSE.md",
"bin": {
"copilot": "npm-loader.js"
},
"optionalDependencies": {
- "@github/copilot-darwin-arm64": "1.0.20-1",
- "@github/copilot-darwin-x64": "1.0.20-1",
- "@github/copilot-linux-arm64": "1.0.20-1",
- "@github/copilot-linux-x64": "1.0.20-1",
- "@github/copilot-win32-arm64": "1.0.20-1",
- "@github/copilot-win32-x64": "1.0.20-1"
+ "@github/copilot-darwin-arm64": "1.0.21",
+ "@github/copilot-darwin-x64": "1.0.21",
+ "@github/copilot-linux-arm64": "1.0.21",
+ "@github/copilot-linux-x64": "1.0.21",
+ "@github/copilot-win32-arm64": "1.0.21",
+ "@github/copilot-win32-x64": "1.0.21"
}
},
"node_modules/@github/copilot-darwin-arm64": {
- "version": "1.0.20-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.20-1.tgz",
- "integrity": "sha512-tip/KyjhRQG7OMAR8rBWrFcPk3XFQQlajozIMPxEA7+qwgMBOlaGcO0iuDEdF5vAtYXhUPPAI/tbuUqkueoJEA==",
+ "version": "1.0.21",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.21.tgz",
+ "integrity": "sha512-aB+s9ldTwcyCOYmzjcQ4SknV6g81z92T8aUJEJZBwOXOTBeWKAJtk16ooAKangZgdwuLgO3or1JUjx1FJAm5nQ==",
"cpu": [
"arm64"
],
@@ -696,9 +696,9 @@
}
},
"node_modules/@github/copilot-darwin-x64": {
- "version": "1.0.20-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.20-1.tgz",
- "integrity": "sha512-d/Etng6335TF1Dcw37XFtjKKZqQbqh9trXg5GhMySUamo4UolykylWJuhs+suCx2JJc1lGzPVAdGOxAvj+4P3Q==",
+ "version": "1.0.21",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.21.tgz",
+ "integrity": "sha512-aNad81DOGuGShmaiFNIxBUSZLwte0dXmDYkGfAF9WJIgY4qP4A8CPWFoNr8//gY+4CwaIf9V+f/OC6k2BdECbw==",
"cpu": [
"x64"
],
@@ -712,9 +712,9 @@
}
},
"node_modules/@github/copilot-linux-arm64": {
- "version": "1.0.20-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.20-1.tgz",
- "integrity": "sha512-ptwwVk/uMEoVdGTbhfC8CLtSCq3agnRKlD+iojabcg5K0y0HbaEGIaOeJle0uARpqeyLADgoUkMbth/wWQI2gQ==",
+ "version": "1.0.21",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.21.tgz",
+ "integrity": "sha512-FL0NsCnHax4czHVv1S8iBqPLGZDhZ28N3+6nT29xWGhmjBWTkIofxLThKUPcyyMsfPTTxIlrdwWa8qQc5z2Q+g==",
"cpu": [
"arm64"
],
@@ -728,9 +728,9 @@
}
},
"node_modules/@github/copilot-linux-x64": {
- "version": "1.0.20-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.20-1.tgz",
- "integrity": "sha512-sUuR5uVR1/Ndew/pSEQP4vLy2iohW+PMD96R+gzJkF77soe+PfFR7R6Py1VWmwAK1MDblyilDfMcusYLXK48LA==",
+ "version": "1.0.21",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.21.tgz",
+ "integrity": "sha512-S7pWVI16hesZtxYbIyfw+MHZpc5ESoGKUVr5Y+lZJNaM2340gJGPQzQwSpvKIRMLHRKI2hXLwciAnYeMFxE/Tg==",
"cpu": [
"x64"
],
@@ -744,9 +744,9 @@
}
},
"node_modules/@github/copilot-win32-arm64": {
- "version": "1.0.20-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.20-1.tgz",
- "integrity": "sha512-gk4belEoOHfQH2pJf0GPh2t1N4suIg1mhwJQHveGi5av22XZzYjY7yarNom+YCqc692MAuYsfNF0wXXSij3wBg==",
+ "version": "1.0.21",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.21.tgz",
+ "integrity": "sha512-a9qc2Ku+XbyBkXCclbIvBbIVnECACTIWnPctmXWsQeSdeapGxgfHGux7y8hAFV5j6+nhCm6cnyEMS3rkZjAhdA==",
"cpu": [
"arm64"
],
@@ -760,9 +760,9 @@
}
},
"node_modules/@github/copilot-win32-x64": {
- "version": "1.0.20-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.20-1.tgz",
- "integrity": "sha512-ypRD1iawRw8a0qzhp4fq4ZqvqL86mk2UZNWyuTM8HOe2o3+SrZbveXpEk7gUYJ4ShLhqLVywJHs4+4yPkv5p+A==",
+ "version": "1.0.21",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.21.tgz",
+ "integrity": "sha512-9klu+7NQ6tEyb8sibb0rsbimBivDrnNltZho10Bgbf1wh3o+erTjffXDjW9Zkyaw8lZA9Fz8bqhVkKntZq58Lg==",
"cpu": [
"x64"
],
diff --git a/nodejs/package.json b/nodejs/package.json
index 55e058ea6..e79814992 100644
--- a/nodejs/package.json
+++ b/nodejs/package.json
@@ -56,7 +56,7 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
- "@github/copilot": "^1.0.20-1",
+ "@github/copilot": "^1.0.21",
"vscode-jsonrpc": "^8.2.1",
"zod": "^4.3.6"
},
diff --git a/nodejs/samples/package-lock.json b/nodejs/samples/package-lock.json
index c0749ee6c..d95f5582a 100644
--- a/nodejs/samples/package-lock.json
+++ b/nodejs/samples/package-lock.json
@@ -18,7 +18,7 @@
"version": "0.1.8",
"license": "MIT",
"dependencies": {
- "@github/copilot": "^1.0.17",
+ "@github/copilot": "^1.0.21",
"vscode-jsonrpc": "^8.2.1",
"zod": "^4.3.6"
},
diff --git a/nodejs/src/generated/rpc.ts b/nodejs/src/generated/rpc.ts
index a72c07b9a..753a6a65f 100644
--- a/nodejs/src/generated/rpc.ts
+++ b/nodejs/src/generated/rpc.ts
@@ -383,6 +383,26 @@ export interface SessionFsSetProviderParams {
conventions: "windows" | "posix";
}
+/** @experimental */
+export interface SessionsForkResult {
+ /**
+ * The new forked session's ID
+ */
+ sessionId: string;
+}
+
+/** @experimental */
+export interface SessionsForkParams {
+ /**
+ * Source session ID to fork from
+ */
+ sessionId: string;
+ /**
+ * Optional event ID boundary. When provided, the fork includes only events before this ID (exclusive). When omitted, all events are included.
+ */
+ toEventId?: string;
+}
+
export interface SessionModelGetCurrentResult {
/**
* Currently active model identifier
@@ -1003,30 +1023,6 @@ export interface SessionExtensionsReloadParams {
sessionId: string;
}
-/** @experimental */
-export interface SessionCompactionCompactResult {
- /**
- * Whether compaction completed successfully
- */
- success: boolean;
- /**
- * Number of tokens freed by compaction
- */
- tokensRemoved: number;
- /**
- * Number of messages removed during compaction
- */
- messagesRemoved: number;
-}
-
-/** @experimental */
-export interface SessionCompactionCompactParams {
- /**
- * Target session identifier
- */
- sessionId: string;
-}
-
export interface SessionToolsHandlePendingToolCallResult {
/**
* Whether the tool call result was handled successfully
@@ -1333,6 +1329,50 @@ export interface SessionShellKillParams {
signal?: "SIGTERM" | "SIGKILL" | "SIGINT";
}
+/** @experimental */
+export interface SessionHistoryCompactResult {
+ /**
+ * Whether compaction completed successfully
+ */
+ success: boolean;
+ /**
+ * Number of tokens freed by compaction
+ */
+ tokensRemoved: number;
+ /**
+ * Number of messages removed during compaction
+ */
+ messagesRemoved: number;
+}
+
+/** @experimental */
+export interface SessionHistoryCompactParams {
+ /**
+ * Target session identifier
+ */
+ sessionId: string;
+}
+
+/** @experimental */
+export interface SessionHistoryTruncateResult {
+ /**
+ * Number of events that were removed
+ */
+ eventsRemoved: number;
+}
+
+/** @experimental */
+export interface SessionHistoryTruncateParams {
+ /**
+ * Target session identifier
+ */
+ sessionId: string;
+ /**
+ * Event ID to truncate to. This event and all events after it are removed from the session.
+ */
+ eventId: string;
+}
+
export interface SessionFsReadFileResult {
/**
* File content as UTF-8 string
@@ -1572,6 +1612,11 @@ export function createServerRpc(connection: MessageConnection) {
setProvider: async (params: SessionFsSetProviderParams): Promise =>
connection.sendRequest("sessionFs.setProvider", params),
},
+ /** @experimental */
+ sessions: {
+ fork: async (params: SessionsForkParams): Promise =>
+ connection.sendRequest("sessions.fork", params),
+ },
};
}
@@ -1662,11 +1707,6 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin
reload: async (): Promise =>
connection.sendRequest("session.extensions.reload", { sessionId }),
},
- /** @experimental */
- compaction: {
- compact: async (): Promise =>
- connection.sendRequest("session.compaction.compact", { sessionId }),
- },
tools: {
handlePendingToolCall: async (params: Omit): Promise =>
connection.sendRequest("session.tools.handlePendingToolCall", { sessionId, ...params }),
@@ -1693,6 +1733,13 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin
kill: async (params: Omit): Promise =>
connection.sendRequest("session.shell.kill", { sessionId, ...params }),
},
+ /** @experimental */
+ history: {
+ compact: async (): Promise =>
+ connection.sendRequest("session.history.compact", { sessionId }),
+ truncate: async (params: Omit): Promise =>
+ connection.sendRequest("session.history.truncate", { sessionId, ...params }),
+ },
};
}
diff --git a/nodejs/src/generated/session-events.ts b/nodejs/src/generated/session-events.ts
index 0c0389ad0..e9bc2a550 100644
--- a/nodejs/src/generated/session-events.ts
+++ b/nodejs/src/generated/session-events.ts
@@ -270,7 +270,7 @@ export type SessionEvent =
ephemeral: true;
type: "session.idle";
/**
- * Payload indicating the session is fully idle with no background tasks in flight
+ * Payload indicating the session is idle with no background agents in flight
*/
data: {
/**
@@ -649,7 +649,7 @@ export type SessionEvent =
*/
data: {
/**
- * Event ID that was rewound to; all events after this one were removed
+ * Event ID that was rewound to; this event and all after it were removed
*/
upToEventId: string;
/**
@@ -1478,6 +1478,10 @@ export type SessionEvent =
* CAPI interaction ID for correlating this message with upstream telemetry
*/
interactionId?: string;
+ /**
+ * GitHub request tracing ID (x-github-request-id header) for correlating with server-side logs
+ */
+ requestId?: string;
/**
* Tool call ID of the parent tool invocation when this event originates from a sub-agent
*/
diff --git a/nodejs/test/e2e/agent_and_compact_rpc.test.ts b/nodejs/test/e2e/agent_and_compact_rpc.test.ts
index 336cd69b6..1e3bfb5e2 100644
--- a/nodejs/test/e2e/agent_and_compact_rpc.test.ts
+++ b/nodejs/test/e2e/agent_and_compact_rpc.test.ts
@@ -139,7 +139,7 @@ describe("Session Compact RPC", async () => {
await session.sendAndWait({ prompt: "What is 2+2?" });
// Compact the session
- const result = await session.rpc.compaction.compact();
+ const result = await session.rpc.history.compact();
expect(typeof result.success).toBe("boolean");
expect(typeof result.tokensRemoved).toBe("number");
expect(typeof result.messagesRemoved).toBe("number");
diff --git a/nodejs/test/e2e/session_fs.test.ts b/nodejs/test/e2e/session_fs.test.ts
index 2f67f2ca0..8185a55be 100644
--- a/nodejs/test/e2e/session_fs.test.ts
+++ b/nodejs/test/e2e/session_fs.test.ts
@@ -139,7 +139,7 @@ describe("Session Fs", async () => {
const contentBefore = await provider.readFile(eventsPath, "utf8");
expect(contentBefore).not.toContain("checkpointNumber");
- await session.rpc.compaction.compact();
+ await session.rpc.history.compact();
await expect.poll(() => compactionEvent).toBeDefined();
expect(compactionEvent!.data.success).toBe(true);
diff --git a/python/copilot/generated/rpc.py b/python/copilot/generated/rpc.py
index 52cc891a4..43bb879be 100644
--- a/python/copilot/generated/rpc.py
+++ b/python/copilot/generated/rpc.py
@@ -841,6 +841,50 @@ def to_dict(self) -> dict:
return result
+# Experimental: this type is part of an experimental API and may change or be removed.
+@dataclass
+class SessionsForkResult:
+ session_id: str
+ """The new forked session's ID"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'SessionsForkResult':
+ assert isinstance(obj, dict)
+ session_id = from_str(obj.get("sessionId"))
+ return SessionsForkResult(session_id)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["sessionId"] = from_str(self.session_id)
+ return result
+
+
+# Experimental: this type is part of an experimental API and may change or be removed.
+@dataclass
+class SessionsForkParams:
+ session_id: str
+ """Source session ID to fork from"""
+
+ to_event_id: str | None = None
+ """Optional event ID boundary. When provided, the fork includes only events before this ID
+ (exclusive). When omitted, all events are included.
+ """
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'SessionsForkParams':
+ assert isinstance(obj, dict)
+ session_id = from_str(obj.get("sessionId"))
+ to_event_id = from_union([from_str, from_none], obj.get("toEventId"))
+ return SessionsForkParams(session_id, to_event_id)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["sessionId"] = from_str(self.session_id)
+ if self.to_event_id is not None:
+ result["toEventId"] = from_union([from_str, from_none], self.to_event_id)
+ return result
+
+
@dataclass
class SessionModelGetCurrentResult:
model_id: str | None = None
@@ -1950,34 +1994,6 @@ def to_dict(self) -> dict:
return result
-# Experimental: this type is part of an experimental API and may change or be removed.
-@dataclass
-class SessionCompactionCompactResult:
- messages_removed: float
- """Number of messages removed during compaction"""
-
- success: bool
- """Whether compaction completed successfully"""
-
- tokens_removed: float
- """Number of tokens freed by compaction"""
-
- @staticmethod
- def from_dict(obj: Any) -> 'SessionCompactionCompactResult':
- assert isinstance(obj, dict)
- messages_removed = from_float(obj.get("messagesRemoved"))
- success = from_bool(obj.get("success"))
- tokens_removed = from_float(obj.get("tokensRemoved"))
- return SessionCompactionCompactResult(messages_removed, success, tokens_removed)
-
- def to_dict(self) -> dict:
- result: dict = {}
- result["messagesRemoved"] = to_float(self.messages_removed)
- result["success"] = from_bool(self.success)
- result["tokensRemoved"] = to_float(self.tokens_removed)
- return result
-
-
@dataclass
class SessionToolsHandlePendingToolCallResult:
success: bool
@@ -2630,6 +2646,70 @@ def to_dict(self) -> dict:
return result
+# Experimental: this type is part of an experimental API and may change or be removed.
+@dataclass
+class SessionHistoryCompactResult:
+ messages_removed: float
+ """Number of messages removed during compaction"""
+
+ success: bool
+ """Whether compaction completed successfully"""
+
+ tokens_removed: float
+ """Number of tokens freed by compaction"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'SessionHistoryCompactResult':
+ assert isinstance(obj, dict)
+ messages_removed = from_float(obj.get("messagesRemoved"))
+ success = from_bool(obj.get("success"))
+ tokens_removed = from_float(obj.get("tokensRemoved"))
+ return SessionHistoryCompactResult(messages_removed, success, tokens_removed)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["messagesRemoved"] = to_float(self.messages_removed)
+ result["success"] = from_bool(self.success)
+ result["tokensRemoved"] = to_float(self.tokens_removed)
+ return result
+
+
+# Experimental: this type is part of an experimental API and may change or be removed.
+@dataclass
+class SessionHistoryTruncateResult:
+ events_removed: float
+ """Number of events that were removed"""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'SessionHistoryTruncateResult':
+ assert isinstance(obj, dict)
+ events_removed = from_float(obj.get("eventsRemoved"))
+ return SessionHistoryTruncateResult(events_removed)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["eventsRemoved"] = to_float(self.events_removed)
+ return result
+
+
+# Experimental: this type is part of an experimental API and may change or be removed.
+@dataclass
+class SessionHistoryTruncateParams:
+ event_id: str
+ """Event ID to truncate to. This event and all events after it are removed from the session."""
+
+ @staticmethod
+ def from_dict(obj: Any) -> 'SessionHistoryTruncateParams':
+ assert isinstance(obj, dict)
+ event_id = from_str(obj.get("eventId"))
+ return SessionHistoryTruncateParams(event_id)
+
+ def to_dict(self) -> dict:
+ result: dict = {}
+ result["eventId"] = from_str(self.event_id)
+ return result
+
+
@dataclass
class SessionFSReadFileResult:
content: str
@@ -3131,6 +3211,22 @@ def session_fs_set_provider_params_to_dict(x: SessionFSSetProviderParams) -> Any
return to_class(SessionFSSetProviderParams, x)
+def sessions_fork_result_from_dict(s: Any) -> SessionsForkResult:
+ return SessionsForkResult.from_dict(s)
+
+
+def sessions_fork_result_to_dict(x: SessionsForkResult) -> Any:
+ return to_class(SessionsForkResult, x)
+
+
+def sessions_fork_params_from_dict(s: Any) -> SessionsForkParams:
+ return SessionsForkParams.from_dict(s)
+
+
+def sessions_fork_params_to_dict(x: SessionsForkParams) -> Any:
+ return to_class(SessionsForkParams, x)
+
+
def session_model_get_current_result_from_dict(s: Any) -> SessionModelGetCurrentResult:
return SessionModelGetCurrentResult.from_dict(s)
@@ -3467,14 +3563,6 @@ def session_extensions_reload_result_to_dict(x: SessionExtensionsReloadResult) -
return to_class(SessionExtensionsReloadResult, x)
-def session_compaction_compact_result_from_dict(s: Any) -> SessionCompactionCompactResult:
- return SessionCompactionCompactResult.from_dict(s)
-
-
-def session_compaction_compact_result_to_dict(x: SessionCompactionCompactResult) -> Any:
- return to_class(SessionCompactionCompactResult, x)
-
-
def session_tools_handle_pending_tool_call_result_from_dict(s: Any) -> SessionToolsHandlePendingToolCallResult:
return SessionToolsHandlePendingToolCallResult.from_dict(s)
@@ -3603,6 +3691,30 @@ def session_shell_kill_params_to_dict(x: SessionShellKillParams) -> Any:
return to_class(SessionShellKillParams, x)
+def session_history_compact_result_from_dict(s: Any) -> SessionHistoryCompactResult:
+ return SessionHistoryCompactResult.from_dict(s)
+
+
+def session_history_compact_result_to_dict(x: SessionHistoryCompactResult) -> Any:
+ return to_class(SessionHistoryCompactResult, x)
+
+
+def session_history_truncate_result_from_dict(s: Any) -> SessionHistoryTruncateResult:
+ return SessionHistoryTruncateResult.from_dict(s)
+
+
+def session_history_truncate_result_to_dict(x: SessionHistoryTruncateResult) -> Any:
+ return to_class(SessionHistoryTruncateResult, x)
+
+
+def session_history_truncate_params_from_dict(s: Any) -> SessionHistoryTruncateParams:
+ return SessionHistoryTruncateParams.from_dict(s)
+
+
+def session_history_truncate_params_to_dict(x: SessionHistoryTruncateParams) -> Any:
+ return to_class(SessionHistoryTruncateParams, x)
+
+
def session_fs_read_file_result_from_dict(s: Any) -> SessionFSReadFileResult:
return SessionFSReadFileResult.from_dict(s)
@@ -3769,6 +3881,16 @@ async def set_provider(self, params: SessionFSSetProviderParams, *, timeout: flo
return SessionFSSetProviderResult.from_dict(await self._client.request("sessionFs.setProvider", params_dict, **_timeout_kwargs(timeout)))
+# Experimental: this API group is experimental and may change or be removed.
+class ServerSessionsApi:
+ def __init__(self, client: "JsonRpcClient"):
+ self._client = client
+
+ async def fork(self, params: SessionsForkParams, *, timeout: float | None = None) -> SessionsForkResult:
+ params_dict = {k: v for k, v in params.to_dict().items() if v is not None}
+ return SessionsForkResult.from_dict(await self._client.request("sessions.fork", params_dict, **_timeout_kwargs(timeout)))
+
+
class ServerRpc:
"""Typed server-scoped RPC methods."""
def __init__(self, client: "JsonRpcClient"):
@@ -3778,6 +3900,7 @@ def __init__(self, client: "JsonRpcClient"):
self.account = ServerAccountApi(client)
self.mcp = ServerMcpApi(client)
self.session_fs = ServerSessionFsApi(client)
+ self.sessions = ServerSessionsApi(client)
async def ping(self, params: PingParams, *, timeout: float | None = None) -> PingResult:
params_dict = {k: v for k, v in params.to_dict().items() if v is not None}
@@ -3963,16 +4086,6 @@ async def reload(self, *, timeout: float | None = None) -> SessionExtensionsRelo
return SessionExtensionsReloadResult.from_dict(await self._client.request("session.extensions.reload", {"sessionId": self._session_id}, **_timeout_kwargs(timeout)))
-# Experimental: this API group is experimental and may change or be removed.
-class CompactionApi:
- def __init__(self, client: "JsonRpcClient", session_id: str):
- self._client = client
- self._session_id = session_id
-
- async def compact(self, *, timeout: float | None = None) -> SessionCompactionCompactResult:
- return SessionCompactionCompactResult.from_dict(await self._client.request("session.compaction.compact", {"sessionId": self._session_id}, **_timeout_kwargs(timeout)))
-
-
class ToolsApi:
def __init__(self, client: "JsonRpcClient", session_id: str):
self._client = client
@@ -4038,6 +4151,21 @@ async def kill(self, params: SessionShellKillParams, *, timeout: float | None =
return SessionShellKillResult.from_dict(await self._client.request("session.shell.kill", params_dict, **_timeout_kwargs(timeout)))
+# Experimental: this API group is experimental and may change or be removed.
+class HistoryApi:
+ def __init__(self, client: "JsonRpcClient", session_id: str):
+ self._client = client
+ self._session_id = session_id
+
+ async def compact(self, *, timeout: float | None = None) -> SessionHistoryCompactResult:
+ return SessionHistoryCompactResult.from_dict(await self._client.request("session.history.compact", {"sessionId": self._session_id}, **_timeout_kwargs(timeout)))
+
+ async def truncate(self, params: SessionHistoryTruncateParams, *, timeout: float | None = None) -> SessionHistoryTruncateResult:
+ params_dict = {k: v for k, v in params.to_dict().items() if v is not None}
+ params_dict["sessionId"] = self._session_id
+ return SessionHistoryTruncateResult.from_dict(await self._client.request("session.history.truncate", params_dict, **_timeout_kwargs(timeout)))
+
+
class SessionRpc:
"""Typed session-scoped RPC methods."""
def __init__(self, client: "JsonRpcClient", session_id: str):
@@ -4053,12 +4181,12 @@ def __init__(self, client: "JsonRpcClient", session_id: str):
self.mcp = McpApi(client, session_id)
self.plugins = PluginsApi(client, session_id)
self.extensions = ExtensionsApi(client, session_id)
- self.compaction = CompactionApi(client, session_id)
self.tools = ToolsApi(client, session_id)
self.commands = CommandsApi(client, session_id)
self.ui = UiApi(client, session_id)
self.permissions = PermissionsApi(client, session_id)
self.shell = ShellApi(client, session_id)
+ self.history = HistoryApi(client, session_id)
async def log(self, params: SessionLogParams, *, timeout: float | None = None) -> SessionLogResult:
params_dict = {k: v for k, v in params.to_dict().items() if v is not None}
diff --git a/python/copilot/generated/session_events.py b/python/copilot/generated/session_events.py
index 361718ebb..dea0e79fd 100644
--- a/python/copilot/generated/session_events.py
+++ b/python/copilot/generated/session_events.py
@@ -1709,7 +1709,7 @@ class Data:
Error details for timeline display including message and optional diagnostic information
- Payload indicating the session is fully idle with no background tasks in flight
+ Payload indicating the session is idle with no background agents in flight
Session title change payload containing the new display title
@@ -2018,7 +2018,7 @@ class Data:
"""Number of events that were removed by the rewind"""
up_to_event_id: str | None = None
- """Event ID that was rewound to; all events after this one were removed"""
+ """Event ID that was rewound to; this event and all after it were removed"""
code_changes: CodeChanges | None = None
"""Aggregate code change metrics for the session"""
@@ -2133,6 +2133,9 @@ class Data:
request_id: str | None = None
"""GitHub request tracing ID (x-github-request-id header) for the compaction LLM call
+ GitHub request tracing ID (x-github-request-id header) for correlating with server-side
+ logs
+
Unique identifier for this permission request; used to respond via
session.respondToPermission()
@@ -3205,7 +3208,7 @@ class SessionEvent:
Error details for timeline display including message and optional diagnostic information
- Payload indicating the session is fully idle with no background tasks in flight
+ Payload indicating the session is idle with no background agents in flight
Session title change payload containing the new display title
diff --git a/python/e2e/test_agent_and_compact_rpc.py b/python/e2e/test_agent_and_compact_rpc.py
index ce946d2f3..047765641 100644
--- a/python/e2e/test_agent_and_compact_rpc.py
+++ b/python/e2e/test_agent_and_compact_rpc.py
@@ -185,7 +185,7 @@ async def test_should_compact_session_history_after_messages(self, ctx: E2ETestC
await session.send_and_wait("What is 2+2?")
# Compact the session
- result = await session.rpc.compaction.compact()
+ result = await session.rpc.history.compact()
assert isinstance(result.success, bool)
assert isinstance(result.tokens_removed, (int, float))
assert isinstance(result.messages_removed, (int, float))
diff --git a/python/e2e/test_session_fs.py b/python/e2e/test_session_fs.py
index a656ce0f8..d9bfabb55 100644
--- a/python/e2e/test_session_fs.py
+++ b/python/e2e/test_session_fs.py
@@ -206,7 +206,7 @@ def on_event(event: SessionEvent):
await wait_for_path(events_path)
assert "checkpointNumber" not in events_path.read_text(encoding="utf-8")
- result = await session.rpc.compaction.compact()
+ result = await session.rpc.history.compact()
await asyncio.wait_for(compaction_event.wait(), timeout=5.0)
assert result.success is True
assert compaction_success is True
diff --git a/test/harness/package-lock.json b/test/harness/package-lock.json
index 67e294c83..7b3277eba 100644
--- a/test/harness/package-lock.json
+++ b/test/harness/package-lock.json
@@ -9,7 +9,7 @@
"version": "1.0.0",
"license": "ISC",
"devDependencies": {
- "@github/copilot": "^1.0.20-1",
+ "@github/copilot": "^1.0.21",
"@modelcontextprotocol/sdk": "^1.26.0",
"@types/node": "^25.3.3",
"openai": "^6.17.0",
@@ -462,27 +462,27 @@
}
},
"node_modules/@github/copilot": {
- "version": "1.0.20-1",
- "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.20-1.tgz",
- "integrity": "sha512-a34M4P6XcKFy1sDubqn54qakQxeWwA44vKaOh3oNZT8vgna9R4ap2NYGnM8fn7XDAdlJ9QgW6Xt7dfPGwKkt/A==",
+ "version": "1.0.21",
+ "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.21.tgz",
+ "integrity": "sha512-P+nORjNKAtl92jYCG6Qr1Rsw2JoyScgeQSkIR6O2WB37WS5JVdA4ax1WVualMbfuc9V58CPHX6fwyNpkI89FkQ==",
"dev": true,
"license": "SEE LICENSE IN LICENSE.md",
"bin": {
"copilot": "npm-loader.js"
},
"optionalDependencies": {
- "@github/copilot-darwin-arm64": "1.0.20-1",
- "@github/copilot-darwin-x64": "1.0.20-1",
- "@github/copilot-linux-arm64": "1.0.20-1",
- "@github/copilot-linux-x64": "1.0.20-1",
- "@github/copilot-win32-arm64": "1.0.20-1",
- "@github/copilot-win32-x64": "1.0.20-1"
+ "@github/copilot-darwin-arm64": "1.0.21",
+ "@github/copilot-darwin-x64": "1.0.21",
+ "@github/copilot-linux-arm64": "1.0.21",
+ "@github/copilot-linux-x64": "1.0.21",
+ "@github/copilot-win32-arm64": "1.0.21",
+ "@github/copilot-win32-x64": "1.0.21"
}
},
"node_modules/@github/copilot-darwin-arm64": {
- "version": "1.0.20-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.20-1.tgz",
- "integrity": "sha512-tip/KyjhRQG7OMAR8rBWrFcPk3XFQQlajozIMPxEA7+qwgMBOlaGcO0iuDEdF5vAtYXhUPPAI/tbuUqkueoJEA==",
+ "version": "1.0.21",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.21.tgz",
+ "integrity": "sha512-aB+s9ldTwcyCOYmzjcQ4SknV6g81z92T8aUJEJZBwOXOTBeWKAJtk16ooAKangZgdwuLgO3or1JUjx1FJAm5nQ==",
"cpu": [
"arm64"
],
@@ -497,9 +497,9 @@
}
},
"node_modules/@github/copilot-darwin-x64": {
- "version": "1.0.20-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.20-1.tgz",
- "integrity": "sha512-d/Etng6335TF1Dcw37XFtjKKZqQbqh9trXg5GhMySUamo4UolykylWJuhs+suCx2JJc1lGzPVAdGOxAvj+4P3Q==",
+ "version": "1.0.21",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.21.tgz",
+ "integrity": "sha512-aNad81DOGuGShmaiFNIxBUSZLwte0dXmDYkGfAF9WJIgY4qP4A8CPWFoNr8//gY+4CwaIf9V+f/OC6k2BdECbw==",
"cpu": [
"x64"
],
@@ -514,9 +514,9 @@
}
},
"node_modules/@github/copilot-linux-arm64": {
- "version": "1.0.20-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.20-1.tgz",
- "integrity": "sha512-ptwwVk/uMEoVdGTbhfC8CLtSCq3agnRKlD+iojabcg5K0y0HbaEGIaOeJle0uARpqeyLADgoUkMbth/wWQI2gQ==",
+ "version": "1.0.21",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.21.tgz",
+ "integrity": "sha512-FL0NsCnHax4czHVv1S8iBqPLGZDhZ28N3+6nT29xWGhmjBWTkIofxLThKUPcyyMsfPTTxIlrdwWa8qQc5z2Q+g==",
"cpu": [
"arm64"
],
@@ -531,9 +531,9 @@
}
},
"node_modules/@github/copilot-linux-x64": {
- "version": "1.0.20-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.20-1.tgz",
- "integrity": "sha512-sUuR5uVR1/Ndew/pSEQP4vLy2iohW+PMD96R+gzJkF77soe+PfFR7R6Py1VWmwAK1MDblyilDfMcusYLXK48LA==",
+ "version": "1.0.21",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.21.tgz",
+ "integrity": "sha512-S7pWVI16hesZtxYbIyfw+MHZpc5ESoGKUVr5Y+lZJNaM2340gJGPQzQwSpvKIRMLHRKI2hXLwciAnYeMFxE/Tg==",
"cpu": [
"x64"
],
@@ -548,9 +548,9 @@
}
},
"node_modules/@github/copilot-win32-arm64": {
- "version": "1.0.20-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.20-1.tgz",
- "integrity": "sha512-gk4belEoOHfQH2pJf0GPh2t1N4suIg1mhwJQHveGi5av22XZzYjY7yarNom+YCqc692MAuYsfNF0wXXSij3wBg==",
+ "version": "1.0.21",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.21.tgz",
+ "integrity": "sha512-a9qc2Ku+XbyBkXCclbIvBbIVnECACTIWnPctmXWsQeSdeapGxgfHGux7y8hAFV5j6+nhCm6cnyEMS3rkZjAhdA==",
"cpu": [
"arm64"
],
@@ -565,9 +565,9 @@
}
},
"node_modules/@github/copilot-win32-x64": {
- "version": "1.0.20-1",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.20-1.tgz",
- "integrity": "sha512-ypRD1iawRw8a0qzhp4fq4ZqvqL86mk2UZNWyuTM8HOe2o3+SrZbveXpEk7gUYJ4ShLhqLVywJHs4+4yPkv5p+A==",
+ "version": "1.0.21",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.21.tgz",
+ "integrity": "sha512-9klu+7NQ6tEyb8sibb0rsbimBivDrnNltZho10Bgbf1wh3o+erTjffXDjW9Zkyaw8lZA9Fz8bqhVkKntZq58Lg==",
"cpu": [
"x64"
],
diff --git a/test/harness/package.json b/test/harness/package.json
index 48f43e856..d9b9ea64b 100644
--- a/test/harness/package.json
+++ b/test/harness/package.json
@@ -11,7 +11,7 @@
"test": "vitest run"
},
"devDependencies": {
- "@github/copilot": "^1.0.20-1",
+ "@github/copilot": "^1.0.21",
"@modelcontextprotocol/sdk": "^1.26.0",
"@types/node": "^25.3.3",
"openai": "^6.17.0",