Skip to content

Commit

Permalink
feat: add auto start action for markdown
Browse files Browse the repository at this point in the history
  • Loading branch information
2214962083 committed Jan 8, 2025
1 parent b1e47b8 commit e0db298
Show file tree
Hide file tree
Showing 65 changed files with 564 additions and 428 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@
"@types/react-dom": "^19.0.2",
"@types/shell-quote": "^1.7.5",
"@types/turndown": "^5.0.5",
"@types/vscode": "1.93.0",
"@types/vscode": "1.96.0",
"@types/vscode-webview": "^1.57.5",
"@typescript-eslint/eslint-plugin": "^7.17.0",
"@typescript-eslint/parser": "^7.17.0",
Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

126 changes: 50 additions & 76 deletions src/extension/actions/agent-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,23 @@ import type { AgentServerUtilsProvider } from '@shared/plugins/agents/_base/serv
import { produce } from 'immer'
import type { DraftFunction } from 'use-immer'

export type SingleSessionActionParams<
ActionType extends ConversationAction = ConversationAction
> = {
chatContext: ChatContext
conversation: Conversation
action: ActionType
autoRefresh?: boolean
}

export type MultipleSessionActionParams<
ActionType extends ConversationAction = ConversationAction
> = {
chatContext: ChatContext
actionItems: { conversation: Conversation; action: ActionType }[]
autoRefresh?: boolean
}

