Skip to content

Commit 41e044f

Browse files
Fix CR feedback
1 parent ac20283 commit 41e044f

File tree

10 files changed

+32
-24
lines changed

10 files changed

+32
-24
lines changed

dotnet/src/Client.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,11 @@ public partial class CopilotClient : IDisposable, IAsyncDisposable
7272
/// <remarks>
7373
/// The client must be started before accessing this property. Use <see cref="StartAsync"/> or set <see cref="CopilotClientOptions.AutoStart"/> to true.
7474
/// </remarks>
75+
/// <exception cref="ObjectDisposedException">Thrown if the client has been disposed.</exception>
7576
/// <exception cref="InvalidOperationException">Thrown if the client is not started.</exception>
76-
public ServerRpc Rpc => _rpc ?? throw new InvalidOperationException("Client is not started. Call StartAsync first.");
77+
public ServerRpc Rpc => _disposed
78+
? throw new ObjectDisposedException(nameof(CopilotClient))
79+
: _rpc ?? throw new InvalidOperationException("Client is not started. Call StartAsync first.");
7780

7881
/// <summary>
7982
/// Creates a new instance of <see cref="CopilotClient"/>.
@@ -300,7 +303,8 @@ private async Task CleanupConnectionAsync(List<Exception>? errors)
300303
try { ctx.Rpc.Dispose(); }
301304
catch (Exception ex) { errors?.Add(ex); }
302305

303-
// Clear models cache
306+
// Clear RPC and models cache
307+
_rpc = null;
304308
_modelsCache = null;
305309

306310
if (ctx.NetworkStream is not null)

dotnet/src/Generated/Rpc.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
// AUTO-GENERATED FILE - DO NOT EDIT
66
// Generated from: api.schema.json
77

8-
using System.Diagnostics.CodeAnalysis;
98
using System.Text.Json.Serialization;
109
using StreamJsonRpc;
1110

dotnet/src/Session.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
using Microsoft.Extensions.AI;
66
using StreamJsonRpc;
7-
using System.Diagnostics.CodeAnalysis;
87
using System.Text.Json;
98
using System.Text.Json.Nodes;
109
using System.Text.Json.Serialization;

go/client.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ type Client struct {
8686
typedLifecycleHandlers map[SessionLifecycleEventType][]SessionLifecycleHandler
8787
lifecycleHandlersMux sync.Mutex
8888

89-
// Rpc provides typed server-scoped RPC methods.
89+
// RPC provides typed server-scoped RPC methods.
9090
// This field is nil until the client is connected via Start().
91-
Rpc *rpc.ServerRpc
91+
RPC *rpc.ServerRpc
9292
}
9393

9494
// NewClient creates a new Copilot CLI client with the given options.
@@ -342,6 +342,7 @@ func (c *Client) Stop() error {
342342
c.actualPort = 0
343343
}
344344

345+
c.RPC = nil
345346
return errors.Join(errs...)
346347
}
347348

@@ -400,6 +401,8 @@ func (c *Client) ForceStop() {
400401
if !c.isExternalServer {
401402
c.actualPort = 0
402403
}
404+
405+
c.RPC = nil
403406
}
404407

405408
func (c *Client) ensureConnected() error {
@@ -1086,7 +1089,7 @@ func (c *Client) startCLIServer(ctx context.Context) error {
10861089

10871090
// Create JSON-RPC client immediately
10881091
c.client = jsonrpc2.NewClient(stdin, stdout)
1089-
c.Rpc = rpc.NewServerRpc(c.client)
1092+
c.RPC = rpc.NewServerRpc(c.client)
10901093
c.setupNotificationHandler()
10911094
c.client.Start()
10921095

@@ -1159,7 +1162,7 @@ func (c *Client) connectViaTcp(ctx context.Context) error {
11591162

11601163
// Create JSON-RPC client with the connection
11611164
c.client = jsonrpc2.NewClient(conn, conn)
1162-
c.Rpc = rpc.NewServerRpc(c.client)
1165+
c.RPC = rpc.NewServerRpc(c.client)
11631166
c.setupNotificationHandler()
11641167
c.client.Start()
11651168

go/session.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ type Session struct {
6565
hooks *SessionHooks
6666
hooksMux sync.RWMutex
6767

68-
// Rpc provides typed session-scoped RPC methods.
69-
Rpc *rpc.SessionRpc
68+
// RPC provides typed session-scoped RPC methods.
69+
RPC *rpc.SessionRpc
7070
}
7171

7272
// WorkspacePath returns the path to the session workspace directory when infinite
@@ -84,7 +84,7 @@ func newSession(sessionID string, client *jsonrpc2.Client, workspacePath string)
8484
client: client,
8585
handlers: make([]sessionHandler, 0),
8686
toolHandlers: make(map[string]ToolHandler),
87-
Rpc: rpc.NewSessionRpc(client, sessionID),
87+
RPC: rpc.NewSessionRpc(client, sessionID),
8888
}
8989
}
9090

nodejs/src/client.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ export class CopilotClient {
358358
);
359359
}
360360
this.connection = null;
361+
this._rpc = null;
361362
}
362363

