Skip to content

Commit 63387e8

Browse files
authored
Document Q&A (#140) (#141)
* Add pdfjs for reading PDF files. * Upgrade various dependeny minor versions. * Add chat button to source action bar. * Add chat model selector in chat toolbar. * chore: bump dependencies * feat(Chat): provide a list of local file types that can be read for chat purposes (PDF and plain text file types). * feat(Chat): Implement online PDF and local file processing for use in Chat. Dramatically improved the ability to summarize, especially larger documents. * chore: Remove unused functions but keep stubs for later use. * fix: a bug where theme settings were not saved to file correctly.
1 parent ce95bdb commit 63387e8

38 files changed

+1617
-471
lines changed

package.json

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "knowledge-canvas",
3-
"version": "0.8.4",
3+
"version": "0.8.5",
44
"description": "Knowledge is a tool for saving, searching, accessing, and exploring all of your favorite websites, documents and files.",
55
"author": "Rob Royce <[email protected]> (https://robroyce.dev)",
66
"license": "Apache-2.0",
@@ -43,47 +43,51 @@
4343
},
4444
"packageManager": "[email protected]",
4545
"dependencies": {
46-
"@adobe/css-tools": "^4.3.1",
47-
"async": "^3.2.4",
48-
"axios": "^1.3.4",
49-
"ejs": "^3.1.8",
46+
"@adobe/css-tools": "^4.3.2",
47+
"async": "^3.2.5",
48+
"axios": "^1.5.1",
49+
"canvas": "^2.11.2",
50+
"ejs": "^3.1.9",
5051
"express": "^4.18.2",
51-
"follow-redirects": "^1.15.2",
52+
"follow-redirects": "^1.15.3",
5253
"got": "^13.0.0",
53-
"highlight.js": "^11.8.0",
54+
"highlight.js": "^11.9.0",
5455
"html-to-text": "^9.0.5",
55-
"minimist": "^1.2.7",
56+
"minimist": "^1.2.8",
5657
"multer": "^1.4.5-lts.1",
57-
"node-fetch": "^3.3.1",
58+
"node-fetch": "^3.3.2",
5859
"node-forge": "^1.3.1",
59-
"plist": "^3.0.6",
60+
"pdfjs-dist": "^3.11.174",
61+
"plist": "^3.1.0",
6062
"postcss": "^8.4.31",
61-
"terser": "^5.15.1",
62-
"url": "^0.11.0"
63+
"terser": "^5.22.0",
64+
"url": "^0.11.3"
6365
},
6466
"devDependencies": {
6567
"@angular-devkit/architect": "^0.1402.13",
6668
"@angular/cli": "^14.2.13",
67-
"@types/async": "^3.2.15",
68-
"@types/ejs": "^3.1.1",
69+
"@types/async": "^3.2.24",
70+
"@types/ejs": "^3.1.4",
6971
"@types/eslint": "^8",
70-
"@types/express": "^4",
71-
"@types/follow-redirects": "^1.14.1",
72-
"@types/html-to-text": "^9",
73-
"@types/minimist": "^1.2.2",
74-
"@types/multer": "^1",
72+
"@types/express": "^4.17.20",
73+
"@types/follow-redirects": "^1.14.3",
74+
"@types/html-to-text": "^9.0.3",
75+
"@types/minimist": "^1.2.4",
76+
"@types/multer": "^1.4.9",
7577
"@types/node": "^17.0.45",
76-
"@types/node-forge": "^1.3.0",
77-
"@types/plist": "^3.0.2",
78-
"@types/prettier": "^2",
79-
"@types/uuid": "^9.0.1",
78+
"@types/node-forge": "^1.3.8",
79+
"@types/plist": "^3.0.4",
80+
"@types/prettier": "^2.7.3",
81+
"@types/uuid": "^9.0.6",
8082
"electron-builder": "^24.6.4",
8183
"electron-notarize": "^1.2.2",
8284
"eslint": "^8.38.0",
8385
"eslint-plugin-html": "^7.1.0",
8486
"loader-utils": "^3.2.1",
85-
"prettier": "^2.8.7",
86-
"standard-version": "^9.5.0"
87+
"node-loader": "^2.0.0",
88+
"prettier": "^2.8.8",
89+
"standard-version": "^9.5.0",
90+
"worker-loader": "^3.0.8"
8791
},
8892
"build": {
8993
"appId": "com.knowledge.canvas.app",

src/kc_angular/package.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,19 @@
3838
"@fullcalendar/timegrid": "^5.11.5",
3939
"chart.js": "^3.9.1",
4040
"chokidar": "^3.5.3",
41-
"cytoscape": "^3.23.0",
41+
"cytoscape": "^3.26.0",
4242
"cytoscape-cola": "^2.5.1",
4343
"cytoscape-dagre": "^2.5.0",
44-
"cytoscape-fcose": "^2.1.0",
44+
"cytoscape-fcose": "^2.2.0",
4545
"cytoscape-klay": "^3.1.4",
4646
"eslint": "^8.38.0",
4747
"fuse.js": "^6.6.2",
4848
"marked": "^4.3.0",
49-
"primeflex": "^3.2.1",
49+
"primeflex": "^3.3.1",
5050
"primeicons": "^6.0.1",
51-
"primeng": "^14.1.2",
51+
"primeng": "^14.2.3",
5252
"rxjs": "~7.5.7",
53-
"tslib": "^2.4.1",
53+
"tslib": "^2.6.2",
5454
"typescript": "<4.9.0",
5555
"zone.js": "^0.11.8"
5656
},
@@ -63,11 +63,11 @@
6363
"@angular-eslint/template-parser": "14.4.0",
6464
"@angular/cli": "^14.2.13",
6565
"@angular/compiler-cli": "^14.3.0",
66-
"@types/cytoscape": "^3.19.12",
67-
"@types/cytoscape-dagre": "^2.3.1",
68-
"@types/cytoscape-fcose": "^2.2.2",
69-
"@types/cytoscape-klay": "^3.1.2",
70-
"@types/marked": "^4.0.8",
66+
"@types/cytoscape": "^3.19.13",
67+
"@types/cytoscape-dagre": "^2.3.2",
68+
"@types/cytoscape-fcose": "^2.2.3",
69+
"@types/cytoscape-klay": "^3.1.3",
70+
"@types/marked": "^4.3.2",
7171
"@typescript-eslint/eslint-plugin": "5.37.0",
7272
"@typescript-eslint/parser": "5.37.0",
7373
"eslint": "^8.38.0",

