@things-factory/ai-assistant 10.1.53 → 10.1.79
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/client/components/assistant-dock.ts +44 -5
- package/client/setup-assistant-dock.ts +54 -19
- package/client/utils/assistant-ask.ts +8 -0
- package/dist-client/components/assistant-dock.d.ts +1 -0
- package/dist-client/components/assistant-dock.js +47 -5
- package/dist-client/components/assistant-dock.js.map +1 -1
- package/dist-client/setup-assistant-dock.js +54 -19
- package/dist-client/setup-assistant-dock.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/utils/assistant-ask.d.ts +5 -0
- package/dist-client/utils/assistant-ask.js +7 -0
- package/dist-client/utils/assistant-ask.js.map +1 -1
- package/package.json +6 -6
- package/test/assistant-dock.test.ts +20 -0
- package/translations/en.json +2 -1
- package/translations/ja.json +2 -1
- package/translations/ko.json +2 -1
- package/translations/ms.json +2 -1
- package/translations/zh.json +2 -1
|
@@ -17,6 +17,11 @@ export interface AssistantAsk {
|
|
|
17
17
|
}
|
|
18
18
|
type Listener = () => void;
|
|
19
19
|
export declare function askAssistant(ask: AssistantAsk): void;
|
|
20
|
+
/**
|
|
21
|
+
* The dock could not take it yet and keeps it for when a conversation stands - a draft only. Nothing is announced:
|
|
22
|
+
* it was already asked for, and announcing would make the dock take it again at once.
|
|
23
|
+
*/
|
|
24
|
+
export declare function holdAssistantAsk(ask: AssistantAsk): void;
|
|
20
25
|
/** The dock takes the request once. */
|
|
21
26
|
export declare function takeAssistantAsk(): AssistantAsk | undefined;
|
|
22
27
|
export declare function subscribeAssistantAsk(listener: Listener): () => void;
|
|
@@ -5,6 +5,13 @@ export function askAssistant(ask) {
|
|
|
5
5
|
listeners.forEach(listener => listener());
|
|
6
6
|
window.dispatchEvent(new CustomEvent('assistant-dock-open'));
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* The dock could not take it yet and keeps it for when a conversation stands - a draft only. Nothing is announced:
|
|
10
|
+
* it was already asked for, and announcing would make the dock take it again at once.
|
|
11
|
+
*/
|
|
12
|
+
export function holdAssistantAsk(ask) {
|
|
13
|
+
pending = ask;
|
|
14
|
+
}
|
|
8
15
|
/** The dock takes the request once. */
|
|
9
16
|
export function takeAssistantAsk() {
|
|
10
17
|
const ask = pending;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistant-ask.js","sourceRoot":"","sources":["../../client/utils/assistant-ask.ts"],"names":[],"mappings":"AAwBA,IAAI,OAAiC,CAAA;AACrC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAY,CAAA;AAErC,MAAM,UAAU,YAAY,CAAC,GAAiB;IAC5C,OAAO,GAAG,GAAG,CAAA;IACb,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAA;IACzC,MAAM,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,qBAAqB,CAAC,CAAC,CAAA;AAC9D,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,gBAAgB;IAC9B,MAAM,GAAG,GAAG,OAAO,CAAA;IACnB,OAAO,GAAG,SAAS,CAAA;IACnB,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,QAAkB;IACtD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACvB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;AACzC,CAAC","sourcesContent":["/*\n * Asking the assistant from another screen - `askAssistant()` (design/ai/shared-dock.md §2-11).\n *\n * Generalised from operato-twin's promotion channel and operato-plant's ask box: a toast's \"ask AI\", a\n * header ask box, a performance page carrying its context. The request waits here until the dock takes it,\n * so a dock that is closed (not mounted) still gets it when it opens.\n */\nexport interface AssistantAsk {\n /** Sent as the next question. */\n ask?: string\n /** Put in the input, not sent. */\n draft?: string\n /** Ask in the open conversation instead of a new one. */\n continueCurrent?: boolean\n /** A new conversation's name. */\n name?: string\n /** Turns carried into the new conversation before the question. */\n transcript?: { role: 'user' | 'ai'; content: string }[]\n /** A note stored first: what the screen was showing when the person asked. */\n context?: string\n}\n\ntype Listener = () => void\n\nlet pending: AssistantAsk | undefined\nconst listeners = new Set<Listener>()\n\nexport function askAssistant(ask: AssistantAsk): void {\n pending = ask\n listeners.forEach(listener => listener())\n window.dispatchEvent(new CustomEvent('assistant-dock-open'))\n}\n\n/** The dock takes the request once. */\nexport function takeAssistantAsk(): AssistantAsk | undefined {\n const ask = pending\n pending = undefined\n return ask\n}\n\nexport function subscribeAssistantAsk(listener: Listener): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"assistant-ask.js","sourceRoot":"","sources":["../../client/utils/assistant-ask.ts"],"names":[],"mappings":"AAwBA,IAAI,OAAiC,CAAA;AACrC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAY,CAAA;AAErC,MAAM,UAAU,YAAY,CAAC,GAAiB;IAC5C,OAAO,GAAG,GAAG,CAAA;IACb,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAA;IACzC,MAAM,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,qBAAqB,CAAC,CAAC,CAAA;AAC9D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAiB;IAChD,OAAO,GAAG,GAAG,CAAA;AACf,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,gBAAgB;IAC9B,MAAM,GAAG,GAAG,OAAO,CAAA;IACnB,OAAO,GAAG,SAAS,CAAA;IACnB,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,QAAkB;IACtD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACvB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;AACzC,CAAC","sourcesContent":["/*\n * Asking the assistant from another screen - `askAssistant()` (design/ai/shared-dock.md §2-11).\n *\n * Generalised from operato-twin's promotion channel and operato-plant's ask box: a toast's \"ask AI\", a\n * header ask box, a performance page carrying its context. The request waits here until the dock takes it,\n * so a dock that is closed (not mounted) still gets it when it opens.\n */\nexport interface AssistantAsk {\n /** Sent as the next question. */\n ask?: string\n /** Put in the input, not sent. */\n draft?: string\n /** Ask in the open conversation instead of a new one. */\n continueCurrent?: boolean\n /** A new conversation's name. */\n name?: string\n /** Turns carried into the new conversation before the question. */\n transcript?: { role: 'user' | 'ai'; content: string }[]\n /** A note stored first: what the screen was showing when the person asked. */\n context?: string\n}\n\ntype Listener = () => void\n\nlet pending: AssistantAsk | undefined\nconst listeners = new Set<Listener>()\n\nexport function askAssistant(ask: AssistantAsk): void {\n pending = ask\n listeners.forEach(listener => listener())\n window.dispatchEvent(new CustomEvent('assistant-dock-open'))\n}\n\n/**\n * The dock could not take it yet and keeps it for when a conversation stands - a draft only. Nothing is announced:\n * it was already asked for, and announcing would make the dock take it again at once.\n */\nexport function holdAssistantAsk(ask: AssistantAsk): void {\n pending = ask\n}\n\n/** The dock takes the request once. */\nexport function takeAssistantAsk(): AssistantAsk | undefined {\n const ask = pending\n pending = undefined\n return ask\n}\n\nexport function subscribeAssistantAsk(listener: Listener): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n}\n"]}
|
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.79",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"things-factory": true,
|
|
6
6
|
"author": "heartyoh",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"@operato/shell": "^10.0.0",
|
|
35
35
|
"@operato/styles": "^10.0.0",
|
|
36
36
|
"@things-factory/ai-client-base": "^10.1.53",
|
|
37
|
-
"@things-factory/apptool-base": "^10.1.
|
|
38
|
-
"@things-factory/attachment-base": "^10.1.
|
|
39
|
-
"@things-factory/auth-base": "^10.1.
|
|
37
|
+
"@things-factory/apptool-base": "^10.1.79",
|
|
38
|
+
"@things-factory/attachment-base": "^10.1.79",
|
|
39
|
+
"@things-factory/auth-base": "^10.1.79",
|
|
40
40
|
"@things-factory/env": "^10.1.20",
|
|
41
|
-
"@things-factory/shell": "^10.1.
|
|
41
|
+
"@things-factory/shell": "^10.1.79",
|
|
42
42
|
"dompurify": "^3.0.0",
|
|
43
43
|
"graphql-scalars": "^1.22.0",
|
|
44
44
|
"graphql-tag": "^2.12.6",
|
|
@@ -51,5 +51,5 @@
|
|
|
51
51
|
"copyfiles": "^2.4.1",
|
|
52
52
|
"rimraf": "^5.0.0"
|
|
53
53
|
},
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "94cde9ba17dfdddb0a16139b71e5a7e370977e4a"
|
|
55
55
|
}
|
|
@@ -122,3 +122,23 @@ describe('attachments in the chat follow the mode', () => {
|
|
|
122
122
|
assert.match(chat, /chatAttachmentUrl\(this\.sessionId, att\.id\)/)
|
|
123
123
|
})
|
|
124
124
|
})
|
|
125
|
+
|
|
126
|
+
describe('what twin needed of the dock', () => {
|
|
127
|
+
it('a surface that says its words changed repaints the header without reopening the conversation', () => {
|
|
128
|
+
assert.match(dock, /next === this\.surface && this\.scopeKey\(next\) === this\.openedFor\) \{\s*this\.requestUpdate\(\)\s*return/)
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
it('a question with no conversation to go to is said now, never sent later; a draft waits', () => {
|
|
132
|
+
assert.match(dock, /if \(waiting\.ask\) notify\(/)
|
|
133
|
+
assert.match(dock, /else holdAssistantAsk\(waiting\)/)
|
|
134
|
+
assert.match(dock, /if \(this\.anchor && !isAnchor\(this\.anchor\)\) void this\.takeAsk\(\)/)
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
it('a handler\'s note stays in the conversation after its outcome is reported', () => {
|
|
138
|
+
assert.match(dock, /await this\.report\(sessionId, proposalKey, outcome\)\s*if \(outcome\.note && sessionId\) await this\.appendNote\(sessionId, outcome\.note\)/)
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
it('a carried conversation that could not be made is said, not swallowed', () => {
|
|
142
|
+
assert.match(dock, /this\.startCarried\(ask\)\.catch\(error => \{\s*notify\(\{ level: 'error'/)
|
|
143
|
+
})
|
|
144
|
+
})
|
package/translations/en.json
CHANGED
|
@@ -170,5 +170,6 @@
|
|
|
170
170
|
"ai-assistant.session.filter-any-visibility": "Public and private",
|
|
171
171
|
"ai-assistant.session.filter-open": "Public",
|
|
172
172
|
"ai-assistant.session.filter-private": "Private",
|
|
173
|
-
"ai-assistant.session.filter-unread": "Unread"
|
|
173
|
+
"ai-assistant.session.filter-unread": "Unread",
|
|
174
|
+
"ai-assistant.dock.ask-needs-conversation": "the question was not sent."
|
|
174
175
|
}
|
package/translations/ja.json
CHANGED
|
@@ -170,5 +170,6 @@
|
|
|
170
170
|
"ai-assistant.session.filter-any-visibility": "公開・非公開",
|
|
171
171
|
"ai-assistant.session.filter-open": "公開",
|
|
172
172
|
"ai-assistant.session.filter-private": "非公開",
|
|
173
|
-
"ai-assistant.session.filter-unread": "未読"
|
|
173
|
+
"ai-assistant.session.filter-unread": "未読",
|
|
174
|
+
"ai-assistant.dock.ask-needs-conversation": "質問は送信されませんでした。"
|
|
174
175
|
}
|
package/translations/ko.json
CHANGED
|
@@ -170,5 +170,6 @@
|
|
|
170
170
|
"ai-assistant.session.filter-any-visibility": "공개 · 비공개",
|
|
171
171
|
"ai-assistant.session.filter-open": "공개",
|
|
172
172
|
"ai-assistant.session.filter-private": "비공개",
|
|
173
|
-
"ai-assistant.session.filter-unread": "안 읽음"
|
|
173
|
+
"ai-assistant.session.filter-unread": "안 읽음",
|
|
174
|
+
"ai-assistant.dock.ask-needs-conversation": "질문을 보내지 않았습니다."
|
|
174
175
|
}
|
package/translations/ms.json
CHANGED
|
@@ -170,5 +170,6 @@
|
|
|
170
170
|
"ai-assistant.session.filter-any-visibility": "Awam dan peribadi",
|
|
171
171
|
"ai-assistant.session.filter-open": "Awam",
|
|
172
172
|
"ai-assistant.session.filter-private": "Peribadi",
|
|
173
|
-
"ai-assistant.session.filter-unread": "Belum dibaca"
|
|
173
|
+
"ai-assistant.session.filter-unread": "Belum dibaca",
|
|
174
|
+
"ai-assistant.dock.ask-needs-conversation": "soalan tidak dihantar."
|
|
174
175
|
}
|
package/translations/zh.json
CHANGED
|
@@ -170,5 +170,6 @@
|
|
|
170
170
|
"ai-assistant.session.filter-any-visibility": "公开和私密",
|
|
171
171
|
"ai-assistant.session.filter-open": "公开",
|
|
172
172
|
"ai-assistant.session.filter-private": "私密",
|
|
173
|
-
"ai-assistant.session.filter-unread": "未读"
|
|
173
|
+
"ai-assistant.session.filter-unread": "未读",
|
|
174
|
+
"ai-assistant.dock.ask-needs-conversation": "问题未发送。"
|
|
174
175
|
}
|