Skip to content

Commit 0555520

Browse files
committed
Go codegen: per-event-type data structs (fixes #1031)
Replace the flat quicktype-generated Data union struct with per-event-type data structs, matching the C# codegen approach. Adding a new session event type can no longer change the struct shape of existing event types. - Replace generateSessionEvents() in scripts/codegen/go.ts with custom codegen that produces 74 per-event data structs, a SessionEventData interface, and custom UnmarshalJSON/MarshalJSON on SessionEvent - Update go/session.go to use idiomatic Go type switches for event dispatch - Update samples, tests, and doc examples for the new API - Add type/const aliases for PermissionRequest, Attachment, and related types to ease migration - Add .gitattributes eol=lf for generated files to prevent cross-platform line ending diffs - Re-enable the codegen-check CI workflow (remove go/generated_session_events.go revert workaround) - Add ui, uri, mime to Go initialisms for correct field naming
1 parent 6565a3b commit 0555520

21 files changed

Lines changed: 2903 additions & 1843 deletions

.gitattributes

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
1-
.github/workflows/*.lock.yml linguist-generated=true merge=ours
1+
.github/workflows/*.lock.yml linguist-generated=true merge=ours
2+
3+
# Generated files — keep LF line endings so codegen output is deterministic across platforms.
4+
nodejs/src/generated/* eol=lf linguist-generated=true
5+
dotnet/src/Generated/* eol=lf linguist-generated=true
6+
python/copilot/generated/* eol=lf linguist-generated=true
7+
go/generated_session_events.go eol=lf linguist-generated=true
8+
go/rpc/generated_rpc.go eol=lf linguist-generated=true

.github/workflows/codegen-check.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,6 @@ jobs:
4747

4848
- name: Check for uncommitted changes
4949
run: |
50-
# TODO: Remove this when https://github.com/github/copilot-sdk/issues/1031 is fixed
51-
# Exclude go/generated_session_events.go from the check — it was intentionally
52-
# reverted to avoid a breaking DataContent change (see #1031) and will be
53-
# regenerated once that issue is resolved.
54-
git checkout -- go/generated_session_events.go 2>/dev/null || true
5550
if [ -n "$(git status --porcelain)" ]; then
5651
echo "::error::Generated files are out of date. Run 'cd scripts/codegen && npm run generate' and commit the changes."
5752
git diff --stat

go/README.md

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,10 @@ func main() {
5757
// Set up event handler
5858
done := make(chan bool)
5959
session.On(func(event copilot.SessionEvent) {
60-
if event.Type == "assistant.message" {
61-
if event.Data.Content != nil && event.Data.Content.String != nil {
62-
fmt.Println(*event.Data.Content.String)
63-
}
64-
}
65-
if event.Type == "session.idle" {
60+
switch d := event.Data.(type) {
61+
case *copilot.AssistantMessageData:
62+
fmt.Println(d.Content)
63+
case *copilot.SessionIdleData:
6664
close(done)
6765
}
6866
})
@@ -404,30 +402,22 @@ func main() {
404402
done := make(chan bool)
405403

406404
session.On(func(event copilot.SessionEvent) {
407-
if event.Type == "assistant.message_delta" {
405+
switch d := event.Data.(type) {
406+
case *copilot.AssistantMessageDeltaData:
408407
// Streaming message chunk - print incrementally
409-
if event.Data.DeltaContent != nil {
410-
fmt.Print(*event.Data.DeltaContent)
411-
}
412-
} else if event.Type == "assistant.reasoning_delta" {
408+
fmt.Print(d.DeltaContent)
409+
case *copilot.AssistantReasoningDeltaData:
413410
// Streaming reasoning chunk (if model supports reasoning)
414-
if event.Data.DeltaContent != nil {
415-
fmt.Print(*event.Data.DeltaContent)
416-
}
417-
} else if event.Type == "assistant.message" {
411+
fmt.Print(d.DeltaContent)
412+
case *copilot.AssistantMessageData:
418413
// Final message - complete content
419414
fmt.Println("\n--- Final message ---")
420-
if event.Data.Content != nil && event.Data.Content.String != nil {
421-
fmt.Println(*event.Data.Content.String)
422-
}
423-
} else if event.Type == "assistant.reasoning" {
415+
fmt.Println(d.Content)
416+
case *copilot.AssistantReasoningData:
424417
// Final reasoning content (if model supports reasoning)
425418
fmt.Println("--- Reasoning ---")
426-
if event.Data.Content != nil && event.Data.Content.String != nil {
427-
fmt.Println(*event.Data.Content.String)
428-
}
429-
}
430-
if event.Type == "session.idle" {
419+
fmt.Println(d.Content)
420+
case *copilot.SessionIdleData:
431421
close(done)
432422
}
433423
})

go/client.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
// }
2121
//
2222
// session.On(func(event copilot.SessionEvent) {
23-
// if event.Type == "assistant.message" {
24-
// fmt.Println(event.Data.Content)
23+
// if d, ok := event.Data.(*copilot.AssistantMessageData); ok {
24+
// fmt.Println(d.Content)
2525
// }
2626
// })
2727
//

0 commit comments

Comments
 (0)