@theia/ai-codex 1.67.0-next.56 → 1.67.0-next.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/codex-chat-agent.d.ts +79 -0
- package/lib/browser/codex-chat-agent.d.ts.map +1 -0
- package/lib/browser/codex-chat-agent.js +556 -0
- package/lib/browser/codex-chat-agent.js.map +1 -0
- package/lib/browser/codex-chat-agent.spec.d.ts +2 -0
- package/lib/browser/codex-chat-agent.spec.d.ts.map +1 -0
- package/lib/browser/codex-chat-agent.spec.js +538 -0
- package/lib/browser/codex-chat-agent.spec.js.map +1 -0
- package/lib/browser/codex-frontend-module.d.ts +5 -0
- package/lib/browser/codex-frontend-module.d.ts.map +1 -0
- package/lib/browser/codex-frontend-module.js +52 -0
- package/lib/browser/codex-frontend-module.js.map +1 -0
- package/lib/browser/codex-frontend-service.d.ts +47 -0
- package/lib/browser/codex-frontend-service.d.ts.map +1 -0
- package/lib/browser/codex-frontend-service.js +194 -0
- package/lib/browser/codex-frontend-service.js.map +1 -0
- package/lib/browser/codex-frontend-service.spec.d.ts +2 -0
- package/lib/browser/codex-frontend-service.spec.d.ts.map +1 -0
- package/lib/browser/codex-frontend-service.spec.js +200 -0
- package/lib/browser/codex-frontend-service.spec.js.map +1 -0
- package/lib/browser/codex-tool-call-content.d.ts +9 -0
- package/lib/browser/codex-tool-call-content.d.ts.map +1 -0
- package/lib/browser/codex-tool-call-content.js +41 -0
- package/lib/browser/codex-tool-call-content.js.map +1 -0
- package/lib/browser/renderers/collapsible-tool-renderer.d.ts +13 -0
- package/lib/browser/renderers/collapsible-tool-renderer.d.ts.map +1 -0
- package/lib/browser/renderers/collapsible-tool-renderer.js +45 -0
- package/lib/browser/renderers/collapsible-tool-renderer.js.map +1 -0
- package/lib/browser/renderers/command-execution-renderer.d.ts +10 -0
- package/lib/browser/renderers/command-execution-renderer.d.ts.map +1 -0
- package/lib/browser/renderers/command-execution-renderer.js +74 -0
- package/lib/browser/renderers/command-execution-renderer.js.map +1 -0
- package/lib/browser/renderers/todo-list-renderer.d.ts +11 -0
- package/lib/browser/renderers/todo-list-renderer.d.ts.map +1 -0
- package/lib/browser/renderers/todo-list-renderer.js +106 -0
- package/lib/browser/renderers/todo-list-renderer.js.map +1 -0
- package/lib/browser/renderers/web-search-renderer.d.ts +10 -0
- package/lib/browser/renderers/web-search-renderer.d.ts.map +1 -0
- package/lib/browser/renderers/web-search-renderer.js +71 -0
- package/lib/browser/renderers/web-search-renderer.js.map +1 -0
- package/lib/common/codex-preferences.d.ts +4 -0
- package/lib/common/codex-preferences.d.ts.map +1 -0
- package/lib/common/codex-preferences.js +32 -0
- package/lib/common/codex-preferences.js.map +1 -0
- package/lib/common/codex-service.d.ts +23 -0
- package/lib/common/codex-service.d.ts.map +1 -0
- package/lib/common/codex-service.js +22 -0
- package/lib/common/codex-service.js.map +1 -0
- package/lib/common/index.d.ts +3 -0
- package/lib/common/index.d.ts.map +1 -0
- package/lib/common/index.js +21 -0
- package/lib/common/index.js.map +1 -0
- package/lib/node/codex-backend-module.d.ts +4 -0
- package/lib/node/codex-backend-module.d.ts.map +1 -0
- package/lib/node/codex-backend-module.js +35 -0
- package/lib/node/codex-backend-module.js.map +1 -0
- package/lib/node/codex-service-impl.d.ts +13 -0
- package/lib/node/codex-service-impl.d.ts.map +1 -0
- package/lib/node/codex-service-impl.js +97 -0
- package/lib/node/codex-service-impl.js.map +1 -0
- package/package.json +11 -11
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { ChatAgent, ChatAgentLocation, MutableChatRequestModel } from '@theia/ai-chat';
|
|
2
|
+
import { TokenUsageService } from '@theia/ai-core';
|
|
3
|
+
import { URI } from '@theia/core/lib/common/uri';
|
|
4
|
+
import type { ItemStartedEvent, ItemUpdatedEvent, ItemCompletedEvent, TurnCompletedEvent, TurnFailedEvent, ThreadEvent, ThreadItem, CommandExecutionItem, FileChangeItem, McpToolCallItem, WebSearchItem, Usage, TodoListItem } from '@openai/codex-sdk';
|
|
5
|
+
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
|
6
|
+
import { WorkspaceService } from '@theia/workspace/lib/browser';
|
|
7
|
+
import { ChangeSetFileElementFactory } from '@theia/ai-chat/lib/browser/change-set-file-element';
|
|
8
|
+
import { CodexToolCallChatResponseContent } from './codex-tool-call-content';
|
|
9
|
+
import { CodexFrontendService } from './codex-frontend-service';
|
|
10
|
+
export declare const CODEX_CHAT_AGENT_ID = "Codex";
|
|
11
|
+
export declare const CODEX_INPUT_TOKENS_KEY = "codexInputTokens";
|
|
12
|
+
export declare const CODEX_OUTPUT_TOKENS_KEY = "codexOutputTokens";
|
|
13
|
+
export declare const CODEX_TOOL_CALLS_KEY = "codexToolCalls";
|
|
14
|
+
type ToolInvocationItem = CommandExecutionItem | FileChangeItem | McpToolCallItem | WebSearchItem | TodoListItem;
|
|
15
|
+
/**
|
|
16
|
+
* Chat agent for OpenAI Codex integration.
|
|
17
|
+
*/
|
|
18
|
+
export declare class CodexChatAgent implements ChatAgent {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
description: string;
|
|
22
|
+
iconClass: string;
|
|
23
|
+
locations: ChatAgentLocation[];
|
|
24
|
+
tags: string[];
|
|
25
|
+
variables: string[];
|
|
26
|
+
prompts: [];
|
|
27
|
+
languageModelRequirements: [];
|
|
28
|
+
agentSpecificVariables: [];
|
|
29
|
+
functions: string[];
|
|
30
|
+
modes: {
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
}[];
|
|
34
|
+
protected codexService: CodexFrontendService;
|
|
35
|
+
protected tokenUsageService: TokenUsageService;
|
|
36
|
+
protected readonly fileService: FileService;
|
|
37
|
+
protected readonly workspaceService: WorkspaceService;
|
|
38
|
+
protected readonly fileChangeFactory: ChangeSetFileElementFactory;
|
|
39
|
+
invoke(request: MutableChatRequestModel): Promise<void>;
|
|
40
|
+
protected extractSandboxMode(modeId?: string): 'read-only' | 'workspace-write' | 'danger-full-access';
|
|
41
|
+
protected getToolCalls(request: MutableChatRequestModel): Map<string, CodexToolCallChatResponseContent>;
|
|
42
|
+
protected handleEvent(event: ThreadEvent, request: MutableChatRequestModel): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Type guard using discriminated union narrowing from SDK types.
|
|
45
|
+
*/
|
|
46
|
+
protected isToolInvocation(item: ThreadItem): item is ToolInvocationItem;
|
|
47
|
+
protected extractToolArguments(item: ToolInvocationItem): string;
|
|
48
|
+
/**
|
|
49
|
+
* Creates a pending tool call that will be updated when the item completes.
|
|
50
|
+
*/
|
|
51
|
+
protected handleItemStarted(event: ItemStartedEvent, request: MutableChatRequestModel): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Updates the pending tool call with new data, especially for todo_list items.
|
|
54
|
+
*/
|
|
55
|
+
protected handleItemUpdated(event: ItemUpdatedEvent, request: MutableChatRequestModel): Promise<void>;
|
|
56
|
+
protected findMatchingToolCall(item: ToolInvocationItem, toolCalls: Map<string, CodexToolCallChatResponseContent>): [string, CodexToolCallChatResponseContent] | undefined;
|
|
57
|
+
protected getFileChangeOriginals(request: MutableChatRequestModel): Map<string, Map<string, string>>;
|
|
58
|
+
/**
|
|
59
|
+
* Snapshot the original contents for files that Codex is about to modify so we can populate the change set later.
|
|
60
|
+
*/
|
|
61
|
+
protected captureFileChangeOriginals(item: FileChangeItem, request: MutableChatRequestModel): Promise<void>;
|
|
62
|
+
protected handleFileChangeCompleted(item: FileChangeItem, request: MutableChatRequestModel): Promise<boolean>;
|
|
63
|
+
protected normalizeRelativePath(path: string, rootUri?: URI): string | undefined;
|
|
64
|
+
protected ensureTrailingSlash(path: string): string;
|
|
65
|
+
protected resolveFileUri(rootUri: URI, relativePath: string): URI | undefined;
|
|
66
|
+
protected getWorkspaceRootUri(): Promise<URI | undefined>;
|
|
67
|
+
protected handleItemCompleted(event: ItemCompletedEvent, request: MutableChatRequestModel): Promise<void>;
|
|
68
|
+
protected handleTurnCompleted(event: TurnCompletedEvent, request: MutableChatRequestModel): void;
|
|
69
|
+
protected handleTurnFailed(event: TurnFailedEvent, request: MutableChatRequestModel): void;
|
|
70
|
+
protected updateTokens(request: MutableChatRequestModel, inputTokens: number, outputTokens: number): void;
|
|
71
|
+
protected updateSessionSuggestion(request: MutableChatRequestModel): void;
|
|
72
|
+
protected getSessionTotalTokens(request: MutableChatRequestModel): {
|
|
73
|
+
inputTokens: number;
|
|
74
|
+
outputTokens: number;
|
|
75
|
+
};
|
|
76
|
+
protected reportTokenUsage(request: MutableChatRequestModel, usage: Usage): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
export {};
|
|
79
|
+
//# sourceMappingURL=codex-chat-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-chat-agent.d.ts","sourceRoot":"","sources":["../../src/browser/codex-chat-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,556 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2025 EclipseSource GmbH.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.CodexChatAgent = exports.CODEX_TOOL_CALLS_KEY = exports.CODEX_OUTPUT_TOKENS_KEY = exports.CODEX_INPUT_TOKENS_KEY = exports.CODEX_CHAT_AGENT_ID = void 0;
|
|
19
|
+
const tslib_1 = require("tslib");
|
|
20
|
+
const ai_chat_1 = require("@theia/ai-chat");
|
|
21
|
+
const ai_core_1 = require("@theia/ai-core");
|
|
22
|
+
const prompt_text_1 = require("@theia/ai-core/lib/common/prompt-text");
|
|
23
|
+
const core_1 = require("@theia/core");
|
|
24
|
+
const uri_1 = require("@theia/core/lib/common/uri");
|
|
25
|
+
const inversify_1 = require("@theia/core/shared/inversify");
|
|
26
|
+
const file_service_1 = require("@theia/filesystem/lib/browser/file-service");
|
|
27
|
+
const browser_1 = require("@theia/workspace/lib/browser");
|
|
28
|
+
const change_set_file_element_1 = require("@theia/ai-chat/lib/browser/change-set-file-element");
|
|
29
|
+
const codex_tool_call_content_1 = require("./codex-tool-call-content");
|
|
30
|
+
const codex_frontend_service_1 = require("./codex-frontend-service");
|
|
31
|
+
exports.CODEX_CHAT_AGENT_ID = 'Codex';
|
|
32
|
+
exports.CODEX_INPUT_TOKENS_KEY = 'codexInputTokens';
|
|
33
|
+
exports.CODEX_OUTPUT_TOKENS_KEY = 'codexOutputTokens';
|
|
34
|
+
exports.CODEX_TOOL_CALLS_KEY = 'codexToolCalls';
|
|
35
|
+
const CODEX_FILE_CHANGE_ORIGINALS_KEY = 'codexFileChangeOriginals';
|
|
36
|
+
/**
|
|
37
|
+
* Chat agent for OpenAI Codex integration.
|
|
38
|
+
*/
|
|
39
|
+
let CodexChatAgent = class CodexChatAgent {
|
|
40
|
+
constructor() {
|
|
41
|
+
this.id = exports.CODEX_CHAT_AGENT_ID;
|
|
42
|
+
this.name = 'Codex';
|
|
43
|
+
this.description = core_1.nls.localize('theia/ai/codex/agentDescription', 'OpenAI\'s coding assistant powered by Codex');
|
|
44
|
+
this.iconClass = 'codicon codicon-robot';
|
|
45
|
+
this.locations = ai_chat_1.ChatAgentLocation.ALL;
|
|
46
|
+
this.tags = [core_1.nls.localizeByDefault('Chat')];
|
|
47
|
+
this.variables = [];
|
|
48
|
+
this.prompts = [];
|
|
49
|
+
this.languageModelRequirements = [];
|
|
50
|
+
this.agentSpecificVariables = [];
|
|
51
|
+
this.functions = [];
|
|
52
|
+
this.modes = [
|
|
53
|
+
{ id: 'workspace-write', name: 'Workspace' },
|
|
54
|
+
{ id: 'read-only', name: 'Read-Only' },
|
|
55
|
+
{ id: 'danger-full-access', name: 'Full Access' }
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
async invoke(request) {
|
|
59
|
+
try {
|
|
60
|
+
const agentAddress = `${prompt_text_1.PromptText.AGENT_CHAR}${exports.CODEX_CHAT_AGENT_ID}`;
|
|
61
|
+
let prompt = request.request.text.trim();
|
|
62
|
+
if (prompt.startsWith(agentAddress)) {
|
|
63
|
+
prompt = prompt.replace(agentAddress, '').trim();
|
|
64
|
+
}
|
|
65
|
+
const sessionId = request.session.id;
|
|
66
|
+
const sandboxMode = this.extractSandboxMode(request.request.modeId);
|
|
67
|
+
const streamResult = await this.codexService.send({ prompt, sessionId, sandboxMode }, request.response.cancellationToken);
|
|
68
|
+
for await (const event of streamResult) {
|
|
69
|
+
await this.handleEvent(event, request);
|
|
70
|
+
}
|
|
71
|
+
request.response.complete();
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error('Codex error:', error);
|
|
75
|
+
request.response.response.addContent(new ai_chat_1.ErrorChatResponseContentImpl(error));
|
|
76
|
+
request.response.error(error);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
extractSandboxMode(modeId) {
|
|
80
|
+
if (modeId === 'read-only' || modeId === 'workspace-write' || modeId === 'danger-full-access') {
|
|
81
|
+
return modeId;
|
|
82
|
+
}
|
|
83
|
+
return 'workspace-write';
|
|
84
|
+
}
|
|
85
|
+
getToolCalls(request) {
|
|
86
|
+
let toolCalls = request.getDataByKey(exports.CODEX_TOOL_CALLS_KEY);
|
|
87
|
+
if (!toolCalls) {
|
|
88
|
+
toolCalls = new Map();
|
|
89
|
+
request.addData(exports.CODEX_TOOL_CALLS_KEY, toolCalls);
|
|
90
|
+
}
|
|
91
|
+
return toolCalls;
|
|
92
|
+
}
|
|
93
|
+
async handleEvent(event, request) {
|
|
94
|
+
if (event.type === 'item.started') {
|
|
95
|
+
await this.handleItemStarted(event, request);
|
|
96
|
+
}
|
|
97
|
+
else if (event.type === 'item.updated') {
|
|
98
|
+
await this.handleItemUpdated(event, request);
|
|
99
|
+
}
|
|
100
|
+
else if (event.type === 'item.completed') {
|
|
101
|
+
await this.handleItemCompleted(event, request);
|
|
102
|
+
}
|
|
103
|
+
else if (event.type === 'turn.completed') {
|
|
104
|
+
this.handleTurnCompleted(event, request);
|
|
105
|
+
}
|
|
106
|
+
else if (event.type === 'turn.failed') {
|
|
107
|
+
this.handleTurnFailed(event, request);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Type guard using discriminated union narrowing from SDK types.
|
|
112
|
+
*/
|
|
113
|
+
isToolInvocation(item) {
|
|
114
|
+
return item.type === 'command_execution' ||
|
|
115
|
+
item.type === 'todo_list' ||
|
|
116
|
+
item.type === 'file_change' ||
|
|
117
|
+
item.type === 'mcp_tool_call' ||
|
|
118
|
+
item.type === 'web_search';
|
|
119
|
+
}
|
|
120
|
+
extractToolArguments(item) {
|
|
121
|
+
const args = {};
|
|
122
|
+
if (item.type === 'command_execution') {
|
|
123
|
+
args.command = item.command;
|
|
124
|
+
args.status = item.status;
|
|
125
|
+
if (item.exit_code !== undefined) {
|
|
126
|
+
args.exit_code = item.exit_code;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else if (item.type === 'file_change') {
|
|
130
|
+
args.changes = item.changes;
|
|
131
|
+
args.status = item.status;
|
|
132
|
+
}
|
|
133
|
+
else if (item.type === 'mcp_tool_call') {
|
|
134
|
+
args.server = item.server;
|
|
135
|
+
args.tool = item.tool;
|
|
136
|
+
args.status = item.status;
|
|
137
|
+
}
|
|
138
|
+
else if (item.type === 'web_search') {
|
|
139
|
+
args.query = item.query;
|
|
140
|
+
}
|
|
141
|
+
else if (item.type === 'todo_list') {
|
|
142
|
+
args.id = item.id;
|
|
143
|
+
args.items = item.items;
|
|
144
|
+
}
|
|
145
|
+
return JSON.stringify(args);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Creates a pending tool call that will be updated when the item completes.
|
|
149
|
+
*/
|
|
150
|
+
async handleItemStarted(event, request) {
|
|
151
|
+
const item = event.item;
|
|
152
|
+
if (this.isToolInvocation(item)) {
|
|
153
|
+
if (item.type === 'file_change') {
|
|
154
|
+
await this.captureFileChangeOriginals(item, request);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const toolCallId = (0, core_1.generateUuid)();
|
|
158
|
+
const args = this.extractToolArguments(item);
|
|
159
|
+
const toolCall = new codex_tool_call_content_1.CodexToolCallChatResponseContent(toolCallId, item.type, args, false, undefined);
|
|
160
|
+
this.getToolCalls(request).set(toolCallId, toolCall);
|
|
161
|
+
request.response.response.addContent(toolCall);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Updates the pending tool call with new data, especially for todo_list items.
|
|
166
|
+
*/
|
|
167
|
+
async handleItemUpdated(event, request) {
|
|
168
|
+
const item = event.item;
|
|
169
|
+
if (this.isToolInvocation(item)) {
|
|
170
|
+
const toolCalls = this.getToolCalls(request);
|
|
171
|
+
const match = this.findMatchingToolCall(item, toolCalls);
|
|
172
|
+
if (match) {
|
|
173
|
+
const [_, existingCall] = match;
|
|
174
|
+
existingCall.update(this.extractToolArguments(item));
|
|
175
|
+
request.response.response.responseContentChanged();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
findMatchingToolCall(item, toolCalls) {
|
|
180
|
+
let matchKey;
|
|
181
|
+
if (item.type === 'command_execution') {
|
|
182
|
+
matchKey = item.command;
|
|
183
|
+
}
|
|
184
|
+
else if (item.type === 'web_search') {
|
|
185
|
+
matchKey = item.query;
|
|
186
|
+
}
|
|
187
|
+
else if (item.type === 'mcp_tool_call') {
|
|
188
|
+
matchKey = `${item.server}:${item.tool}`;
|
|
189
|
+
}
|
|
190
|
+
else if (item.type === 'todo_list') {
|
|
191
|
+
matchKey = item.id;
|
|
192
|
+
}
|
|
193
|
+
if (!matchKey) {
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
for (const [id, call] of toolCalls.entries()) {
|
|
197
|
+
const toolCallContent = call;
|
|
198
|
+
if (toolCallContent.name !== item.type || toolCallContent.finished) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
const args = toolCallContent.arguments ? JSON.parse(toolCallContent.arguments) : {};
|
|
203
|
+
let argKey;
|
|
204
|
+
if (item.type === 'command_execution') {
|
|
205
|
+
argKey = args.command;
|
|
206
|
+
}
|
|
207
|
+
else if (item.type === 'web_search') {
|
|
208
|
+
argKey = args.query;
|
|
209
|
+
}
|
|
210
|
+
else if (item.type === 'mcp_tool_call') {
|
|
211
|
+
argKey = `${args.server}:${args.tool}`;
|
|
212
|
+
}
|
|
213
|
+
else if (item.type === 'todo_list') {
|
|
214
|
+
argKey = args.id;
|
|
215
|
+
}
|
|
216
|
+
if (argKey === matchKey) {
|
|
217
|
+
return [id, call];
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return undefined;
|
|
225
|
+
}
|
|
226
|
+
getFileChangeOriginals(request) {
|
|
227
|
+
let originals = request.getDataByKey(CODEX_FILE_CHANGE_ORIGINALS_KEY);
|
|
228
|
+
if (!originals) {
|
|
229
|
+
originals = new Map();
|
|
230
|
+
request.addData(CODEX_FILE_CHANGE_ORIGINALS_KEY, originals);
|
|
231
|
+
}
|
|
232
|
+
return originals;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Snapshot the original contents for files that Codex is about to modify so we can populate the change set later.
|
|
236
|
+
*/
|
|
237
|
+
async captureFileChangeOriginals(item, request) {
|
|
238
|
+
const changes = item.changes;
|
|
239
|
+
if (!changes || changes.length === 0) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
const rootUri = await this.getWorkspaceRootUri();
|
|
243
|
+
if (!rootUri) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const originals = this.getFileChangeOriginals(request);
|
|
247
|
+
let itemOriginals = originals.get(item.id);
|
|
248
|
+
if (!itemOriginals) {
|
|
249
|
+
itemOriginals = new Map();
|
|
250
|
+
originals.set(item.id, itemOriginals);
|
|
251
|
+
}
|
|
252
|
+
for (const change of changes) {
|
|
253
|
+
const rawPath = typeof change.path === 'string' ? change.path.trim() : '';
|
|
254
|
+
const path = this.normalizeRelativePath(rawPath, rootUri);
|
|
255
|
+
if (!path) {
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
const fileUri = this.resolveFileUri(rootUri, path);
|
|
259
|
+
if (!fileUri) {
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
// For additions we snapshot an empty original state; for deletions/updates we capture existing content if available.
|
|
263
|
+
if (change.kind === 'add') {
|
|
264
|
+
itemOriginals.set(path, '');
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
try {
|
|
268
|
+
if (await this.fileService.exists(fileUri)) {
|
|
269
|
+
const currentContent = await this.fileService.read(fileUri);
|
|
270
|
+
itemOriginals.set(path, currentContent.value.toString());
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
itemOriginals.set(path, '');
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
console.error('CodexChatAgent: Failed to capture original content for', path, error);
|
|
278
|
+
itemOriginals.set(path, '');
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
async handleFileChangeCompleted(item, request) {
|
|
283
|
+
if (!item.changes || item.changes.length === 0) {
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
const originals = this.getFileChangeOriginals(request);
|
|
287
|
+
if (item.status === 'failed') {
|
|
288
|
+
const affectedPaths = item.changes
|
|
289
|
+
.map(change => change.path)
|
|
290
|
+
.filter(path => !!path)
|
|
291
|
+
.join(', ');
|
|
292
|
+
const message = affectedPaths.length > 0
|
|
293
|
+
? core_1.nls.localize('theia/ai/codex/fileChangeFailed', 'Codex failed to apply changes for: {0}', affectedPaths)
|
|
294
|
+
: core_1.nls.localize('theia/ai/codex/fileChangeFailedGeneric', 'Codex failed to apply file changes.');
|
|
295
|
+
request.response.response.addContent(new ai_chat_1.ErrorChatResponseContentImpl(new Error(message)));
|
|
296
|
+
originals.delete(item.id);
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
// const rootUri = await this.getWorkspaceRootUri();
|
|
300
|
+
// if (!rootUri) {
|
|
301
|
+
// console.warn('CodexChatAgent: Unable to resolve workspace root for file change event.');
|
|
302
|
+
// return false;
|
|
303
|
+
// }
|
|
304
|
+
// const changeSet = request.session?.changeSet;
|
|
305
|
+
// if (!changeSet) {
|
|
306
|
+
// originals.delete(item.id);
|
|
307
|
+
// return false;
|
|
308
|
+
// }
|
|
309
|
+
// const itemOriginals = originals.get(item.id);
|
|
310
|
+
// let createdElement = false;
|
|
311
|
+
// for (const change of item.changes) {
|
|
312
|
+
// const rawPath = typeof change.path === 'string' ? change.path.trim() : '';
|
|
313
|
+
// const path = this.normalizeRelativePath(rawPath, rootUri);
|
|
314
|
+
// if (!path) {
|
|
315
|
+
// continue;
|
|
316
|
+
// }
|
|
317
|
+
// const fileUri = this.resolveFileUri(rootUri, path);
|
|
318
|
+
// if (!fileUri) {
|
|
319
|
+
// continue;
|
|
320
|
+
// }
|
|
321
|
+
// const originalState = itemOriginals?.get(path) ?? '';
|
|
322
|
+
// let targetState = '';
|
|
323
|
+
// if (change.kind !== 'delete') {
|
|
324
|
+
// const content = await this.readFileContentSafe(fileUri);
|
|
325
|
+
// if (content === undefined) {
|
|
326
|
+
// continue;
|
|
327
|
+
// }
|
|
328
|
+
// targetState = content;
|
|
329
|
+
// }
|
|
330
|
+
// const elementType = this.mapChangeKind(change.kind);
|
|
331
|
+
// const fileElement = this.fileChangeFactory({
|
|
332
|
+
// uri: fileUri,
|
|
333
|
+
// type: elementType,
|
|
334
|
+
// state: 'applied',
|
|
335
|
+
// targetState,
|
|
336
|
+
// originalState,
|
|
337
|
+
// requestId: request.id,
|
|
338
|
+
// chatSessionId: request.session.id
|
|
339
|
+
// });
|
|
340
|
+
// changeSet.addElements(fileElement);
|
|
341
|
+
// createdElement = true;
|
|
342
|
+
// }
|
|
343
|
+
originals.delete(item.id);
|
|
344
|
+
// if (createdElement) {
|
|
345
|
+
// changeSet.setTitle(CODEX_CHANGESET_TITLE);
|
|
346
|
+
// }
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
normalizeRelativePath(path, rootUri) {
|
|
350
|
+
if (!path) {
|
|
351
|
+
return undefined;
|
|
352
|
+
}
|
|
353
|
+
let normalized = path.replace(/\\/g, '/').trim();
|
|
354
|
+
if (!normalized) {
|
|
355
|
+
return undefined;
|
|
356
|
+
}
|
|
357
|
+
if (normalized.includes('://')) {
|
|
358
|
+
try {
|
|
359
|
+
const uri = new uri_1.URI(normalized);
|
|
360
|
+
normalized = uri.path.fsPath();
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
if (/^[a-zA-Z]:\//.test(normalized)) {
|
|
366
|
+
normalized = `/${normalized}`;
|
|
367
|
+
}
|
|
368
|
+
if (rootUri) {
|
|
369
|
+
const candidates = [
|
|
370
|
+
this.ensureTrailingSlash(rootUri.path.normalize().toString()),
|
|
371
|
+
this.ensureTrailingSlash(rootUri.path.fsPath().replace(/\\/g, '/'))
|
|
372
|
+
];
|
|
373
|
+
const lowerNormalized = normalized.toLowerCase();
|
|
374
|
+
for (const candidate of candidates) {
|
|
375
|
+
if (!candidate) {
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
const lowerCandidate = candidate.toLowerCase();
|
|
379
|
+
if (lowerNormalized.startsWith(lowerCandidate)) {
|
|
380
|
+
normalized = normalized.substring(candidate.length);
|
|
381
|
+
break;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
if (normalized.startsWith('./')) {
|
|
386
|
+
normalized = normalized.substring(2);
|
|
387
|
+
}
|
|
388
|
+
while (normalized.startsWith('/')) {
|
|
389
|
+
normalized = normalized.substring(1);
|
|
390
|
+
}
|
|
391
|
+
normalized = normalized.trim();
|
|
392
|
+
return normalized || undefined;
|
|
393
|
+
}
|
|
394
|
+
ensureTrailingSlash(path) {
|
|
395
|
+
if (!path) {
|
|
396
|
+
return '';
|
|
397
|
+
}
|
|
398
|
+
return path.endsWith('/') ? path : `${path}/`;
|
|
399
|
+
}
|
|
400
|
+
// protected async readFileContentSafe(fileUri: URI): Promise<string | undefined> {
|
|
401
|
+
// try {
|
|
402
|
+
// if (!await this.fileService.exists(fileUri)) {
|
|
403
|
+
// console.warn('CodexChatAgent: Skipping file change entry because file is missing', fileUri.toString());
|
|
404
|
+
// return undefined;
|
|
405
|
+
// }
|
|
406
|
+
// const fileContent = await this.fileService.read(fileUri);
|
|
407
|
+
// return fileContent.value.toString();
|
|
408
|
+
// } catch (error) {
|
|
409
|
+
// console.error('CodexChatAgent: Failed to read updated file content for', fileUri.toString(), error);
|
|
410
|
+
// return undefined;
|
|
411
|
+
// }
|
|
412
|
+
// }
|
|
413
|
+
// protected mapChangeKind(kind: FileChangeItem['changes'][number]['kind']): 'add' | 'delete' | 'modify' {
|
|
414
|
+
// switch (kind) {
|
|
415
|
+
// case 'add':
|
|
416
|
+
// return 'add';
|
|
417
|
+
// case 'delete':
|
|
418
|
+
// return 'delete';
|
|
419
|
+
// default:
|
|
420
|
+
// return 'modify';
|
|
421
|
+
// }
|
|
422
|
+
// }
|
|
423
|
+
resolveFileUri(rootUri, relativePath) {
|
|
424
|
+
try {
|
|
425
|
+
const candidate = rootUri.resolve(relativePath);
|
|
426
|
+
const normalizedCandidate = candidate.withPath(candidate.path.normalize());
|
|
427
|
+
const normalizedRoot = rootUri.withPath(rootUri.path.normalize());
|
|
428
|
+
if (!normalizedRoot.isEqualOrParent(normalizedCandidate)) {
|
|
429
|
+
console.warn(`CodexChatAgent: Skipping file change outside workspace: ${relativePath}`);
|
|
430
|
+
return undefined;
|
|
431
|
+
}
|
|
432
|
+
return normalizedCandidate;
|
|
433
|
+
}
|
|
434
|
+
catch (error) {
|
|
435
|
+
console.error('CodexChatAgent: Failed to resolve file URI for', relativePath, error);
|
|
436
|
+
return undefined;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
async getWorkspaceRootUri() {
|
|
440
|
+
const roots = await this.workspaceService.roots;
|
|
441
|
+
if (roots && roots.length > 0) {
|
|
442
|
+
return roots[0].resource;
|
|
443
|
+
}
|
|
444
|
+
return undefined;
|
|
445
|
+
}
|
|
446
|
+
async handleItemCompleted(event, request) {
|
|
447
|
+
const item = event.item;
|
|
448
|
+
if (this.isToolInvocation(item)) {
|
|
449
|
+
if (item.type === 'file_change') {
|
|
450
|
+
const handled = await this.handleFileChangeCompleted(item, request);
|
|
451
|
+
if (handled) {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
const toolCalls = this.getToolCalls(request);
|
|
456
|
+
const match = this.findMatchingToolCall(item, toolCalls);
|
|
457
|
+
if (match) {
|
|
458
|
+
const [id, _] = match;
|
|
459
|
+
const updatedCall = new codex_tool_call_content_1.CodexToolCallChatResponseContent(id, item.type, this.extractToolArguments(item), true, JSON.stringify(item));
|
|
460
|
+
toolCalls.set(id, updatedCall);
|
|
461
|
+
request.response.response.addContent(updatedCall);
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
const toolCallId = (0, core_1.generateUuid)();
|
|
465
|
+
const newToolCall = new codex_tool_call_content_1.CodexToolCallChatResponseContent(toolCallId, item.type, this.extractToolArguments(item), true, JSON.stringify(item));
|
|
466
|
+
toolCalls.set(toolCallId, newToolCall);
|
|
467
|
+
request.response.response.addContent(newToolCall);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
else if (item.type === 'reasoning') {
|
|
471
|
+
request.response.response.addContent(new ai_chat_1.ThinkingChatResponseContentImpl(item.text, ''));
|
|
472
|
+
}
|
|
473
|
+
else if (item.type === 'agent_message') {
|
|
474
|
+
request.response.response.addContent(new ai_chat_1.MarkdownChatResponseContentImpl(item.text));
|
|
475
|
+
}
|
|
476
|
+
else if (item.type === 'error') {
|
|
477
|
+
request.response.response.addContent(new ai_chat_1.ErrorChatResponseContentImpl(new Error(item.message)));
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
handleTurnCompleted(event, request) {
|
|
481
|
+
const usage = event.usage;
|
|
482
|
+
this.updateTokens(request, usage.input_tokens, usage.output_tokens);
|
|
483
|
+
this.reportTokenUsage(request, usage);
|
|
484
|
+
}
|
|
485
|
+
handleTurnFailed(event, request) {
|
|
486
|
+
const errorMsg = event.error.message;
|
|
487
|
+
request.response.response.addContent(new ai_chat_1.ErrorChatResponseContentImpl(new Error(errorMsg)));
|
|
488
|
+
}
|
|
489
|
+
updateTokens(request, inputTokens, outputTokens) {
|
|
490
|
+
request.addData(exports.CODEX_INPUT_TOKENS_KEY, inputTokens);
|
|
491
|
+
request.addData(exports.CODEX_OUTPUT_TOKENS_KEY, outputTokens);
|
|
492
|
+
this.updateSessionSuggestion(request);
|
|
493
|
+
}
|
|
494
|
+
updateSessionSuggestion(request) {
|
|
495
|
+
const { inputTokens, outputTokens } = this.getSessionTotalTokens(request);
|
|
496
|
+
const formatTokens = (tokens) => {
|
|
497
|
+
if (tokens >= 1000) {
|
|
498
|
+
return `${(tokens / 1000).toFixed(1)}K`;
|
|
499
|
+
}
|
|
500
|
+
return tokens.toString();
|
|
501
|
+
};
|
|
502
|
+
const suggestion = `↑ ${formatTokens(inputTokens)} | ↓ ${formatTokens(outputTokens)}`;
|
|
503
|
+
request.session.setSuggestions([suggestion]);
|
|
504
|
+
}
|
|
505
|
+
getSessionTotalTokens(request) {
|
|
506
|
+
var _a, _b;
|
|
507
|
+
const requests = request.session.getRequests();
|
|
508
|
+
let totalInputTokens = 0;
|
|
509
|
+
let totalOutputTokens = 0;
|
|
510
|
+
for (const req of requests) {
|
|
511
|
+
const inputTokens = (_a = req.getDataByKey(exports.CODEX_INPUT_TOKENS_KEY)) !== null && _a !== void 0 ? _a : 0;
|
|
512
|
+
const outputTokens = (_b = req.getDataByKey(exports.CODEX_OUTPUT_TOKENS_KEY)) !== null && _b !== void 0 ? _b : 0;
|
|
513
|
+
totalInputTokens += inputTokens;
|
|
514
|
+
totalOutputTokens += outputTokens;
|
|
515
|
+
}
|
|
516
|
+
return { inputTokens: totalInputTokens, outputTokens: totalOutputTokens };
|
|
517
|
+
}
|
|
518
|
+
async reportTokenUsage(request, usage) {
|
|
519
|
+
try {
|
|
520
|
+
await this.tokenUsageService.recordTokenUsage('openai/codex', {
|
|
521
|
+
inputTokens: usage.input_tokens,
|
|
522
|
+
outputTokens: usage.output_tokens,
|
|
523
|
+
cachedInputTokens: usage.cached_input_tokens,
|
|
524
|
+
requestId: request.id
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
catch (error) {
|
|
528
|
+
console.error('Failed to report token usage:', error);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
exports.CodexChatAgent = CodexChatAgent;
|
|
533
|
+
tslib_1.__decorate([
|
|
534
|
+
(0, inversify_1.inject)(codex_frontend_service_1.CodexFrontendService),
|
|
535
|
+
tslib_1.__metadata("design:type", codex_frontend_service_1.CodexFrontendService)
|
|
536
|
+
], CodexChatAgent.prototype, "codexService", void 0);
|
|
537
|
+
tslib_1.__decorate([
|
|
538
|
+
(0, inversify_1.inject)(ai_core_1.TokenUsageService),
|
|
539
|
+
tslib_1.__metadata("design:type", Object)
|
|
540
|
+
], CodexChatAgent.prototype, "tokenUsageService", void 0);
|
|
541
|
+
tslib_1.__decorate([
|
|
542
|
+
(0, inversify_1.inject)(file_service_1.FileService),
|
|
543
|
+
tslib_1.__metadata("design:type", file_service_1.FileService)
|
|
544
|
+
], CodexChatAgent.prototype, "fileService", void 0);
|
|
545
|
+
tslib_1.__decorate([
|
|
546
|
+
(0, inversify_1.inject)(browser_1.WorkspaceService),
|
|
547
|
+
tslib_1.__metadata("design:type", browser_1.WorkspaceService)
|
|
548
|
+
], CodexChatAgent.prototype, "workspaceService", void 0);
|
|
549
|
+
tslib_1.__decorate([
|
|
550
|
+
(0, inversify_1.inject)(change_set_file_element_1.ChangeSetFileElementFactory),
|
|
551
|
+
tslib_1.__metadata("design:type", Function)
|
|
552
|
+
], CodexChatAgent.prototype, "fileChangeFactory", void 0);
|
|
553
|
+
exports.CodexChatAgent = CodexChatAgent = tslib_1.__decorate([
|
|
554
|
+
(0, inversify_1.injectable)()
|
|
555
|
+
], CodexChatAgent);
|
|
556
|
+
//# sourceMappingURL=codex-chat-agent.js.map
|