mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-10 16:58:55 -05:00
Agents - scaffold Changesets model (#313577)
* Agents - scaffold Changesets model * Pull request feedback
This commit is contained in:
@@ -32,7 +32,7 @@ import { diffsEqual, diffsToChanges, mapProtocolStatus } from './agentHostDiffs.
|
||||
import { buildMutableConfigSchema, IAgentHostSessionsProvider, resolvedConfigsEqual } from '../../../common/agentHostSessionsProvider.js';
|
||||
import { agentHostSessionWorkspaceKey } from '../../../common/agentHostSessionWorkspace.js';
|
||||
import { isSessionConfigComplete } from '../../../common/sessionConfig.js';
|
||||
import { IChat, IGitHubInfo, ISession, ISessionType, ISessionWorkspace, ISessionWorkspaceBrowseAction, SessionStatus, toSessionId } from '../../../services/sessions/common/session.js';
|
||||
import { IChat, IGitHubInfo, ISession, ISessionChangeset, ISessionType, ISessionWorkspace, ISessionWorkspaceBrowseAction, SessionStatus, toSessionId } from '../../../services/sessions/common/session.js';
|
||||
import { ISendRequestOptions, ISessionChangeEvent } from '../../../services/sessions/common/sessionsProvider.js';
|
||||
|
||||
// ============================================================================
|
||||
@@ -74,6 +74,7 @@ export class AgentHostSessionAdapter implements ISession {
|
||||
readonly updatedAt: ISettableObservable<Date>;
|
||||
readonly status: ISettableObservable<SessionStatus>;
|
||||
readonly changes = observableValue<readonly (IChatSessionFileChange | IChatSessionFileChange2)[]>('changes', []);
|
||||
readonly changesets = observableValue<readonly ISessionChangeset[]>('changesets', []);
|
||||
readonly modelId: ISettableObservable<string | undefined>;
|
||||
modelSelection: ModelSelection | undefined;
|
||||
readonly mode = observableValue<{ readonly id: string; readonly kind: string } | undefined>('mode', undefined);
|
||||
@@ -162,6 +163,7 @@ export class AgentHostSessionAdapter implements ISession {
|
||||
updatedAt: this.updatedAt,
|
||||
status: this.status,
|
||||
changes: this.changes,
|
||||
changesets: this.changesets,
|
||||
modelId: this.modelId,
|
||||
mode: this.mode,
|
||||
isArchived: this.isArchived,
|
||||
@@ -381,6 +383,7 @@ class NewSession extends Disposable {
|
||||
this._status = observableValue<SessionStatus>(this, SessionStatus.Untitled);
|
||||
const title = observableValue<string>(this, '');
|
||||
const updatedAt = observableValue(this, new Date());
|
||||
const changesets = observableValue<readonly ISessionChangeset[]>(this, []);
|
||||
const changes = observableValue<readonly (IChatSessionFileChange | IChatSessionFileChange2)[]>(this, []);
|
||||
this._modelId = observableValue<string | undefined>(this, undefined);
|
||||
const mode = observableValue<{ readonly id: string; readonly kind: string } | undefined>(this, undefined);
|
||||
@@ -394,6 +397,7 @@ class NewSession extends Disposable {
|
||||
const mainChat: IChat = {
|
||||
resource, createdAt, title, updatedAt,
|
||||
status: this._status,
|
||||
changesets,
|
||||
changes,
|
||||
modelId: this._modelId,
|
||||
mode, isArchived, isRead, description, lastTurnEnd,
|
||||
@@ -411,6 +415,7 @@ class NewSession extends Disposable {
|
||||
title,
|
||||
updatedAt,
|
||||
status: this._status,
|
||||
changesets,
|
||||
changes,
|
||||
modelId: this._modelId,
|
||||
mode,
|
||||
|
||||
@@ -31,6 +31,7 @@ function makeActiveSession(providerId: string): IActiveSession {
|
||||
title: observableValue('t', 'Test'),
|
||||
updatedAt: observableValue('u', new Date()),
|
||||
status: observableValue('s', 0),
|
||||
changesets: observableValue('cs', []),
|
||||
changes: observableValue('c', []),
|
||||
modelId: observableValue('m', undefined),
|
||||
mode: observableValue('mo', undefined),
|
||||
@@ -50,6 +51,7 @@ function makeActiveSession(providerId: string): IActiveSession {
|
||||
title: chat.title,
|
||||
updatedAt: chat.updatedAt,
|
||||
status: chat.status,
|
||||
changesets: chat.changesets,
|
||||
changes: chat.changes,
|
||||
modelId: chat.modelId,
|
||||
mode: chat.mode,
|
||||
|
||||
@@ -41,6 +41,7 @@ function makeSession(opts: { repository?: URI; worktree?: URI } = {}): ISession
|
||||
title: observableValue('title', 'session'),
|
||||
updatedAt: observableValue('updatedAt', new Date()),
|
||||
status: observableValue('status', SessionStatus.Untitled),
|
||||
changesets: observableValue('changesets', []),
|
||||
changes: observableValue('changes', []),
|
||||
modelId: observableValue('modelId', undefined),
|
||||
mode: observableValue('mode', undefined),
|
||||
@@ -60,6 +61,7 @@ function makeSession(opts: { repository?: URI; worktree?: URI } = {}): ISession
|
||||
title: chat.title,
|
||||
updatedAt: chat.updatedAt,
|
||||
status: chat.status,
|
||||
changesets: chat.changesets,
|
||||
changes: chat.changes,
|
||||
modelId: chat.modelId,
|
||||
mode: chat.mode,
|
||||
|
||||
@@ -23,7 +23,7 @@ import { AgentSessionProviders, AgentSessionTarget } from '../../../../workbench
|
||||
import { IChatService, IChatSendRequestOptions } from '../../../../workbench/contrib/chat/common/chatService/chatService.js';
|
||||
import { IChatResponseModel } from '../../../../workbench/contrib/chat/common/model/chatModel.js';
|
||||
import { ChatSessionStatus, IChatSessionsService, IChatSessionProviderOptionGroup, IChatSessionProviderOptionItem, SessionType } from '../../../../workbench/contrib/chat/common/chatSessionsService.js';
|
||||
import { ISession, IChat, ISessionRepository, ISessionWorkspace, SessionStatus, GITHUB_REMOTE_FILE_SCHEME, IGitHubInfo, CopilotCLISessionType, CopilotCloudSessionType, ClaudeCodeSessionType, ISessionType, ISessionWorkspaceBrowseAction, ISessionFileChange, toSessionId, SESSION_WORKSPACE_GROUP_LOCAL } from '../../../services/sessions/common/session.js';
|
||||
import { ISession, IChat, ISessionRepository, ISessionWorkspace, SessionStatus, GITHUB_REMOTE_FILE_SCHEME, IGitHubInfo, CopilotCLISessionType, CopilotCloudSessionType, ClaudeCodeSessionType, ISessionType, ISessionWorkspaceBrowseAction, ISessionFileChange, toSessionId, SESSION_WORKSPACE_GROUP_LOCAL, ISessionChangeset } from '../../../services/sessions/common/session.js';
|
||||
import { ChatAgentLocation, ChatConfiguration, ChatModeKind, ChatPermissionLevel, isChatPermissionLevel } from '../../../../workbench/contrib/chat/common/constants.js';
|
||||
import { basename, dirname, isEqual } from '../../../../base/common/resources.js';
|
||||
import { ISendRequestOptions, ISessionChangeEvent, ISessionsProvider } from '../../../services/sessions/common/sessionsProvider.js';
|
||||
@@ -71,6 +71,8 @@ export interface ICopilotChatSession {
|
||||
readonly updatedAt: IObservable<Date>;
|
||||
/** Current session status. */
|
||||
readonly status: IObservable<SessionStatus>;
|
||||
/** File changesets produced by the session. */
|
||||
readonly changesets: IObservable<readonly ISessionChangeset[]>;
|
||||
/** File changes produced by the session. */
|
||||
readonly changes: IObservable<readonly ISessionFileChange[]>;
|
||||
/** Currently selected model identifier. */
|
||||
@@ -180,6 +182,9 @@ class CopilotCLISession extends Disposable implements ICopilotChatSession {
|
||||
private readonly _loading = observableValue(this, true);
|
||||
readonly loading: IObservable<boolean> = this._loading;
|
||||
|
||||
private readonly _changesets: ReturnType<typeof observableValue<readonly ISessionChangeset[]>>;
|
||||
readonly changesets: IObservable<readonly ISessionChangeset[]>;
|
||||
|
||||
private readonly _changes: ReturnType<typeof observableValue<readonly ISessionFileChange[]>>;
|
||||
readonly changes: IObservable<readonly ISessionFileChange[]>;
|
||||
|
||||
@@ -259,6 +264,9 @@ class CopilotCLISession extends Disposable implements ICopilotChatSession {
|
||||
this._description = observableValue(this, undefined);
|
||||
this.description = this._description;
|
||||
|
||||
this._changesets = observableValue<readonly ISessionChangeset[]>(this, []);
|
||||
this.changesets = this._changesets;
|
||||
|
||||
this._changes = observableValue<readonly ISessionFileChange[]>(this, []);
|
||||
this.changes = this._changes;
|
||||
}
|
||||
@@ -416,6 +424,7 @@ class CopilotCLISession extends Disposable implements ICopilotChatSession {
|
||||
this._title.set(session.title.get(), undefined);
|
||||
this._status.set(session.status.get(), undefined);
|
||||
this._updatedAt.set(session.updatedAt.get(), undefined);
|
||||
this._changesets.set(session.changesets.get(), undefined);
|
||||
this._changes.set(session.changes.get(), undefined);
|
||||
this._description.set(session.description.get(), undefined);
|
||||
}
|
||||
@@ -463,6 +472,7 @@ export class RemoteNewSession extends Disposable implements ICopilotChatSession
|
||||
private readonly _workspaceData = observableValue<ISessionWorkspace | undefined>(this, undefined);
|
||||
readonly workspace: IObservable<ISessionWorkspace | undefined> = this._workspaceData;
|
||||
|
||||
readonly changesets: IObservable<readonly ISessionChangeset[]> = observableValue<readonly ISessionChangeset[]>(this, []);
|
||||
readonly changes: IObservable<readonly ISessionFileChange[]> = observableValue<readonly ISessionFileChange[]>(this, []);
|
||||
|
||||
private readonly _modelIdObservable = observableValue<string | undefined>(this, undefined);
|
||||
@@ -705,6 +715,7 @@ class ClaudeCodeNewSession extends Disposable implements ICopilotChatSession {
|
||||
private readonly _workspaceData = observableValue<ISessionWorkspace | undefined>(this, undefined);
|
||||
readonly workspace: IObservable<ISessionWorkspace | undefined> = this._workspaceData;
|
||||
|
||||
readonly changesets: IObservable<readonly ISessionChangeset[]> = observableValue<readonly ISessionChangeset[]>(this, []);
|
||||
readonly changes: IObservable<readonly ISessionFileChange[]> = observableValue<readonly ISessionFileChange[]>(this, []);
|
||||
|
||||
private readonly _modelIdObservable = observableValue<string | undefined>(this, undefined);
|
||||
@@ -844,6 +855,9 @@ class AgentSessionAdapter implements ICopilotChatSession {
|
||||
private readonly _status: ReturnType<typeof observableValue<SessionStatus>>;
|
||||
readonly status: IObservable<SessionStatus>;
|
||||
|
||||
private readonly _changesets: ReturnType<typeof observableValue<readonly ISessionChangeset[]>>;
|
||||
readonly changesets: IObservable<readonly ISessionChangeset[]>;
|
||||
|
||||
private readonly _changes: ReturnType<typeof observableValue<readonly ISessionFileChange[]>>;
|
||||
readonly changes: IObservable<readonly ISessionFileChange[]>;
|
||||
|
||||
@@ -896,6 +910,9 @@ class AgentSessionAdapter implements ICopilotChatSession {
|
||||
this._status = observableValue(this, toSessionStatus(session.status));
|
||||
this.status = this._status;
|
||||
|
||||
this._changesets = observableValue<readonly ISessionChangeset[]>(this, this._extractChangesets(session));
|
||||
this.changesets = this._changesets;
|
||||
|
||||
this._changes = observableValue<readonly ISessionFileChange[]>(this, this._extractChanges(session));
|
||||
this.changes = this._changes;
|
||||
|
||||
@@ -1094,6 +1111,10 @@ class AgentSessionAdapter implements ICopilotChatSession {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private _extractChangesets(session: IAgentSession): readonly ISessionChangeset[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
private _extractChanges(session: IAgentSession): readonly ISessionFileChange[] {
|
||||
if (!session.changes) {
|
||||
return [];
|
||||
@@ -2593,6 +2614,7 @@ export class CopilotChatSessionsProvider extends Disposable implements ISessions
|
||||
title: primaryChat.title,
|
||||
updatedAt: chatsObs.map((chats, reader) => this._latestDate(chats, c => c.updatedAt.read(reader))!),
|
||||
status: chatsObs.map((chats, reader) => this._aggregateStatus(chats, reader)),
|
||||
changesets: primaryChat.changesets,
|
||||
changes: primaryChat.changes,
|
||||
modelId: primaryChat.modelId,
|
||||
mode: primaryChat.mode,
|
||||
@@ -2623,6 +2645,7 @@ export class CopilotChatSessionsProvider extends Disposable implements ISessions
|
||||
title: chat.title,
|
||||
updatedAt: chat.updatedAt,
|
||||
status: chat.status,
|
||||
changesets: chat.changesets,
|
||||
changes: chat.changes,
|
||||
modelId: chat.modelId,
|
||||
mode: chat.mode,
|
||||
@@ -2645,6 +2668,7 @@ export class CopilotChatSessionsProvider extends Disposable implements ISessions
|
||||
title: chat.title,
|
||||
updatedAt: chat.updatedAt,
|
||||
status: chat.status,
|
||||
changesets: chat.changesets,
|
||||
changes: chat.changes,
|
||||
modelId: chat.modelId,
|
||||
mode: chat.mode,
|
||||
|
||||
@@ -15,7 +15,7 @@ import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/tes
|
||||
import { mock } from '../../../../../base/test/common/mock.js';
|
||||
import { GitHubPullRequestPollingContribution } from '../../browser/github.contribution.js';
|
||||
import { IGitHubService } from '../../browser/githubService.js';
|
||||
import { IChat, IGitHubInfo, ISession, ISessionCapabilities, ISessionFileChange, ISessionWorkspace, SessionStatus } from '../../../../services/sessions/common/session.js';
|
||||
import { IChat, IGitHubInfo, ISession, ISessionCapabilities, ISessionChangeset, ISessionFileChange, ISessionWorkspace, SessionStatus } from '../../../../services/sessions/common/session.js';
|
||||
import { IActiveSession, ISessionsChangeEvent, ISessionsManagementService } from '../../../../services/sessions/common/sessionsManagement.js';
|
||||
|
||||
suite('GitHubPullRequestPollingContribution', () => {
|
||||
@@ -152,6 +152,7 @@ class TestSession implements ISession {
|
||||
readonly title: ReturnType<typeof observableValue<string>>;
|
||||
readonly updatedAt: ReturnType<typeof observableValue<Date>>;
|
||||
readonly status: ReturnType<typeof observableValue<SessionStatus>>;
|
||||
readonly changesets: ReturnType<typeof observableValue<readonly ISessionChangeset[]>>;
|
||||
readonly changes: ReturnType<typeof observableValue<readonly ISessionFileChange[]>>;
|
||||
readonly workspace: ReturnType<typeof observableValue<ISessionWorkspace | undefined>>;
|
||||
readonly modelId: ReturnType<typeof observableValue<string | undefined>>;
|
||||
@@ -172,6 +173,7 @@ class TestSession implements ISession {
|
||||
this.title = observableValue<string>(`test.title.${id}`, id);
|
||||
this.updatedAt = observableValue<Date>(`test.updatedAt.${id}`, new Date(0));
|
||||
this.status = observableValue<SessionStatus>(`test.status.${id}`, SessionStatus.Completed);
|
||||
this.changesets = observableValue<readonly ISessionChangeset[]>(`test.changesets.${id}`, []);
|
||||
this.changes = observableValue<readonly ISessionFileChange[]>(`test.changes.${id}`, []);
|
||||
this.workspace = observableValue<ISessionWorkspace | undefined>(`test.workspace.${id}`, undefined);
|
||||
this.modelId = observableValue<string | undefined>(`test.modelId.${id}`, undefined);
|
||||
@@ -188,6 +190,7 @@ class TestSession implements ISession {
|
||||
title: this.title,
|
||||
updatedAt: this.updatedAt,
|
||||
status: this.status,
|
||||
changesets: this.changesets,
|
||||
changes: this.changes,
|
||||
modelId: this.modelId,
|
||||
mode: this.mode,
|
||||
|
||||
@@ -35,6 +35,7 @@ function createSession(id: string, opts: {
|
||||
title: observableValue(`title-${id}`, id),
|
||||
updatedAt: observableValue(`updatedAt-${id}`, updatedAt),
|
||||
status: observableValue(`status-${id}`, SessionStatus.Completed),
|
||||
changesets: observableValue(`changesets-${id}`, []),
|
||||
changes: observableValue(`changes-${id}`, []),
|
||||
modelId: observableValue(`modelId-${id}`, undefined),
|
||||
mode: observableValue(`mode-${id}`, undefined),
|
||||
|
||||
@@ -28,6 +28,7 @@ function createSession(id: string): ISession {
|
||||
title: observableValue(`title-${id}`, id),
|
||||
updatedAt: observableValue(`updatedAt-${id}`, new Date()),
|
||||
status: observableValue(`status-${id}`, SessionStatus.Completed),
|
||||
changesets: observableValue(`changesets-${id}`, []),
|
||||
changes: observableValue(`changes-${id}`, []),
|
||||
modelId: observableValue(`modelId-${id}`, undefined),
|
||||
mode: observableValue(`mode-${id}`, undefined),
|
||||
|
||||
@@ -64,6 +64,7 @@ function makeAgentSession(opts: {
|
||||
title: observableValue('test.title', 'Test Session'),
|
||||
updatedAt: observableValue('test.updatedAt', new Date()),
|
||||
status: observableValue('test.status', 0),
|
||||
changesets: observableValue('test.changesets', []),
|
||||
changes: observableValue('test.changes', []),
|
||||
modelId: observableValue('test.modelId', undefined),
|
||||
mode: observableValue('test.mode', undefined),
|
||||
@@ -83,6 +84,7 @@ function makeAgentSession(opts: {
|
||||
title: chat.title,
|
||||
updatedAt: chat.updatedAt,
|
||||
status: chat.status,
|
||||
changesets: chat.changesets,
|
||||
changes: chat.changes,
|
||||
modelId: chat.modelId,
|
||||
mode: chat.mode,
|
||||
@@ -113,6 +115,7 @@ function makeNonAgentSession(opts: { repository?: URI; worktree?: URI; providerT
|
||||
title: observableValue('test.title', 'Test Session'),
|
||||
updatedAt: observableValue('test.updatedAt', new Date()),
|
||||
status: observableValue('test.status', 0),
|
||||
changesets: observableValue('test.changesets', []),
|
||||
changes: observableValue('test.changes', []),
|
||||
modelId: observableValue('test.modelId', undefined),
|
||||
mode: observableValue('test.mode', undefined),
|
||||
@@ -132,6 +135,7 @@ function makeNonAgentSession(opts: { repository?: URI; worktree?: URI; providerT
|
||||
title: chat.title,
|
||||
updatedAt: chat.updatedAt,
|
||||
status: chat.status,
|
||||
changesets: chat.changesets,
|
||||
changes: chat.changes,
|
||||
modelId: chat.modelId,
|
||||
mode: chat.mode,
|
||||
|
||||
@@ -150,6 +150,19 @@ export interface IGitHubInfo {
|
||||
|
||||
export type ISessionFileChange = IChatSessionFileChange | IChatSessionFileChange2;
|
||||
|
||||
export interface ISessionChangeset {
|
||||
/** Unique identifier for the changeset. */
|
||||
readonly id: string;
|
||||
/** Display label for the changeset. */
|
||||
readonly label: string;
|
||||
/** Optional description for the changeset. */
|
||||
readonly description?: string;
|
||||
/** Whether the changeset is enabled. */
|
||||
readonly enabled: IObservable<boolean>;
|
||||
/** File changes associated with this changeset. */
|
||||
readonly changes: IObservable<readonly ISessionFileChange[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A single chat within a session, produced by the sessions management layer.
|
||||
*/
|
||||
@@ -169,6 +182,8 @@ export interface IChat {
|
||||
readonly status: IObservable<SessionStatus>;
|
||||
/** File changes produced by the chat. */
|
||||
readonly changes: IObservable<readonly ISessionFileChange[]>;
|
||||
/** Changesets produced by the chat. */
|
||||
readonly changesets: IObservable<readonly ISessionChangeset[]>;
|
||||
/** Currently selected model identifier. */
|
||||
readonly modelId: IObservable<string | undefined>;
|
||||
/** Currently selected mode identifier and kind. */
|
||||
@@ -213,6 +228,8 @@ export interface ISession {
|
||||
readonly status: IObservable<SessionStatus>;
|
||||
/** File changes produced by the session. */
|
||||
readonly changes: IObservable<readonly ISessionFileChange[]>;
|
||||
/** Changesets produced by the session. */
|
||||
readonly changesets: IObservable<readonly ISessionChangeset[]>;
|
||||
/** Currently selected model identifier. */
|
||||
readonly modelId: IObservable<string | undefined>;
|
||||
/** Currently selected mode identifier and kind. */
|
||||
|
||||
@@ -18,6 +18,7 @@ const stubChat: IChat = {
|
||||
title: constObservable('Chat'),
|
||||
updatedAt: constObservable(new Date()),
|
||||
status: constObservable(0),
|
||||
changesets: constObservable([]),
|
||||
changes: constObservable([]),
|
||||
modelId: constObservable(undefined),
|
||||
mode: constObservable(undefined),
|
||||
@@ -37,6 +38,7 @@ function stubSession(overrides: Partial<ISession> & Pick<ISession, 'sessionId' |
|
||||
title: constObservable('Test'),
|
||||
updatedAt: constObservable(new Date()),
|
||||
status: constObservable(0),
|
||||
changesets: constObservable([]),
|
||||
changes: constObservable([]),
|
||||
modelId: constObservable(undefined),
|
||||
mode: constObservable(undefined),
|
||||
|
||||
Reference in New Issue
Block a user