Skip to content

Conversation

@baywet
Copy link
Member

@baywet baywet commented Oct 27, 2025

  • feat: adds new discriminator default mapping field
  • feat: add new OAS version in emitter options fix: default version for OAS emitter do not match valid values
  • docs: adds the chronus entry for OAI 3.2.0 support
  • feat: adds support for $self property in oai 3.2.0
  • feat: adds support for server name in OAS 3.2.0
  • feat: adds support for media type components in 3.2 feat: adds support for item/prefix encoding and encoding fields for media type and encoding in 3.2.0

baywet and others added 23 commits October 10, 2025 13:51
Signed-off-by: Vincent Biret <vincentbiret@hotmail.com>
Signed-off-by: Vincent Biret <vincentbiret@hotmail.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
fix: default version for OAS emitter do not match valid values

Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
feat: adds support for item/prefix encoding and encoding fields for media type and encoding in 3.2.0

Signed-off-by: Vincent Biret <vibiret@microsoft.com>
@baywet baywet self-assigned this Oct 27, 2025
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Base automatically changed from chore/parser-migration to main October 28, 2025 12:53
@github-actions
Copy link
Contributor

github-actions bot commented Oct 28, 2025

All changed packages have been documented.

  • @typespec/openapi3
Show changes

@typespec/openapi3 - feature ✏️

added support for OpenAPI 3.2.0 emission

Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
@baywet baywet marked this pull request as ready for review October 29, 2025 17:52
@baywet baywet enabled auto-merge October 29, 2025 17:52
@baywet baywet force-pushed the feat/oai-3-2-emission branch from cbf2f37 to 217c869 Compare October 30, 2025 13:00
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
@baywet baywet requested a review from timotheeguerin October 30, 2025 17:44
@baywet baywet added this pull request to the merge queue Oct 30, 2025
Merged via the queue into main with commit 2993f7d Oct 30, 2025
26 checks passed
@baywet baywet deleted the feat/oai-3-2-emission branch October 30, 2025 18:47
github-merge-queue bot pushed a commit that referenced this pull request Nov 7, 2025
## Implementation Plan for Stream Support in OpenAPI 3.2

This PR implements support for streaming responses (including
Server-Sent Events) in OpenAPI 3.2 emission and import using the
`itemSchema` field.

### Checklist

- [x] 1. Add `itemSchema` support to OpenAPI 3.2 MediaType definition in
types.ts
- [x] 2. Create an SSE module (sse-module.ts) following the
xml-module.ts pattern
- [x] 3. Integrate SSE module into the OpenAPI emitter for emission
support
- [x] 4. Add package dependencies for @typespec/streams,
@typespec/events, @typespec/sse
- [x] 5. Use getStreamMetadata from @typespec/http/experimental to
detect streams
- [x] 6. Remove debug console.log statements
- [x] 7. Tests passing for SSE emission
- [x] 8. Handle @events decorator to emit proper SSE event structures
- [x] 9. Handle @ContentType decorator on union variants
- [x] 10. Handle @terminalevent decorator (preserve with @extension)
- [x] 11. Run formatter and linter
- [x] 12. Add changelog entry with chronus
- [x] 13. Generalize stream support for all content types

### Changes Made

**Type Definitions:**
- Added `itemSchema` property to `OpenAPIMediaType3_2` for streaming
event schema definitions

**SSE Module (`sse-module.ts`):**
- Created stream detection and emission logic following `xml-module.ts`
pattern
- Implements stream detection via `@typespec/streams.getStreamOf`
- Generates `itemSchema` with `oneOf` variants for `@events` union
members
- Works with any stream content type (SSE, JSON Lines, etc.)

**OpenAPI Emitter Integration:**
- Integrated SSE module as optional dependency alongside XML/JSON Schema
- Modified `getBodyContentEntry` to detect all stream responses via
`getStreamMetadata`
- Routes stream responses through emission path for OpenAPI 3.2 with
`itemSchema`
- Generalized to support any `HttpStream<ContentType, Type>`, not just
SSE streams

**Testing:**
- All stream tests passing
- Simplified test structure by removing namespaces and extra decorators
- Used ApiTester base for common libraries with stream-specific imports
on top

**Diagnostics:**
- Added "streams-not-supported" diagnostic for OpenAPI 3.0/3.1
- Warning message indicates streams with itemSchema require OpenAPI
3.2.0

### Stream Support

This implementation supports any stream type in OpenAPI 3.2.0:
- Server-Sent Events (SSE) with `text/event-stream`
- JSON Lines with `application/jsonl`
- Any custom `HttpStream<ContentType, Type>`

For OpenAPI 3.0/3.1, streams are emitted without `itemSchema` and a
warning is generated.

- Fixes #8887

<!-- START COPILOT CODING AGENT SUFFIX -->



<details>

<summary>Original prompt</summary>


----

*This section details on the original issue you should resolve*

<issue_title>[Feat] OpenAPI - add support for SSE import and
emission</issue_title>
<issue_description>### Clear and concise description of the problem

Now that we have support for OpenAPI 3.2.0 (#8828 ) both in emissions
and in importing descriptions to TypeSpec, it'd be nice to have support
for importing SSE (server-sent events).
@timotheeguerin and I spent the better part of an hour combing through
multiple specifications to understand what needs to happen here, so
strap in, this is going to be a long issue.

## Relevant resources

- #154 as the initial specification for sse in
typespec
- https://github.com/OAI/OpenAPI-Specification/discussions/5096 ongoing
discussion about terminal events
-
https://github.com/Azure/azure-sdk-for-python/blob/894d166350f0ccbe2fae467e4093ed0c3b428213/sdk/ai/azure-ai-agents/azure/ai/agents/operations/_patch.py#L564
manual implementation of SSE for Azure AI Foundry: Agents threads run
API
-
https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/ai/azure-ai-agents/tests/assets/send_email_stream_response.txt
an example of the payloads sent by this API
- [WHATWG specification for
SSE](https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events)
- [OAI 3.2.0 example on how to describe
SSE](https://spec.openapis.org/oas/v3.2.0.html#server-sent-event-streams)
- [OpenAI terminal event
description](https://platform.openai.com/docs/api-reference/runs/createRun#runs_createrun-stream)
- [OpenAI streaming responses
documentation](https://platform.openai.com/docs/guides/streaming-responses?api-mode=responses)
- [Blog post about using SSE APIs with
OpenAI](https://medium.com/better-programming/openai-sse-sever-side-events-streaming-api-733b8ec32897)
- [TypeSpec very sparse documentation for
SSE](https://typespec.io/docs/libraries/sse/reference/)


## Import

### Scenario 1 : no terminal event

Given the following OpenAPI Response object.

```yaml
content:
  description: A request body to add a stream of typed data.
  required: true
  content:
    text/event-stream:
      itemSchema:
        type: object
        properties:
          event:
            type: string
          data:
            type: string
        required: [event]
        # Define event types and specific schemas for the corresponding data
        oneOf:
          - properties:
              event:
                const: userconnect
              data:
                contentMediaType: application/json
                contentSchema:
                  type: object
                  required: [username]
                  properties:
                    username:
                      type: string
          - properties:
              event:
                const: usermessage
              data:
                contentMediaType: application/json
                contentSchema:
                  type: object
                  required: [text]
                  properties:
                    text:
                      type: string
```


I'd expect aresulting TypeSpec description looking like this.

```tsp
import "@typespec/streams";
import "@typespec/sse";
import "@typespec/events";

using SSE;

model UserConnect {
  username: string;
}
model UserMessage {
  text: string;
}

@TypeSpec.Events.events
union ChannelEvents {
  userconnect: UserConnect,
  usermessage: UserMessage,
}
op subscribeToChannel(): SSEStream<ChannelEvents>;
```

Note that the terminal event is NOT present, this is ok because it's an
invention of some APIs, and is not part of the WHATWG spec. It should
remain optional.

Here a couple of things are worth noting:
- imports for typespec streams/sse/events are added
- a using for SSE is added
- a `@TypeSpec.Events.events` decorator is added to the union type
- the return type of the operation is now `SSEStream<ChannelEvents>`
(instead of ChannelEvents)
- The union type discriminator values are obtained by conventions based
on the event properties in the schema (name is a convention)
- the union type member types are defined by convention by the schema of
the data property, and the fact the content media type is
application/json

### Scenario 2: with terminal events

Given the following OpenAPI Response object.

```yaml
content:
  description: A request body to add a stream of typed data.
  required: true
  content:
    text/event-stream:
      itemSchema:
        type: object
        properties:
          event:
            type: string
          data:
            type: string
        required: [event]
        # Define event types and specific schemas for the corresponding data
        oneOf:
          - properties:
              data:
                contentMediaType: text/plain
                const: "[done]"
                "x-ms-sse-terminal-event": true
          - properties:
              event:
                const: userconnect
              data:
                contentMediaType: app...

</details>

- Fixes #8887

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: baywet <7905502+baywet@users.noreply.github.com>
Co-authored-by: Vincent Biret <vibiret@microsoft.com>
Co-authored-by: Timothee Guerin <tiguerin@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants