Add Go SDK and generator#56
Conversation
Change-Id: Ic3a8ca18551872870ebc922dcdce7ec1669c9fd6 Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I17041dcb362750bad7e95ab5c84ab707dfaec85f Signed-off-by: Thomas Kosiewski <tk@coder.com>
…nal methods Change-Id: I4d1ebe3b6f5b53a52e1ec9c13e4028b4d05a6b5e Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I6f5b08f6e93cd8fc5b904ab91014c206647a4aca Signed-off-by: Thomas Kosiewski <tk@coder.com>
…and add Claude Code example Change-Id: I7ee9a6217c3c33ef27e5143acf8e2f9e17ded3dc Signed-off-by: Thomas Kosiewski <tk@coder.com>
…h handlers Change-Id: Ie1670abd513fab42dedaa2c9e55362840f2f9985 Signed-off-by: Thomas Kosiewski <tk@coder.com>
…ntation Change-Id: I337b07eea029a16481cf41869f9a327f9184c5fa Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Idbc02da87f6925b2fd847ffe1a04fcdda33b2162 Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: If82530aca4ae621a6d8200cebbdd50e144f57f24 Signed-off-by: Thomas Kosiewski <tk@coder.com>
…ancellation Change-Id: Ic242f8ab12e3760e7ef67b70385f8db1cf5a0262 Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I2bdd3b643953b5ef1856e73285087d7976a130ec Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Iaf75a10da7807d196dde16ec744c72182d767dd2 Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Iad1f284ea06288dd72e8eab3b6c429ea88113fee Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Idf60f2e210f012cb035aa4de5680a1fbcf84d4c5 Signed-off-by: Thomas Kosiewski <tk@coder.com>
…alidation Change-Id: I9363d69a0842e656ecbfeeba19f379206407d924 Signed-off-by: Thomas Kosiewski <tk@coder.com>
…d JSON marshaling Change-Id: Ia6003b4adb006cce9db9e6ab9b0a17294bfcfa44 Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I410e8a8452949641864ca4e2e876ff2df6d71eee Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
We require contributors to sign our Contributor License Agreement, and we don't have @ThomasK33 on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'. |
|
@cla-bot check |
|
The cla-bot has been summoned, and re-checked this pull request! |
Change-Id: I07e46aa00b16f50b44e8e56b614c125cbf8bcb47 Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
Thanks for this, it looks great! One thing I noticed is that if you run the rust example client with the go example agent, it crashes because it returns |
|
Thank you very much for this I tried to use this to integrate crush in Zed editor (ref: https://github.com/deepakdinesh1123/crush/blob/feat/acp/internal/acpagent/acp.go), as soon as I launch a new thread with crush agent in Zed I get the error |
|
@deepakdinesh1123 Does it work if you set AuthMethods to the empty array? |
|
@ConradIrwin the typ type AuthenticateResponse struct{}and the method authenticate method signature is func (a *ACPAgent) Authenticate(ctx context.Context, _ acp.AuthenticateRequest) error { return nil }so I was not able to return any response other than the error as nil |
|
I think the problem is the type InitializeResponse struct {
AgentCapabilities AgentCapabilities `json:"agentCapabilities,omitempty"`
AuthMethods []AuthMethod `json:"authMethods"` <--- THIS ONE
ProtocolVersion ProtocolVersion `json:"protocolVersion"`
} |
|
Hey @ConradIrwin, you're right. Let me look into extending the codegen to either serialize to the default values specified in the Updating the func (a *exampleAgent) Initialize(ctx context.Context, params acp.InitializeRequest) (acp.InitializeResponse, error) {
return acp.InitializeResponse{
ProtocolVersion: acp.ProtocolVersionNumber,
AgentCapabilities: acp.AgentCapabilities{
LoadSession: false,
},
AuthMethods: []acp.AuthMethod{},
}, nil
}seems to fix the issue as you suggested. |
|
👍 Also happy to make changes to how the schema is generated if there's a way we can express "undefined is fine, but null causes rust's |
…o module restructure Change-Id: Ic03480847e6d562067e0b170eb72fe6ea39efc20 Signed-off-by: Thomas Kosiewski <tk@coder.com>
… and reduced code duplication Change-Id: I808b16216e09a94eca58cd8e95c99b3bb927596f Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: If54609a9f26d3faef80d821b6d80fcd9696a4f62 Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I5db6760df4ae4f89ebacc3f1cc83f15d95afd0b9 Signed-off-by: Thomas Kosiewski <tk@coder.com>
Since most of this is generated code, it's fine for now. The generator can handle serialization and deserialization of default values, working around Go's default value serialization issues. Also, I added a Nix flake to set up a dev shell with all the necessary packages to run the npm scripts. Let me know if you’d prefer to remove it—I'm OK with that. |
|
Having a nix flake seems fine (assuming I don't have to use it :D). Do the latest set of changes fix the serialization thing? Is there anything else you wanted to tidy up before merging this? |
|
I am getting this error when I try to build a version of crush that is using this module invalid receiver type SetSessionModeResponse (pointer or interface type) (compiler InvalidRecv)due to this in type SetSessionModeResponse any
func (v *SetSessionModeResponse) Validate() error {
return nil
} |
Change-Id: I8b0d3562a5abd7f61416eb4efd8f6b52c0c3f3c8 Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I6c29fa534f61d9571b61c95f6fc13a791700f9f1 Signed-off-by: Thomas Kosiewski <tk@coder.com>
… KillTerminalCommand Change-Id: Ie34241477e4f04a55a57dd04639c68f9b2b6fcc3 Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@ThomasK33 let us know if we can help get this over the line! |
Change-Id: I190a4c47db0efdc54acae7e0ceceb711c85ade02 Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I702ad8086d4da8253e8caca8d11ec8346e690bff Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Ifb2d5b0a40cd17c0b014431d15852606700ea001 Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I76bfcaaf9522c224c2d846535a11a2d99323d05c Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I2505cb5e1175520c06d933455f995aa93bd11f58 Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I1b5054a0dcfbde8002ba67d42f1f19a786d48a6f Signed-off-by: Thomas Kosiewski <tk@coder.com>
Hey @morgankrey, sorry, I somehow did not see the ping. @deepakdinesh1123 I also tested it against your crush fork with the acp subcommand. Inline Patch on `feat/acp`diff --git a/internal/acpagent/acp.go b/internal/acpagent/acp.go
index e20a351d..c4c63481 100644
--- a/internal/acpagent/acp.go
+++ b/internal/acpagent/acp.go
@@ -12,6 +12,8 @@ import (
acp "github.com/zed-industries/agent-client-protocol/go"
)
+var _ acp.Agent = (*ACPAgent)(nil)
+
type ACPAgent struct {
app *app.App
conn *acp.AgentSideConnection
@@ -63,9 +65,10 @@ func (a *ACPAgent) Cancel(ctx context.Context, params acp.CancelNotification) er
}
func (a *ACPAgent) Prompt(ctx context.Context, params acp.PromptRequest) (acp.PromptResponse, error) {
- _, err := a.app.Sessions.Get(ctx, string(params.SessionId))
+ sessionID := string(params.SessionId)
+ _, err := a.app.Sessions.Get(ctx, sessionID)
if err != nil {
- return acp.PromptResponse{}, fmt.Errorf("session %s not found", string(params.SessionId))
+ return acp.PromptResponse{}, fmt.Errorf("session %s not found", sessionID)
}
content := ""
@@ -75,7 +78,7 @@ func (a *ACPAgent) Prompt(ctx context.Context, params acp.PromptRequest) (acp.Pr
}
}
- done, err := a.app.CoderAgent.Run(context.Background(), string(params.SessionId), content)
+ done, err := a.app.CoderAgent.Run(ctx, sessionID, content)
if err != nil {
return acp.PromptResponse{}, err
}
@@ -134,6 +137,7 @@ func (a *ACPAgent) Prompt(ctx context.Context, params acp.PromptRequest) (acp.Pr
case message.BinaryContent:
case message.ImageURLContent:
case message.Finish:
+ return acp.PromptResponse{StopReason: acp.StopReasonEndTurn}, nil
case message.TextContent:
// Only send the delta (new text content)
if len(part.Text) > len(lastTextSent) {
@@ -169,7 +173,13 @@ func (a *ACPAgent) Prompt(ctx context.Context, params acp.PromptRequest) (acp.Pr
}
}
}
+}
+func (a *ACPAgent) Authenticate(ctx context.Context, _ acp.AuthenticateRequest) (acp.AuthenticateResponse, error) {
+ return acp.AuthenticateResponse{}, nil
}
-func (a *ACPAgent) Authenticate(ctx context.Context, _ acp.AuthenticateRequest) error { return nil }
+// SetSessionMode implements acp.Agent.
+func (a *ACPAgent) SetSessionMode(ctx context.Context, params acp.SetSessionModeRequest) (acp.SetSessionModeResponse, error) {
+ return acp.SetSessionModeResponse{}, nil
+} |
|
Awesome - @benbrandt @rtfeldman ready for review! |
|
Closing in favor of: https://github.com/coder/acp-go-sdk |
Overview
This PR introduces a Go SDK for ACP, including terminal support, context-aware APIs with cancellation, a modular code generator, structured error handling, JSON parity tests with golden files, and updated docs/examples.
What’s Supported
context.Contextwith cancellation propagation.*_gen.gofor types, constants, helpers, and interfaces.Implementation Notes
Testing
Docs & Examples
Change-Id: Ic3a8ca18551872870ebc922dcdce7ec1669c9fd6
Signed-off-by: Thomas Kosiewski tk@coder.com