// offending code· 2 files flaggedpatterns: 3
--- package/scripts/bge-embed.py (excerpt) ---
#!/usr/bin/env python3
"""
BGE Embedding Server for KIVO — persistent stdin/stdout pipe mode.
Loads BAAI/bge-small-zh-v1.5 once, then loops reading JSON lines from stdin.
Each line: a JSON array of strings → outputs a JSON array of embedding vectors.
Exits on EOF or empty line.
Usage (pipe mode, default):
# Start as persistent process, send JSON lines:
echo '["hello world", "你好世界"]' | python3 scripts/bge-embed.py
# Or keep alive and send multiple batches:
python3 scripts/bge-embed.py <<EOF
["batch one text"]
["batch two text", "another"]
EOF
"""
import sys
import json
def main():
# Load model once at startup
try:
from sentence_transformers import SentenceTransformer
except ImportError:
err = json.dumps({"error": "sentence-transformers not installed. Run: pip install sentence-transformers"})
print(err, flush=True)
sys.exit(1)
try:
model = SentenceTransformer("BAAI/bge-small-zh-v1.5")
except Exception as e:
err = json.dumps({"error": f"Failed to load model: {e}"})
print(err, flush=True)
sys.exit(1)
# Signal ready
print(json.dumps({"status": "ready", "model": "bge-small-zh-v1.5", "dimensions": 512}), flush=True)
# Loop: read one JSON line, process, write one JSON line
for line in sys.stdin:
line = line.strip()
if not line:
continue
try:
texts = json.loads(line)
except json.JSONDecodeError as e:
--- package/hooks/kivo-intent-injection/handler.js (excerpt) ---
/**
* KIVO Intent Injection Hook — 薄壳实现
*
* 职责:监听事件 → 调用 KIVO 包 hook-api → 格式化结果 → 注入 context
* 核心逻辑(向量搜索、embedding、DB 操作)全部委托给 KIVO 包。
*/
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { spawn } from 'node:child_process';
import { createRequire } from 'node:module';
// better-sqlite3 for graph expansion (FR-G05)
const require = createRequire(import.meta.url);
const BetterSqlite3 = require('better-sqlite3');
// --- KIVO hook-api import (relative path for dev; npm users use package name) ---
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const hookApiPath = path.resolve(__dirname, '..', '..', 'projects', 'kivo', 'dist', 'esm', 'hook-api', 'index.js');
let hookApi = null;
async function loadHookApi() {
if (hookApi) return hookApi;
try {
hookApi = await import(hookApiPath);
return hookApi;
} catch (err) {
// Fallback: try package name (for npm-installed environments)
try {
hookApi = await import('@self-evolving-harness/kivo/hook-api');
return hookApi;
} catch {
throw new Error(`Failed to load KIVO hook-api: ${err.message}`);
}
}
}
// --- Path resolution ---
function resolveWorkspace() {
if (process.env.OPENCLAW_WORKSPACE) return process.env.OPENCLAW_WORKSPACE;
const home = process.env.HOME || process.env.USERPROFILE || '';
const candidate = path.join(home, '.openclaw', 'workspace');
if (fs.existsSync(candidate)) return candidate;
re
--- bundled output (OSV-MAL flagged — LLM scope expansion) ---
--- scripts/fix-long-titles.mjs (bundled) ---
#!/usr/bin/env node
/**
* Fix long titles in KIVO knowledge DB.
* FR-N05 AC8: title ≤ 20 chars.
*
* Compression rules (no LLM):
* 1. Remove parenthetical content: (...) / (...)
* 2. Remove content after colon if remainder is mostly non-CJK
* 3. Hard truncate to 19 chars + '…'
*/
import Database from 'better-sqlite3';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
const __dirname = dirname(fileURLToPath(import.meta.url));
const DB_PATH = join(__dirname, '..', 'kivo.db');
const TITLE_HARD_LIMIT = 20;
function compressTitle(title) {
if (title.length <= TITLE_HARD_LIMIT) return title;
let t = title;
// Step 1: Remove parenthetical content
t = t.replace(/[((][^))]*[))]/g, '').trim();
if (t.length <= TITLE_HARD_LIMIT && t.length > 0) return t;
// Step 2: If colon present and after-colon is mostly non-CJK, keep only before
const colonMatch = t.match(/^(.+?)[::](.*)/s);
if (colonMatch) {
const before = colonMatch[1].trim();
const after = colonMatch[2].trim();
const nonCjk = after.replace(/[\u4e00-\u9fff\u3400-\u4dbf]/g, '').length;
if (after.length > 0 && nonCjk / after.length > 0.6) {
t = before;
if (t.length <= TITLE_HARD_LIMIT && t.length > 0) return t;
}
}
// Step 3: Hard truncate
if (t.length > TITLE_HARD_LIMIT) {
t = t.slice(0, TITLE_HARD_LIMIT - 1) + '…';
}
return t || title.slice(0, TITLE_HARD_LIMIT - 1) + '…';
}
// Main
const db = new Database(DB_PATH);
const rows = db.prepare(
`SELECT id, title FROM entries WHERE status='active' AND length(title) > ?`
).all(TITLE_HARD_LIMIT);
console.log(`Found ${rows.length} entries with title > ${TITLE_HARD_LIMIT} chars`);
const update = db.prepare(`UPDATE entries SET title = ?, updated_at = datetime('now') WHERE id = ?`);
const changes = [];
const txn = db.transaction(() => {
for (const row of rows) {
const newTitle = compressTitle(row.title);
if (newTitle !== row.title) {
update.run(newTi
--- hooks/kivo-intent-injection/scripts/extract-queue-worker.mjs (bundled) ---
#!/usr/bin/env node
/**
* KIVO Intent Extraction Worker
*
* Processes queued messages from the hook and extracts high-value knowledge
* using LLM semantic judgment. Writes extracted entries to the KIVO DB.
*
* This script is spawned as a detached background process by the hook handler.
* It uses the same LLM config resolution as KIVO's extract-sessions command.
*
* Usage: node extract-queue-worker.mjs [--queue-path <path>] [--db-path <path>]
*/
import fs from 'node:fs';
import path from 'node:path';
import { randomUUID } from 'node:crypto';
// --- Config resolution (mirrors KIVO's resolveLlmConfig) ---
const DEFAULT_MODEL = 'claude-opus-4-6';
const DEFAULT_BASE_URL = 'https://api.penguinsaichat.dpdns.org/v1';
function normalizeBaseUrl(raw) {
let url = raw.replace(/\/+$/, '');
if (!url.endsWith('/v1')) url += '/v1';
return url;
}
function resolveLlmConfig() {
const envKey = process.env.OPENAI_API_KEY ?? '';
const envBase = process.env.OPENAI_BASE_URL ?? '';
const envModel = process.env.KIVO_LLM_MODEL ?? '';
if (envKey && !envBase.includes('api2.penguinsaichat')) {
return { apiKey: envKey, baseUrl: envBase || DEFAULT_BASE_URL, model: envModel || DEFAULT_MODEL };
}
const ocPath = path.resolve(process.env.HOME ?? '/root', '.openclaw', 'openclaw.json');
if (!fs.existsSync(ocPath)) return { error: 'No openclaw.json found' };
let ocConfig;
try { ocConfig = JSON.parse(fs.readFileSync(ocPath, 'utf-8')); } catch { return { error: 'Failed to parse openclaw.json' }; }
const providers = ocConfig?.models?.providers;
if (!providers || typeof providers !== 'object') return { error: 'No providers in openclaw.json' };
// Prefer penguin-main
const penguinMain = providers['penguin-main'];
if (penguinMain?.apiKey) {
return { apiKey: penguinMain.apiKey, baseUrl: penguinMain.baseUrl ? normalizeBaseUrl(penguinMain.baseUrl) : DEFAULT_BASE_URL, model: envModel || DEFAULT_MODEL };
}
// Find first penguin provider (not api2)
--- dist/esm/config.d.ts (bundled) ---
/**
* KIVO Configuration — re-exports from config/ module for backward compatibility
*/
export { type KivoConfig, type EmbeddingConfig, type ValueGateConfig, type ValueGateThresholds, DEFAULT_VALUE_GATE_THRESHOLDS, mergeConfig } from './config/types.js';
export { validateConfigDetailed, formatValidationErrors } from './config/config-validator.js';
export type { ValidationError, ValidationResult } from './config/config-validator.js';
export { loadEnvConfig, mergeWithEnv, listEnvVars } from './config/env-loader.js';
import type { KivoConfig } from './config/types.js';
export declare function validateConfig(config: KivoConfig): void;
//# sourceMappingURL=config.d.ts.map
--- dist/esm/config.js (bundled) ---
/**
* KIVO Configuration — re-exports from config/ module for backward compatibility
*/
export { DEFAULT_VALUE_GATE_THRESHOLDS, mergeConfig } from './config/types.js';
export { validateConfigDetailed, formatValidationErrors } from './config/config-validator.js';
export { loadEnvConfig, mergeWithEnv, listEnvVars } from './config/env-loader.js';
import { validateConfigDetailed, formatValidationErrors } from './config/config-validator.js';
export function validateConfig(config) {
const result = validateConfigDetailed(config);
if (!result.valid) {
throw new Error(formatValidationErrors(result));
}
}
//# sourceMappingURL=config.js.map
--- dist/esm/index.d.ts (bundled) ---
export * from './types/index.js';
export * from './association/index.js';
export * from './pipeline/index.js';
export { ConflictDetector, cosineSimilarity, keywordOverlap, ConflictResolver, ConflictResolutionLog } from './conflict/index.js';
export type { ConflictDetectorOptions, ResolutionResult, ConflictRecord, ConflictVerdict, ResolutionStrategy, LLMJudgeProvider, ResolutionLogEntry } from './conflict/index.js';
export * from './repository/index.js';
export * from './storage/index.js';
export * from './injection/index.js';
export { ContextInjector as IntentContextInjector, Disambiguator, DisambiguationInference, } from './intent/index.js';
export type { ContextInjectorOptions as IntentContextInjectorOptions, InjectionRequest as IntentInjectionRequest, InjectedContextEntry, InjectedContextSource, InjectionResult as IntentInjectionResult, ClarificationSuggestion, DisambiguationMode, DisambiguationRequest, DisambiguationResult, Interpretation, DisambiguatorOptions, DisambiguationInferenceRequest, DisambiguationInferenceResult, } from './intent/index.js';
export { ConversationExtractor, type ConversationExtractorOptions, type ConversationExtractionResult, type ConversationMessage, MarkdownParser, PlainTextParser, type DocumentParser, type ParsedSection, type Frontmatter, DocumentExtractor, detectDocumentFormat, type DocumentExtractorOptions, type DocumentExtractionResult, type DocumentMetadata, type DocumentFormat, RuleExtractor, type RuleEntry, type RuleExtractorOptions, type RulePriority, type RuleChangeEvent, type RuleConflict, ExtractionPipeline, type ExtractionPipelineOptions, ChunkStrategy, type ChunkOptions, type Chunk, createAnalysisArtifact, type ArtifactSourceType, type CandidateEntity, type ConceptSuggestion, type AssociationSuggestion, type ConflictSuggestion, PersonalKnowledgeInput, type PersonalKnowledgeInputOptions, type ManualEntryInput, type FileImportInput, type UrlImportInput, type ConversationMarkInput, type BatchFolderInput, type BatchImportProgr
--- dist/esm/index.js (bundled) ---
export * from './types/index.js';
export * from './association/index.js';
export * from './pipeline/index.js';
export { ConflictDetector, cosineSimilarity, keywordOverlap, ConflictResolver, ConflictResolutionLog } from './conflict/index.js';
export * from './repository/index.js';
export * from './storage/index.js';
export * from './injection/index.js';
export { ContextInjector as Intent