Skip to content

feat(ai): add type-safe tool call events to chat() stream#452

Open
AlemTuzlak wants to merge 6 commits intomainfrom
worktree-serialized-exploring-wall
Open

feat(ai): add type-safe tool call events to chat() stream#452
AlemTuzlak wants to merge 6 commits intomainfrom
worktree-serialized-exploring-wall

Conversation

@AlemTuzlak
Copy link
Copy Markdown
Contributor

@AlemTuzlak AlemTuzlak commented Apr 15, 2026

Summary

  • Made ToolCallStartEvent and ToolCallEndEvent generic with backward-compatible defaults (string / unknown)
  • Added TypedStreamChunk<TTools> exported type that replaces untyped tool call events with typed versions based on the tools array
  • Threaded TTools generic through TextActivityOptions, TextActivityResult, chat(), and createChatOptions() so the stream return type carries tool type information
  • Added IsAny guard in ToolInputsOf to prevent any leaking through InferSchemaType for tools without inputSchema
  • Added 29 type-level tests covering: typed names/inputs, server/client/definition tool variants, empty/default/readonly arrays, backward compatibility, and chat() inference without explicit type args
  • Updated streaming docs with "Type-Safe Tool Call Events" section, StreamChunk.md reference, and cross-links from tools docs
  • Added showcase snippet in ts-react-chat example

Test plan

  • All 660 unit tests pass (pnpm --filter @tanstack/ai test:lib)
  • Build succeeds (pnpm --filter @tanstack/ai build)
  • Example app builds (pnpm --filter ts-react-chat build)
  • 29 type-level tests verify: literal name narrowing, input type inference, fallback to string/unknown, empty arrays, as const, server/client tool variants, chat() inference, backward compat (assignability, StreamChunk unchanged)
  • toBeUnknown() assertions used instead of toEqualTypeOf<unknown>() to catch any leaks

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Streaming chat now provides type-safe tool-call events: tool names and inputs are narrowed when tools include input schemas.
  • Documentation

    • Added a "Type-Safe Tool Call Events" guide and reference and a TypedStreamChunk helper description.
    • Tool docs and examples updated with tips and a typed stream showcase illustrating consumption patterns.

When tools with Zod schemas are passed to chat(), the stream chunks now
carry type information on TOOL_CALL_START and TOOL_CALL_END events:
- toolName narrows to the union of tool name literals
- input on TOOL_CALL_END is typed as the union of tool input types

Made ToolCallStartEvent and ToolCallEndEvent generic with backward-
compatible defaults. Added TypedStreamChunk<TTools> type that threads
through TextActivityOptions, TextActivityResult, chat(), and
createChatOptions(). Includes IsAny guard in ToolInputsOf to prevent
`any` leaking through InferSchemaType for tools without inputSchema.

Fully backward compatible — StreamChunk and AGUIEvent are unchanged,
unparameterized event types use string/unknown defaults.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 15, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 97002002-683e-4415-8051-f40b9aa9a447

📥 Commits

Reviewing files that changed from the base of the PR and between 9a1df7e and d46cd6d.

📒 Files selected for processing (5)
  • docs/chat/streaming.md
  • docs/reference/type-aliases/StreamChunk.md
  • docs/tools/server-tools.md
  • packages/typescript/ai/src/types.ts
  • packages/typescript/ai/tests/type-check.test.ts
✅ Files skipped from review due to trivial changes (3)
  • docs/tools/server-tools.md
  • docs/chat/streaming.md
  • packages/typescript/ai/src/types.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/reference/type-aliases/StreamChunk.md

📝 Walkthrough

Walkthrough

Adds generic tool-aware stream typing: TOOL_CALL_START/TOOL_CALL_END events gain narrowed toolName literals and per-tool input types when chat() receives typed tools. Introduces TypedStreamChunk<TTools>, threads TTools through chat APIs, and updates docs, examples, and tests.

Changes

