copilotAgent.ts ×7

Frontier kind: Code frontier

unlabeled · c_49c1985e6555

38 tests · 51537 LOC · 300 files · introduces 0 tests · 76 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
7 ranges76 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
4929 ranges51537 lines · 300 files · Browse complete extent
All tests (intent)
38 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 76 introduced LOC across 7 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/copilot/copilotAgent.ts 76 introduced LOC · 7 ranges

Open complete file

1488 */
1489 private async _resolveCreateWorkingDirectory(sessionConfig: IAgentCreateSessionConfig, sessionId: string, isWorkspaceless: boolean): Promise<URI> {
1490 > const existing = sessionConfig.workingDirectory ?? this._provisionalSessions.get(sessionId)?.workingDirectory; copilotAgent.ts
1491 > if (existing) {
1492 return existing;
1493 }
1506 this._logService.trace(`[Copilot] No workingDirectory provided, defaulting to temp directory: ${workingDirectory.fsPath}`);
1507 return workingDirectory;
1508 > } copilotAgent.ts
1509
1510 /**
1652
1653 async createSession(config?: IAgentCreateSessionConfig): Promise<IAgentCreateSessionResult> {
1654 > const sessionConfig = config ?? {}; copilotAgent.ts
1655 >
1656 > this._logService.info(`[Copilot] Creating session... ${sessionConfig.model ? `model=${sessionConfig.model.id}` : ''}`);
1657 > const sessionId = sessionConfig.session ? AgentSession.id(sessionConfig.session) : generateUuid();
1658 > // Workspace-less is inferred at create from an absent input
1659 > // `workingDirectory`: such a session is run in a stable scratch dir. The
1660 > // AH service persists the marker centrally (`agentHost.workspaceless`) and
1661 > // hands it back on restore; the agent only reads it (never persists it) to
1662 > // pick the workspace-less system prompt. Forks always inherit the source
1663 > // session's context, so they are never inferred workspace-less even when no
1664 > // `workingDirectory` is passed.
1665 > const isWorkspaceless = !sessionConfig.fork && !sessionConfig.workingDirectory;
1666 > const workingDirectory = await this._resolveCreateWorkingDirectory(sessionConfig, sessionId, isWorkspaceless);
1667 > const client = await this._ensureClient();
1668 > // When forking, use the SDK's sessions.fork RPC. Forking from a source
1669 > // session that has no turns is equivalent to creating a fresh session;
1670 > // in that case the agent service drops `config.fork` before calling us,
1671 > // so we never enter this branch with a provisional source.
1672 > if (sessionConfig.fork) {
1673 const sourceSessionId = AgentSession.id(sessionConfig.fork.session);
1674
1741 });
1742 }
1744 > if (sessionConfig.importConversation) {
1745 return this._importConversation(sessionConfig, sessionId, workingDirectory);
1746 }
1748 > // Non-fork path: create a *provisional* session. The Copilot SDK
1749 > // session, the worktree (if any), and the on-disk metadata are all
1750 > // deferred until the first {@link sendMessage} via
1751 > // {@link _materializeProvisional}. Until then this session occupies
1752 > // only an in-memory slot plus a state-manager entry, so a workspace
1753 > // switch (or quick close) costs nothing on disk.
1754 > const sessionUri = AgentSession.uri(this.id, sessionId);
1755 >
1756 > // Idempotency for already-materialized sessions: a duplicate
1757 > // `createSession` for a URI that has already been promoted to a real
1758 > // SDK session (or restored from disk) is a no-op; we return the
1759 > // non-provisional result so the caller doesn't re-fire `SessionAdded`.
1760 > // This guards against client retries that race a successful first
1761 > // message.
1762 > if (this._findAnySession(sessionId)) {
1763 this._logService.info(`[Copilot] createSession is a no-op: session already materialized: ${sessionUri.toString()}`);
1764 const project = await projectFromCopilotContext({ cwd: workingDirectory.fsPath }, this._gitService);
1765 return { session: sessionUri, workingDirectory, ...(project ? { project } : {}) };
1766 }
1768 > // Idempotent: a duplicate `createSession` for a still-provisional URI
1769 > // (e.g. a client retried on reconnect with the same URI) keeps the
1770 > // existing record. We deliberately do NOT overwrite `model` or
1771 > // `workingDirectory`: a re-create payload from a fresh connection sends
1772 > // the eager-create defaults (model: undefined, the same workingDirectory),
1773 > // which would clobber the user's selections accumulated since the
1774 > // original create. The active-client / plugin sync below still runs so
1775 > // the new connection's claim takes effect.
1776 > const alreadyProvisional = this._provisionalSessions.has(sessionId);
1777 >
1778 > // Seed active-client snapshot if the client claimed it eagerly. This
1779 > // runs identically for provisional and real sessions; the SDK side
1780 > // of activeClient state isn't engaged until materialization.
1781 > if (sessionConfig.activeClient) {
1782 const ac = this._getOrCreateActiveClient(sessionUri, workingDirectory);
1783 const seeded = sessionConfig.activeClient;
1792 }
1793 }
1795 > // Compute project metadata cheaply from the original working dir.
1796 > // Worktrees aren't created until materialization, so the project is
1797 > // reported relative to the user's chosen folder.
1798 > const project = await projectFromCopilotContext({ cwd: workingDirectory.fsPath }, this._gitService);
1799 >
1800 > if (!alreadyProvisional) {
1801 > this._provisionalSessions.set(sessionId, {
1802 > sessionId,
1803 > sessionUri,
1804 > workingDirectory,
1805 > model: sessionConfig.model,
1806 > agent: sessionConfig.agent,
1807 > project,
1808 > workspaceless: isWorkspaceless,
1809 > });
1810 > }
1811 >
1812 > this._logService.info(`[Copilot] Session created (provisional): ${sessionUri.toString()}`);
1813 > return { session: sessionUri, workingDirectory, provisional: true, ...(project ? { project } : {}) };
1814 > }
1815
1816 /**