Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V1 new client extension API, for inline edits + document code #3445

Merged
merged 18 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@
"outFiles": ["${workspaceFolder}/vscode/dist/**/*.js"],
"args": ["--extensionDevelopmentPath=${workspaceRoot}/vscode", "--extensionDevelopmentKind=web"]
},
{
"name": "Attach to Agent",
"port": 9229,
"request": "attach",
"skipFiles": ["<node_internals>/**"],
"type": "node"
},
{
"type": "node",
"request": "launch",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ interface CodyAgentClient {
// =============
@JsonNotification("debug/message")
fun debug_message(params: DebugMessage)
@JsonNotification("editTaskState/didChange")
fun editTaskState_didChange(params: EditTask)
@JsonNotification("editTask/didUpdate")
fun editTask_didUpdate(params: EditTask)
@JsonNotification("editTask/didDelete")
fun editTask_didDelete(params: EditTask)
@JsonNotification("codeLenses/display")
fun codeLenses_display(params: DisplayCodeLensParams)
@JsonNotification("webview/postMessage")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,20 @@ interface CodyAgentServer {
fun commands_smell(params: Null): CompletableFuture<String>
@JsonRequest("commands/custom")
fun commands_custom(params: Commands_CustomParams): CompletableFuture<CustomCommandResult>
@JsonRequest("editCommands/code")
fun editCommands_code(params: EditCommands_CodeParams): CompletableFuture<EditTask>
@JsonRequest("editCommands/test")
fun editCommands_test(params: Null): CompletableFuture<EditTask>
@JsonRequest("commands/document")
fun commands_document(params: Null): CompletableFuture<EditTask>
@JsonRequest("editTask/accept")
fun editTask_accept(params: FixupTaskID): CompletableFuture<Null>
@JsonRequest("editTask/undo")
fun editTask_undo(params: FixupTaskID): CompletableFuture<Null>
@JsonRequest("editTask/cancel")
fun editTask_cancel(params: FixupTaskID): CompletableFuture<Null>
@JsonRequest("editTask/getFoldingRanges")
fun editTask_getFoldingRanges(params: GetFoldingRangeParams): CompletableFuture<GetFoldingRangeResult>
@JsonRequest("command/execute")
fun command_execute(params: ExecuteCommandParams): CompletableFuture<Any>
@JsonRequest("autocomplete/execute")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@file:Suppress("FunctionName", "ClassName", "unused", "EnumEntryName", "UnusedImport")
package com.sourcegraph.cody.protocol_generated

data class EditCommands_CodeParams(
val params: ParamsParams? = null,
)

Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ data class EditTask(
val id: String? = null,
val state: CodyTaskState? = null,
val error: CodyError? = null,
val selectionRange: Range? = null,
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@file:Suppress("FunctionName", "ClassName", "unused", "EnumEntryName", "UnusedImport")
package com.sourcegraph.cody.protocol_generated

typealias FixupTaskID = String // One of:

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@file:Suppress("FunctionName", "ClassName", "unused", "EnumEntryName", "UnusedImport")
package com.sourcegraph.cody.protocol_generated

data class GetFoldingRangeParams(
val uri: String? = null,
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@file:Suppress("FunctionName", "ClassName", "unused", "EnumEntryName", "UnusedImport")
package com.sourcegraph.cody.protocol_generated

data class GetFoldingRangeResult(
val ranges: List<Range>? = null,
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@file:Suppress("FunctionName", "ClassName", "unused", "EnumEntryName", "UnusedImport")
package com.sourcegraph.cody.protocol_generated

data class ParamsParams(
val instruction: String? = null,
)

2 changes: 1 addition & 1 deletion agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"build": "pnpm run build:root && pnpm run build:agent",
"build-minify": "pnpm run build --minify",
"agent": "pnpm run build && node dist/index.js",
"agent:debug": "pnpm run build && node --inspect --enable-source-maps ./dist/index.js",
"agent:debug": "pnpm run build && CODY_AGENT_TRACE_PATH=/tmp/agent.json CODY_AGENT_DEBUG_REMOTE=true node --enable-source-maps ./dist/index.js",
"build-ts": "tsc --build",
"build-agent-binaries": "pnpm run build && pkg --compress GZip --no-bytecode --public-packages \"*\" --public . --out-path ${AGENT_EXECUTABLE_TARGET_DIRECTORY:-dist}",
"test-agent-binary": "esbuild ./scripts/test-agent-binary.ts --bundle --platform=node --alias:vscode=./src/vscode-shim.ts --outdir=dist && node ./dist/test-agent-binary.js",
Expand Down
56 changes: 56 additions & 0 deletions agent/src/AgentFixupControls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { FixupFile } from '../../vscode/src/non-stop/FixupFile'
import type { FixupTask, FixupTaskID } from '../../vscode/src/non-stop/FixupTask'
import type { FixupActor, FixupFileCollection } from '../../vscode/src/non-stop/roles'
import type { FixupControlApplicator } from '../../vscode/src/non-stop/strategies'
import { type Agent, errorToCodyError } from './agent'
import type { EditTask } from './protocol-alias'

export class AgentFixupControls implements FixupControlApplicator {
constructor(
private readonly fixups: FixupActor & FixupFileCollection,
private readonly notify: typeof Agent.prototype.notify
) {}

public accept(id: FixupTaskID): void {
const task = this.fixups.taskForId(id)
if (task) {
this.fixups.accept(task)
}
}

public undo(id: FixupTaskID): void {
const task = this.fixups.taskForId(id)
if (task) {
this.fixups.undo(task)
}
}

public cancel(id: FixupTaskID): void {
const task = this.fixups.taskForId(id)
if (task) {
this.fixups.cancel(task)
}
}

// FixupControlApplicator

didUpdateTask(task: FixupTask): void {
this.notify('editTask/didUpdate', AgentFixupControls.serialize(task))
}
didDeleteTask(task: FixupTask): void {
this.notify('editTask/didDelete', AgentFixupControls.serialize(task))
}

visibleFilesWithTasksMaybeChanged(files: readonly FixupFile[]): void {}

dispose() {}

public static serialize(task: FixupTask): EditTask {
return {
id: task.id,
state: task.state,
error: errorToCodyError(task.error),
selectionRange: task.selectionRange,
}
}
}
68 changes: 45 additions & 23 deletions agent/src/TestClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,33 +343,52 @@ export class TestClient extends MessageHandler {
)
}

let disposable: vscode.Disposable
let disposables: vscode.Disposable[]
return new Promise<void>((resolve, reject) => {
disposable = this.onDidChangeTaskState(({ id, state, error }) => {
if (id === params.id) {
switch (state) {
case CodyTaskState.applied:
return resolve()
case CodyTaskState.error:
case CodyTaskState.finished:
return reject(
new Error(
`Task reached terminal state before being applied ${JSON.stringify({
id,
state: CodyTaskState[state],
error,
})}`
disposables = [
this.onDidUpdateTask(({ id, state, error }) => {
if (id === params.id) {
switch (state) {
case CodyTaskState.applied:
return resolve()
case CodyTaskState.error:
case CodyTaskState.finished:
return reject(
new Error(
`Task reached terminal state before being applied ${JSON.stringify(
{
id,
state: CodyTaskState[state],
error,
}
)}`
)
)
)
}
}
}
})
}).finally(() => disposable.dispose())
}),
this.onDidDeleteTask(task => {
if (task.id === params.id) {
// Applied tasks can also be deleted, but in that case
// the Promise is already resolved and this is a no-op.
reject(
new Error(`Task was deleted before being applied ${JSON.stringify(task)}`)
)
}
}),
]
}).finally(() => {
for (const disposable of disposables) {
disposable.dispose()
}
})
}

public codeLenses = new Map<string, ProtocolCodeLens[]>()
public newTaskState = new vscode.EventEmitter<EditTask>()
public onDidChangeTaskState = this.newTaskState.event
public taskUpdate = new vscode.EventEmitter<EditTask>()
public onDidUpdateTask = this.taskUpdate.event
public taskDelete = new vscode.EventEmitter<EditTask>()
public onDidDeleteTask = this.taskDelete.event
public webviewMessages: WebviewPostMessageParams[] = []
public webviewMessagesEmitter = new vscode.EventEmitter<WebviewPostMessageParams>()

Expand Down Expand Up @@ -416,8 +435,11 @@ export class TestClient extends MessageHandler {
this.connectProcess(this.agentProcess, error => {
console.error(error)
})
this.registerNotification('editTaskState/didChange', params => {
this.newTaskState.fire(params)
this.registerNotification('editTask/didUpdate', params => {
this.taskUpdate.fire(params)
})
this.registerNotification('editTask/didDelete', params => {
this.taskDelete.fire(params)
})

this.registerNotification('webview/postMessage', params => {
Expand Down
Loading
Loading