@arkimedehq/openclaw-recordare 0.1.0 → 0.2.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/README.md +56 -33
- package/README_it.md +60 -36
- package/dist/index.js +536 -186
- package/openclaw.plugin.json +27 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -97,7 +97,7 @@ var require_code = __commonJS({
|
|
|
97
97
|
}
|
|
98
98
|
exports._ = _;
|
|
99
99
|
var plus = new _Code("+");
|
|
100
|
-
function
|
|
100
|
+
function str3(strs, ...args) {
|
|
101
101
|
const expr = [safeStringify(strs[0])];
|
|
102
102
|
let i = 0;
|
|
103
103
|
while (i < args.length) {
|
|
@@ -108,7 +108,7 @@ var require_code = __commonJS({
|
|
|
108
108
|
optimize(expr);
|
|
109
109
|
return new _Code(expr);
|
|
110
110
|
}
|
|
111
|
-
exports.str =
|
|
111
|
+
exports.str = str3;
|
|
112
112
|
function addCodeArg(code, arg) {
|
|
113
113
|
if (arg instanceof _Code)
|
|
114
114
|
code.push(...arg._items);
|
|
@@ -151,7 +151,7 @@ var require_code = __commonJS({
|
|
|
151
151
|
return;
|
|
152
152
|
}
|
|
153
153
|
function strConcat(c1, c2) {
|
|
154
|
-
return c2.emptyStr() ? c1 : c1.emptyStr() ? c2 :
|
|
154
|
+
return c2.emptyStr() ? c1 : c1.emptyStr() ? c2 : str3`${c1}${c2}`;
|
|
155
155
|
}
|
|
156
156
|
exports.strConcat = strConcat;
|
|
157
157
|
function interpolate(x) {
|
|
@@ -865,12 +865,12 @@ var require_codegen = __commonJS({
|
|
|
865
865
|
}
|
|
866
866
|
// `for-in` statement.
|
|
867
867
|
// With option `ownProperties` replaced with a `for-of` loop for object keys
|
|
868
|
-
forIn(nameOrPrefix,
|
|
868
|
+
forIn(nameOrPrefix, obj, forBody, varKind = this.opts.es5 ? scope_1.varKinds.var : scope_1.varKinds.const) {
|
|
869
869
|
if (this.opts.ownProperties) {
|
|
870
|
-
return this.forOf(nameOrPrefix, (0, code_1._)`Object.keys(${
|
|
870
|
+
return this.forOf(nameOrPrefix, (0, code_1._)`Object.keys(${obj})`, forBody);
|
|
871
871
|
}
|
|
872
872
|
const name = this._scope.toName(nameOrPrefix);
|
|
873
|
-
return this._for(new ForIter("in", varKind, name,
|
|
873
|
+
return this._for(new ForIter("in", varKind, name, obj), () => forBody(name));
|
|
874
874
|
}
|
|
875
875
|
// end `for` loop
|
|
876
876
|
endFor() {
|
|
@@ -1113,22 +1113,22 @@ var require_util = __commonJS({
|
|
|
1113
1113
|
return (0, codegen_1._)`${topSchemaRef}${schemaPath}${(0, codegen_1.getProperty)(keyword)}`;
|
|
1114
1114
|
}
|
|
1115
1115
|
exports.schemaRefOrVal = schemaRefOrVal;
|
|
1116
|
-
function unescapeFragment(
|
|
1117
|
-
return unescapeJsonPointer(decodeURIComponent(
|
|
1116
|
+
function unescapeFragment(str3) {
|
|
1117
|
+
return unescapeJsonPointer(decodeURIComponent(str3));
|
|
1118
1118
|
}
|
|
1119
1119
|
exports.unescapeFragment = unescapeFragment;
|
|
1120
|
-
function escapeFragment(
|
|
1121
|
-
return encodeURIComponent(escapeJsonPointer(
|
|
1120
|
+
function escapeFragment(str3) {
|
|
1121
|
+
return encodeURIComponent(escapeJsonPointer(str3));
|
|
1122
1122
|
}
|
|
1123
1123
|
exports.escapeFragment = escapeFragment;
|
|
1124
|
-
function escapeJsonPointer(
|
|
1125
|
-
if (typeof
|
|
1126
|
-
return `${
|
|
1127
|
-
return
|
|
1124
|
+
function escapeJsonPointer(str3) {
|
|
1125
|
+
if (typeof str3 == "number")
|
|
1126
|
+
return `${str3}`;
|
|
1127
|
+
return str3.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
1128
1128
|
}
|
|
1129
1129
|
exports.escapeJsonPointer = escapeJsonPointer;
|
|
1130
|
-
function unescapeJsonPointer(
|
|
1131
|
-
return
|
|
1130
|
+
function unescapeJsonPointer(str3) {
|
|
1131
|
+
return str3.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
1132
1132
|
}
|
|
1133
1133
|
exports.unescapeJsonPointer = unescapeJsonPointer;
|
|
1134
1134
|
function eachItem(xs, f) {
|
|
@@ -2153,8 +2153,8 @@ var require_json_schema_traverse = __commonJS({
|
|
|
2153
2153
|
post(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex);
|
|
2154
2154
|
}
|
|
2155
2155
|
}
|
|
2156
|
-
function escapeJsonPtr(
|
|
2157
|
-
return
|
|
2156
|
+
function escapeJsonPtr(str3) {
|
|
2157
|
+
return str3.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
2158
2158
|
}
|
|
2159
2159
|
}
|
|
2160
2160
|
});
|
|
@@ -2690,11 +2690,11 @@ var require_validate = __commonJS({
|
|
|
2690
2690
|
if (!this.allErrors)
|
|
2691
2691
|
this.gen.if(cond);
|
|
2692
2692
|
}
|
|
2693
|
-
setParams(
|
|
2693
|
+
setParams(obj, assign) {
|
|
2694
2694
|
if (assign)
|
|
2695
|
-
Object.assign(this.params,
|
|
2695
|
+
Object.assign(this.params, obj);
|
|
2696
2696
|
else
|
|
2697
|
-
this.params =
|
|
2697
|
+
this.params = obj;
|
|
2698
2698
|
}
|
|
2699
2699
|
block$data(valid, codeBlock, $dataValid = codegen_1.nil) {
|
|
2700
2700
|
this.gen.block(() => {
|
|
@@ -3251,10 +3251,10 @@ var require_utils = __commonJS({
|
|
|
3251
3251
|
isIPV6: true
|
|
3252
3252
|
};
|
|
3253
3253
|
}
|
|
3254
|
-
function findToken(
|
|
3254
|
+
function findToken(str3, token) {
|
|
3255
3255
|
let ind = 0;
|
|
3256
|
-
for (let i = 0; i <
|
|
3257
|
-
if (
|
|
3256
|
+
for (let i = 0; i < str3.length; i++) {
|
|
3257
|
+
if (str3[i] === token) ind++;
|
|
3258
3258
|
}
|
|
3259
3259
|
return ind;
|
|
3260
3260
|
}
|
|
@@ -4268,7 +4268,7 @@ var require_core = __commonJS({
|
|
|
4268
4268
|
var util_1 = require_util();
|
|
4269
4269
|
var $dataRefSchema = require_data();
|
|
4270
4270
|
var uri_1 = require_uri();
|
|
4271
|
-
var defaultRegExp = (
|
|
4271
|
+
var defaultRegExp = (str3, flags) => new RegExp(str3, flags);
|
|
4272
4272
|
defaultRegExp.code = "new RegExp";
|
|
4273
4273
|
var META_IGNORE_OPTIONS = ["removeAdditional", "useDefaults", "coerceTypes"];
|
|
4274
4274
|
var EXT_SCOPE_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -5063,16 +5063,16 @@ var require_ucs2length = __commonJS({
|
|
|
5063
5063
|
"../../packages/client/node_modules/ajv/dist/runtime/ucs2length.js"(exports) {
|
|
5064
5064
|
"use strict";
|
|
5065
5065
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5066
|
-
function ucs2length(
|
|
5067
|
-
const len =
|
|
5066
|
+
function ucs2length(str3) {
|
|
5067
|
+
const len = str3.length;
|
|
5068
5068
|
let length = 0;
|
|
5069
5069
|
let pos = 0;
|
|
5070
5070
|
let value;
|
|
5071
5071
|
while (pos < len) {
|
|
5072
5072
|
length++;
|
|
5073
|
-
value =
|
|
5073
|
+
value = str3.charCodeAt(pos++);
|
|
5074
5074
|
if (value >= 55296 && value <= 56319 && pos < len) {
|
|
5075
|
-
value =
|
|
5075
|
+
value = str3.charCodeAt(pos);
|
|
5076
5076
|
if ((value & 64512) === 56320)
|
|
5077
5077
|
pos++;
|
|
5078
5078
|
}
|
|
@@ -6955,8 +6955,8 @@ var require_formats = __commonJS({
|
|
|
6955
6955
|
}
|
|
6956
6956
|
var DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
|
|
6957
6957
|
var DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
6958
|
-
function date4(
|
|
6959
|
-
const matches = DATE.exec(
|
|
6958
|
+
function date4(str3) {
|
|
6959
|
+
const matches = DATE.exec(str3);
|
|
6960
6960
|
if (!matches)
|
|
6961
6961
|
return false;
|
|
6962
6962
|
const year = +matches[1];
|
|
@@ -6975,8 +6975,8 @@ var require_formats = __commonJS({
|
|
|
6975
6975
|
}
|
|
6976
6976
|
var TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;
|
|
6977
6977
|
function getTime(strictTimeZone) {
|
|
6978
|
-
return function time3(
|
|
6979
|
-
const matches = TIME.exec(
|
|
6978
|
+
return function time3(str3) {
|
|
6979
|
+
const matches = TIME.exec(str3);
|
|
6980
6980
|
if (!matches)
|
|
6981
6981
|
return false;
|
|
6982
6982
|
const hr = +matches[1];
|
|
@@ -7022,8 +7022,8 @@ var require_formats = __commonJS({
|
|
|
7022
7022
|
var DATE_TIME_SEPARATOR = /t|\s/i;
|
|
7023
7023
|
function getDateTime(strictTimeZone) {
|
|
7024
7024
|
const time3 = getTime(strictTimeZone);
|
|
7025
|
-
return function date_time(
|
|
7026
|
-
const dateTime =
|
|
7025
|
+
return function date_time(str3) {
|
|
7026
|
+
const dateTime = str3.split(DATE_TIME_SEPARATOR);
|
|
7027
7027
|
return dateTime.length === 2 && date4(dateTime[0]) && time3(dateTime[1]);
|
|
7028
7028
|
};
|
|
7029
7029
|
}
|
|
@@ -7048,13 +7048,13 @@ var require_formats = __commonJS({
|
|
|
7048
7048
|
}
|
|
7049
7049
|
var NOT_URI_FRAGMENT = /\/|:/;
|
|
7050
7050
|
var URI = /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;
|
|
7051
|
-
function uri(
|
|
7052
|
-
return NOT_URI_FRAGMENT.test(
|
|
7051
|
+
function uri(str3) {
|
|
7052
|
+
return NOT_URI_FRAGMENT.test(str3) && URI.test(str3);
|
|
7053
7053
|
}
|
|
7054
7054
|
var BYTE = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/gm;
|
|
7055
|
-
function byte(
|
|
7055
|
+
function byte(str3) {
|
|
7056
7056
|
BYTE.lastIndex = 0;
|
|
7057
|
-
return BYTE.test(
|
|
7057
|
+
return BYTE.test(str3);
|
|
7058
7058
|
}
|
|
7059
7059
|
var MIN_INT32 = -(2 ** 31);
|
|
7060
7060
|
var MAX_INT32 = 2 ** 31 - 1;
|
|
@@ -7068,11 +7068,11 @@ var require_formats = __commonJS({
|
|
|
7068
7068
|
return true;
|
|
7069
7069
|
}
|
|
7070
7070
|
var Z_ANCHOR = /[^\\]\\Z/;
|
|
7071
|
-
function regex(
|
|
7072
|
-
if (Z_ANCHOR.test(
|
|
7071
|
+
function regex(str3) {
|
|
7072
|
+
if (Z_ANCHOR.test(str3))
|
|
7073
7073
|
return false;
|
|
7074
7074
|
try {
|
|
7075
|
-
new RegExp(
|
|
7075
|
+
new RegExp(str3);
|
|
7076
7076
|
return true;
|
|
7077
7077
|
} catch (e) {
|
|
7078
7078
|
return false;
|
|
@@ -7207,25 +7207,25 @@ var require_content_type = __commonJS({
|
|
|
7207
7207
|
var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
7208
7208
|
exports.format = format;
|
|
7209
7209
|
exports.parse = parse3;
|
|
7210
|
-
function format(
|
|
7211
|
-
if (!
|
|
7210
|
+
function format(obj) {
|
|
7211
|
+
if (!obj || typeof obj !== "object") {
|
|
7212
7212
|
throw new TypeError("argument obj is required");
|
|
7213
7213
|
}
|
|
7214
|
-
var
|
|
7215
|
-
var type =
|
|
7214
|
+
var parameters2 = obj.parameters;
|
|
7215
|
+
var type = obj.type;
|
|
7216
7216
|
if (!type || !TYPE_REGEXP.test(type)) {
|
|
7217
7217
|
throw new TypeError("invalid type");
|
|
7218
7218
|
}
|
|
7219
7219
|
var string4 = type;
|
|
7220
|
-
if (
|
|
7220
|
+
if (parameters2 && typeof parameters2 === "object") {
|
|
7221
7221
|
var param;
|
|
7222
|
-
var params = Object.keys(
|
|
7222
|
+
var params = Object.keys(parameters2).sort();
|
|
7223
7223
|
for (var i = 0; i < params.length; i++) {
|
|
7224
7224
|
param = params[i];
|
|
7225
7225
|
if (!TOKEN_REGEXP.test(param)) {
|
|
7226
7226
|
throw new TypeError("invalid parameter name");
|
|
7227
7227
|
}
|
|
7228
|
-
string4 += "; " + param + "=" + qstring(
|
|
7228
|
+
string4 += "; " + param + "=" + qstring(parameters2[param]);
|
|
7229
7229
|
}
|
|
7230
7230
|
}
|
|
7231
7231
|
return string4;
|
|
@@ -7243,7 +7243,7 @@ var require_content_type = __commonJS({
|
|
|
7243
7243
|
if (!TYPE_REGEXP.test(type)) {
|
|
7244
7244
|
throw new TypeError("invalid media type");
|
|
7245
7245
|
}
|
|
7246
|
-
var
|
|
7246
|
+
var obj = new ContentType(type.toLowerCase());
|
|
7247
7247
|
if (index !== -1) {
|
|
7248
7248
|
var key;
|
|
7249
7249
|
var match;
|
|
@@ -7262,20 +7262,20 @@ var require_content_type = __commonJS({
|
|
|
7262
7262
|
value = value.replace(QESC_REGEXP, "$1");
|
|
7263
7263
|
}
|
|
7264
7264
|
}
|
|
7265
|
-
|
|
7265
|
+
obj.parameters[key] = value;
|
|
7266
7266
|
}
|
|
7267
7267
|
if (index !== header.length) {
|
|
7268
7268
|
throw new TypeError("invalid parameter format");
|
|
7269
7269
|
}
|
|
7270
7270
|
}
|
|
7271
|
-
return
|
|
7271
|
+
return obj;
|
|
7272
7272
|
}
|
|
7273
|
-
function getcontenttype(
|
|
7273
|
+
function getcontenttype(obj) {
|
|
7274
7274
|
var header;
|
|
7275
|
-
if (typeof
|
|
7276
|
-
header =
|
|
7277
|
-
} else if (typeof
|
|
7278
|
-
header =
|
|
7275
|
+
if (typeof obj.getHeader === "function") {
|
|
7276
|
+
header = obj.getHeader("content-type");
|
|
7277
|
+
} else if (typeof obj.headers === "object") {
|
|
7278
|
+
header = obj.headers && obj.headers["content-type"];
|
|
7279
7279
|
}
|
|
7280
7280
|
if (typeof header !== "string") {
|
|
7281
7281
|
throw new TypeError("content-type header is missing from object");
|
|
@@ -7283,14 +7283,14 @@ var require_content_type = __commonJS({
|
|
|
7283
7283
|
return header;
|
|
7284
7284
|
}
|
|
7285
7285
|
function qstring(val) {
|
|
7286
|
-
var
|
|
7287
|
-
if (TOKEN_REGEXP.test(
|
|
7288
|
-
return
|
|
7286
|
+
var str3 = String(val);
|
|
7287
|
+
if (TOKEN_REGEXP.test(str3)) {
|
|
7288
|
+
return str3;
|
|
7289
7289
|
}
|
|
7290
|
-
if (
|
|
7290
|
+
if (str3.length > 0 && !TEXT_REGEXP.test(str3)) {
|
|
7291
7291
|
throw new TypeError("invalid parameter value");
|
|
7292
7292
|
}
|
|
7293
|
-
return '"' +
|
|
7293
|
+
return '"' + str3.replace(QUOTE_REGEXP, "\\$1") + '"';
|
|
7294
7294
|
}
|
|
7295
7295
|
function ContentType(type) {
|
|
7296
7296
|
this.parameters = /* @__PURE__ */ Object.create(null);
|
|
@@ -7318,12 +7318,15 @@ function parseConfig(raw, env = process.env) {
|
|
|
7318
7318
|
if (user) users[k.trim()] = user;
|
|
7319
7319
|
}
|
|
7320
7320
|
}
|
|
7321
|
+
const selfSenders = Array.isArray(c.selfSenders) ? c.selfSenders.map(str).filter((v) => !!v) : [];
|
|
7321
7322
|
const personal = apiKey.startsWith("rp_");
|
|
7322
7323
|
return {
|
|
7323
7324
|
url: url2,
|
|
7324
7325
|
apiKey,
|
|
7326
|
+
memoryPer: c.memoryPer === "user" ? "user" : "agent",
|
|
7327
|
+
selfSenders,
|
|
7325
7328
|
users,
|
|
7326
|
-
// A personal token is one
|
|
7329
|
+
// A personal token is one memory (the user header is ignored): any non-empty value stands for it.
|
|
7327
7330
|
defaultUser: str(c.defaultUser) ?? (personal ? "me" : void 0),
|
|
7328
7331
|
autoRecall: bool(c.autoRecall, true),
|
|
7329
7332
|
capture: bool(c.capture, true),
|
|
@@ -7342,6 +7345,7 @@ var USER_HEADER = "X-Recordare-User";
|
|
|
7342
7345
|
var CONVERSATION_HEADER = "X-Recordare-Conversation";
|
|
7343
7346
|
var MAX_CONTENT_BYTES = 64 * 1024;
|
|
7344
7347
|
var MAX_MESSAGES_PER_REQUEST = 500;
|
|
7348
|
+
var SOURCE_PART_BYTES = 4 * 1024 * 1024;
|
|
7345
7349
|
function clipUtf8(text, maxBytes = MAX_CONTENT_BYTES, marker = " \u2026[truncated]") {
|
|
7346
7350
|
const bytes = Buffer.from(text, "utf8");
|
|
7347
7351
|
if (bytes.length <= maxBytes) return text;
|
|
@@ -7368,7 +7372,7 @@ var RecordareUnavailableError = class extends Error {
|
|
|
7368
7372
|
};
|
|
7369
7373
|
var MemoryNotEmptyError = class extends Error {
|
|
7370
7374
|
constructor() {
|
|
7371
|
-
super("The memory
|
|
7375
|
+
super("The memory mode can change only while the memory is empty");
|
|
7372
7376
|
this.name = "MemoryNotEmptyError";
|
|
7373
7377
|
}
|
|
7374
7378
|
};
|
|
@@ -7601,8 +7605,8 @@ function defineLazy(object3, key, getter) {
|
|
|
7601
7605
|
configurable: true
|
|
7602
7606
|
});
|
|
7603
7607
|
}
|
|
7604
|
-
function objectClone(
|
|
7605
|
-
return Object.create(Object.getPrototypeOf(
|
|
7608
|
+
function objectClone(obj) {
|
|
7609
|
+
return Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
|
|
7606
7610
|
}
|
|
7607
7611
|
function assignProp(target, prop, value) {
|
|
7608
7612
|
Object.defineProperty(target, prop, {
|
|
@@ -7673,10 +7677,10 @@ function mergeDefs(...defs) {
|
|
|
7673
7677
|
function cloneDef(schema) {
|
|
7674
7678
|
return mergeDefs(schema._zod.def);
|
|
7675
7679
|
}
|
|
7676
|
-
function getElementAtPath(
|
|
7680
|
+
function getElementAtPath(obj, path) {
|
|
7677
7681
|
if (!path)
|
|
7678
|
-
return
|
|
7679
|
-
return path.reduce((acc, key) => acc?.[key],
|
|
7682
|
+
return obj;
|
|
7683
|
+
return path.reduce((acc, key) => acc?.[key], obj);
|
|
7680
7684
|
}
|
|
7681
7685
|
function promiseAllObject(promisesObj) {
|
|
7682
7686
|
const keys = Object.keys(promisesObj);
|
|
@@ -7691,14 +7695,14 @@ function promiseAllObject(promisesObj) {
|
|
|
7691
7695
|
}
|
|
7692
7696
|
function randomString(length = 10) {
|
|
7693
7697
|
const chars = "abcdefghijklmnopqrstuvwxyz";
|
|
7694
|
-
let
|
|
7698
|
+
let str3 = "";
|
|
7695
7699
|
for (let i = 0; i < length; i++) {
|
|
7696
|
-
|
|
7700
|
+
str3 += chars[Math.floor(Math.random() * chars.length)];
|
|
7697
7701
|
}
|
|
7698
|
-
return
|
|
7702
|
+
return str3;
|
|
7699
7703
|
}
|
|
7700
|
-
function esc(
|
|
7701
|
-
return JSON.stringify(
|
|
7704
|
+
function esc(str3) {
|
|
7705
|
+
return JSON.stringify(str3);
|
|
7702
7706
|
}
|
|
7703
7707
|
function slugify(input) {
|
|
7704
7708
|
return input.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -7812,8 +7816,8 @@ var primitiveTypes = /* @__PURE__ */ new Set([
|
|
|
7812
7816
|
"symbol",
|
|
7813
7817
|
"undefined"
|
|
7814
7818
|
]);
|
|
7815
|
-
function escapeRegex(
|
|
7816
|
-
return
|
|
7819
|
+
function escapeRegex(str3) {
|
|
7820
|
+
return str3.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7817
7821
|
}
|
|
7818
7822
|
function clone(inst, def, params) {
|
|
7819
7823
|
const cl = new inst._zod.constr(def ?? inst._zod.def);
|
|
@@ -8067,13 +8071,13 @@ function getSizableOrigin(input) {
|
|
|
8067
8071
|
return "unknown";
|
|
8068
8072
|
}
|
|
8069
8073
|
var highSurrogate = /[\uD800-\uDBFF]/;
|
|
8070
|
-
function codePointLength(
|
|
8071
|
-
const units =
|
|
8072
|
-
if (!highSurrogate.test(
|
|
8074
|
+
function codePointLength(str3) {
|
|
8075
|
+
const units = str3.length;
|
|
8076
|
+
if (!highSurrogate.test(str3))
|
|
8073
8077
|
return units;
|
|
8074
8078
|
let count = units;
|
|
8075
8079
|
for (let i = 0; i < units - 1; i++) {
|
|
8076
|
-
if ((
|
|
8080
|
+
if ((str3.charCodeAt(i) & 64512) === 55296 && (str3.charCodeAt(i + 1) & 64512) === 56320) {
|
|
8077
8081
|
count--;
|
|
8078
8082
|
i++;
|
|
8079
8083
|
}
|
|
@@ -8100,9 +8104,9 @@ function parsedType(data) {
|
|
|
8100
8104
|
if (Array.isArray(data)) {
|
|
8101
8105
|
return "array";
|
|
8102
8106
|
}
|
|
8103
|
-
const
|
|
8104
|
-
if (
|
|
8105
|
-
return
|
|
8107
|
+
const obj = data;
|
|
8108
|
+
if (obj && Object.getPrototypeOf(obj) !== Object.prototype && "constructor" in obj && obj.constructor) {
|
|
8109
|
+
return obj.constructor.name;
|
|
8106
8110
|
}
|
|
8107
8111
|
}
|
|
8108
8112
|
}
|
|
@@ -8120,8 +8124,8 @@ function issue(...args) {
|
|
|
8120
8124
|
}
|
|
8121
8125
|
return { ...iss };
|
|
8122
8126
|
}
|
|
8123
|
-
function cleanEnum(
|
|
8124
|
-
return Object.entries(
|
|
8127
|
+
function cleanEnum(obj) {
|
|
8128
|
+
return Object.entries(obj).filter(([k, _]) => {
|
|
8125
8129
|
return Number.isNaN(Number.parseInt(k, 10));
|
|
8126
8130
|
}).map((el) => el[1]);
|
|
8127
8131
|
}
|
|
@@ -8445,15 +8449,15 @@ var $ZodError = $constructor("$ZodError", initializer);
|
|
|
8445
8449
|
var $ZodRealError = $constructor("$ZodError", initializer, void 0, {
|
|
8446
8450
|
Parent: Error
|
|
8447
8451
|
});
|
|
8448
|
-
function node(
|
|
8449
|
-
if (!Object.prototype.hasOwnProperty.call(
|
|
8452
|
+
function node(obj, key, make) {
|
|
8453
|
+
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
8450
8454
|
if (key === "__proto__") {
|
|
8451
|
-
Object.defineProperty(
|
|
8455
|
+
Object.defineProperty(obj, key, { value: make(), writable: true, enumerable: true, configurable: true });
|
|
8452
8456
|
} else {
|
|
8453
|
-
|
|
8457
|
+
obj[key] = make();
|
|
8454
8458
|
}
|
|
8455
8459
|
}
|
|
8456
|
-
return
|
|
8460
|
+
return obj[key];
|
|
8457
8461
|
}
|
|
8458
8462
|
function flattenError(error2, mapper = (issue2) => issue2.message) {
|
|
8459
8463
|
const fieldErrors = {};
|
|
@@ -16875,15 +16879,15 @@ function applyElicitationDefaults(schema, data) {
|
|
|
16875
16879
|
if (!schema || data === null || typeof data !== "object")
|
|
16876
16880
|
return;
|
|
16877
16881
|
if (schema.type === "object" && schema.properties && typeof schema.properties === "object") {
|
|
16878
|
-
const
|
|
16882
|
+
const obj = data;
|
|
16879
16883
|
const props = schema.properties;
|
|
16880
16884
|
for (const key of Object.keys(props)) {
|
|
16881
16885
|
const propSchema = props[key];
|
|
16882
|
-
if (
|
|
16883
|
-
|
|
16886
|
+
if (obj[key] === void 0 && Object.prototype.hasOwnProperty.call(propSchema, "default")) {
|
|
16887
|
+
obj[key] = propSchema.default;
|
|
16884
16888
|
}
|
|
16885
|
-
if (
|
|
16886
|
-
applyElicitationDefaults(propSchema,
|
|
16889
|
+
if (obj[key] !== void 0) {
|
|
16890
|
+
applyElicitationDefaults(propSchema, obj[key]);
|
|
16887
16891
|
}
|
|
16888
16892
|
}
|
|
16889
16893
|
}
|
|
@@ -19066,7 +19070,7 @@ var RecordareMcp = class {
|
|
|
19066
19070
|
},
|
|
19067
19071
|
requestInit: { headers: { ...this.http.headers(user), [CONVERSATION_HEADER]: conversation } }
|
|
19068
19072
|
});
|
|
19069
|
-
const client = new Client(this.options.clientInfo ?? { name: "recordare-client", version: "0.
|
|
19073
|
+
const client = new Client(this.options.clientInfo ?? { name: "recordare-client", version: "0.2.0" });
|
|
19070
19074
|
await client.connect(transport);
|
|
19071
19075
|
return client;
|
|
19072
19076
|
}
|
|
@@ -19092,11 +19096,11 @@ var RecordareClient = class {
|
|
|
19092
19096
|
this.http = new Http(options);
|
|
19093
19097
|
this.mcp = new RecordareMcp(this.http, options.mcp);
|
|
19094
19098
|
}
|
|
19095
|
-
/** The
|
|
19099
|
+
/** The memory behind `user` (auto-provisioned when the client allows it), its mode and gender. */
|
|
19096
19100
|
me(user) {
|
|
19097
19101
|
return this.http.request("GET", "api/v1/me", { user });
|
|
19098
19102
|
}
|
|
19099
|
-
/** The
|
|
19103
|
+
/** The memory's settings from the platform: the name (keep it in sync on every rename), the mode and the gender. */
|
|
19100
19104
|
async updateMe(user, settings) {
|
|
19101
19105
|
try {
|
|
19102
19106
|
await this.http.request("PATCH", "api/v1/me", { user, body: settings });
|
|
@@ -19107,10 +19111,10 @@ var RecordareClient = class {
|
|
|
19107
19111
|
}
|
|
19108
19112
|
/**
|
|
19109
19113
|
* Sends messages of one conversation, split into requests of at most MAX_MESSAGES_PER_REQUEST. Idempotent: Recordare
|
|
19110
|
-
* deduplicates on each message's externalId.
|
|
19114
|
+
* deduplicates on each message's externalId. Recordare always stores (D50): the on/off switch is the platform's.
|
|
19111
19115
|
*/
|
|
19112
19116
|
async ingest(user, req) {
|
|
19113
|
-
const total = { conversationId: null, accepted: 0, duplicates: 0, conflicts: []
|
|
19117
|
+
const total = { conversationId: null, accepted: 0, duplicates: 0, conflicts: [] };
|
|
19114
19118
|
for (let i = 0; i < req.messages.length; i += MAX_MESSAGES_PER_REQUEST) {
|
|
19115
19119
|
const last = i + MAX_MESSAGES_PER_REQUEST >= req.messages.length;
|
|
19116
19120
|
const part = await this.http.request("POST", "api/v1/ingest/messages", {
|
|
@@ -19126,7 +19130,6 @@ var RecordareClient = class {
|
|
|
19126
19130
|
total.accepted += part.accepted;
|
|
19127
19131
|
total.duplicates += part.duplicates;
|
|
19128
19132
|
total.conflicts.push(...part.conflicts);
|
|
19129
|
-
total.stored &&= part.stored;
|
|
19130
19133
|
}
|
|
19131
19134
|
return total;
|
|
19132
19135
|
}
|
|
@@ -19138,6 +19141,17 @@ var RecordareClient = class {
|
|
|
19138
19141
|
context(user, conversation, query) {
|
|
19139
19142
|
return this.http.request("POST", "api/v1/context", { user, body: { query }, headers: { [CONVERSATION_HEADER]: conversation } });
|
|
19140
19143
|
}
|
|
19144
|
+
/**
|
|
19145
|
+
* Stores the turn and returns the memory context for it in one round trip (needs the `ingest` and `read` scopes):
|
|
19146
|
+
* the context is computed for the ingested conversation, from `query` or else the turn's last user message.
|
|
19147
|
+
*/
|
|
19148
|
+
contextWithTurn(user, turn, query) {
|
|
19149
|
+
return this.http.request("POST", "api/v1/context", { user, body: { ingest: turn, ...query ? { query } : {} } });
|
|
19150
|
+
}
|
|
19151
|
+
/** The conversation ended (session closed, /new): extraction runs now. A conversation Recordare never had is done. */
|
|
19152
|
+
async endConversation(user, conversation) {
|
|
19153
|
+
await this.gone(this.http.request("POST", `api/v1/ingest/conversations/${enc(conversation)}/end`, { user }));
|
|
19154
|
+
}
|
|
19141
19155
|
/** An edited message: Recordare re-extracts what depended on it. */
|
|
19142
19156
|
async editMessage(user, conversation, message, content) {
|
|
19143
19157
|
await this.http.request("PATCH", `api/v1/ingest/conversations/${enc(conversation)}/messages/${enc(message)}`, { user, body: { content } });
|
|
@@ -19150,6 +19164,32 @@ var RecordareClient = class {
|
|
|
19150
19164
|
async deleteConversation(user, conversation) {
|
|
19151
19165
|
await this.gone(this.http.request("DELETE", `api/v1/ingest/conversations/${enc(conversation)}`, { user }));
|
|
19152
19166
|
}
|
|
19167
|
+
// ── Learned sources (WORK_PLAN 8.9, D49): text the agent learns — the client turns files into text ─────────────
|
|
19168
|
+
/**
|
|
19169
|
+
* The agent learns a text. A big one is sent in parts (at paragraph boundaries, `partBytes` each); any size works.
|
|
19170
|
+
* Sending the same `externalId` again replaces the source; the same first part again is a duplicate.
|
|
19171
|
+
*/
|
|
19172
|
+
async learnSource(user, source, partBytes = SOURCE_PART_BYTES) {
|
|
19173
|
+
const [first = "", ...rest] = splitParts(source.text, partBytes);
|
|
19174
|
+
let result = await this.http.request("POST", "api/v1/ingest/sources", { user, body: { ...source, text: first, final: rest.length === 0 } });
|
|
19175
|
+
if (result.duplicate) return result;
|
|
19176
|
+
for (const [i, text] of rest.entries()) {
|
|
19177
|
+
result = await this.http.request(
|
|
19178
|
+
"POST",
|
|
19179
|
+
`api/v1/ingest/sources/${enc(source.externalId)}/parts`,
|
|
19180
|
+
{ user, body: { part: i + 1, text, final: i === rest.length - 1 } }
|
|
19181
|
+
);
|
|
19182
|
+
}
|
|
19183
|
+
return result;
|
|
19184
|
+
}
|
|
19185
|
+
/** The agent forgets a source (its text and passages; episodes keep a "forgotten source" marker). One it never had counts as done. */
|
|
19186
|
+
async forgetSource(user, externalId) {
|
|
19187
|
+
await this.http.request("DELETE", `api/v1/ingest/sources/${enc(externalId)}`, { user });
|
|
19188
|
+
}
|
|
19189
|
+
/** What the agent learned, newest first. */
|
|
19190
|
+
sources(user) {
|
|
19191
|
+
return this.http.request("GET", "api/v1/sources", { user });
|
|
19192
|
+
}
|
|
19153
19193
|
// ── The diary (API.md §4): what Recordare remembers, shown to the person in the platform's UI ──────────────────
|
|
19154
19194
|
/** The timeline, newest first; pass `nextCursor` back as `cursor` for the next page. */
|
|
19155
19195
|
episodes(user, query = {}) {
|
|
@@ -19202,6 +19242,319 @@ var RecordareClient = class {
|
|
|
19202
19242
|
}
|
|
19203
19243
|
}
|
|
19204
19244
|
};
|
|
19245
|
+
function splitParts(text, maxBytes) {
|
|
19246
|
+
const size = (t) => Buffer.byteLength(t, "utf8");
|
|
19247
|
+
if (size(text) <= maxBytes) return [text];
|
|
19248
|
+
const parts = [];
|
|
19249
|
+
let current = "";
|
|
19250
|
+
const push = (piece) => {
|
|
19251
|
+
const joined = current ? `${current}
|
|
19252
|
+
|
|
19253
|
+
${piece}` : piece;
|
|
19254
|
+
if (size(joined) <= maxBytes) {
|
|
19255
|
+
current = joined;
|
|
19256
|
+
return;
|
|
19257
|
+
}
|
|
19258
|
+
if (current) parts.push(current);
|
|
19259
|
+
current = piece;
|
|
19260
|
+
};
|
|
19261
|
+
for (const paragraph of text.split(/\n\s*\n/)) {
|
|
19262
|
+
let rest = paragraph;
|
|
19263
|
+
while (size(rest) > maxBytes) {
|
|
19264
|
+
let end = rest.length;
|
|
19265
|
+
while (end > 0 && size(rest.slice(0, end)) > maxBytes) end = Math.floor(end * 0.9);
|
|
19266
|
+
const space = rest.lastIndexOf(" ", end);
|
|
19267
|
+
let cut = space > end / 2 ? space : end;
|
|
19268
|
+
if (/[\uD800-\uDBFF]/.test(rest.charAt(cut - 1))) cut--;
|
|
19269
|
+
push(rest.slice(0, cut));
|
|
19270
|
+
rest = rest.slice(cut).trimStart();
|
|
19271
|
+
}
|
|
19272
|
+
if (rest) push(rest);
|
|
19273
|
+
}
|
|
19274
|
+
if (current) parts.push(current);
|
|
19275
|
+
return parts;
|
|
19276
|
+
}
|
|
19277
|
+
|
|
19278
|
+
// ../../packages/client/src/tools.ts
|
|
19279
|
+
var TOOLS = [
|
|
19280
|
+
{
|
|
19281
|
+
"name": "correct_episode",
|
|
19282
|
+
"title": "Correct a memory",
|
|
19283
|
+
"description": "Correct a remembered episode (wrong date or detail). The old version is kept as history, never shown as current.",
|
|
19284
|
+
"inputSchema": {
|
|
19285
|
+
"type": "object",
|
|
19286
|
+
"properties": {
|
|
19287
|
+
"id": {
|
|
19288
|
+
"type": "string",
|
|
19289
|
+
"format": "uuid",
|
|
19290
|
+
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
|
|
19291
|
+
},
|
|
19292
|
+
"content": {
|
|
19293
|
+
"type": "string"
|
|
19294
|
+
},
|
|
19295
|
+
"occurred_at": {
|
|
19296
|
+
"type": "string",
|
|
19297
|
+
"pattern": "^\\d{4}-\\d{2}(-\\d{2})?$"
|
|
19298
|
+
},
|
|
19299
|
+
"date_precision": {
|
|
19300
|
+
"type": "string",
|
|
19301
|
+
"enum": [
|
|
19302
|
+
"day",
|
|
19303
|
+
"month",
|
|
19304
|
+
"year",
|
|
19305
|
+
"approximate"
|
|
19306
|
+
]
|
|
19307
|
+
}
|
|
19308
|
+
},
|
|
19309
|
+
"required": [
|
|
19310
|
+
"id"
|
|
19311
|
+
],
|
|
19312
|
+
"$schema": "http://json-schema.org/draft-07/schema#"
|
|
19313
|
+
}
|
|
19314
|
+
},
|
|
19315
|
+
{
|
|
19316
|
+
"name": "forget_episode",
|
|
19317
|
+
"title": "Forget a memory",
|
|
19318
|
+
"description": "Forget an episode, when asked to. It is deleted with its corrections and never recreated.",
|
|
19319
|
+
"inputSchema": {
|
|
19320
|
+
"type": "object",
|
|
19321
|
+
"properties": {
|
|
19322
|
+
"id": {
|
|
19323
|
+
"type": "string",
|
|
19324
|
+
"format": "uuid",
|
|
19325
|
+
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
|
|
19326
|
+
}
|
|
19327
|
+
},
|
|
19328
|
+
"required": [
|
|
19329
|
+
"id"
|
|
19330
|
+
],
|
|
19331
|
+
"$schema": "http://json-schema.org/draft-07/schema#"
|
|
19332
|
+
}
|
|
19333
|
+
},
|
|
19334
|
+
{
|
|
19335
|
+
"name": "learn_source",
|
|
19336
|
+
"title": "Learn a text",
|
|
19337
|
+
"description": "Learn a text as knowledge (a manual, a page, a note \u2014 as plain text; send it again with the same title to replace it). It stays searchable with search_knowledge; the learning becomes a memory of this conversation.",
|
|
19338
|
+
"inputSchema": {
|
|
19339
|
+
"type": "object",
|
|
19340
|
+
"properties": {
|
|
19341
|
+
"title": {
|
|
19342
|
+
"type": "string"
|
|
19343
|
+
},
|
|
19344
|
+
"text": {
|
|
19345
|
+
"type": "string"
|
|
19346
|
+
},
|
|
19347
|
+
"author": {
|
|
19348
|
+
"type": "string"
|
|
19349
|
+
},
|
|
19350
|
+
"kind": {
|
|
19351
|
+
"type": "string",
|
|
19352
|
+
"enum": [
|
|
19353
|
+
"document",
|
|
19354
|
+
"page",
|
|
19355
|
+
"note",
|
|
19356
|
+
"book",
|
|
19357
|
+
"own_text"
|
|
19358
|
+
]
|
|
19359
|
+
},
|
|
19360
|
+
"uri": {
|
|
19361
|
+
"type": "string"
|
|
19362
|
+
}
|
|
19363
|
+
},
|
|
19364
|
+
"required": [
|
|
19365
|
+
"title",
|
|
19366
|
+
"text"
|
|
19367
|
+
],
|
|
19368
|
+
"$schema": "http://json-schema.org/draft-07/schema#"
|
|
19369
|
+
}
|
|
19370
|
+
},
|
|
19371
|
+
{
|
|
19372
|
+
"name": "log_episode",
|
|
19373
|
+
"title": "Note something that happened or is planned",
|
|
19374
|
+
"description": 'Explicit capture ("note that today I serviced the car"). Resolve the date yourself (ISO).',
|
|
19375
|
+
"inputSchema": {
|
|
19376
|
+
"type": "object",
|
|
19377
|
+
"properties": {
|
|
19378
|
+
"content": {
|
|
19379
|
+
"type": "string"
|
|
19380
|
+
},
|
|
19381
|
+
"kind": {
|
|
19382
|
+
"type": "string",
|
|
19383
|
+
"enum": [
|
|
19384
|
+
"event",
|
|
19385
|
+
"plan"
|
|
19386
|
+
]
|
|
19387
|
+
},
|
|
19388
|
+
"occurred_at": {
|
|
19389
|
+
"type": "string",
|
|
19390
|
+
"pattern": "^\\d{4}-\\d{2}(-\\d{2})?$"
|
|
19391
|
+
},
|
|
19392
|
+
"occurred_until": {
|
|
19393
|
+
"type": "string",
|
|
19394
|
+
"pattern": "^\\d{4}-\\d{2}(-\\d{2})?$"
|
|
19395
|
+
},
|
|
19396
|
+
"date_precision": {
|
|
19397
|
+
"type": "string",
|
|
19398
|
+
"enum": [
|
|
19399
|
+
"day",
|
|
19400
|
+
"month",
|
|
19401
|
+
"year",
|
|
19402
|
+
"approximate"
|
|
19403
|
+
]
|
|
19404
|
+
},
|
|
19405
|
+
"people": {
|
|
19406
|
+
"type": "array",
|
|
19407
|
+
"items": {
|
|
19408
|
+
"type": "string"
|
|
19409
|
+
}
|
|
19410
|
+
},
|
|
19411
|
+
"place": {
|
|
19412
|
+
"type": "string"
|
|
19413
|
+
}
|
|
19414
|
+
},
|
|
19415
|
+
"required": [
|
|
19416
|
+
"content"
|
|
19417
|
+
],
|
|
19418
|
+
"$schema": "http://json-schema.org/draft-07/schema#"
|
|
19419
|
+
}
|
|
19420
|
+
},
|
|
19421
|
+
{
|
|
19422
|
+
"name": "remember",
|
|
19423
|
+
"title": "Remember something",
|
|
19424
|
+
"description": 'Explicit "remember that\u2026" about preferences, habits, values, knowledge.',
|
|
19425
|
+
"inputSchema": {
|
|
19426
|
+
"type": "object",
|
|
19427
|
+
"properties": {
|
|
19428
|
+
"content": {
|
|
19429
|
+
"type": "string"
|
|
19430
|
+
},
|
|
19431
|
+
"category": {
|
|
19432
|
+
"type": "string",
|
|
19433
|
+
"enum": [
|
|
19434
|
+
"preference",
|
|
19435
|
+
"habit",
|
|
19436
|
+
"value",
|
|
19437
|
+
"relationship",
|
|
19438
|
+
"knowledge",
|
|
19439
|
+
"profile",
|
|
19440
|
+
"constraint"
|
|
19441
|
+
]
|
|
19442
|
+
}
|
|
19443
|
+
},
|
|
19444
|
+
"required": [
|
|
19445
|
+
"content"
|
|
19446
|
+
],
|
|
19447
|
+
"$schema": "http://json-schema.org/draft-07/schema#"
|
|
19448
|
+
}
|
|
19449
|
+
},
|
|
19450
|
+
{
|
|
19451
|
+
"name": "resolve_period",
|
|
19452
|
+
"title": "Turn a period expression into dates",
|
|
19453
|
+
"description": 'Deterministic: "questa settimana", "la settimana scorsa", "a febbraio", "lo scorso dicembre", "last week"\u2026 \u2192 {from, to} (ISO, inclusive).',
|
|
19454
|
+
"inputSchema": {
|
|
19455
|
+
"type": "object",
|
|
19456
|
+
"properties": {
|
|
19457
|
+
"expression": {
|
|
19458
|
+
"type": "string"
|
|
19459
|
+
}
|
|
19460
|
+
},
|
|
19461
|
+
"required": [
|
|
19462
|
+
"expression"
|
|
19463
|
+
],
|
|
19464
|
+
"$schema": "http://json-schema.org/draft-07/schema#"
|
|
19465
|
+
}
|
|
19466
|
+
},
|
|
19467
|
+
{
|
|
19468
|
+
"name": "search_episodes",
|
|
19469
|
+
"title": "Search what happened",
|
|
19470
|
+
"description": 'Search your memory of what happened: what you lived, did, planned or learned, and what happened to the people you know (events, plans, changes), with dates and status. Each item has a subject: you (written in the first person), a person by name, someone, or undecided. Use `from`/`to` (ISO dates, inclusive; see resolve_period) for questions about a period. mode: "search" = most relevant, "list" = chronological in the period (overviews, counting), "latest" = most recent first ("when did I last\u2026").',
|
|
19471
|
+
"inputSchema": {
|
|
19472
|
+
"type": "object",
|
|
19473
|
+
"properties": {
|
|
19474
|
+
"query": {
|
|
19475
|
+
"description": "What to look for \u2014 pass the question also when listing a period: it ranks the items and finds the matching chat excerpts",
|
|
19476
|
+
"type": "string"
|
|
19477
|
+
},
|
|
19478
|
+
"from": {
|
|
19479
|
+
"description": "Start date, ISO (YYYY-MM-DD or YYYY-MM)",
|
|
19480
|
+
"type": "string",
|
|
19481
|
+
"pattern": "^\\d{4}-\\d{2}(-\\d{2})?$"
|
|
19482
|
+
},
|
|
19483
|
+
"to": {
|
|
19484
|
+
"description": "End date, ISO (YYYY-MM-DD or YYYY-MM), inclusive",
|
|
19485
|
+
"type": "string",
|
|
19486
|
+
"pattern": "^\\d{4}-\\d{2}(-\\d{2})?$"
|
|
19487
|
+
},
|
|
19488
|
+
"mode": {
|
|
19489
|
+
"type": "string",
|
|
19490
|
+
"enum": [
|
|
19491
|
+
"search",
|
|
19492
|
+
"list",
|
|
19493
|
+
"latest"
|
|
19494
|
+
]
|
|
19495
|
+
},
|
|
19496
|
+
"include_plans": {
|
|
19497
|
+
"type": "boolean"
|
|
19498
|
+
},
|
|
19499
|
+
"limit": {
|
|
19500
|
+
"type": "integer",
|
|
19501
|
+
"minimum": 1,
|
|
19502
|
+
"maximum": 50
|
|
19503
|
+
}
|
|
19504
|
+
},
|
|
19505
|
+
"$schema": "http://json-schema.org/draft-07/schema#"
|
|
19506
|
+
}
|
|
19507
|
+
},
|
|
19508
|
+
{
|
|
19509
|
+
"name": "search_knowledge",
|
|
19510
|
+
"title": "Search what you learned",
|
|
19511
|
+
"description": "Search the sources you learned (manuals, documents, pages, notes you were given or wrote): passages of their text, each with its source (title, author, who gave it, when) and the episodes that refer to it. For what happened, use search_episodes.",
|
|
19512
|
+
"inputSchema": {
|
|
19513
|
+
"type": "object",
|
|
19514
|
+
"properties": {
|
|
19515
|
+
"query": {
|
|
19516
|
+
"type": "string",
|
|
19517
|
+
"description": "What to look up"
|
|
19518
|
+
},
|
|
19519
|
+
"limit": {
|
|
19520
|
+
"type": "integer",
|
|
19521
|
+
"minimum": 1,
|
|
19522
|
+
"maximum": 20
|
|
19523
|
+
}
|
|
19524
|
+
},
|
|
19525
|
+
"required": [
|
|
19526
|
+
"query"
|
|
19527
|
+
],
|
|
19528
|
+
"$schema": "http://json-schema.org/draft-07/schema#"
|
|
19529
|
+
}
|
|
19530
|
+
},
|
|
19531
|
+
{
|
|
19532
|
+
"name": "search_memory",
|
|
19533
|
+
"title": "Search what you know about yourself and others",
|
|
19534
|
+
"description": 'Search your memory of preferences, habits, values, relationships, knowledge and current state (car, home, job\u2026) \u2014 yours and of the people you know; each item has its subject. Use `as_of` (ISO date) for "what was it on that date" questions; each fact comes with its history.',
|
|
19535
|
+
"inputSchema": {
|
|
19536
|
+
"type": "object",
|
|
19537
|
+
"properties": {
|
|
19538
|
+
"query": {
|
|
19539
|
+
"type": "string",
|
|
19540
|
+
"description": "Topic"
|
|
19541
|
+
},
|
|
19542
|
+
"as_of": {
|
|
19543
|
+
"description": "ISO date (YYYY-MM-DD); default today",
|
|
19544
|
+
"type": "string",
|
|
19545
|
+
"pattern": "^\\d{4}-\\d{2}(-\\d{2})?$"
|
|
19546
|
+
},
|
|
19547
|
+
"include_pending": {
|
|
19548
|
+
"type": "boolean"
|
|
19549
|
+
}
|
|
19550
|
+
},
|
|
19551
|
+
"required": [
|
|
19552
|
+
"query"
|
|
19553
|
+
],
|
|
19554
|
+
"$schema": "http://json-schema.org/draft-07/schema#"
|
|
19555
|
+
}
|
|
19556
|
+
}
|
|
19557
|
+
];
|
|
19205
19558
|
|
|
19206
19559
|
// ../../packages/client/src/delivery.ts
|
|
19207
19560
|
var DEFAULT_DELIVERY = { maxAttempts: 12, baseDelayMs: 5e3, maxDelayMs: 60 * 60 * 1e3 };
|
|
@@ -19218,6 +19571,7 @@ function afterFailure(err, attempts, policy = DEFAULT_DELIVERY, random2 = Math.r
|
|
|
19218
19571
|
|
|
19219
19572
|
// src/identity.ts
|
|
19220
19573
|
function resolveUser(cfg, channel, senderId) {
|
|
19574
|
+
if (cfg.memoryPer === "agent") return cfg.defaultUser;
|
|
19221
19575
|
if (senderId) {
|
|
19222
19576
|
const mapped = channel ? cfg.users[`${channel}:${senderId}`] : void 0;
|
|
19223
19577
|
if (mapped) return mapped;
|
|
@@ -19225,6 +19579,22 @@ function resolveUser(cfg, channel, senderId) {
|
|
|
19225
19579
|
}
|
|
19226
19580
|
return cfg.defaultUser;
|
|
19227
19581
|
}
|
|
19582
|
+
var senderRef = (channel, senderId) => `${channel ?? "openclaw"}:${senderId}`;
|
|
19583
|
+
function senderParticipant(channel, senderId, displayName) {
|
|
19584
|
+
return {
|
|
19585
|
+
ref: senderRef(channel, senderId),
|
|
19586
|
+
role: "other",
|
|
19587
|
+
identity: { channel: channel ?? "openclaw", externalId: senderId },
|
|
19588
|
+
...displayName ? { displayName } : {}
|
|
19589
|
+
};
|
|
19590
|
+
}
|
|
19591
|
+
function resolveSpeaker(cfg, channel, senderId, displayName) {
|
|
19592
|
+
if (cfg.memoryPer === "user" || !senderId || cfg.selfSenders.includes(senderRef(channel, senderId))) {
|
|
19593
|
+
return { ref: "holder", role: "user" };
|
|
19594
|
+
}
|
|
19595
|
+
const participant = senderParticipant(channel, senderId, displayName);
|
|
19596
|
+
return { ref: participant.ref, role: "other", participant };
|
|
19597
|
+
}
|
|
19228
19598
|
function conversationId(sessionKey, sessionId) {
|
|
19229
19599
|
if (!sessionKey && !sessionId) return void 0;
|
|
19230
19600
|
return `openclaw:${sessionKey ?? "session"}${sessionId ? `/${sessionId}` : ""}`;
|
|
@@ -19237,62 +19607,19 @@ function isSystemRun(ctx) {
|
|
|
19237
19607
|
}
|
|
19238
19608
|
|
|
19239
19609
|
// src/tools.ts
|
|
19240
|
-
var
|
|
19241
|
-
var
|
|
19242
|
-
|
|
19243
|
-
|
|
19244
|
-
|
|
19245
|
-
|
|
19246
|
-
|
|
19247
|
-
|
|
19248
|
-
|
|
19249
|
-
|
|
19250
|
-
|
|
19251
|
-
|
|
19252
|
-
|
|
19253
|
-
mode: { type: "string", enum: ["search", "list", "latest"] },
|
|
19254
|
-
include_plans: { type: "boolean" },
|
|
19255
|
-
limit: { type: "integer", minimum: 1, maximum: 50 }
|
|
19256
|
-
})
|
|
19257
|
-
},
|
|
19258
|
-
{
|
|
19259
|
-
mcpName: "search_memory",
|
|
19260
|
-
label: "Recordare: search who the user is",
|
|
19261
|
-
description: 'Search the user\'s preferences, habits, values, relationships, knowledge and current state (car, home, job\u2026) in their long-term memory. Use `as_of` (ISO date) for "what was it on that date" questions; each fact comes with its history.',
|
|
19262
|
-
parameters: obj({
|
|
19263
|
-
query: { type: "string", description: "Topic" },
|
|
19264
|
-
as_of: { ...isoDay, description: "ISO date (YYYY-MM-DD); default today" },
|
|
19265
|
-
include_pending: { type: "boolean" }
|
|
19266
|
-
}, ["query"])
|
|
19267
|
-
},
|
|
19268
|
-
{
|
|
19269
|
-
mcpName: "resolve_period",
|
|
19270
|
-
label: "Recordare: period to dates",
|
|
19271
|
-
description: 'Deterministic: "this week", "last week", "in February", "last December", "la settimana scorsa"\u2026 \u2192 {from, to} (ISO, inclusive).',
|
|
19272
|
-
parameters: obj({ expression: { type: "string" } }, ["expression"])
|
|
19273
|
-
},
|
|
19274
|
-
{
|
|
19275
|
-
mcpName: "remember",
|
|
19276
|
-
label: "Recordare: remember",
|
|
19277
|
-
description: `Explicit "remember that\u2026" about the user's preferences, habits, values, knowledge (long-term memory).`,
|
|
19278
|
-
parameters: obj({
|
|
19279
|
-
content: { type: "string" },
|
|
19280
|
-
category: { type: "string", enum: ["preference", "habit", "value", "relationship", "knowledge", "profile", "constraint"] }
|
|
19281
|
-
}, ["content"])
|
|
19282
|
-
},
|
|
19283
|
-
{
|
|
19284
|
-
mcpName: "correct_episode",
|
|
19285
|
-
label: "Recordare: correct a memory",
|
|
19286
|
-
description: "The user corrects a remembered episode (wrong date or detail). The old version is kept as history, never shown as current.",
|
|
19287
|
-
parameters: obj({ id: uuid2, content: { type: "string" }, occurred_at: isoDay, date_precision: precision }, ["id"])
|
|
19288
|
-
},
|
|
19289
|
-
{
|
|
19290
|
-
mcpName: "forget_episode",
|
|
19291
|
-
label: "Recordare: forget a memory",
|
|
19292
|
-
description: "The user asks to forget an episode. It is deleted with its corrections and never recreated.",
|
|
19293
|
-
parameters: obj({ id: uuid2 }, ["id"])
|
|
19294
|
-
}
|
|
19295
|
-
];
|
|
19610
|
+
var OFFERED = TOOLS.filter((t) => t.name !== "log_episode");
|
|
19611
|
+
var NAMES = new RegExp(`\\b(${OFFERED.map((t) => t.name).join("|")})\\b`, "g");
|
|
19612
|
+
function parameters(schema) {
|
|
19613
|
+
const { $schema: _ignored, ...rest } = structuredClone(schema);
|
|
19614
|
+
return rest;
|
|
19615
|
+
}
|
|
19616
|
+
var TOOLS2 = OFFERED.map((t) => ({
|
|
19617
|
+
mcpName: t.name,
|
|
19618
|
+
label: `Recordare: ${t.title.charAt(0).toLowerCase()}${t.title.slice(1)}`,
|
|
19619
|
+
// Tool names the description mentions are the plugin's (`recordare_…`); the memory is the agent's long-term one (D50).
|
|
19620
|
+
description: `${t.description.replace(NAMES, "recordare_$1")} (Recordare: your long-term memory.)`,
|
|
19621
|
+
parameters: parameters(t.inputSchema)
|
|
19622
|
+
}));
|
|
19296
19623
|
var toolName = (spec) => `recordare_${spec.mcpName}`;
|
|
19297
19624
|
|
|
19298
19625
|
// src/transcript.ts
|
|
@@ -19333,14 +19660,16 @@ function lastTurn(messages) {
|
|
|
19333
19660
|
}
|
|
19334
19661
|
|
|
19335
19662
|
// src/plugin.ts
|
|
19336
|
-
var VERSION = "0.
|
|
19663
|
+
var VERSION = "0.2.0";
|
|
19337
19664
|
var TOOL_TIMEOUT_MS = 2e4;
|
|
19338
19665
|
var RETRY = { maxAttempts: 8, baseDelayMs: 2e3, maxDelayMs: 5 * 6e4 };
|
|
19339
19666
|
var MAX_QUEUE = 500;
|
|
19340
19667
|
var MAX_TRACKED = 500;
|
|
19341
19668
|
var MAX_GROUP_BUFFER = 50;
|
|
19669
|
+
var MAX_NAMES = 1e3;
|
|
19342
19670
|
var hash = (s) => createHash("sha256").update(s).digest("hex").slice(0, 16);
|
|
19343
19671
|
var errName = (err) => err instanceof Error ? err.message : "error";
|
|
19672
|
+
var str2 = (v) => typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
19344
19673
|
function remember(map, key, value, max = MAX_TRACKED) {
|
|
19345
19674
|
map.delete(key);
|
|
19346
19675
|
map.set(key, value);
|
|
@@ -19362,12 +19691,19 @@ function registerRecordare(api, cfg, kinds) {
|
|
|
19362
19691
|
const slow = new RecordareClient({ baseUrl: cfg.url, apiKey: cfg.apiKey, mcp: { clientInfo, maxSessions: 50 } });
|
|
19363
19692
|
const headerUser = (user) => cfg.personal ? "" : user;
|
|
19364
19693
|
const turns = /* @__PURE__ */ new Map();
|
|
19365
|
-
const
|
|
19694
|
+
const captured = /* @__PURE__ */ new Map();
|
|
19366
19695
|
const groupBuffer = /* @__PURE__ */ new Map();
|
|
19367
19696
|
const groupParticipants = /* @__PURE__ */ new Map();
|
|
19697
|
+
const names = /* @__PURE__ */ new Map();
|
|
19368
19698
|
const queue = [];
|
|
19369
19699
|
let timer;
|
|
19370
19700
|
let stopped = false;
|
|
19701
|
+
if (cfg.memoryPer === "agent" && !cfg.defaultUser) {
|
|
19702
|
+
log.warn("recordare: set defaultUser (the agent's Recordare account) or use a personal token; memory is off");
|
|
19703
|
+
}
|
|
19704
|
+
if (cfg.memoryPer === "agent" && Object.keys(cfg.users).length) {
|
|
19705
|
+
log.warn('recordare: `users` is used only with memoryPer "user"; every sender is a participant of the agent\'s memory');
|
|
19706
|
+
}
|
|
19371
19707
|
async function deliver(p) {
|
|
19372
19708
|
try {
|
|
19373
19709
|
const res = await slow.ingest(headerUser(p.user), p.req);
|
|
@@ -19413,14 +19749,18 @@ function registerRecordare(api, cfg, kinds) {
|
|
|
19413
19749
|
const user = resolveUser(cfg, channel, ctx.senderId);
|
|
19414
19750
|
const conversation = conversationId(key, ctx.sessionId);
|
|
19415
19751
|
if (!user || !conversation) return null;
|
|
19416
|
-
|
|
19752
|
+
const name = ctx.senderId ? names.get(senderRef(channel, ctx.senderId)) : void 0;
|
|
19753
|
+
return { user, conversation, channel, speaker: resolveSpeaker(cfg, channel, ctx.senderId, name) };
|
|
19417
19754
|
}
|
|
19418
19755
|
function conversationMeta(w, ctx) {
|
|
19419
19756
|
const participants = [
|
|
19420
|
-
{ ref: "
|
|
19757
|
+
{ ref: "holder", role: "holder" },
|
|
19421
19758
|
{ ref: "assistant", role: "assistant", displayName: ctx.agentId ?? "assistant" },
|
|
19422
|
-
...
|
|
19759
|
+
...w.speaker.participant ? [w.speaker.participant] : []
|
|
19423
19760
|
];
|
|
19761
|
+
for (const p of ctx.sessionKey ? groupParticipants.get(ctx.sessionKey) ?? [] : []) {
|
|
19762
|
+
if (!participants.some((q) => q.ref === p.ref)) participants.push(p);
|
|
19763
|
+
}
|
|
19424
19764
|
return {
|
|
19425
19765
|
externalId: w.conversation,
|
|
19426
19766
|
source: "chat",
|
|
@@ -19445,20 +19785,26 @@ function registerRecordare(api, cfg, kinds) {
|
|
|
19445
19785
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
19446
19786
|
const id = event.currentUserMessageId ?? ctx.runId ?? hash(`${w.conversation}\0${text}\0${now}`);
|
|
19447
19787
|
const conversation = conversationMeta(w, ctx);
|
|
19448
|
-
const message = { externalId: `${id}:u`, role:
|
|
19788
|
+
const message = { externalId: `${id}:u`, role: w.speaker.role, authorRef: w.speaker.ref, content: clipUtf8(text), sentAt: now };
|
|
19449
19789
|
remember(turns, ctx.runId ?? w.conversation, { user: w.user, conversation, message });
|
|
19450
|
-
if (cfg.capture) {
|
|
19451
|
-
const
|
|
19452
|
-
|
|
19453
|
-
|
|
19454
|
-
|
|
19455
|
-
|
|
19456
|
-
|
|
19790
|
+
if (!cfg.capture) {
|
|
19791
|
+
const ctxRes = await fast.context(headerUser(w.user), w.conversation, text.slice(0, 4e3));
|
|
19792
|
+
return ctxRes.block ? { prependContext: ctxRes.block } : void 0;
|
|
19793
|
+
}
|
|
19794
|
+
const turn = { conversation, messages: [...takeGroupMessages(ctx.sessionKey, text), message] };
|
|
19795
|
+
remember(captured, w.conversation, w.user);
|
|
19796
|
+
try {
|
|
19797
|
+
if (!cfg.autoRecall) {
|
|
19798
|
+
await fast.ingest(headerUser(w.user), turn);
|
|
19799
|
+
return void 0;
|
|
19457
19800
|
}
|
|
19801
|
+
const ctxRes = await fast.contextWithTurn(headerUser(w.user), turn, text.slice(0, 4e3));
|
|
19802
|
+
return ctxRes.block ? { prependContext: ctxRes.block } : void 0;
|
|
19803
|
+
} catch (err) {
|
|
19804
|
+
log.warn(`recordare: storing the message before the turn failed (${errName(err)}), will retry; no memory context this turn`);
|
|
19805
|
+
void send(w.user, turn);
|
|
19806
|
+
return void 0;
|
|
19458
19807
|
}
|
|
19459
|
-
if (!cfg.autoRecall) return;
|
|
19460
|
-
const ctxRes = await fast.context(headerUser(w.user), w.conversation, text.slice(0, 4e3));
|
|
19461
|
-
return ctxRes.block ? { prependContext: ctxRes.block } : void 0;
|
|
19462
19808
|
} catch (err) {
|
|
19463
19809
|
log.warn(`recordare: memory context unavailable (${errName(err)})`);
|
|
19464
19810
|
return void 0;
|
|
@@ -19476,10 +19822,10 @@ function registerRecordare(api, cfg, kinds) {
|
|
|
19476
19822
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
19477
19823
|
const runId = event.runId ?? ctx.runId ?? hash(`${w.conversation}\0${turn.assistant}`);
|
|
19478
19824
|
const conversation = conversationMeta(w, ctx);
|
|
19479
|
-
const userMessage = stashed?.message ?? (turn.user ? { externalId: `${runId}:u`, role:
|
|
19825
|
+
const userMessage = stashed?.message ?? (turn.user ? { externalId: `${runId}:u`, role: w.speaker.role, authorRef: w.speaker.ref, content: clipUtf8(turn.user), sentAt: now } : void 0);
|
|
19480
19826
|
const answer = { externalId: `${runId}:a`, role: "assistant", authorRef: "assistant", content: clipUtf8(turn.assistant), sentAt: now };
|
|
19481
19827
|
const messages = [...userMessage ? [userMessage] : [], answer];
|
|
19482
|
-
remember(
|
|
19828
|
+
remember(captured, w.conversation, w.user);
|
|
19483
19829
|
await send(w.user, { conversation, messages });
|
|
19484
19830
|
} catch (err) {
|
|
19485
19831
|
log.warn(`recordare: capture failed (${errName(err)})`);
|
|
@@ -19489,10 +19835,10 @@ function registerRecordare(api, cfg, kinds) {
|
|
|
19489
19835
|
try {
|
|
19490
19836
|
if (!cfg.capture || ["compaction", "shutdown", "restart"].includes(event.reason ?? "")) return;
|
|
19491
19837
|
const conv = conversationId(event.sessionKey ?? ctx.sessionKey, event.sessionId ?? ctx.sessionId);
|
|
19492
|
-
const
|
|
19493
|
-
if (!conv ||
|
|
19494
|
-
|
|
19495
|
-
await
|
|
19838
|
+
const user = conv ? captured.get(conv) : void 0;
|
|
19839
|
+
if (!conv || user === void 0) return;
|
|
19840
|
+
captured.delete(conv);
|
|
19841
|
+
await slow.endConversation(headerUser(user), conv);
|
|
19496
19842
|
} catch (err) {
|
|
19497
19843
|
log.warn(`recordare: end of conversation not sent (${errName(err)})`);
|
|
19498
19844
|
}
|
|
@@ -19501,18 +19847,22 @@ function registerRecordare(api, cfg, kinds) {
|
|
|
19501
19847
|
try {
|
|
19502
19848
|
const key = event.sessionKey ?? ctx.sessionKey;
|
|
19503
19849
|
const senderId = event.senderId ?? ctx.senderId;
|
|
19504
|
-
if (!
|
|
19505
|
-
const ref =
|
|
19850
|
+
if (!senderId) return;
|
|
19851
|
+
const ref = senderRef(ctx.channelId, senderId);
|
|
19852
|
+
const name = str2(event.metadata?.senderName) ?? str2(event.metadata?.senderUsername);
|
|
19853
|
+
if (name) remember(names, ref, name, MAX_NAMES);
|
|
19854
|
+
if (!cfg.capture || !cfg.groups || !isGroupSession(key) || !event.content?.trim()) return;
|
|
19855
|
+
const speaker = cfg.memoryPer === "agent" ? resolveSpeaker(cfg, ctx.channelId, senderId, name) : { ref, role: "other", participant: senderParticipant(ctx.channelId, senderId, name) };
|
|
19506
19856
|
const members2 = groupParticipants.get(key) ?? [];
|
|
19507
|
-
if (!members2.some((p) => p.ref === ref)) {
|
|
19508
|
-
remember(groupParticipants, key, [...members2,
|
|
19857
|
+
if (speaker.participant && !members2.some((p) => p.ref === speaker.ref)) {
|
|
19858
|
+
remember(groupParticipants, key, [...members2, speaker.participant]);
|
|
19509
19859
|
}
|
|
19510
19860
|
const at = event.timestamp ? new Date(event.timestamp) : /* @__PURE__ */ new Date();
|
|
19511
19861
|
const buffered = groupBuffer.get(key) ?? [];
|
|
19512
19862
|
buffered.push({
|
|
19513
19863
|
externalId: `msg:${event.messageId ?? ctx.messageId ?? hash(`${ref}\0${event.content}\0${at.toISOString()}`)}`,
|
|
19514
|
-
role:
|
|
19515
|
-
authorRef: ref,
|
|
19864
|
+
role: speaker.role,
|
|
19865
|
+
authorRef: speaker.ref,
|
|
19516
19866
|
content: clipUtf8(event.content),
|
|
19517
19867
|
sentAt: at.toISOString()
|
|
19518
19868
|
});
|
|
@@ -19522,7 +19872,7 @@ function registerRecordare(api, cfg, kinds) {
|
|
|
19522
19872
|
}
|
|
19523
19873
|
});
|
|
19524
19874
|
if (cfg.tools) {
|
|
19525
|
-
for (const spec of
|
|
19875
|
+
for (const spec of TOOLS2) {
|
|
19526
19876
|
const name = toolName(spec);
|
|
19527
19877
|
api.registerTool((ctx) => {
|
|
19528
19878
|
if (kinds.isIncognito(ctx.sessionKey)) return null;
|