Cohort / File(s) Summary
Documentation
docs/chat/streaming.md, docs/reference/type-aliases/StreamChunk.md, docs/tools/tools.md, docs/tools/server-tools.md
New "Type-Safe Tool Call Events" docs, added TypedStreamChunk reference, explanatory tips, examples, and cross-links describing discriminated unions for tool-call events.
Type System Core
packages/typescript/ai/src/types.ts
Made ToolCallStartEvent/ToolCallEndEvent generic over toolName/input; added exported TypedStreamChunk<TTools> that produces discriminated tool-call unions when tools are typed.
API Integration
packages/typescript/ai/src/activities/chat/index.ts
Threaded TTools generic through TextActivityOptions, createChatOptions, and chat(); streaming return type changed to AsyncIterable<TypedStreamChunk<TTools>> with matching exported type updates.
Tests & Examples
packages/typescript/ai/tests/type-check.test.ts, examples/ts-react-chat/src/routes/api.tanchat.ts
Expanded compile-time type-checks for TypedStreamChunk with Zod/tool fixtures and added typedStreamShowcase() example demonstrating typed stream handling and branching on toolName.
Other
packages/typescript/ai/tests/..., examples/...
Minor test scaffolding adjustments and example tweaks to exercise and validate new typings.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I nibble at types with tiny hops,
Tool names snap tight — no loose flops.
Streams now hum with matching input,
One carrot-typed event, then another jump! 🥕✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is comprehensive and covers the main changes, test results, and includes a detailed summary section. However, it lacks the checklist items from the required template (Contributing guide steps and changeset generation). Complete the PR checklist by confirming that Contributing guide steps were followed and indicating whether a changeset was generated (or whether this is docs/CI-only).
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main feature: adding type-safe tool call events to the chat() stream, which matches the primary objective of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch worktree-serialized-exploring-wall

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 15, 2026

🚀 Changeset Version Preview

4 package(s) bumped directly, 23 bumped as dependents.

🟩 Patch bumps

Package Version Reason
@tanstack/ai 0.10.2 → 0.10.3 Changeset
@tanstack/ai-gemini 0.8.7 → 0.8.8 Changeset
@tanstack/ai-ollama 0.6.5 → 0.6.6 Changeset
@tanstack/ai-openai 0.7.4 → 0.7.5 Changeset
@tanstack/ai-client 0.7.9 → 0.7.10 Dependent
@tanstack/ai-code-mode 0.1.2 → 0.1.3 Dependent
@tanstack/ai-code-mode-models-eval 0.0.5 → 0.0.6 Dependent
@tanstack/ai-code-mode-skills 0.1.2 → 0.1.3 Dependent
@tanstack/ai-devtools-core 0.3.19 → 0.3.20 Dependent
@tanstack/ai-event-client 0.2.2 → 0.2.3 Dependent
@tanstack/ai-fal 0.6.12 → 0.6.13 Dependent
@tanstack/ai-isolate-cloudflare 0.1.2 → 0.1.3 Dependent
@tanstack/ai-isolate-node 0.1.2 → 0.1.3 Dependent
@tanstack/ai-isolate-quickjs 0.1.2 → 0.1.3 Dependent
@tanstack/ai-openrouter 0.7.4 → 0.7.5 Dependent
@tanstack/ai-preact 0.6.14 → 0.6.15 Dependent
@tanstack/ai-react 0.7.10 → 0.7.11 Dependent
@tanstack/ai-solid 0.6.14 → 0.6.15 Dependent
@tanstack/ai-svelte 0.6.14 → 0.6.15 Dependent
@tanstack/ai-vue 0.6.14 → 0.6.15 Dependent
@tanstack/ai-vue-ui 0.1.25 → 0.1.26 Dependent
@tanstack/preact-ai-devtools 0.1.23 → 0.1.24 Dependent
@tanstack/react-ai-devtools 0.2.23 → 0.2.24 Dependent
@tanstack/solid-ai-devtools 0.2.23 → 0.2.24 Dependent
ts-svelte-chat 0.1.31 → 0.1.32 Dependent
ts-vue-chat 0.1.31 → 0.1.32 Dependent
vanilla-chat 0.0.29 → 0.0.30 Dependent

@nx-cloud
Copy link
Copy Markdown

nx-cloud bot commented Apr 15, 2026

View your CI Pipeline Execution ↗ for commit d46cd6d

