portable-agent-layer 0.81.0 → 0.81.1
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/package.json
CHANGED
|
@@ -8,11 +8,6 @@ import { extractKeywords, similarity } from "./text-similarity";
|
|
|
8
8
|
|
|
9
9
|
export type Reaction = "corrected" | "repeated" | "approved" | "new-topic" | "follow-up";
|
|
10
10
|
|
|
11
|
-
export interface ReplyContext {
|
|
12
|
-
previousPrompt?: string;
|
|
13
|
-
replyKeywords: string[];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
11
|
const CORRECTION_RE =
|
|
17
12
|
/^(?:(?:no|nope|wrong)(?:[,.!]|$)|(?:that'?s|this is|it'?s) (?:wrong|not)\b|not what i\b|i said\b|i told you\b|you forgot\b|you missed\b|still (?:broken|failing|wrong)\b)/i;
|
|
18
13
|
|
|
@@ -20,15 +15,16 @@ const APPROVAL_RE =
|
|
|
20
15
|
/^(?:good|great|nice|perfect|cool|amazing|awesome|excellent|brilliant|works|it works|thanks|thank you|thx|y+e+s+|yep|yeah|yup|sure|exactly|correct|agreed|lgtm|well done|love it|sounds good|looks good|that'?s it|(?:it|this|that) (?:is|'s) (?:fine|good|great|right))\b/i;
|
|
21
16
|
|
|
22
17
|
const GO_AHEAD_RE =
|
|
23
|
-
/^(?:go ahead|go|do it|proceed|continue|merge|push|ship|commit|build|approved|let'?s (?:see|do|go))\b/i;
|
|
18
|
+
/^(?:go ahead|go|do it|proceed|continue|merge|push|ship|commit|build|start|fix (?:all|them|both)|approved|let'?s (?:see|do|go))\b/i;
|
|
19
|
+
|
|
20
|
+
const NEW_TOPIC_RE =
|
|
21
|
+
/^(?:(?:ok(?:ay)?|btw|also),?\s+)?(?:new (?:\w+ ){0,2}(?:task|topic|question|thing)|(?:different|unrelated|separate|another) (?:task|topic|question|thing)|unrelated\b|switching (?:gears|topics?)|change of (?:topic|subject))/i;
|
|
24
22
|
|
|
25
23
|
const GO_AHEAD_MAX_WORDS = 6;
|
|
26
24
|
const BARE_OK_RE = /^(?:ok(?:ay)?|k)[,.!]?(?:\s+\S+){0,2}$/i;
|
|
27
25
|
const HEDGE_RE = /\b(?:but|however|though|except|instead)\b/i;
|
|
28
26
|
const REPEAT_SIMILARITY = 0.6;
|
|
29
27
|
const REPEAT_MIN_KEYWORDS = 5;
|
|
30
|
-
const NEW_TOPIC_MIN_KEYWORDS = 4;
|
|
31
|
-
const NEW_TOPIC_MAX_OVERLAP = 0.15;
|
|
32
28
|
|
|
33
29
|
export function isCorrection(text: string): boolean {
|
|
34
30
|
return CORRECTION_RE.test(text.trim());
|
|
@@ -39,33 +35,36 @@ export function isRepeat(text: string, previous: string | undefined): boolean {
|
|
|
39
35
|
return similarity(text, previous) >= REPEAT_SIMILARITY;
|
|
40
36
|
}
|
|
41
37
|
|
|
38
|
+
function isShortGoAhead(sentence: string): boolean {
|
|
39
|
+
return GO_AHEAD_RE.test(sentence) && sentence.split(/\s+/).length <= GO_AHEAD_MAX_WORDS;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function lastSentence(text: string): string {
|
|
43
|
+
return (
|
|
44
|
+
text
|
|
45
|
+
.split(/[.!\n]\s*/)
|
|
46
|
+
.filter(Boolean)
|
|
47
|
+
.at(-1)
|
|
48
|
+
?.trim() ?? ""
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
42
52
|
function isApproval(text: string): boolean {
|
|
43
53
|
const trimmed = text.trim();
|
|
44
|
-
if (HEDGE_RE.test(trimmed.split(/[.!?\n]/)[0])) return false;
|
|
54
|
+
if (trimmed.includes("?") || HEDGE_RE.test(trimmed.split(/[.!?\n]/)[0])) return false;
|
|
45
55
|
if (APPROVAL_RE.test(trimmed) || BARE_OK_RE.test(trimmed)) return true;
|
|
46
|
-
return
|
|
56
|
+
return isShortGoAhead(trimmed) || isShortGoAhead(lastSentence(trimmed));
|
|
47
57
|
}
|
|
48
58
|
|
|
49
|
-
/**
|
|
50
|
-
function isNewTopic(text: string
|
|
51
|
-
|
|
52
|
-
if (words.size < NEW_TOPIC_MIN_KEYWORDS) return false;
|
|
53
|
-
const exchange = new Set([
|
|
54
|
-
...context.replyKeywords,
|
|
55
|
-
...extractKeywords(context.previousPrompt ?? ""),
|
|
56
|
-
]);
|
|
57
|
-
const shared = [...words].filter((w) => exchange.has(w)).length;
|
|
58
|
-
return shared / words.size <= NEW_TOPIC_MAX_OVERLAP;
|
|
59
|
+
/** Word overlap was measured against real messages and does not separate topics; only saying so does. */
|
|
60
|
+
function isNewTopic(text: string): boolean {
|
|
61
|
+
return NEW_TOPIC_RE.test(text.trim());
|
|
59
62
|
}
|
|
60
63
|
|
|
61
|
-
export function reactionTo(text: string,
|
|
64
|
+
export function reactionTo(text: string, previousPrompt: string | undefined): Reaction {
|
|
62
65
|
if (isCorrection(text)) return "corrected";
|
|
63
|
-
if (isRepeat(text,
|
|
66
|
+
if (isRepeat(text, previousPrompt)) return "repeated";
|
|
64
67
|
if (isApproval(text)) return "approved";
|
|
65
|
-
if (isNewTopic(text
|
|
68
|
+
if (isNewTopic(text)) return "new-topic";
|
|
66
69
|
return "follow-up";
|
|
67
70
|
}
|
|
68
|
-
|
|
69
|
-
export function replyKeywords(reply: string): string[] {
|
|
70
|
-
return [...extractKeywords(reply)];
|
|
71
|
-
}
|
|
@@ -19,7 +19,6 @@ import {
|
|
|
19
19
|
isRepeat,
|
|
20
20
|
type Reaction,
|
|
21
21
|
reactionTo,
|
|
22
|
-
replyKeywords,
|
|
23
22
|
} from "./interaction-reaction";
|
|
24
23
|
import { keepSample, replyEnd } from "./interaction-samples";
|
|
25
24
|
import { ensureDir, paths } from "./paths";
|
|
@@ -50,7 +49,6 @@ interface SessionTrack {
|
|
|
50
49
|
lastPrompt?: string;
|
|
51
50
|
lastPromptAt?: string;
|
|
52
51
|
reply?: ReplyShape;
|
|
53
|
-
replyKeywords?: string[];
|
|
54
52
|
replyEnd?: string;
|
|
55
53
|
recent: TurnEvent[];
|
|
56
54
|
mood?: string;
|
|
@@ -117,12 +115,7 @@ function measureTurn(
|
|
|
117
115
|
repeated: isRepeat(text, track.lastPrompt),
|
|
118
116
|
corrected: isCorrection(text),
|
|
119
117
|
reply: reply ? replyFeatures(reply) : null,
|
|
120
|
-
reaction: reply
|
|
121
|
-
? reactionTo(text, {
|
|
122
|
-
previousPrompt: track.lastPrompt,
|
|
123
|
-
replyKeywords: track.replyKeywords ?? [],
|
|
124
|
-
})
|
|
125
|
-
: null,
|
|
118
|
+
reaction: reply ? reactionTo(text, track.lastPrompt) : null,
|
|
126
119
|
};
|
|
127
120
|
}
|
|
128
121
|
|
|
@@ -211,7 +204,6 @@ export function recordReply(
|
|
|
211
204
|
...track,
|
|
212
205
|
updated: now.toISOString(),
|
|
213
206
|
reply: replyShape(reply, now),
|
|
214
|
-
replyKeywords: replyKeywords(reply),
|
|
215
207
|
replyEnd: replyEnd(reply),
|
|
216
208
|
});
|
|
217
209
|
}
|