@remnic/plugin-openclaw 9.3.563 → 9.3.564
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 +27 -11
- package/dist/index.js +624 -41
- package/openclaw.plugin.json +69 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ The package metadata keeps the installer compatibility floor at the single
|
|
|
49
49
|
`>=2026.4.1` shape OpenClaw setup expects because that older floor is still
|
|
50
50
|
more permissive than the active 60-day requirement. The peer and plugin-API
|
|
51
51
|
compatibility ranges explicitly include reviewed prerelease hosts in that
|
|
52
|
-
window. The adapter separately records `2026.6.2-alpha.
|
|
52
|
+
window. The adapter separately records `2026.6.2-alpha.2` as the latest
|
|
53
53
|
reviewed OpenClaw source-tag target.
|
|
54
54
|
|
|
55
55
|
When adding newer OpenClaw manifest surfaces, keep older-compatible metadata in
|
|
@@ -192,11 +192,11 @@ for the Remnic adapter surfaces. The May 31 sweep checked source tags
|
|
|
192
192
|
#1203 through #1245, excluding unrelated issue #1211. The June 2 sweep reviewed
|
|
193
193
|
Remnic issues #1258, #1259, #1266, and #1271 against OpenClaw tags
|
|
194
194
|
`v2026.5.31-beta.4`, `v2026.6.1-alpha.1`, `v2026.6.1-alpha.2`,
|
|
195
|
-
`v2026.6.1-alpha.3`, `v2026.6.1-beta.1`, `v2026.6.1-beta.2`,
|
|
196
|
-
`v2026.6.2-alpha.1`. The existing SDK snapshot still
|
|
197
|
-
22 hooks, 2 manifest contracts`) for each tag.
|
|
198
|
-
|
|
199
|
-
published npm
|
|
195
|
+
`v2026.6.1-alpha.3`, `v2026.6.1-beta.1`, `v2026.6.1-beta.2`,
|
|
196
|
+
`v2026.6.2-alpha.1`, and `v2026.6.2-alpha.2`. The existing SDK snapshot still
|
|
197
|
+
matched (`14 registrars, 22 hooks, 2 manifest contracts`) for each tag.
|
|
198
|
+
`v2026.6.2-alpha.1` and `v2026.6.2-alpha.2` exist as upstream source tags, but
|
|
199
|
+
as of June 2, 2026 they are not GitHub release pages or published npm packages.
|
|
200
200
|
|
|
201
201
|
OpenClaw 2026.5.16 package-entry discovery prefers explicit built runtime
|
|
202
202
|
entries for installed packages. The published Remnic adapter declares
|
|
@@ -236,15 +236,31 @@ because the adapter owns mixed memory-slot hooks, lifecycle handlers, slash
|
|
|
236
236
|
command metadata, public artifacts, and runtime tools rather than only static
|
|
237
237
|
tools.
|
|
238
238
|
|
|
239
|
-
OpenClaw 2026.5.20-beta.2 through the reviewed `2026.6.2-alpha.
|
|
239
|
+
OpenClaw 2026.5.20-beta.2 through the reviewed `2026.6.2-alpha.2` source tag
|
|
240
240
|
keep the Remnic-required plugin install, ClawHub fallback, manifest contract,
|
|
241
241
|
hook, memory-slot, gateway LLM, and plugin security-scan surfaces compatible.
|
|
242
242
|
OpenClaw 2026.5.31-beta.4 added optional `plugin-sdk/chat-channel-ids` and
|
|
243
243
|
`plugin-sdk/memory-core-host-embedding-registry` subpaths, and
|
|
244
|
-
`2026.6.2-alpha.1`
|
|
245
|
-
`before_dispatch` hook contexts. Remnic
|
|
246
|
-
surfaces
|
|
247
|
-
|
|
244
|
+
`2026.6.2-alpha.1`/`2026.6.2-alpha.2` add quoted-reply metadata fields to
|
|
245
|
+
inbound and `before_dispatch` hook contexts. Remnic consumes those optional
|
|
246
|
+
surfaces only through compatibility gates:
|
|
247
|
+
|
|
248
|
+
- `hostEmbeddingProviderEnabled` (default `true`) lets Remnic prefer
|
|
249
|
+
OpenClaw memory/generic embedding providers for semantic fallback and
|
|
250
|
+
embedded vector backends when the host SDK exposes them. Provider creation
|
|
251
|
+
failures fall back to Remnic's existing embedding path.
|
|
252
|
+
- `openclawMessageReceivedCaptureEnabled` (default `true`) captures inbound
|
|
253
|
+
`message_received` content into transcripts when the host emits that hook.
|
|
254
|
+
- `openclawReplyMetadataCaptureEnabled` (default `true`) stores bounded
|
|
255
|
+
`messageId`, `threadId`, `replyToId`, `replyToBody`, and `replyToSender`
|
|
256
|
+
transcript metadata.
|
|
257
|
+
- `openclawReplyMetadataExtractionHintsEnabled` (default `false`) prepends
|
|
258
|
+
bounded quoted-reply context to user turns before extraction.
|
|
259
|
+
- `openclawChannelEnvelopeCleaningEnabled` (default `true`) uses OpenClaw's
|
|
260
|
+
canonical channel envelope prefixes when the SDK subpath exists, with the
|
|
261
|
+
legacy OpenClaw-only cleaner preserved for older hosts.
|
|
262
|
+
|
|
263
|
+
The package metadata now records `2026.6.2-alpha.2` as the reviewed OpenClaw
|
|
248
264
|
source-tag target and keeps the stable `>=2026.4.1` installer floor plus
|
|
249
265
|
reviewed prerelease peer/plugin-API hosts eligible.
|
|
250
266
|
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ import * as day_summary_star from "@remnic/core/day-summary";
|
|
|
24
24
|
// ../../src/index.ts
|
|
25
25
|
import OpenAI from "openai";
|
|
26
26
|
import { createRequire } from "module";
|
|
27
|
+
import { createHash as createHash2 } from "crypto";
|
|
27
28
|
|
|
28
29
|
// ../../src/config.ts
|
|
29
30
|
var config_exports = {};
|
|
@@ -2943,13 +2944,23 @@ import { readEnvVar, resolveHomeDir } from "@remnic/core/runtime/env";
|
|
|
2943
2944
|
import { migrateFromEngram, rollbackFromEngramMigration } from "@remnic/core/migrate/from-engram";
|
|
2944
2945
|
|
|
2945
2946
|
// ../../src/user-message-cleaning.ts
|
|
2946
|
-
|
|
2947
|
+
var DEFAULT_CHANNEL_ENVELOPE_PREFIXES = ["OpenClaw"];
|
|
2948
|
+
function createOpenClawUserMessageCleaner(prefixes, options = {}) {
|
|
2949
|
+
const normalized = normalizeOpenClawChannelEnvelopePrefixes(prefixes);
|
|
2950
|
+
const includeLegacyChannelEnvelopePattern = options.includeLegacyChannelEnvelopePattern ?? true;
|
|
2951
|
+
const platformHeaderPattern = channelEnvelopeHeaderPattern(
|
|
2952
|
+
normalized,
|
|
2953
|
+
includeLegacyChannelEnvelopePattern === true
|
|
2954
|
+
);
|
|
2955
|
+
return (content) => cleanUserMessageWithPattern(content, platformHeaderPattern);
|
|
2956
|
+
}
|
|
2957
|
+
function cleanUserMessageWithPattern(content, platformHeaderPattern) {
|
|
2947
2958
|
let cleaned = content;
|
|
2948
2959
|
cleaned = cleaned.replace(
|
|
2949
2960
|
/<supermemory-context[^>]*>[\s\S]*?<\/supermemory-context>\s*/gi,
|
|
2950
2961
|
""
|
|
2951
2962
|
);
|
|
2952
|
-
const platformHeader = cleaned.match(
|
|
2963
|
+
const platformHeader = cleaned.match(platformHeaderPattern);
|
|
2953
2964
|
const hasPlatformHeader = platformHeader !== null;
|
|
2954
2965
|
if (platformHeader) {
|
|
2955
2966
|
cleaned = cleaned.slice(platformHeader[0].length);
|
|
@@ -2963,6 +2974,21 @@ function cleanUserMessage(content) {
|
|
|
2963
2974
|
}
|
|
2964
2975
|
return cleaned.trim();
|
|
2965
2976
|
}
|
|
2977
|
+
function normalizeOpenClawChannelEnvelopePrefixes(prefixes) {
|
|
2978
|
+
const cleaned = prefixes.map((prefix) => typeof prefix === "string" ? prefix.trim() : "").filter((prefix) => prefix.length > 0);
|
|
2979
|
+
return cleaned.length > 0 ? cleaned : [...DEFAULT_CHANNEL_ENVELOPE_PREFIXES];
|
|
2980
|
+
}
|
|
2981
|
+
function channelEnvelopeHeaderPattern(prefixes, includeLegacyChannelEnvelopePattern) {
|
|
2982
|
+
const alternatives = prefixes.map(escapeRegExp).join("|");
|
|
2983
|
+
const patterns = [`\\[(?:${alternatives})\\s+.+?\\s+id:\\d+\\s+[^\\]]+\\]`];
|
|
2984
|
+
if (includeLegacyChannelEnvelopePattern) {
|
|
2985
|
+
patterns.push("\\[\\w+\\s+.+?\\s+id:\\d+\\s+[^\\]]+\\]");
|
|
2986
|
+
}
|
|
2987
|
+
return new RegExp(`^(?:${patterns.join("|")})\\s*`);
|
|
2988
|
+
}
|
|
2989
|
+
function escapeRegExp(value) {
|
|
2990
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2991
|
+
}
|
|
2966
2992
|
|
|
2967
2993
|
// src/public-artifacts.ts
|
|
2968
2994
|
import { readdir, access, stat, lstat, realpath } from "fs/promises";
|
|
@@ -3484,7 +3510,7 @@ async function syncHeartbeatSurfaceEntries(params) {
|
|
|
3484
3510
|
}
|
|
3485
3511
|
return { created, updated, linked: 0 };
|
|
3486
3512
|
}
|
|
3487
|
-
function
|
|
3513
|
+
function escapeRegExp2(value) {
|
|
3488
3514
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3489
3515
|
}
|
|
3490
3516
|
function buildDelimitedBoundaryClass() {
|
|
@@ -3495,7 +3521,7 @@ function compileDelimitedPhrasePattern(value) {
|
|
|
3495
3521
|
if (normalized.length === 0) return null;
|
|
3496
3522
|
const boundaryClass = buildDelimitedBoundaryClass();
|
|
3497
3523
|
return new RegExp(
|
|
3498
|
-
`(^|[^${boundaryClass}])${
|
|
3524
|
+
`(^|[^${boundaryClass}])${escapeRegExp2(normalized)}([^${boundaryClass}]|$)`
|
|
3499
3525
|
);
|
|
3500
3526
|
}
|
|
3501
3527
|
function matchesDelimitedPattern(haystack, pattern) {
|
|
@@ -4074,6 +4100,7 @@ function buildTurnFingerprint(input) {
|
|
|
4074
4100
|
// ../../src/index.ts
|
|
4075
4101
|
import { planRecallMode } from "@remnic/core/intent";
|
|
4076
4102
|
import { resolvePrincipal, resolveAgentAccessAuthToken as resolveAgentAccessAuthCredential, expandTildePath } from "@remnic/core";
|
|
4103
|
+
import { normalizeHostEmbeddingVector, registerHostEmbeddingProvider } from "@remnic/core/host-embedding-provider";
|
|
4077
4104
|
|
|
4078
4105
|
// ../../src/resolve-provider-secret.ts
|
|
4079
4106
|
var resolve_provider_secret_exports = {};
|
|
@@ -4372,6 +4399,8 @@ function buildServiceKeys(serviceId) {
|
|
|
4372
4399
|
const suffix = `::${serviceId}`;
|
|
4373
4400
|
return {
|
|
4374
4401
|
REGISTERED_GUARD: `__openclawEngramRegistered${suffix}`,
|
|
4402
|
+
HOST_EMBEDDING_UNREGISTER: `__openclawEngramHostEmbeddingUnregister${suffix}`,
|
|
4403
|
+
HOST_EMBEDDING_SIGNATURE: `__openclawEngramHostEmbeddingSignature${suffix}`,
|
|
4375
4404
|
HOOK_APIS: `__openclawEngramHookApis${suffix}`,
|
|
4376
4405
|
ACCESS_SERVICE: `__openclawEngramAccessService${suffix}`,
|
|
4377
4406
|
ACCESS_HTTP_SERVER: `__openclawEngramAccessHttpServer${suffix}`,
|
|
@@ -4570,6 +4599,211 @@ function tryDefinePluginEntry(def) {
|
|
|
4570
4599
|
return def;
|
|
4571
4600
|
}
|
|
4572
4601
|
}
|
|
4602
|
+
var MAX_OBSERVED_INBOUND_MESSAGE_IDS = 1024;
|
|
4603
|
+
var MAX_OBSERVED_INLINE_EXPLICIT_CAPTURE_KEYS = 1024;
|
|
4604
|
+
function requireOpenClawSdkSubpath(subpath) {
|
|
4605
|
+
try {
|
|
4606
|
+
const _require = createRequire(import.meta.url);
|
|
4607
|
+
return _require(subpath);
|
|
4608
|
+
} catch {
|
|
4609
|
+
return null;
|
|
4610
|
+
}
|
|
4611
|
+
}
|
|
4612
|
+
function resolveChannelEnvelopePrefixes(cfg) {
|
|
4613
|
+
if (!cfg.openclawChannelEnvelopeCleaningEnabled) {
|
|
4614
|
+
return { prefixes: ["OpenClaw"], includeLegacyChannelEnvelopePattern: true };
|
|
4615
|
+
}
|
|
4616
|
+
const sdk = requireOpenClawSdkSubpath("openclaw/plugin-sdk/chat-channel-ids");
|
|
4617
|
+
const prefixes = sdk?.BUNDLED_CHAT_CHANNEL_ENVELOPE_PREFIXES;
|
|
4618
|
+
if (!Array.isArray(prefixes)) {
|
|
4619
|
+
return { prefixes: ["OpenClaw"], includeLegacyChannelEnvelopePattern: true };
|
|
4620
|
+
}
|
|
4621
|
+
const cleaned = prefixes.filter((value) => typeof value === "string");
|
|
4622
|
+
return {
|
|
4623
|
+
prefixes: cleaned.length > 0 ? cleaned : ["OpenClaw"],
|
|
4624
|
+
includeLegacyChannelEnvelopePattern: false
|
|
4625
|
+
};
|
|
4626
|
+
}
|
|
4627
|
+
function registerOpenClawHostEmbeddingProvider(params) {
|
|
4628
|
+
const { api, cfg, serviceId } = params;
|
|
4629
|
+
if (cfg.hostEmbeddingProviderEnabled === false) return null;
|
|
4630
|
+
const selected = selectOpenClawEmbeddingAdapter(api, cfg.hostEmbeddingProviderId);
|
|
4631
|
+
if (!selected) return null;
|
|
4632
|
+
const model = cfg.hostEmbeddingProviderModel || selected.adapter.defaultModel || "text-embedding-3-small";
|
|
4633
|
+
const workspaceDir = getOpenClawRuntimeWorkspaceDir(api);
|
|
4634
|
+
let providerPromise = null;
|
|
4635
|
+
let providerInstance = null;
|
|
4636
|
+
const resolveProvider = async () => {
|
|
4637
|
+
if (providerInstance) return providerInstance;
|
|
4638
|
+
providerPromise ??= selected.adapter.create({
|
|
4639
|
+
config: api.config ?? {},
|
|
4640
|
+
workspaceDir,
|
|
4641
|
+
agentDir: workspaceDir,
|
|
4642
|
+
provider: cfg.hostEmbeddingProviderId || selected.adapter.id,
|
|
4643
|
+
model
|
|
4644
|
+
}).then((result) => {
|
|
4645
|
+
providerInstance = result && typeof result === "object" ? result.provider ?? null : null;
|
|
4646
|
+
if (!providerInstance) {
|
|
4647
|
+
logger_exports.log.debug(
|
|
4648
|
+
`OpenClaw host embedding provider ${selected.adapter.id} did not create a provider; using Remnic fallback embeddings`
|
|
4649
|
+
);
|
|
4650
|
+
}
|
|
4651
|
+
return providerInstance;
|
|
4652
|
+
}).catch((error) => {
|
|
4653
|
+
logger_exports.log.debug(
|
|
4654
|
+
`OpenClaw host embedding provider ${selected.adapter.id} unavailable: ${error}`
|
|
4655
|
+
);
|
|
4656
|
+
return null;
|
|
4657
|
+
}).finally(() => {
|
|
4658
|
+
if (!providerInstance) {
|
|
4659
|
+
providerPromise = null;
|
|
4660
|
+
}
|
|
4661
|
+
});
|
|
4662
|
+
return providerPromise;
|
|
4663
|
+
};
|
|
4664
|
+
const hostProvider = {
|
|
4665
|
+
id: `openclaw:${selected.kind}:${selected.adapter.id}`,
|
|
4666
|
+
model: `${selected.kind}:${selected.adapter.id}/${model}`,
|
|
4667
|
+
async embed(text, options) {
|
|
4668
|
+
const provider = await resolveProvider();
|
|
4669
|
+
if (!provider) return null;
|
|
4670
|
+
return embedWithOpenClawProvider(selected.kind, provider, text, options);
|
|
4671
|
+
},
|
|
4672
|
+
async embedBatch(texts, options) {
|
|
4673
|
+
const provider = await resolveProvider();
|
|
4674
|
+
if (!provider) return texts.map(() => null);
|
|
4675
|
+
return embedBatchWithOpenClawProvider(selected.kind, provider, texts, options);
|
|
4676
|
+
},
|
|
4677
|
+
async close() {
|
|
4678
|
+
const close = providerInstance && typeof providerInstance === "object" ? providerInstance.close : void 0;
|
|
4679
|
+
if (typeof close === "function") {
|
|
4680
|
+
await close.call(providerInstance);
|
|
4681
|
+
}
|
|
4682
|
+
}
|
|
4683
|
+
};
|
|
4684
|
+
const unregister = registerHostEmbeddingProvider(cfg.memoryDir, hostProvider);
|
|
4685
|
+
logger_exports.log.info(
|
|
4686
|
+
`registered OpenClaw host embedding provider bridge (${selected.adapter.id}) for ${serviceId}`
|
|
4687
|
+
);
|
|
4688
|
+
return unregister;
|
|
4689
|
+
}
|
|
4690
|
+
function getOpenClawRuntimeWorkspaceDir(api) {
|
|
4691
|
+
const runtimeWorkspaceDir = api.runtime?.agent?.workspaceDir;
|
|
4692
|
+
return typeof runtimeWorkspaceDir === "string" && runtimeWorkspaceDir.length > 0 ? runtimeWorkspaceDir : void 0;
|
|
4693
|
+
}
|
|
4694
|
+
function stableOpenClawConfigSignature(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
4695
|
+
if (value === null) return "null";
|
|
4696
|
+
const valueType = typeof value;
|
|
4697
|
+
if (valueType === "string" || valueType === "number" || valueType === "boolean") {
|
|
4698
|
+
return JSON.stringify(value);
|
|
4699
|
+
}
|
|
4700
|
+
if (valueType === "bigint") return JSON.stringify(String(value));
|
|
4701
|
+
if (valueType === "undefined" || valueType === "function" || valueType === "symbol") {
|
|
4702
|
+
return JSON.stringify(`[${valueType}]`);
|
|
4703
|
+
}
|
|
4704
|
+
if (Array.isArray(value)) {
|
|
4705
|
+
return `[${value.map((entry) => stableOpenClawConfigSignature(entry, seen)).join(",")}]`;
|
|
4706
|
+
}
|
|
4707
|
+
if (value && valueType === "object") {
|
|
4708
|
+
if (seen.has(value)) return JSON.stringify("[Circular]");
|
|
4709
|
+
seen.add(value);
|
|
4710
|
+
const entries = Object.keys(value).sort().map(
|
|
4711
|
+
(key) => `${JSON.stringify(key)}:${stableOpenClawConfigSignature(
|
|
4712
|
+
value[key],
|
|
4713
|
+
seen
|
|
4714
|
+
)}`
|
|
4715
|
+
);
|
|
4716
|
+
seen.delete(value);
|
|
4717
|
+
return `{${entries.join(",")}}`;
|
|
4718
|
+
}
|
|
4719
|
+
return JSON.stringify(String(value));
|
|
4720
|
+
}
|
|
4721
|
+
function openClawHostEmbeddingConfigSignature(cfg, apiConfig, workspaceDir) {
|
|
4722
|
+
return `sha256:${createHash2("sha256").update(JSON.stringify({
|
|
4723
|
+
enabled: cfg.hostEmbeddingProviderEnabled !== false,
|
|
4724
|
+
memoryDir: cfg.memoryDir,
|
|
4725
|
+
providerId: cfg.hostEmbeddingProviderId ?? "",
|
|
4726
|
+
providerModel: cfg.hostEmbeddingProviderModel ?? "",
|
|
4727
|
+
workspaceDir: workspaceDir ?? "",
|
|
4728
|
+
openClawConfig: stableOpenClawConfigSignature(apiConfig)
|
|
4729
|
+
})).digest("hex")}`;
|
|
4730
|
+
}
|
|
4731
|
+
function selectOpenClawEmbeddingAdapter(api, requestedId) {
|
|
4732
|
+
const memorySdk = loadOpenClawMemoryEmbeddingSdk();
|
|
4733
|
+
const memoryAdapters = memorySdk?.listMemoryEmbeddingProviders?.(api.config) ?? [];
|
|
4734
|
+
const selectedMemory = selectAdapter(memoryAdapters, requestedId);
|
|
4735
|
+
if (selectedMemory) {
|
|
4736
|
+
return { kind: "memory", adapter: selectedMemory };
|
|
4737
|
+
}
|
|
4738
|
+
const genericSdk = requireOpenClawSdkSubpath("openclaw/plugin-sdk/embedding-providers");
|
|
4739
|
+
const genericAdapters = genericSdk?.listEmbeddingProviders?.(api.config) ?? [];
|
|
4740
|
+
const selectedGeneric = selectAdapter(genericAdapters, requestedId);
|
|
4741
|
+
if (selectedGeneric) {
|
|
4742
|
+
return { kind: "generic", adapter: selectedGeneric };
|
|
4743
|
+
}
|
|
4744
|
+
return null;
|
|
4745
|
+
}
|
|
4746
|
+
function loadOpenClawMemoryEmbeddingSdk() {
|
|
4747
|
+
return selectOpenClawMemoryEmbeddingSdk(
|
|
4748
|
+
requireOpenClawSdkSubpath("openclaw/plugin-sdk/memory-core-host-engine-embeddings"),
|
|
4749
|
+
requireOpenClawSdkSubpath("openclaw/plugin-sdk/memory-core-host-embedding-registry")
|
|
4750
|
+
);
|
|
4751
|
+
}
|
|
4752
|
+
function selectOpenClawMemoryEmbeddingSdk(currentSdk, legacySdk) {
|
|
4753
|
+
return currentSdk ?? legacySdk;
|
|
4754
|
+
}
|
|
4755
|
+
function selectAdapter(adapters, requestedId) {
|
|
4756
|
+
const valid = adapters.filter(isOpenClawEmbeddingAdapter);
|
|
4757
|
+
if (valid.length === 0) return null;
|
|
4758
|
+
if (requestedId) {
|
|
4759
|
+
return valid.find((adapter) => adapter.id === requestedId) ?? null;
|
|
4760
|
+
}
|
|
4761
|
+
return valid[0] ?? null;
|
|
4762
|
+
}
|
|
4763
|
+
function isOpenClawEmbeddingAdapter(value) {
|
|
4764
|
+
return Boolean(value) && typeof value === "object" && typeof value.id === "string" && typeof value.create === "function";
|
|
4765
|
+
}
|
|
4766
|
+
async function embedWithOpenClawProvider(_kind, provider, text, options) {
|
|
4767
|
+
if (!provider || typeof provider !== "object") return null;
|
|
4768
|
+
const record = provider;
|
|
4769
|
+
if (options?.inputType === "query" && typeof record.embedQuery === "function") {
|
|
4770
|
+
return normalizeHostEmbeddingVector(
|
|
4771
|
+
await record.embedQuery.call(provider, text, { signal: options.signal })
|
|
4772
|
+
);
|
|
4773
|
+
}
|
|
4774
|
+
if (typeof record.embed === "function") {
|
|
4775
|
+
return normalizeHostEmbeddingVector(
|
|
4776
|
+
await record.embed.call(provider, text, {
|
|
4777
|
+
signal: options?.signal,
|
|
4778
|
+
inputType: options?.inputType
|
|
4779
|
+
})
|
|
4780
|
+
);
|
|
4781
|
+
}
|
|
4782
|
+
if (typeof record.embedBatch === "function") {
|
|
4783
|
+
const vectors = await record.embedBatch.call(provider, [text], {
|
|
4784
|
+
signal: options?.signal,
|
|
4785
|
+
inputType: options?.inputType
|
|
4786
|
+
});
|
|
4787
|
+
return normalizeHostEmbeddingVector(Array.isArray(vectors) ? vectors[0] : null);
|
|
4788
|
+
}
|
|
4789
|
+
return null;
|
|
4790
|
+
}
|
|
4791
|
+
async function embedBatchWithOpenClawProvider(kind, provider, texts, options) {
|
|
4792
|
+
if (!provider || typeof provider !== "object") return texts.map(() => null);
|
|
4793
|
+
const record = provider;
|
|
4794
|
+
if (typeof record.embedBatch === "function") {
|
|
4795
|
+
const vectors = await record.embedBatch.call(provider, texts, {
|
|
4796
|
+
signal: options?.signal,
|
|
4797
|
+
inputType: options?.inputType
|
|
4798
|
+
});
|
|
4799
|
+
return texts.map(
|
|
4800
|
+
(_, index) => normalizeHostEmbeddingVector(Array.isArray(vectors) ? vectors[index] : null)
|
|
4801
|
+
);
|
|
4802
|
+
}
|
|
4803
|
+
return Promise.all(
|
|
4804
|
+
texts.map((text) => embedWithOpenClawProvider(kind, provider, text, options))
|
|
4805
|
+
);
|
|
4806
|
+
}
|
|
4573
4807
|
var sdkCaps;
|
|
4574
4808
|
var NON_RUNTIME_REGISTRATION_MODES = /* @__PURE__ */ new Set([
|
|
4575
4809
|
"discovery",
|
|
@@ -4644,10 +4878,47 @@ var pluginDefinition = {
|
|
|
4644
4878
|
`[remnic] memory slot not assigned to ${serviceId}; running passively`
|
|
4645
4879
|
);
|
|
4646
4880
|
}
|
|
4881
|
+
const channelEnvelopeCleaning = resolveChannelEnvelopePrefixes(cfg);
|
|
4882
|
+
const cleanOpenClawUserMessage = createOpenClawUserMessageCleaner(
|
|
4883
|
+
channelEnvelopeCleaning.prefixes,
|
|
4884
|
+
{
|
|
4885
|
+
includeLegacyChannelEnvelopePattern: channelEnvelopeCleaning.includeLegacyChannelEnvelopePattern
|
|
4886
|
+
}
|
|
4887
|
+
);
|
|
4647
4888
|
const existing = globalThis[keys.ORCHESTRATOR];
|
|
4648
4889
|
const orchestrator = existing?.recall ? existing : new Orchestrator(cfg);
|
|
4649
4890
|
const isFirstRegistration = !globalThis[keys.REGISTERED_GUARD];
|
|
4650
4891
|
globalThis[keys.REGISTERED_GUARD] = true;
|
|
4892
|
+
const unregisterExistingHostEmbeddingProvider = () => {
|
|
4893
|
+
const unregisterHostEmbedding = globalThis[keys.HOST_EMBEDDING_UNREGISTER];
|
|
4894
|
+
unregisterHostEmbedding?.();
|
|
4895
|
+
delete globalThis[keys.HOST_EMBEDDING_UNREGISTER];
|
|
4896
|
+
delete globalThis[keys.HOST_EMBEDDING_SIGNATURE];
|
|
4897
|
+
};
|
|
4898
|
+
if (passiveMode) {
|
|
4899
|
+
unregisterExistingHostEmbeddingProvider();
|
|
4900
|
+
} else {
|
|
4901
|
+
const hostEmbeddingSignature = openClawHostEmbeddingConfigSignature(
|
|
4902
|
+
cfg,
|
|
4903
|
+
api.config,
|
|
4904
|
+
getOpenClawRuntimeWorkspaceDir(api)
|
|
4905
|
+
);
|
|
4906
|
+
const existingHostEmbeddingSignature = globalThis[keys.HOST_EMBEDDING_SIGNATURE];
|
|
4907
|
+
if (globalThis[keys.HOST_EMBEDDING_UNREGISTER] && existingHostEmbeddingSignature !== hostEmbeddingSignature) {
|
|
4908
|
+
unregisterExistingHostEmbeddingProvider();
|
|
4909
|
+
}
|
|
4910
|
+
if (!globalThis[keys.HOST_EMBEDDING_UNREGISTER]) {
|
|
4911
|
+
const unregisterHostEmbedding = registerOpenClawHostEmbeddingProvider({
|
|
4912
|
+
api,
|
|
4913
|
+
cfg,
|
|
4914
|
+
serviceId
|
|
4915
|
+
});
|
|
4916
|
+
if (unregisterHostEmbedding) {
|
|
4917
|
+
globalThis[keys.HOST_EMBEDDING_UNREGISTER] = unregisterHostEmbedding;
|
|
4918
|
+
globalThis[keys.HOST_EMBEDDING_SIGNATURE] = hostEmbeddingSignature;
|
|
4919
|
+
}
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4651
4922
|
const hookApis = globalThis[keys.HOOK_APIS] ??= /* @__PURE__ */ new WeakSet();
|
|
4652
4923
|
if (hookApis.has(api)) {
|
|
4653
4924
|
logger_exports.log.debug(
|
|
@@ -4884,7 +5155,83 @@ Keep the reflection grounded in the evidence below.
|
|
|
4884
5155
|
}
|
|
4885
5156
|
);
|
|
4886
5157
|
if (!passiveMode) {
|
|
4887
|
-
let
|
|
5158
|
+
let rememberObservedInboundMessageId2 = function(messageKey) {
|
|
5159
|
+
if (!observedInboundMessageIds.has(messageKey)) {
|
|
5160
|
+
observedInboundMessageIds.add(messageKey);
|
|
5161
|
+
observedInboundMessageIdOrder.push(messageKey);
|
|
5162
|
+
}
|
|
5163
|
+
while (observedInboundMessageIdOrder.length > MAX_OBSERVED_INBOUND_MESSAGE_IDS) {
|
|
5164
|
+
const expired = observedInboundMessageIdOrder.shift();
|
|
5165
|
+
if (expired) {
|
|
5166
|
+
observedInboundMessageIds.delete(expired);
|
|
5167
|
+
inboundReplyMetadataByMessageKey.delete(expired);
|
|
5168
|
+
}
|
|
5169
|
+
}
|
|
5170
|
+
}, rememberObservedInboundMessageKeys2 = function(messageKeys) {
|
|
5171
|
+
for (const messageKey of messageKeys) {
|
|
5172
|
+
rememberObservedInboundMessageId2(messageKey);
|
|
5173
|
+
}
|
|
5174
|
+
}, rememberObservedInboundContentFingerprint2 = function(contentFingerprint) {
|
|
5175
|
+
if (!contentFingerprint) return;
|
|
5176
|
+
if (!observedInboundContentFingerprints.has(contentFingerprint)) {
|
|
5177
|
+
observedInboundContentFingerprints.add(contentFingerprint);
|
|
5178
|
+
observedInboundContentFingerprintOrder.push(contentFingerprint);
|
|
5179
|
+
}
|
|
5180
|
+
while (observedInboundContentFingerprintOrder.length > MAX_OBSERVED_INBOUND_MESSAGE_IDS) {
|
|
5181
|
+
const expired = observedInboundContentFingerprintOrder.shift();
|
|
5182
|
+
if (expired) observedInboundContentFingerprints.delete(expired);
|
|
5183
|
+
}
|
|
5184
|
+
}, rememberPendingSparseInboundContentFingerprint2 = function(contentFingerprint) {
|
|
5185
|
+
if (!contentFingerprint) return;
|
|
5186
|
+
if (!pendingSparseInboundContentFingerprints.has(contentFingerprint)) {
|
|
5187
|
+
pendingSparseInboundContentFingerprints.add(contentFingerprint);
|
|
5188
|
+
pendingSparseInboundContentFingerprintOrder.push(contentFingerprint);
|
|
5189
|
+
}
|
|
5190
|
+
while (pendingSparseInboundContentFingerprintOrder.length > MAX_OBSERVED_INBOUND_MESSAGE_IDS) {
|
|
5191
|
+
const expired = pendingSparseInboundContentFingerprintOrder.shift();
|
|
5192
|
+
if (expired) pendingSparseInboundContentFingerprints.delete(expired);
|
|
5193
|
+
}
|
|
5194
|
+
}, consumePendingSparseInboundContentFingerprint2 = function(contentFingerprint) {
|
|
5195
|
+
if (!contentFingerprint || !pendingSparseInboundContentFingerprints.has(contentFingerprint)) {
|
|
5196
|
+
return false;
|
|
5197
|
+
}
|
|
5198
|
+
pendingSparseInboundContentFingerprints.delete(contentFingerprint);
|
|
5199
|
+
const index = pendingSparseInboundContentFingerprintOrder.indexOf(contentFingerprint);
|
|
5200
|
+
if (index >= 0) pendingSparseInboundContentFingerprintOrder.splice(index, 1);
|
|
5201
|
+
return true;
|
|
5202
|
+
}, rememberInboundReplyMetadata2 = function(messageKeys, metadata) {
|
|
5203
|
+
if (!metadata?.replyToBody?.trim()) return;
|
|
5204
|
+
for (const messageKey of messageKeys) {
|
|
5205
|
+
if (!inboundReplyMetadataByMessageKey.has(messageKey)) {
|
|
5206
|
+
inboundReplyMetadataKeyOrder.push(messageKey);
|
|
5207
|
+
}
|
|
5208
|
+
inboundReplyMetadataByMessageKey.set(messageKey, metadata);
|
|
5209
|
+
}
|
|
5210
|
+
while (inboundReplyMetadataKeyOrder.length > MAX_OBSERVED_INBOUND_MESSAGE_IDS) {
|
|
5211
|
+
const expired = inboundReplyMetadataKeyOrder.shift();
|
|
5212
|
+
if (expired && !observedInboundMessageIds.has(expired)) {
|
|
5213
|
+
inboundReplyMetadataByMessageKey.delete(expired);
|
|
5214
|
+
}
|
|
5215
|
+
}
|
|
5216
|
+
}, getInboundReplyMetadata2 = function(messageKeys) {
|
|
5217
|
+
for (const messageKey of messageKeys) {
|
|
5218
|
+
const metadata = inboundReplyMetadataByMessageKey.get(messageKey);
|
|
5219
|
+
if (metadata?.replyToBody?.trim()) return metadata;
|
|
5220
|
+
}
|
|
5221
|
+
return null;
|
|
5222
|
+
}, rememberObservedInlineExplicitCaptureKey2 = function(noteKey) {
|
|
5223
|
+
if (!observedInlineExplicitCaptureKeys.has(noteKey)) {
|
|
5224
|
+
observedInlineExplicitCaptureKeys.add(noteKey);
|
|
5225
|
+
observedInlineExplicitCaptureKeyOrder.push(noteKey);
|
|
5226
|
+
}
|
|
5227
|
+
while (observedInlineExplicitCaptureKeyOrder.length > MAX_OBSERVED_INLINE_EXPLICIT_CAPTURE_KEYS) {
|
|
5228
|
+
const expired = observedInlineExplicitCaptureKeyOrder.shift();
|
|
5229
|
+
if (expired) observedInlineExplicitCaptureKeys.delete(expired);
|
|
5230
|
+
}
|
|
5231
|
+
}, buildInlineExplicitCaptureDedupeKey2 = function(messageKey, note) {
|
|
5232
|
+
if (!messageKey) return null;
|
|
5233
|
+
return `${messageKey}:inline-memory-note:${createHash2("sha256").update(JSON.stringify(note)).digest("hex")}`;
|
|
5234
|
+
}, resolveStoredCodexThreadId2 = function(sessionKey) {
|
|
4888
5235
|
const threadId = codexThreadBySession.get(sessionKey);
|
|
4889
5236
|
return typeof threadId === "string" && threadId.length > 0 ? threadId : null;
|
|
4890
5237
|
}, resolveStoredCodexBufferKey2 = function(sessionKey) {
|
|
@@ -5171,7 +5518,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
5171
5518
|
const lowered = prompt.trim().toLowerCase();
|
|
5172
5519
|
return lowered.startsWith("read heartbeat.md") || lowered.startsWith("run the following periodic tasks");
|
|
5173
5520
|
};
|
|
5174
|
-
var resolveStoredCodexThreadId = resolveStoredCodexThreadId2, resolveStoredCodexBufferKey = resolveStoredCodexBufferKey2, addSessionToCodexIndex = addSessionToCodexIndex2, removeSessionFromCodexIndex = removeSessionFromCodexIndex2, resolveCodexCompactionBaselineKey = resolveCodexCompactionBaselineKey2, resolveCodexPromptCacheKey = resolveCodexPromptCacheKey2, rememberCodexThread = rememberCodexThread2, forgetCodexThread = forgetCodexThread2, clearCodexCompatCaches = clearCodexCompatCaches2, hasExplicitProviderIdentity = hasExplicitProviderIdentity2, cachePromptMemoryLines = cachePromptMemoryLines2, consumePromptMemoryLines = consumePromptMemoryLines2, resolveSessionIdentity = resolveSessionIdentity2, hasBufferedTurns = hasBufferedTurns2, resolveExtractionBufferKey = resolveExtractionBufferKey2, buildMemoryContextLines = buildMemoryContextLines2, renderMemoryContextPrompt = renderMemoryContextPrompt2, isHeartbeatTrigger = isHeartbeatTrigger2, resolveHeartbeatPromptCandidates = resolveHeartbeatPromptCandidates2, matchHeartbeatEntry = matchHeartbeatEntry2, looksLikeHeartbeatPrompt = looksLikeHeartbeatPrompt2;
|
|
5521
|
+
var rememberObservedInboundMessageId = rememberObservedInboundMessageId2, rememberObservedInboundMessageKeys = rememberObservedInboundMessageKeys2, rememberObservedInboundContentFingerprint = rememberObservedInboundContentFingerprint2, rememberPendingSparseInboundContentFingerprint = rememberPendingSparseInboundContentFingerprint2, consumePendingSparseInboundContentFingerprint = consumePendingSparseInboundContentFingerprint2, rememberInboundReplyMetadata = rememberInboundReplyMetadata2, getInboundReplyMetadata = getInboundReplyMetadata2, rememberObservedInlineExplicitCaptureKey = rememberObservedInlineExplicitCaptureKey2, buildInlineExplicitCaptureDedupeKey = buildInlineExplicitCaptureDedupeKey2, resolveStoredCodexThreadId = resolveStoredCodexThreadId2, resolveStoredCodexBufferKey = resolveStoredCodexBufferKey2, addSessionToCodexIndex = addSessionToCodexIndex2, removeSessionFromCodexIndex = removeSessionFromCodexIndex2, resolveCodexCompactionBaselineKey = resolveCodexCompactionBaselineKey2, resolveCodexPromptCacheKey = resolveCodexPromptCacheKey2, rememberCodexThread = rememberCodexThread2, forgetCodexThread = forgetCodexThread2, clearCodexCompatCaches = clearCodexCompatCaches2, hasExplicitProviderIdentity = hasExplicitProviderIdentity2, cachePromptMemoryLines = cachePromptMemoryLines2, consumePromptMemoryLines = consumePromptMemoryLines2, resolveSessionIdentity = resolveSessionIdentity2, hasBufferedTurns = hasBufferedTurns2, resolveExtractionBufferKey = resolveExtractionBufferKey2, buildMemoryContextLines = buildMemoryContextLines2, renderMemoryContextPrompt = renderMemoryContextPrompt2, isHeartbeatTrigger = isHeartbeatTrigger2, resolveHeartbeatPromptCandidates = resolveHeartbeatPromptCandidates2, matchHeartbeatEntry = matchHeartbeatEntry2, looksLikeHeartbeatPrompt = looksLikeHeartbeatPrompt2;
|
|
5175
5522
|
const hooksPolicy = readPluginHooksPolicy(api.config, serviceId);
|
|
5176
5523
|
const promptInjectionAllowed = coerceRawConfigBoolean(hooksPolicy?.allowPromptInjection) !== false;
|
|
5177
5524
|
const useMemoryPromptSection = sdkCaps.hasRegisterMemoryPromptSection && typeof api.registerMemoryPromptSection === "function" && promptInjectionAllowed;
|
|
@@ -5183,7 +5530,62 @@ Keep the reflection grounded in the evidence below.
|
|
|
5183
5530
|
const codexSessionsByThread = /* @__PURE__ */ new Map();
|
|
5184
5531
|
const codexSessionsByBufferKey = /* @__PURE__ */ new Map();
|
|
5185
5532
|
const codexMessageCountByBufferKey = /* @__PURE__ */ new Map();
|
|
5533
|
+
const observedInboundMessageIds = /* @__PURE__ */ new Set();
|
|
5534
|
+
const observedInboundMessageIdOrder = [];
|
|
5535
|
+
const observedInboundContentFingerprints = /* @__PURE__ */ new Set();
|
|
5536
|
+
const observedInboundContentFingerprintOrder = [];
|
|
5537
|
+
const pendingSparseInboundContentFingerprints = /* @__PURE__ */ new Set();
|
|
5538
|
+
const pendingSparseInboundContentFingerprintOrder = [];
|
|
5539
|
+
const inboundReplyMetadataByMessageKey = /* @__PURE__ */ new Map();
|
|
5540
|
+
const inboundReplyMetadataKeyOrder = [];
|
|
5541
|
+
const observedInlineExplicitCaptureKeys = /* @__PURE__ */ new Set();
|
|
5542
|
+
const observedInlineExplicitCaptureKeyOrder = [];
|
|
5186
5543
|
let codexCompactionModeLogged = false;
|
|
5544
|
+
async function processInlineExplicitCaptureNotes(notes, messageKeys) {
|
|
5545
|
+
let processed = 0;
|
|
5546
|
+
for (const note of notes) {
|
|
5547
|
+
const noteKeys = (messageKeys ?? []).map((messageKey) => buildInlineExplicitCaptureDedupeKey2(messageKey, note)).filter((noteKey) => typeof noteKey === "string");
|
|
5548
|
+
if (noteKeys.length > 0 && noteKeys.some((noteKey) => observedInlineExplicitCaptureKeys.has(noteKey))) {
|
|
5549
|
+
continue;
|
|
5550
|
+
}
|
|
5551
|
+
try {
|
|
5552
|
+
await (0, explicit_capture_exports.persistExplicitCapture)(
|
|
5553
|
+
orchestrator,
|
|
5554
|
+
(0, explicit_capture_exports.validateExplicitCaptureInput)(note),
|
|
5555
|
+
"inline"
|
|
5556
|
+
);
|
|
5557
|
+
orchestrator.requestQmdMaintenanceForTool("inline.memory_note");
|
|
5558
|
+
for (const noteKey of noteKeys) {
|
|
5559
|
+
rememberObservedInlineExplicitCaptureKey2(noteKey);
|
|
5560
|
+
}
|
|
5561
|
+
processed += 1;
|
|
5562
|
+
} catch (error) {
|
|
5563
|
+
try {
|
|
5564
|
+
const queued = await (0, explicit_capture_exports.queueExplicitCaptureForReview)(
|
|
5565
|
+
orchestrator,
|
|
5566
|
+
note,
|
|
5567
|
+
"inline",
|
|
5568
|
+
error
|
|
5569
|
+
);
|
|
5570
|
+
orchestrator.requestQmdMaintenanceForTool(
|
|
5571
|
+
"inline.memory_note.review"
|
|
5572
|
+
);
|
|
5573
|
+
for (const noteKey of noteKeys) {
|
|
5574
|
+
rememberObservedInlineExplicitCaptureKey2(noteKey);
|
|
5575
|
+
}
|
|
5576
|
+
processed += 1;
|
|
5577
|
+
logger_exports.log.warn(
|
|
5578
|
+
`explicit inline capture queued for review: ${queued.id}${queued.duplicateOf ? ` (duplicate of ${queued.duplicateOf})` : ""}`
|
|
5579
|
+
);
|
|
5580
|
+
} catch (queueError) {
|
|
5581
|
+
logger_exports.log.warn(
|
|
5582
|
+
`explicit inline capture rejected: ${error}; review queue fallback failed: ${queueError}`
|
|
5583
|
+
);
|
|
5584
|
+
}
|
|
5585
|
+
}
|
|
5586
|
+
}
|
|
5587
|
+
return processed;
|
|
5588
|
+
}
|
|
5187
5589
|
async function flushAndForgetCodexThreadOnProviderSwitch(sessionKey, sessionIdentity) {
|
|
5188
5590
|
if (sessionIdentity.isCodex || !sessionIdentity.previousCodexThreadId) {
|
|
5189
5591
|
return;
|
|
@@ -6007,6 +6409,86 @@ Keep the reflection grounded in the evidence below.
|
|
|
6007
6409
|
const capabilityDesc = typeof api.registerMemoryCapability === "function" ? `memory capability with publicArtifacts provider${builderDesc}` : "split memory runtime/flush-plan surfaces";
|
|
6008
6410
|
logger_exports.log.info(`registered ${capabilityDesc}`);
|
|
6009
6411
|
}
|
|
6412
|
+
if (cfg.openclawMessageReceivedCaptureEnabled) {
|
|
6413
|
+
api.on(
|
|
6414
|
+
"message_received",
|
|
6415
|
+
async (event, ctx) => {
|
|
6416
|
+
if (cfg.heartbeat.enabled && cfg.heartbeat.gateExtractionDuringHeartbeat && isHeartbeatTrigger2(event, ctx)) {
|
|
6417
|
+
logger_exports.log.debug(
|
|
6418
|
+
`message_received: skipping transcript capture during heartbeat run for ${ctx?.sessionKey ?? "default"}`
|
|
6419
|
+
);
|
|
6420
|
+
return;
|
|
6421
|
+
}
|
|
6422
|
+
const content = typeof event.content === "string" ? event.content.trim() : "";
|
|
6423
|
+
if (content.length === 0) return;
|
|
6424
|
+
const sessionKey = normalizeOptionalString(ctx.sessionKey) ?? normalizeOptionalString(event.sessionKey) ?? "default";
|
|
6425
|
+
const inboundMessageKeys = getOpenClawMessageDedupeKeys(event, event, ctx, sessionKey);
|
|
6426
|
+
if (inboundMessageKeys.some((key) => observedInboundMessageIds.has(key))) return;
|
|
6427
|
+
const metadata = buildOpenClawMessageMetadata(event, event, ctx, cfg);
|
|
6428
|
+
const inboundReplyHintMetadata = cfg.openclawReplyMetadataExtractionHintsEnabled ? buildOpenClawMessageMetadata(event, event, ctx, {
|
|
6429
|
+
openclawReplyMetadataCaptureEnabled: true
|
|
6430
|
+
}) : metadata;
|
|
6431
|
+
const eventDate = typeof event.timestamp === "number" && Number.isFinite(event.timestamp) ? new Date(event.timestamp) : /* @__PURE__ */ new Date();
|
|
6432
|
+
const timestamp = Number.isFinite(eventDate.getTime()) ? eventDate.toISOString() : (/* @__PURE__ */ new Date()).toISOString();
|
|
6433
|
+
const cleaned = cleanOpenClawUserMessage(content);
|
|
6434
|
+
const inlineCaptureEnabled = (0, explicit_capture_exports.shouldProcessInlineExplicitCapture)(
|
|
6435
|
+
orchestrator.config
|
|
6436
|
+
);
|
|
6437
|
+
const explicitNotes = inlineCaptureEnabled ? (0, explicit_capture_exports.parseInlineExplicitCaptureNotes)(cleaned) : [];
|
|
6438
|
+
const transcriptContent = inlineCaptureEnabled && (0, explicit_capture_exports.hasInlineExplicitCaptureMarkup)(cleaned) ? (0, explicit_capture_exports.stripInlineExplicitCaptureNotes)(cleaned) : cleaned;
|
|
6439
|
+
const inboundContentFingerprint = buildOpenClawInboundContentFingerprint(
|
|
6440
|
+
transcriptContent,
|
|
6441
|
+
event,
|
|
6442
|
+
event,
|
|
6443
|
+
ctx,
|
|
6444
|
+
sessionKey
|
|
6445
|
+
);
|
|
6446
|
+
const sparseInboundContentFingerprint = buildOpenClawSparseInboundContentFingerprint(
|
|
6447
|
+
transcriptContent,
|
|
6448
|
+
sessionKey
|
|
6449
|
+
);
|
|
6450
|
+
if (inboundContentFingerprint && observedInboundContentFingerprints.has(inboundContentFingerprint)) {
|
|
6451
|
+
return;
|
|
6452
|
+
}
|
|
6453
|
+
const inlineCaptureDedupeKeys = inboundMessageKeys.length > 0 ? inboundMessageKeys : inboundContentFingerprint ? [inboundContentFingerprint] : sparseInboundContentFingerprint ? [sparseInboundContentFingerprint] : [];
|
|
6454
|
+
const processedExplicitNotes = explicitNotes.length > 0 ? await processInlineExplicitCaptureNotes(
|
|
6455
|
+
explicitNotes,
|
|
6456
|
+
inlineCaptureDedupeKeys
|
|
6457
|
+
) : 0;
|
|
6458
|
+
if (!orchestrator.config.transcriptEnabled || transcriptContent.length === 0) {
|
|
6459
|
+
rememberInboundReplyMetadata2(inboundMessageKeys, inboundReplyHintMetadata);
|
|
6460
|
+
if (processedExplicitNotes > 0) {
|
|
6461
|
+
rememberObservedInboundMessageKeys2(inboundMessageKeys);
|
|
6462
|
+
rememberObservedInboundContentFingerprint2(inboundContentFingerprint);
|
|
6463
|
+
if (inboundMessageKeys.length === 0) {
|
|
6464
|
+
rememberPendingSparseInboundContentFingerprint2(sparseInboundContentFingerprint);
|
|
6465
|
+
}
|
|
6466
|
+
}
|
|
6467
|
+
return;
|
|
6468
|
+
}
|
|
6469
|
+
try {
|
|
6470
|
+
await orchestrator.transcript.append({
|
|
6471
|
+
timestamp,
|
|
6472
|
+
role: "user",
|
|
6473
|
+
content: transcriptContent,
|
|
6474
|
+
sessionKey,
|
|
6475
|
+
turnId: crypto.randomUUID(),
|
|
6476
|
+
...metadata ? { metadata } : {}
|
|
6477
|
+
});
|
|
6478
|
+
if (inboundMessageKeys.length > 0) {
|
|
6479
|
+
rememberObservedInboundMessageKeys2(inboundMessageKeys);
|
|
6480
|
+
rememberInboundReplyMetadata2(inboundMessageKeys, inboundReplyHintMetadata);
|
|
6481
|
+
}
|
|
6482
|
+
rememberObservedInboundContentFingerprint2(inboundContentFingerprint);
|
|
6483
|
+
if (inboundMessageKeys.length === 0) {
|
|
6484
|
+
rememberPendingSparseInboundContentFingerprint2(sparseInboundContentFingerprint);
|
|
6485
|
+
}
|
|
6486
|
+
} catch (err) {
|
|
6487
|
+
logger_exports.log.debug(`message_received transcript append failed: ${err}`);
|
|
6488
|
+
}
|
|
6489
|
+
}
|
|
6490
|
+
);
|
|
6491
|
+
}
|
|
6010
6492
|
api.on(
|
|
6011
6493
|
"agent_end",
|
|
6012
6494
|
async (event, ctx) => {
|
|
@@ -6089,52 +6571,58 @@ Keep the reflection grounded in the evidence below.
|
|
|
6089
6571
|
const role = rawRole;
|
|
6090
6572
|
const content = extractTextContent(msg);
|
|
6091
6573
|
if (content.length < 10) continue;
|
|
6092
|
-
const cleaned = role === "user" ?
|
|
6574
|
+
const cleaned = role === "user" ? cleanOpenClawUserMessage(content) : content;
|
|
6093
6575
|
const inlineCaptureEnabled = (0, explicit_capture_exports.shouldProcessInlineExplicitCapture)(
|
|
6094
6576
|
orchestrator.config
|
|
6095
6577
|
);
|
|
6096
6578
|
const explicitNotes = inlineCaptureEnabled ? (0, explicit_capture_exports.parseInlineExplicitCaptureNotes)(cleaned) : [];
|
|
6097
6579
|
const stripped = inlineCaptureEnabled && (0, explicit_capture_exports.hasInlineExplicitCaptureMarkup)(cleaned) ? (0, explicit_capture_exports.stripInlineExplicitCaptureNotes)(cleaned) : cleaned;
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
}
|
|
6127
|
-
if (orchestrator.config.transcriptEnabled && stripped.length > 0) {
|
|
6580
|
+
const messageMetadata = buildOpenClawMessageMetadata(
|
|
6581
|
+
msg,
|
|
6582
|
+
event,
|
|
6583
|
+
ctx,
|
|
6584
|
+
cfg
|
|
6585
|
+
);
|
|
6586
|
+
const messageDedupeKeys = getOpenClawMessageDedupeKeys(msg, event, ctx, sessionKey);
|
|
6587
|
+
const messageContentFingerprint = buildOpenClawInboundContentFingerprint(
|
|
6588
|
+
stripped,
|
|
6589
|
+
msg,
|
|
6590
|
+
event,
|
|
6591
|
+
ctx,
|
|
6592
|
+
sessionKey
|
|
6593
|
+
);
|
|
6594
|
+
const sparseMessageContentFingerprint = buildOpenClawSparseInboundContentFingerprint(stripped, sessionKey);
|
|
6595
|
+
const cachedReplyHintMetadata = role === "user" && cfg.openclawReplyMetadataExtractionHintsEnabled ? getInboundReplyMetadata2(messageDedupeKeys) : null;
|
|
6596
|
+
const replyHintMetadata = cfg.openclawReplyMetadataExtractionHintsEnabled ? cachedReplyHintMetadata ?? buildOpenClawMessageMetadata(msg, event, ctx, {
|
|
6597
|
+
openclawReplyMetadataCaptureEnabled: true
|
|
6598
|
+
}) : messageMetadata;
|
|
6599
|
+
const messageDedupeKey = messageDedupeKeys[0];
|
|
6600
|
+
const sparseInboundAlreadyCaptured = role === "user" && messageDedupeKeys.length === 0 && consumePendingSparseInboundContentFingerprint2(sparseMessageContentFingerprint);
|
|
6601
|
+
const transcriptAlreadyCaptured = role === "user" && (messageDedupeKeys.length > 0 && messageDedupeKeys.some((key) => observedInboundMessageIds.has(key)) || sparseInboundAlreadyCaptured || messageContentFingerprint !== null && observedInboundContentFingerprints.has(messageContentFingerprint));
|
|
6602
|
+
const inlineCaptureDedupeKeys = messageDedupeKeys.length > 0 ? messageDedupeKeys : messageContentFingerprint ? [messageContentFingerprint] : sparseMessageContentFingerprint ? [sparseMessageContentFingerprint] : [];
|
|
6603
|
+
await processInlineExplicitCaptureNotes(
|
|
6604
|
+
explicitNotes,
|
|
6605
|
+
inlineCaptureDedupeKeys
|
|
6606
|
+
);
|
|
6607
|
+
if (orchestrator.config.transcriptEnabled && stripped.length > 0 && !transcriptAlreadyCaptured) {
|
|
6128
6608
|
await orchestrator.transcript.append({
|
|
6129
6609
|
timestamp: eventTimestamp,
|
|
6130
6610
|
role,
|
|
6131
6611
|
content: stripped,
|
|
6132
6612
|
sessionKey,
|
|
6133
|
-
turnId: crypto.randomUUID()
|
|
6613
|
+
turnId: crypto.randomUUID(),
|
|
6614
|
+
...messageMetadata ? { metadata: messageMetadata } : {}
|
|
6134
6615
|
});
|
|
6616
|
+
if (role === "user") {
|
|
6617
|
+
if (messageDedupeKey) {
|
|
6618
|
+
rememberObservedInboundMessageKeys2(messageDedupeKeys);
|
|
6619
|
+
}
|
|
6620
|
+
rememberObservedInboundContentFingerprint2(messageContentFingerprint);
|
|
6621
|
+
}
|
|
6135
6622
|
}
|
|
6136
6623
|
if (stripped.length > 0) {
|
|
6137
|
-
|
|
6624
|
+
const extractionContent = role === "user" && cfg.openclawReplyMetadataExtractionHintsEnabled ? withReplyExtractionHint(stripped, replyHintMetadata) : stripped;
|
|
6625
|
+
await orchestrator.processTurn(role, extractionContent, sessionKey, {
|
|
6138
6626
|
bufferKey: resolveExtractionBufferKey2(
|
|
6139
6627
|
sessionKey,
|
|
6140
6628
|
sessionIdentity.logicalSessionKey
|
|
@@ -6143,7 +6631,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
6143
6631
|
providerThreadId: sessionIdentity.providerThreadId,
|
|
6144
6632
|
turnFingerprint: buildTurnFingerprint({
|
|
6145
6633
|
role,
|
|
6146
|
-
content:
|
|
6634
|
+
content: extractionContent,
|
|
6147
6635
|
logicalSessionKey: sessionIdentity.logicalSessionKey,
|
|
6148
6636
|
providerThreadId: sessionIdentity.providerThreadId,
|
|
6149
6637
|
maxContentChars: cfg.extractionMaxTurnChars,
|
|
@@ -6990,6 +7478,10 @@ Keep the reflection grounded in the evidence below.
|
|
|
6990
7478
|
stopHeartbeatWatcher = null;
|
|
6991
7479
|
removeDreamingObserver?.();
|
|
6992
7480
|
removeDreamingObserver = null;
|
|
7481
|
+
const unregisterOpenClawHostEmbeddingProvider = globalThis[keys.HOST_EMBEDDING_UNREGISTER];
|
|
7482
|
+
unregisterOpenClawHostEmbeddingProvider?.();
|
|
7483
|
+
delete globalThis[keys.HOST_EMBEDDING_UNREGISTER];
|
|
7484
|
+
delete globalThis[keys.HOST_EMBEDDING_SIGNATURE];
|
|
6993
7485
|
delete globalThis[keys.ACCESS_HTTP_SERVER];
|
|
6994
7486
|
delete globalThis[keys.ACCESS_HTTP_AUTH_STATE];
|
|
6995
7487
|
delete globalThis[keys.ACCESS_SERVICE];
|
|
@@ -7025,6 +7517,97 @@ function extractTextContent(msg) {
|
|
|
7025
7517
|
}
|
|
7026
7518
|
return "";
|
|
7027
7519
|
}
|
|
7520
|
+
function buildOpenClawMessageMetadata(message, event, ctx, cfg) {
|
|
7521
|
+
if (!cfg.openclawReplyMetadataCaptureEnabled) return null;
|
|
7522
|
+
const metadata = {};
|
|
7523
|
+
const messageId = getOpenClawMessageId(message, event, ctx);
|
|
7524
|
+
if (messageId) metadata.messageId = truncateMetadataValue(messageId, 512);
|
|
7525
|
+
const threadId = normalizeThreadId(message.threadId) ?? normalizeThreadId(event.threadId) ?? normalizeThreadId(ctx.threadId);
|
|
7526
|
+
if (threadId) metadata.threadId = truncateMetadataValue(threadId, 512);
|
|
7527
|
+
const replyToId = normalizeOptionalString(message.replyToId) ?? normalizeOptionalString(event.replyToId) ?? normalizeOptionalString(ctx.replyToId);
|
|
7528
|
+
if (replyToId) metadata.replyToId = truncateMetadataValue(replyToId, 512);
|
|
7529
|
+
const replyToBody = normalizeOptionalString(message.replyToBody) ?? normalizeOptionalString(event.replyToBody) ?? normalizeOptionalString(ctx.replyToBody);
|
|
7530
|
+
if (replyToBody) metadata.replyToBody = truncateMetadataValue(replyToBody, 1e3);
|
|
7531
|
+
const replyToSender = normalizeOptionalString(message.replyToSender) ?? normalizeOptionalString(event.replyToSender) ?? normalizeOptionalString(ctx.replyToSender);
|
|
7532
|
+
if (replyToSender) metadata.replyToSender = truncateMetadataValue(replyToSender, 256);
|
|
7533
|
+
return Object.keys(metadata).length > 0 ? metadata : null;
|
|
7534
|
+
}
|
|
7535
|
+
function getOpenClawMessageId(message, event, ctx) {
|
|
7536
|
+
const messageId = normalizeOptionalString(message.messageId) ?? normalizeOptionalString(event.messageId) ?? normalizeOptionalString(ctx.messageId);
|
|
7537
|
+
return messageId ? truncateMetadataValue(messageId, 512) : void 0;
|
|
7538
|
+
}
|
|
7539
|
+
function getOpenClawMessageDedupeKeys(message, event, ctx, sessionKey) {
|
|
7540
|
+
const messageId = getOpenClawMessageId(message, event, ctx);
|
|
7541
|
+
if (!messageId) return [];
|
|
7542
|
+
const sessionScope = normalizeOptionalString(message.sessionKey) ?? normalizeOptionalString(event.sessionKey) ?? normalizeOptionalString(ctx.sessionKey) ?? sessionKey;
|
|
7543
|
+
const threadScope = truncateMetadataValue(
|
|
7544
|
+
normalizeThreadId(message.threadId) ?? normalizeThreadId(event.threadId) ?? normalizeThreadId(ctx.threadId) ?? "",
|
|
7545
|
+
512
|
|
7546
|
+
);
|
|
7547
|
+
const runScope = truncateMetadataValue(
|
|
7548
|
+
normalizeOptionalString(message.runId) ?? normalizeOptionalString(event.runId) ?? normalizeOptionalString(ctx.runId) ?? "",
|
|
7549
|
+
512
|
|
7550
|
+
);
|
|
7551
|
+
const sessionPart = truncateMetadataValue(sessionScope, 512);
|
|
7552
|
+
const dedupeScopes = /* @__PURE__ */ new Set();
|
|
7553
|
+
if (threadScope) dedupeScopes.add(threadScope);
|
|
7554
|
+
if (runScope) dedupeScopes.add(runScope);
|
|
7555
|
+
dedupeScopes.add("");
|
|
7556
|
+
return [...dedupeScopes].map((scope) => `${sessionPart}\0${scope}\0${messageId}`);
|
|
7557
|
+
}
|
|
7558
|
+
function buildOpenClawInboundContentFingerprint(content, message, event, ctx, sessionKey) {
|
|
7559
|
+
const normalizedContent = content.trim();
|
|
7560
|
+
if (!normalizedContent) return null;
|
|
7561
|
+
const sessionPart = truncateMetadataValue(sessionKey || "default", 512);
|
|
7562
|
+
const runScope = truncateMetadataValue(
|
|
7563
|
+
normalizeOptionalString(message.runId) ?? normalizeOptionalString(event.runId) ?? normalizeOptionalString(ctx.runId) ?? "",
|
|
7564
|
+
512
|
|
7565
|
+
);
|
|
7566
|
+
const rawTimestamp = normalizeOptionalString(message.timestamp) ?? normalizeOptionalString(event.timestamp) ?? normalizeOptionalString(ctx.timestamp) ?? (typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? String(message.timestamp) : void 0) ?? (typeof event.timestamp === "number" && Number.isFinite(event.timestamp) ? String(event.timestamp) : void 0) ?? (typeof ctx.timestamp === "number" && Number.isFinite(ctx.timestamp) ? String(ctx.timestamp) : void 0);
|
|
7567
|
+
const timestampScope = rawTimestamp ? truncateMetadataValue(rawTimestamp, 512) : "";
|
|
7568
|
+
if (!runScope && !timestampScope) return null;
|
|
7569
|
+
const threadScope = truncateMetadataValue(
|
|
7570
|
+
normalizeThreadId(message.threadId) ?? normalizeThreadId(event.threadId) ?? normalizeThreadId(ctx.threadId) ?? "",
|
|
7571
|
+
512
|
|
7572
|
+
);
|
|
7573
|
+
const contentHash = createHash2("sha256").update(normalizedContent).digest("hex");
|
|
7574
|
+
return [
|
|
7575
|
+
sessionPart,
|
|
7576
|
+
"content",
|
|
7577
|
+
threadScope,
|
|
7578
|
+
runScope,
|
|
7579
|
+
timestampScope,
|
|
7580
|
+
contentHash
|
|
7581
|
+
].join("\0");
|
|
7582
|
+
}
|
|
7583
|
+
function buildOpenClawSparseInboundContentFingerprint(content, sessionKey) {
|
|
7584
|
+
const normalizedContent = content.trim();
|
|
7585
|
+
if (!normalizedContent) return null;
|
|
7586
|
+
const sessionPart = truncateMetadataValue(sessionKey || "default", 512);
|
|
7587
|
+
const contentHash = createHash2("sha256").update(normalizedContent).digest("hex");
|
|
7588
|
+
return `${sessionPart}\0sparse-content\0${contentHash}`;
|
|
7589
|
+
}
|
|
7590
|
+
function withReplyExtractionHint(content, metadata) {
|
|
7591
|
+
const replyBody = metadata?.replyToBody?.trim();
|
|
7592
|
+
if (!replyBody) return content;
|
|
7593
|
+
const sender = metadata?.replyToSender?.trim();
|
|
7594
|
+
const prefix = sender ? `Reply context from ${sender}: ${replyBody}` : `Reply context: ${replyBody}`;
|
|
7595
|
+
return `${prefix}
|
|
7596
|
+
|
|
7597
|
+
Current message: ${content}`;
|
|
7598
|
+
}
|
|
7599
|
+
function normalizeOptionalString(value) {
|
|
7600
|
+
if (typeof value !== "string") return void 0;
|
|
7601
|
+
const trimmed = value.trim();
|
|
7602
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
7603
|
+
}
|
|
7604
|
+
function normalizeThreadId(value) {
|
|
7605
|
+
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
7606
|
+
return normalizeOptionalString(value);
|
|
7607
|
+
}
|
|
7608
|
+
function truncateMetadataValue(value, maxChars) {
|
|
7609
|
+
return value.length <= maxChars ? value : value.slice(0, maxChars);
|
|
7610
|
+
}
|
|
7028
7611
|
|
|
7029
7612
|
// src/bridge.ts
|
|
7030
7613
|
import fs from "fs";
|
|
@@ -7273,4 +7856,4 @@ async function checkDaemonHealth(host, port) {
|
|
|
7273
7856
|
}
|
|
7274
7857
|
}
|
|
7275
7858
|
var export_loadDaySummaryPrompt = day_summary_exports.loadDaySummaryPrompt;
|
|
7276
|
-
export { checkDaemonHealth, src_default as default, detectBridgeMode, listRemnicPublicArtifacts, export_loadDaySummaryPrompt as loadDaySummaryPrompt, loadHourlySummaryCronJobsData, parseHourlySummaryCronJobsData };
|
|
7859
|
+
export { checkDaemonHealth, src_default as default, detectBridgeMode, embedWithOpenClawProvider, listRemnicPublicArtifacts, export_loadDaySummaryPrompt as loadDaySummaryPrompt, loadHourlySummaryCronJobsData, loadOpenClawMemoryEmbeddingSdk, parseHourlySummaryCronJobsData, selectOpenClawMemoryEmbeddingSdk };
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "openclaw-remnic",
|
|
3
3
|
"name": "Remnic OpenClaw Plugin",
|
|
4
|
-
"version": "9.3.
|
|
4
|
+
"version": "9.3.564",
|
|
5
5
|
"kind": "memory",
|
|
6
6
|
"description": "Local semantic memory for OpenClaw with bundled Remnic core runtime. Requires plugins.slots.memory set to this plugin id for hooks to fire.",
|
|
7
7
|
"setup": {
|
|
@@ -371,6 +371,19 @@
|
|
|
371
371
|
"default": "auto",
|
|
372
372
|
"description": "Embedding provider selection for semantic fallback"
|
|
373
373
|
},
|
|
374
|
+
"hostEmbeddingProviderEnabled": {
|
|
375
|
+
"type": "boolean",
|
|
376
|
+
"default": true,
|
|
377
|
+
"description": "Prefer OpenClaw host-registered embedding providers for Remnic's semantic fallback and embedded vector backends when the OpenClaw SDK exposes them. Falls back to Remnic's existing embedding provider path on older hosts or provider setup failures."
|
|
378
|
+
},
|
|
379
|
+
"hostEmbeddingProviderId": {
|
|
380
|
+
"type": "string",
|
|
381
|
+
"description": "Optional OpenClaw embedding provider adapter id to use. Leave unset for automatic selection from OpenClaw's memory/generic embedding provider registry."
|
|
382
|
+
},
|
|
383
|
+
"hostEmbeddingProviderModel": {
|
|
384
|
+
"type": "string",
|
|
385
|
+
"description": "Optional embedding model id passed to the selected OpenClaw host embedding provider."
|
|
386
|
+
},
|
|
374
387
|
"embeddingFallbackModel": {
|
|
375
388
|
"type": "string",
|
|
376
389
|
"description": "Optional model identifier for embedding fallback requests. Defaults to localLlmModel for legacy installs."
|
|
@@ -801,6 +814,26 @@
|
|
|
801
814
|
"default": 600,
|
|
802
815
|
"description": "Maximum snippet size returned by the OpenClaw memory tool adapters."
|
|
803
816
|
},
|
|
817
|
+
"openclawMessageReceivedCaptureEnabled": {
|
|
818
|
+
"type": "boolean",
|
|
819
|
+
"default": true,
|
|
820
|
+
"description": "Capture OpenClaw message_received hook content into transcripts when that hook is emitted by the host. Older OpenClaw versions that never emit the hook continue through agent_end capture."
|
|
821
|
+
},
|
|
822
|
+
"openclawReplyMetadataCaptureEnabled": {
|
|
823
|
+
"type": "boolean",
|
|
824
|
+
"default": true,
|
|
825
|
+
"description": "Persist bounded OpenClaw messageId, threadId, replyToId, replyToBody, and replyToSender fields in transcript metadata when available."
|
|
826
|
+
},
|
|
827
|
+
"openclawReplyMetadataExtractionHintsEnabled": {
|
|
828
|
+
"type": "boolean",
|
|
829
|
+
"default": false,
|
|
830
|
+
"description": "When true, prepend bounded quoted-reply context to user turns before Remnic extraction. Leave false to store reply metadata without changing extraction behavior."
|
|
831
|
+
},
|
|
832
|
+
"openclawChannelEnvelopeCleaningEnabled": {
|
|
833
|
+
"type": "boolean",
|
|
834
|
+
"default": true,
|
|
835
|
+
"description": "Use OpenClaw's canonical chat-channel envelope prefixes when the SDK exposes plugin-sdk/chat-channel-ids, while keeping the legacy OpenClaw-only cleaner on older hosts."
|
|
836
|
+
},
|
|
804
837
|
"sessionTogglesEnabled": {
|
|
805
838
|
"type": "boolean",
|
|
806
839
|
"default": true,
|
|
@@ -4883,6 +4916,41 @@
|
|
|
4883
4916
|
"label": "Enable QMD",
|
|
4884
4917
|
"help": "Enable QMD for memory search/indexing"
|
|
4885
4918
|
},
|
|
4919
|
+
"hostEmbeddingProviderEnabled": {
|
|
4920
|
+
"label": "Use Host Embeddings",
|
|
4921
|
+
"advanced": true,
|
|
4922
|
+
"help": "Prefer OpenClaw's registered embedding providers when available; Remnic falls back automatically."
|
|
4923
|
+
},
|
|
4924
|
+
"hostEmbeddingProviderId": {
|
|
4925
|
+
"label": "Host Embedding Provider",
|
|
4926
|
+
"advanced": true,
|
|
4927
|
+
"placeholder": "openai-compatible"
|
|
4928
|
+
},
|
|
4929
|
+
"hostEmbeddingProviderModel": {
|
|
4930
|
+
"label": "Host Embedding Model",
|
|
4931
|
+
"advanced": true,
|
|
4932
|
+
"placeholder": "text-embedding-3-small"
|
|
4933
|
+
},
|
|
4934
|
+
"openclawMessageReceivedCaptureEnabled": {
|
|
4935
|
+
"label": "Capture Inbound Messages",
|
|
4936
|
+
"advanced": true,
|
|
4937
|
+
"help": "Use OpenClaw message_received transcript capture when the host emits it."
|
|
4938
|
+
},
|
|
4939
|
+
"openclawReplyMetadataCaptureEnabled": {
|
|
4940
|
+
"label": "Capture Reply Metadata",
|
|
4941
|
+
"advanced": true,
|
|
4942
|
+
"help": "Store bounded message/thread/reply fields in transcript metadata."
|
|
4943
|
+
},
|
|
4944
|
+
"openclawReplyMetadataExtractionHintsEnabled": {
|
|
4945
|
+
"label": "Use Reply Extraction Hints",
|
|
4946
|
+
"advanced": true,
|
|
4947
|
+
"help": "Include bounded quoted-reply context in extraction prompts. Off by default."
|
|
4948
|
+
},
|
|
4949
|
+
"openclawChannelEnvelopeCleaningEnabled": {
|
|
4950
|
+
"label": "Clean Channel Envelopes",
|
|
4951
|
+
"advanced": true,
|
|
4952
|
+
"help": "Use OpenClaw's canonical channel envelope prefixes when available."
|
|
4953
|
+
},
|
|
4886
4954
|
"qmdCollection": {
|
|
4887
4955
|
"label": "QMD Collection",
|
|
4888
4956
|
"advanced": true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/plugin-openclaw",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.564",
|
|
4
4
|
"description": "OpenClaw adapter for Remnic memory with bundled @remnic/core runtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"./dist/index.js"
|
|
29
29
|
],
|
|
30
30
|
"compat": {
|
|
31
|
-
"pluginApi": ">=2026.4.1 || 2026.4.7-1 || 2026.4.9-beta.1 || 2026.4.11-beta.1 || 2026.4.12-beta.1 || 2026.4.14-beta.1 || 2026.4.15-beta.1 || 2026.4.15-beta.2 || 2026.4.19-beta.1 || 2026.4.19-beta.2 || 2026.4.20-beta.1 || 2026.4.20-beta.2 || 2026.4.22-beta.1 || 2026.4.23-beta.1 || 2026.4.23-beta.2 || 2026.4.23-beta.3 || 2026.4.23-beta.4 || 2026.4.23-beta.5 || 2026.4.23-beta.6 || 2026.4.24-beta.1 || 2026.4.24-beta.2 || 2026.4.24-beta.3 || 2026.4.24-beta.4 || 2026.4.24-beta.5 || 2026.4.24-beta.6 || 2026.4.25-beta.1 || 2026.4.25-beta.2 || 2026.4.25-beta.3 || 2026.4.25-beta.4 || 2026.4.25-beta.5 || 2026.4.25-beta.6 || 2026.4.25-beta.7 || 2026.4.25-beta.8 || 2026.4.25-beta.9 || 2026.4.25-beta.10 || 2026.4.25-beta.11 || 2026.4.26-beta.1 || 2026.4.27-beta.1 || 2026.4.29-beta.1 || 2026.4.29-beta.2 || 2026.4.29-beta.3 || 2026.4.29-beta.4 || 2026.4.30-beta.1 || 2026.5.2-beta.1 || 2026.5.2-beta.2 || 2026.5.2-beta.3 || 2026.5.3-1 || 2026.5.3-beta.1 || 2026.5.3-beta.2 || 2026.5.3-beta.3 || 2026.5.3-beta.4 || 2026.5.4-beta.1 || 2026.5.4-beta.2 || 2026.5.4-beta.3 || 2026.5.5-beta.1 || 2026.5.5-beta.2 || 2026.5.6-beta.1 || 2026.5.7-beta.1 || 2026.5.9-beta.1 || 2026.5.10-beta.1 || 2026.5.10-beta.2 || 2026.5.10-beta.3 || 2026.5.10-beta.4 || 2026.5.10-beta.5 || 2026.5.10-beta.6 || 2026.5.12-beta.1 || 2026.5.12-beta.2 || 2026.5.12-beta.3 || 2026.5.12-beta.4 || 2026.5.12-beta.5 || 2026.5.12-beta.6 || 2026.5.12-beta.7 || 2026.5.12-beta.8 || 2026.5.14-beta.1 || 2026.5.14-beta.2 || 2026.5.16-beta.1 || 2026.5.16-beta.2 || 2026.5.16-beta.3 || 2026.5.16-beta.4 || 2026.5.16-beta.5 || 2026.5.16-beta.6 || 2026.5.16-beta.7 || 2026.5.18-beta.1 || 2026.5.19-alpha.1 || 2026.5.19-beta.1 || 2026.5.19-beta.2 || 2026.5.20-beta.1 || 2026.5.20-beta.2 || 2026.5.21-alpha.1 || 2026.5.21-beta.1 || 2026.5.22-beta.1 || 2026.5.23-alpha.1 || 2026.5.24-alpha.1 || 2026.5.24-beta.1 || 2026.5.24-beta.2 || 2026.5.25-alpha.1 || 2026.5.25-alpha.2 || 2026.5.25-beta.1 || 2026.5.26-beta.1 || 2026.5.26-beta.2 || 2026.5.27-alpha.1 || 2026.5.27-beta.1 || 2026.5.28-alpha.1 || 2026.5.28-beta.1 || 2026.5.28-beta.2 || 2026.5.28-beta.3 || 2026.5.28-beta.4 || 2026.5.29-alpha.1 || 2026.5.30-beta.1 || 2026.5.30-beta.2 || 2026.5.31-alpha.1 || 2026.5.31-beta.1 || 2026.5.31-beta.2 || 2026.5.31-beta.3 || 2026.5.31-beta.4 || 2026.6.1-alpha.1 || 2026.6.1-alpha.2 || 2026.6.1-alpha.3 || 2026.6.1-beta.1 || 2026.6.1-beta.2 || 2026.6.2-alpha.1"
|
|
31
|
+
"pluginApi": ">=2026.4.1 || 2026.4.7-1 || 2026.4.9-beta.1 || 2026.4.11-beta.1 || 2026.4.12-beta.1 || 2026.4.14-beta.1 || 2026.4.15-beta.1 || 2026.4.15-beta.2 || 2026.4.19-beta.1 || 2026.4.19-beta.2 || 2026.4.20-beta.1 || 2026.4.20-beta.2 || 2026.4.22-beta.1 || 2026.4.23-beta.1 || 2026.4.23-beta.2 || 2026.4.23-beta.3 || 2026.4.23-beta.4 || 2026.4.23-beta.5 || 2026.4.23-beta.6 || 2026.4.24-beta.1 || 2026.4.24-beta.2 || 2026.4.24-beta.3 || 2026.4.24-beta.4 || 2026.4.24-beta.5 || 2026.4.24-beta.6 || 2026.4.25-beta.1 || 2026.4.25-beta.2 || 2026.4.25-beta.3 || 2026.4.25-beta.4 || 2026.4.25-beta.5 || 2026.4.25-beta.6 || 2026.4.25-beta.7 || 2026.4.25-beta.8 || 2026.4.25-beta.9 || 2026.4.25-beta.10 || 2026.4.25-beta.11 || 2026.4.26-beta.1 || 2026.4.27-beta.1 || 2026.4.29-beta.1 || 2026.4.29-beta.2 || 2026.4.29-beta.3 || 2026.4.29-beta.4 || 2026.4.30-beta.1 || 2026.5.2-beta.1 || 2026.5.2-beta.2 || 2026.5.2-beta.3 || 2026.5.3-1 || 2026.5.3-beta.1 || 2026.5.3-beta.2 || 2026.5.3-beta.3 || 2026.5.3-beta.4 || 2026.5.4-beta.1 || 2026.5.4-beta.2 || 2026.5.4-beta.3 || 2026.5.5-beta.1 || 2026.5.5-beta.2 || 2026.5.6-beta.1 || 2026.5.7-beta.1 || 2026.5.9-beta.1 || 2026.5.10-beta.1 || 2026.5.10-beta.2 || 2026.5.10-beta.3 || 2026.5.10-beta.4 || 2026.5.10-beta.5 || 2026.5.10-beta.6 || 2026.5.12-beta.1 || 2026.5.12-beta.2 || 2026.5.12-beta.3 || 2026.5.12-beta.4 || 2026.5.12-beta.5 || 2026.5.12-beta.6 || 2026.5.12-beta.7 || 2026.5.12-beta.8 || 2026.5.14-beta.1 || 2026.5.14-beta.2 || 2026.5.16-beta.1 || 2026.5.16-beta.2 || 2026.5.16-beta.3 || 2026.5.16-beta.4 || 2026.5.16-beta.5 || 2026.5.16-beta.6 || 2026.5.16-beta.7 || 2026.5.18-beta.1 || 2026.5.19-alpha.1 || 2026.5.19-beta.1 || 2026.5.19-beta.2 || 2026.5.20-beta.1 || 2026.5.20-beta.2 || 2026.5.21-alpha.1 || 2026.5.21-beta.1 || 2026.5.22-beta.1 || 2026.5.23-alpha.1 || 2026.5.24-alpha.1 || 2026.5.24-beta.1 || 2026.5.24-beta.2 || 2026.5.25-alpha.1 || 2026.5.25-alpha.2 || 2026.5.25-beta.1 || 2026.5.26-beta.1 || 2026.5.26-beta.2 || 2026.5.27-alpha.1 || 2026.5.27-beta.1 || 2026.5.28-alpha.1 || 2026.5.28-beta.1 || 2026.5.28-beta.2 || 2026.5.28-beta.3 || 2026.5.28-beta.4 || 2026.5.29-alpha.1 || 2026.5.30-beta.1 || 2026.5.30-beta.2 || 2026.5.31-alpha.1 || 2026.5.31-beta.1 || 2026.5.31-beta.2 || 2026.5.31-beta.3 || 2026.5.31-beta.4 || 2026.6.1-alpha.1 || 2026.6.1-alpha.2 || 2026.6.1-alpha.3 || 2026.6.1-beta.1 || 2026.6.1-beta.2 || 2026.6.2-alpha.1 || 2026.6.2-alpha.2"
|
|
32
32
|
},
|
|
33
33
|
"build": {
|
|
34
|
-
"openclawVersion": "2026.6.2-alpha.
|
|
35
|
-
"pluginSdkVersion": "2026.6.2-alpha.
|
|
34
|
+
"openclawVersion": "2026.6.2-alpha.2",
|
|
35
|
+
"pluginSdkVersion": "2026.6.2-alpha.2"
|
|
36
36
|
},
|
|
37
37
|
"install": {
|
|
38
38
|
"clawhubSpec": "clawhub:@remnic/plugin-openclaw",
|
|
@@ -72,17 +72,17 @@
|
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@sinclair/typebox": "^0.34.0",
|
|
74
74
|
"openai": "^6.0.0",
|
|
75
|
-
"@remnic/core": "^9.3.
|
|
75
|
+
"@remnic/core": "^9.3.564"
|
|
76
76
|
},
|
|
77
77
|
"peerDependencies": {
|
|
78
|
-
"openclaw": ">=2026.4.1 || 2026.4.7-1 || 2026.4.9-beta.1 || 2026.4.11-beta.1 || 2026.4.12-beta.1 || 2026.4.14-beta.1 || 2026.4.15-beta.1 || 2026.4.15-beta.2 || 2026.4.19-beta.1 || 2026.4.19-beta.2 || 2026.4.20-beta.1 || 2026.4.20-beta.2 || 2026.4.22-beta.1 || 2026.4.23-beta.1 || 2026.4.23-beta.2 || 2026.4.23-beta.3 || 2026.4.23-beta.4 || 2026.4.23-beta.5 || 2026.4.23-beta.6 || 2026.4.24-beta.1 || 2026.4.24-beta.2 || 2026.4.24-beta.3 || 2026.4.24-beta.4 || 2026.4.24-beta.5 || 2026.4.24-beta.6 || 2026.4.25-beta.1 || 2026.4.25-beta.2 || 2026.4.25-beta.3 || 2026.4.25-beta.4 || 2026.4.25-beta.5 || 2026.4.25-beta.6 || 2026.4.25-beta.7 || 2026.4.25-beta.8 || 2026.4.25-beta.9 || 2026.4.25-beta.10 || 2026.4.25-beta.11 || 2026.4.26-beta.1 || 2026.4.27-beta.1 || 2026.4.29-beta.1 || 2026.4.29-beta.2 || 2026.4.29-beta.3 || 2026.4.29-beta.4 || 2026.4.30-beta.1 || 2026.5.2-beta.1 || 2026.5.2-beta.2 || 2026.5.2-beta.3 || 2026.5.3-1 || 2026.5.3-beta.1 || 2026.5.3-beta.2 || 2026.5.3-beta.3 || 2026.5.3-beta.4 || 2026.5.4-beta.1 || 2026.5.4-beta.2 || 2026.5.4-beta.3 || 2026.5.5-beta.1 || 2026.5.5-beta.2 || 2026.5.6-beta.1 || 2026.5.7-beta.1 || 2026.5.9-beta.1 || 2026.5.10-beta.1 || 2026.5.10-beta.2 || 2026.5.10-beta.3 || 2026.5.10-beta.4 || 2026.5.10-beta.5 || 2026.5.10-beta.6 || 2026.5.12-beta.1 || 2026.5.12-beta.2 || 2026.5.12-beta.3 || 2026.5.12-beta.4 || 2026.5.12-beta.5 || 2026.5.12-beta.6 || 2026.5.12-beta.7 || 2026.5.12-beta.8 || 2026.5.14-beta.1 || 2026.5.14-beta.2 || 2026.5.16-beta.1 || 2026.5.16-beta.2 || 2026.5.16-beta.3 || 2026.5.16-beta.4 || 2026.5.16-beta.5 || 2026.5.16-beta.6 || 2026.5.16-beta.7 || 2026.5.18-beta.1 || 2026.5.19-alpha.1 || 2026.5.19-beta.1 || 2026.5.19-beta.2 || 2026.5.20-beta.1 || 2026.5.20-beta.2 || 2026.5.21-alpha.1 || 2026.5.21-beta.1 || 2026.5.22-beta.1 || 2026.5.23-alpha.1 || 2026.5.24-alpha.1 || 2026.5.24-beta.1 || 2026.5.24-beta.2 || 2026.5.25-alpha.1 || 2026.5.25-alpha.2 || 2026.5.25-beta.1 || 2026.5.26-beta.1 || 2026.5.26-beta.2 || 2026.5.27-alpha.1 || 2026.5.27-beta.1 || 2026.5.28-alpha.1 || 2026.5.28-beta.1 || 2026.5.28-beta.2 || 2026.5.28-beta.3 || 2026.5.28-beta.4 || 2026.5.29-alpha.1 || 2026.5.30-beta.1 || 2026.5.30-beta.2 || 2026.5.31-alpha.1 || 2026.5.31-beta.1 || 2026.5.31-beta.2 || 2026.5.31-beta.3 || 2026.5.31-beta.4 || 2026.6.1-alpha.1 || 2026.6.1-alpha.2 || 2026.6.1-alpha.3 || 2026.6.1-beta.1 || 2026.6.1-beta.2 || 2026.6.2-alpha.1"
|
|
78
|
+
"openclaw": ">=2026.4.1 || 2026.4.7-1 || 2026.4.9-beta.1 || 2026.4.11-beta.1 || 2026.4.12-beta.1 || 2026.4.14-beta.1 || 2026.4.15-beta.1 || 2026.4.15-beta.2 || 2026.4.19-beta.1 || 2026.4.19-beta.2 || 2026.4.20-beta.1 || 2026.4.20-beta.2 || 2026.4.22-beta.1 || 2026.4.23-beta.1 || 2026.4.23-beta.2 || 2026.4.23-beta.3 || 2026.4.23-beta.4 || 2026.4.23-beta.5 || 2026.4.23-beta.6 || 2026.4.24-beta.1 || 2026.4.24-beta.2 || 2026.4.24-beta.3 || 2026.4.24-beta.4 || 2026.4.24-beta.5 || 2026.4.24-beta.6 || 2026.4.25-beta.1 || 2026.4.25-beta.2 || 2026.4.25-beta.3 || 2026.4.25-beta.4 || 2026.4.25-beta.5 || 2026.4.25-beta.6 || 2026.4.25-beta.7 || 2026.4.25-beta.8 || 2026.4.25-beta.9 || 2026.4.25-beta.10 || 2026.4.25-beta.11 || 2026.4.26-beta.1 || 2026.4.27-beta.1 || 2026.4.29-beta.1 || 2026.4.29-beta.2 || 2026.4.29-beta.3 || 2026.4.29-beta.4 || 2026.4.30-beta.1 || 2026.5.2-beta.1 || 2026.5.2-beta.2 || 2026.5.2-beta.3 || 2026.5.3-1 || 2026.5.3-beta.1 || 2026.5.3-beta.2 || 2026.5.3-beta.3 || 2026.5.3-beta.4 || 2026.5.4-beta.1 || 2026.5.4-beta.2 || 2026.5.4-beta.3 || 2026.5.5-beta.1 || 2026.5.5-beta.2 || 2026.5.6-beta.1 || 2026.5.7-beta.1 || 2026.5.9-beta.1 || 2026.5.10-beta.1 || 2026.5.10-beta.2 || 2026.5.10-beta.3 || 2026.5.10-beta.4 || 2026.5.10-beta.5 || 2026.5.10-beta.6 || 2026.5.12-beta.1 || 2026.5.12-beta.2 || 2026.5.12-beta.3 || 2026.5.12-beta.4 || 2026.5.12-beta.5 || 2026.5.12-beta.6 || 2026.5.12-beta.7 || 2026.5.12-beta.8 || 2026.5.14-beta.1 || 2026.5.14-beta.2 || 2026.5.16-beta.1 || 2026.5.16-beta.2 || 2026.5.16-beta.3 || 2026.5.16-beta.4 || 2026.5.16-beta.5 || 2026.5.16-beta.6 || 2026.5.16-beta.7 || 2026.5.18-beta.1 || 2026.5.19-alpha.1 || 2026.5.19-beta.1 || 2026.5.19-beta.2 || 2026.5.20-beta.1 || 2026.5.20-beta.2 || 2026.5.21-alpha.1 || 2026.5.21-beta.1 || 2026.5.22-beta.1 || 2026.5.23-alpha.1 || 2026.5.24-alpha.1 || 2026.5.24-beta.1 || 2026.5.24-beta.2 || 2026.5.25-alpha.1 || 2026.5.25-alpha.2 || 2026.5.25-beta.1 || 2026.5.26-beta.1 || 2026.5.26-beta.2 || 2026.5.27-alpha.1 || 2026.5.27-beta.1 || 2026.5.28-alpha.1 || 2026.5.28-beta.1 || 2026.5.28-beta.2 || 2026.5.28-beta.3 || 2026.5.28-beta.4 || 2026.5.29-alpha.1 || 2026.5.30-beta.1 || 2026.5.30-beta.2 || 2026.5.31-alpha.1 || 2026.5.31-beta.1 || 2026.5.31-beta.2 || 2026.5.31-beta.3 || 2026.5.31-beta.4 || 2026.6.1-alpha.1 || 2026.6.1-alpha.2 || 2026.6.1-alpha.3 || 2026.6.1-beta.1 || 2026.6.1-beta.2 || 2026.6.2-alpha.1 || 2026.6.2-alpha.2"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
81
|
"@openclaw/plugin-inspector": "0.3.10",
|
|
82
82
|
"acorn": "^8.16.0",
|
|
83
83
|
"tsup": "^8.5.1",
|
|
84
84
|
"typescript": "^5.9.3",
|
|
85
|
-
"@remnic/core": "^9.3.
|
|
85
|
+
"@remnic/core": "^9.3.564"
|
|
86
86
|
},
|
|
87
87
|
"license": "MIT",
|
|
88
88
|
"repository": {
|