Command Status Duration Result
nx run-many --targets=build --exclude=examples/** ✅ Succeeded 1m 40s View ↗

☁️ Nx Cloud last updated this comment at 2026-04-16 12:04:34 UTC

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 15, 2026

Open in StackBlitz

@tanstack/ai

npm i https://pkg.pr.new/@tanstack/ai@452

@tanstack/ai-anthropic

npm i https://pkg.pr.new/@tanstack/ai-anthropic@452

@tanstack/ai-client

npm i https://pkg.pr.new/@tanstack/ai-client@452

@tanstack/ai-code-mode

npm i https://pkg.pr.new/@tanstack/ai-code-mode@452

@tanstack/ai-code-mode-skills

npm i https://pkg.pr.new/@tanstack/ai-code-mode-skills@452

@tanstack/ai-devtools-core

npm i https://pkg.pr.new/@tanstack/ai-devtools-core@452

@tanstack/ai-elevenlabs

npm i https://pkg.pr.new/@tanstack/ai-elevenlabs@452

@tanstack/ai-event-client

npm i https://pkg.pr.new/@tanstack/ai-event-client@452

@tanstack/ai-fal

npm i https://pkg.pr.new/@tanstack/ai-fal@452

@tanstack/ai-gemini

npm i https://pkg.pr.new/@tanstack/ai-gemini@452

@tanstack/ai-grok

npm i https://pkg.pr.new/@tanstack/ai-grok@452

@tanstack/ai-groq

npm i https://pkg.pr.new/@tanstack/ai-groq@452

@tanstack/ai-isolate-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-isolate-cloudflare@452

@tanstack/ai-isolate-node

npm i https://pkg.pr.new/@tanstack/ai-isolate-node@452

@tanstack/ai-isolate-quickjs

npm i https://pkg.pr.new/@tanstack/ai-isolate-quickjs@452

@tanstack/ai-ollama

npm i https://pkg.pr.new/@tanstack/ai-ollama@452

@tanstack/ai-openai

npm i https://pkg.pr.new/@tanstack/ai-openai@452

@tanstack/ai-openrouter

npm i https://pkg.pr.new/@tanstack/ai-openrouter@452

@tanstack/ai-preact

npm i https://pkg.pr.new/@tanstack/ai-preact@452

@tanstack/ai-react

npm i https://pkg.pr.new/@tanstack/ai-react@452

@tanstack/ai-react-ui

npm i https://pkg.pr.new/@tanstack/ai-react-ui@452

@tanstack/ai-solid

npm i https://pkg.pr.new/@tanstack/ai-solid@452

@tanstack/ai-solid-ui

npm i https://pkg.pr.new/@tanstack/ai-solid-ui@452

@tanstack/ai-svelte

npm i https://pkg.pr.new/@tanstack/ai-svelte@452

@tanstack/ai-vue

npm i https://pkg.pr.new/@tanstack/ai-vue@452

@tanstack/ai-vue-ui

npm i https://pkg.pr.new/@tanstack/ai-vue-ui@452

@tanstack/preact-ai-devtools

npm i https://pkg.pr.new/@tanstack/preact-ai-devtools@452

@tanstack/react-ai-devtools

npm i https://pkg.pr.new/@tanstack/react-ai-devtools@452

@tanstack/solid-ai-devtools

npm i https://pkg.pr.new/@tanstack/solid-ai-devtools@452

commit: d46cd6d

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/chat/streaming.md`:
- Around line 115-117: Remove the blank line between the two blockquotes so the
"**Note:**" and "**Tip:**" paragraphs are adjacent (or merge them into one
blockquote); specifically edit the section containing the "**Note:** When
multiple tools..." and the "**Tip:** The typed stream chunk type..." strings so
there is no empty line between those blockquote lines to satisfy markdownlint
MD028.

In `@docs/reference/type-aliases/StreamChunk.md`:
- Line 23: The "Defined in" source anchor for the TypedStreamChunk entry is
stale; update the anchor in docs/reference/type-aliases/StreamChunk.md to point
to the current declaration location packages/typescript/ai/src/types.ts at line
1048 (or to the exact URL/permalink generated by TypeDoc for TypedStreamChunk),
ensuring the link text and URL reflect the new file and line; update the
markdown so it uses the correct Markdown link format and matches the repo's
TypeDoc-generated anchor for TypedStreamChunk.

In `@packages/typescript/ai/tests/type-check.test.ts`:
- Around line 6-17: The named imports in this test file are not alphabetized
causing ESLint sort-imports errors; reorder the members inside each import's
braces alphabetically (e.g., change "describe, it, expectTypeOf" to "describe,
expectTypeOf, it" for the vitest import, and similarly alphabetize "chat,
createChatOptions, toolDefinition" and the type import list "JSONSchema,
StreamChunk, Tool, ToolCallArgsEvent, ToolCallEndEvent, ToolCallStartEvent,
TypedStreamChunk") so each import's named members are in ascending alphabetical
order.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 28ddc119-4e8d-45ba-8567-1aae00525797

📥 Commits

Reviewing files that changed from the base of the PR and between db5c3d3 and a2c2f9c.

📒 Files selected for processing (7)
  • docs/chat/streaming.md
  • docs/reference/type-aliases/StreamChunk.md
  • docs/tools/tools.md
  • examples/ts-react-chat/src/routes/api.tanchat.ts
  • packages/typescript/ai/src/activities/chat/index.ts
  • packages/typescript/ai/src/types.ts
  • packages/typescript/ai/tests/type-check.test.ts

Comment thread docs/chat/streaming.md Outdated
type TypedStreamChunk<TTools extends ReadonlyArray<Tool<any, any, any>> = ReadonlyArray<Tool<any, any, any>>>
```

Defined in: [types.ts:1033](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/types.ts#L1033)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Update the TypedStreamChunk source anchor.

This Defined in link still points to types.ts:1033, but the alias is declared at packages/typescript/ai/src/types.ts Line 1048 in this PR, so the reference page is already stale. As per coding guidelines, docs/**/*.md: Use Markdown for documentation in the docs/ directory with auto-generated docs via TypeDoc.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/reference/type-aliases/StreamChunk.md` at line 23, The "Defined in"
source anchor for the TypedStreamChunk entry is stale; update the anchor in
docs/reference/type-aliases/StreamChunk.md to point to the current declaration
location packages/typescript/ai/src/types.ts at line 1048 (or to the exact
URL/permalink generated by TypeDoc for TypedStreamChunk), ensuring the link text
and URL reflect the new file and line; update the markdown so it uses the
correct Markdown link format and matches the repo's TypeDoc-generated anchor for
TypedStreamChunk.

Comment on lines 6 to +17
import { describe, it, expectTypeOf } from 'vitest'
import { createChatOptions } from '../src'
import { z } from 'zod'
import { chat, createChatOptions, toolDefinition } from '../src'
import type {
JSONSchema,
StreamChunk,
Tool,
ToolCallArgsEvent,
ToolCallStartEvent,
ToolCallEndEvent,
TypedStreamChunk,
} from '../src'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix the import member ordering before merge.

ESLint is already flagging this block (sort-imports on Line 6 and Line 15), so this file will stay red until the named imports are alphabetized.

🧰 Tools
🪛 ESLint

[error] 6-6: Member 'expectTypeOf' of the import declaration should be sorted alphabetically.

(sort-imports)


[error] 15-15: Member 'ToolCallEndEvent' of the import declaration should be sorted alphabetically.

(sort-imports)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/typescript/ai/tests/type-check.test.ts` around lines 6 - 17, The
named imports in this test file are not alphabetized causing ESLint sort-imports
errors; reorder the members inside each import's braces alphabetically (e.g.,
change "describe, it, expectTypeOf" to "describe, expectTypeOf, it" for the
vitest import, and similarly alphabetize "chat, createChatOptions,
toolDefinition" and the type import list "JSONSchema, StreamChunk, Tool,
ToolCallArgsEvent, ToolCallEndEvent, ToolCallStartEvent, TypedStreamChunk") so
each import's named members are in ascending alphabetical order.

