Feature/post tool text and concurrent threads#94
Open
Gourav-InfoTech wants to merge 6 commits into
Open
Conversation
- Introduced a mechanism to handle post-tool text streaming when a message:delta is received without a preceding message:start, allowing for live updates. - Added a guard to prevent duplicate insertion of assistant messages that follow tool results, ensuring proper message flow. - Improved debug logging for better traceability of streaming state changes. This update refines the chat experience by ensuring that tool responses are integrated seamlessly into the conversation flow.
Adds an opt-in mode where multiple threads can stream at the same time. Users can switch away from a generating thread, start a second one, and have both run in parallel. Single-thread mode (default) is byte-for-byte unchanged. Provider-side: - Instance registry keyed by thread id behind `concurrentThreads` flag - `busyThreadIds: ReadonlySet<string>` for per-thread picker spinners - `assignLocalThreadId(id)` so the hook can bind a locally-minted id to the active pending instance mid-stream (for backends that only emit the session id in the final `done` chunk) - `disposeThreadInstance(id)` for clean teardown on thread delete - Provider-level shared registries (tools, skills, system context) so new instances inherit the right state; register/unregister fan out to every live instance - `handleInstanceThreadAssigned` re-keys only when leaving an internal slot in multi-thread mode — preserves the stable UI id when a session creator isn't in play Chat/agent-loop: - `getThreadId?` override on `ChatWithToolsConfig` so the provider can surface its registry key (the stable UI id) to tool handlers instead of `chat.config.threadId` - Public `get threadId()` on `AbstractChat` - Tool context carries `threadId` for per-thread state Hook (`useInternalThreadManager`): - In multi-thread mode, dispatches the first-response transition as soon as streaming starts so the picker row appears immediately - Defers when `sessionStatus === "creating"` so `yourgptConfig` / `onCreateSession` consumers keep their server `session_uid` as the thread id (preserves the pre-multi-thread contract) - Mints a local id and calls `assignLocalThreadId` when no session creator is configured Backward compatibility: - `concurrentThreads` defaults to `false`; existing consumers run the original single-instance path unchanged - `handleInstanceThreadAssigned` skip is gated on `concurrentThreads` so `renewSession()` in single-thread mode still propagates the new server id to `useCopilot().threadId` and the `onThreadChange` prop - `getThreadId` override is opt-in on config; direct `ChatWithTools` consumers without the provider keep the old `() => chat.threadId`
isBusy now respects `concurrentThreads` — when enabled, ThreadPicker and NewChat stay interactive while the active thread streams, which is the whole point of the feature. Single-thread behavior unchanged. Also wire the playground to exercise both `concurrentThreads` and `yourgptConfig`: - Switch playground to `workspace:*` so it consumes the local SDK (matching every other example in examples/*). - Add Concurrent Threads toggle and YourGPT Auth section (apiKey + widgetUid inputs, stored in localStorage) to the Beta panel. - Pass `concurrentThreads` + conditional `yourgptConfig` to the CopilotProvider; include both in the remount key.
…state In concurrent-threads mode, a background instance can enter approval-required while the user is on a different thread. The existing pendingApprovals (line 1373 area) reflects only the active instance's toolExecutions, so consumers had no way to see that a background thread was blocked. Add a reactive ReadonlyMap<threadId, ToolExecution[]> that scans every instance in instancesRef, filtering by approvalStatus === "required", following the existing busyThreadIds pattern. Recomputed from notifyStateChange, from the eager recompute sites in handleInstanceThreadAssigned / disposeThreadInstance / assignLocalThreadId, and — crucially — directly from the per-instance onToolExecutionsChange and onApprovalRequired callbacks. The reactState subscribe channel only fires on message changes, so tool-execution transitions on background instances wouldn't otherwise trigger a recompute. Exposed on CopilotContextValue so consumers can read it via useCopilot(). UI in the downstream extension now lights up an indicator on the thread picker for threads whose pending executions aren't already covered by a session grant.
…/copilot-sdk into feature/postToolTextAndConcurrentThreads
…v-InfoTech/copilot-sdk into feature/postToolTextAndConcurrentThreads
|
@Gourav-InfoTech is attempting to deploy a commit to the Delta4 Infotech Team on Vercel. A member of the Team first needs to authorize it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #
Changes
Type of Change
Testing
Checklist
Screenshots (if applicable)