@psiclawops/hypercompositor 0.9.2 → 0.9.4
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/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +175 -8
- package/openclaw.plugin.json +199 -2
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -81,6 +81,8 @@ declare function lifecyclePolicyTelemetry(fields: {
|
|
|
81
81
|
pressurePct?: number;
|
|
82
82
|
topicShiftConfidence?: number;
|
|
83
83
|
trimSoftTarget?: number;
|
|
84
|
+
protectedWarmingFloorFraction?: number;
|
|
85
|
+
protectedSlotsKept?: number;
|
|
84
86
|
reasons?: string[];
|
|
85
87
|
}): void;
|
|
86
88
|
declare function nextTurnId(): string;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -128,6 +128,20 @@ function lifecyclePolicyTelemetry(fields) {
|
|
|
128
128
|
// Telemetry must never throw
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
+
function resolveAfterTurnProtectedWarmingTelemetry(policy, effectiveBudget) {
|
|
132
|
+
if (policy.band !== 'bootstrap' && policy.band !== 'warmup')
|
|
133
|
+
return {};
|
|
134
|
+
if (Math.max(0, Math.floor(effectiveBudget ?? 0)) <= 0)
|
|
135
|
+
return {};
|
|
136
|
+
const elevatedFloor = 0.34;
|
|
137
|
+
const bandFloor = Math.max(elevatedFloor, Math.max(0, policy.warmHistoryBudgetFraction ?? 0) * 0.60);
|
|
138
|
+
return {
|
|
139
|
+
protectedWarmingFloorFraction: Math.round(bandFloor * 10000) / 10000,
|
|
140
|
+
// Metadata-only count: one protected warming slot is active for this
|
|
141
|
+
// afterTurn gradient refresh. No message text or identifiers are emitted.
|
|
142
|
+
protectedSlotsKept: 1,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
131
145
|
function nextTurnId() {
|
|
132
146
|
_telemetryTurnCounter = (_telemetryTurnCounter + 1) >>> 0;
|
|
133
147
|
return `${Date.now().toString(36)}-${_telemetryTurnCounter.toString(36)}`;
|
|
@@ -623,7 +637,7 @@ async function getHyperMem() {
|
|
|
623
637
|
// same provider as the indexer (Ollama vs OpenAI).
|
|
624
638
|
if (typeof mod.generateEmbeddings === 'function') {
|
|
625
639
|
const rawGenerate = mod.generateEmbeddings;
|
|
626
|
-
_generateEmbeddings = (texts) => rawGenerate(texts, _embeddingConfig ?? undefined);
|
|
640
|
+
_generateEmbeddings = (texts) => rawGenerate(texts, _embeddingConfig ?? undefined, 'query');
|
|
627
641
|
}
|
|
628
642
|
// Load optional user config — compositor tuning overrides
|
|
629
643
|
const userConfig = await loadUserConfig();
|
|
@@ -645,13 +659,18 @@ async function getHyperMem() {
|
|
|
645
659
|
geminiBaseUrl: ue.geminiBaseUrl,
|
|
646
660
|
geminiIndexTaskType: ue.geminiIndexTaskType,
|
|
647
661
|
geminiQueryTaskType: ue.geminiQueryTaskType,
|
|
662
|
+
queryInputType: ue.queryInputType,
|
|
663
|
+
documentInputType: ue.documentInputType,
|
|
664
|
+
queryPrefix: ue.queryPrefix,
|
|
665
|
+
documentPrefix: ue.documentPrefix,
|
|
648
666
|
model: ue.model ?? providerDefaults.model,
|
|
649
667
|
dimensions: ue.dimensions ?? providerDefaults.dimensions,
|
|
650
668
|
timeout: ue.timeout ?? providerDefaults.timeout,
|
|
651
669
|
batchSize: ue.batchSize ?? providerDefaults.batchSize,
|
|
652
670
|
};
|
|
653
|
-
|
|
654
|
-
|
|
671
|
+
const embeddingConfig = _embeddingConfig;
|
|
672
|
+
console.log(`[hypermem-plugin] Embedding provider: ${embeddingConfig.provider} ` +
|
|
673
|
+
`(model: ${embeddingConfig.model}, ${embeddingConfig.dimensions}d, batch: ${embeddingConfig.batchSize})`);
|
|
655
674
|
}
|
|
656
675
|
// Cache eviction config at module scope so assemble() can read it
|
|
657
676
|
// synchronously without re-reading disk on every turn.
|
|
@@ -794,6 +813,35 @@ function extractTextFromInboundContent(content) {
|
|
|
794
813
|
.map(part => part.text ?? '')
|
|
795
814
|
.join('\n');
|
|
796
815
|
}
|
|
816
|
+
/**
|
|
817
|
+
* Determine whether a user turn is "topic-bearing" (substantive).
|
|
818
|
+
*
|
|
819
|
+
* Heartbeat, empty, and small-talk turns are NOT topic-bearing and do not
|
|
820
|
+
* extend the warmup window. This is intentionally a lightweight heuristic:
|
|
821
|
+
* no topic-detector architecture change, no model calls.
|
|
822
|
+
*/
|
|
823
|
+
function isTopicBearingTurn(msg, isHeartbeat) {
|
|
824
|
+
if (isHeartbeat)
|
|
825
|
+
return false;
|
|
826
|
+
if (!msg)
|
|
827
|
+
return false;
|
|
828
|
+
if (msg.role !== 'user')
|
|
829
|
+
return false;
|
|
830
|
+
const text = stripMessageMetadata(extractTextFromInboundContent(msg.content)).trim();
|
|
831
|
+
// Empty turn
|
|
832
|
+
if (text.length === 0)
|
|
833
|
+
return false;
|
|
834
|
+
// Small-talk: very short generic acknowledgments
|
|
835
|
+
if (text.length < 15) {
|
|
836
|
+
if (/^(ok|okay|yes|no|thanks|thank\s+you|got\s+it|sure|yep|nah|nope|alright|cool|nice|great|good|k|kk|heartbeat[_\s-]*ok|👍|👎|hi|hello|hey)[.!]*$/iu.test(text)) {
|
|
837
|
+
return false;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
// Pure punctuation or emoji
|
|
841
|
+
if (/^[\s\p{P}\p{Emoji}]+$/u.test(text))
|
|
842
|
+
return false;
|
|
843
|
+
return true;
|
|
844
|
+
}
|
|
797
845
|
function resolveAssistantTokenCount(msg, runtimeContext) {
|
|
798
846
|
const usage = msg.usage;
|
|
799
847
|
if (usage && typeof usage === 'object') {
|
|
@@ -2248,7 +2296,11 @@ function createHyperMemEngine() {
|
|
|
2248
2296
|
// (contextBlock) is cached, since that's what determines prefix identity.
|
|
2249
2297
|
const cacheReplayThresholdMs = _cacheReplayThresholdMs;
|
|
2250
2298
|
let cachedContextBlock = null;
|
|
2251
|
-
|
|
2299
|
+
const promptHasUserText = typeof prompt === 'string' && prompt.trim().length > 0;
|
|
2300
|
+
// A new user prompt must force a fresh context block. Prefix-cache replay is
|
|
2301
|
+
// only safe for tool-loop/maintenance paths where no new conversational
|
|
2302
|
+
// antecedent needs to be reflected in the transcript context.
|
|
2303
|
+
if (cacheReplayThresholdMs > 0 && !promptHasUserText && !replayRecovery.shouldSkipCacheReplay) {
|
|
2252
2304
|
try {
|
|
2253
2305
|
const cachedAt = await hm.cache.getSlot(agentId, sk, 'assemblyContextAt');
|
|
2254
2306
|
if (cachedAt && Date.now() - parseInt(cachedAt) < cacheReplayThresholdMs) {
|
|
@@ -2401,6 +2453,49 @@ function createHyperMemEngine() {
|
|
|
2401
2453
|
${replayRecovery.emittedText}`
|
|
2402
2454
|
: replayRecovery.emittedText;
|
|
2403
2455
|
}
|
|
2456
|
+
if (forkedContext) {
|
|
2457
|
+
try {
|
|
2458
|
+
let parentHistoryText = forkedContext?.parentHistoryText;
|
|
2459
|
+
if (!parentHistoryText) {
|
|
2460
|
+
const rawParentHistory = await hm.cache.getSlot(agentId, sk, 'parentHistory');
|
|
2461
|
+
if (rawParentHistory) {
|
|
2462
|
+
const parentHistory = JSON.parse(rawParentHistory);
|
|
2463
|
+
parentHistoryText = parentHistory
|
|
2464
|
+
.map(m => ({ role: m.role, text: m.textContent ?? m.content ?? null }))
|
|
2465
|
+
.filter(m => m && typeof m.role === 'string' && typeof m.text === 'string' && m.text.trim())
|
|
2466
|
+
.slice(-12)
|
|
2467
|
+
.map(m => `${m.role}: ${m.text.trim()}`)
|
|
2468
|
+
.join('\n');
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
if (!parentHistoryText && forkedContext.parentSessionKey) {
|
|
2472
|
+
const parentAgentId = extractAgentId(forkedContext.parentSessionKey);
|
|
2473
|
+
const durableParentHistory = hm.queryHistory({
|
|
2474
|
+
agentId: parentAgentId,
|
|
2475
|
+
sessionKey: forkedContext.parentSessionKey,
|
|
2476
|
+
mode: 'runtime_chain',
|
|
2477
|
+
limit: 12,
|
|
2478
|
+
});
|
|
2479
|
+
parentHistoryText = durableParentHistory.messages
|
|
2480
|
+
.filter(m => typeof m.textContent === 'string' && m.textContent.trim())
|
|
2481
|
+
.map(m => `${m.role}: ${m.textContent.trim()}`)
|
|
2482
|
+
.join('\n');
|
|
2483
|
+
}
|
|
2484
|
+
if (parentHistoryText && !(result.contextBlock ?? '').includes(parentHistoryText)) {
|
|
2485
|
+
const forkedHistoryBlock = `## Forked Parent Working History\n${parentHistoryText}`;
|
|
2486
|
+
result.contextBlock = result.contextBlock
|
|
2487
|
+
? `${result.contextBlock}\n\n${forkedHistoryBlock}`
|
|
2488
|
+
: forkedHistoryBlock;
|
|
2489
|
+
result.messages.unshift({
|
|
2490
|
+
role: 'system',
|
|
2491
|
+
content: forkedHistoryBlock,
|
|
2492
|
+
});
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
catch {
|
|
2496
|
+
// Parent-history injection is advisory; seeded hot history remains primary.
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2404
2499
|
// Convert NeutralMessage[] → AgentMessage[] for the OpenClaw runtime.
|
|
2405
2500
|
// neutralToAgentMessage can return a single message or an array (tool results
|
|
2406
2501
|
// expand to individual ToolResultMessage objects), so we flatMap.
|
|
@@ -2865,11 +2960,38 @@ ${replayRecovery.emittedText}`
|
|
|
2865
2960
|
const inboundUserText = inboundUserMsg
|
|
2866
2961
|
? stripMessageMetadata(extractTextFromInboundContent(inboundUserMsg.content))
|
|
2867
2962
|
: '';
|
|
2963
|
+
// Packet 2: topic-bearing warmup decay.
|
|
2964
|
+
// Persist a running count of substantive user turns per session.
|
|
2965
|
+
// Heartbeat/empty/small-talk turns do not increment the counter.
|
|
2966
|
+
const isCurrentTurnTopicBearing = isTopicBearingTurn(inboundUserMsg, Boolean(isHeartbeat));
|
|
2967
|
+
let topicBearingTurnCount = 0;
|
|
2968
|
+
try {
|
|
2969
|
+
const raw = await hm.cache.getSlot(agentId, sk, 'topicBearingTurnCount');
|
|
2970
|
+
if (raw)
|
|
2971
|
+
topicBearingTurnCount = Math.max(0, parseInt(raw, 10) || 0);
|
|
2972
|
+
}
|
|
2973
|
+
catch { /* non-fatal */ }
|
|
2974
|
+
const explicitNewSession = /^\/new(?:\s|$)/i.test(inboundUserText.trim());
|
|
2975
|
+
if (explicitNewSession) {
|
|
2976
|
+
topicBearingTurnCount = 0;
|
|
2977
|
+
try {
|
|
2978
|
+
await hm.cache.setSlot(agentId, sk, 'topicBearingTurnCount', '0');
|
|
2979
|
+
}
|
|
2980
|
+
catch { /* non-fatal */ }
|
|
2981
|
+
}
|
|
2982
|
+
else if (isCurrentTurnTopicBearing) {
|
|
2983
|
+
topicBearingTurnCount++;
|
|
2984
|
+
try {
|
|
2985
|
+
await hm.cache.setSlot(agentId, sk, 'topicBearingTurnCount', String(topicBearingTurnCount));
|
|
2986
|
+
}
|
|
2987
|
+
catch { /* non-fatal */ }
|
|
2988
|
+
}
|
|
2868
2989
|
const lifecyclePolicy = resolveAdaptiveLifecyclePolicy({
|
|
2869
2990
|
usedTokens: estimateMessageArrayTokens(messages),
|
|
2870
2991
|
effectiveBudget: gradientBudget,
|
|
2871
2992
|
userTurnCount: messages.filter(m => m.role === 'user').length,
|
|
2872
|
-
|
|
2993
|
+
topicBearingTurnCount,
|
|
2994
|
+
explicitNewSession,
|
|
2873
2995
|
topicShiftConfidence: adaptiveTopicShiftConfidence,
|
|
2874
2996
|
});
|
|
2875
2997
|
lifecyclePolicyTelemetry({
|
|
@@ -2880,6 +3002,7 @@ ${replayRecovery.emittedText}`
|
|
|
2880
3002
|
pressurePct: lifecyclePolicy.pressurePct,
|
|
2881
3003
|
topicShiftConfidence: adaptiveTopicShiftConfidence,
|
|
2882
3004
|
trimSoftTarget: lifecyclePolicy.trimSoftTarget,
|
|
3005
|
+
...resolveAfterTurnProtectedWarmingTelemetry(lifecyclePolicy, gradientBudget),
|
|
2883
3006
|
reasons: lifecyclePolicy.reasons,
|
|
2884
3007
|
});
|
|
2885
3008
|
await hm.refreshRedisGradient(agentId, sk, gradientBudget, gradientDepth, lifecyclePolicy.trimSoftTarget);
|
|
@@ -3069,6 +3192,7 @@ ${replayRecovery.emittedText}`
|
|
|
3069
3192
|
let parentHistoryMessages = 0;
|
|
3070
3193
|
let parentUserTurnCount = 0;
|
|
3071
3194
|
let parentPressureFraction;
|
|
3195
|
+
let parentHistoryText;
|
|
3072
3196
|
// Seed child with parent's active facts. This preserves the historical
|
|
3073
3197
|
// slot for compatibility; facts still primarily come from L4 by agent id.
|
|
3074
3198
|
const facts = hm.getActiveFacts(parentAgentId, { limit: 50 });
|
|
@@ -3078,12 +3202,41 @@ ${replayRecovery.emittedText}`
|
|
|
3078
3202
|
.join('\n');
|
|
3079
3203
|
await hm.cache.setSlot(childAgentId, childSessionKey, 'parentFacts', factBlock);
|
|
3080
3204
|
}
|
|
3081
|
-
const
|
|
3205
|
+
const maxSeededHistory = _subagentWarming === 'full' ? 25 : 12;
|
|
3206
|
+
let history = await hm.cache.getHistory(parentAgentId, parentSessionKey, maxSeededHistory);
|
|
3207
|
+
if (!history || history.length === 0) {
|
|
3208
|
+
const durableHistory = hm.queryHistory({
|
|
3209
|
+
agentId: parentAgentId,
|
|
3210
|
+
sessionKey: parentSessionKey,
|
|
3211
|
+
mode: 'runtime_chain',
|
|
3212
|
+
limit: maxSeededHistory,
|
|
3213
|
+
});
|
|
3214
|
+
history = durableHistory.messages.map(message => ({
|
|
3215
|
+
id: message.id,
|
|
3216
|
+
conversationId: durableHistory.scopedBy.conversationId ?? 0,
|
|
3217
|
+
agentId: parentAgentId,
|
|
3218
|
+
role: message.role,
|
|
3219
|
+
textContent: message.textContent ?? null,
|
|
3220
|
+
toolCalls: Array.isArray(message.toolCalls) ? message.toolCalls : null,
|
|
3221
|
+
toolResults: Array.isArray(message.toolResults) ? message.toolResults : null,
|
|
3222
|
+
messageIndex: message.messageIndex,
|
|
3223
|
+
tokenCount: null,
|
|
3224
|
+
isHeartbeat: false,
|
|
3225
|
+
createdAt: message.createdAt,
|
|
3226
|
+
}));
|
|
3227
|
+
}
|
|
3082
3228
|
if (history && history.length > 0) {
|
|
3083
|
-
const maxSeededHistory = _subagentWarming === 'full' ? 25 : 12;
|
|
3084
3229
|
const recentHistory = history.slice(-maxSeededHistory);
|
|
3085
3230
|
parentHistoryMessages = recentHistory.length;
|
|
3086
3231
|
parentUserTurnCount = recentHistory.filter(m => m.role === 'user').length;
|
|
3232
|
+
parentHistoryText = recentHistory
|
|
3233
|
+
.map(m => ({
|
|
3234
|
+
role: m.role,
|
|
3235
|
+
text: typeof m.textContent === 'string' ? m.textContent : (typeof m.content === 'string' ? m.content : null),
|
|
3236
|
+
}))
|
|
3237
|
+
.filter(m => typeof m.text === 'string' && m.text.trim())
|
|
3238
|
+
.map(m => `${m.role}: ${m.text.trim()}`)
|
|
3239
|
+
.join('\n');
|
|
3087
3240
|
const parentTokens = estimateMessageArrayTokens(recentHistory);
|
|
3088
3241
|
const parentModelState = await hm.cache.getModelState(parentAgentId, parentSessionKey).catch(() => null);
|
|
3089
3242
|
const parentBudget = parentModelState?.tokenBudget && parentModelState.tokenBudget > 0
|
|
@@ -3091,7 +3244,16 @@ ${replayRecovery.emittedText}`
|
|
|
3091
3244
|
: undefined;
|
|
3092
3245
|
parentPressureFraction = parentBudget ? parentTokens / parentBudget : undefined;
|
|
3093
3246
|
if (isForkedContext || _subagentWarming === 'full') {
|
|
3094
|
-
|
|
3247
|
+
const forkedHistoryText = parentHistoryText
|
|
3248
|
+
? `Forked parent working history:\n${parentHistoryText}`
|
|
3249
|
+
: undefined;
|
|
3250
|
+
if (isForkedContext && forkedHistoryText) {
|
|
3251
|
+
await hm.recordUserMessage(childAgentId, childSessionKey, forkedHistoryText, { channelType: 'subagent' });
|
|
3252
|
+
}
|
|
3253
|
+
const seededHistory = isForkedContext && parentHistoryText
|
|
3254
|
+
? [{ role: 'system', textContent: `## Forked Parent Working History\n${parentHistoryText}`, toolCalls: null, toolResults: null }, ...recentHistory]
|
|
3255
|
+
: recentHistory;
|
|
3256
|
+
await hm.cache.replaceHistory(childAgentId, childSessionKey, seededHistory, maxSeededHistory + 1);
|
|
3095
3257
|
await hm.cache.invalidateWindow(childAgentId, childSessionKey).catch(() => { });
|
|
3096
3258
|
}
|
|
3097
3259
|
await hm.cache.setSlot(childAgentId, childSessionKey, 'parentHistory', JSON.stringify(recentHistory));
|
|
@@ -3105,6 +3267,7 @@ ${replayRecovery.emittedText}`
|
|
|
3105
3267
|
parentPressureFraction,
|
|
3106
3268
|
parentUserTurnCount,
|
|
3107
3269
|
parentHistoryMessages,
|
|
3270
|
+
parentHistoryText,
|
|
3108
3271
|
};
|
|
3109
3272
|
await hm.cache.setSlot(childAgentId, childSessionKey, FORKED_CONTEXT_META_SLOT, JSON.stringify(forkedMeta));
|
|
3110
3273
|
}
|
|
@@ -3352,6 +3515,10 @@ const hypercompositorConfigSchema = z.object({
|
|
|
3352
3515
|
geminiBaseUrl: z.string().optional(),
|
|
3353
3516
|
geminiIndexTaskType: z.string().optional(),
|
|
3354
3517
|
geminiQueryTaskType: z.string().optional(),
|
|
3518
|
+
queryInputType: z.string().optional(),
|
|
3519
|
+
documentInputType: z.string().optional(),
|
|
3520
|
+
queryPrefix: z.string().optional(),
|
|
3521
|
+
documentPrefix: z.string().optional(),
|
|
3355
3522
|
model: z.string().optional(),
|
|
3356
3523
|
dimensions: z.number().int().positive().optional(),
|
|
3357
3524
|
timeout: z.number().int().positive().optional(),
|
package/openclaw.plugin.json
CHANGED
|
@@ -3,11 +3,208 @@
|
|
|
3
3
|
"enabledByDefault": false,
|
|
4
4
|
"kind": "context-engine",
|
|
5
5
|
"activation": {
|
|
6
|
-
"onCapabilities": [
|
|
6
|
+
"onCapabilities": [
|
|
7
|
+
"context-engine"
|
|
8
|
+
]
|
|
7
9
|
},
|
|
8
10
|
"configSchema": {
|
|
9
11
|
"type": "object",
|
|
10
12
|
"additionalProperties": false,
|
|
11
|
-
"properties": {
|
|
13
|
+
"properties": {
|
|
14
|
+
"hyperMemPath": {
|
|
15
|
+
"type": "string"
|
|
16
|
+
},
|
|
17
|
+
"dataDir": {
|
|
18
|
+
"type": "string"
|
|
19
|
+
},
|
|
20
|
+
"contextWindowSize": {
|
|
21
|
+
"type": "integer",
|
|
22
|
+
"minimum": 1
|
|
23
|
+
},
|
|
24
|
+
"contextWindowReserve": {
|
|
25
|
+
"type": "number",
|
|
26
|
+
"minimum": 0,
|
|
27
|
+
"maximum": 0.5
|
|
28
|
+
},
|
|
29
|
+
"deferToolPruning": {
|
|
30
|
+
"type": "boolean"
|
|
31
|
+
},
|
|
32
|
+
"verboseLogging": {
|
|
33
|
+
"type": "boolean"
|
|
34
|
+
},
|
|
35
|
+
"warmCacheReplayThresholdMs": {
|
|
36
|
+
"type": "integer",
|
|
37
|
+
"minimum": 0
|
|
38
|
+
},
|
|
39
|
+
"subagentWarming": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"enum": [
|
|
42
|
+
"full",
|
|
43
|
+
"light",
|
|
44
|
+
"off"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
"contextWindowOverrides": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"additionalProperties": {
|
|
50
|
+
"type": "object",
|
|
51
|
+
"additionalProperties": false,
|
|
52
|
+
"properties": {
|
|
53
|
+
"contextTokens": {
|
|
54
|
+
"type": "integer",
|
|
55
|
+
"minimum": 1
|
|
56
|
+
},
|
|
57
|
+
"contextWindow": {
|
|
58
|
+
"type": "integer",
|
|
59
|
+
"minimum": 1
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"compositor": {
|
|
65
|
+
"type": "object",
|
|
66
|
+
"additionalProperties": true
|
|
67
|
+
},
|
|
68
|
+
"eviction": {
|
|
69
|
+
"type": "object",
|
|
70
|
+
"additionalProperties": false,
|
|
71
|
+
"properties": {
|
|
72
|
+
"enabled": {
|
|
73
|
+
"type": "boolean"
|
|
74
|
+
},
|
|
75
|
+
"imageAgeTurns": {
|
|
76
|
+
"type": "integer",
|
|
77
|
+
"minimum": 0
|
|
78
|
+
},
|
|
79
|
+
"toolResultAgeTurns": {
|
|
80
|
+
"type": "integer",
|
|
81
|
+
"minimum": 0
|
|
82
|
+
},
|
|
83
|
+
"minTokensToEvict": {
|
|
84
|
+
"type": "integer",
|
|
85
|
+
"minimum": 0
|
|
86
|
+
},
|
|
87
|
+
"keepPreviewChars": {
|
|
88
|
+
"type": "integer",
|
|
89
|
+
"minimum": 0
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"embedding": {
|
|
94
|
+
"type": "object",
|
|
95
|
+
"additionalProperties": false,
|
|
96
|
+
"properties": {
|
|
97
|
+
"provider": {
|
|
98
|
+
"type": "string",
|
|
99
|
+
"enum": [
|
|
100
|
+
"none",
|
|
101
|
+
"ollama",
|
|
102
|
+
"openai",
|
|
103
|
+
"gemini"
|
|
104
|
+
]
|
|
105
|
+
},
|
|
106
|
+
"ollamaUrl": {
|
|
107
|
+
"type": "string"
|
|
108
|
+
},
|
|
109
|
+
"openaiApiKey": {
|
|
110
|
+
"type": "string"
|
|
111
|
+
},
|
|
112
|
+
"openaiBaseUrl": {
|
|
113
|
+
"type": "string"
|
|
114
|
+
},
|
|
115
|
+
"geminiApiKey": {
|
|
116
|
+
"type": "string"
|
|
117
|
+
},
|
|
118
|
+
"geminiBaseUrl": {
|
|
119
|
+
"type": "string"
|
|
120
|
+
},
|
|
121
|
+
"geminiIndexTaskType": {
|
|
122
|
+
"type": "string"
|
|
123
|
+
},
|
|
124
|
+
"geminiQueryTaskType": {
|
|
125
|
+
"type": "string"
|
|
126
|
+
},
|
|
127
|
+
"queryInputType": {
|
|
128
|
+
"type": "string"
|
|
129
|
+
},
|
|
130
|
+
"documentInputType": {
|
|
131
|
+
"type": "string"
|
|
132
|
+
},
|
|
133
|
+
"queryPrefix": {
|
|
134
|
+
"type": "string"
|
|
135
|
+
},
|
|
136
|
+
"documentPrefix": {
|
|
137
|
+
"type": "string"
|
|
138
|
+
},
|
|
139
|
+
"model": {
|
|
140
|
+
"type": "string"
|
|
141
|
+
},
|
|
142
|
+
"dimensions": {
|
|
143
|
+
"type": "integer",
|
|
144
|
+
"minimum": 1
|
|
145
|
+
},
|
|
146
|
+
"timeout": {
|
|
147
|
+
"type": "integer",
|
|
148
|
+
"minimum": 1
|
|
149
|
+
},
|
|
150
|
+
"batchSize": {
|
|
151
|
+
"type": "integer",
|
|
152
|
+
"minimum": 1
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
"reranker": {
|
|
157
|
+
"type": "object",
|
|
158
|
+
"additionalProperties": false,
|
|
159
|
+
"required": [
|
|
160
|
+
"provider"
|
|
161
|
+
],
|
|
162
|
+
"properties": {
|
|
163
|
+
"provider": {
|
|
164
|
+
"type": "string",
|
|
165
|
+
"enum": [
|
|
166
|
+
"zeroentropy",
|
|
167
|
+
"openrouter",
|
|
168
|
+
"local",
|
|
169
|
+
"none"
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
"minCandidates": {
|
|
173
|
+
"type": "integer",
|
|
174
|
+
"minimum": 0
|
|
175
|
+
},
|
|
176
|
+
"maxDocuments": {
|
|
177
|
+
"type": "integer",
|
|
178
|
+
"minimum": 1
|
|
179
|
+
},
|
|
180
|
+
"topK": {
|
|
181
|
+
"type": "integer",
|
|
182
|
+
"minimum": 1
|
|
183
|
+
},
|
|
184
|
+
"timeoutMs": {
|
|
185
|
+
"type": "integer",
|
|
186
|
+
"minimum": 1
|
|
187
|
+
},
|
|
188
|
+
"zeroEntropyApiKey": {
|
|
189
|
+
"type": "string"
|
|
190
|
+
},
|
|
191
|
+
"zeroEntropyModel": {
|
|
192
|
+
"type": "string"
|
|
193
|
+
},
|
|
194
|
+
"openrouterApiKey": {
|
|
195
|
+
"type": "string"
|
|
196
|
+
},
|
|
197
|
+
"openrouterModel": {
|
|
198
|
+
"type": "string"
|
|
199
|
+
},
|
|
200
|
+
"ollamaUrl": {
|
|
201
|
+
"type": "string"
|
|
202
|
+
},
|
|
203
|
+
"ollamaModel": {
|
|
204
|
+
"type": "string"
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
12
209
|
}
|
|
13
210
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@psiclawops/hypercompositor",
|
|
3
|
-
"version": "0.9.
|
|
4
|
-
"description": "HyperCompositor
|
|
3
|
+
"version": "0.9.4",
|
|
4
|
+
"description": "HyperCompositor \u2014 context engine plugin for OpenClaw",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"openclaw": {
|
|
19
19
|
"plugin": {
|
|
20
20
|
"id": "hypercompositor",
|
|
21
|
-
"name": "HyperCompositor
|
|
21
|
+
"name": "HyperCompositor \u2014 Context Engine",
|
|
22
22
|
"kind": "context-engine"
|
|
23
23
|
},
|
|
24
24
|
"extensions": [
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"typecheck": "tsc --noEmit"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@psiclawops/hypermem": "0.9.
|
|
43
|
+
"@psiclawops/hypermem": "^0.9.4",
|
|
44
44
|
"zod": "^4.0.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|