pi-harness-runtime 1.1.94 → 1.1.96
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/CHANGELOG.md +33 -0
- package/harness/e2e/chatgpt-quota-scraper.ts +28 -4
- package/harness/loop-runtime.ts +3 -0
- package/index.ts +130 -29
- package/package.json +2 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/dist/client.d.ts +51 -0
- package/packages/qdrant-skills/dist/client.d.ts.map +1 -0
- package/packages/qdrant-skills/dist/client.js +105 -0
- package/packages/qdrant-skills/dist/client.js.map +1 -0
- package/packages/qdrant-skills/dist/embedder.d.ts +39 -0
- package/packages/qdrant-skills/dist/embedder.d.ts.map +1 -0
- package/packages/qdrant-skills/dist/embedder.js +101 -0
- package/packages/qdrant-skills/dist/embedder.js.map +1 -0
- package/packages/qdrant-skills/dist/index.d.ts +25 -0
- package/packages/qdrant-skills/dist/index.d.ts.map +1 -0
- package/packages/qdrant-skills/dist/index.js +25 -0
- package/packages/qdrant-skills/dist/index.js.map +1 -0
- package/packages/qdrant-skills/package.json +27 -0
- package/packages/qdrant-skills/src/client.ts +178 -0
- package/packages/qdrant-skills/src/embedder.ts +137 -0
- package/packages/qdrant-skills/src/index.ts +42 -0
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/skills/dist/index.d.ts +40 -0
- package/packages/skills/dist/index.d.ts.map +1 -0
- package/packages/skills/dist/index.js +82 -0
- package/packages/skills/dist/index.js.map +1 -0
- package/packages/skills/dist/linter.d.ts +38 -0
- package/packages/skills/dist/linter.d.ts.map +1 -0
- package/packages/skills/dist/linter.js +323 -0
- package/packages/skills/dist/linter.js.map +1 -0
- package/packages/skills/dist/loader.d.ts +74 -0
- package/packages/skills/dist/loader.d.ts.map +1 -0
- package/packages/skills/dist/loader.js +280 -0
- package/packages/skills/dist/loader.js.map +1 -0
- package/packages/skills/dist/parser.d.ts +32 -0
- package/packages/skills/dist/parser.d.ts.map +1 -0
- package/packages/skills/dist/parser.js +459 -0
- package/packages/skills/dist/parser.js.map +1 -0
- package/packages/skills/dist/scanner.d.ts +33 -0
- package/packages/skills/dist/scanner.d.ts.map +1 -0
- package/packages/skills/dist/scanner.js +257 -0
- package/packages/skills/dist/scanner.js.map +1 -0
- package/packages/skills/dist/skill-commands.d.ts +33 -0
- package/packages/skills/dist/skill-commands.d.ts.map +1 -0
- package/packages/skills/dist/skill-commands.js +239 -0
- package/packages/skills/dist/skill-commands.js.map +1 -0
- package/packages/skills/dist/skill-tool.d.ts +120 -0
- package/packages/skills/dist/skill-tool.d.ts.map +1 -0
- package/packages/skills/dist/skill-tool.js +239 -0
- package/packages/skills/dist/skill-tool.js.map +1 -0
- package/packages/skills/dist/skill-versioning.d.ts +123 -0
- package/packages/skills/dist/skill-versioning.d.ts.map +1 -0
- package/packages/skills/dist/skill-versioning.js +240 -0
- package/packages/skills/dist/skill-versioning.js.map +1 -0
- package/packages/skills/dist/types.d.ts +226 -0
- package/packages/skills/dist/types.d.ts.map +1 -0
- package/packages/skills/dist/types.js +21 -0
- package/packages/skills/dist/types.js.map +1 -0
- package/packages/skills/package.json +46 -0
- package/packages/skills/src/index.ts +93 -0
- package/packages/skills/src/linter.ts +371 -0
- package/packages/skills/src/loader.ts +335 -0
- package/packages/skills/src/parser.ts +548 -0
- package/packages/skills/src/scanner.ts +322 -0
- package/packages/skills/src/skill-commands.ts +318 -0
- package/packages/skills/src/skill-tool.ts +324 -0
- package/packages/skills/src/skill-versioning.ts +345 -0
- package/packages/skills/src/types.ts +259 -0
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/trajectory/dist/src/curator.d.ts +189 -0
- package/packages/trajectory/dist/src/curator.d.ts.map +1 -0
- package/packages/trajectory/dist/src/curator.js +340 -0
- package/packages/trajectory/dist/src/curator.js.map +1 -0
- package/packages/trajectory/dist/src/journey-renderer.d.ts +53 -0
- package/packages/trajectory/dist/src/journey-renderer.d.ts.map +1 -0
- package/packages/trajectory/dist/src/journey-renderer.js +324 -0
- package/packages/trajectory/dist/src/journey-renderer.js.map +1 -0
- package/packages/trajectory/dist/src/learning-graph.d.ts +159 -0
- package/packages/trajectory/dist/src/learning-graph.d.ts.map +1 -0
- package/packages/trajectory/dist/src/learning-graph.js +258 -0
- package/packages/trajectory/dist/src/learning-graph.js.map +1 -0
- package/packages/trajectory/dist/src/memory-store.d.ts +146 -0
- package/packages/trajectory/dist/src/memory-store.d.ts.map +1 -0
- package/packages/trajectory/dist/src/memory-store.js +472 -0
- package/packages/trajectory/dist/src/memory-store.js.map +1 -0
- package/packages/trajectory/dist/src/review-fork.d.ts +164 -0
- package/packages/trajectory/dist/src/review-fork.d.ts.map +1 -0
- package/packages/trajectory/dist/src/review-fork.js +332 -0
- package/packages/trajectory/dist/src/review-fork.js.map +1 -0
- package/packages/trajectory/dist/src/write-approval.d.ts +136 -0
- package/packages/trajectory/dist/src/write-approval.d.ts.map +1 -0
- package/packages/trajectory/dist/src/write-approval.js +281 -0
- package/packages/trajectory/dist/src/write-approval.js.map +1 -0
- package/packages/trajectory/package.json +1 -1
- package/packages/trajectory/src/curator.ts +485 -0
- package/packages/trajectory/src/journey-renderer.ts +399 -0
- package/packages/trajectory/src/learning-graph.ts +363 -0
- package/packages/trajectory/src/memory-store.ts +578 -0
- package/packages/trajectory/src/review-fork.ts +450 -0
- package/packages/trajectory/src/write-approval.ts +372 -0
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/dist/blackboard.d.ts +98 -0
- package/packages/write-review/dist/blackboard.d.ts.map +1 -0
- package/packages/write-review/dist/blackboard.js +289 -0
- package/packages/write-review/dist/blackboard.js.map +1 -0
- package/packages/write-review/dist/event-bus.d.ts +106 -0
- package/packages/write-review/dist/event-bus.d.ts.map +1 -0
- package/packages/write-review/dist/event-bus.js +294 -0
- package/packages/write-review/dist/event-bus.js.map +1 -0
- package/packages/write-review/dist/gate.d.ts +37 -0
- package/packages/write-review/dist/gate.d.ts.map +1 -0
- package/packages/write-review/dist/gate.js +138 -0
- package/packages/write-review/dist/gate.js.map +1 -0
- package/packages/write-review/dist/index.d.ts +22 -0
- package/packages/write-review/dist/index.d.ts.map +1 -0
- package/packages/write-review/dist/index.js +60 -0
- package/packages/write-review/dist/index.js.map +1 -0
- package/packages/write-review/dist/injection.d.ts +40 -0
- package/packages/write-review/dist/injection.d.ts.map +1 -0
- package/packages/write-review/dist/injection.js +179 -0
- package/packages/write-review/dist/injection.js.map +1 -0
- package/packages/write-review/dist/review.d.ts +54 -0
- package/packages/write-review/dist/review.d.ts.map +1 -0
- package/packages/write-review/dist/review.js +154 -0
- package/packages/write-review/dist/review.js.map +1 -0
- package/packages/write-review/dist/trigger.d.ts +39 -0
- package/packages/write-review/dist/trigger.d.ts.map +1 -0
- package/packages/write-review/dist/trigger.js +107 -0
- package/packages/write-review/dist/trigger.js.map +1 -0
- package/packages/write-review/dist/types.d.ts +78 -0
- package/packages/write-review/dist/types.d.ts.map +1 -0
- package/packages/write-review/dist/types.js +26 -0
- package/packages/write-review/dist/types.js.map +1 -0
- package/packages/write-review/package.json +1 -1
- package/packages/write-review/src/event-bus.ts +351 -0
- package/packages/write-review/src/index.ts +1 -0
- package/packages/write-review/src/injection.ts +25 -3
- package/proactive-compact.ts +51 -7
- package/scripts/sync-skills.ts +275 -0
- package/scripts/sync-to-qdrant.ts +398 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Qdrant Skills Package
|
|
3
|
+
*
|
|
4
|
+
* Vector search integration for Hermes-style skill system.
|
|
5
|
+
* Uses Qdrant Cloud with built-in sentence-transformers inference.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { createQdrantClient, searchSkills, upsertSkills } from '@pi-harness/qdrant-skills';
|
|
10
|
+
*
|
|
11
|
+
* const client = createQdrantClient({
|
|
12
|
+
* url: process.env.QDRANT_CLUSTER_ENDPOINT!,
|
|
13
|
+
* apiKey: process.env.QDRANT_API_KEY!,
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* // Search for skills
|
|
17
|
+
* const results = await searchSkills(client, 'my-skills', 'frappe permissions');
|
|
18
|
+
*
|
|
19
|
+
* // Upload skills
|
|
20
|
+
* await upsertSkills(client, 'my-skills', [{ id: 1, name: 'test', description: '...', body: '...', text: '...' }]);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export { createQdrantClient, createCollection, deleteCollection, upsertSkills, searchSkills, getAllSkills, type QdrantConfig, type SkillPoint, type SearchResult, } from './client.js';
|
|
24
|
+
export { createEmbedding, embedSkillDocument, embedSkillsBatch, getOpenAIApiKey, type EmbeddingResult, } from './embedder.js';
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Qdrant Skills Package
|
|
3
|
+
*
|
|
4
|
+
* Vector search integration for Hermes-style skill system.
|
|
5
|
+
* Uses Qdrant Cloud with built-in sentence-transformers inference.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { createQdrantClient, searchSkills, upsertSkills } from '@pi-harness/qdrant-skills';
|
|
10
|
+
*
|
|
11
|
+
* const client = createQdrantClient({
|
|
12
|
+
* url: process.env.QDRANT_CLUSTER_ENDPOINT!,
|
|
13
|
+
* apiKey: process.env.QDRANT_API_KEY!,
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* // Search for skills
|
|
17
|
+
* const results = await searchSkills(client, 'my-skills', 'frappe permissions');
|
|
18
|
+
*
|
|
19
|
+
* // Upload skills
|
|
20
|
+
* await upsertSkills(client, 'my-skills', [{ id: 1, name: 'test', description: '...', body: '...', text: '...' }]);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export { createQdrantClient, createCollection, deleteCollection, upsertSkills, searchSkills, getAllSkills, } from './client.js';
|
|
24
|
+
export { createEmbedding, embedSkillDocument, embedSkillsBatch, getOpenAIApiKey, } from './embedder.js';
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,YAAY,GAIb,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,GAEhB,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pi-harness/qdrant-skills",
|
|
3
|
+
"version": "1.1.96",
|
|
4
|
+
"description": "Qdrant vector search integration for Hermes-style skill system",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/index.js",
|
|
10
|
+
"./client": "./dist/client.js",
|
|
11
|
+
"./embedder": "./dist/embedder.js"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"test": "echo \"No tests yet\" && exit 0"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@qdrant/js-client-rest": "^1.19.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "^20.0.0",
|
|
22
|
+
"typescript": "^5.0.0"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"@earendil-works/pi-coding-agent": "*"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Qdrant Client - Official @qdrant/js-client-rest wrapper
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { QdrantClient } from "@qdrant/js-client-rest";
|
|
6
|
+
|
|
7
|
+
export interface QdrantConfig {
|
|
8
|
+
/** Qdrant cluster URL (e.g., https://xxx.qdrant.tech) */
|
|
9
|
+
url: string;
|
|
10
|
+
/** API key for authentication */
|
|
11
|
+
apiKey: string;
|
|
12
|
+
/** Collection name (default: 'pi-harness-skills') */
|
|
13
|
+
collection?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface SkillPoint {
|
|
17
|
+
id: number;
|
|
18
|
+
name: string;
|
|
19
|
+
description: string;
|
|
20
|
+
body: string;
|
|
21
|
+
/** Full text to embed */
|
|
22
|
+
text: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface SearchResult {
|
|
26
|
+
id: number;
|
|
27
|
+
name: string;
|
|
28
|
+
description: string;
|
|
29
|
+
score: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parse host:port from URL
|
|
34
|
+
*/
|
|
35
|
+
function parseHostPort(url: string): { host: string; port: number } {
|
|
36
|
+
const match = url.match(/https?:\/\/([^:]+)(?::(\d+))?/);
|
|
37
|
+
return {
|
|
38
|
+
host: match?.[1] || url,
|
|
39
|
+
port: parseInt(match?.[2] || "6333"),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Create a Qdrant client
|
|
45
|
+
*/
|
|
46
|
+
export function createQdrantClient(config: QdrantConfig): QdrantClient {
|
|
47
|
+
const { host, port } = parseHostPort(config.url);
|
|
48
|
+
return new QdrantClient({ host, port, apiKey: config.apiKey });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Create a collection with dense vectors
|
|
53
|
+
*/
|
|
54
|
+
export async function createCollection(
|
|
55
|
+
client: QdrantClient,
|
|
56
|
+
name: string,
|
|
57
|
+
dimensions: number = 384 // all-MiniLM-L6-v2
|
|
58
|
+
): Promise<void> {
|
|
59
|
+
try {
|
|
60
|
+
await client.createCollection(name, {
|
|
61
|
+
vectors: { size: dimensions, distance: "Cosine" },
|
|
62
|
+
});
|
|
63
|
+
} catch (err) {
|
|
64
|
+
// Ignore "already exists" errors
|
|
65
|
+
if (err instanceof Error && !err.message.includes("already exists")) {
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Delete a collection
|
|
73
|
+
*/
|
|
74
|
+
export async function deleteCollection(
|
|
75
|
+
client: QdrantClient,
|
|
76
|
+
name: string
|
|
77
|
+
): Promise<void> {
|
|
78
|
+
try {
|
|
79
|
+
await client.deleteCollection(name);
|
|
80
|
+
} catch {
|
|
81
|
+
// Ignore if not exists
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Upsert skill points with cloud inference
|
|
87
|
+
*/
|
|
88
|
+
export async function upsertSkills(
|
|
89
|
+
client: QdrantClient,
|
|
90
|
+
collectionName: string,
|
|
91
|
+
skills: SkillPoint[],
|
|
92
|
+
model: string = "sentence-transformers/all-MiniLM-L6-v2"
|
|
93
|
+
): Promise<void> {
|
|
94
|
+
const points = skills.map((skill, idx) => ({
|
|
95
|
+
id: skill.id || idx + 1,
|
|
96
|
+
payload: {
|
|
97
|
+
name: skill.name,
|
|
98
|
+
description: skill.description,
|
|
99
|
+
body: skill.body.slice(0, 2000),
|
|
100
|
+
},
|
|
101
|
+
vector: {
|
|
102
|
+
text: skill.text,
|
|
103
|
+
model,
|
|
104
|
+
},
|
|
105
|
+
}));
|
|
106
|
+
|
|
107
|
+
await client.upsert(collectionName, { wait: true, points });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Search skills with semantic query
|
|
112
|
+
*/
|
|
113
|
+
export async function searchSkills(
|
|
114
|
+
client: QdrantClient,
|
|
115
|
+
collectionName: string,
|
|
116
|
+
query: string,
|
|
117
|
+
model: string = "sentence-transformers/all-MiniLM-L6-v2",
|
|
118
|
+
limit: number = 5
|
|
119
|
+
): Promise<SearchResult[]> {
|
|
120
|
+
const results = await client.query(collectionName, {
|
|
121
|
+
query: { text: query, model },
|
|
122
|
+
limit,
|
|
123
|
+
with_payload: true,
|
|
124
|
+
} as Parameters<typeof client.query>[1]);
|
|
125
|
+
|
|
126
|
+
// Parse response: { result: { points: [...] } }
|
|
127
|
+
const typedResults = results as {
|
|
128
|
+
result?: {
|
|
129
|
+
points?: Array<{
|
|
130
|
+
id: number;
|
|
131
|
+
score: number;
|
|
132
|
+
payload?: Record<string, unknown>;
|
|
133
|
+
}>;
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const points = typedResults?.result?.points || [];
|
|
138
|
+
|
|
139
|
+
return points.map((point) => ({
|
|
140
|
+
id: point.id,
|
|
141
|
+
name: (point.payload?.name as string) || `skill-${point.id}`,
|
|
142
|
+
description: (point.payload?.description as string) || "",
|
|
143
|
+
score: point.score,
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Get all skills from collection
|
|
149
|
+
*/
|
|
150
|
+
export async function getAllSkills(
|
|
151
|
+
client: QdrantClient,
|
|
152
|
+
collectionName: string
|
|
153
|
+
): Promise<SearchResult[]> {
|
|
154
|
+
const results = await client.query(collectionName, {
|
|
155
|
+
filter: {}, // Empty filter = all
|
|
156
|
+
limit: 100,
|
|
157
|
+
with_payload: true,
|
|
158
|
+
} as Parameters<typeof client.query>[1]);
|
|
159
|
+
|
|
160
|
+
const typedResults = results as {
|
|
161
|
+
result?: {
|
|
162
|
+
points?: Array<{
|
|
163
|
+
id: number;
|
|
164
|
+
score: number;
|
|
165
|
+
payload?: Record<string, unknown>;
|
|
166
|
+
}>;
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const points = typedResults?.result?.points || [];
|
|
171
|
+
|
|
172
|
+
return points.map((point) => ({
|
|
173
|
+
id: point.id,
|
|
174
|
+
name: (point.payload?.name as string) || `skill-${point.id}`,
|
|
175
|
+
description: (point.payload?.description as string) || "",
|
|
176
|
+
score: point.score || 0,
|
|
177
|
+
}));
|
|
178
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Embedder
|
|
3
|
+
*
|
|
4
|
+
* Creates embeddings for skill content using OpenAI.
|
|
5
|
+
* Used to store skills in Qdrant for semantic search.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { SkillPoint } from "./client.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Embedding result
|
|
12
|
+
*/
|
|
13
|
+
export interface EmbeddingResult {
|
|
14
|
+
embedding: number[];
|
|
15
|
+
tokens: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Get OpenAI API key for embeddings
|
|
20
|
+
*/
|
|
21
|
+
export function getOpenAIApiKey(): string | null {
|
|
22
|
+
// Check env vars (same as Jev)
|
|
23
|
+
if (process.env.OPENAI_API_KEY) {
|
|
24
|
+
return process.env.OPENAI_API_KEY;
|
|
25
|
+
}
|
|
26
|
+
if (process.env.TYPESAFE_API_KEY) {
|
|
27
|
+
return process.env.TYPESAFE_API_KEY;
|
|
28
|
+
}
|
|
29
|
+
if (process.env.OPENROUTER_API_KEY) {
|
|
30
|
+
return process.env.OPENROUTER_API_KEY;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Check keys file
|
|
34
|
+
try {
|
|
35
|
+
const { existsSync, readFileSync } = require("node:fs");
|
|
36
|
+
const homedir = process.env.HOME || process.env.USERPROFILE || "/home/frappe";
|
|
37
|
+
const keyPath = `${homedir}/.pi-harness-runtime/keys/openai-api-key.txt`;
|
|
38
|
+
if (existsSync(keyPath)) {
|
|
39
|
+
return readFileSync(keyPath, "utf-8").trim();
|
|
40
|
+
}
|
|
41
|
+
} catch {
|
|
42
|
+
// ignore
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Create embedding for text using OpenAI
|
|
50
|
+
*/
|
|
51
|
+
export async function createEmbedding(
|
|
52
|
+
text: string,
|
|
53
|
+
apiKey?: string
|
|
54
|
+
): Promise<EmbeddingResult> {
|
|
55
|
+
const key = apiKey || getOpenAIApiKey();
|
|
56
|
+
if (!key) {
|
|
57
|
+
throw new Error("No OpenAI API key available for embeddings");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const response = await fetch("https://api.openai.com/v1/embeddings", {
|
|
61
|
+
method: "POST",
|
|
62
|
+
headers: {
|
|
63
|
+
"Content-Type": "application/json",
|
|
64
|
+
"Authorization": `Bearer ${key}`,
|
|
65
|
+
},
|
|
66
|
+
body: JSON.stringify({
|
|
67
|
+
model: "text-embedding-3-small",
|
|
68
|
+
input: text.slice(0, 8000), // Limit to avoid token limits
|
|
69
|
+
}),
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
const error = await response.text();
|
|
74
|
+
throw new Error(`OpenAI embedding failed: ${error}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const data = await response.json() as {
|
|
78
|
+
data: Array<{ embedding: number[] }>;
|
|
79
|
+
usage: { total_tokens: number };
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
embedding: data.data[0]?.embedding || [],
|
|
84
|
+
tokens: data.usage?.total_tokens || 0,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Create embedding for a skill document
|
|
90
|
+
*/
|
|
91
|
+
export async function embedSkillDocument(
|
|
92
|
+
skill: SkillPoint,
|
|
93
|
+
apiKey?: string
|
|
94
|
+
): Promise<{ id: number; embedding: number[]; payload: SkillPoint }> {
|
|
95
|
+
// Combine name and description for embedding
|
|
96
|
+
const textToEmbed = [skill.name, skill.description].join(". ");
|
|
97
|
+
|
|
98
|
+
const { embedding } = await createEmbedding(textToEmbed, apiKey);
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
id: skill.id,
|
|
102
|
+
embedding,
|
|
103
|
+
payload: skill,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Batch embed multiple skills
|
|
109
|
+
*/
|
|
110
|
+
export async function embedSkillsBatch(
|
|
111
|
+
skills: SkillPoint[],
|
|
112
|
+
apiKey?: string,
|
|
113
|
+
onProgress?: (index: number, total: number) => void
|
|
114
|
+
): Promise<Array<{ id: number; embedding: number[]; payload: SkillPoint }>> {
|
|
115
|
+
const results: Array<{ id: number; embedding: number[]; payload: SkillPoint }> = [];
|
|
116
|
+
|
|
117
|
+
for (let i = 0; i < skills.length; i++) {
|
|
118
|
+
const skill = skills[i];
|
|
119
|
+
try {
|
|
120
|
+
const result = await embedSkillDocument(skill, apiKey);
|
|
121
|
+
results.push(result);
|
|
122
|
+
} catch (err) {
|
|
123
|
+
console.error(`[QdrantSkills] Failed to embed skill ${skill.name}:`, err);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (onProgress) {
|
|
127
|
+
onProgress(i + 1, skills.length);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Small delay to avoid rate limiting
|
|
131
|
+
if (i < skills.length - 1) {
|
|
132
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return results;
|
|
137
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Qdrant Skills Package
|
|
3
|
+
*
|
|
4
|
+
* Vector search integration for Hermes-style skill system.
|
|
5
|
+
* Uses Qdrant Cloud with built-in sentence-transformers inference.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { createQdrantClient, searchSkills, upsertSkills } from '@pi-harness/qdrant-skills';
|
|
10
|
+
*
|
|
11
|
+
* const client = createQdrantClient({
|
|
12
|
+
* url: process.env.QDRANT_CLUSTER_ENDPOINT!,
|
|
13
|
+
* apiKey: process.env.QDRANT_API_KEY!,
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* // Search for skills
|
|
17
|
+
* const results = await searchSkills(client, 'my-skills', 'frappe permissions');
|
|
18
|
+
*
|
|
19
|
+
* // Upload skills
|
|
20
|
+
* await upsertSkills(client, 'my-skills', [{ id: 1, name: 'test', description: '...', body: '...', text: '...' }]);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export {
|
|
25
|
+
createQdrantClient,
|
|
26
|
+
createCollection,
|
|
27
|
+
deleteCollection,
|
|
28
|
+
upsertSkills,
|
|
29
|
+
searchSkills,
|
|
30
|
+
getAllSkills,
|
|
31
|
+
type QdrantConfig,
|
|
32
|
+
type SkillPoint,
|
|
33
|
+
type SearchResult,
|
|
34
|
+
} from './client.js';
|
|
35
|
+
|
|
36
|
+
export {
|
|
37
|
+
createEmbedding,
|
|
38
|
+
embedSkillDocument,
|
|
39
|
+
embedSkillsBatch,
|
|
40
|
+
getOpenAIApiKey,
|
|
41
|
+
type EmbeddingResult,
|
|
42
|
+
} from './embedder.js';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills Package - File-based skill system with pi.dev compatibility
|
|
3
|
+
*
|
|
4
|
+
* Implements Hermes-style self-improving skills with:
|
|
5
|
+
* - pi.dev Agent Skills specification compatibility
|
|
6
|
+
* - Progressive disclosure (lazy loading)
|
|
7
|
+
* - Background review and auto-improvement
|
|
8
|
+
* - Hermes-style linter for quality checks
|
|
9
|
+
*/
|
|
10
|
+
export * from "./types.js";
|
|
11
|
+
export * from "./parser.js";
|
|
12
|
+
export * from "./scanner.js";
|
|
13
|
+
export * from "./loader.js";
|
|
14
|
+
export * from "./skill-commands.js";
|
|
15
|
+
export * from "./skill-tool.js";
|
|
16
|
+
export * from "./skill-versioning.js";
|
|
17
|
+
export * from "./linter.js";
|
|
18
|
+
import type { SkillsConfig, ScanResult } from "./types.js";
|
|
19
|
+
/**
|
|
20
|
+
* Initialize skills system
|
|
21
|
+
*/
|
|
22
|
+
export declare function initSkills(config?: Partial<SkillsConfig & {
|
|
23
|
+
maxDepth?: number;
|
|
24
|
+
includeHidden?: boolean;
|
|
25
|
+
}>): ScanResult;
|
|
26
|
+
/**
|
|
27
|
+
* Get skills summary
|
|
28
|
+
*/
|
|
29
|
+
export declare function getSkillsSummary(): {
|
|
30
|
+
total: number;
|
|
31
|
+
loaded: number;
|
|
32
|
+
byAuthor: {
|
|
33
|
+
agent: number;
|
|
34
|
+
user: number;
|
|
35
|
+
curator: number;
|
|
36
|
+
unknown: number;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export declare const DEFAULT_SKILL_CONFIG: SkillsConfig;
|
|
40
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAe,MAAM,YAAY,CAAC;AAIxE;;GAEG;AACH,wBAAgB,UAAU,CACxB,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GAC9E,UAAU,CAkBZ;AAED;;GAEG;AACH,wBAAgB,gBAAgB;;;;;;;;;EAyB/B;AAGD,eAAO,MAAM,oBAAoB,EAAE,YAYlC,CAAC"}
|