export class AgentActionsCollection extends ServerActionCollection {
readonly categoryName = 'agent'

Expand Down Expand Up @@ -48,17 +65,13 @@ export class AgentActionsCollection extends ServerActionCollection {
}

private async handleAction(
context: ActionContext<{
chatContext: ChatContext
conversation: Conversation
action: ConversationAction
autoRefresh?: boolean
}>,
context: ActionContext<SingleSessionActionParams>,
handlerType:
| 'onAcceptAction'
| 'onRejectAction'
| 'onStartAction'
| 'onRestartAction'
| 'onRefreshAction'
) {
const { action, autoRefresh = true } = context.actionParams
const provider = this.getAgentServerUtilsProvider(action.agent?.name)
Expand All @@ -71,15 +84,8 @@ export class AgentActionsCollection extends ServerActionCollection {
}

private async handleMultipleActions(
context: ActionContext<{
chatContext: ChatContext
actionItems: {
conversation: Conversation
action: ConversationAction
}[]
autoRefresh?: boolean
}>,
handlerType: 'acceptAction' | 'rejectAction'
context: ActionContext<MultipleSessionActionParams>,
handlerType: 'acceptAction' | 'rejectAction' | 'refreshAction'
) {
const {
chatContext,
Expand Down Expand Up @@ -112,73 +118,41 @@ export class AgentActionsCollection extends ServerActionCollection {
)
}

async acceptAction(
context: ActionContext<{
chatContext: ChatContext
conversation: Conversation
action: ConversationAction
autoRefresh?: boolean
}>
) {
async acceptAction(context: ActionContext<SingleSessionActionParams>) {
await this.handleAction(context, 'onAcceptAction')
}

async rejectAction(
context: ActionContext<{
chatContext: ChatContext
conversation: Conversation
action: ConversationAction
autoRefresh?: boolean
}>
) {
async rejectAction(context: ActionContext<SingleSessionActionParams>) {
await this.handleAction(context, 'onRejectAction')
}

async refreshAction(context: ActionContext<SingleSessionActionParams>) {
await this.handleAction(context, 'onRefreshAction')
}

async acceptMultipleActions(
context: ActionContext<{
chatContext: ChatContext
actionItems: {
conversation: Conversation
action: ConversationAction
}[]
autoRefresh?: boolean
}>
context: ActionContext<MultipleSessionActionParams>
) {
await this.handleMultipleActions(context, 'acceptAction')
}

async rejectMultipleActions(
context: ActionContext<{
chatContext: ChatContext
actionItems: {
conversation: Conversation
action: ConversationAction
}[]
autoRefresh?: boolean
}>
context: ActionContext<MultipleSessionActionParams>
) {
await this.handleMultipleActions(context, 'rejectAction')
}

async startAction(
context: ActionContext<{
chatContext: ChatContext
conversation: Conversation
action: ConversationAction
autoRefresh?: boolean
}>
async refreshMultipleActions(
context: ActionContext<MultipleSessionActionParams>
) {
await this.handleMultipleActions(context, 'refreshAction')
}

async startAction(context: ActionContext<SingleSessionActionParams>) {
await this.handleAction(context, 'onStartAction')
}

async restartAction(
context: ActionContext<{
chatContext: ChatContext
conversation: Conversation
action: ConversationAction
autoRefresh?: boolean
}>
) {
async restartAction(context: ActionContext<SingleSessionActionParams>) {
await this.handleAction(context, 'onRestartAction')
}

Expand All @@ -188,13 +162,15 @@ export class AgentActionsCollection extends ServerActionCollection {
conversation: Conversation
action: ConversationAction
updater: ConversationAction | DraftFunction<ConversationAction>
autoRefresh?: boolean
}>
) {
const {
chatContext: oldChatContext,
conversation,
action,
updater
updater,
autoRefresh = false
} = context.actionParams

const chatContext = await runAction(
Expand All @@ -213,25 +189,19 @@ export class AgentActionsCollection extends ServerActionCollection {

if (conversationIndex === -1) throw new Error('Conversation not found')

const actionIndex = chatContext.conversations[
let actionIndex = chatContext.conversations[
conversationIndex
]!.actions.findIndex(a => a.id === action.id)

if (actionIndex === -1) throw new Error('Action not found')

const currentChatContext = await runAction(
this.registerManager
).server.chatSession.getChatContext({
actionParams: {
sessionId: chatContext.id
const newChatContext = produce(chatContext, draft => {
if (actionIndex === -1) {
draft!.conversations[conversationIndex]!.actions.push(action)
actionIndex =
draft!.conversations[conversationIndex]!.actions.length - 1
}
})

const newChatContext = produce(currentChatContext, draft => {
const action =
draft!.conversations[conversationIndex]!.actions[actionIndex]!
if (typeof updater === 'function') {
updater(action)
updater(draft!.conversations[conversationIndex]!.actions[actionIndex]!)
} else {
draft!.conversations[conversationIndex]!.actions[actionIndex] = updater
}
Expand All @@ -243,5 +213,9 @@ export class AgentActionsCollection extends ServerActionCollection {
chatContext: newChatContext!
}
})

if (autoRefresh) {
await this.refreshChatSession()
}
}
}
66 changes: 51 additions & 15 deletions src/extension/actions/apply-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ModelProviderFactory } from '@extension/ai/model-providers/helpers/fact
import { VsCodeFS } from '@extension/file-utils/vscode-fs'
import { InlineDiffRegister } from '@extension/registers/inline-diff-register'
import { TaskEntity } from '@extension/registers/inline-diff-register/task-entity'
import type { InlineDiffTask } from '@extension/registers/inline-diff-register/types'
import type { InlineDiffTaskJson } from '@extension/registers/inline-diff-register/types'
import { HumanMessage, SystemMessage } from '@langchain/core/messages'
import { ServerActionCollection } from '@shared/actions/server-action-collection'
import type { ActionContext } from '@shared/actions/types'
Expand All @@ -23,8 +23,9 @@ export class ApplyActionsCollection extends ServerActionCollection {
code: string
selectionRange?: vscode.Range
cleanLast?: boolean
onTaskChange?: (task: InlineDiffTaskJson) => void
}>
): AsyncGenerator<InlineDiffTask, void, unknown> {
): AsyncGenerator<InlineDiffTaskJson, void, unknown> {
const { abortController, actionParams } = context
const { path, code, selectionRange, cleanLast } = actionParams
if (!path || !code || !this.inlineDiffProvider)
Expand Down Expand Up @@ -76,22 +77,57 @@ Don't reply with anything except the code.
)
const finalSelectionRange = selectionRange || fullRange

yield await this.inlineDiffProvider.createTask(
this.inlineDiffProvider.taskChangeEmitter.event(task => {
if (task.id === taskId) {
context.actionParams.onTaskChange?.(task)
}
})

yield TaskEntity.toJson(
await this.inlineDiffProvider.createTask(
taskId,
uri,
finalSelectionRange,
'',
abortController
)
)

const streamTask = await this.inlineDiffProvider.startStreamTask(
taskId,
uri,
finalSelectionRange,
'',
abortController
buildAiStream
)

yield* await this.inlineDiffProvider.startStreamTask(taskId, buildAiStream)
for await (const task of streamTask) {
yield TaskEntity.toJson(task)
}
}

async refreshApplyCodeTask(
context: ActionContext<{
task: InlineDiffTaskJson
}>
): Promise<InlineDiffTaskJson | null> {
const { actionParams } = context
const task = TaskEntity.fromJson({
...actionParams.task,
abortController: context.abortController
})

if (!this.inlineDiffProvider)
throw new Error('refreshApplyCodeTask: inlineDiffProvider not found')

const finalTask = this.inlineDiffProvider.taskManager.getTask(task.id)
if (!finalTask) return null

return TaskEntity.toJson(finalTask)
}

async acceptApplyCodeTask(
context: ActionContext<{
task: InlineDiffTask
task: InlineDiffTaskJson
}>
): Promise<InlineDiffTask> {
): Promise<InlineDiffTaskJson> {
const { actionParams } = context
const task = TaskEntity.fromJson({
...actionParams.task,
Expand All @@ -101,14 +137,14 @@ Don't reply with anything except the code.
if (!this.inlineDiffProvider)
throw new Error('acceptApplyCodeTask: inlineDiffProvider not found')

return this.inlineDiffProvider.acceptAll(task)
return TaskEntity.toJson(await this.inlineDiffProvider.acceptAll(task))
}

async rejectApplyCodeTask(
context: ActionContext<{
task: InlineDiffTask
task: InlineDiffTaskJson
}>
): Promise<InlineDiffTask> {
): Promise<InlineDiffTaskJson> {
const { actionParams } = context
const task = TaskEntity.fromJson({
...actionParams.task,
Expand All @@ -118,7 +154,7 @@ Don't reply with anything except the code.
if (!this.inlineDiffProvider)
throw new Error('rejectApplyCodeTask: inlineDiffProvider not found')

return this.inlineDiffProvider.rejectAll(task)
return TaskEntity.toJson(await this.inlineDiffProvider.rejectAll(task))
}

async abortAndCleanApplyCodeTaskByPath(
Expand All @@ -135,7 +171,7 @@ Don't reply with anything except the code.

async abortAndCleanApplyCodeTask(
context: ActionContext<{
task: InlineDiffTask
task: InlineDiffTaskJson
}>
): Promise<void> {
const { actionParams } = context
Expand Down
6 changes: 3 additions & 3 deletions src/extension/chat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import {
type Conversation
} from '@shared/entities'

import { AutoTaskStrategy } from './strategies/auto-task-strategy'
import type {
BaseStrategy,
BaseStrategyOptions
} from './strategies/base/base-strategy'
} from './strategies/_base/base-strategy'
import { AgentStrategy } from './strategies/agent-strategy'
import { ChatStrategy } from './strategies/chat-strategy'
import { ComposerStrategy } from './strategies/composer-strategy'
import { UIDesignerStrategy } from './strategies/ui-designer-strategy'
Expand Down Expand Up @@ -38,7 +38,7 @@ export class ChatContextProcessor {
[ChatContextType.Chat, new ChatStrategy(baseStrategyOptions)],
[ChatContextType.Composer, new ComposerStrategy(baseStrategyOptions)],
[ChatContextType.UIDesigner, new UIDesignerStrategy(baseStrategyOptions)],
[ChatContextType.AutoTask, new AutoTaskStrategy(baseStrategyOptions)]
[ChatContextType.Agent, new AgentStrategy(baseStrategyOptions)]
])
}

Expand Down
Loading

0 comments on commit e0db298

Please sign in to comment.