cozy-viewer 26.2.2 → 26.3.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.
- package/CHANGELOG.md +17 -0
- package/dist/Footer/FooterContent.js +1 -1
- package/dist/Panel/AI/AIAssistantPanel.js +1 -1
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +20 -2
- package/package.json +3 -3
- package/src/Footer/FooterContent.jsx +1 -1
- package/src/Panel/AI/AIAssistantPanel.jsx +4 -2
- package/src/helpers.js +17 -0
- package/src/helpers.spec.js +34 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,23 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [26.3.0](https://github.com/cozy/cozy-libs/compare/cozy-viewer@26.2.3...cozy-viewer@26.3.0) (2025-12-23)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- Handle Windows CRLF line endings :bug: ([e415041](https://github.com/cozy/cozy-libs/commit/e41504102b12b0d51a63db368c4c028c5d1e18c3))
|
|
11
|
+
- Resolve failed test cases :bug: ([8a7bc67](https://github.com/cozy/cozy-libs/commit/8a7bc67aa3856b4707b69bd8e2deafc21a9d4827))
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
- Sanitize text content for AI ([6a4dc7b](https://github.com/cozy/cozy-libs/commit/6a4dc7bc52126a39fd89284cfd3c7b142699c5eb))
|
|
16
|
+
|
|
17
|
+
## [26.2.3](https://github.com/cozy/cozy-libs/compare/cozy-viewer@26.2.2...cozy-viewer@26.2.3) (2025-12-20)
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
- **cozy-viewer:** Reduce the default height of the bottom sheet ([808bddd](https://github.com/cozy/cozy-libs/commit/808bdddaf6675e73e5b1d87ec8d4dfe26e9f32a7))
|
|
22
|
+
|
|
6
23
|
## [26.2.2](https://github.com/cozy/cozy-libs/compare/cozy-viewer@26.2.1...cozy-viewer@26.2.2) (2025-12-16)
|
|
7
24
|
|
|
8
25
|
### Bug Fixes
|
|
@@ -67,7 +67,7 @@ var FooterContent = function FooterContent(_ref) {
|
|
|
67
67
|
});
|
|
68
68
|
var bottomSheetSettings = {
|
|
69
69
|
isOpenMin: true,
|
|
70
|
-
mediumHeightRatio: isPublic ? undefined : 0.
|
|
70
|
+
mediumHeightRatio: isPublic ? undefined : 0.2
|
|
71
71
|
};
|
|
72
72
|
return /*#__PURE__*/_react.default.createElement(_BottomSheet.default, {
|
|
73
73
|
toolbarProps: toolbarProps,
|
|
@@ -146,7 +146,7 @@ var AIAssistantPanel = function AIAssistantPanel(_ref) {
|
|
|
146
146
|
|
|
147
147
|
case 7:
|
|
148
148
|
rawTextContent = _context.sent;
|
|
149
|
-
textContent = rawTextContent ? JSON.stringify(rawTextContent) : '';
|
|
149
|
+
textContent = rawTextContent ? (0, _helpers.sanitizeText)(JSON.stringify(rawTextContent)) : '';
|
|
150
150
|
summaryConfig = (0, _cozyFlags.default)('drive.summary');
|
|
151
151
|
|
|
152
152
|
if (!(summaryConfig !== null && summaryConfig !== void 0 && summaryConfig.maxTokens && (0, _helpers.roughTokensEstimation)(textContent) > summaryConfig.maxTokens)) {
|
package/dist/helpers.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export function makeWebLink({ client, slug, path }: {
|
|
|
13
13
|
}): string;
|
|
14
14
|
export function removeFilenameFromPath(path: string): string;
|
|
15
15
|
export function roughTokensEstimation(text: string): number;
|
|
16
|
+
export function sanitizeText(text: string): string;
|
|
16
17
|
export function isFileSummaryCompatible(file: object, options?: {
|
|
17
18
|
pageCount: number;
|
|
18
19
|
}): boolean;
|
package/dist/helpers.js
CHANGED
|
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
-
exports.roughTokensEstimation = exports.removeFilenameFromPath = exports.normalizeAndSpreadAttributes = exports.makeWebLink = exports.isFileSummaryCompatible = exports.isFileEncrypted = exports.isEditableAttribute = exports.formatDate = void 0;
|
|
8
|
+
exports.sanitizeText = exports.roughTokensEstimation = exports.removeFilenameFromPath = exports.normalizeAndSpreadAttributes = exports.makeWebLink = exports.isFileSummaryCompatible = exports.isFileEncrypted = exports.isEditableAttribute = exports.formatDate = void 0;
|
|
9
9
|
|
|
10
10
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
11
|
|
|
@@ -115,6 +115,24 @@ exports.removeFilenameFromPath = removeFilenameFromPath;
|
|
|
115
115
|
var roughTokensEstimation = function roughTokensEstimation(text) {
|
|
116
116
|
return Math.ceil(text.length / 4);
|
|
117
117
|
};
|
|
118
|
+
/**
|
|
119
|
+
* Sanitize text, typically from after file text extraction
|
|
120
|
+
* @param {string} text - The text to sanitize
|
|
121
|
+
* @returns {string} The sanitized text
|
|
122
|
+
*/
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
exports.roughTokensEstimation = roughTokensEstimation;
|
|
126
|
+
|
|
127
|
+
var sanitizeText = function sanitizeText(text) {
|
|
128
|
+
if (!text) return '';
|
|
129
|
+
return text.replace(/\r\n?/g, '\n') // Normalize line endings
|
|
130
|
+
.replace(/[^\S\r\n]{4,}/g, ' ') // Compress spaces
|
|
131
|
+
.replace(/\n{2,}/g, '\n') // Remove empty lines
|
|
132
|
+
// eslint-disable-next-line no-control-regex
|
|
133
|
+
.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '') // Remove control chars
|
|
134
|
+
;
|
|
135
|
+
};
|
|
118
136
|
/**
|
|
119
137
|
* Check if a file is compatible with AI summary feature
|
|
120
138
|
* Compatible file types are defined in the drive.summary flag
|
|
@@ -126,7 +144,7 @@ var roughTokensEstimation = function roughTokensEstimation(text) {
|
|
|
126
144
|
*/
|
|
127
145
|
|
|
128
146
|
|
|
129
|
-
exports.
|
|
147
|
+
exports.sanitizeText = sanitizeText;
|
|
130
148
|
|
|
131
149
|
var isFileSummaryCompatible = function isFileSummaryCompatible(file) {
|
|
132
150
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-viewer",
|
|
3
|
-
"version": "26.
|
|
3
|
+
"version": "26.3.0",
|
|
4
4
|
"description": "Cozy-Viewer provides a component to show files in a viewer.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"babel-preset-cozy-app": "^2.8.2",
|
|
32
32
|
"cozy-client": "^60.20.0",
|
|
33
33
|
"cozy-device-helper": "2.0.0",
|
|
34
|
-
"cozy-harvest-lib": "^36.0.
|
|
34
|
+
"cozy-harvest-lib": "^36.0.13",
|
|
35
35
|
"cozy-intent": "^2.30.1",
|
|
36
36
|
"cozy-logger": "^1.17.0",
|
|
37
37
|
"cozy-sharing": "^28.1.2",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"react-router-dom": ">=6.14.2",
|
|
71
71
|
"twake-i18n": ">=0.3.0"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "6b0e77a72b8e001001efccbee4a99bc03aa3563d"
|
|
74
74
|
}
|
|
@@ -23,7 +23,7 @@ import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert'
|
|
|
23
23
|
|
|
24
24
|
import { SUMMARY_SYSTEM_PROMPT, getSummaryUserPrompt } from './prompts'
|
|
25
25
|
import styles from './styles.styl'
|
|
26
|
-
import { roughTokensEstimation } from '../../helpers'
|
|
26
|
+
import { roughTokensEstimation, sanitizeText } from '../../helpers'
|
|
27
27
|
import { useViewer } from '../../providers/ViewerProvider'
|
|
28
28
|
|
|
29
29
|
const AIAssistantPanel = ({ className }) => {
|
|
@@ -57,7 +57,9 @@ const AIAssistantPanel = ({ className }) => {
|
|
|
57
57
|
name: file.name,
|
|
58
58
|
mime: file.mime
|
|
59
59
|
})
|
|
60
|
-
const textContent = rawTextContent
|
|
60
|
+
const textContent = rawTextContent
|
|
61
|
+
? sanitizeText(JSON.stringify(rawTextContent))
|
|
62
|
+
: ''
|
|
61
63
|
|
|
62
64
|
const summaryConfig = flag('drive.summary')
|
|
63
65
|
if (
|
package/src/helpers.js
CHANGED
|
@@ -84,6 +84,23 @@ export const roughTokensEstimation = text => {
|
|
|
84
84
|
return Math.ceil(text.length / 4)
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Sanitize text, typically from after file text extraction
|
|
89
|
+
* @param {string} text - The text to sanitize
|
|
90
|
+
* @returns {string} The sanitized text
|
|
91
|
+
*/
|
|
92
|
+
export const sanitizeText = text => {
|
|
93
|
+
if (!text) return ''
|
|
94
|
+
return (
|
|
95
|
+
text
|
|
96
|
+
.replace(/\r\n?/g, '\n') // Normalize line endings
|
|
97
|
+
.replace(/[^\S\r\n]{4,}/g, ' ') // Compress spaces
|
|
98
|
+
.replace(/\n{2,}/g, '\n') // Remove empty lines
|
|
99
|
+
// eslint-disable-next-line no-control-regex
|
|
100
|
+
.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '') // Remove control chars
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
87
104
|
/**
|
|
88
105
|
* Check if a file is compatible with AI summary feature
|
|
89
106
|
* Compatible file types are defined in the drive.summary flag
|
package/src/helpers.spec.js
CHANGED
|
@@ -3,7 +3,8 @@ import flag from 'cozy-flags'
|
|
|
3
3
|
import {
|
|
4
4
|
isEditableAttribute,
|
|
5
5
|
removeFilenameFromPath,
|
|
6
|
-
isFileSummaryCompatible
|
|
6
|
+
isFileSummaryCompatible,
|
|
7
|
+
sanitizeText
|
|
7
8
|
} from './helpers'
|
|
8
9
|
|
|
9
10
|
jest.mock('cozy-flags')
|
|
@@ -193,4 +194,36 @@ describe('helpers', () => {
|
|
|
193
194
|
expect(isFileSummaryCompatible({ mime: 'application/pdf' })).toBe(true)
|
|
194
195
|
})
|
|
195
196
|
})
|
|
197
|
+
|
|
198
|
+
describe('sanitizeText', () => {
|
|
199
|
+
it('compresses 4+ consecutive spaces into a single space', () => {
|
|
200
|
+
const input = 'Hello world !'
|
|
201
|
+
const output = sanitizeText(input)
|
|
202
|
+
expect(output).toBe('Hello world !')
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
it('does not modify sequences of less than 4 spaces', () => {
|
|
206
|
+
const input = 'a b c d'
|
|
207
|
+
const output = sanitizeText(input)
|
|
208
|
+
expect(output).toBe('a b c d')
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
it('collapses multiple empty lines into a single newline', () => {
|
|
212
|
+
const input = 'line 1\n\n\nline 2\nline 3'
|
|
213
|
+
const output = sanitizeText(input)
|
|
214
|
+
expect(output).toBe('line 1\nline 2\nline 3')
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
it('removes ASCII control characters but keeps accents and punctuation', () => {
|
|
218
|
+
const input = 'A\u0001B\u001F C éàç €'
|
|
219
|
+
const output = sanitizeText(input)
|
|
220
|
+
expect(output).toBe('AB C éàç €')
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
it('handles a mix of spaces, newlines and control characters', () => {
|
|
224
|
+
const input = 'Foo \n\n\nbar\u0003 baz'
|
|
225
|
+
const output = sanitizeText(input)
|
|
226
|
+
expect(output).toBe('Foo \nbar baz')
|
|
227
|
+
})
|
|
228
|
+
})
|
|
196
229
|
})
|