Skip to content

1.0.8 breaks typing on events #2078

Description

@Stono

Summary

@github/copilot-sdk@1.0.8 generates a SessionEvent union that references AssistantTurnRetryEvent and ModelCallStartEvent, but neither interface is declared.

Because the union contains unresolved type names, TypeScript resolves SessionEvent to any when declaration checking is skipped. This propagates to SessionEventType, SessionEventPayload, and every callback registered through CopilotSession.on().

Expected Behavior

The generated declarations should compile without missing-type errors. SessionEventPayload<'skill.invoked'> and every other event payload should preserve its declared structure, and session.on() callbacks should receive typed events.

Actual Behavior

The SDK declarations produce these errors when skipLibCheck is disabled:

dist/generated/session-events.d.ts: Cannot find name 'AssistantTurnRetryEvent'.
dist/generated/session-events.d.ts: Cannot find name 'ModelCallStartEvent'.

With skipLibCheck enabled, TypeScript silently resolves SessionEvent to any. For example, the following invalid access compiles:

const event: SessionEventPayload<'skill.invoked'> = null as never
event.notARealProperty
const invalid: number = event.data.name

This affects skill events as well as all other session events. In particular, an unannotated skill callback parameter is reported as implicit any:

error TS7006: Parameter 'skill' implicitly has an 'any' type.

Steps to Reproduce

  1. Install @github/copilot-sdk@1.0.8.
  2. Run TypeScript with skipLibCheck: false.
  3. Observe the two missing generated event types listed above.
  4. Alternatively, enable skipLibCheck and compile code that consumes a session event:
session.on('skill.invoked', (event) => {
  const invalid: number = event.data.name
  event.notARealProperty
})
  1. TypeScript accepts the invalid assignment and property access because event is any.

Environment

  • OS: macOS
  • Node version: 24.17.0
  • @github/copilot-sdk version: 1.0.8
  • TypeScript: repository build invoked via bun at build

Evidence

The SDK derives callback payloads from SessionEvent:

export type SessionEventType = SessionEvent['type']

export type SessionEventPayload<T extends SessionEventType> = Extract<
  SessionEvent,
  { type: T }
>

export type TypedSessionEventHandler<T extends SessionEventType> = (
  event: SessionEventPayload<T>
) => void

The generated SessionEvent union references AssistantTurnRetryEvent and ModelCallStartEvent, but neither is present in dist/generated/session-events.d.ts.

Workaround

Consumers can explicitly annotate event values with individual exported event interfaces where needed:

session.on('skill.invoked', (event: SkillInvokedEvent) => {
  const skillName = event.data.name
})

This restores type checking locally but should not be required once SessionEvent is valid.

Suggested Fix

Update the event-union generator so every referenced event interface is emitted. In particular, either emit AssistantTurnRetryEvent and ModelCallStartEvent, or remove them from SessionEvent until they are defined.

export type SessionEvent =
  | /* existing event types */
  | AssistantTurnRetryEvent
  | ModelCallStartEvent

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions