From c94ea680c19ddc0962534e1eff4f5757f858ee3c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 18 Nov 2025 20:03:57 +0000 Subject: [PATCH 1/9] Initial plan From a9123ec2ce369d213223582e8574cd706b35481e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 18 Nov 2025 20:10:46 +0000 Subject: [PATCH 2/9] Add comprehensive Events documentation to FSD and code generation docs Co-authored-by: ddunkin <264744+ddunkin@users.noreply.github.com> --- define/fsd.md | 126 +++++++++++++++++++++++++++++++++++++++++ generate/csharp.md | 55 ++++++++++++++++++ generate/javascript.md | 52 +++++++++++++++++ 3 files changed, 233 insertions(+) diff --git a/define/fsd.md b/define/fsd.md index e69c1b0..bc24364 100644 --- a/define/fsd.md +++ b/define/fsd.md @@ -148,6 +148,132 @@ The `code` parameter indicates the HTTP status code used if the method is succes } ``` +### Events + +Events are similar to methods but support streaming responses. Instead of returning a single response, an event returns a stream of response chunks over time, enabling server-sent events (SSE) style communication. + +Like methods, each event has a **name**, **request fields**, and **response fields**. Events can also have [attributes](#attributes), a [summary](#summary), and [remarks](#remarks). + +When a client invokes an event, it provides request field values just like a method. However, unlike a method that returns a single response, an event returns a stream where each item is a complete response DTO. The stream can yield multiple responses over time until it completes. + +In C#, events return `Task>>>`, allowing clients to process responses as they arrive using `await foreach`. Other languages provide similar async iterable constructs. + +#### Event FSD + +In an FSD file, the `event` keyword starts the definition of an event. It is followed by the event name and optionally preceded by event attributes. + +The request and response follow the event name, each enclosed in braces and separated by a colon (`:`). The syntax is identical to methods, but the response represents a single chunk of data rather than the entire response. + +```fsd +/// Generates the next message in a chat. +event chatStream +{ + settings: ChatSettings; + messages: ChatMessage[]; +}: +{ + messages: ChatMessage[]; + status: ChatStatus; + usage: ChatUsage; +} +``` + +#### Event HTTP + +The `http` attribute works the same for events as for methods. Events support the `method` and `path` parameters. + +The `method` parameter indicates the HTTP method to use, typically `POST` (the default). The `path` parameter specifies the HTTP path, defaulting to the event name with a leading slash (e.g., `/chatStream`). + +Events always use server-sent events (SSE) for the response, with `Content-Type: text/event-stream`. The HTTP response uses status code `200` and keeps the connection open to stream multiple response DTOs as separate SSE events. + +```fsd +[http(method: POST, path: "/chat/stream")] +event chatStream +{ + settings: ChatSettings; + messages: ChatMessage[]; +}: +{ + messages: ChatMessage[]; + status: ChatStatus; + usage: ChatUsage; +} +``` + +#### Events vs Methods + +**Methods** return a single response (or error) and then complete. They are ideal for traditional request-response operations. + +**Events** return a stream of responses, allowing progressive updates. Each response in the stream is a complete response DTO. Events are ideal for: + +* Long-running operations with progress updates +* Streaming AI/LLM responses where tokens are generated incrementally +* Real-time data feeds that push updates to clients +* Incremental results where partial data is useful before completion + +#### Response Streaming Behavior + +When an event is invoked: + +* The server establishes an HTTP connection with server-sent events (SSE) +* The server yields multiple response chunks over time +* Each chunk is a complete response DTO, serialized and sent as an SSE event +* Clients can process chunks as they arrive, enabling progressive rendering +* The stream completes when the server finishes sending data +* Errors can be returned at any point in the stream using the `ServiceResult` wrapper + +#### Event Example + +Here's a practical example showing how events are used for streaming AI chat responses: + +```fsd +service ChatApi +{ + /// Streams chat response tokens as they're generated. + event streamChat + { + /// The user's prompt + prompt: string; + + /// The model to use (optional) + model: string; + }: + { + /// Text delta to append to response + textDelta: string; + + /// Completion status (sent in final chunk) + status: CompletionStatus; + + /// Token usage statistics (sent in final chunk) + usage: UsageInfo; + } +} + +data UsageInfo +{ + inputTokens: int32; + outputTokens: int32; +} + +enum CompletionStatus +{ + /// Response completed successfully + complete, + + /// Response was truncated + truncated, + + /// An error occurred + error, +} +``` + +In this example, the server would stream multiple responses: +* Initial chunks contain `textDelta` with generated text fragments +* Intermediate chunks may include additional `textDelta` values +* The final chunk includes `status` and `usage` to indicate completion + ### Fields A field stores data for a method request, method response, or data transfer object. diff --git a/generate/csharp.md b/generate/csharp.md index 97566a3..ea67ed9 100644 --- a/generate/csharp.md +++ b/generate/csharp.md @@ -20,3 +20,58 @@ Install `fsdgencsharp` [as documented](/generate/tools#installation) from its [N * `--namespace `: Sets the namespace used by the generated C#. * `--csproj`: Updates any .csproj files in the output directory. Specifically, it adds any missing `.g.cs` files and removes any `.g.cs` files no longer needed. + +## Events + +[Events](/define/fsd#events) in Facility enable streaming responses using server-sent events (SSE). The C# code generator produces special method signatures for events that return streams of responses. + +For an event defined as: + +```fsd +event streamChat +{ + prompt: string; +}: +{ + textDelta: string; +} +``` + +The generated C# interface includes: + +```csharp +Task>>> StreamChatAsync( + StreamChatRequestDto request, + CancellationToken cancellationToken = default); +``` + +### Using Events in C# + +Clients can consume event streams using `await foreach`: + +```csharp +var request = new StreamChatRequestDto { Prompt = "Hello" }; +var result = await client.StreamChatAsync(request); + +if (result.IsFailure) +{ + // Handle error + Console.WriteLine($"Error: {result.Error.Message}"); + return; +} + +await foreach (var chunkResult in result.Value) +{ + if (chunkResult.IsFailure) + { + // Handle error in stream + Console.WriteLine($"Stream error: {chunkResult.Error.Message}"); + break; + } + + var chunk = chunkResult.Value; + Console.Write(chunk.TextDelta); +} +``` + +The HTTP client implementation uses server-sent events to receive response chunks from the server, automatically deserializing each SSE event into a response DTO. diff --git a/generate/javascript.md b/generate/javascript.md index a859cb5..8d201eb 100644 --- a/generate/javascript.md +++ b/generate/javascript.md @@ -22,3 +22,55 @@ Install `fsdgenjs` [as documented](/generate/tools#installation) from its [NuGet * `--typescript`: Generates TypeScript rather than JavaScript. * `--express`: Generates an [Express](http://expressjs.com) server. * `--disable-eslint`: Disables ESLint via code comment. + +## Events + +[Events](/define/fsd#events) in Facility enable streaming responses using server-sent events (SSE). The JavaScript/TypeScript code generator produces methods that return async iterables for events. + +For an event defined as: + +```fsd +event streamChat +{ + prompt: string; +}: +{ + textDelta: string; +} +``` + +The generated TypeScript client includes: + +```typescript +streamChat( + request: IStreamChatRequest +): Promise>>>; +``` + +### Using Events in JavaScript/TypeScript + +Clients can consume event streams using `for await...of`: + +```typescript +const request = { prompt: "Hello" }; +const result = await client.streamChat(request); + +if (!result.value) { + // Handle error + console.error(`Error: ${result.error.message}`); + return; +} + +for await (const chunkResult of result.value) { + if (!chunkResult.value) { + // Handle error in stream + console.error(`Stream error: ${chunkResult.error.message}`); + break; + } + + const chunk = chunkResult.value; + process.stdout.write(chunk.textDelta); +} +``` + +The HTTP client implementation uses the Fetch API or similar to consume server-sent events, automatically parsing each SSE event into a response object. From 77d302f0244795b6c8e3910e08139e0a96f4c6f2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 18 Nov 2025 20:16:58 +0000 Subject: [PATCH 3/9] Add events references throughout the FSD documentation Co-authored-by: ddunkin <264744+ddunkin@users.noreply.github.com> --- define/fsd.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/define/fsd.md b/define/fsd.md index bc24364..2afa3d6 100644 --- a/define/fsd.md +++ b/define/fsd.md @@ -20,13 +20,13 @@ An FSD file is a text file encoded with UTF-8 and no byte order mark (BOM). Every service has a **name**. Unless otherwise noted, a name in this specification must start with an ASCII letter but may otherwise contain ASCII letters, numbers, and/or underscores. -A service contains one or more service elements: [methods](#methods), [data transfer objects](#data-transfer-objects), [enumerated types](#enumerated-types), and [error sets](#error-sets). A service can also have [attributes](#attributes), a [summary](#summary), and [remarks](#remarks). +A service contains one or more service elements: [methods](#methods), [events](#events), [data transfer objects](#data-transfer-objects), [enumerated types](#enumerated-types), and [error sets](#error-sets). A service can also have [attributes](#attributes), a [summary](#summary), and [remarks](#remarks). #### Service FSD In an FSD file, the `service` keyword starts the definition of a service. It is followed by the service name and optionally preceded by service attributes. -The methods and other service items follow the service name, enclosed in braces. +The methods, events, and other service items follow the service name, enclosed in braces. ```fsd [http(url: "https://api.example.com/v1/")] @@ -34,6 +34,7 @@ The methods and other service items follow the service name, enclosed in braces. service MyApi { method myMethod { … }: { … } + event myEvent { … }: { … } data MyData { … } enum MyEnum { … } … @@ -48,6 +49,7 @@ It is also possible to omit the curly braces around the service members and inst service MyApi; method myMethod { … }: { … } +event myEvent { … }: { … } data MyData { … } enum MyEnum { … } … @@ -90,7 +92,7 @@ Multiple attributes can be comma-delimited within one set of square brackets (as #### Attribute HTTP -Every Facility API has a default HTTP mapping. The HTTP mapping can be customized by using the `http` attribute, which can be applied to services, methods, request fields, response fields, and errors. +Every Facility API has a default HTTP mapping. The HTTP mapping can be customized by using the `http` attribute, which can be applied to services, methods, events, request fields, response fields, and errors. The `http` attribute is always optional. When the attribute is omitted, the defaults are used, as documented. @@ -276,7 +278,7 @@ In this example, the server would stream multiple responses: ### Fields -A field stores data for a method request, method response, or data transfer object. +A field stores data for a method request, method response, event request, event response, or data transfer object. Each field has a **name** and a **type**. The field type restricts the type of data that can be stored in that field. @@ -687,7 +689,7 @@ Use two slashes to start a comment. The slashes and everything that follows them ### Summary -Most elements of a service support a **summary** string for documentation purposes: service, methods, DTOs, fields, enumerated types, enumerated type values, error sets, and error set values. +Most elements of a service support a **summary** string for documentation purposes: service, methods, events, DTOs, fields, enumerated types, enumerated type values, error sets, and error set values. The summary should be short and consist of a single sentence or short paragraph. @@ -695,7 +697,7 @@ The summary should be short and consist of a single sentence or short paragraph. To add a summary to a service element, place a comment line before it that uses three slashes instead of two. Multiple summary comments can be used for a single element of a service; newlines are automatically replaced with spaces. -Summaries are supported by services, methods, DTOs, fields, enumerated types, enumerated values, error sets, and error values. +Summaries are supported by services, methods, events, DTOs, fields, enumerated types, enumerated values, error sets, and error values. ```fsd /// My awesome data. @@ -707,7 +709,7 @@ Summaries are supported by services, methods, DTOs, fields, enumerated types, en ### Remarks -Some elements also support **remarks**: service, methods, DTOs, enumerated types, and error sets. +Some elements also support **remarks**: service, methods, events, DTOs, enumerated types, and error sets. The remarks can use [GitHub Flavored Markdown](https://guides.github.com/features/mastering-markdown/). They can be arbitrarily long and can include multiple paragraphs. From 9b4e46fc631c64cca010605baa4f633e306c0376 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 18 Nov 2025 20:23:07 +0000 Subject: [PATCH 4/9] Address review feedback: simplify examples and terminology Co-authored-by: ddunkin <264744+ddunkin@users.noreply.github.com> --- define/fsd.md | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/define/fsd.md b/define/fsd.md index 2afa3d6..b218770 100644 --- a/define/fsd.md +++ b/define/fsd.md @@ -176,7 +176,6 @@ event chatStream { messages: ChatMessage[]; status: ChatStatus; - usage: ChatUsage; } ``` @@ -218,9 +217,9 @@ event chatStream When an event is invoked: * The server establishes an HTTP connection with server-sent events (SSE) -* The server yields multiple response chunks over time -* Each chunk is a complete response DTO, serialized and sent as an SSE event -* Clients can process chunks as they arrive, enabling progressive rendering +* The server yields multiple responses over time +* Each response is a complete response DTO, serialized and sent as an SSE event +* Clients can process responses as they arrive * The stream completes when the server finishes sending data * Errors can be returned at any point in the stream using the `ServiceResult` wrapper @@ -246,18 +245,9 @@ service ChatApi /// Completion status (sent in final chunk) status: CompletionStatus; - - /// Token usage statistics (sent in final chunk) - usage: UsageInfo; } } -data UsageInfo -{ - inputTokens: int32; - outputTokens: int32; -} - enum CompletionStatus { /// Response completed successfully @@ -272,9 +262,9 @@ enum CompletionStatus ``` In this example, the server would stream multiple responses: -* Initial chunks contain `textDelta` with generated text fragments -* Intermediate chunks may include additional `textDelta` values -* The final chunk includes `status` and `usage` to indicate completion +* Initial responses contain `textDelta` with generated text fragments +* Intermediate responses may include additional `textDelta` values +* The final response includes `status` to indicate completion ### Fields From f672e8b40d4bbd00c1f46902fcd5fbc4c1fcec00 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 18 Nov 2025 22:14:18 +0000 Subject: [PATCH 5/9] Simplify Events documentation and add SSE specification link Co-authored-by: ddunkin <264744+ddunkin@users.noreply.github.com> --- define/fsd.md | 48 ++++++++---------------------------------------- 1 file changed, 8 insertions(+), 40 deletions(-) diff --git a/define/fsd.md b/define/fsd.md index b218770..c0a5649 100644 --- a/define/fsd.md +++ b/define/fsd.md @@ -152,19 +152,17 @@ The `code` parameter indicates the HTTP status code used if the method is succes ### Events -Events are similar to methods but support streaming responses. Instead of returning a single response, an event returns a stream of response chunks over time, enabling server-sent events (SSE) style communication. +Events are similar to methods but support streaming responses using [server-sent events (SSE)](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events). Like methods, each event has a **name**, **request fields**, and **response fields**. Events can also have [attributes](#attributes), a [summary](#summary), and [remarks](#remarks). -When a client invokes an event, it provides request field values just like a method. However, unlike a method that returns a single response, an event returns a stream where each item is a complete response DTO. The stream can yield multiple responses over time until it completes. - -In C#, events return `Task>>>`, allowing clients to process responses as they arrive using `await foreach`. Other languages provide similar async iterable constructs. +When invoked, an event returns a stream of responses over time. Each response is a complete response DTO. SSE provides a simple, HTTP-based approach for server-to-client streaming that works well with standard web infrastructure. #### Event FSD In an FSD file, the `event` keyword starts the definition of an event. It is followed by the event name and optionally preceded by event attributes. -The request and response follow the event name, each enclosed in braces and separated by a colon (`:`). The syntax is identical to methods, but the response represents a single chunk of data rather than the entire response. +The request and response follow the event name, each enclosed in braces and separated by a colon (`:`). The syntax is identical to methods. ```fsd /// Generates the next message in a chat. @@ -197,35 +195,21 @@ event chatStream { messages: ChatMessage[]; status: ChatStatus; - usage: ChatUsage; } ``` #### Events vs Methods -**Methods** return a single response (or error) and then complete. They are ideal for traditional request-response operations. - -**Events** return a stream of responses, allowing progressive updates. Each response in the stream is a complete response DTO. Events are ideal for: +**Methods** return a single response. **Events** return a stream of responses over time. Events are ideal for: * Long-running operations with progress updates -* Streaming AI/LLM responses where tokens are generated incrementally -* Real-time data feeds that push updates to clients -* Incremental results where partial data is useful before completion - -#### Response Streaming Behavior - -When an event is invoked: - -* The server establishes an HTTP connection with server-sent events (SSE) -* The server yields multiple responses over time -* Each response is a complete response DTO, serialized and sent as an SSE event -* Clients can process responses as they arrive -* The stream completes when the server finishes sending data -* Errors can be returned at any point in the stream using the `ServiceResult` wrapper +* Streaming AI/LLM responses +* Real-time data feeds +* Incremental results #### Event Example -Here's a practical example showing how events are used for streaming AI chat responses: +Example of streaming AI chat responses: ```fsd service ChatApi @@ -233,39 +217,23 @@ service ChatApi /// Streams chat response tokens as they're generated. event streamChat { - /// The user's prompt prompt: string; - - /// The model to use (optional) model: string; }: { - /// Text delta to append to response textDelta: string; - - /// Completion status (sent in final chunk) status: CompletionStatus; } } enum CompletionStatus { - /// Response completed successfully complete, - - /// Response was truncated truncated, - - /// An error occurred error, } ``` -In this example, the server would stream multiple responses: -* Initial responses contain `textDelta` with generated text fragments -* Intermediate responses may include additional `textDelta` values -* The final response includes `status` to indicate completion - ### Fields A field stores data for a method request, method response, event request, event response, or data transfer object. From 61da9fa50e45ec141a1d618ebe8b5a5e2800f4fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Nov 2025 00:06:12 +0000 Subject: [PATCH 6/9] Correct Event HTTP default to GET (EventSource limitation) Co-authored-by: ddunkin <264744+ddunkin@users.noreply.github.com> --- define/fsd.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/define/fsd.md b/define/fsd.md index c0a5649..8774739 100644 --- a/define/fsd.md +++ b/define/fsd.md @@ -181,12 +181,12 @@ event chatStream The `http` attribute works the same for events as for methods. Events support the `method` and `path` parameters. -The `method` parameter indicates the HTTP method to use, typically `POST` (the default). The `path` parameter specifies the HTTP path, defaulting to the event name with a leading slash (e.g., `/chatStream`). +The `method` parameter indicates the HTTP method to use. If omitted, the default is `GET` (unlike methods, which default to `POST`). This default is appropriate for events because [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) only supports GET requests. The `path` parameter specifies the HTTP path, defaulting to the event name with a leading slash (e.g., `/chatStream`). Events always use server-sent events (SSE) for the response, with `Content-Type: text/event-stream`. The HTTP response uses status code `200` and keeps the connection open to stream multiple response DTOs as separate SSE events. ```fsd -[http(method: POST, path: "/chat/stream")] +[http(path: "/chat/stream")] event chatStream { settings: ChatSettings; From 73fb843272bb0c340674cc0f9bbea03bd31e49bf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Nov 2025 00:10:08 +0000 Subject: [PATCH 7/9] Clarify Event HTTP method defaults and EventSource limitation Co-authored-by: ddunkin <264744+ddunkin@users.noreply.github.com> --- define/fsd.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/define/fsd.md b/define/fsd.md index 8774739..e0377e6 100644 --- a/define/fsd.md +++ b/define/fsd.md @@ -181,7 +181,9 @@ event chatStream The `http` attribute works the same for events as for methods. Events support the `method` and `path` parameters. -The `method` parameter indicates the HTTP method to use. If omitted, the default is `GET` (unlike methods, which default to `POST`). This default is appropriate for events because [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) only supports GET requests. The `path` parameter specifies the HTTP path, defaulting to the event name with a leading slash (e.g., `/chatStream`). +The `method` parameter indicates the HTTP method to use. If omitted, the default is `POST` (the same as methods). The `path` parameter specifies the HTTP path, defaulting to the event name with a leading slash (e.g., `/chatStream`). + +Note that the browser [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) API only supports GET requests. For other HTTP methods, clients must use custom SSE implementations (e.g., using the fetch API with SSE parsing). Events always use server-sent events (SSE) for the response, with `Content-Type: text/event-stream`. The HTTP response uses status code `200` and keeps the connection open to stream multiple response DTOs as separate SSE events. From 3a25b50cd6da76fdae2a6a6caa41d6bc8f6af1a8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 20 Nov 2025 21:25:26 +0000 Subject: [PATCH 8/9] Update documentation based on PR #75 implementation details Co-authored-by: ddunkin <264744+ddunkin@users.noreply.github.com> --- define/fsd.md | 2 +- generate/javascript.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/define/fsd.md b/define/fsd.md index e0377e6..9e2353e 100644 --- a/define/fsd.md +++ b/define/fsd.md @@ -183,7 +183,7 @@ The `http` attribute works the same for events as for methods. Events support th The `method` parameter indicates the HTTP method to use. If omitted, the default is `POST` (the same as methods). The `path` parameter specifies the HTTP path, defaulting to the event name with a leading slash (e.g., `/chatStream`). -Note that the browser [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) API only supports GET requests. For other HTTP methods, clients must use custom SSE implementations (e.g., using the fetch API with SSE parsing). + Events always use server-sent events (SSE) for the response, with `Content-Type: text/event-stream`. The HTTP response uses status code `200` and keeps the connection open to stream multiple response DTOs as separate SSE events. diff --git a/generate/javascript.md b/generate/javascript.md index 8d201eb..27606f7 100644 --- a/generate/javascript.md +++ b/generate/javascript.md @@ -55,14 +55,14 @@ Clients can consume event streams using `for await...of`: const request = { prompt: "Hello" }; const result = await client.streamChat(request); -if (!result.value) { +if (!result.ok) { // Handle error console.error(`Error: ${result.error.message}`); return; } for await (const chunkResult of result.value) { - if (!chunkResult.value) { + if (!chunkResult.ok) { // Handle error in stream console.error(`Stream error: ${chunkResult.error.message}`); break; @@ -73,4 +73,4 @@ for await (const chunkResult of result.value) { } ``` -The HTTP client implementation uses the Fetch API or similar to consume server-sent events, automatically parsing each SSE event into a response object. +The HTTP client implementation uses the Fetch API to consume server-sent events with all HTTP methods supported, automatically parsing each SSE event into a response object. From c0de51f0e358c94bf3a1fd3a46a22cf39903c347 Mon Sep 17 00:00:00 2001 From: Dave Dunkin Date: Thu, 20 Nov 2025 15:05:58 -0700 Subject: [PATCH 9/9] Clean up formatting in fsd.md Removed unnecessary blank lines before the SSE explanation. --- define/fsd.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/define/fsd.md b/define/fsd.md index 9e2353e..2d7e4f0 100644 --- a/define/fsd.md +++ b/define/fsd.md @@ -183,8 +183,6 @@ The `http` attribute works the same for events as for methods. Events support th The `method` parameter indicates the HTTP method to use. If omitted, the default is `POST` (the same as methods). The `path` parameter specifies the HTTP path, defaulting to the event name with a leading slash (e.g., `/chatStream`). - - Events always use server-sent events (SSE) for the response, with `Content-Type: text/event-stream`. The HTTP response uses status code `200` and keeps the connection open to stream multiple response DTOs as separate SSE events. ```fsd