src/kc_angular/src/app/app.component.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022-2023 Rob Royce
2+
* Copyright (c) 2022-2024 Rob Royce
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -210,9 +210,15 @@ export class AppComponent implements OnInit {
210210
if (ks?.force && this.sourceInfoDialog) {
211211
this.sourceInfoDialog.close();
212212
}
213+
214+
let view = 'details';
215+
if (ks?.view) {
216+
view = ks.view;
217+
}
218+
213219
if (ks && !this.sourceInfoDialog) {
214220
this.sourceInfoDialog = this.dialog.open(KsDetailsComponent, {
215-
data: { ks: ks },
221+
data: { ks: ks, view: view },
216222
width: '100vw !important',
217223
height: '100vh !important',
218224
styleClass: 'min-h-screen',

src/kc_angular/src/app/components/calendar.component.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022-2023 Rob Royce
2+
* Copyright (c) 2022-2024 Rob Royce
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -51,9 +51,11 @@ import { take, tap } from 'rxjs/operators';
5151
(onRemove)="onRemove($event)"
5252
(onEdit)="onEdit($event)"
5353
(onOpen)="onOpen($event)"
54+
(onChat)="onChat($event)"
5455
(onPreview)="onPreview($event)"
5556
(onTopicClick)="onTopicClick($event)"
5657
[ks]="selectedKs"
58+
[showChat]="true"
5759
>
5860
</app-ks-card>
5961
<app-project-card
@@ -155,6 +157,10 @@ export class CalendarComponent implements OnDestroy {
155157
this.command.open(ks);
156158
}
157159

160+
onChat(ks: KnowledgeSource) {
161+
this.command.chat(ks);
162+
}
163+
158164
onPreview(ks: KnowledgeSource) {
159165
this.command.preview(ks);
160166
}

src/kc_angular/src/app/components/chat-components/chat.toolbar.component.ts

Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023 Rob Royce
2+
* Copyright (c) 2023-2024 Rob Royce
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,8 +16,11 @@
1616

1717
import { Component, EventEmitter, Output } from '@angular/core';
1818
import { BehaviorSubject, skip } from 'rxjs';
19-
import { debounceTime, tap } from 'rxjs/operators';
19+
import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators';
2020
import { SettingsService } from '@services/ipc-services/settings.service';
21+
import { ChatModel, SupportedChatModels } from '@shared/models/chat.model';
22+
import { FormBuilder, FormGroup } from '@angular/forms';
23+
import { ChatSettingsModel } from '@shared/models/settings.model';
2124

2225
@Component({
2326
selector: 'chat-toolbar',
@@ -26,7 +29,17 @@ import { SettingsService } from '@services/ipc-services/settings.service';
2629
class="flex flex-row justify-content-between top-0 pb-2"
2730
id="chat-toolbar"
2831
>
29-
<div></div>
32+
<div class="chat-toolbar-model-selector">
33+
<form [formGroup]="form">
34+
<p-dropdown
35+
class="settings-input w-12rem"
36+
formControlName="modelName"
37+
[options]="SupportedChatModels"
38+
optionLabel="label"
39+
optionValue="name"
40+
></p-dropdown>
41+
</form>
42+
</div>
3043
3144
<div class="chat-toolbar-filter">
3245
<div class="p-inputgroup p-fluid mr-3 ml-3 w-24rem">
@@ -92,7 +105,26 @@ export class ChatToolbarComponent {
92105
private _filter$ = new BehaviorSubject<string>('');
93106
filter$ = this._filter$.asObservable();
94107

95-
constructor(private settings: SettingsService) {
108+
form: FormGroup;
109+
110+
settingsModel: ChatSettingsModel = new ChatSettingsModel();
111+
112+
constructor(private settings: SettingsService, private fb: FormBuilder) {
113+
const chatSettings = this.settings.get().app.chat;
114+
if (!chatSettings) {
115+
this.set();
116+
} else {
117+
this.settingsModel = {
118+
...this.chatSettings,
119+
...chatSettings,
120+
};
121+
}
122+
123+
// Create form group for chat model selector
124+
this.form = this.fb.group({
125+
modelName: [this.settingsModel.model.name],
126+
});
127+
96128
this.filter$
97129
.pipe(
98130
skip(1),
@@ -102,18 +134,71 @@ export class ChatToolbarComponent {
102134
})
103135
)
104136
.subscribe();
137+
138+
// Listen for changes in the chat model setting, update if there are any
139+
this.form.valueChanges
140+
.pipe(
141+
debounceTime(500),
142+
distinctUntilChanged(),
143+
tap((formValue) => {
144+
let model: ChatModel;
145+
146+
// If the model has changed, update the local copy with static values from the SupportedChatModels array.
147+
if (formValue.modelName !== this.settingsModel.model.name) {
148+
model =
149+
SupportedChatModels.find((m) => m.name === formValue.modelName) ??
150+
this.settingsModel.model;
151+
} else {
152+
return;
153+
}
154+
155+
this.settingsModel = {
156+
display: this.settingsModel.display,
157+
suggestions: this.settingsModel.suggestions,
158+
model: model,
159+
};
160+
this.set();
161+
})
162+
)
163+
.subscribe();
164+
165+
this.settings.all
166+
.pipe(
167+
tap((settings) => {
168+
if (settings.app.chat) {
169+
this.settingsModel = {
170+
...this.settingsModel,
171+
...settings.app.chat,
172+
};
173+
this.form.patchValue({
174+
modelName: this.settingsModel.model.name,
175+
});
176+
}
177+
})
178+
)
179+
.subscribe();
105180
}
106181

107182
/* Filter the chat based on the value of the filter input */
108183
filter(value: string) {
109184
this._filter$.next(value);
110185
}
111186

187+
private set() {
188+
this.settings.set({
189+
app: {
190+
chat: this.settingsModel,
191+
},
192+
});
193+
}
194+
112195
chatSettings() {
113196
this.settings.show('chat');
114197
}
115198

116199
clearChat() {
117200
this.onClear.emit();
118201
}
202+
203+
protected readonly SupportedChatModels = SupportedChatModels;
119204
}

src/kc_angular/src/app/components/settings/display-settings.component.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022-2023 Rob Royce
2+
* Copyright (c) 2022-2024 Rob Royce
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -255,6 +255,10 @@ export class DisplaySettingsComponent {
255255
this.send(this.channels.zoomOut, this.displaySettings.zoom);
256256
}
257257

258+
const themeSettings = this.themeService.findTheme(
259+
formValue.theme.code
260+
);
261+
258262
this.displaySettings = {
259263
autoplay: formValue.autoplay,
260264
logging: {
@@ -263,7 +267,7 @@ export class DisplaySettingsComponent {
263267
warn: warn ?? this.displaySettings.logging.warn,
264268
},
265269
syncTheme: formValue.syncTheme,
266-
theme: formValue.theme,
270+
theme: themeSettings,
267271
zoom: formValue.zoom,
268272
animations: formValue.animations,
269273
};

0 commit comments

Comments
 (0)