@unclick/mcp-server 0.2.5 → 0.3.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 +160 -139
- package/dist/abn-tool.js +1 -1
- package/dist/bgg-tool.js +1 -1
- package/dist/carboninterface-tool.js +1 -1
- package/dist/cards/card.d.ts +9 -0
- package/dist/cards/card.d.ts.map +1 -0
- package/dist/cards/card.js +4 -0
- package/dist/cards/card.js.map +1 -0
- package/dist/cards/search-memory-card.d.ts +11 -0
- package/dist/cards/search-memory-card.d.ts.map +1 -0
- package/dist/cards/search-memory-card.js +75 -0
- package/dist/cards/search-memory-card.js.map +1 -0
- package/dist/cards/search-memory-card.test.d.ts +2 -0
- package/dist/cards/search-memory-card.test.d.ts.map +1 -0
- package/dist/cards/search-memory-card.test.js +59 -0
- package/dist/cards/search-memory-card.test.js.map +1 -0
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +265 -4
- package/dist/catalog.js.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +96 -6
- package/dist/client.js.map +1 -1
- package/dist/converter-tools.js +1 -1
- package/dist/crews-tool.d.ts +12 -0
- package/dist/crews-tool.d.ts.map +1 -0
- package/dist/crews-tool.js +125 -0
- package/dist/crews-tool.js.map +1 -0
- package/dist/gdelt-tool.js +4 -4
- package/dist/hackernews-tool.js +1 -1
- package/dist/index.js +0 -0
- package/dist/keychain-secure-input.js +42 -42
- package/dist/line-tool.js +1 -1
- package/dist/linear-tool.js +73 -73
- package/dist/local-catalog-handlers.js +1 -1
- package/dist/local-catalog-handlers.js.map +1 -1
- package/dist/local-tools.js +7 -7
- package/dist/local-tools.js.map +1 -1
- package/dist/memory/__tests__/bitemporal.test.d.ts +8 -0
- package/dist/memory/__tests__/bitemporal.test.d.ts.map +1 -0
- package/dist/memory/__tests__/bitemporal.test.js +148 -0
- package/dist/memory/__tests__/bitemporal.test.js.map +1 -0
- package/dist/memory/__tests__/hybrid-search.test.d.ts +14 -0
- package/dist/memory/__tests__/hybrid-search.test.d.ts.map +1 -0
- package/dist/memory/__tests__/hybrid-search.test.js +304 -0
- package/dist/memory/__tests__/hybrid-search.test.js.map +1 -0
- package/dist/memory/agent.d.ts +34 -0
- package/dist/memory/agent.d.ts.map +1 -0
- package/dist/memory/agent.js +69 -0
- package/dist/memory/agent.js.map +1 -0
- package/dist/memory/conflicts.d.ts +48 -0
- package/dist/memory/conflicts.d.ts.map +1 -0
- package/dist/memory/conflicts.js +209 -0
- package/dist/memory/conflicts.js.map +1 -0
- package/dist/memory/db.d.ts +25 -0
- package/dist/memory/db.d.ts.map +1 -0
- package/dist/memory/db.js +144 -0
- package/dist/memory/db.js.map +1 -0
- package/dist/memory/device.d.ts +20 -0
- package/dist/memory/device.d.ts.map +1 -0
- package/dist/memory/device.js +48 -0
- package/dist/memory/device.js.map +1 -0
- package/dist/memory/embeddings.d.ts +10 -0
- package/dist/memory/embeddings.d.ts.map +1 -0
- package/dist/memory/embeddings.js +40 -0
- package/dist/memory/embeddings.js.map +1 -0
- package/dist/memory/handlers.d.ts +11 -0
- package/dist/memory/handlers.d.ts.map +1 -0
- package/dist/memory/handlers.js +219 -0
- package/dist/memory/handlers.js.map +1 -0
- package/dist/memory/instrumentation.d.ts +38 -0
- package/dist/memory/instrumentation.d.ts.map +1 -0
- package/dist/memory/instrumentation.js +97 -0
- package/dist/memory/instrumentation.js.map +1 -0
- package/dist/memory/load-events.d.ts +18 -0
- package/dist/memory/load-events.d.ts.map +1 -0
- package/dist/memory/load-events.js +61 -0
- package/dist/memory/load-events.js.map +1 -0
- package/dist/memory/local.d.ts +40 -0
- package/dist/memory/local.d.ts.map +1 -0
- package/dist/memory/local.js +400 -0
- package/dist/memory/local.js.map +1 -0
- package/dist/memory/session-state.d.ts +37 -0
- package/dist/memory/session-state.d.ts.map +1 -0
- package/dist/memory/session-state.js +82 -0
- package/dist/memory/session-state.js.map +1 -0
- package/dist/memory/supabase.d.ts +104 -0
- package/dist/memory/supabase.d.ts.map +1 -0
- package/dist/memory/supabase.js +710 -0
- package/dist/memory/supabase.js.map +1 -0
- package/dist/memory/tenant-settings.d.ts +33 -0
- package/dist/memory/tenant-settings.d.ts.map +1 -0
- package/dist/memory/tenant-settings.js +79 -0
- package/dist/memory/tenant-settings.js.map +1 -0
- package/dist/memory/tool-awareness.d.ts +66 -0
- package/dist/memory/tool-awareness.d.ts.map +1 -0
- package/dist/memory/tool-awareness.js +307 -0
- package/dist/memory/tool-awareness.js.map +1 -0
- package/dist/memory/types.d.ts +97 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +5 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/monday-tool.js +46 -46
- package/dist/musicbrainz-tool.js +1 -1
- package/dist/musicbrainz-tool.js.map +1 -1
- package/dist/numbers-tool.js +2 -2
- package/dist/openfoodfacts-tool.js +1 -1
- package/dist/openmeteo-tool.js +1 -1
- package/dist/radiobrowser-tool.js +2 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +838 -15
- package/dist/server.js.map +1 -1
- package/dist/signals/emit.d.ts +11 -0
- package/dist/signals/emit.d.ts.map +1 -0
- package/dist/signals/emit.js +26 -0
- package/dist/signals/emit.js.map +1 -0
- package/dist/testpass-tool.d.ts +12 -0
- package/dist/testpass-tool.d.ts.map +1 -0
- package/dist/testpass-tool.js +121 -0
- package/dist/testpass-tool.js.map +1 -0
- package/dist/toilets-tool.js +2 -2
- package/dist/tool-wiring.d.ts +320 -4
- package/dist/tool-wiring.d.ts.map +1 -1
- package/dist/tool-wiring.js +246 -5
- package/dist/tool-wiring.js.map +1 -1
- package/dist/trivia-tool.js +5 -5
- package/dist/usgs-tool.js +1 -1
- package/dist/uxpass-tool.d.ts +24 -0
- package/dist/uxpass-tool.d.ts.map +1 -0
- package/dist/uxpass-tool.js +165 -0
- package/dist/uxpass-tool.js.map +1 -0
- package/dist/vault-bridge.js +7 -7
- package/dist/vercel-tool.d.ts +3 -0
- package/dist/vercel-tool.d.ts.map +1 -1
- package/dist/vercel-tool.js +198 -7
- package/dist/vercel-tool.js.map +1 -1
- package/dist/web-tools.d.ts +62 -0
- package/dist/web-tools.d.ts.map +1 -0
- package/dist/web-tools.js +271 -0
- package/dist/web-tools.js.map +1 -0
- package/package.json +69 -65
- package/public/icon.svg +15 -15
- package/server.json +37 -37
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory operation handlers for @unclick/mcp-server.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the 17 memory operations (get_startup_context, search_memory, add_fact,
|
|
5
|
+
* write_session_summary, etc.) as plain async functions that take a single
|
|
6
|
+
* params object. Used by both direct MCP tools and the unclick_call meta-tool.
|
|
7
|
+
*/
|
|
8
|
+
import { getBackend } from "./db.js";
|
|
9
|
+
import { buildToolGuidance, classifyTools, reportToolDetections, } from "./tool-awareness.js";
|
|
10
|
+
import { resolveAgent, filterContextByLayers } from "./agent.js";
|
|
11
|
+
import { emitSignal } from "../signals/emit.js";
|
|
12
|
+
import { buildSearchMemoryCard } from "../cards/search-memory-card.js";
|
|
13
|
+
function currentApiKeyHash() {
|
|
14
|
+
return process.env.UNCLICK_API_KEY_HASH ?? null;
|
|
15
|
+
}
|
|
16
|
+
function str(v, fallback = "") {
|
|
17
|
+
return typeof v === "string" ? v : fallback;
|
|
18
|
+
}
|
|
19
|
+
function num(v, fallback) {
|
|
20
|
+
return typeof v === "number" && Number.isFinite(v) ? v : fallback;
|
|
21
|
+
}
|
|
22
|
+
function arr(v) {
|
|
23
|
+
return Array.isArray(v) ? v.map(String) : [];
|
|
24
|
+
}
|
|
25
|
+
function bool(v, fallback = false) {
|
|
26
|
+
return typeof v === "boolean" ? v : fallback;
|
|
27
|
+
}
|
|
28
|
+
export const MEMORY_HANDLERS = {
|
|
29
|
+
async get_startup_context(args) {
|
|
30
|
+
const db = await getBackend();
|
|
31
|
+
const slug = typeof args.agent_slug === "string" ? args.agent_slug : undefined;
|
|
32
|
+
const id = typeof args.agent_id === "string" ? args.agent_id : undefined;
|
|
33
|
+
const [baseContext, resolved] = await Promise.all([
|
|
34
|
+
db.getStartupContext(num(args.num_sessions, 5)),
|
|
35
|
+
resolveAgent({ agent_slug: slug, agent_id: id }),
|
|
36
|
+
]);
|
|
37
|
+
// Optional: if the client passed the list of other tools in this session,
|
|
38
|
+
// classify them and attach tool_guidance so the agent can nudge the user.
|
|
39
|
+
const sessionTools = Array.isArray(args.session_tools)
|
|
40
|
+
? args.session_tools.map(String).filter(Boolean)
|
|
41
|
+
: [];
|
|
42
|
+
let tool_guidance = undefined;
|
|
43
|
+
if (sessionTools.length > 0) {
|
|
44
|
+
const detections = classifyTools(sessionTools);
|
|
45
|
+
const nudgeable = await reportToolDetections(detections);
|
|
46
|
+
tool_guidance = buildToolGuidance(detections, nudgeable);
|
|
47
|
+
}
|
|
48
|
+
if (!resolved) {
|
|
49
|
+
if (tool_guidance === undefined)
|
|
50
|
+
return baseContext;
|
|
51
|
+
return { ...baseContext, tool_guidance };
|
|
52
|
+
}
|
|
53
|
+
const scoped = filterContextByLayers(baseContext, resolved.enabled_memory_layers);
|
|
54
|
+
const result = {
|
|
55
|
+
agent: {
|
|
56
|
+
id: resolved.agent.id,
|
|
57
|
+
slug: resolved.agent.slug,
|
|
58
|
+
name: resolved.agent.name,
|
|
59
|
+
role: resolved.agent.role,
|
|
60
|
+
description: resolved.agent.description,
|
|
61
|
+
system_prompt: resolved.agent.system_prompt,
|
|
62
|
+
is_default: resolved.agent.is_default,
|
|
63
|
+
},
|
|
64
|
+
enabled_tools: resolved.enabled_tools,
|
|
65
|
+
enabled_memory_layers: resolved.enabled_memory_layers,
|
|
66
|
+
memory: scoped && typeof scoped === "object" ? scoped : { _raw: baseContext },
|
|
67
|
+
};
|
|
68
|
+
if (tool_guidance !== undefined)
|
|
69
|
+
result.tool_guidance = tool_guidance;
|
|
70
|
+
return result;
|
|
71
|
+
},
|
|
72
|
+
async search_memory(args) {
|
|
73
|
+
const db = await getBackend();
|
|
74
|
+
const asOf = typeof args.as_of === "string" ? args.as_of : undefined;
|
|
75
|
+
const query = str(args.query);
|
|
76
|
+
const results = await db.searchMemory(query, num(args.max_results, 10), asOf);
|
|
77
|
+
// Phase 1 Wizard wrap: opt-in card alongside the existing array payload.
|
|
78
|
+
// Defaults off to keep backward compatibility for current consumers.
|
|
79
|
+
if (bool(args.include_card, false)) {
|
|
80
|
+
return { results, card: buildSearchMemoryCard(query, results) };
|
|
81
|
+
}
|
|
82
|
+
return results;
|
|
83
|
+
},
|
|
84
|
+
async search_facts(args) {
|
|
85
|
+
const db = await getBackend();
|
|
86
|
+
return db.searchFacts(str(args.query));
|
|
87
|
+
},
|
|
88
|
+
async search_library(args) {
|
|
89
|
+
const db = await getBackend();
|
|
90
|
+
return db.searchLibrary(str(args.query));
|
|
91
|
+
},
|
|
92
|
+
async get_library_doc(args) {
|
|
93
|
+
const db = await getBackend();
|
|
94
|
+
return db.getLibraryDoc(str(args.slug));
|
|
95
|
+
},
|
|
96
|
+
async list_library() {
|
|
97
|
+
const db = await getBackend();
|
|
98
|
+
return db.listLibrary();
|
|
99
|
+
},
|
|
100
|
+
async write_session_summary(args) {
|
|
101
|
+
const db = await getBackend();
|
|
102
|
+
const result = await db.writeSessionSummary({
|
|
103
|
+
session_id: str(args.session_id),
|
|
104
|
+
summary: str(args.summary),
|
|
105
|
+
topics: arr(args.topics),
|
|
106
|
+
open_loops: arr(args.open_loops),
|
|
107
|
+
decisions: arr(args.decisions),
|
|
108
|
+
platform: str(args.platform, "claude-code"),
|
|
109
|
+
duration_minutes: typeof args.duration_minutes === "number" ? args.duration_minutes : undefined,
|
|
110
|
+
});
|
|
111
|
+
const hash = currentApiKeyHash();
|
|
112
|
+
if (hash) {
|
|
113
|
+
void emitSignal({
|
|
114
|
+
apiKeyHash: hash,
|
|
115
|
+
tool: "memory",
|
|
116
|
+
action: "session_saved",
|
|
117
|
+
severity: "info",
|
|
118
|
+
summary: "Session summary saved to memory",
|
|
119
|
+
deepLink: "/admin/memory?tab=sessions",
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return result;
|
|
123
|
+
},
|
|
124
|
+
async add_fact(args) {
|
|
125
|
+
const db = await getBackend();
|
|
126
|
+
const result = await db.addFact({
|
|
127
|
+
fact: str(args.fact),
|
|
128
|
+
category: str(args.category, "general"),
|
|
129
|
+
confidence: num(args.confidence, 0.9),
|
|
130
|
+
source_session_id: typeof args.source_session_id === "string" ? args.source_session_id : undefined,
|
|
131
|
+
valid_from: typeof args.valid_from === "string" ? args.valid_from : undefined,
|
|
132
|
+
extractor_id: typeof args.extractor_id === "string" ? args.extractor_id : undefined,
|
|
133
|
+
prompt_version: typeof args.prompt_version === "string" ? args.prompt_version : undefined,
|
|
134
|
+
model_id: typeof args.model_id === "string" ? args.model_id : undefined,
|
|
135
|
+
preserve_as_blob: typeof args.preserve_as_blob === "boolean" ? args.preserve_as_blob : false,
|
|
136
|
+
commit_sha: typeof args.commit_sha === "string" ? args.commit_sha : undefined,
|
|
137
|
+
pr_number: typeof args.pr_number === "number" ? Math.floor(args.pr_number) : undefined,
|
|
138
|
+
});
|
|
139
|
+
const hash = currentApiKeyHash();
|
|
140
|
+
if (hash) {
|
|
141
|
+
const preview = str(args.fact).slice(0, 80);
|
|
142
|
+
void emitSignal({
|
|
143
|
+
apiKeyHash: hash,
|
|
144
|
+
tool: "memory",
|
|
145
|
+
action: "fact_saved",
|
|
146
|
+
severity: "info",
|
|
147
|
+
summary: preview ? `Fact saved: ${preview}` : "Fact saved to memory",
|
|
148
|
+
deepLink: "/admin/memory?tab=facts",
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return result;
|
|
152
|
+
},
|
|
153
|
+
async supersede_fact(args) {
|
|
154
|
+
const db = await getBackend();
|
|
155
|
+
const newId = await db.supersedeFact(str(args.old_fact_id), str(args.new_fact_text), typeof args.new_category === "string" ? args.new_category : undefined, typeof args.new_confidence === "number" ? args.new_confidence : undefined);
|
|
156
|
+
return { new_fact_id: newId };
|
|
157
|
+
},
|
|
158
|
+
async log_conversation(args) {
|
|
159
|
+
const db = await getBackend();
|
|
160
|
+
await db.logConversation({
|
|
161
|
+
session_id: str(args.session_id),
|
|
162
|
+
role: str(args.role),
|
|
163
|
+
content: str(args.content),
|
|
164
|
+
has_code: bool(args.has_code),
|
|
165
|
+
});
|
|
166
|
+
return { logged: true };
|
|
167
|
+
},
|
|
168
|
+
async get_conversation_detail(args) {
|
|
169
|
+
const db = await getBackend();
|
|
170
|
+
return db.getConversationDetail(str(args.session_id));
|
|
171
|
+
},
|
|
172
|
+
async store_code(args) {
|
|
173
|
+
const db = await getBackend();
|
|
174
|
+
return db.storeCode({
|
|
175
|
+
session_id: str(args.session_id),
|
|
176
|
+
language: str(args.language, "typescript"),
|
|
177
|
+
filename: typeof args.filename === "string" ? args.filename : undefined,
|
|
178
|
+
content: str(args.code || args.content),
|
|
179
|
+
description: typeof args.description === "string" ? args.description : undefined,
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
|
+
async get_business_context() {
|
|
183
|
+
const db = await getBackend();
|
|
184
|
+
return db.getBusinessContext();
|
|
185
|
+
},
|
|
186
|
+
async set_business_context(args) {
|
|
187
|
+
const db = await getBackend();
|
|
188
|
+
await db.setBusinessContext(str(args.category), str(args.key), args.value, typeof args.priority === "number" ? args.priority : undefined);
|
|
189
|
+
return { set: true, category: str(args.category), key: str(args.key) };
|
|
190
|
+
},
|
|
191
|
+
async upsert_library_doc(args) {
|
|
192
|
+
const db = await getBackend();
|
|
193
|
+
const msg = await db.upsertLibraryDoc({
|
|
194
|
+
slug: str(args.slug),
|
|
195
|
+
title: str(args.title),
|
|
196
|
+
category: str(args.category, "reference"),
|
|
197
|
+
content: str(args.content),
|
|
198
|
+
tags: arr(args.tags),
|
|
199
|
+
});
|
|
200
|
+
return { message: msg };
|
|
201
|
+
},
|
|
202
|
+
async manage_decay() {
|
|
203
|
+
const db = await getBackend();
|
|
204
|
+
return db.manageDecay();
|
|
205
|
+
},
|
|
206
|
+
async memory_status() {
|
|
207
|
+
const db = await getBackend();
|
|
208
|
+
return db.getMemoryStatus();
|
|
209
|
+
},
|
|
210
|
+
async invalidate_fact(args) {
|
|
211
|
+
const db = await getBackend();
|
|
212
|
+
return db.invalidateFact({
|
|
213
|
+
fact_id: str(args.fact_id),
|
|
214
|
+
reason: typeof args.reason === "string" ? args.reason : undefined,
|
|
215
|
+
session_id: typeof args.session_id === "string" ? args.session_id : undefined,
|
|
216
|
+
});
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
//# sourceMappingURL=handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/memory/handlers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,SAAS,iBAAiB;IACxB,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,IAAI,CAAC;AAClD,CAAC;AAID,SAAS,GAAG,CAAC,CAAU,EAAE,QAAQ,GAAG,EAAE;IACpC,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC9C,CAAC;AAED,SAAS,GAAG,CAAC,CAAU,EAAE,QAAgB;IACvC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AACpE,CAAC;AAED,SAAS,GAAG,CAAC,CAAU;IACrB,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED,SAAS,IAAI,CAAC,CAAU,EAAE,QAAQ,GAAG,KAAK;IACxC,OAAO,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAqD;IAC/E,KAAK,CAAC,mBAAmB,CAAC,IAAI;QAC5B,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;QAC/E,MAAM,EAAE,GAAG,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;QAEzE,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAChD,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;YAC/C,YAAY,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;SACjD,CAAC,CAAC;QAEH,0EAA0E;QAC1E,0EAA0E;QAC1E,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC;YACpD,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;YAChD,CAAC,CAAC,EAAE,CAAC;QAEP,IAAI,aAAa,GAAY,SAAS,CAAC;QACvC,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,UAAU,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;YAC/C,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC,UAAU,CAAC,CAAC;YACzD,aAAa,GAAG,iBAAiB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC3D,CAAC;QAED,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,IAAI,aAAa,KAAK,SAAS;gBAAE,OAAO,WAAW,CAAC;YACpD,OAAO,EAAE,GAAI,WAAuC,EAAE,aAAa,EAAE,CAAC;QACxE,CAAC;QAED,MAAM,MAAM,GAAG,qBAAqB,CAAC,WAAW,EAAE,QAAQ,CAAC,qBAAqB,CAAC,CAAC;QAClF,MAAM,MAAM,GAA4B;YACtC,KAAK,EAAE;gBACL,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE;gBACrB,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI;gBACzB,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI;gBACzB,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI;gBACzB,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW;gBACvC,aAAa,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa;gBAC3C,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU;aACtC;YACD,aAAa,EAAE,QAAQ,CAAC,aAAa;YACrC,qBAAqB,EAAE,QAAQ,CAAC,qBAAqB;YACrD,MAAM,EACJ,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE;SACxE,CAAC;QACF,IAAI,aAAa,KAAK,SAAS;YAAE,MAAM,CAAC,aAAa,GAAG,aAAa,CAAC;QACtE,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAI;QACtB,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QACrE,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAC9E,yEAAyE;QACzE,qEAAqE;QACrE,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;QAClE,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,IAAI;QACrB,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,IAAI;QACvB,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,IAAI;QACxB,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,IAAI;QAC9B,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,mBAAmB,CAAC;YAC1C,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;YAChC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;YAC1B,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;YACxB,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;YAChC,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YAC9B,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC;YAC3C,gBAAgB,EAAE,OAAO,IAAI,CAAC,gBAAgB,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS;SAChG,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;QACjC,IAAI,IAAI,EAAE,CAAC;YACT,KAAK,UAAU,CAAC;gBACd,UAAU,EAAE,IAAI;gBAChB,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,eAAe;gBACvB,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,iCAAiC;gBAC1C,QAAQ,EAAE,4BAA4B;aACvC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAI;QACjB,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC;YAC9B,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YACpB,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC;YACvC,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC;YACrC,iBAAiB,EAAE,OAAO,IAAI,CAAC,iBAAiB,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS;YAClG,UAAU,EAAE,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;YAC7E,YAAY,EAAE,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;YACnF,cAAc,EAAE,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS;YACzF,QAAQ,EAAE,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;YACvE,gBAAgB,EAAE,OAAO,IAAI,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK;YAC5F,UAAU,EAAE,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;YAC7E,SAAS,EAAE,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;SACvF,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;QACjC,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5C,KAAK,UAAU,CAAC;gBACd,UAAU,EAAE,IAAI;gBAChB,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,YAAY;gBACpB,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,eAAe,OAAO,EAAE,CAAC,CAAC,CAAC,sBAAsB;gBACpE,QAAQ,EAAE,yBAAyB;aACpC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,IAAI;QACvB,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,aAAa,CAClC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,EACrB,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,EACvB,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,EACrE,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAC1E,CAAC;QACF,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,IAAI;QACzB,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,MAAM,EAAE,CAAC,eAAe,CAAC;YACvB,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;YAChC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YACpB,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;YAC1B,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;SAC9B,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,IAAI;QAChC,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAI;QACnB,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC,SAAS,CAAC;YAClB,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;YAChC,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC;YAC1C,QAAQ,EAAE,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;YACvE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC;YACvC,WAAW,EAAE,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;SACjF,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,oBAAoB;QACxB,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC,kBAAkB,EAAE,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,IAAI;QAC7B,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,MAAM,EAAE,CAAC,kBAAkB,CACzB,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAClB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EACb,IAAI,CAAC,KAAK,EACV,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAC9D,CAAC;QACF,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IACzE,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,IAAI;QAC3B,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,gBAAgB,CAAC;YACpC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YACpB,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;YACtB,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC;YACzC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;YAC1B,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;SACrB,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC,eAAe,EAAE,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,IAAI;QACxB,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC,cAAc,CAAC;YACvB,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;YAC1B,MAAM,EAAE,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;YACjE,UAAU,EAAE,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;SAC9E,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Instrumentation surface for UnClick Memory.
|
|
3
|
+
*
|
|
4
|
+
* Two related responsibilities live here:
|
|
5
|
+
*
|
|
6
|
+
* 1. Low-level event logger. Writes a single row per event to
|
|
7
|
+
* memory_load_events (local JSON in dev, Supabase table in cloud).
|
|
8
|
+
* Used by the MCP Resources ReadResource handler and other callers
|
|
9
|
+
* that want to record a memory-related event directly.
|
|
10
|
+
*
|
|
11
|
+
* 2. Thin wrappers over session-state.ts so server.ts can keep its
|
|
12
|
+
* request handlers focused on protocol work while still recording
|
|
13
|
+
* which autoload path (instructions / prompt / resource / tool
|
|
14
|
+
* description) actually reached the agent. The session snapshot is
|
|
15
|
+
* flushed to memory_load_events by load-events.ts on the first tool
|
|
16
|
+
* call.
|
|
17
|
+
*/
|
|
18
|
+
import { type AutoloadMethod } from "./session-state.js";
|
|
19
|
+
export interface MemoryLoadEvent {
|
|
20
|
+
tool_name: string;
|
|
21
|
+
params?: Record<string, unknown>;
|
|
22
|
+
result_bytes?: number;
|
|
23
|
+
created_at: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function logMemoryLoadEvent(event: Omit<MemoryLoadEvent, "created_at">): void;
|
|
26
|
+
/** Called from the Initialize handler. */
|
|
27
|
+
export declare function trackInitialize(clientInfo: {
|
|
28
|
+
name?: string;
|
|
29
|
+
version?: string;
|
|
30
|
+
} | undefined, instructionsSent: boolean): void;
|
|
31
|
+
/** Called from GetPromptRequest handler for any prompt read. */
|
|
32
|
+
export declare function trackPromptUsed(name: string): void;
|
|
33
|
+
/** Called from ReadResourceRequest handler for any resource read. */
|
|
34
|
+
export declare function trackResourceRead(uri: string): void;
|
|
35
|
+
/** Explicit hook for code paths that load context outside of the
|
|
36
|
+
* prompt / resource / instructions flow (e.g. direct RPC or manual). */
|
|
37
|
+
export declare function trackManualLoad(method?: AutoloadMethod): void;
|
|
38
|
+
//# sourceMappingURL=instrumentation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../src/memory/instrumentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAOH,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAK5B,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAqCD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC,GAAG,IAAI,CAYnF;AAED,0CAA0C;AAC1C,wBAAgB,eAAe,CAC7B,UAAU,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EAC3D,gBAAgB,EAAE,OAAO,GACxB,IAAI,CAMN;AAED,gEAAgE;AAChE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,qEAAqE;AACrE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEnD;AAED;yEACyE;AACzE,wBAAgB,eAAe,CAAC,MAAM,GAAE,cAAyB,GAAG,IAAI,CAEvE"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Instrumentation surface for UnClick Memory.
|
|
3
|
+
*
|
|
4
|
+
* Two related responsibilities live here:
|
|
5
|
+
*
|
|
6
|
+
* 1. Low-level event logger. Writes a single row per event to
|
|
7
|
+
* memory_load_events (local JSON in dev, Supabase table in cloud).
|
|
8
|
+
* Used by the MCP Resources ReadResource handler and other callers
|
|
9
|
+
* that want to record a memory-related event directly.
|
|
10
|
+
*
|
|
11
|
+
* 2. Thin wrappers over session-state.ts so server.ts can keep its
|
|
12
|
+
* request handlers focused on protocol work while still recording
|
|
13
|
+
* which autoload path (instructions / prompt / resource / tool
|
|
14
|
+
* description) actually reached the agent. The session snapshot is
|
|
15
|
+
* flushed to memory_load_events by load-events.ts on the first tool
|
|
16
|
+
* call.
|
|
17
|
+
*/
|
|
18
|
+
import * as fs from "fs";
|
|
19
|
+
import * as path from "path";
|
|
20
|
+
import * as os from "os";
|
|
21
|
+
import * as crypto from "crypto";
|
|
22
|
+
import { markPromptUsed, markResourceRead, markContextLoaded, setClientInfo, setInstructionsSent, } from "./session-state.js";
|
|
23
|
+
const DATA_DIR = path.join(os.homedir(), ".unclick", "memory");
|
|
24
|
+
const TABLE = "memory_load_events";
|
|
25
|
+
function appendLocal(row) {
|
|
26
|
+
try {
|
|
27
|
+
fs.mkdirSync(DATA_DIR, { recursive: true });
|
|
28
|
+
const file = path.join(DATA_DIR, `${TABLE}.json`);
|
|
29
|
+
let rows = [];
|
|
30
|
+
if (fs.existsSync(file)) {
|
|
31
|
+
try {
|
|
32
|
+
rows = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
33
|
+
if (!Array.isArray(rows))
|
|
34
|
+
rows = [];
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
rows = [];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
rows.push(row);
|
|
41
|
+
const tmp = file + ".tmp";
|
|
42
|
+
fs.writeFileSync(tmp, JSON.stringify(rows, null, 2));
|
|
43
|
+
fs.renameSync(tmp, file);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// instrumentation must never crash the caller
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function insertSupabase(row) {
|
|
50
|
+
try {
|
|
51
|
+
const { createClient } = await import("@supabase/supabase-js");
|
|
52
|
+
const url = process.env.SUPABASE_URL;
|
|
53
|
+
const key = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_ANON_KEY;
|
|
54
|
+
if (!url || !key)
|
|
55
|
+
return;
|
|
56
|
+
const sb = createClient(url, key, { auth: { persistSession: false, autoRefreshToken: false } });
|
|
57
|
+
await sb.from(TABLE).insert(row);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// table may not exist yet (chunk 0 installs it); ignore
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export function logMemoryLoadEvent(event) {
|
|
64
|
+
const row = {
|
|
65
|
+
id: crypto.randomUUID(),
|
|
66
|
+
created_at: new Date().toISOString(),
|
|
67
|
+
...event,
|
|
68
|
+
};
|
|
69
|
+
if (process.env.SUPABASE_URL) {
|
|
70
|
+
void insertSupabase(row);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
appendLocal(row);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** Called from the Initialize handler. */
|
|
77
|
+
export function trackInitialize(clientInfo, instructionsSent) {
|
|
78
|
+
setClientInfo(clientInfo);
|
|
79
|
+
setInstructionsSent(instructionsSent);
|
|
80
|
+
if (instructionsSent) {
|
|
81
|
+
markContextLoaded("instructions");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** Called from GetPromptRequest handler for any prompt read. */
|
|
85
|
+
export function trackPromptUsed(name) {
|
|
86
|
+
markPromptUsed(name);
|
|
87
|
+
}
|
|
88
|
+
/** Called from ReadResourceRequest handler for any resource read. */
|
|
89
|
+
export function trackResourceRead(uri) {
|
|
90
|
+
markResourceRead(uri);
|
|
91
|
+
}
|
|
92
|
+
/** Explicit hook for code paths that load context outside of the
|
|
93
|
+
* prompt / resource / instructions flow (e.g. direct RPC or manual). */
|
|
94
|
+
export function trackManualLoad(method = "manual") {
|
|
95
|
+
markContextLoaded(method);
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=instrumentation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../src/memory/instrumentation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load event logger for the UnClick MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Fires a single memory_load_events row per session on the first tool
|
|
5
|
+
* call, capturing everything session-state.ts has observed up to that
|
|
6
|
+
* point (client info, whether instructions were sent, whether the
|
|
7
|
+
* load-memory prompt fired, which memory:// resources were read, etc.).
|
|
8
|
+
*
|
|
9
|
+
* Designed to be fire-and-forget: any failure is swallowed so
|
|
10
|
+
* instrumentation never breaks an agent's actual tool call.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Log a tool call event. Safe to call on every tool invocation: the first
|
|
14
|
+
* call writes the memory_load_events row for this session, subsequent
|
|
15
|
+
* calls are no-ops (we only care about the initial load pattern).
|
|
16
|
+
*/
|
|
17
|
+
export declare function logToolCall(toolName: string): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=load-events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-events.d.ts","sourceRoot":"","sources":["../../src/memory/load-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA8CH;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQjE"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load event logger for the UnClick MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Fires a single memory_load_events row per session on the first tool
|
|
5
|
+
* call, capturing everything session-state.ts has observed up to that
|
|
6
|
+
* point (client info, whether instructions were sent, whether the
|
|
7
|
+
* load-memory prompt fired, which memory:// resources were read, etc.).
|
|
8
|
+
*
|
|
9
|
+
* Designed to be fire-and-forget: any failure is swallowed so
|
|
10
|
+
* instrumentation never breaks an agent's actual tool call.
|
|
11
|
+
*/
|
|
12
|
+
import * as crypto from "crypto";
|
|
13
|
+
import { sessionState, recordToolCall, } from "./session-state.js";
|
|
14
|
+
const MEMORY_API_BASE = process.env.UNCLICK_MEMORY_BASE_URL ||
|
|
15
|
+
process.env.UNCLICK_SITE_URL ||
|
|
16
|
+
"https://unclick.world";
|
|
17
|
+
function sha256hex(input) {
|
|
18
|
+
return crypto.createHash("sha256").update(input).digest("hex");
|
|
19
|
+
}
|
|
20
|
+
function buildPayload(state) {
|
|
21
|
+
const apiKey = process.env.UNCLICK_API_KEY;
|
|
22
|
+
return {
|
|
23
|
+
api_key_hash: apiKey ? sha256hex(apiKey) : null,
|
|
24
|
+
session_id: state.sessionId,
|
|
25
|
+
client_name: state.clientInfo?.name ?? null,
|
|
26
|
+
client_version: state.clientInfo?.version ?? null,
|
|
27
|
+
first_tool: state.firstToolCall,
|
|
28
|
+
context_loaded: state.contextLoaded,
|
|
29
|
+
tools_called_before_context: state.toolsCalledBeforeContext,
|
|
30
|
+
instructions_sent: state.instructionsSent,
|
|
31
|
+
prompt_used: state.promptUsed,
|
|
32
|
+
resource_read: state.resourcesRead.length > 0,
|
|
33
|
+
autoload_method: state.contextLoadMethod ?? "none",
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async function sendEvent(payload) {
|
|
37
|
+
const apiKey = process.env.UNCLICK_API_KEY;
|
|
38
|
+
const headers = { "Content-Type": "application/json" };
|
|
39
|
+
if (apiKey)
|
|
40
|
+
headers.Authorization = `Bearer ${apiKey}`;
|
|
41
|
+
await fetch(`${MEMORY_API_BASE}/api/memory-admin?action=log_tool_event`, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers,
|
|
44
|
+
body: JSON.stringify(payload),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Log a tool call event. Safe to call on every tool invocation: the first
|
|
49
|
+
* call writes the memory_load_events row for this session, subsequent
|
|
50
|
+
* calls are no-ops (we only care about the initial load pattern).
|
|
51
|
+
*/
|
|
52
|
+
export async function logToolCall(toolName) {
|
|
53
|
+
recordToolCall(toolName);
|
|
54
|
+
if (sessionState.logged)
|
|
55
|
+
return;
|
|
56
|
+
sessionState.logged = true;
|
|
57
|
+
const payload = buildPayload(sessionState);
|
|
58
|
+
// Fire-and-forget. Never let instrumentation break a tool call.
|
|
59
|
+
sendEvent(payload).catch(() => { });
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=load-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-events.js","sourceRoot":"","sources":["../../src/memory/load-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EACL,YAAY,EACZ,cAAc,GAEf,MAAM,oBAAoB,CAAC;AAE5B,MAAM,eAAe,GACnB,OAAO,CAAC,GAAG,CAAC,uBAAuB;IACnC,OAAO,CAAC,GAAG,CAAC,gBAAgB;IAC5B,uBAAuB,CAAC;AAE1B,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,YAAY,CAAC,KAAmB;IACvC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC3C,OAAO;QACL,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;QAC/C,UAAU,EAAE,KAAK,CAAC,SAAS;QAC3B,WAAW,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,IAAI,IAAI;QAC3C,cAAc,EAAE,KAAK,CAAC,UAAU,EAAE,OAAO,IAAI,IAAI;QACjD,UAAU,EAAE,KAAK,CAAC,aAAa;QAC/B,cAAc,EAAE,KAAK,CAAC,aAAa;QACnC,2BAA2B,EAAE,KAAK,CAAC,wBAAwB;QAC3D,iBAAiB,EAAE,KAAK,CAAC,gBAAgB;QACzC,WAAW,EAAE,KAAK,CAAC,UAAU;QAC7B,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;QAC7C,eAAe,EAAE,KAAK,CAAC,iBAAiB,IAAI,MAAM;KACnD,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,OAAgC;IACvD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC3C,MAAM,OAAO,GAA2B,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;IAC/E,IAAI,MAAM;QAAE,OAAO,CAAC,aAAa,GAAG,UAAU,MAAM,EAAE,CAAC;IACvD,MAAM,KAAK,CAAC,GAAG,eAAe,yCAAyC,EAAE;QACvE,MAAM,EAAE,MAAM;QACd,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;KAC9B,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB;IAChD,cAAc,CAAC,QAAQ,CAAC,CAAC;IACzB,IAAI,YAAY,CAAC,MAAM;QAAE,OAAO;IAChC,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC;IAE3B,MAAM,OAAO,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;IAC3C,gEAAgE;IAChE,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local JSON file storage backend for UnClick Memory.
|
|
3
|
+
*
|
|
4
|
+
* Zero-config mode: no accounts, no keys, no database setup.
|
|
5
|
+
* Memory is stored as JSON files in ~/.unclick/memory/
|
|
6
|
+
*
|
|
7
|
+
* This is the default when no SUPABASE_URL is set.
|
|
8
|
+
* Upgrade to Supabase for cloud sync across machines.
|
|
9
|
+
*/
|
|
10
|
+
import type { MemoryBackend, SessionSummaryInput, FactInput, InvalidateFactInput, ConversationInput, CodeInput, LibraryDocInput } from "./types.js";
|
|
11
|
+
export declare class LocalBackend implements MemoryBackend {
|
|
12
|
+
constructor();
|
|
13
|
+
getStartupContext(numSessions: number): Promise<unknown>;
|
|
14
|
+
searchMemory(query: string, maxResults: number): Promise<unknown>;
|
|
15
|
+
searchFacts(query: string): Promise<unknown>;
|
|
16
|
+
searchLibrary(query: string): Promise<unknown>;
|
|
17
|
+
getLibraryDoc(slug: string): Promise<unknown>;
|
|
18
|
+
listLibrary(): Promise<unknown>;
|
|
19
|
+
writeSessionSummary(data: SessionSummaryInput): Promise<{
|
|
20
|
+
id: string;
|
|
21
|
+
}>;
|
|
22
|
+
addFact(data: FactInput): Promise<{
|
|
23
|
+
id: string;
|
|
24
|
+
}>;
|
|
25
|
+
supersedeFact(oldId: string, newText: string, category?: string, confidence?: number): Promise<string>;
|
|
26
|
+
logConversation(data: ConversationInput): Promise<void>;
|
|
27
|
+
getConversationDetail(sessionId: string): Promise<unknown>;
|
|
28
|
+
storeCode(data: CodeInput): Promise<{
|
|
29
|
+
id: string;
|
|
30
|
+
}>;
|
|
31
|
+
getBusinessContext(): Promise<unknown[]>;
|
|
32
|
+
setBusinessContext(category: string, key: string, value: unknown, priority?: number): Promise<void>;
|
|
33
|
+
upsertLibraryDoc(data: LibraryDocInput): Promise<string>;
|
|
34
|
+
manageDecay(): Promise<unknown>;
|
|
35
|
+
getMemoryStatus(): Promise<unknown>;
|
|
36
|
+
invalidateFact(_input: InvalidateFactInput): Promise<{
|
|
37
|
+
invalidated_at: string;
|
|
38
|
+
}>;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/memory/local.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EACV,aAAa,EACb,mBAAmB,EACnB,SAAS,EACT,mBAAmB,EACnB,iBAAiB,EACjB,SAAS,EACT,eAAe,EAChB,MAAM,YAAY,CAAC;AAoIpB,qBAAa,YAAa,YAAW,aAAa;;IAM1C,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkDxD,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQjE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ5C,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ9C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkB7C,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAM/B,mBAAmB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAkBvE,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAwBjD,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA6BtG,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAavD,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAO1D,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAgBnD,kBAAkB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAKxC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BnG,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAgDxD,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAgD/B,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAqBnC,cAAc,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;CAGvF"}
|