@pi-unipi/notify 2.16.0 → 2.16.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/README.md +16 -0
- package/events.ts +3 -1
- package/package.json +2 -2
- package/settings.ts +1 -0
- package/summarize.ts +23 -1
- package/types.ts +9 -0
package/README.md
CHANGED
|
@@ -120,6 +120,22 @@ Settings stored at `~/.unipi/config/notify/config.json`. Edit via `/unipi:notify
|
|
|
120
120
|
|
|
121
121
|
Per-event platform routing lets you control where each event type goes. The settings overlay shows all events with platform toggles.
|
|
122
122
|
|
|
123
|
+
### Recap (thinking models)
|
|
124
|
+
|
|
125
|
+
Recap summarizes the last assistant message into a one-line push notification (100-token budget). Thinking models served by llama.cpp or vLLM can spend that entire budget on reasoning and return nothing, falling back to a plain 100-character truncation. If your recap endpoint supports chat-template kwargs, set `recap.disableThinking` to skip reasoning tokens:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"recap": {
|
|
130
|
+
"enabled": true,
|
|
131
|
+
"model": "localhost/gemma-4-e4b",
|
|
132
|
+
"disableThinking": true
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
This sends `chat_template_kwargs: { enable_thinking: false, preserve_thinking: false }` with the request. Keep it `false` (the default) for strict OpenAI-compatible endpoints — they reject unknown params. Anthropic models are unaffected (thinking is opt-in there).
|
|
138
|
+
|
|
123
139
|
## License
|
|
124
140
|
|
|
125
141
|
MIT
|
package/events.ts
CHANGED
|
@@ -352,7 +352,9 @@ function registerAgentNotification(
|
|
|
352
352
|
.then((apiKeyResult) => {
|
|
353
353
|
const apiKey = apiKeyResult.ok ? (apiKeyResult as { apiKey?: string }).apiKey : undefined;
|
|
354
354
|
if (apiKey) {
|
|
355
|
-
return summarizeLastMessage(lastText, apiKey, model.baseUrl, model.api, modelId
|
|
355
|
+
return summarizeLastMessage(lastText, apiKey, model.baseUrl, model.api, modelId, {
|
|
356
|
+
disableThinking: config.recap.disableThinking,
|
|
357
|
+
})
|
|
356
358
|
.then((recap) => sessionName ? `${sessionName}: ${recap}` : recap);
|
|
357
359
|
}
|
|
358
360
|
return buildAgentLifecycleMessage(eventKey, sessionName);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/notify",
|
|
3
|
-
"version": "2.16.
|
|
3
|
+
"version": "2.16.1",
|
|
4
4
|
"description": "Cross-platform notification extension for Pi — native OS, Gotify, and Telegram notifications for agent lifecycle events",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@pi-unipi/core": "2.16.
|
|
37
|
+
"@pi-unipi/core": "2.16.1",
|
|
38
38
|
"node-notifier": "^10.0.1"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
package/settings.ts
CHANGED
package/summarize.ts
CHANGED
|
@@ -12,6 +12,17 @@ const MAX_TOKENS = 100;
|
|
|
12
12
|
const TIMEOUT_MS = 10_000;
|
|
13
13
|
const FALLBACK_TRUNCATE_CHARS = 100;
|
|
14
14
|
|
|
15
|
+
/** Options for summarizeLastMessage */
|
|
16
|
+
export interface SummarizeOptions {
|
|
17
|
+
/**
|
|
18
|
+
* Send `chat_template_kwargs: { enable_thinking: false, preserve_thinking: false }`
|
|
19
|
+
* on OpenAI-compatible requests (llama.cpp / vLLM chat templates) so thinking
|
|
20
|
+
* models don't burn the token budget on reasoning (issue #36). Anthropic
|
|
21
|
+
* ignores this — thinking is opt-in there already.
|
|
22
|
+
*/
|
|
23
|
+
disableThinking?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
15
26
|
/**
|
|
16
27
|
* Summarize a message using an LLM.
|
|
17
28
|
*
|
|
@@ -20,6 +31,7 @@ const FALLBACK_TRUNCATE_CHARS = 100;
|
|
|
20
31
|
* @param baseUrl - Provider base URL (from Model.baseUrl)
|
|
21
32
|
* @param api - API type (from Model.api, e.g. "openai-completions")
|
|
22
33
|
* @param modelId - Model ID to use
|
|
34
|
+
* @param opts - Optional summarization options
|
|
23
35
|
* @returns Summarized text, or truncated original on failure
|
|
24
36
|
*/
|
|
25
37
|
export async function summarizeLastMessage(
|
|
@@ -28,6 +40,7 @@ export async function summarizeLastMessage(
|
|
|
28
40
|
baseUrl: string,
|
|
29
41
|
api: string,
|
|
30
42
|
modelId: string,
|
|
43
|
+
opts?: SummarizeOptions,
|
|
31
44
|
): Promise<string> {
|
|
32
45
|
// Truncate input if too long
|
|
33
46
|
const input =
|
|
@@ -41,7 +54,7 @@ export async function summarizeLastMessage(
|
|
|
41
54
|
return await callAnthropic(baseUrl, apiKey, modelId, input);
|
|
42
55
|
}
|
|
43
56
|
// Default: OpenAI-compatible (covers openai-completions, openai-responses, etc.)
|
|
44
|
-
return await callOpenAICompatible(baseUrl, apiKey, modelId, input);
|
|
57
|
+
return await callOpenAICompatible(baseUrl, apiKey, modelId, input, opts);
|
|
45
58
|
} catch {
|
|
46
59
|
return fallbackSummary(messageText);
|
|
47
60
|
}
|
|
@@ -53,6 +66,7 @@ async function callOpenAICompatible(
|
|
|
53
66
|
apiKey: string,
|
|
54
67
|
modelId: string,
|
|
55
68
|
input: string,
|
|
69
|
+
opts?: SummarizeOptions,
|
|
56
70
|
): Promise<string> {
|
|
57
71
|
const url = `${baseUrl.replace(/\/$/, "")}/chat/completions`;
|
|
58
72
|
const controller = new AbortController();
|
|
@@ -68,6 +82,14 @@ async function callOpenAICompatible(
|
|
|
68
82
|
body: JSON.stringify({
|
|
69
83
|
model: modelId,
|
|
70
84
|
max_tokens: MAX_TOKENS,
|
|
85
|
+
...(opts?.disableThinking
|
|
86
|
+
? {
|
|
87
|
+
chat_template_kwargs: {
|
|
88
|
+
enable_thinking: false,
|
|
89
|
+
preserve_thinking: false,
|
|
90
|
+
},
|
|
91
|
+
}
|
|
92
|
+
: {}),
|
|
71
93
|
messages: [
|
|
72
94
|
{ role: "system", content: SYSTEM_PROMPT },
|
|
73
95
|
{ role: "user", content: input },
|
package/types.ts
CHANGED
|
@@ -69,6 +69,15 @@ export interface RecapConfig {
|
|
|
69
69
|
enabled: boolean;
|
|
70
70
|
/** Model to use for recap (e.g. "openrouter/openai/gpt-oss-20b") */
|
|
71
71
|
model: string;
|
|
72
|
+
/**
|
|
73
|
+
* Send `chat_template_kwargs: { enable_thinking: false, preserve_thinking: false }`
|
|
74
|
+
* with recap requests so llama.cpp/vLLM-style servers skip reasoning tokens.
|
|
75
|
+
* Without this, a thinking model can burn the entire 100-token budget on
|
|
76
|
+
* reasoning and return no summary (issue #36). Only enable for endpoints
|
|
77
|
+
* that accept these params — strict OpenAI-compatible servers reject them.
|
|
78
|
+
* The Anthropic path ignores this (thinking is opt-in there already).
|
|
79
|
+
*/
|
|
80
|
+
disableThinking?: boolean;
|
|
72
81
|
}
|
|
73
82
|
|
|
74
83
|
/** Quiet listed platforms after recent terminal input */
|