qlogicagent 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -45
- package/package.json +56 -42
- package/dist/agent/agent.d.ts +0 -43
- package/dist/agent/agent.js +0 -113
- package/dist/agent/tool-loop.d.ts +0 -64
- package/dist/agent/tool-loop.js +0 -575
- package/dist/agent/types.d.ts +0 -175
- package/dist/agent/types.js +0 -14
- package/dist/cli/main.d.ts +0 -11
- package/dist/cli/main.js +0 -23
- package/dist/cli/stdio-server.d.ts +0 -45
- package/dist/cli/stdio-server.js +0 -463
- package/dist/config/config.d.ts +0 -17
- package/dist/config/config.js +0 -21
- package/dist/contracts/hooks.d.ts +0 -120
- package/dist/contracts/hooks.js +0 -7
- package/dist/contracts/index.d.ts +0 -10
- package/dist/contracts/index.js +0 -10
- package/dist/contracts/planner.d.ts +0 -35
- package/dist/contracts/planner.js +0 -2
- package/dist/contracts/skill-candidate.d.ts +0 -63
- package/dist/contracts/skill-candidate.js +0 -195
- package/dist/contracts/todo.d.ts +0 -14
- package/dist/contracts/todo.js +0 -9
- package/dist/index.d.ts +0 -13
- package/dist/index.js +0 -15
- package/dist/llm/builtin-providers.d.ts +0 -10
- package/dist/llm/builtin-providers.js +0 -531
- package/dist/llm/index.d.ts +0 -15
- package/dist/llm/index.js +0 -14
- package/dist/llm/llm-client.d.ts +0 -43
- package/dist/llm/llm-client.js +0 -67
- package/dist/llm/model-catalog.d.ts +0 -53
- package/dist/llm/model-catalog.js +0 -191
- package/dist/llm/provider-def.d.ts +0 -59
- package/dist/llm/provider-def.js +0 -12
- package/dist/llm/provider-registry.d.ts +0 -54
- package/dist/llm/provider-registry.js +0 -147
- package/dist/llm/transport.d.ts +0 -62
- package/dist/llm/transport.js +0 -27
- package/dist/llm/transports/anthropic-messages.d.ts +0 -31
- package/dist/llm/transports/anthropic-messages.js +0 -293
- package/dist/llm/transports/openai-chat.d.ts +0 -36
- package/dist/llm/transports/openai-chat.js +0 -165
- package/dist/orchestration/agent-registry.d.ts +0 -41
- package/dist/orchestration/agent-registry.js +0 -116
- package/dist/orchestration/approval-aware-tool-plan.d.ts +0 -32
- package/dist/orchestration/approval-aware-tool-plan.js +0 -87
- package/dist/orchestration/context-compression.d.ts +0 -220
- package/dist/orchestration/context-compression.js +0 -583
- package/dist/orchestration/conversation-repair.d.ts +0 -61
- package/dist/orchestration/conversation-repair.js +0 -429
- package/dist/orchestration/curator-scheduler.d.ts +0 -119
- package/dist/orchestration/curator-scheduler.js +0 -135
- package/dist/orchestration/embedded-failover-policy.d.ts +0 -110
- package/dist/orchestration/embedded-failover-policy.js +0 -168
- package/dist/orchestration/error-classification.d.ts +0 -12
- package/dist/orchestration/error-classification.js +0 -77
- package/dist/orchestration/failover-classification.d.ts +0 -8
- package/dist/orchestration/failover-classification.js +0 -381
- package/dist/orchestration/failover-error.d.ts +0 -33
- package/dist/orchestration/failover-error.js +0 -198
- package/dist/orchestration/fork-subagent.d.ts +0 -100
- package/dist/orchestration/fork-subagent.js +0 -98
- package/dist/orchestration/index.d.ts +0 -120
- package/dist/orchestration/index.js +0 -267
- package/dist/orchestration/memory-flush-policy.d.ts +0 -57
- package/dist/orchestration/memory-flush-policy.js +0 -85
- package/dist/orchestration/memory-provider.d.ts +0 -14
- package/dist/orchestration/memory-provider.js +0 -2
- package/dist/orchestration/parallel-tool-calls.d.ts +0 -41
- package/dist/orchestration/parallel-tool-calls.js +0 -59
- package/dist/orchestration/prompt-cache-strategy.d.ts +0 -126
- package/dist/orchestration/prompt-cache-strategy.js +0 -228
- package/dist/orchestration/reactive-compact.d.ts +0 -73
- package/dist/orchestration/reactive-compact.js +0 -78
- package/dist/orchestration/retry-loop.d.ts +0 -22
- package/dist/orchestration/retry-loop.js +0 -24
- package/dist/orchestration/skill-candidate.d.ts +0 -52
- package/dist/orchestration/skill-candidate.js +0 -141
- package/dist/orchestration/skill-consolidation.d.ts +0 -123
- package/dist/orchestration/skill-consolidation.js +0 -220
- package/dist/orchestration/skill-improvement.d.ts +0 -59
- package/dist/orchestration/skill-improvement.js +0 -66
- package/dist/orchestration/skill-similarity.d.ts +0 -98
- package/dist/orchestration/skill-similarity.js +0 -131
- package/dist/orchestration/streaming-tool-executor.d.ts +0 -73
- package/dist/orchestration/streaming-tool-executor.js +0 -96
- package/dist/orchestration/team-orchestration.d.ts +0 -195
- package/dist/orchestration/team-orchestration.js +0 -369
- package/dist/orchestration/team-tool-loop-wiring.d.ts +0 -92
- package/dist/orchestration/team-tool-loop-wiring.js +0 -147
- package/dist/orchestration/tool-choice-policy.d.ts +0 -54
- package/dist/orchestration/tool-choice-policy.js +0 -164
- package/dist/orchestration/tool-loop-state.d.ts +0 -50
- package/dist/orchestration/tool-loop-state.js +0 -133
- package/dist/orchestration/tool-schema.d.ts +0 -39
- package/dist/orchestration/tool-schema.js +0 -297
- package/dist/orchestration/transcript-repair.d.ts +0 -42
- package/dist/orchestration/transcript-repair.js +0 -426
- package/dist/orchestration/turn-loop-guard.d.ts +0 -86
- package/dist/orchestration/turn-loop-guard.js +0 -92
- package/dist/orchestration/web-browser-policy.d.ts +0 -17
- package/dist/orchestration/web-browser-policy.js +0 -39
- package/dist/runtime/context-compression.d.ts +0 -61
- package/dist/runtime/context-compression.js +0 -274
- package/dist/runtime/hook-registry.d.ts +0 -12
- package/dist/runtime/hook-registry.js +0 -53
- package/dist/runtime/memory-hooks.d.ts +0 -23
- package/dist/runtime/memory-hooks.js +0 -65
- package/dist/runtime/tool-eligibility.d.ts +0 -59
- package/dist/runtime/tool-eligibility.js +0 -111
- package/dist/skills/index.d.ts +0 -108
- package/dist/skills/index.js +0 -82
- package/dist/skills/memory-extractor.d.ts +0 -64
- package/dist/skills/memory-extractor.js +0 -173
- package/dist/skills/memory-query-tool.d.ts +0 -43
- package/dist/skills/memory-query-tool.js +0 -127
- package/dist/skills/memory-store.d.ts +0 -66
- package/dist/skills/memory-store.js +0 -228
- package/dist/skills/memory-tool.d.ts +0 -67
- package/dist/skills/memory-tool.js +0 -192
- package/dist/skills/portable-tool.d.ts +0 -71
- package/dist/skills/portable-tool.js +0 -14
- package/dist/skills/qmemory-adapter.d.ts +0 -52
- package/dist/skills/qmemory-adapter.js +0 -165
- package/dist/skills/skill-frontmatter.d.ts +0 -19
- package/dist/skills/skill-frontmatter.js +0 -344
- package/dist/skills/skill-guard.d.ts +0 -23
- package/dist/skills/skill-guard.js +0 -229
- package/dist/skills/skill-loader.d.ts +0 -16
- package/dist/skills/skill-loader.js +0 -303
- package/dist/skills/skill-source.d.ts +0 -119
- package/dist/skills/skill-source.js +0 -126
- package/dist/skills/skill-types.d.ts +0 -199
- package/dist/skills/skill-types.js +0 -6
- package/dist/skills/think-tool.d.ts +0 -16
- package/dist/skills/think-tool.js +0 -59
- package/dist/skills/todo-tool.d.ts +0 -63
- package/dist/skills/todo-tool.js +0 -114
- package/dist/skills/tools/agent-tool.d.ts +0 -91
- package/dist/skills/tools/agent-tool.js +0 -142
- package/dist/skills/tools/apply-patch-tool.d.ts +0 -29
- package/dist/skills/tools/apply-patch-tool.js +0 -184
- package/dist/skills/tools/ask-user-tool.d.ts +0 -80
- package/dist/skills/tools/ask-user-tool.js +0 -121
- package/dist/skills/tools/brief-tool.d.ts +0 -74
- package/dist/skills/tools/brief-tool.js +0 -95
- package/dist/skills/tools/browser-tool.d.ts +0 -114
- package/dist/skills/tools/browser-tool.js +0 -155
- package/dist/skills/tools/checkpoint-tool.d.ts +0 -66
- package/dist/skills/tools/checkpoint-tool.js +0 -102
- package/dist/skills/tools/config-tool.d.ts +0 -63
- package/dist/skills/tools/config-tool.js +0 -143
- package/dist/skills/tools/cron-tool.d.ts +0 -116
- package/dist/skills/tools/cron-tool.js +0 -175
- package/dist/skills/tools/edit-tool.d.ts +0 -43
- package/dist/skills/tools/edit-tool.js +0 -70
- package/dist/skills/tools/exec-tool.d.ts +0 -102
- package/dist/skills/tools/exec-tool.js +0 -133
- package/dist/skills/tools/image-generate-tool.d.ts +0 -62
- package/dist/skills/tools/image-generate-tool.js +0 -67
- package/dist/skills/tools/instructions-tool.d.ts +0 -103
- package/dist/skills/tools/instructions-tool.js +0 -187
- package/dist/skills/tools/lsp-tool.d.ts +0 -153
- package/dist/skills/tools/lsp-tool.js +0 -227
- package/dist/skills/tools/mcp-client-types.d.ts +0 -269
- package/dist/skills/tools/mcp-client-types.js +0 -53
- package/dist/skills/tools/mcp-tool.d.ts +0 -249
- package/dist/skills/tools/mcp-tool.js +0 -503
- package/dist/skills/tools/memory-tool.d.ts +0 -74
- package/dist/skills/tools/memory-tool.js +0 -88
- package/dist/skills/tools/monitor-tool.d.ts +0 -113
- package/dist/skills/tools/monitor-tool.js +0 -131
- package/dist/skills/tools/music-generate-tool.d.ts +0 -55
- package/dist/skills/tools/music-generate-tool.js +0 -62
- package/dist/skills/tools/notify-tool.d.ts +0 -53
- package/dist/skills/tools/notify-tool.js +0 -62
- package/dist/skills/tools/patch-tool.d.ts +0 -45
- package/dist/skills/tools/patch-tool.js +0 -505
- package/dist/skills/tools/pdf-tool.d.ts +0 -66
- package/dist/skills/tools/pdf-tool.js +0 -88
- package/dist/skills/tools/plan-mode-tool.d.ts +0 -59
- package/dist/skills/tools/plan-mode-tool.js +0 -122
- package/dist/skills/tools/read-tool.d.ts +0 -51
- package/dist/skills/tools/read-tool.js +0 -84
- package/dist/skills/tools/repl-tool.d.ts +0 -70
- package/dist/skills/tools/repl-tool.js +0 -69
- package/dist/skills/tools/search-tool.d.ts +0 -112
- package/dist/skills/tools/search-tool.js +0 -225
- package/dist/skills/tools/send-message-tool.d.ts +0 -51
- package/dist/skills/tools/send-message-tool.js +0 -76
- package/dist/skills/tools/skill-list-tool.d.ts +0 -33
- package/dist/skills/tools/skill-list-tool.js +0 -54
- package/dist/skills/tools/skill-manage-tool.d.ts +0 -73
- package/dist/skills/tools/skill-manage-tool.js +0 -153
- package/dist/skills/tools/skill-view-tool.d.ts +0 -37
- package/dist/skills/tools/skill-view-tool.js +0 -72
- package/dist/skills/tools/sleep-tool.d.ts +0 -49
- package/dist/skills/tools/sleep-tool.js +0 -81
- package/dist/skills/tools/structured-output-tool.d.ts +0 -116
- package/dist/skills/tools/structured-output-tool.js +0 -176
- package/dist/skills/tools/task-tool.d.ts +0 -104
- package/dist/skills/tools/task-tool.js +0 -161
- package/dist/skills/tools/team-tool.d.ts +0 -89
- package/dist/skills/tools/team-tool.js +0 -105
- package/dist/skills/tools/tool-search-tool.d.ts +0 -51
- package/dist/skills/tools/tool-search-tool.js +0 -110
- package/dist/skills/tools/tts-tool.d.ts +0 -38
- package/dist/skills/tools/tts-tool.js +0 -45
- package/dist/skills/tools/video-edit-tool.d.ts +0 -69
- package/dist/skills/tools/video-edit-tool.js +0 -74
- package/dist/skills/tools/video-generate-tool.d.ts +0 -62
- package/dist/skills/tools/video-generate-tool.js +0 -66
- package/dist/skills/tools/video-merge-tool.d.ts +0 -105
- package/dist/skills/tools/video-merge-tool.js +0 -92
- package/dist/skills/tools/video-upscale-tool.d.ts +0 -45
- package/dist/skills/tools/video-upscale-tool.js +0 -52
- package/dist/skills/tools/web-fetch-tool.d.ts +0 -78
- package/dist/skills/tools/web-fetch-tool.js +0 -92
- package/dist/skills/tools/web-search-tool.d.ts +0 -57
- package/dist/skills/tools/web-search-tool.js +0 -86
- package/dist/skills/tools/worktree-tool.d.ts +0 -69
- package/dist/skills/tools/worktree-tool.js +0 -147
- package/dist/skills/tools/write-tool.d.ts +0 -45
- package/dist/skills/tools/write-tool.js +0 -81
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import type { MemoryIngestOptions, MemoryProvider } from "qlogicagent-runtime-contracts";
|
|
2
|
-
/** A pre-extracted memory item ready to be stored (no LLM needed). */
|
|
3
|
-
export interface ExtractedMemoryItem {
|
|
4
|
-
text: string;
|
|
5
|
-
category?: string;
|
|
6
|
-
importance?: number;
|
|
7
|
-
speaker?: string;
|
|
8
|
-
event_date?: string;
|
|
9
|
-
tags?: string[];
|
|
10
|
-
}
|
|
11
|
-
/** Configuration for the QMemory HTTP adapter. */
|
|
12
|
-
export interface QMemoryAdapterConfig {
|
|
13
|
-
/** Base URL of the qmemory server (e.g. "http://localhost:18800"). */
|
|
14
|
-
baseUrl: string;
|
|
15
|
-
/** Optional API key for authentication. */
|
|
16
|
-
apiKey?: string;
|
|
17
|
-
/** Request timeout in milliseconds (default: 5000). */
|
|
18
|
-
timeoutMs?: number;
|
|
19
|
-
/** Prefix prepended to userId for multi-tenant isolation. */
|
|
20
|
-
userIdPrefix?: string;
|
|
21
|
-
}
|
|
22
|
-
/** Health status returned by qmemory `/v1/health/`. */
|
|
23
|
-
export interface QMemoryHealthStatus {
|
|
24
|
-
status: string;
|
|
25
|
-
version: string;
|
|
26
|
-
memoryCount: number;
|
|
27
|
-
dbSizeBytes: number;
|
|
28
|
-
embeddingModel: string;
|
|
29
|
-
uptimeSeconds: number;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Create a MemoryProvider backed by a QMemory HTTP server.
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* ```ts
|
|
36
|
-
* const provider = createQMemoryAdapter({
|
|
37
|
-
* baseUrl: "http://localhost:18800",
|
|
38
|
-
* apiKey: "sk-...",
|
|
39
|
-
* });
|
|
40
|
-
*
|
|
41
|
-
* const results = await provider.search("last meeting notes", "alice");
|
|
42
|
-
* await provider.ingest([{ role: "user", content: "..." }], "alice");
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
export declare function createQMemoryAdapter(config: QMemoryAdapterConfig): MemoryProvider & {
|
|
46
|
-
/** Check qmemory server health. */
|
|
47
|
-
health(): Promise<QMemoryHealthStatus>;
|
|
48
|
-
/** Write pre-extracted memories (no LLM extraction on qmemory side). */
|
|
49
|
-
ingestExtracted(items: ExtractedMemoryItem[], userId: string, options?: MemoryIngestOptions): Promise<{
|
|
50
|
-
memoriesAdded: number;
|
|
51
|
-
}>;
|
|
52
|
-
};
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// QMemory HTTP adapter — implements MemoryProvider against the
|
|
3
|
-
// QMemory REST API (v1).
|
|
4
|
-
//
|
|
5
|
-
// This is a Hub-ready, provider-agnostic adapter that can be
|
|
6
|
-
// plugged into any consumer of the MemoryProvider contract.
|
|
7
|
-
// ============================================================
|
|
8
|
-
const DEFAULT_TIMEOUT_MS = 5_000;
|
|
9
|
-
const PROVIDER_ID = "qmemory";
|
|
10
|
-
/**
|
|
11
|
-
* Create a MemoryProvider backed by a QMemory HTTP server.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```ts
|
|
15
|
-
* const provider = createQMemoryAdapter({
|
|
16
|
-
* baseUrl: "http://localhost:18800",
|
|
17
|
-
* apiKey: "sk-...",
|
|
18
|
-
* });
|
|
19
|
-
*
|
|
20
|
-
* const results = await provider.search("last meeting notes", "alice");
|
|
21
|
-
* await provider.ingest([{ role: "user", content: "..." }], "alice");
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
export function createQMemoryAdapter(config) {
|
|
25
|
-
const baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
26
|
-
const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
27
|
-
function resolveUserId(userId) {
|
|
28
|
-
return config.userIdPrefix ? `${config.userIdPrefix}:${userId}` : userId;
|
|
29
|
-
}
|
|
30
|
-
function buildHeaders() {
|
|
31
|
-
const headers = {
|
|
32
|
-
"Accept": "application/json",
|
|
33
|
-
};
|
|
34
|
-
if (config.apiKey) {
|
|
35
|
-
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
36
|
-
}
|
|
37
|
-
return headers;
|
|
38
|
-
}
|
|
39
|
-
async function request(pathname, init) {
|
|
40
|
-
const url = `${baseUrl}${pathname}`;
|
|
41
|
-
const controller = new AbortController();
|
|
42
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
43
|
-
try {
|
|
44
|
-
const response = await fetch(url, {
|
|
45
|
-
...init,
|
|
46
|
-
headers: { ...buildHeaders(), ...init?.headers },
|
|
47
|
-
signal: controller.signal,
|
|
48
|
-
});
|
|
49
|
-
if (!response.ok) {
|
|
50
|
-
const text = await response.text().catch(() => "");
|
|
51
|
-
throw new Error(`QMemory ${init?.method ?? "GET"} ${pathname} returned ${response.status}: ${text.slice(0, 200)}`);
|
|
52
|
-
}
|
|
53
|
-
return await response.json();
|
|
54
|
-
}
|
|
55
|
-
finally {
|
|
56
|
-
clearTimeout(timer);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return {
|
|
60
|
-
providerId: PROVIDER_ID,
|
|
61
|
-
async search(query, userId, options) {
|
|
62
|
-
const resolvedUserId = resolveUserId(userId);
|
|
63
|
-
const limit = options?.limit ?? 10;
|
|
64
|
-
const params = new URLSearchParams({
|
|
65
|
-
q: query,
|
|
66
|
-
user_id: resolvedUserId,
|
|
67
|
-
limit: String(limit),
|
|
68
|
-
});
|
|
69
|
-
const result = await request(`/v1/memories/search/?${params.toString()}`);
|
|
70
|
-
return (result.memories ?? [])
|
|
71
|
-
.filter((m) => m.id && m.text)
|
|
72
|
-
.map((m) => ({
|
|
73
|
-
blockId: m.id,
|
|
74
|
-
text: m.text,
|
|
75
|
-
score: typeof m.importance === "number" ? m.importance : 0,
|
|
76
|
-
source: PROVIDER_ID,
|
|
77
|
-
metadata: m.metadata,
|
|
78
|
-
}));
|
|
79
|
-
},
|
|
80
|
-
async ingest(messages, userId, options) {
|
|
81
|
-
const resolvedUserId = resolveUserId(userId);
|
|
82
|
-
await request("/v1/memories/", {
|
|
83
|
-
method: "POST",
|
|
84
|
-
headers: { "Content-Type": "application/json" },
|
|
85
|
-
body: JSON.stringify({
|
|
86
|
-
user_id: resolvedUserId,
|
|
87
|
-
messages: messages.map((m) => ({
|
|
88
|
-
role: m.role,
|
|
89
|
-
content: m.content,
|
|
90
|
-
...(m.timestamp ? { timestamp: m.timestamp } : {}),
|
|
91
|
-
})), extraction_mode: "none", ...(options?.sessionId ? { session_id: options.sessionId } : {}),
|
|
92
|
-
...(options?.source ? { metadata: { source: options.source } } : {}),
|
|
93
|
-
run_async: true,
|
|
94
|
-
}),
|
|
95
|
-
});
|
|
96
|
-
},
|
|
97
|
-
async health() {
|
|
98
|
-
const raw = await request("/v1/health/");
|
|
99
|
-
return {
|
|
100
|
-
status: raw.status ?? "unknown",
|
|
101
|
-
version: raw.version ?? "",
|
|
102
|
-
memoryCount: raw.memory_count ?? 0,
|
|
103
|
-
dbSizeBytes: raw.db_size_bytes ?? 0,
|
|
104
|
-
embeddingModel: raw.embedding_model ?? "",
|
|
105
|
-
uptimeSeconds: raw.uptime_seconds ?? 0,
|
|
106
|
-
};
|
|
107
|
-
},
|
|
108
|
-
async addText(text, userId, options) {
|
|
109
|
-
const resolvedUserId = resolveUserId(userId);
|
|
110
|
-
const result = await request("/v1/memories/", {
|
|
111
|
-
method: "POST",
|
|
112
|
-
headers: { "Content-Type": "application/json" },
|
|
113
|
-
body: JSON.stringify({
|
|
114
|
-
user_id: resolvedUserId,
|
|
115
|
-
text,
|
|
116
|
-
extraction_mode: "none",
|
|
117
|
-
...(options?.sessionId ? { session_id: options.sessionId } : {}),
|
|
118
|
-
...(options?.source ? { metadata: { source: options.source } } : {}),
|
|
119
|
-
}),
|
|
120
|
-
});
|
|
121
|
-
return { memoriesAdded: result.memories_added ?? 0 };
|
|
122
|
-
},
|
|
123
|
-
async ingestExtracted(items, userId, options) {
|
|
124
|
-
if (items.length === 0)
|
|
125
|
-
return { memoriesAdded: 0 };
|
|
126
|
-
const resolvedUserId = resolveUserId(userId);
|
|
127
|
-
const results = await Promise.allSettled(items.map((item) => request("/v1/memories/", {
|
|
128
|
-
method: "POST",
|
|
129
|
-
headers: { "Content-Type": "application/json" },
|
|
130
|
-
body: JSON.stringify({
|
|
131
|
-
user_id: resolvedUserId,
|
|
132
|
-
text: item.text,
|
|
133
|
-
extraction_mode: "none",
|
|
134
|
-
...(options?.sessionId ? { session_id: options.sessionId } : {}),
|
|
135
|
-
metadata: {
|
|
136
|
-
...(options?.source ? { source: options.source } : {}),
|
|
137
|
-
...(item.category ? { category: item.category } : {}),
|
|
138
|
-
...(typeof item.importance === "number" ? { importance: item.importance } : {}),
|
|
139
|
-
...(item.speaker ? { speaker: item.speaker } : {}),
|
|
140
|
-
...(item.event_date ? { event_date: item.event_date } : {}),
|
|
141
|
-
...(item.tags?.length ? { tags: item.tags } : {}),
|
|
142
|
-
},
|
|
143
|
-
}),
|
|
144
|
-
})));
|
|
145
|
-
let total = 0;
|
|
146
|
-
for (const r of results) {
|
|
147
|
-
if (r.status === "fulfilled") {
|
|
148
|
-
total += r.value.memories_added ?? 1;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
return { memoriesAdded: total };
|
|
152
|
-
},
|
|
153
|
-
async remove(memoryId) {
|
|
154
|
-
try {
|
|
155
|
-
await request(`/v1/memories/${encodeURIComponent(memoryId)}/`, {
|
|
156
|
-
method: "DELETE",
|
|
157
|
-
});
|
|
158
|
-
return true;
|
|
159
|
-
}
|
|
160
|
-
catch {
|
|
161
|
-
return false;
|
|
162
|
-
}
|
|
163
|
-
},
|
|
164
|
-
};
|
|
165
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { ParsedSkillFrontmatter, SkillInvocationPolicy, SkillMetadata } from "./skill-types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Parse a YAML-like frontmatter block into a flat key→value record.
|
|
4
|
-
* Uses a lightweight line parser to avoid a YAML library dependency.
|
|
5
|
-
*/
|
|
6
|
-
export declare function parseFrontmatter(content: string): ParsedSkillFrontmatter;
|
|
7
|
-
/**
|
|
8
|
-
* Resolve structured metadata from the `metadata:` frontmatter field.
|
|
9
|
-
* Expects `metadata: {"openclaw": {...}}` (JSON format).
|
|
10
|
-
*/
|
|
11
|
-
export declare function resolveSkillMetadata(frontmatter: ParsedSkillFrontmatter): SkillMetadata | undefined;
|
|
12
|
-
/**
|
|
13
|
-
* Resolve invocation policy from frontmatter fields.
|
|
14
|
-
*/
|
|
15
|
-
export declare function resolveSkillInvocationPolicy(frontmatter: ParsedSkillFrontmatter): SkillInvocationPolicy;
|
|
16
|
-
/**
|
|
17
|
-
* Get the canonical key for a skill (metadata.skillKey or skill.name).
|
|
18
|
-
*/
|
|
19
|
-
export declare function resolveSkillKey(skillName: string, metadata?: SkillMetadata): string;
|
|
@@ -1,344 +0,0 @@
|
|
|
1
|
-
// ---------------------------------------------------------------------------
|
|
2
|
-
// SKILL.md frontmatter parser — portable, zero external dependencies.
|
|
3
|
-
// Mirrors openclaw/src/markdown/frontmatter.ts + src/agents/skills/frontmatter.ts
|
|
4
|
-
// but without YAML library (uses simple line parser + JSON5-free metadata).
|
|
5
|
-
// ---------------------------------------------------------------------------
|
|
6
|
-
// ---------------------------------------------------------------------------
|
|
7
|
-
// Block extraction
|
|
8
|
-
// ---------------------------------------------------------------------------
|
|
9
|
-
function extractFrontmatterBlock(content) {
|
|
10
|
-
const normalized = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
11
|
-
if (!normalized.startsWith("---")) {
|
|
12
|
-
return undefined;
|
|
13
|
-
}
|
|
14
|
-
const endIndex = normalized.indexOf("\n---", 3);
|
|
15
|
-
if (endIndex === -1) {
|
|
16
|
-
return undefined;
|
|
17
|
-
}
|
|
18
|
-
return normalized.slice(4, endIndex);
|
|
19
|
-
}
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
// Line parser (handles both inline and multi-line values)
|
|
22
|
-
// ---------------------------------------------------------------------------
|
|
23
|
-
function stripQuotes(value) {
|
|
24
|
-
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
25
|
-
(value.startsWith("'") && value.endsWith("'"))) {
|
|
26
|
-
return value.slice(1, -1);
|
|
27
|
-
}
|
|
28
|
-
return value;
|
|
29
|
-
}
|
|
30
|
-
function extractMultiLineValue(lines, startIndex) {
|
|
31
|
-
const valueLines = [];
|
|
32
|
-
let i = startIndex + 1;
|
|
33
|
-
while (i < lines.length) {
|
|
34
|
-
const line = lines[i];
|
|
35
|
-
if (line.length > 0 && !line.startsWith(" ") && !line.startsWith("\t")) {
|
|
36
|
-
break;
|
|
37
|
-
}
|
|
38
|
-
valueLines.push(line);
|
|
39
|
-
i += 1;
|
|
40
|
-
}
|
|
41
|
-
return { value: valueLines.join("\n").trim(), linesConsumed: i - startIndex };
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Parse a YAML-like frontmatter block into a flat key→value record.
|
|
45
|
-
* Uses a lightweight line parser to avoid a YAML library dependency.
|
|
46
|
-
*/
|
|
47
|
-
export function parseFrontmatter(content) {
|
|
48
|
-
const block = extractFrontmatterBlock(content);
|
|
49
|
-
if (!block) {
|
|
50
|
-
return {};
|
|
51
|
-
}
|
|
52
|
-
const result = {};
|
|
53
|
-
const lines = block.split("\n");
|
|
54
|
-
let i = 0;
|
|
55
|
-
while (i < lines.length) {
|
|
56
|
-
const line = lines[i];
|
|
57
|
-
const match = line.match(/^([\w-]+):\s*(.*)$/);
|
|
58
|
-
if (!match) {
|
|
59
|
-
i += 1;
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
const key = match[1];
|
|
63
|
-
const inlineValue = match[2].trim();
|
|
64
|
-
if (!key) {
|
|
65
|
-
i += 1;
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
// Check for multi-line value
|
|
69
|
-
if (!inlineValue && i + 1 < lines.length) {
|
|
70
|
-
const nextLine = lines[i + 1];
|
|
71
|
-
if (nextLine.startsWith(" ") || nextLine.startsWith("\t")) {
|
|
72
|
-
const { value, linesConsumed } = extractMultiLineValue(lines, i);
|
|
73
|
-
if (value) {
|
|
74
|
-
result[key] = value;
|
|
75
|
-
}
|
|
76
|
-
i += linesConsumed;
|
|
77
|
-
continue;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
const value = stripQuotes(inlineValue);
|
|
81
|
-
if (value) {
|
|
82
|
-
result[key] = value;
|
|
83
|
-
}
|
|
84
|
-
i += 1;
|
|
85
|
-
}
|
|
86
|
-
return result;
|
|
87
|
-
}
|
|
88
|
-
// ---------------------------------------------------------------------------
|
|
89
|
-
// Metadata resolver (from `metadata:` JSON block)
|
|
90
|
-
// ---------------------------------------------------------------------------
|
|
91
|
-
function parseMetadataJson(raw) {
|
|
92
|
-
// Try direct JSON first: `metadata: {"openclaw": {...}}`
|
|
93
|
-
try {
|
|
94
|
-
const parsed = JSON.parse(raw);
|
|
95
|
-
if (parsed && typeof parsed === "object") {
|
|
96
|
-
const obj = parsed;
|
|
97
|
-
const nested = obj["openclaw"];
|
|
98
|
-
if (nested && typeof nested === "object") {
|
|
99
|
-
return nested;
|
|
100
|
-
}
|
|
101
|
-
return obj;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
catch {
|
|
105
|
-
// Not JSON — fall through to YAML-like parser
|
|
106
|
-
}
|
|
107
|
-
// Handle YAML-like multi-line: `key: value` per line
|
|
108
|
-
return parseYamlLikeMetadata(raw);
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Parse simple YAML-like `key: value` lines where values may be JSON
|
|
112
|
-
* literals (objects, arrays, booleans, numbers) or plain strings.
|
|
113
|
-
*/
|
|
114
|
-
function parseYamlLikeMetadata(raw) {
|
|
115
|
-
const result = {};
|
|
116
|
-
let found = false;
|
|
117
|
-
for (const line of raw.split("\n")) {
|
|
118
|
-
const trimmed = line.trim();
|
|
119
|
-
if (!trimmed)
|
|
120
|
-
continue;
|
|
121
|
-
const m = trimmed.match(/^([\w-]+):\s*(.+)$/);
|
|
122
|
-
if (!m)
|
|
123
|
-
continue;
|
|
124
|
-
const key = m[1];
|
|
125
|
-
const val = m[2].trim();
|
|
126
|
-
found = true;
|
|
127
|
-
// Try JSON parse for objects / arrays / booleans / numbers
|
|
128
|
-
try {
|
|
129
|
-
result[key] = JSON.parse(val);
|
|
130
|
-
}
|
|
131
|
-
catch {
|
|
132
|
-
// Plain string — normalise booleans / numbers
|
|
133
|
-
if (val === "true")
|
|
134
|
-
result[key] = true;
|
|
135
|
-
else if (val === "false")
|
|
136
|
-
result[key] = false;
|
|
137
|
-
else if (/^-?\d+(\.\d+)?$/.test(val))
|
|
138
|
-
result[key] = Number(val);
|
|
139
|
-
else
|
|
140
|
-
result[key] = val;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return found ? result : undefined;
|
|
144
|
-
}
|
|
145
|
-
function normalizeStringList(input) {
|
|
146
|
-
if (!input)
|
|
147
|
-
return [];
|
|
148
|
-
if (Array.isArray(input)) {
|
|
149
|
-
return input.map((v) => String(v).trim()).filter(Boolean);
|
|
150
|
-
}
|
|
151
|
-
if (typeof input === "string") {
|
|
152
|
-
return input
|
|
153
|
-
.split(",")
|
|
154
|
-
.map((v) => v.trim())
|
|
155
|
-
.filter(Boolean);
|
|
156
|
-
}
|
|
157
|
-
return [];
|
|
158
|
-
}
|
|
159
|
-
function parseBool(value, fallback) {
|
|
160
|
-
if (value === undefined)
|
|
161
|
-
return fallback;
|
|
162
|
-
const lower = value.toLowerCase().trim();
|
|
163
|
-
if (lower === "true" || lower === "1" || lower === "yes")
|
|
164
|
-
return true;
|
|
165
|
-
if (lower === "false" || lower === "0" || lower === "no")
|
|
166
|
-
return false;
|
|
167
|
-
return fallback;
|
|
168
|
-
}
|
|
169
|
-
// ---------------------------------------------------------------------------
|
|
170
|
-
// Install spec validation (safe input normalization)
|
|
171
|
-
// ---------------------------------------------------------------------------
|
|
172
|
-
const BREW_FORMULA_PATTERN = /^[A-Za-z0-9][A-Za-z0-9@+._/-]*$/;
|
|
173
|
-
const GO_MODULE_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._~+\-/]*(?:@[A-Za-z0-9][A-Za-z0-9._~+\-/]*)?$/;
|
|
174
|
-
const UV_PACKAGE_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._\-[\]=<>!~+,]*$/;
|
|
175
|
-
const NPM_SPEC_PATTERN = /^(@[a-z0-9][\w.\-]*\/)?[a-z0-9][\w.\-]*(@[~^]?[\d.*]+[\w.\-+]*)?$/;
|
|
176
|
-
function normalizeSafeBrewFormula(raw) {
|
|
177
|
-
if (typeof raw !== "string")
|
|
178
|
-
return undefined;
|
|
179
|
-
const formula = raw.trim();
|
|
180
|
-
if (!formula || formula.startsWith("-") || formula.includes("\\") || formula.includes("..")) {
|
|
181
|
-
return undefined;
|
|
182
|
-
}
|
|
183
|
-
return BREW_FORMULA_PATTERN.test(formula) ? formula : undefined;
|
|
184
|
-
}
|
|
185
|
-
function normalizeSafeNpmSpec(raw) {
|
|
186
|
-
if (typeof raw !== "string")
|
|
187
|
-
return undefined;
|
|
188
|
-
const spec = raw.trim();
|
|
189
|
-
if (!spec || spec.startsWith("-"))
|
|
190
|
-
return undefined;
|
|
191
|
-
return NPM_SPEC_PATTERN.test(spec) ? spec : undefined;
|
|
192
|
-
}
|
|
193
|
-
function normalizeSafeGoModule(raw) {
|
|
194
|
-
if (typeof raw !== "string")
|
|
195
|
-
return undefined;
|
|
196
|
-
const mod = raw.trim();
|
|
197
|
-
if (!mod || mod.startsWith("-") || mod.includes("\\") || mod.includes("://"))
|
|
198
|
-
return undefined;
|
|
199
|
-
return GO_MODULE_PATTERN.test(mod) ? mod : undefined;
|
|
200
|
-
}
|
|
201
|
-
function normalizeSafeUvPackage(raw) {
|
|
202
|
-
if (typeof raw !== "string")
|
|
203
|
-
return undefined;
|
|
204
|
-
const pkg = raw.trim();
|
|
205
|
-
if (!pkg || pkg.startsWith("-") || pkg.includes("\\") || pkg.includes("://"))
|
|
206
|
-
return undefined;
|
|
207
|
-
return UV_PACKAGE_PATTERN.test(pkg) ? pkg : undefined;
|
|
208
|
-
}
|
|
209
|
-
function normalizeSafeDownloadUrl(raw) {
|
|
210
|
-
if (typeof raw !== "string")
|
|
211
|
-
return undefined;
|
|
212
|
-
const value = raw.trim();
|
|
213
|
-
if (!value || /\s/.test(value))
|
|
214
|
-
return undefined;
|
|
215
|
-
try {
|
|
216
|
-
const parsed = new URL(value);
|
|
217
|
-
if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
|
|
218
|
-
return undefined;
|
|
219
|
-
return parsed.toString();
|
|
220
|
-
}
|
|
221
|
-
catch {
|
|
222
|
-
return undefined;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
function parseInstallSpec(input) {
|
|
226
|
-
if (!input || typeof input !== "object")
|
|
227
|
-
return undefined;
|
|
228
|
-
const raw = input;
|
|
229
|
-
const kindRaw = typeof raw.kind === "string" ? raw.kind : typeof raw.type === "string" ? raw.type : "";
|
|
230
|
-
const kind = kindRaw.trim().toLowerCase();
|
|
231
|
-
const ALLOWED_KINDS = ["brew", "node", "go", "uv", "download"];
|
|
232
|
-
if (!ALLOWED_KINDS.includes(kind))
|
|
233
|
-
return undefined;
|
|
234
|
-
const spec = { kind: kind };
|
|
235
|
-
if (typeof raw.id === "string")
|
|
236
|
-
spec.id = raw.id;
|
|
237
|
-
if (typeof raw.label === "string")
|
|
238
|
-
spec.label = raw.label;
|
|
239
|
-
const bins = normalizeStringList(raw.bins);
|
|
240
|
-
if (bins.length > 0)
|
|
241
|
-
spec.bins = bins;
|
|
242
|
-
const osList = normalizeStringList(raw.os);
|
|
243
|
-
if (osList.length > 0)
|
|
244
|
-
spec.os = osList;
|
|
245
|
-
// Kind-specific fields
|
|
246
|
-
const formula = normalizeSafeBrewFormula(raw.formula) ?? normalizeSafeBrewFormula(raw.cask);
|
|
247
|
-
if (formula)
|
|
248
|
-
spec.formula = formula;
|
|
249
|
-
if (kind === "node") {
|
|
250
|
-
const pkg = normalizeSafeNpmSpec(raw.package);
|
|
251
|
-
if (pkg)
|
|
252
|
-
spec.package = pkg;
|
|
253
|
-
}
|
|
254
|
-
else if (kind === "uv") {
|
|
255
|
-
const pkg = normalizeSafeUvPackage(raw.package);
|
|
256
|
-
if (pkg)
|
|
257
|
-
spec.package = pkg;
|
|
258
|
-
}
|
|
259
|
-
const mod = normalizeSafeGoModule(raw.module);
|
|
260
|
-
if (mod)
|
|
261
|
-
spec.module = mod;
|
|
262
|
-
const url = normalizeSafeDownloadUrl(raw.url);
|
|
263
|
-
if (url)
|
|
264
|
-
spec.url = url;
|
|
265
|
-
if (typeof raw.archive === "string")
|
|
266
|
-
spec.archive = raw.archive;
|
|
267
|
-
if (typeof raw.extract === "boolean")
|
|
268
|
-
spec.extract = raw.extract;
|
|
269
|
-
if (typeof raw.stripComponents === "number")
|
|
270
|
-
spec.stripComponents = raw.stripComponents;
|
|
271
|
-
if (typeof raw.targetDir === "string")
|
|
272
|
-
spec.targetDir = raw.targetDir;
|
|
273
|
-
// Validate required field per kind
|
|
274
|
-
if (kind === "brew" && !spec.formula)
|
|
275
|
-
return undefined;
|
|
276
|
-
if (kind === "node" && !spec.package)
|
|
277
|
-
return undefined;
|
|
278
|
-
if (kind === "go" && !spec.module)
|
|
279
|
-
return undefined;
|
|
280
|
-
if (kind === "uv" && !spec.package)
|
|
281
|
-
return undefined;
|
|
282
|
-
if (kind === "download" && !spec.url)
|
|
283
|
-
return undefined;
|
|
284
|
-
return spec;
|
|
285
|
-
}
|
|
286
|
-
// ---------------------------------------------------------------------------
|
|
287
|
-
// Public API
|
|
288
|
-
// ---------------------------------------------------------------------------
|
|
289
|
-
/**
|
|
290
|
-
* Resolve structured metadata from the `metadata:` frontmatter field.
|
|
291
|
-
* Expects `metadata: {"openclaw": {...}}` (JSON format).
|
|
292
|
-
*/
|
|
293
|
-
export function resolveSkillMetadata(frontmatter) {
|
|
294
|
-
const raw = frontmatter["metadata"];
|
|
295
|
-
if (!raw)
|
|
296
|
-
return undefined;
|
|
297
|
-
const metadataObj = parseMetadataJson(raw);
|
|
298
|
-
if (!metadataObj)
|
|
299
|
-
return undefined;
|
|
300
|
-
const requiresRaw = typeof metadataObj.requires === "object" && metadataObj.requires !== null
|
|
301
|
-
? metadataObj.requires
|
|
302
|
-
: undefined;
|
|
303
|
-
const requires = requiresRaw
|
|
304
|
-
? {
|
|
305
|
-
bins: normalizeStringList(requiresRaw.bins),
|
|
306
|
-
anyBins: normalizeStringList(requiresRaw.anyBins),
|
|
307
|
-
env: normalizeStringList(requiresRaw.env),
|
|
308
|
-
config: normalizeStringList(requiresRaw.config),
|
|
309
|
-
}
|
|
310
|
-
: undefined;
|
|
311
|
-
const installRaw = Array.isArray(metadataObj.install)
|
|
312
|
-
? metadataObj.install
|
|
313
|
-
: [];
|
|
314
|
-
const install = installRaw
|
|
315
|
-
.map((entry) => parseInstallSpec(entry))
|
|
316
|
-
.filter((entry) => Boolean(entry));
|
|
317
|
-
const osRaw = normalizeStringList(metadataObj.os);
|
|
318
|
-
return {
|
|
319
|
-
always: typeof metadataObj.always === "boolean" ? metadataObj.always : undefined,
|
|
320
|
-
emoji: typeof metadataObj.emoji === "string" ? metadataObj.emoji : undefined,
|
|
321
|
-
homepage: typeof metadataObj.homepage === "string" ? metadataObj.homepage : undefined,
|
|
322
|
-
skillKey: typeof metadataObj.skillKey === "string" ? metadataObj.skillKey : undefined,
|
|
323
|
-
primaryEnv: typeof metadataObj.primaryEnv === "string" ? metadataObj.primaryEnv : undefined,
|
|
324
|
-
os: osRaw.length > 0 ? osRaw : undefined,
|
|
325
|
-
category: typeof metadataObj.category === "string" ? metadataObj.category : undefined,
|
|
326
|
-
requires,
|
|
327
|
-
install: install.length > 0 ? install : undefined,
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
/**
|
|
331
|
-
* Resolve invocation policy from frontmatter fields.
|
|
332
|
-
*/
|
|
333
|
-
export function resolveSkillInvocationPolicy(frontmatter) {
|
|
334
|
-
return {
|
|
335
|
-
userInvocable: parseBool(frontmatter["user-invocable"], true),
|
|
336
|
-
disableModelInvocation: parseBool(frontmatter["disable-model-invocation"], false),
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
/**
|
|
340
|
-
* Get the canonical key for a skill (metadata.skillKey or skill.name).
|
|
341
|
-
*/
|
|
342
|
-
export function resolveSkillKey(skillName, metadata) {
|
|
343
|
-
return metadata?.skillKey ?? skillName;
|
|
344
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { SkillFsDeps, SkillPathDeps, SkillScanFinding, SkillScanOptions, SkillScanSummary } from "./skill-types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Scan a source string for security findings.
|
|
4
|
-
* This is a pure function — no file I/O.
|
|
5
|
-
*/
|
|
6
|
-
export declare function scanSource(source: string, filePath: string): SkillScanFinding[];
|
|
7
|
-
export interface SkillGuardDeps {
|
|
8
|
-
fs: SkillFsDeps;
|
|
9
|
-
path: SkillPathDeps;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Scan an entire skill directory for security issues.
|
|
13
|
-
* Returns a summary with per-file findings.
|
|
14
|
-
*/
|
|
15
|
-
export declare function scanSkillDirectory(deps: SkillGuardDeps, skillDir: string, opts?: SkillScanOptions): Promise<SkillScanSummary>;
|
|
16
|
-
/**
|
|
17
|
-
* Quick check: does this source have any critical findings?
|
|
18
|
-
*/
|
|
19
|
-
export declare function hasCriticalFindings(source: string, filePath: string): boolean;
|
|
20
|
-
/**
|
|
21
|
-
* Check if a file extension is scannable by the guard.
|
|
22
|
-
*/
|
|
23
|
-
export declare function isScannable(filePath: string, pathDeps: SkillPathDeps): boolean;
|