AlemTuzlak and others added 2 commits April 16, 2026 12:58
…put narrowing

Replace flat toolName/input unions with distributive conditional types
so checking toolName === 'x' narrows input to that specific tool's type.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (2)
docs/reference/type-aliases/StreamChunk.md (1)

23-23: ⚠️ Potential issue | 🟡 Minor

Stale Defined in link for TypedStreamChunk.

The link points to types.ts:1033, but TypedStreamChunk is defined at line 1065 in the current code. This will create a broken anchor.

📝 Suggested fix
-Defined in: [types.ts:1033](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/types.ts#L1033)
+Defined in: [types.ts:1065](https://github.com/TanStack/ai/blob/main/packages/typescript/ai/src/types.ts#L1065)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/reference/type-aliases/StreamChunk.md` at line 23, The documentation
entry for TypedStreamChunk has a stale "Defined in" anchor; update the link
target in docs/reference/type-aliases/StreamChunk.md so it points to the actual
definition of TypedStreamChunk in types.ts (current location around line 1065)
or replace the fragile line-number anchor with a file-level link to types.ts and
a search-friendly fragment for TypedStreamChunk; ensure the reference text
"Defined in" continues to reference types.ts and that the anchor resolves to the
TypedStreamChunk definition.
packages/typescript/ai/tests/type-check.test.ts (1)

6-17: ⚠️ Potential issue | 🟡 Minor

Import members need alphabetical sorting.

ESLint's sort-imports rule requires alphabetically ordered named imports within each statement.

🔧 Suggested fix
-import { describe, it, expectTypeOf } from 'vitest'
+import { describe, expectTypeOf, it } from 'vitest'
 import { z } from 'zod'
 import { chat, createChatOptions, toolDefinition } from '../src'
 import type {
   JSONSchema,
   StreamChunk,
   Tool,
   ToolCallArgsEvent,
-  ToolCallStartEvent,
   ToolCallEndEvent,
+  ToolCallStartEvent,
   TypedStreamChunk,
 } from '../src'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/typescript/ai/tests/type-check.test.ts` around lines 6 - 17, The
named imports in this file are not alphabetized; reorder the identifiers
alphabetically within each import statement—for example change "describe, it,
expectTypeOf" to "describe, expectTypeOf, it", "chat, createChatOptions,
toolDefinition" to "chat, createChatOptions, toolDefinition" (ensure correct
alphabetical order), and the type import list "JSONSchema, StreamChunk, Tool,
ToolCallArgsEvent, ToolCallStartEvent, ToolCallEndEvent, TypedStreamChunk"
should be reordered alphabetically (e.g., "JSONSchema, StreamChunk, Tool,
ToolCallArgsEvent, ToolCallEndEvent, ToolCallStartEvent, TypedStreamChunk") so
each import's named members follow ESLint's sort-imports rule.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@docs/reference/type-aliases/StreamChunk.md`:
- Line 23: The documentation entry for TypedStreamChunk has a stale "Defined in"
anchor; update the link target in docs/reference/type-aliases/StreamChunk.md so
it points to the actual definition of TypedStreamChunk in types.ts (current
location around line 1065) or replace the fragile line-number anchor with a
file-level link to types.ts and a search-friendly fragment for TypedStreamChunk;
ensure the reference text "Defined in" continues to reference types.ts and that
the anchor resolves to the TypedStreamChunk definition.

In `@packages/typescript/ai/tests/type-check.test.ts`:
- Around line 6-17: The named imports in this file are not alphabetized; reorder
the identifiers alphabetically within each import statement—for example change
"describe, it, expectTypeOf" to "describe, expectTypeOf, it", "chat,
createChatOptions, toolDefinition" to "chat, createChatOptions, toolDefinition"
(ensure correct alphabetical order), and the type import list "JSONSchema,
StreamChunk, Tool, ToolCallArgsEvent, ToolCallStartEvent, ToolCallEndEvent,
TypedStreamChunk" should be reordered alphabetically (e.g., "JSONSchema,
StreamChunk, Tool, ToolCallArgsEvent, ToolCallEndEvent, ToolCallStartEvent,
TypedStreamChunk") so each import's named members follow ESLint's sort-imports
rule.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 230ab7f9-f926-49b5-a973-0080ff8b4502

📥 Commits

Reviewing files that changed from the base of the PR and between a2c2f9c and 5e3ebd7.

📒 Files selected for processing (5)
  • docs/chat/streaming.md
  • docs/reference/type-aliases/StreamChunk.md
  • examples/ts-react-chat/src/routes/api.tanchat.ts
  • packages/typescript/ai/src/types.ts
  • packages/typescript/ai/tests/type-check.test.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/chat/streaming.md

- Show practical property access after discriminated narrowing
- Add description field to searchTool example for consistency
- Add cross-link from server-tools to streaming type safety
- Fix stale line number references in StreamChunk.md
- Remove T & Tool<any,any,any> intersection in DistributedToolCallEnd
  that caused tsc to resolve input as unknown for all tools
- Relax SafeToolInput constraint to structural match (no generic bound)
- Fix "Zod schema inference" → "Standard Schema inference" in JSDoc/docs
- Fix off-by-one line number in StreamChunk.md reference
- Fix misleading test comment about searchClientTool
- Add | undefined to input type annotation in streaming docs
- Broaden server-tools.md tip to cover all typed tool variants
- Add tests for mixed Zod+JSON Schema and chat() with server/client tools
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.

1 participant