Skip to content

Commit 3dd7b01

Browse files
SDK: Align canvas with codegen pipeline, add e2e tests (#1413)
1 parent ac6de48 commit 3dd7b01

47 files changed

Lines changed: 3551 additions & 1774 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

dotnet/src/Canvas.cs

Lines changed: 8 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -55,110 +55,6 @@ public sealed class ExtensionInfo
5555
public string Name { get; set; } = string.Empty;
5656
}
5757

58-
/// <summary>Response returned from <see cref="ICanvasHandler.OnOpenAsync"/>.</summary>
59-
[Experimental(Diagnostics.Experimental)]
60-
public sealed class CanvasOpenResponse
61-
{
62-
/// <summary>URL the host should render. Optional for canvases with no visual surface.</summary>
63-
[JsonPropertyName("url")]
64-
public string? Url { get; set; }
65-
66-
/// <summary>Provider-supplied title shown in host chrome.</summary>
67-
[JsonPropertyName("title")]
68-
public string? Title { get; set; }
69-
70-
/// <summary>Provider-supplied status text shown in host chrome.</summary>
71-
[JsonPropertyName("status")]
72-
public string? Status { get; set; }
73-
}
74-
75-
/// <summary>Host capabilities passed to canvas provider callbacks.</summary>
76-
[Experimental(Diagnostics.Experimental)]
77-
public sealed class CanvasHostContext
78-
{
79-
/// <summary>Host capability details.</summary>
80-
[JsonPropertyName("capabilities")]
81-
public CanvasHostCapabilities Capabilities { get; set; } = new();
82-
}
83-
84-
/// <summary>Host capability details passed to canvas provider callbacks.</summary>
85-
[Experimental(Diagnostics.Experimental)]
86-
public sealed class CanvasHostCapabilities
87-
{
88-
/// <summary>Whether the host supports canvas rendering.</summary>
89-
[JsonPropertyName("canvases")]
90-
public bool Canvases { get; set; }
91-
}
92-
93-
/// <summary>Context handed to <see cref="ICanvasHandler.OnOpenAsync"/>.</summary>
94-
[Experimental(Diagnostics.Experimental)]
95-
public sealed class CanvasOpenContext
96-
{
97-
/// <summary>Session that requested the canvas.</summary>
98-
public string SessionId { get; init; } = string.Empty;
99-
100-
/// <summary>Owning provider identifier.</summary>
101-
public string ExtensionId { get; init; } = string.Empty;
102-
103-
/// <summary>Canvas id from the declaring <see cref="CanvasDeclaration"/>.</summary>
104-
public string CanvasId { get; init; } = string.Empty;
105-
106-
/// <summary>Stable instance id supplied by the runtime.</summary>
107-
public string InstanceId { get; init; } = string.Empty;
108-
109-
/// <summary>Validated input payload.</summary>
110-
public JsonElement Input { get; init; }
111-
112-
/// <summary>Host capabilities supplied by the runtime.</summary>
113-
public CanvasHostContext? Host { get; init; }
114-
}
115-
116-
/// <summary>Context handed to <see cref="ICanvasHandler.OnActionAsync"/>.</summary>
117-
[Experimental(Diagnostics.Experimental)]
118-
public sealed class CanvasActionContext
119-
{
120-
/// <summary>Session that invoked the action.</summary>
121-
public string SessionId { get; init; } = string.Empty;
122-
123-
/// <summary>Owning provider identifier.</summary>
124-
public string ExtensionId { get; init; } = string.Empty;
125-
126-
/// <summary>Canvas id targeted by the action.</summary>
127-
public string CanvasId { get; init; } = string.Empty;
128-
129-
/// <summary>Instance id targeted by the action.</summary>
130-
public string InstanceId { get; init; } = string.Empty;
131-
132-
/// <summary>Action name from <see cref="CanvasAction.Name"/>.</summary>
133-
public string ActionName { get; init; } = string.Empty;
134-
135-
/// <summary>Validated input payload.</summary>
136-
public JsonElement Input { get; init; }
137-
138-
/// <summary>Host capabilities supplied by the runtime.</summary>
139-
public CanvasHostContext? Host { get; init; }
140-
}
141-
142-
/// <summary>Context handed to a canvas's close lifecycle hook.</summary>
143-
[Experimental(Diagnostics.Experimental)]
144-
public sealed class CanvasLifecycleContext
145-
{
146-
/// <summary>Session owning the canvas instance.</summary>
147-
public string SessionId { get; init; } = string.Empty;
148-
149-
/// <summary>Owning provider identifier.</summary>
150-
public string ExtensionId { get; init; } = string.Empty;
151-
152-
/// <summary>Canvas id from the declaring <see cref="CanvasDeclaration"/>.</summary>
153-
public string CanvasId { get; init; } = string.Empty;
154-
155-
/// <summary>Instance id this lifecycle event applies to.</summary>
156-
public string InstanceId { get; init; } = string.Empty;
157-
158-
/// <summary>Host capabilities supplied by the runtime.</summary>
159-
public CanvasHostContext? Host { get; init; }
160-
}
161-
16258
/// <summary>Structured error returned from canvas handlers.</summary>
16359
/// <remarks>
16460
/// Throw this from <see cref="ICanvasHandler"/> implementations to surface a
@@ -234,9 +130,9 @@ internal partial class CanvasJsonContext : JsonSerializerContext;
234130
/// <remarks>
235131
/// A session installs a single <see cref="ICanvasHandler"/> via
236132
/// <c>SessionConfigBase.CanvasHandler</c>. The handler receives every
237-
/// inbound <c>canvas.open</c> / <c>canvas.close</c> / <c>canvas.action.invoke</c>
133+
/// inbound <c>canvas.open</c> / <c>canvas.close</c> / <c>canvas.invokeAction</c>
238134
/// JSON-RPC request the runtime issues for this session and decides — typically
239-
/// by inspecting <see cref="CanvasOpenContext.CanvasId"/> — which
135+
/// by inspecting <see cref="CanvasProviderOpenRequest.CanvasId"/> — which
240136
/// application-side canvas should handle the call.
241137
/// <para>
242138
/// The SDK does not maintain a per-canvas registry; multiplexing across
@@ -252,16 +148,16 @@ internal partial class CanvasJsonContext : JsonSerializerContext;
252148
public interface ICanvasHandler
253149
{
254150
/// <summary>Open a new canvas instance.</summary>
255-
Task<CanvasOpenResponse> OnOpenAsync(CanvasOpenContext context, CancellationToken cancellationToken);
151+
Task<CanvasProviderOpenResult> OnOpenAsync(CanvasProviderOpenRequest context, CancellationToken cancellationToken);
256152

257153
/// <summary>Canvas was closed by the user or agent. Default: no-op.</summary>
258-
Task OnCloseAsync(CanvasLifecycleContext context, CancellationToken cancellationToken);
154+
Task OnCloseAsync(CanvasProviderCloseRequest context, CancellationToken cancellationToken);
259155

260156
/// <summary>
261157
/// Handle a non-lifecycle action declared by the canvas.
262158
/// Default: throws <see cref="CanvasError.NoHandler"/>.
263159
/// </summary>
264-
Task<object?> OnActionAsync(CanvasActionContext context, CancellationToken cancellationToken);
160+
Task<object?> OnActionAsync(CanvasProviderInvokeActionRequest context, CancellationToken cancellationToken);
265161
}
266162

