@primusclaw/personal-agent 0.7.1 → 0.8.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/dist/index.js +360 -160
- package/dist/types/assistant/citations.d.ts +5 -5
- package/dist/types/assistant/events.d.ts +4 -3
- package/dist/types/assistant/files.d.ts +5 -2
- package/dist/types/assistant/receipt.d.ts +10 -4
- package/dist/types/assistant/receipts.d.ts +2 -0
- package/dist/types/assistant/say.d.ts +3 -1
- package/dist/types/assistant/tracked-stream.d.ts +1 -0
- package/dist/types/capabilities/help.d.ts +2 -0
- package/dist/types/claw/message-text.d.ts +10 -14
- package/dist/types/feedback/issue-text.d.ts +2 -1
- package/dist/types/feedback/thumbs.d.ts +5 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/language/chosen.d.ts +1 -1
- package/dist/types/locales/account.d.ts +3 -1
- package/dist/types/locales/group.d.ts +4 -1
- package/dist/types/locales/link.d.ts +14 -3
- package/dist/types/locales/review-github.d.ts +9 -6
- package/dist/types/locales/transparency.d.ts +8 -3
- package/dist/types/observe/command.d.ts +5 -2
- package/dist/types/ports/claw/sessions.d.ts +7 -0
- package/dist/types/ports/claw/settings.d.ts +8 -3
- package/dist/types/ports/github.d.ts +5 -4
- package/dist/types/ports/store/remote.d.ts +8 -0
- package/dist/types/ports/surface.d.ts +35 -1
- package/dist/types/protocol/claw-api/notifications.d.ts +11 -0
- package/dist/types/remote/permissions.d.ts +5 -0
- package/dist/types/review/service/notices.d.ts +5 -2
- package/dist/types/review/service/request.d.ts +2 -0
- package/dist/types/routing/features.d.ts +2 -0
- package/dist/types/routing/turn-runner.d.ts +2 -2
- package/dist/types/routing/turn-start.d.ts +22 -8
- package/dist/types/routing/views.d.ts +2 -1
- package/dist/types/subscriptions/subscriptions.d.ts +10 -1
- package/dist/types/turn/files.d.ts +6 -2
- package/dist/types/turn/ports.d.ts +1 -1
- package/dist/types/turn/progress/status-message.d.ts +3 -1
- package/dist/types/typed-answer/prompt.d.ts +3 -2
- package/dist/types/understanding/context.d.ts +5 -0
- package/dist/types/understanding/people.d.ts +9 -4
- package/package.json +1 -1
|
@@ -4,19 +4,20 @@ import type { InboundFile } from "../ports/surface.js";
|
|
|
4
4
|
import { type Chat } from "./chat.js";
|
|
5
5
|
import type { RouterContext } from "./context.js";
|
|
6
6
|
import type { ReviewRunFields, TurnOutcome } from "./turn-runner.js";
|
|
7
|
-
/**
|
|
7
|
+
/** A client on a phone or a tablet (Teams: its own Stop under a reply is greyed out, its own thumbs never reach the worker). */
|
|
8
8
|
export declare function isMobile(clientPlatform: string): boolean;
|
|
9
9
|
/**
|
|
10
|
-
* The path a message from
|
|
10
|
+
* The path a message from the chat took: to the person's assistant, to a plain Claw session of their own (the old path, neither
|
|
11
11
|
* the assistant's nor a work item's), or to a review's turn. Logged so the worker's lines can be counted per path.
|
|
12
12
|
*/
|
|
13
13
|
export type TurnRoute = "assistant" | "legacy" | "review";
|
|
14
14
|
/**
|
|
15
|
-
* The line for a turn started from
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* The line for a turn started from a chat app (`channel`: its short name, `SurfaceCaps.shortName`; "turn started from
|
|
16
|
+
* Teams client"): where it came from and which path it took, never its words or any id. One line per turn: a message to
|
|
17
|
+
* the assistant or to a plain session is one turn, and a review request for several pull requests starts one review turn
|
|
18
|
+
* (and one line) for each.
|
|
18
19
|
*/
|
|
19
|
-
export declare function logTurnStarted(logger: Logger, clientPlatform: string, group: boolean, route: TurnRoute): void;
|
|
20
|
+
export declare function logTurnStarted(logger: Logger, channel: string, clientPlatform: string, group: boolean, route: TurnRoute): void;
|
|
20
21
|
/** A review the review service starts as a turn here (its item runs in Claw already; the turn only follows it). */
|
|
21
22
|
export interface ReviewTurnStart {
|
|
22
23
|
/** The work item Claw made for it ("" none: the turn makes a session of its own). */
|
|
@@ -68,6 +69,7 @@ export interface StartTurn {
|
|
|
68
69
|
export declare class TurnStarter {
|
|
69
70
|
private readonly ctx;
|
|
70
71
|
private readonly running;
|
|
72
|
+
private readonly askers;
|
|
71
73
|
constructor(ctx: RouterContext);
|
|
72
74
|
/** The turns that run now (a test waits for them). */
|
|
73
75
|
settled(): Promise<void>;
|
|
@@ -98,8 +100,11 @@ export declare class TurnStarter {
|
|
|
98
100
|
private sessionPart;
|
|
99
101
|
private runOf;
|
|
100
102
|
/**
|
|
101
|
-
* The language a chat turn is to be answered in
|
|
102
|
-
* group the group's (`groupChosenLang`; the sender's own choice is not read there)
|
|
103
|
+
* The language a chat turn is to be answered in (a review's answer follows its request's language). In a 1:1 chat the one the
|
|
104
|
+
* person chose, if any. In a group the group's (`groupChosenLang`; the sender's own choice is not read there); with none set, or
|
|
105
|
+
* "follow the asker", the language of the @-message's own words (`writtenLang`), else of the sender's last message in this
|
|
106
|
+
* group that had some (`AskerLanguages`), else none. A group's shared session holds every member's turns, and without the line
|
|
107
|
+
* the model answers in the language of that history, not the asker's.
|
|
103
108
|
*/
|
|
104
109
|
private replyLang;
|
|
105
110
|
private hooks;
|
|
@@ -111,3 +116,12 @@ export declare class TurnStarter {
|
|
|
111
116
|
*/
|
|
112
117
|
private recordSession;
|
|
113
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* The language each member of a group last asked in there, for a message with no words of its own (`ok`, `#3`, a link): kept in
|
|
121
|
+
* memory, per group and member, the newest `ASKERS_MAX`. After a restart such a message gets no language until its sender writes one.
|
|
122
|
+
*/
|
|
123
|
+
export declare class AskerLanguages {
|
|
124
|
+
private readonly last;
|
|
125
|
+
/** The language of `text` when it has words (and it is remembered), else the one remembered for `userId` in `scope`. */
|
|
126
|
+
answer(scope: string, userId: string, text: string): Lang | undefined;
|
|
127
|
+
}
|
|
@@ -95,7 +95,8 @@ export declare class CommandViews {
|
|
|
95
95
|
private readonly publicBaseUrl;
|
|
96
96
|
readonly note: NoteFactory;
|
|
97
97
|
constructor(bot: string, publicBaseUrl: string, note: NoteFactory);
|
|
98
|
-
link(
|
|
98
|
+
/** The card that sends the person to the console's `/link` page of the channel `channel` (`SurfaceCaps.channel`). */
|
|
99
|
+
link(who: string, channel: string): OutMessage;
|
|
99
100
|
/** The binding card in the person's language `lang` (its title, body, buttons and notice; `lead` is the caller's). */
|
|
100
101
|
binding(confirmUrl: string, lead?: string, lang?: Lang): OutMessage;
|
|
101
102
|
onboarding(member: {
|
|
@@ -22,6 +22,11 @@ export interface SubscriptionsOptions {
|
|
|
22
22
|
readonly assistantFor?: (aadId: string) => boolean;
|
|
23
23
|
/** (key) -> the Claw user id the key is of; undefined when that could not be read. Absent: ids are not filled in. */
|
|
24
24
|
readonly userIdOf?: (key: string) => Promise<string | undefined>;
|
|
25
|
+
/**
|
|
26
|
+
* The chat surface this worker is (`teams`, `slack`, ...), sent as the subscription's `surface`: Claw sends a reply back to the
|
|
27
|
+
* surface the person's message came from, and a proactive message to the one they used last. Absent: Teams.
|
|
28
|
+
*/
|
|
29
|
+
readonly surface?: string;
|
|
25
30
|
}
|
|
26
31
|
export declare class Subscriptions {
|
|
27
32
|
private readonly store;
|
|
@@ -33,6 +38,7 @@ export declare class Subscriptions {
|
|
|
33
38
|
private readonly understood;
|
|
34
39
|
private readonly assistantFor;
|
|
35
40
|
private readonly userIdOf;
|
|
41
|
+
private readonly surface;
|
|
36
42
|
constructor(options: SubscriptionsOptions);
|
|
37
43
|
/** This person's subscription gets the assistant's events (so the assistant can reach them). */
|
|
38
44
|
hasAssistantTypes(aadId: string): boolean;
|
|
@@ -64,7 +70,10 @@ export declare class Subscriptions {
|
|
|
64
70
|
* one); one Claw refuses even the assistant's types (400, 404) takes the person back to sessions (`types_version` 0).
|
|
65
71
|
*/
|
|
66
72
|
private reconcile;
|
|
67
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* The best rung the subscription has already, or the best Claw takes; throws Claw's last refusal when it takes none. A subscription
|
|
75
|
+
* Claw lists with another surface than this worker's is changed to this worker's with it (a Claw from before the label lists none).
|
|
76
|
+
*/
|
|
68
77
|
private mend;
|
|
69
78
|
/** Delete this person's earlier subscriptions to this worker: their secret is unknown here, so they would only be refused. */
|
|
70
79
|
private dropStale;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/** A file's name said back to the user is cut to this. */
|
|
2
2
|
export declare const SHOWN_NAME_MAX = 100;
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* The folder under the session's `.uploads/` the files of one message go to (`upload_folder`), so two messages never
|
|
5
|
+
* overwrite each other's files: under the channel's id (`SurfaceCaps.channel`, e.g. `teams/<message>`). A caller that
|
|
6
|
+
* names no channel gets the message's folder alone.
|
|
7
|
+
*/
|
|
8
|
+
export declare function uploadFolder(messageId: string, channel?: string): string;
|
|
5
9
|
/** The line the model reads after the user's words: where the files are, and that what is in them is the user's data. */
|
|
6
10
|
export declare function filesNote(paths: readonly string[]): string;
|
|
7
11
|
/** A file's name as it is said back in a message: in a code span, one line, its backticks turned to quotes, clipped. */
|
|
@@ -10,6 +10,6 @@ export declare function nowSeconds(clock: Clock): number;
|
|
|
10
10
|
/** Sleep `seconds` of `clock`; rejects with the signal's reason when it is aborted. */
|
|
11
11
|
export declare function sleepSeconds(clock: Clock, seconds: number, signal?: AbortSignal): Promise<void>;
|
|
12
12
|
/** The conversation the turn answers in: the calls of the Conversation port it makes. */
|
|
13
|
-
export type TurnSurface = Pick<Conversation, "typing" | "send" | "post" | "update" | "delete" | "openStream" | "outgoing" | "deliver">;
|
|
13
|
+
export type TurnSurface = Pick<Conversation, "caps" | "typing" | "send" | "post" | "update" | "delete" | "openStream" | "outgoing" | "deliver">;
|
|
14
14
|
/** The calls of Claw's sessions port a turn makes. */
|
|
15
15
|
export type TurnClaw = Pick<ClawSessionsPort, "create" | "sendMessage" | "setModel" | "lastEventId" | "turn" | "stream" | "uploadFiles" | "events" | "deliveryLink" | "changes">;
|
|
@@ -22,7 +22,9 @@ export declare const PREPARING_AFTER_SECONDS = 1.5;
|
|
|
22
22
|
export declare const FINAL_SETTLE_SECONDS = 1;
|
|
23
23
|
/** ... and one that is late anyway is covered by sending DONE_LINE once more this long afterwards. */
|
|
24
24
|
export declare const REASSERT_SECONDS = 6;
|
|
25
|
-
/**
|
|
25
|
+
/** A stream is closed by its final message this long before the chat would close it (`SurfaceCaps.streamSeconds`). */
|
|
26
|
+
export declare const STREAM_CLOSE_MARGIN_SECONDS = 60;
|
|
27
|
+
/** When a stream is closed on a chat that closes one 10 minutes after it opened (Teams). */
|
|
26
28
|
export declare const STREAM_CLOSE_SECONDS: number;
|
|
27
29
|
export interface StatusOptions<S> {
|
|
28
30
|
readonly clock: Clock;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* What the model is asked when it reads whether a message is the person's answer to what waits for them. The rules
|
|
3
|
-
* (`read.ts`) then say what it answers; with no reading, only a message that is nothing but an answer counts.
|
|
3
|
+
* (`read.ts`) then say what it answers; with no reading, only a message that is nothing but an answer counts. `channel`: the
|
|
4
|
+
* chat app's full name (`SurfaceCaps.name`).
|
|
4
5
|
*/
|
|
5
|
-
export declare const
|
|
6
|
+
export declare const answerPrompt: (channel: string) => string;
|
|
@@ -30,6 +30,11 @@ export declare function attachedContext(attached: Attached): {
|
|
|
30
30
|
};
|
|
31
31
|
/** What a channel context is made of. */
|
|
32
32
|
export interface ChannelContextInput {
|
|
33
|
+
/**
|
|
34
|
+
* The channel the message came through (`SurfaceCaps.channel`). The router sets it on what the builder returns, so a
|
|
35
|
+
* builder that does not pass it on gets "" here and the channel there.
|
|
36
|
+
*/
|
|
37
|
+
readonly channel?: string;
|
|
33
38
|
readonly channelMessageId: string;
|
|
34
39
|
readonly people: readonly NamedPerson[];
|
|
35
40
|
readonly pending: readonly PendingEntry[];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type PersonRecord } from "./record.js";
|
|
2
|
+
import type { Mention } from "../review-text/names.js";
|
|
2
3
|
/** One person the message names, as the channel context carries them. */
|
|
3
4
|
export interface NamedPerson {
|
|
4
5
|
readonly name: string;
|
|
@@ -7,9 +8,12 @@ export interface NamedPerson {
|
|
|
7
8
|
readonly email?: string;
|
|
8
9
|
readonly source: "mention" | "known" | "near";
|
|
9
10
|
}
|
|
10
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* A mention in the shape an older assembly still builds from `InboundMention` (`{mentioned: {id, name, aadObjectId}}`),
|
|
13
|
+
* read as the same `Mention`. New callers pass `message.mentions` as they are.
|
|
14
|
+
*/
|
|
11
15
|
export type MentionRecord = Readonly<Record<string, unknown>>;
|
|
12
|
-
/** The Claw user id of a person by their
|
|
16
|
+
/** The Claw user id of a person by their directory id (null: not linked, or no id recorded). */
|
|
13
17
|
export type UserIdOf = (channelUserId: string) => string | null | undefined;
|
|
14
18
|
/** A review request that names nobody offers at most this many people it may have meant. */
|
|
15
19
|
export declare const NEAR_MAX = 3;
|
|
@@ -20,9 +24,10 @@ export declare function withoutRefs(text: string): string;
|
|
|
20
24
|
/**
|
|
21
25
|
* Who the message names: the people it @mentions, then the people this worker knows whose name it writes (in any
|
|
22
26
|
* order, run together, or their address), each once; with nobody named, the people a review request may have meant
|
|
23
|
-
* (`nearPeople`). `user_id` only for a linked person. A mention without
|
|
27
|
+
* (`nearPeople`). `user_id` only for a linked person. A mention without the person's directory id is looked up by its
|
|
28
|
+
* channel id (`userIdOfChannel`). A known person is matched by their directory id (`objectId` of the member record).
|
|
24
29
|
*/
|
|
25
|
-
export declare function peopleOf(mentions: readonly MentionRecord[], text: string, known: readonly PersonRecord[], userIdOf: UserIdOf,
|
|
30
|
+
export declare function peopleOf(mentions: readonly (Mention | MentionRecord)[], text: string, known: readonly PersonRecord[], userIdOf: UserIdOf, userIdOfChannel?: (channelUserId: string) => string | null | undefined): NamedPerson[];
|
|
26
31
|
/**
|
|
27
32
|
* The linked people a review request may have meant when it names nobody known: a Latin word of it is alike one of the
|
|
28
33
|
* ways their name or address is written ("linme" for "linmei"), closest first. One is offered only when nothing of
|