@things-factory/ai-assistant 10.1.250 → 10.1.256
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/dist-server/service/help-documents/help-tools.d.ts +4 -4
- package/dist-server/service/help-documents/help-tools.js +10 -8
- package/dist-server/service/help-documents/help-tools.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/server/service/help-documents/help-tools.test.ts +8 -8
- package/server/service/help-documents/help-tools.ts +10 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/ai-assistant",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.256",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"things-factory": true,
|
|
6
6
|
"author": "heartyoh",
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
"@operato/shell": "^10.29.39",
|
|
36
36
|
"@operato/styles": "^10.0.0",
|
|
37
37
|
"@operato/utils": "^10.29.39",
|
|
38
|
-
"@things-factory/ai-client-base": "^10.1.
|
|
39
|
-
"@things-factory/apptool-base": "^10.1.
|
|
40
|
-
"@things-factory/attachment-base": "^10.1.
|
|
41
|
-
"@things-factory/auth-base": "^10.1.
|
|
38
|
+
"@things-factory/ai-client-base": "^10.1.256",
|
|
39
|
+
"@things-factory/apptool-base": "^10.1.254",
|
|
40
|
+
"@things-factory/attachment-base": "^10.1.256",
|
|
41
|
+
"@things-factory/auth-base": "^10.1.256",
|
|
42
42
|
"@things-factory/env": "^10.1.149",
|
|
43
|
-
"@things-factory/help": "^10.1.
|
|
44
|
-
"@things-factory/setting-base": "^10.1.
|
|
45
|
-
"@things-factory/shell": "^10.1.
|
|
43
|
+
"@things-factory/help": "^10.1.254",
|
|
44
|
+
"@things-factory/setting-base": "^10.1.256",
|
|
45
|
+
"@things-factory/shell": "^10.1.254",
|
|
46
46
|
"dompurify": "^3.0.0",
|
|
47
47
|
"exceljs": "4.2.0",
|
|
48
48
|
"graphql-scalars": "^1.22.0",
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"copyfiles": "^2.4.1",
|
|
59
59
|
"rimraf": "^5.0.0"
|
|
60
60
|
},
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "2fd641697190ce6e87bcf454a60b2321553e8110"
|
|
62
62
|
}
|
|
@@ -7,7 +7,7 @@ jest.mock('@things-factory/help', () => {
|
|
|
7
7
|
...partsOfDocument('office/guide-employee.ko.html', '<h1>모든 직원</h1><h2 id="spending">경비 · 지출 올리기</h2><p>내 정보 › 내 지출결의 에서 새 결의를 작성합니다.</p>'),
|
|
8
8
|
...partsOfDocument('office/guide-employee.html', '<h1>Everyone</h1><h2 id="spending">Spending</h2><p>Write a new claim in My expense claims.</p>')
|
|
9
9
|
])
|
|
10
|
-
return { searchHelp: (q: string, o: any) => index.search(q, o), readHelp: (t: string, s: string, l: string) => index.read(t, s, l) }
|
|
10
|
+
return { searchHelp: async (q: string, o: any) => index.search(q, o), readHelp: async (t: string, s: string, l: string) => index.read(t, s, l) }
|
|
11
11
|
})
|
|
12
12
|
|
|
13
13
|
import { helpCategory, readHelpDocument, searchHelpDocuments } from './help-tools'
|
|
@@ -16,20 +16,20 @@ import { modeFrontCategories, modeToolCategories } from '../assistant-mode/mode-
|
|
|
16
16
|
const korean = { state: { lng: 'ko' } }
|
|
17
17
|
|
|
18
18
|
describe('the help tools', () => {
|
|
19
|
-
it('finds a part with its title and its link', () => {
|
|
20
|
-
expect(searchHelpDocuments({ query: '지출결의 올리기' }, korean)).toEqual({
|
|
19
|
+
it('finds a part with its title and its link', async () => {
|
|
20
|
+
expect(await searchHelpDocuments({ query: '지출결의 올리기' }, korean)).toEqual({
|
|
21
21
|
found: 1,
|
|
22
22
|
parts: [{ topic: 'office/guide-employee', section: 'spending', title: '모든 직원 › 경비 · 지출 올리기', summary: '내 정보 › 내 지출결의 에서 새 결의를 작성합니다.', link: 'help?topic=office%2Fguide-employee§ion=spending' }]
|
|
23
23
|
})
|
|
24
24
|
})
|
|
25
25
|
|
|
26
|
-
it('says when the help has nothing, so the model does not answer from elsewhere', () => {
|
|
27
|
-
expect(searchHelpDocuments({ query: '주식 매수 방법' }, korean)).toMatchObject({ found: 0, message: expect.stringContaining('say so') })
|
|
26
|
+
it('says when the help has nothing, so the model does not answer from elsewhere', async () => {
|
|
27
|
+
expect(await searchHelpDocuments({ query: '주식 매수 방법' }, korean)).toMatchObject({ found: 0, message: expect.stringContaining('say so') })
|
|
28
28
|
})
|
|
29
29
|
|
|
30
|
-
it('reads a part in the person\'s language', () => {
|
|
31
|
-
expect(readHelpDocument({ topic: 'office/guide-employee', section: 'spending' }, { state: { lng: 'en' } })).toMatchObject({ found: true, title: 'Spending' })
|
|
32
|
-
expect(readHelpDocument({ topic: 'office/guide-employee', section: 'none' }, korean)).toMatchObject({ found: false })
|
|
30
|
+
it('reads a part in the person\'s language', async () => {
|
|
31
|
+
expect(await readHelpDocument({ topic: 'office/guide-employee', section: 'spending' }, { state: { lng: 'en' } })).toMatchObject({ found: true, title: 'Spending' })
|
|
32
|
+
expect(await readHelpDocument({ topic: 'office/guide-employee', section: 'none' }, korean)).toMatchObject({ found: false })
|
|
33
33
|
})
|
|
34
34
|
|
|
35
35
|
it('reaches no door, and every conversation has it in front', () => {
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* and reads it, rather than the mode's prompt carrying the manual.
|
|
5
5
|
*
|
|
6
6
|
* The help is no one's secret - every screen's `?` opens it for whoever is there - so the tools reach no door. Whether
|
|
7
|
-
* the person may open the screen a part names is still that screen's own door.
|
|
7
|
+
* the person may open the screen a part names is still that screen's own door. A source's parts - the company's rules
|
|
8
|
+
* (ADR-0187 decision 12) - are found only where the source lets the person read them; they open where the source says.
|
|
8
9
|
*/
|
|
9
10
|
import { registerToolCategory, type ToolCategory, type ToolSpec } from '@things-factory/ai-client-base'
|
|
10
11
|
import { readHelp, searchHelp } from '@things-factory/help'
|
|
@@ -16,25 +17,25 @@ export const helpLink = (topic: string, section = '') => `help?topic=${encodeURI
|
|
|
16
17
|
|
|
17
18
|
const languageOf = (context: any): string | undefined => context?.state?.lng || context?.state?.language || undefined
|
|
18
19
|
|
|
19
|
-
export function searchHelpDocuments(args: { query?: string; limit?: number }, context?: any) {
|
|
20
|
+
export async function searchHelpDocuments(args: { query?: string; limit?: number }, context?: any) {
|
|
20
21
|
const query = String(args?.query ?? '').trim()
|
|
21
22
|
if (!query) return { found: 0, parts: [], message: 'name what to look for.' }
|
|
22
|
-
const parts = searchHelp(query, { lang: languageOf(context), limit: Math.min(Math.max(Number(args?.limit) || 5, 1), 10) }).map(hit => ({
|
|
23
|
+
const parts = (await searchHelp(query, { lang: languageOf(context), limit: Math.min(Math.max(Number(args?.limit) || 5, 1), 10), context })).map(hit => ({
|
|
23
24
|
topic: hit.topic,
|
|
24
25
|
section: hit.section,
|
|
25
26
|
title: hit.documentTitle === hit.title ? hit.title : `${hit.documentTitle} › ${hit.title}`,
|
|
26
27
|
summary: hit.summary,
|
|
27
|
-
link: helpLink(hit.topic, hit.section)
|
|
28
|
+
link: hit.link ?? helpLink(hit.topic, hit.section)
|
|
28
29
|
}))
|
|
29
30
|
return parts.length ? { found: parts.length, parts } : { found: 0, parts: [], message: 'the help has nothing on this - say so; do not answer from general knowledge as if it were this application.' }
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
export function readHelpDocument(args: { topic?: string; section?: string }, context?: any) {
|
|
33
|
+
export async function readHelpDocument(args: { topic?: string; section?: string }, context?: any) {
|
|
33
34
|
const topic = String(args?.topic ?? '').trim()
|
|
34
35
|
const section = String(args?.section ?? '').trim()
|
|
35
|
-
const part = topic ? readHelp(topic, section, languageOf(context)) : null
|
|
36
|
+
const part = topic ? await readHelp(topic, section, languageOf(context), context) : null
|
|
36
37
|
if (!part) return { found: false, message: `no help part ${topic}${section ? `#${section}` : ''} - search again with searchHelp.` }
|
|
37
|
-
return { found: true, ...part, link: helpLink(part.topic, part.section) }
|
|
38
|
+
return { found: true, ...part, link: part.link ?? helpLink(part.topic, part.section) }
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
const searchSpec = {
|
|
@@ -78,7 +79,8 @@ export const helpCategory: ToolCategory = {
|
|
|
78
79
|
'- When the person asks how to do something in this application, where a screen or menu is, what the steps are, or what a term on a screen means, call searchHelp, then readHelp on the part that answers it - before you answer.',
|
|
79
80
|
'- Answer from what readHelp returned, in your own short words, and end with the part as a link: [its title](its link). Never invent a menu, a button or a step the help does not name.',
|
|
80
81
|
'- When searchHelp finds nothing, say the help does not cover it; then answer only what your other tools show.',
|
|
81
|
-
'- The help says how the application works; figures and records still come from the other tools.'
|
|
82
|
+
'- The help says how the application works; figures and records still come from the other tools.',
|
|
83
|
+
"- A part of the company's own rules (a topic under regulation/) is the company's: answer with the article and its effective day as a link. Where the guidance on the law and the company's rule read differently, show both and do not judge between them."
|
|
82
84
|
].join('\n'),
|
|
83
85
|
specs: [searchSpec, readSpec]
|
|
84
86
|
}
|