267163
/// <summary>
@@ -272,17 +168,17 @@ public interface ICanvasHandler
272168
public abstract class CanvasHandlerBase : ICanvasHandler
273169
{
274170
/// <inheritdoc />
275-
public abstract Task<CanvasOpenResponse> OnOpenAsync(CanvasOpenContext context, CancellationToken cancellationToken);
171+
public abstract Task<CanvasProviderOpenResult> OnOpenAsync(CanvasProviderOpenRequest context, CancellationToken cancellationToken);
276172

277173
/// <inheritdoc />
278-
public virtual Task OnCloseAsync(CanvasLifecycleContext context, CancellationToken cancellationToken)
174+
public virtual Task OnCloseAsync(CanvasProviderCloseRequest context, CancellationToken cancellationToken)
279175
#if NET8_0_OR_GREATER
280176
=> Task.CompletedTask;
281177
#else
282178
=> Task.FromResult<object?>(null);
283179
#endif
284180

285181
/// <inheritdoc />
286-
public virtual Task<object?> OnActionAsync(CanvasActionContext context, CancellationToken cancellationToken)
182+
public virtual Task<object?> OnActionAsync(CanvasProviderInvokeActionRequest context, CancellationToken cancellationToken)
287183
=> Task.FromException<object?>(CanvasError.NoHandler());
288184
}