363364
// Clear models cache
@@ -435,6 +436,7 @@ export class CopilotClient {
435436
// Ignore errors during force stop
436437
}
437438
this.connection = null;
439+
this._rpc = null;
438440
}
439441

440442
// Clear models cache

python/copilot/client.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ async def stop(self) -> list["StopError"]:
334334
if self._client:
335335
await self._client.stop()
336336
self._client = None
337+
self._rpc = None
337338

338339
# Clear models cache
339340
async with self._models_cache_lock:
@@ -382,6 +383,7 @@ async def force_stop(self) -> None:
382383
except Exception:
383384
pass # Ignore errors during force stop
384385
self._client = None
386+
self._rpc = None
385387

386388
# Clear models cache
387389
async with self._models_cache_lock:

scripts/codegen/csharp.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,6 @@ function generateRpcCode(schema: ApiSchema): string {
712712
// AUTO-GENERATED FILE - DO NOT EDIT
713713
// Generated from: api.schema.json
714714
715-
using System.Diagnostics.CodeAnalysis;
716715
using System.Text.Json.Serialization;
717716
using StreamJsonRpc;
718717

scripts/codegen/go.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ function emitMethod(lines: string[], receiver: string, name: string, method: Rpc
267267
}
268268
lines.push(` raw, err := a.client.Request("${method.rpcMethod}", req)`);
269269
} else {
270-
const arg = hasParams ? "params" : "nil";
270+
const arg = hasParams ? "params" : "map[string]interface{}{}";
271271
lines.push(` raw, err := a.client.Request("${method.rpcMethod}", ${arg})`);
272272
}
273273

scripts/codegen/python.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -251,30 +251,30 @@ function emitMethod(lines: string[], name: string, method: RpcMethod, isSession:
251251
const paramProps = method.params?.properties || {};
252252
const nonSessionParams = Object.keys(paramProps).filter((k) => k !== "sessionId");
253253
const hasParams = isSession ? nonSessionParams.length > 0 : Object.keys(paramProps).length > 0;
254+
const paramsType = toPascalCase(method.rpcMethod) + "Params";
254255

255-
// Build signature
256-
const sigParams = isSession ? nonSessionParams : Object.keys(paramProps);
257-
const paramList = sigParams.map((p) => `${toSnakeCase(p)}`).join(", ");
256+
// Build signature with typed params
258257
const sig = hasParams
259-
? ` async def ${methodName}(self, ${paramList}) -> ${resultType}:`
258+
? ` async def ${methodName}(self, params: ${paramsType}) -> ${resultType}:`
260259
: ` async def ${methodName}(self) -> ${resultType}:`;
261260

262261
lines.push(sig);
263262

264-
// Build request body
263+
// Build request body with proper serialization/deserialization
265264
if (isSession) {
266265
if (hasParams) {
267-
const paramDict = nonSessionParams.map((p) => `"${p}": ${toSnakeCase(p)}`).join(", ");
268-
lines.push(` return await self._client.request("${method.rpcMethod}", {"sessionId": self._session_id, ${paramDict}})`);
266+
lines.push(` params_dict = {k: v for k, v in params.to_dict().items() if v is not None}`);
267+
lines.push(` params_dict["sessionId"] = self._session_id`);
268+
lines.push(` return ${resultType}.from_dict(await self._client.request("${method.rpcMethod}", params_dict))`);
269269
} else {
270-
lines.push(` return await self._client.request("${method.rpcMethod}", {"sessionId": self._session_id})`);
270+
lines.push(` return ${resultType}.from_dict(await self._client.request("${method.rpcMethod}", {"sessionId": self._session_id}))`);
271271
}
272272
} else {
273273
if (hasParams) {
274-
const paramDict = Object.keys(paramProps).map((p) => `"${p}": ${toSnakeCase(p)}`).join(", ");
275-
lines.push(` return await self._client.request("${method.rpcMethod}", {${paramDict}})`);
274+
lines.push(` params_dict = {k: v for k, v in params.to_dict().items() if v is not None}`);
275+
lines.push(` return ${resultType}.from_dict(await self._client.request("${method.rpcMethod}", params_dict))`);
276276
} else {
277-
lines.push(` return await self._client.request("${method.rpcMethod}", {})`);
277+
lines.push(` return ${resultType}.from_dict(await self._client.request("${method.rpcMethod}", {}))`);
278278
}
279279
}
280280
lines.push(``);

0 commit comments

Comments
 (0)