@theia/ai-history 1.54.0

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.
Files changed (38) hide show
  1. package/README.md +31 -0
  2. package/lib/browser/ai-history-communication-card.d.ts +8 -0
  3. package/lib/browser/ai-history-communication-card.d.ts.map +1 -0
  4. package/lib/browser/ai-history-communication-card.js +31 -0
  5. package/lib/browser/ai-history-communication-card.js.map +1 -0
  6. package/lib/browser/ai-history-contribution.d.ts +12 -0
  7. package/lib/browser/ai-history-contribution.d.ts.map +1 -0
  8. package/lib/browser/ai-history-contribution.js +41 -0
  9. package/lib/browser/ai-history-contribution.js.map +1 -0
  10. package/lib/browser/ai-history-frontend-module.d.ts +5 -0
  11. package/lib/browser/ai-history-frontend-module.d.ts.map +1 -0
  12. package/lib/browser/ai-history-frontend-module.js +40 -0
  13. package/lib/browser/ai-history-frontend-module.js.map +1 -0
  14. package/lib/browser/ai-history-widget.d.ts +19 -0
  15. package/lib/browser/ai-history-widget.d.ts.map +1 -0
  16. package/lib/browser/ai-history-widget.js +101 -0
  17. package/lib/browser/ai-history-widget.js.map +1 -0
  18. package/lib/common/communication-recording-service.d.ts +14 -0
  19. package/lib/common/communication-recording-service.d.ts.map +1 -0
  20. package/lib/common/communication-recording-service.js +54 -0
  21. package/lib/common/communication-recording-service.js.map +1 -0
  22. package/lib/common/communication-recording-service.spec.d.ts +2 -0
  23. package/lib/common/communication-recording-service.spec.d.ts.map +1 -0
  24. package/lib/common/communication-recording-service.spec.js +19 -0
  25. package/lib/common/communication-recording-service.spec.js.map +1 -0
  26. package/lib/common/index.d.ts +2 -0
  27. package/lib/common/index.d.ts.map +1 -0
  28. package/lib/common/index.js +20 -0
  29. package/lib/common/index.js.map +1 -0
  30. package/package.json +54 -0
  31. package/src/browser/ai-history-communication-card.tsx +48 -0
  32. package/src/browser/ai-history-contribution.ts +52 -0
  33. package/src/browser/ai-history-frontend-module.ts +41 -0
  34. package/src/browser/ai-history-widget.tsx +96 -0
  35. package/src/browser/style/ai-history.css +75 -0
  36. package/src/common/communication-recording-service.spec.ts +37 -0
  37. package/src/common/communication-recording-service.ts +63 -0
  38. package/src/common/index.ts +17 -0
package/README.md ADDED
@@ -0,0 +1,31 @@
1
+ <div align='center'>
2
+
3
+ <br />
4
+
5
+ <img src='https://raw.githubusercontent.com/eclipse-theia/theia/master/logo/theia.svg?sanitize=true' alt='theia-ext-logo' width='100px' />
6
+
7
+ <h2>ECLIPSE THEIA - AI History EXTENSION</h2>
8
+
9
+ <hr />
10
+
11
+ </div>
12
+
13
+ ## Description
14
+
15
+ The `@theia/ai-history` extension offers a framework for agents to record their requests and responses.
16
+ It also offers a view to inspect the history.
17
+
18
+
19
+ ## Additional Information
20
+
21
+ - [Theia - GitHub](https://github.com/eclipse-theia/theia)
22
+ - [Theia - Website](https://theia-ide.org/)
23
+
24
+ ## License
25
+
26
+ - [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/)
27
+ - [一 (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](https://projects.eclipse.org/license/secondary-gpl-2.0-cp)
28
+
29
+ ## Trademark
30
+ "Theia" is a trademark of the Eclipse Foundation
31
+ https://www.eclipse.org/theia
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ import { CommunicationHistoryEntry } from '@theia/ai-core';
3
+ import * as React from '@theia/core/shared/react';
4
+ export interface CommunicationCardProps {
5
+ entry: CommunicationHistoryEntry;
6
+ }
7
+ export declare const CommunicationCard: React.FC<CommunicationCardProps>;
8
+ //# sourceMappingURL=ai-history-communication-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-history-communication-card.d.ts","sourceRoot":"","sources":["../../src/browser/ai-history-communication-card.tsx"],"names":[],"mappings":";AAeA,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,KAAK,MAAM,0BAA0B,CAAC;AAElD,MAAM,WAAW,sBAAsB;IACnC,KAAK,EAAE,yBAAyB,CAAC;CACpC;AAED,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAyB9D,CAAC"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CommunicationCard = void 0;
4
+ const React = require("@theia/core/shared/react");
5
+ const CommunicationCard = ({ entry }) => (React.createElement("div", { className: 'theia-card' },
6
+ React.createElement("div", { className: 'theia-card-meta' },
7
+ React.createElement("span", { className: 'theia-card-request-id' },
8
+ "Request ID: ",
9
+ entry.requestId),
10
+ React.createElement("span", { className: 'theia-card-session-id' },
11
+ "Session ID: ",
12
+ entry.sessionId)),
13
+ React.createElement("div", { className: 'theia-card-content' },
14
+ entry.request && (React.createElement("div", { className: 'theia-card-request' },
15
+ React.createElement("p", null,
16
+ React.createElement("strong", null, "Request")),
17
+ React.createElement("pre", null, entry.request))),
18
+ entry.response && (React.createElement("div", { className: 'theia-card-response' },
19
+ React.createElement("p", null,
20
+ React.createElement("strong", null, "Response")),
21
+ React.createElement("pre", null, entry.response)))),
22
+ React.createElement("div", { className: 'theia-card-meta' },
23
+ React.createElement("span", { className: 'theia-card-timestamp' },
24
+ "Timestamp: ",
25
+ new Date(entry.timestamp).toLocaleString()),
26
+ entry.responseTime && React.createElement("span", { className: 'theia-card-response-time' },
27
+ "Response Time: ",
28
+ entry.responseTime,
29
+ "ms"))));
30
+ exports.CommunicationCard = CommunicationCard;
31
+ //# sourceMappingURL=ai-history-communication-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-history-communication-card.js","sourceRoot":"","sources":["../../src/browser/ai-history-communication-card.tsx"],"names":[],"mappings":";;;AAgBA,kDAAkD;AAM3C,MAAM,iBAAiB,GAAqC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAC9E,6BAAK,SAAS,EAAC,YAAY;IACvB,6BAAK,SAAS,EAAC,iBAAiB;QAC5B,8BAAM,SAAS,EAAC,uBAAuB;;YAAc,KAAK,CAAC,SAAS,CAAQ;QAC5E,8BAAM,SAAS,EAAC,uBAAuB;;YAAc,KAAK,CAAC,SAAS,CAAQ,CAC1E;IACN,6BAAK,SAAS,EAAC,oBAAoB;QAC9B,KAAK,CAAC,OAAO,IAAI,CACd,6BAAK,SAAS,EAAC,oBAAoB;YAC/B;gBAAG,8CAAwB,CAAI;YAC/B,iCAAM,KAAK,CAAC,OAAO,CAAO,CACxB,CACT;QACA,KAAK,CAAC,QAAQ,IAAI,CACf,6BAAK,SAAS,EAAC,qBAAqB;YAChC;gBAAG,+CAAyB,CAAI;YAChC,iCAAM,KAAK,CAAC,QAAQ,CAAO,CACzB,CACT,CACC;IACN,6BAAK,SAAS,EAAC,iBAAiB;QAC5B,8BAAM,SAAS,EAAC,sBAAsB;;YAAa,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,CAAQ;QACpG,KAAK,CAAC,YAAY,IAAI,8BAAM,SAAS,EAAC,0BAA0B;;YAAiB,KAAK,CAAC,YAAY;iBAAU,CAC5G,CACJ,CACT,CAAC;AAzBW,QAAA,iBAAiB,qBAyB5B"}
@@ -0,0 +1,12 @@
1
+ import { FrontendApplication } from '@theia/core/lib/browser';
2
+ import { AIViewContribution } from '@theia/ai-core/lib/browser';
3
+ import { AIHistoryView } from './ai-history-widget';
4
+ import { Command, CommandRegistry } from '@theia/core';
5
+ export declare const AI_HISTORY_TOGGLE_COMMAND_ID = "aiHistory:toggle";
6
+ export declare const OPEN_AI_HISTORY_VIEW: Command;
7
+ export declare class AIHistoryViewContribution extends AIViewContribution<AIHistoryView> {
8
+ constructor();
9
+ initializeLayout(_app: FrontendApplication): Promise<void>;
10
+ registerCommands(commands: CommandRegistry): void;
11
+ }
12
+ //# sourceMappingURL=ai-history-contribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-history-contribution.d.ts","sourceRoot":"","sources":["../../src/browser/ai-history-contribution.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEvD,eAAO,MAAM,4BAA4B,qBAAqB,CAAC;AAC/D,eAAO,MAAM,oBAAoB,SAG/B,CAAC;AAEH,qBACa,yBAA0B,SAAQ,kBAAkB,CAAC,aAAa,CAAC;;IAatE,gBAAgB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvD,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;CAM7D"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AIHistoryViewContribution = exports.OPEN_AI_HISTORY_VIEW = exports.AI_HISTORY_TOGGLE_COMMAND_ID = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const browser_1 = require("@theia/ai-core/lib/browser");
6
+ const inversify_1 = require("@theia/core/shared/inversify");
7
+ const ai_history_widget_1 = require("./ai-history-widget");
8
+ const core_1 = require("@theia/core");
9
+ exports.AI_HISTORY_TOGGLE_COMMAND_ID = 'aiHistory:toggle';
10
+ exports.OPEN_AI_HISTORY_VIEW = core_1.Command.toLocalizedCommand({
11
+ id: 'aiHistory:open',
12
+ label: 'Open AI History view',
13
+ });
14
+ let AIHistoryViewContribution = class AIHistoryViewContribution extends browser_1.AIViewContribution {
15
+ constructor() {
16
+ super({
17
+ widgetId: ai_history_widget_1.AIHistoryView.ID,
18
+ widgetName: ai_history_widget_1.AIHistoryView.LABEL,
19
+ defaultWidgetOptions: {
20
+ area: 'bottom',
21
+ rank: 100
22
+ },
23
+ toggleCommandId: exports.AI_HISTORY_TOGGLE_COMMAND_ID,
24
+ });
25
+ }
26
+ async initializeLayout(_app) {
27
+ await this.openView();
28
+ }
29
+ registerCommands(commands) {
30
+ super.registerCommands(commands);
31
+ commands.registerCommand(exports.OPEN_AI_HISTORY_VIEW, {
32
+ execute: () => this.openView({ activate: true }),
33
+ });
34
+ }
35
+ };
36
+ exports.AIHistoryViewContribution = AIHistoryViewContribution;
37
+ exports.AIHistoryViewContribution = AIHistoryViewContribution = tslib_1.__decorate([
38
+ (0, inversify_1.injectable)(),
39
+ tslib_1.__metadata("design:paramtypes", [])
40
+ ], AIHistoryViewContribution);
41
+ //# sourceMappingURL=ai-history-contribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-history-contribution.js","sourceRoot":"","sources":["../../src/browser/ai-history-contribution.ts"],"names":[],"mappings":";;;;AAgBA,wDAAgE;AAChE,4DAA0D;AAC1D,2DAAoD;AACpD,sCAAuD;AAE1C,QAAA,4BAA4B,GAAG,kBAAkB,CAAC;AAClD,QAAA,oBAAoB,GAAG,cAAO,CAAC,kBAAkB,CAAC;IAC3D,EAAE,EAAE,gBAAgB;IACpB,KAAK,EAAE,sBAAsB;CAChC,CAAC,CAAC;AAGI,IAAM,yBAAyB,GAA/B,MAAM,yBAA0B,SAAQ,4BAAiC;IAC5E;QACI,KAAK,CAAC;YACF,QAAQ,EAAE,iCAAa,CAAC,EAAE;YAC1B,UAAU,EAAE,iCAAa,CAAC,KAAK;YAC/B,oBAAoB,EAAE;gBAClB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,GAAG;aACZ;YACD,eAAe,EAAE,oCAA4B;SAChD,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,IAAyB;QAC5C,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;IAEQ,gBAAgB,CAAC,QAAyB;QAC/C,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACjC,QAAQ,CAAC,eAAe,CAAC,4BAAoB,EAAE;YAC3C,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;SACnD,CAAC,CAAC;IACP,CAAC;CACJ,CAAA;AAvBY,8DAAyB;oCAAzB,yBAAyB;IADrC,IAAA,sBAAU,GAAE;;GACA,yBAAyB,CAuBrC"}
@@ -0,0 +1,5 @@
1
+ import { ContainerModule } from '@theia/core/shared/inversify';
2
+ import '../../src/browser/style/ai-history.css';
3
+ declare const _default: ContainerModule;
4
+ export default _default;
5
+ //# sourceMappingURL=ai-history-frontend-module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-history-frontend-module.d.ts","sourceRoot":"","sources":["../../src/browser/ai-history-frontend-module.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAM/D,OAAO,wCAAwC,CAAC;;AAEhD,wBAgBG"}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // *****************************************************************************
4
+ // Copyright (C) 2024 EclipseSource GmbH.
5
+ //
6
+ // This program and the accompanying materials are made available under the
7
+ // terms of the Eclipse Public License v. 2.0 which is available at
8
+ // http://www.eclipse.org/legal/epl-2.0.
9
+ //
10
+ // This Source Code may also be made available under the following Secondary
11
+ // Licenses when the conditions for such availability set forth in the Eclipse
12
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
13
+ // with the GNU Classpath Exception which is available at
14
+ // https://www.gnu.org/software/classpath/license.html.
15
+ //
16
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
17
+ // *****************************************************************************
18
+ const ai_core_1 = require("@theia/ai-core");
19
+ const inversify_1 = require("@theia/core/shared/inversify");
20
+ const communication_recording_service_1 = require("../common/communication-recording-service");
21
+ const browser_1 = require("@theia/core/lib/browser");
22
+ const core_1 = require("@theia/core");
23
+ const ai_history_contribution_1 = require("./ai-history-contribution");
24
+ const ai_history_widget_1 = require("./ai-history-widget");
25
+ require("../../src/browser/style/ai-history.css");
26
+ exports.default = new inversify_1.ContainerModule(bind => {
27
+ bind(communication_recording_service_1.DefaultCommunicationRecordingService).toSelf().inSingletonScope();
28
+ bind(ai_core_1.CommunicationRecordingService).toService(communication_recording_service_1.DefaultCommunicationRecordingService);
29
+ bind(core_1.ILogger).toDynamicValue(ctx => {
30
+ const parentLogger = ctx.container.get(core_1.ILogger);
31
+ return parentLogger.child('llm-communication-recorder');
32
+ }).inSingletonScope().whenTargetNamed('llm-communication-recorder');
33
+ (0, browser_1.bindViewContribution)(bind, ai_history_contribution_1.AIHistoryViewContribution);
34
+ bind(ai_history_widget_1.AIHistoryView).toSelf().inSingletonScope();
35
+ bind(browser_1.WidgetFactory).toDynamicValue(context => ({
36
+ id: ai_history_widget_1.AIHistoryView.ID,
37
+ createWidget: () => context.container.get(ai_history_widget_1.AIHistoryView)
38
+ })).inSingletonScope();
39
+ });
40
+ //# sourceMappingURL=ai-history-frontend-module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-history-frontend-module.js","sourceRoot":"","sources":["../../src/browser/ai-history-frontend-module.ts"],"names":[],"mappings":";;AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,4CAA+D;AAC/D,4DAA+D;AAC/D,+FAAiG;AACjG,qDAA8E;AAC9E,sCAAsC;AACtC,uEAAsE;AACtE,2DAAoD;AACpD,kDAAgD;AAEhD,kBAAe,IAAI,2BAAe,CAAC,IAAI,CAAC,EAAE;IACtC,IAAI,CAAC,sEAAoC,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IACvE,IAAI,CAAC,uCAA6B,CAAC,CAAC,SAAS,CAAC,sEAAoC,CAAC,CAAC;IAEpF,IAAI,CAAC,cAAO,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;QAC/B,MAAM,YAAY,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAU,cAAO,CAAC,CAAC;QACzD,OAAO,YAAY,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC,eAAe,CAAC,4BAA4B,CAAC,CAAC;IAEpE,IAAA,8BAAoB,EAAC,IAAI,EAAE,mDAAyB,CAAC,CAAC;IAEtD,IAAI,CAAC,iCAAa,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAChD,IAAI,CAAC,uBAAa,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC3C,EAAE,EAAE,iCAAa,CAAC,EAAE;QACpB,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAgB,iCAAa,CAAC;KAC1E,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC;AAC3B,CAAC,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ /// <reference types="react" />
2
+ import { Agent, AgentService, CommunicationRecordingService, CommunicationRequestEntry, CommunicationResponseEntry } from '@theia/ai-core';
3
+ import { ReactWidget } from '@theia/core/lib/browser';
4
+ import * as React from '@theia/core/shared/react';
5
+ export declare class AIHistoryView extends ReactWidget {
6
+ protected recordingService: CommunicationRecordingService;
7
+ protected readonly agentService: AgentService;
8
+ static ID: string;
9
+ static LABEL: string;
10
+ protected selectedAgent?: Agent;
11
+ constructor();
12
+ protected init(): void;
13
+ protected selectAgent(agent: Agent | undefined): void;
14
+ protected historyContentUpdated(entry: CommunicationRequestEntry | CommunicationResponseEntry): void;
15
+ render(): React.ReactNode;
16
+ protected renderHistory(): React.ReactNode;
17
+ protected onClick(e: React.MouseEvent<HTMLDivElement>, agent: Agent): void;
18
+ }
19
+ //# sourceMappingURL=ai-history-widget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-history-widget.d.ts","sourceRoot":"","sources":["../../src/browser/ai-history-widget.tsx"],"names":[],"mappings":";AAeA,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,6BAA6B,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC3I,OAAO,EAAW,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,KAAK,KAAK,MAAM,0BAA0B,CAAC;AAIlD,qBACa,aAAc,SAAQ,WAAW;IAE1C,SAAS,CAAC,gBAAgB,EAAE,6BAA6B,CAAC;IAE1D,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAE9C,OAAc,EAAE,SAAuB;IACvC,MAAM,CAAC,KAAK,SAAuC;IAEnD,SAAS,CAAC,aAAa,CAAC,EAAE,KAAK,CAAC;;IAYhC,SAAS,CAAC,IAAI,IAAI,IAAI;IAOtB,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI;IAKrD,SAAS,CAAC,qBAAqB,CAAC,KAAK,EAAE,yBAAyB,GAAG,0BAA0B,GAAG,IAAI;IAMpG,MAAM,IAAI,KAAK,CAAC,SAAS;IAkBzB,SAAS,CAAC,aAAa,IAAI,KAAK,CAAC,SAAS;IAW1C,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;CAI7E"}
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ var AIHistoryView_1;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.AIHistoryView = void 0;
5
+ const tslib_1 = require("tslib");
6
+ // *****************************************************************************
7
+ // Copyright (C) 2024 EclipseSource GmbH.
8
+ //
9
+ // This program and the accompanying materials are made available under the
10
+ // terms of the Eclipse Public License v. 2.0 which is available at
11
+ // http://www.eclipse.org/legal/epl-2.0.
12
+ //
13
+ // This Source Code may also be made available under the following Secondary
14
+ // Licenses when the conditions for such availability set forth in the Eclipse
15
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
16
+ // with the GNU Classpath Exception which is available at
17
+ // https://www.gnu.org/software/classpath/license.html.
18
+ //
19
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
20
+ // *****************************************************************************
21
+ const ai_core_1 = require("@theia/ai-core");
22
+ const browser_1 = require("@theia/core/lib/browser");
23
+ const inversify_1 = require("@theia/core/shared/inversify");
24
+ const React = require("@theia/core/shared/react");
25
+ const ai_history_communication_card_1 = require("./ai-history-communication-card");
26
+ const select_component_1 = require("@theia/core/lib/browser/widgets/select-component");
27
+ let AIHistoryView = AIHistoryView_1 = class AIHistoryView extends browser_1.ReactWidget {
28
+ constructor() {
29
+ super();
30
+ this.id = AIHistoryView_1.ID;
31
+ this.title.label = AIHistoryView_1.LABEL;
32
+ this.title.caption = AIHistoryView_1.LABEL;
33
+ this.title.closable = true;
34
+ this.title.iconClass = (0, browser_1.codicon)('history');
35
+ }
36
+ init() {
37
+ this.update();
38
+ this.toDispose.push(this.recordingService.onDidRecordRequest(entry => this.historyContentUpdated(entry)));
39
+ this.toDispose.push(this.recordingService.onDidRecordResponse(entry => this.historyContentUpdated(entry)));
40
+ this.selectAgent(this.agentService.getAllAgents()[0]);
41
+ }
42
+ selectAgent(agent) {
43
+ this.selectedAgent = agent;
44
+ this.update();
45
+ }
46
+ historyContentUpdated(entry) {
47
+ var _a;
48
+ if (entry.agentId === ((_a = this.selectedAgent) === null || _a === void 0 ? void 0 : _a.id)) {
49
+ this.update();
50
+ }
51
+ }
52
+ render() {
53
+ var _a;
54
+ const selectionChange = (value) => {
55
+ this.selectedAgent = this.agentService.getAllAgents().find(agent => agent.id === value.value);
56
+ this.update();
57
+ };
58
+ return (React.createElement("div", { className: 'agent-history-widget' },
59
+ React.createElement(select_component_1.SelectComponent, { options: this.agentService.getAllAgents().map(agent => ({ value: agent.id, label: agent.name, description: agent.description })), onChange: selectionChange, defaultValue: (_a = this.selectedAgent) === null || _a === void 0 ? void 0 : _a.id }),
60
+ React.createElement("div", { className: 'agent-history' }, this.renderHistory())));
61
+ }
62
+ renderHistory() {
63
+ if (!this.selectedAgent) {
64
+ return React.createElement("div", { className: 'theia-card no-content' }, "No agent selected.");
65
+ }
66
+ const history = this.recordingService.getHistory(this.selectedAgent.id);
67
+ if (history.length === 0) {
68
+ return React.createElement("div", { className: 'theia-card no-content' },
69
+ "No history available for the selected agent '",
70
+ this.selectedAgent.name,
71
+ "'.");
72
+ }
73
+ return history.map(entry => React.createElement(ai_history_communication_card_1.CommunicationCard, { key: entry.requestId, entry: entry }));
74
+ }
75
+ onClick(e, agent) {
76
+ e.stopPropagation();
77
+ this.selectAgent(agent);
78
+ }
79
+ };
80
+ exports.AIHistoryView = AIHistoryView;
81
+ AIHistoryView.ID = 'ai-history-widget';
82
+ AIHistoryView.LABEL = '✨ AI Agent History [Experimental]';
83
+ tslib_1.__decorate([
84
+ (0, inversify_1.inject)(ai_core_1.CommunicationRecordingService),
85
+ tslib_1.__metadata("design:type", Object)
86
+ ], AIHistoryView.prototype, "recordingService", void 0);
87
+ tslib_1.__decorate([
88
+ (0, inversify_1.inject)(ai_core_1.AgentService),
89
+ tslib_1.__metadata("design:type", Object)
90
+ ], AIHistoryView.prototype, "agentService", void 0);
91
+ tslib_1.__decorate([
92
+ (0, inversify_1.postConstruct)(),
93
+ tslib_1.__metadata("design:type", Function),
94
+ tslib_1.__metadata("design:paramtypes", []),
95
+ tslib_1.__metadata("design:returntype", void 0)
96
+ ], AIHistoryView.prototype, "init", null);
97
+ exports.AIHistoryView = AIHistoryView = AIHistoryView_1 = tslib_1.__decorate([
98
+ (0, inversify_1.injectable)(),
99
+ tslib_1.__metadata("design:paramtypes", [])
100
+ ], AIHistoryView);
101
+ //# sourceMappingURL=ai-history-widget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-history-widget.js","sourceRoot":"","sources":["../../src/browser/ai-history-widget.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { CommunicationHistory, CommunicationHistoryEntry, CommunicationRecordingService, CommunicationRequestEntry, CommunicationResponseEntry } from '@theia/ai-core';
2
+ import { Emitter, Event, ILogger } from '@theia/core';
3
+ export declare class DefaultCommunicationRecordingService implements CommunicationRecordingService {
4
+ protected logger: ILogger;
5
+ protected onDidRecordRequestEmitter: Emitter<CommunicationRequestEntry>;
6
+ readonly onDidRecordRequest: Event<CommunicationRequestEntry>;
7
+ protected onDidRecordResponseEmitter: Emitter<CommunicationResponseEntry>;
8
+ readonly onDidRecordResponse: Event<CommunicationResponseEntry>;
9
+ protected history: Map<string, CommunicationHistory>;
10
+ getHistory(agentId: string): CommunicationHistory;
11
+ recordRequest(requestEntry: CommunicationHistoryEntry): void;
12
+ recordResponse(responseEntry: CommunicationHistoryEntry): void;
13
+ }
14
+ //# sourceMappingURL=communication-recording-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"communication-recording-service.d.ts","sourceRoot":"","sources":["../../src/common/communication-recording-service.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,6BAA6B,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AACvK,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtD,qBACa,oCAAqC,YAAW,6BAA6B;IAGtF,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC;IAE1B,SAAS,CAAC,yBAAyB,qCAA4C;IAC/E,QAAQ,CAAC,kBAAkB,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAwC;IAErG,SAAS,CAAC,0BAA0B,sCAA6C;IACjF,QAAQ,CAAC,mBAAmB,EAAE,KAAK,CAAC,0BAA0B,CAAC,CAAyC;IAExG,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAa;IAEjE,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,oBAAoB;IAIjD,aAAa,CAAC,YAAY,EAAE,yBAAyB,GAAG,IAAI;IAU5D,cAAc,CAAC,aAAa,EAAE,yBAAyB,GAAG,IAAI;CAejE"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DefaultCommunicationRecordingService = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const core_1 = require("@theia/core");
6
+ const inversify_1 = require("@theia/core/shared/inversify");
7
+ let DefaultCommunicationRecordingService = class DefaultCommunicationRecordingService {
8
+ constructor() {
9
+ this.onDidRecordRequestEmitter = new core_1.Emitter();
10
+ this.onDidRecordRequest = this.onDidRecordRequestEmitter.event;
11
+ this.onDidRecordResponseEmitter = new core_1.Emitter();
12
+ this.onDidRecordResponse = this.onDidRecordResponseEmitter.event;
13
+ this.history = new Map();
14
+ }
15
+ getHistory(agentId) {
16
+ return this.history.get(agentId) || [];
17
+ }
18
+ recordRequest(requestEntry) {
19
+ var _a;
20
+ this.logger.debug('Recording request:', requestEntry.request);
21
+ if (this.history.has(requestEntry.agentId)) {
22
+ (_a = this.history.get(requestEntry.agentId)) === null || _a === void 0 ? void 0 : _a.push(requestEntry);
23
+ }
24
+ else {
25
+ this.history.set(requestEntry.agentId, [requestEntry]);
26
+ }
27
+ this.onDidRecordRequestEmitter.fire(requestEntry);
28
+ }
29
+ recordResponse(responseEntry) {
30
+ this.logger.debug('Recording response:', responseEntry.response);
31
+ if (this.history.has(responseEntry.agentId)) {
32
+ const entry = this.history.get(responseEntry.agentId);
33
+ if (entry) {
34
+ const matchingRequest = entry.find(e => e.requestId === responseEntry.requestId);
35
+ if (!matchingRequest) {
36
+ throw Error('No matching request found for response');
37
+ }
38
+ matchingRequest.response = responseEntry.response;
39
+ matchingRequest.responseTime = responseEntry.timestamp - matchingRequest.timestamp;
40
+ this.onDidRecordResponseEmitter.fire(responseEntry);
41
+ }
42
+ }
43
+ }
44
+ };
45
+ exports.DefaultCommunicationRecordingService = DefaultCommunicationRecordingService;
46
+ tslib_1.__decorate([
47
+ (0, inversify_1.inject)(core_1.ILogger),
48
+ (0, inversify_1.named)('llm-communication-recorder'),
49
+ tslib_1.__metadata("design:type", Object)
50
+ ], DefaultCommunicationRecordingService.prototype, "logger", void 0);
51
+ exports.DefaultCommunicationRecordingService = DefaultCommunicationRecordingService = tslib_1.__decorate([
52
+ (0, inversify_1.injectable)()
53
+ ], DefaultCommunicationRecordingService);
54
+ //# sourceMappingURL=communication-recording-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"communication-recording-service.js","sourceRoot":"","sources":["../../src/common/communication-recording-service.ts"],"names":[],"mappings":";;;;AAgBA,sCAAsD;AACtD,4DAAyE;AAGlE,IAAM,oCAAoC,GAA1C,MAAM,oCAAoC;IAA1C;QAKO,8BAAyB,GAAG,IAAI,cAAO,EAA6B,CAAC;QACtE,uBAAkB,GAAqC,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC;QAE3F,+BAA0B,GAAG,IAAI,cAAO,EAA8B,CAAC;QACxE,wBAAmB,GAAsC,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC;QAE9F,YAAO,GAAsC,IAAI,GAAG,EAAE,CAAC;IA+BrE,CAAC;IA7BG,UAAU,CAAC,OAAe;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IAC3C,CAAC;IAED,aAAa,CAAC,YAAuC;;QACjD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;QAC9D,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;YACzC,MAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,0CAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACtD,CAAC;IAED,cAAc,CAAC,aAAwC;QACnD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;QACjE,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YACtD,IAAI,KAAK,EAAE,CAAC;gBACR,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,aAAa,CAAC,SAAS,CAAC,CAAC;gBACjF,IAAI,CAAC,eAAe,EAAE,CAAC;oBACnB,MAAM,KAAK,CAAC,wCAAwC,CAAC,CAAC;gBAC1D,CAAC;gBACD,eAAe,CAAC,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;gBAClD,eAAe,CAAC,YAAY,GAAG,aAAa,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC;gBACnF,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACxD,CAAC;QACL,CAAC;IACL,CAAC;CACJ,CAAA;AA1CY,oFAAoC;AAGnC;IADT,IAAA,kBAAM,EAAC,cAAO,CAAC;IAAE,IAAA,iBAAK,EAAC,4BAA4B,CAAC;;oEAC3B;+CAHjB,oCAAoC;IADhD,IAAA,sBAAU,GAAE;GACA,oCAAoC,CA0ChD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=communication-recording-service.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"communication-recording-service.spec.d.ts","sourceRoot":"","sources":["../../src/common/communication-recording-service.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const mock_logger_1 = require("@theia/core/lib/common/test/mock-logger");
4
+ const communication_recording_service_1 = require("./communication-recording-service");
5
+ const chai_1 = require("chai");
6
+ describe('DefaultCommunicationRecordingService', () => {
7
+ it('records history', () => {
8
+ const service = new communication_recording_service_1.DefaultCommunicationRecordingService();
9
+ service.logger = new mock_logger_1.MockLogger();
10
+ service.recordRequest({ agentId: 'agent', requestId: '1', sessionId: '1', timestamp: 100, request: 'dummy request' });
11
+ const history1 = service.getHistory('agent');
12
+ (0, chai_1.expect)(history1[0].request).to.eq('dummy request');
13
+ service.recordResponse({ agentId: 'agent', requestId: '1', sessionId: '1', timestamp: 200, response: 'dummy response' });
14
+ const history2 = service.getHistory('agent');
15
+ (0, chai_1.expect)(history2[0].request).to.eq('dummy request');
16
+ (0, chai_1.expect)(history2[0].response).to.eq('dummy response');
17
+ });
18
+ });
19
+ //# sourceMappingURL=communication-recording-service.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"communication-recording-service.spec.js","sourceRoot":"","sources":["../../src/common/communication-recording-service.spec.ts"],"names":[],"mappings":";;AAgBA,yEAAqE;AACrE,uFAAyF;AACzF,+BAA8B;AAE9B,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;IAElD,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;QACvB,MAAM,OAAO,GAAG,IAAI,sEAAoC,EAAE,CAAC;QAC1D,OAA0C,CAAC,MAAM,GAAG,IAAI,wBAAU,EAAE,CAAC;QACtE,OAAO,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;QAEtH,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAA,aAAM,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC;QAEnD,OAAO,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACzH,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAA,aAAM,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC;QACnD,IAAA,aAAM,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AAEP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './communication-recording-service';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AAgBA,cAAc,mCAAmC,CAAC"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2024 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
+ const tslib_1 = require("tslib");
19
+ tslib_1.__exportStar(require("./communication-recording-service"), exports);
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;AAEhF,4EAAkD"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@theia/ai-history",
3
+ "version": "1.54.0",
4
+ "description": "Theia - AI communication history",
5
+ "dependencies": {
6
+ "@theia/ai-core": "1.54.0",
7
+ "@theia/core": "1.54.0",
8
+ "@theia/filesystem": "1.54.0",
9
+ "@theia/output": "1.54.0",
10
+ "@theia/workspace": "1.54.0",
11
+ "minimatch": "^5.1.0",
12
+ "tslib": "^2.6.2"
13
+ },
14
+ "main": "lib/common",
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "theiaExtensions": [
19
+ {
20
+ "frontend": "lib/browser/ai-history-frontend-module"
21
+ }
22
+ ],
23
+ "keywords": [
24
+ "theia-extension"
25
+ ],
26
+ "license": "EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/eclipse-theia/theia.git"
30
+ },
31
+ "bugs": {
32
+ "url": "https://github.com/eclipse-theia/theia/issues"
33
+ },
34
+ "homepage": "https://github.com/eclipse-theia/theia",
35
+ "files": [
36
+ "lib",
37
+ "src"
38
+ ],
39
+ "scripts": {
40
+ "build": "theiaext build",
41
+ "clean": "theiaext clean",
42
+ "compile": "theiaext compile",
43
+ "lint": "theiaext lint",
44
+ "test": "theiaext test",
45
+ "watch": "theiaext watch"
46
+ },
47
+ "devDependencies": {
48
+ "@theia/ext-scripts": "1.54.0"
49
+ },
50
+ "nyc": {
51
+ "extends": "../../configs/nyc.json"
52
+ },
53
+ "gitHead": "8fb36a237db744cff6e78eaff1481e1f36bb7a69"
54
+ }
@@ -0,0 +1,48 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 EclipseSource GmbH.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+ import { CommunicationHistoryEntry } from '@theia/ai-core';
17
+ import * as React from '@theia/core/shared/react';
18
+
19
+ export interface CommunicationCardProps {
20
+ entry: CommunicationHistoryEntry;
21
+ }
22
+
23
+ export const CommunicationCard: React.FC<CommunicationCardProps> = ({ entry }) => (
24
+ <div className='theia-card'>
25
+ <div className='theia-card-meta'>
26
+ <span className='theia-card-request-id'>Request ID: {entry.requestId}</span>
27
+ <span className='theia-card-session-id'>Session ID: {entry.sessionId}</span>
28
+ </div>
29
+ <div className='theia-card-content'>
30
+ {entry.request && (
31
+ <div className='theia-card-request'>
32
+ <p><strong>Request</strong></p>
33
+ <pre>{entry.request}</pre>
34
+ </div>
35
+ )}
36
+ {entry.response && (
37
+ <div className='theia-card-response'>
38
+ <p><strong>Response</strong></p>
39
+ <pre>{entry.response}</pre>
40
+ </div>
41
+ )}
42
+ </div>
43
+ <div className='theia-card-meta'>
44
+ <span className='theia-card-timestamp'>Timestamp: {new Date(entry.timestamp).toLocaleString()}</span>
45
+ {entry.responseTime && <span className='theia-card-response-time'>Response Time: {entry.responseTime}ms</span>}
46
+ </div>
47
+ </div>
48
+ );
@@ -0,0 +1,52 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 EclipseSource GmbH.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+ import { FrontendApplication } from '@theia/core/lib/browser';
17
+ import { AIViewContribution } from '@theia/ai-core/lib/browser';
18
+ import { injectable } from '@theia/core/shared/inversify';
19
+ import { AIHistoryView } from './ai-history-widget';
20
+ import { Command, CommandRegistry } from '@theia/core';
21
+
22
+ export const AI_HISTORY_TOGGLE_COMMAND_ID = 'aiHistory:toggle';
23
+ export const OPEN_AI_HISTORY_VIEW = Command.toLocalizedCommand({
24
+ id: 'aiHistory:open',
25
+ label: 'Open AI History view',
26
+ });
27
+
28
+ @injectable()
29
+ export class AIHistoryViewContribution extends AIViewContribution<AIHistoryView> {
30
+ constructor() {
31
+ super({
32
+ widgetId: AIHistoryView.ID,
33
+ widgetName: AIHistoryView.LABEL,
34
+ defaultWidgetOptions: {
35
+ area: 'bottom',
36
+ rank: 100
37
+ },
38
+ toggleCommandId: AI_HISTORY_TOGGLE_COMMAND_ID,
39
+ });
40
+ }
41
+
42
+ async initializeLayout(_app: FrontendApplication): Promise<void> {
43
+ await this.openView();
44
+ }
45
+
46
+ override registerCommands(commands: CommandRegistry): void {
47
+ super.registerCommands(commands);
48
+ commands.registerCommand(OPEN_AI_HISTORY_VIEW, {
49
+ execute: () => this.openView({ activate: true }),
50
+ });
51
+ }
52
+ }
@@ -0,0 +1,41 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 EclipseSource GmbH.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+ import { CommunicationRecordingService } from '@theia/ai-core';
17
+ import { ContainerModule } from '@theia/core/shared/inversify';
18
+ import { DefaultCommunicationRecordingService } from '../common/communication-recording-service';
19
+ import { bindViewContribution, WidgetFactory } from '@theia/core/lib/browser';
20
+ import { ILogger } from '@theia/core';
21
+ import { AIHistoryViewContribution } from './ai-history-contribution';
22
+ import { AIHistoryView } from './ai-history-widget';
23
+ import '../../src/browser/style/ai-history.css';
24
+
25
+ export default new ContainerModule(bind => {
26
+ bind(DefaultCommunicationRecordingService).toSelf().inSingletonScope();
27
+ bind(CommunicationRecordingService).toService(DefaultCommunicationRecordingService);
28
+
29
+ bind(ILogger).toDynamicValue(ctx => {
30
+ const parentLogger = ctx.container.get<ILogger>(ILogger);
31
+ return parentLogger.child('llm-communication-recorder');
32
+ }).inSingletonScope().whenTargetNamed('llm-communication-recorder');
33
+
34
+ bindViewContribution(bind, AIHistoryViewContribution);
35
+
36
+ bind(AIHistoryView).toSelf().inSingletonScope();
37
+ bind(WidgetFactory).toDynamicValue(context => ({
38
+ id: AIHistoryView.ID,
39
+ createWidget: () => context.container.get<AIHistoryView>(AIHistoryView)
40
+ })).inSingletonScope();
41
+ });
@@ -0,0 +1,96 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 EclipseSource GmbH.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+ import { Agent, AgentService, CommunicationRecordingService, CommunicationRequestEntry, CommunicationResponseEntry } from '@theia/ai-core';
17
+ import { codicon, ReactWidget } from '@theia/core/lib/browser';
18
+ import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
19
+ import * as React from '@theia/core/shared/react';
20
+ import { CommunicationCard } from './ai-history-communication-card';
21
+ import { SelectComponent, SelectOption } from '@theia/core/lib/browser/widgets/select-component';
22
+
23
+ @injectable()
24
+ export class AIHistoryView extends ReactWidget {
25
+ @inject(CommunicationRecordingService)
26
+ protected recordingService: CommunicationRecordingService;
27
+ @inject(AgentService)
28
+ protected readonly agentService: AgentService;
29
+
30
+ public static ID = 'ai-history-widget';
31
+ static LABEL = '✨ AI Agent History [Experimental]';
32
+
33
+ protected selectedAgent?: Agent;
34
+
35
+ constructor() {
36
+ super();
37
+ this.id = AIHistoryView.ID;
38
+ this.title.label = AIHistoryView.LABEL;
39
+ this.title.caption = AIHistoryView.LABEL;
40
+ this.title.closable = true;
41
+ this.title.iconClass = codicon('history');
42
+ }
43
+
44
+ @postConstruct()
45
+ protected init(): void {
46
+ this.update();
47
+ this.toDispose.push(this.recordingService.onDidRecordRequest(entry => this.historyContentUpdated(entry)));
48
+ this.toDispose.push(this.recordingService.onDidRecordResponse(entry => this.historyContentUpdated(entry)));
49
+ this.selectAgent(this.agentService.getAllAgents()[0]);
50
+ }
51
+
52
+ protected selectAgent(agent: Agent | undefined): void {
53
+ this.selectedAgent = agent;
54
+ this.update();
55
+ }
56
+
57
+ protected historyContentUpdated(entry: CommunicationRequestEntry | CommunicationResponseEntry): void {
58
+ if (entry.agentId === this.selectedAgent?.id) {
59
+ this.update();
60
+ }
61
+ }
62
+
63
+ render(): React.ReactNode {
64
+ const selectionChange = (value: SelectOption) => {
65
+ this.selectedAgent = this.agentService.getAllAgents().find(agent => agent.id === value.value);
66
+ this.update();
67
+ };
68
+ return (
69
+ <div className='agent-history-widget'>
70
+ <SelectComponent
71
+ options={this.agentService.getAllAgents().map(agent => ({ value: agent.id, label: agent.name, description: agent.description }))}
72
+ onChange={selectionChange}
73
+ defaultValue={this.selectedAgent?.id} />
74
+ <div className='agent-history'>
75
+ {this.renderHistory()}
76
+ </div>
77
+ </div >
78
+ );
79
+ }
80
+
81
+ protected renderHistory(): React.ReactNode {
82
+ if (!this.selectedAgent) {
83
+ return <div className='theia-card no-content'>No agent selected.</div>;
84
+ }
85
+ const history = this.recordingService.getHistory(this.selectedAgent.id);
86
+ if (history.length === 0) {
87
+ return <div className='theia-card no-content'>No history available for the selected agent '{this.selectedAgent.name}'.</div>;
88
+ }
89
+ return history.map(entry => <CommunicationCard key={entry.requestId} entry={entry} />);
90
+ }
91
+
92
+ protected onClick(e: React.MouseEvent<HTMLDivElement>, agent: Agent): void {
93
+ e.stopPropagation();
94
+ this.selectAgent(agent);
95
+ }
96
+ }
@@ -0,0 +1,75 @@
1
+ .agent-history-widget {
2
+ display: flex;
3
+ flex-direction: column;
4
+ align-items: center;
5
+ }
6
+
7
+
8
+ .agent-history-widget .theia-select-component {
9
+ margin: 10px 0;
10
+ width: 80%;
11
+ }
12
+
13
+ .agent-history {
14
+ width: calc(80% + 16px);
15
+ display: flex;
16
+ align-items: center;
17
+ flex-direction: column;
18
+ }
19
+
20
+ .theia-card {
21
+ background-color: var(--theia-sideBar-background);
22
+ border: 1px solid var(--theia-sideBarSectionHeader-border);
23
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
24
+ padding: 15px;
25
+ margin: 10px 0;
26
+ width: 100%;
27
+ box-sizing: border-box;
28
+ }
29
+
30
+ .theia-card-meta {
31
+ display: flex;
32
+ justify-content: space-between;
33
+ font-size: 0.9em;
34
+ margin-bottom: var(--theia-ui-padding);
35
+ padding: var(--theia-ui-padding) 0;
36
+ }
37
+
38
+ .theia-card-content {
39
+ color: var(--theia-font-color);
40
+ margin-bottom: 10px;
41
+ }
42
+
43
+ .theia-card-content p {
44
+ margin: var(--theia-ui-padding) 0;
45
+ }
46
+
47
+ .theia-card-request, .theia-card-response {
48
+ margin-bottom: 10px;
49
+ }
50
+
51
+ .theia-card-request pre,
52
+ .theia-card-response pre {
53
+ font-family: monospace;
54
+ white-space: pre-wrap;
55
+ word-wrap: break-word;
56
+ background-color: var(--theia-sideBar-background);
57
+ margin: var(--theia-ui-padding) 0;
58
+ }
59
+
60
+ .theia-card-request-id,
61
+ .theia-card-session-id,
62
+ .theia-card-timestamp,
63
+ .theia-card-response-time {
64
+ flex: 1;
65
+ }
66
+
67
+ .theia-card-request-id,
68
+ .theia-card-timestamp {
69
+ text-align: left;
70
+ }
71
+
72
+ .theia-card-session-id,
73
+ .theia-card-response-time {
74
+ text-align: right;
75
+ }
@@ -0,0 +1,37 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 EclipseSource GmbH.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+ import { ILogger } from '@theia/core';
17
+ import { MockLogger } from '@theia/core/lib/common/test/mock-logger';
18
+ import { DefaultCommunicationRecordingService } from './communication-recording-service';
19
+ import { expect } from 'chai';
20
+
21
+ describe('DefaultCommunicationRecordingService', () => {
22
+
23
+ it('records history', () => {
24
+ const service = new DefaultCommunicationRecordingService();
25
+ (service as unknown as { logger: ILogger }).logger = new MockLogger();
26
+ service.recordRequest({ agentId: 'agent', requestId: '1', sessionId: '1', timestamp: 100, request: 'dummy request' });
27
+
28
+ const history1 = service.getHistory('agent');
29
+ expect(history1[0].request).to.eq('dummy request');
30
+
31
+ service.recordResponse({ agentId: 'agent', requestId: '1', sessionId: '1', timestamp: 200, response: 'dummy response' });
32
+ const history2 = service.getHistory('agent');
33
+ expect(history2[0].request).to.eq('dummy request');
34
+ expect(history2[0].response).to.eq('dummy response');
35
+ });
36
+
37
+ });
@@ -0,0 +1,63 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 EclipseSource GmbH.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+ import { CommunicationHistory, CommunicationHistoryEntry, CommunicationRecordingService, CommunicationRequestEntry, CommunicationResponseEntry } from '@theia/ai-core';
17
+ import { Emitter, Event, ILogger } from '@theia/core';
18
+ import { inject, injectable, named } from '@theia/core/shared/inversify';
19
+
20
+ @injectable()
21
+ export class DefaultCommunicationRecordingService implements CommunicationRecordingService {
22
+
23
+ @inject(ILogger) @named('llm-communication-recorder')
24
+ protected logger: ILogger;
25
+
26
+ protected onDidRecordRequestEmitter = new Emitter<CommunicationRequestEntry>();
27
+ readonly onDidRecordRequest: Event<CommunicationRequestEntry> = this.onDidRecordRequestEmitter.event;
28
+
29
+ protected onDidRecordResponseEmitter = new Emitter<CommunicationResponseEntry>();
30
+ readonly onDidRecordResponse: Event<CommunicationResponseEntry> = this.onDidRecordResponseEmitter.event;
31
+
32
+ protected history: Map<string, CommunicationHistory> = new Map();
33
+
34
+ getHistory(agentId: string): CommunicationHistory {
35
+ return this.history.get(agentId) || [];
36
+ }
37
+
38
+ recordRequest(requestEntry: CommunicationHistoryEntry): void {
39
+ this.logger.debug('Recording request:', requestEntry.request);
40
+ if (this.history.has(requestEntry.agentId)) {
41
+ this.history.get(requestEntry.agentId)?.push(requestEntry);
42
+ } else {
43
+ this.history.set(requestEntry.agentId, [requestEntry]);
44
+ }
45
+ this.onDidRecordRequestEmitter.fire(requestEntry);
46
+ }
47
+
48
+ recordResponse(responseEntry: CommunicationHistoryEntry): void {
49
+ this.logger.debug('Recording response:', responseEntry.response);
50
+ if (this.history.has(responseEntry.agentId)) {
51
+ const entry = this.history.get(responseEntry.agentId);
52
+ if (entry) {
53
+ const matchingRequest = entry.find(e => e.requestId === responseEntry.requestId);
54
+ if (!matchingRequest) {
55
+ throw Error('No matching request found for response');
56
+ }
57
+ matchingRequest.response = responseEntry.response;
58
+ matchingRequest.responseTime = responseEntry.timestamp - matchingRequest.timestamp;
59
+ this.onDidRecordResponseEmitter.fire(responseEntry);
60
+ }
61
+ }
62
+ }
63
+ }
@@ -0,0 +1,17 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 EclipseSource GmbH.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ export * from './communication-recording-service';