dotnet/src/Client.cs

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,9 +1625,6 @@ private async Task<Connection> ConnectToServerAsync(Process? cliProcess, string?
16251625
rpc.SetLocalRpcMethod("autoModeSwitch.request", handler.OnAutoModeSwitchRequest);
16261626
rpc.SetLocalRpcMethod("hooks.invoke", handler.OnHooksInvoke);
16271627
rpc.SetLocalRpcMethod("systemMessage.transform", handler.OnSystemMessageTransform);
1628-
rpc.SetLocalRpcMethod("canvas.open", handler.OnCanvasOpen);
1629-
rpc.SetLocalRpcMethod("canvas.close", handler.OnCanvasClose);
1630-
rpc.SetLocalRpcMethod("canvas.action.invoke", handler.OnCanvasInvokeAction);
16311628
ClientSessionApiRegistration.RegisterClientSessionApiHandlers(rpc, sessionId =>
16321629
{
16331630
var session = GetSession(sessionId) ?? throw new ArgumentException($"Unknown session {sessionId}");
@@ -1821,46 +1818,6 @@ public async ValueTask<SystemMessageTransformRpcResponse> OnSystemMessageTransfo
18211818
return await session.HandleSystemMessageTransformAsync(sections);
18221819
}
18231820

1824-
#pragma warning disable GHCP001
1825-
public ValueTask<CanvasOpenResponse> OnCanvasOpen(
1826-
string sessionId,
1827-
string extensionId,
1828-
string canvasId,
1829-
string instanceId,
1830-
JsonElement? input = null,
1831-
CanvasHostContext? host = null)
1832-
{
1833-
var session = client.GetSession(sessionId) ?? throw new ArgumentException($"Unknown session {sessionId}");
1834-
return session.HandleCanvasOpenAsync(
1835-
extensionId, canvasId, instanceId, input ?? default, host);
1836-
}
1837-
1838-
public async ValueTask OnCanvasClose(
1839-
string sessionId,
1840-
string extensionId,
1841-
string canvasId,
1842-
string instanceId,
1843-
JsonElement? input = null,
1844-
CanvasHostContext? host = null)
1845-
{
1846-
var session = client.GetSession(sessionId) ?? throw new ArgumentException($"Unknown session {sessionId}");
1847-
await session.HandleCanvasCloseAsync(extensionId, canvasId, instanceId, host);
1848-
}
1849-
1850-
public ValueTask<JsonElement> OnCanvasInvokeAction(
1851-
string sessionId,
1852-
string extensionId,
1853-
string canvasId,
1854-
string instanceId,
1855-
string actionName,
1856-
JsonElement? input = null,
1857-
CanvasHostContext? host = null)
1858-
{
1859-
var session = client.GetSession(sessionId) ?? throw new ArgumentException($"Unknown session {sessionId}");
1860-
return session.HandleCanvasActionAsync(
1861-
extensionId, canvasId, instanceId, actionName, input ?? default, host);
1862-
}
1863-
#pragma warning restore GHCP001
18641821
}
18651822

18661823
private class Connection(

0 commit comments

Comments
 (0)