@ayni.org/ayni-ui-core 0.3.4 → 0.3.6
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/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/profileClient.d.ts +3 -1
- package/dist/profileClient.js +4 -1
- package/dist/readState.d.ts +29 -0
- package/dist/readState.js +58 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export * from './flag.js';
|
|
|
6
6
|
export * from './homeDesign.js';
|
|
7
7
|
export * from './profileClient.js';
|
|
8
8
|
export * from './proofOfTrustDesign.js';
|
|
9
|
+
export * from './readState.js';
|
|
9
10
|
export * from './reducer.js';
|
|
10
11
|
export * from './sse.js';
|
|
11
12
|
export * from './store.js';
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export * from './flag.js';
|
|
|
6
6
|
export * from './homeDesign.js';
|
|
7
7
|
export * from './profileClient.js';
|
|
8
8
|
export * from './proofOfTrustDesign.js';
|
|
9
|
+
export * from './readState.js';
|
|
9
10
|
export * from './reducer.js';
|
|
10
11
|
export * from './sse.js';
|
|
11
12
|
export * from './store.js';
|
package/dist/profileClient.d.ts
CHANGED
|
@@ -26,7 +26,9 @@ export declare class ProfileClient {
|
|
|
26
26
|
constructor(sessionsUrl: string, fetchFn?: typeof fetch);
|
|
27
27
|
private url;
|
|
28
28
|
private headers;
|
|
29
|
-
create(client: ClientDescription, locale?: string, siblingOfToken?: string, deviceHandle?: string, resumeSessionId?: string, deviceProof?: string, conversationId?: string, newConversation?: boolean
|
|
29
|
+
create(client: ClientDescription, locale?: string, siblingOfToken?: string, deviceHandle?: string, resumeSessionId?: string, deviceProof?: string, conversationId?: string, newConversation?: boolean,
|
|
30
|
+
/** a bound session or none (PROF-SESS-015): 409 when the device proof does not bind, nothing asked on the phone */
|
|
31
|
+
silent?: boolean): Promise<CreateSessionResponse>;
|
|
30
32
|
/** The Principal's conversations with this agent (PROF-CONV-001). */
|
|
31
33
|
conversations(token: string): Promise<ConversationsResponse>;
|
|
32
34
|
/** Rename, archive or unarchive (PROF-CONV-002/003). */
|
package/dist/profileClient.js
CHANGED
|
@@ -37,7 +37,9 @@ export class ProfileClient {
|
|
|
37
37
|
headers(token, extra = {}) {
|
|
38
38
|
return { accept: 'application/json', ...(token ? { authorization: `Bearer ${token}` } : {}), ...extra };
|
|
39
39
|
}
|
|
40
|
-
async create(client, locale, siblingOfToken, deviceHandle, resumeSessionId, deviceProof, conversationId, newConversation = false
|
|
40
|
+
async create(client, locale, siblingOfToken, deviceHandle, resumeSessionId, deviceProof, conversationId, newConversation = false,
|
|
41
|
+
/** a bound session or none (PROF-SESS-015): 409 when the device proof does not bind, nothing asked on the phone */
|
|
42
|
+
silent = false) {
|
|
41
43
|
const response = await this.fetchFn(this.url(), {
|
|
42
44
|
method: 'POST',
|
|
43
45
|
headers: this.headers(siblingOfToken, { 'content-type': 'application/json' }),
|
|
@@ -48,6 +50,7 @@ export class ProfileClient {
|
|
|
48
50
|
...(deviceHandle && deviceProof && !siblingOfToken ? { deviceProof } : {}),
|
|
49
51
|
...(conversationId ? { conversationId } : resumeSessionId ? { resumeSessionId } : {}),
|
|
50
52
|
...(newConversation ? { newConversation: true } : {}),
|
|
53
|
+
...(silent && !siblingOfToken ? { silent: true } : {}),
|
|
51
54
|
}),
|
|
52
55
|
});
|
|
53
56
|
if (!response.ok)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AgUiEvent } from './profileClient.js';
|
|
2
|
+
import type { TranscriptMessage } from './types.js';
|
|
3
|
+
/** Whether the agent keeps the shared read state. */
|
|
4
|
+
export declare function hasReadState(descriptor: {
|
|
5
|
+
features?: unknown;
|
|
6
|
+
} | undefined): boolean;
|
|
7
|
+
/** Whether a device reports what it shows: for the audit trail (`receipts`), for the read marker (`readState`). */
|
|
8
|
+
export declare function sendsViewed(descriptor: {
|
|
9
|
+
features?: unknown;
|
|
10
|
+
} | undefined): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* The unread count a device shows for a conversation: the agent's when it gave one, the device's own otherwise,
|
|
13
|
+
* and none for the conversation in front of the person, which the device is reporting as viewed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function unreadFrom(agentCount: unknown, own: number, onScreen: boolean): number;
|
|
16
|
+
/**
|
|
17
|
+
* The messages of a transcript to report as viewed: what the agent said that is shown whole and was not reported
|
|
18
|
+
* yet, by the id the agent knows it under (a text by its own id, an attachment by its entry's).
|
|
19
|
+
*/
|
|
20
|
+
export declare function viewedIds(messages: readonly TranscriptMessage[], reported: ReadonlySet<string>): string[];
|
|
21
|
+
/** What `ayni.conversation.changed` says of a conversation (PROF-CONV-007); null for any other event. */
|
|
22
|
+
export interface ChangedConversation {
|
|
23
|
+
conversationId: string;
|
|
24
|
+
title?: string;
|
|
25
|
+
state?: 'active' | 'archived' | 'final';
|
|
26
|
+
unread?: number;
|
|
27
|
+
readUpTo?: string | null;
|
|
28
|
+
}
|
|
29
|
+
export declare function changedConversation(event: AgUiEvent): ChangedConversation | null;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shared read state, as a device uses it (D62, PROF-CONV-008, PROF-DESC-005): the agent keeps one read marker
|
|
3
|
+
* per conversation and counts what is unread after it; a device reports the messages it shows with a `viewed`
|
|
4
|
+
* receipt and shows the agent's count in place of its own. The rules are here so the web UI and the app apply
|
|
5
|
+
* the same ones.
|
|
6
|
+
*/
|
|
7
|
+
import { ACTIVITY } from '@ayni.org/ayni-agui-profile';
|
|
8
|
+
import { CONVERSATION_CHANGED } from './reducer.js';
|
|
9
|
+
/** Whether the agent keeps the shared read state. */
|
|
10
|
+
export function hasReadState(descriptor) {
|
|
11
|
+
return descriptor?.features?.readState === true;
|
|
12
|
+
}
|
|
13
|
+
/** Whether a device reports what it shows: for the audit trail (`receipts`), for the read marker (`readState`). */
|
|
14
|
+
export function sendsViewed(descriptor) {
|
|
15
|
+
return descriptor?.features?.receipts === true || hasReadState(descriptor);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The unread count a device shows for a conversation: the agent's when it gave one, the device's own otherwise,
|
|
19
|
+
* and none for the conversation in front of the person, which the device is reporting as viewed.
|
|
20
|
+
*/
|
|
21
|
+
export function unreadFrom(agentCount, own, onScreen) {
|
|
22
|
+
if (onScreen)
|
|
23
|
+
return 0;
|
|
24
|
+
return typeof agentCount === 'number' && agentCount >= 0 ? agentCount : own;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The messages of a transcript to report as viewed: what the agent said that is shown whole and was not reported
|
|
28
|
+
* yet, by the id the agent knows it under (a text by its own id, an attachment by its entry's).
|
|
29
|
+
*/
|
|
30
|
+
export function viewedIds(messages, reported) {
|
|
31
|
+
const ids = [];
|
|
32
|
+
for (const m of messages) {
|
|
33
|
+
let id;
|
|
34
|
+
if (m.role === 'assistant' && !m.streaming)
|
|
35
|
+
id = m.id;
|
|
36
|
+
else if (m.role === 'activity' &&
|
|
37
|
+
m.activityType === ACTIVITY.attachment &&
|
|
38
|
+
m.content.role === 'assistant')
|
|
39
|
+
id = m.entryId;
|
|
40
|
+
if (id && !reported.has(id) && !ids.includes(id))
|
|
41
|
+
ids.push(id);
|
|
42
|
+
}
|
|
43
|
+
return ids;
|
|
44
|
+
}
|
|
45
|
+
export function changedConversation(event) {
|
|
46
|
+
if (event.type !== 'CUSTOM' || event.name !== CONVERSATION_CHANGED)
|
|
47
|
+
return null;
|
|
48
|
+
const value = (event.value ?? {});
|
|
49
|
+
if (typeof value.conversationId !== 'string')
|
|
50
|
+
return null;
|
|
51
|
+
return {
|
|
52
|
+
conversationId: value.conversationId,
|
|
53
|
+
title: typeof value.title === 'string' ? value.title : undefined,
|
|
54
|
+
state: value.state === 'active' || value.state === 'archived' || value.state === 'final' ? value.state : undefined,
|
|
55
|
+
unread: typeof value.unread === 'number' ? value.unread : undefined,
|
|
56
|
+
readUpTo: typeof value.readUpTo === 'string' || value.readUpTo === null ? value.readUpTo : undefined,
|
|
57
|
+
};
|
|
58
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ayni.org/ayni-ui-core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "Framework-independent core of the Ayni UI (UI-SHELL-004): agents and controllers, trust resolution, sessions and binding, the conversation reducer, the local store and sync; shared by the browser UI and the Ayni app",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|