@fly3366/deepjit 0.1.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/LICENSE +21 -0
- package/README.md +134 -0
- package/README.zh.md +126 -0
- package/cordis.patch.yml +16 -0
- package/dist/collector.d.ts +31 -0
- package/dist/collector.js +258 -0
- package/dist/collector.js.map +1 -0
- package/dist/compiler/optimize.d.ts +30 -0
- package/dist/compiler/optimize.js +47 -0
- package/dist/compiler/optimize.js.map +1 -0
- package/dist/compiler/tiering.d.ts +22 -0
- package/dist/compiler/tiering.js +20 -0
- package/dist/compiler/tiering.js.map +1 -0
- package/dist/config.d.ts +42 -0
- package/dist/config.js +42 -0
- package/dist/config.js.map +1 -0
- package/dist/feedback.d.ts +43 -0
- package/dist/feedback.js +172 -0
- package/dist/feedback.js.map +1 -0
- package/dist/flow-executor.d.ts +46 -0
- package/dist/flow-executor.js +184 -0
- package/dist/flow-executor.js.map +1 -0
- package/dist/genai.d.ts +27 -0
- package/dist/genai.js +57 -0
- package/dist/genai.js.map +1 -0
- package/dist/i18n.d.ts +40 -0
- package/dist/i18n.js +81 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +170 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics.d.ts +28 -0
- package/dist/metrics.js +68 -0
- package/dist/metrics.js.map +1 -0
- package/dist/miner.d.ts +14 -0
- package/dist/miner.js +93 -0
- package/dist/miner.js.map +1 -0
- package/dist/paths.d.ts +13 -0
- package/dist/paths.js +44 -0
- package/dist/paths.js.map +1 -0
- package/dist/status-tool.d.ts +21 -0
- package/dist/status-tool.js +113 -0
- package/dist/status-tool.js.map +1 -0
- package/dist/store.d.ts +122 -0
- package/dist/store.js +317 -0
- package/dist/store.js.map +1 -0
- package/dist/summarizer.d.ts +102 -0
- package/dist/summarizer.js +472 -0
- package/dist/summarizer.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"miner.js","sourceRoot":"","sources":["../src/miner.ts"],"names":[],"mappings":"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"}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
/** Resolve the dsh home directory (~/.dsh by default). */
|
|
3
|
+
export declare function resolveHome(ctx: Context): string;
|
|
4
|
+
export declare function resolveDirs(ctx: Context, config: {
|
|
5
|
+
dbPath?: string;
|
|
6
|
+
skillDir?: string;
|
|
7
|
+
flowDir?: string;
|
|
8
|
+
}): {
|
|
9
|
+
home: string;
|
|
10
|
+
dbPath: string;
|
|
11
|
+
skillDir: string;
|
|
12
|
+
flowDir: string;
|
|
13
|
+
};
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
/** Resolve the dsh home directory (~/.dsh by default). */
|
|
4
|
+
export function resolveHome(ctx) {
|
|
5
|
+
try {
|
|
6
|
+
const raw = ctx.dshHomePath;
|
|
7
|
+
if (typeof raw === 'string' && raw)
|
|
8
|
+
return raw;
|
|
9
|
+
if (typeof raw === 'function') {
|
|
10
|
+
for (const arg of ['', '/']) {
|
|
11
|
+
try {
|
|
12
|
+
const v = raw(arg);
|
|
13
|
+
if (typeof v === 'string' && v)
|
|
14
|
+
return v;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// fall through
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const v = raw();
|
|
22
|
+
if (typeof v === 'string' && v)
|
|
23
|
+
return v;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// fall through
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// dshHomePath not injectable in this baseline; fall back to env/home
|
|
32
|
+
}
|
|
33
|
+
return process.env.DSH_HOME ?? path.join(os.homedir(), '.dsh');
|
|
34
|
+
}
|
|
35
|
+
export function resolveDirs(ctx, config) {
|
|
36
|
+
const home = resolveHome(ctx);
|
|
37
|
+
return {
|
|
38
|
+
home,
|
|
39
|
+
dbPath: config.dbPath || path.join(home, 'deepjit', 'deepjit.db'),
|
|
40
|
+
skillDir: config.skillDir || path.join(home, 'deepjit', 'skills'),
|
|
41
|
+
flowDir: config.flowDir || path.join(home, 'deepjit', 'flows'),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,MAAM,SAAS,CAAA;AAGxB,0DAA0D;AAC1D,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,IAAI,CAAC;QACH,MAAM,GAAG,GAAI,GAA4C,CAAC,WAAW,CAAA;QACrE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG;YAAE,OAAO,GAAG,CAAA;QAC9C,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE,CAAC;YAC9B,KAAK,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC;oBACH,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;oBAClB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC;wBAAE,OAAO,CAAC,CAAA;gBAC1C,CAAC;gBAAC,MAAM,CAAC;oBACP,eAAe;gBACjB,CAAC;YACH,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,CAAC,GAAG,GAAG,EAAE,CAAA;gBACf,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC;oBAAE,OAAO,CAAC,CAAA;YAC1C,CAAC;YAAC,MAAM,CAAC;gBACP,eAAe;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qEAAqE;IACvE,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,CAAA;AAChE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAY,EAAE,MAAgE;IACxG,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IAC7B,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,CAAC;QACjE,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC;QACjE,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC;KAC/D,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { DeepJitStore } from './store.ts';
|
|
2
|
+
import { ArtifactFeedback } from './feedback.ts';
|
|
3
|
+
interface StatusArgs {
|
|
4
|
+
action: 'list' | 'show' | 'disable' | 'enable' | 'delete' | 'metrics';
|
|
5
|
+
type?: 'skill' | 'flow';
|
|
6
|
+
name?: string;
|
|
7
|
+
}
|
|
8
|
+
/** The deepjit_status tool: inspect and manage compiled artifacts. */
|
|
9
|
+
export declare class StatusTool {
|
|
10
|
+
private store;
|
|
11
|
+
private feedback;
|
|
12
|
+
private dirs;
|
|
13
|
+
private log;
|
|
14
|
+
constructor(store: DeepJitStore, feedback: ArtifactFeedback, dirs: {
|
|
15
|
+
skillDir: string;
|
|
16
|
+
flowDir: string;
|
|
17
|
+
}, log: (msg: string) => void);
|
|
18
|
+
get toolDefinition(): object;
|
|
19
|
+
private handle;
|
|
20
|
+
}
|
|
21
|
+
export type { StatusArgs };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { qualityScore } from "./store.js";
|
|
3
|
+
import { t } from "./i18n.js";
|
|
4
|
+
import { metrics } from "./metrics.js";
|
|
5
|
+
/** The deepjit_status tool: inspect and manage compiled artifacts. */
|
|
6
|
+
export class StatusTool {
|
|
7
|
+
store;
|
|
8
|
+
feedback;
|
|
9
|
+
dirs;
|
|
10
|
+
log;
|
|
11
|
+
constructor(store, feedback, dirs, log) {
|
|
12
|
+
this.store = store;
|
|
13
|
+
this.feedback = feedback;
|
|
14
|
+
this.dirs = dirs;
|
|
15
|
+
this.log = log;
|
|
16
|
+
}
|
|
17
|
+
get toolDefinition() {
|
|
18
|
+
return {
|
|
19
|
+
name: 'deepjit_status',
|
|
20
|
+
description: 'Inspect and manage deepjit JIT-compiled artifacts. list shows all skills and flows with their status; ' +
|
|
21
|
+
'show prints the file content; disable/enable toggle availability; delete removes the artifact.',
|
|
22
|
+
parameters: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: {
|
|
25
|
+
action: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
enum: ['list', 'show', 'disable', 'enable', 'delete', 'metrics'],
|
|
28
|
+
description: 'Operation to perform',
|
|
29
|
+
},
|
|
30
|
+
type: { type: 'string', enum: ['skill', 'flow'], description: 'Artifact type (list only)' },
|
|
31
|
+
name: { type: 'string', description: 'Artifact name, e.g. "deepjit-summarize-repo"' },
|
|
32
|
+
},
|
|
33
|
+
required: ['action'],
|
|
34
|
+
},
|
|
35
|
+
output: {
|
|
36
|
+
schema: { type: 'string' },
|
|
37
|
+
render: (_args, value) => [{ type: 'text', text: String(value) }],
|
|
38
|
+
},
|
|
39
|
+
execute: (args) => this.handle(args),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
handle(args) {
|
|
43
|
+
switch (args.action) {
|
|
44
|
+
case 'list': {
|
|
45
|
+
const rows = this.store.listArtifacts(args.type);
|
|
46
|
+
if (rows.length === 0)
|
|
47
|
+
return t('status.empty');
|
|
48
|
+
const lines = rows.map((r) => {
|
|
49
|
+
const fileOk = existsSync(r.file_path);
|
|
50
|
+
const q = qualityScore(r.use_count, r.success_count);
|
|
51
|
+
return `- [${r.status}] ${r.type} ${r.name} — ${r.description ?? ''} (quality: ${q}, uses: ${r.use_count}, ${fileOk ? 'file ok' : 'MISSING FILE'})`;
|
|
52
|
+
});
|
|
53
|
+
return `deepjit artifacts (${rows.length}):\n${lines.join('\n')}`;
|
|
54
|
+
}
|
|
55
|
+
case 'show': {
|
|
56
|
+
if (!args.name)
|
|
57
|
+
return t('status.nameRequired', { action: 'show' });
|
|
58
|
+
const row = this.store.getArtifact(args.name);
|
|
59
|
+
if (!row)
|
|
60
|
+
return t('status.unknown', { name: args.name });
|
|
61
|
+
if (!existsSync(row.file_path))
|
|
62
|
+
return t('status.fileMissing', { name: args.name, path: row.file_path });
|
|
63
|
+
const content = readFileSync(row.file_path, 'utf8');
|
|
64
|
+
return `# ${row.name}\nstatus: ${row.status}\npath: ${row.file_path}\n\n${content.slice(0, 6000)}`;
|
|
65
|
+
}
|
|
66
|
+
case 'disable': {
|
|
67
|
+
if (!args.name)
|
|
68
|
+
return t('status.nameRequired', { action: 'disable' });
|
|
69
|
+
const row = this.store.getArtifact(args.name);
|
|
70
|
+
if (!row)
|
|
71
|
+
return t('status.unknown', { name: args.name });
|
|
72
|
+
if (row.status === 'disabled')
|
|
73
|
+
return t('status.alreadyDisabled', { name: args.name });
|
|
74
|
+
this.feedback.disable(args.name);
|
|
75
|
+
this.store.updateArtifactStatus(args.name, 'disabled');
|
|
76
|
+
this.log(`deepjit: disabled artifact ${args.name}`);
|
|
77
|
+
return t('status.disabled', { name: args.name });
|
|
78
|
+
}
|
|
79
|
+
case 'enable': {
|
|
80
|
+
if (!args.name)
|
|
81
|
+
return t('status.nameRequired', { action: 'enable' });
|
|
82
|
+
const row = this.store.getArtifact(args.name);
|
|
83
|
+
if (!row)
|
|
84
|
+
return t('status.unknown', { name: args.name });
|
|
85
|
+
if (row.status === 'active')
|
|
86
|
+
return t('status.alreadyActive', { name: args.name });
|
|
87
|
+
this.feedback.enable(args.name);
|
|
88
|
+
this.store.updateArtifactStatus(args.name, 'active');
|
|
89
|
+
this.log(`deepjit: enabled artifact ${args.name}`);
|
|
90
|
+
return t('status.enabled', { name: args.name });
|
|
91
|
+
}
|
|
92
|
+
case 'delete': {
|
|
93
|
+
if (!args.name)
|
|
94
|
+
return t('status.nameRequired', { action: 'delete' });
|
|
95
|
+
const row = this.store.getArtifact(args.name);
|
|
96
|
+
if (!row)
|
|
97
|
+
return t('status.unknown', { name: args.name });
|
|
98
|
+
this.feedback.remove(args.name);
|
|
99
|
+
this.store.deleteArtifact(args.name);
|
|
100
|
+
this.log(`deepjit: deleted artifact ${args.name}`);
|
|
101
|
+
return t('status.deleted', { name: args.name });
|
|
102
|
+
}
|
|
103
|
+
case 'metrics': {
|
|
104
|
+
const snap = metrics.snapshot();
|
|
105
|
+
const lines = Object.entries(snap).map(([k, v]) => `${k}: ${v}`);
|
|
106
|
+
return lines.length ? `deepjit metrics:\n${lines.join('\n')}` : t('status.empty');
|
|
107
|
+
}
|
|
108
|
+
default:
|
|
109
|
+
return t('status.unknownAction', { action: args.action });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=status-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-tool.js","sourceRoot":"","sources":["../src/status-tool.ts"],"names":[],"mappings":"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"}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
export type TraceKind = 'user' | 'assistant' | 'tool' | 'boundary';
|
|
2
|
+
export interface TraceRow {
|
|
3
|
+
session_id: string;
|
|
4
|
+
turn: number;
|
|
5
|
+
step: number | null;
|
|
6
|
+
kind: TraceKind;
|
|
7
|
+
seq: number;
|
|
8
|
+
ts_ms: number;
|
|
9
|
+
payload: string;
|
|
10
|
+
}
|
|
11
|
+
export interface PatternRow {
|
|
12
|
+
id: number;
|
|
13
|
+
kind: string;
|
|
14
|
+
key: string;
|
|
15
|
+
count: number;
|
|
16
|
+
sessions_seen: number;
|
|
17
|
+
compiled: number;
|
|
18
|
+
sample_session: string;
|
|
19
|
+
first_seen_ms: number;
|
|
20
|
+
last_seen_ms: number;
|
|
21
|
+
}
|
|
22
|
+
export interface ArtifactRow {
|
|
23
|
+
id: number;
|
|
24
|
+
type: 'skill' | 'flow';
|
|
25
|
+
name: string;
|
|
26
|
+
title: string | null;
|
|
27
|
+
description: string | null;
|
|
28
|
+
file_path: string;
|
|
29
|
+
source_pattern_id: number | null;
|
|
30
|
+
status: 'active' | 'disabled';
|
|
31
|
+
feedback_mode: 'filesystem' | 'runtime' | null;
|
|
32
|
+
llm_provider: string | null;
|
|
33
|
+
llm_model: string | null;
|
|
34
|
+
summary: string | null;
|
|
35
|
+
created_ms: number;
|
|
36
|
+
updated_ms: number;
|
|
37
|
+
use_count: number;
|
|
38
|
+
last_used_ms: number | null;
|
|
39
|
+
success_count: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Heuristic artifact quality: success rate weighted by usage volume.
|
|
43
|
+
* log2 dampens volume so a rarely-used artifact isn't over-rated.
|
|
44
|
+
*/
|
|
45
|
+
export declare function qualityScore(useCount: number, successCount: number): number;
|
|
46
|
+
export declare class DeepJitStore {
|
|
47
|
+
private db;
|
|
48
|
+
constructor(dbPath: string);
|
|
49
|
+
private migrate;
|
|
50
|
+
upsertSession(sessionId: string, startedMs: number, cwd?: string): void;
|
|
51
|
+
touchSession(sessionId: string, endedMs: number): void;
|
|
52
|
+
setSessionContext(sessionId: string, provider?: string, model?: string): void;
|
|
53
|
+
getSessionWatermark(sessionId: string): {
|
|
54
|
+
last_seq: number;
|
|
55
|
+
last_summarized_seq: number;
|
|
56
|
+
};
|
|
57
|
+
/** Insert a batch of traces in one transaction and advance the session watermark. */
|
|
58
|
+
insertTraces(rows: TraceRow[]): void;
|
|
59
|
+
/** Tool / user traces after the summarization watermark, ordered by seq. */
|
|
60
|
+
readTracesSince(sessionId: string, fromSeq: number, kinds: TraceKind[], limit?: number): TraceRow[];
|
|
61
|
+
advanceSummarizeWatermark(sessionId: string, upToSeq: number): void;
|
|
62
|
+
listSummarizableSessions(): {
|
|
63
|
+
id: string;
|
|
64
|
+
last_seq: number;
|
|
65
|
+
last_summarized_seq: number;
|
|
66
|
+
}[];
|
|
67
|
+
/** Most recently observed provider/model across sessions (from request/context events). */
|
|
68
|
+
latestSessionContext(): {
|
|
69
|
+
provider?: string;
|
|
70
|
+
model?: string;
|
|
71
|
+
};
|
|
72
|
+
upsertPattern(kind: string, key: string, count: number, sessionsSeen: number, sampleSession: string, tsMs: number): void;
|
|
73
|
+
getHotPatterns(kind: string, minCount: number, minSessions: number, limit: number): PatternRow[];
|
|
74
|
+
markPatternCompiled(id: number): void;
|
|
75
|
+
getPatternByKey(kind: string, key: string): PatternRow | undefined;
|
|
76
|
+
getPatternById(id: number): PatternRow | undefined;
|
|
77
|
+
hasArtifact(name: string): boolean;
|
|
78
|
+
insertArtifact(row: {
|
|
79
|
+
type: 'skill' | 'flow';
|
|
80
|
+
name: string;
|
|
81
|
+
title?: string | null;
|
|
82
|
+
description?: string | null;
|
|
83
|
+
file_path: string;
|
|
84
|
+
source_pattern_id?: number | null;
|
|
85
|
+
status?: 'active' | 'disabled';
|
|
86
|
+
feedback_mode?: 'filesystem' | 'runtime' | null;
|
|
87
|
+
llm_provider?: string | null;
|
|
88
|
+
llm_model?: string | null;
|
|
89
|
+
summary?: string | null;
|
|
90
|
+
created_ms?: number;
|
|
91
|
+
}): void;
|
|
92
|
+
listArtifacts(type?: string): ArtifactRow[];
|
|
93
|
+
getArtifact(name: string): ArtifactRow | undefined;
|
|
94
|
+
updateArtifactStatus(name: string, status: 'active' | 'disabled'): void;
|
|
95
|
+
deleteArtifact(name: string): void;
|
|
96
|
+
/** Bump usage counters when an artifact is invoked (skill load or flow replay). */
|
|
97
|
+
recordUsage(name: string, now?: number): void;
|
|
98
|
+
/** Record whether an invocation succeeded (drives promotion / deoptimization). */
|
|
99
|
+
recordOutcome(name: string, ok: boolean): void;
|
|
100
|
+
/** Flows used enough but failing too often — candidates for deoptimization. */
|
|
101
|
+
listDeoptCandidates(minUses: number, maxSuccessRate: number): ArtifactRow[];
|
|
102
|
+
/** Skills used often and reliably — candidates for promotion to flow (tier 2). */
|
|
103
|
+
listPromoteCandidates(minUses: number, minSuccessRate: number): ArtifactRow[];
|
|
104
|
+
/** Active artifacts with at least minUses (candidates for quality pruning). */
|
|
105
|
+
listActiveWithUsage(minUses: number): ArtifactRow[];
|
|
106
|
+
/**
|
|
107
|
+
* Disable active artifacts that are old enough (past the protection window)
|
|
108
|
+
* and unused for longer than the stale window. Returns the disabled names.
|
|
109
|
+
*/
|
|
110
|
+
gcStale(now: number, staleMs: number, protectMs: number): string[];
|
|
111
|
+
/** Delete trace rows older than the cutoff; returns the number removed. */
|
|
112
|
+
pruneTraces(olderThanMs: number, now?: number): number;
|
|
113
|
+
/** Delete uncompiled patterns not seen within the retention window. */
|
|
114
|
+
prunePatterns(olderThanMs: number, now?: number): number;
|
|
115
|
+
stats(): {
|
|
116
|
+
traces: number;
|
|
117
|
+
sessions: number;
|
|
118
|
+
patterns: number;
|
|
119
|
+
artifacts: number;
|
|
120
|
+
};
|
|
121
|
+
close(): void;
|
|
122
|
+
}
|
package/dist/store.js
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
2
|
+
import { mkdirSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
const SCHEMA_V1 = `
|
|
5
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
6
|
+
id TEXT PRIMARY KEY,
|
|
7
|
+
cwd TEXT,
|
|
8
|
+
provider TEXT,
|
|
9
|
+
model TEXT,
|
|
10
|
+
started_ms INTEGER,
|
|
11
|
+
ended_ms INTEGER,
|
|
12
|
+
last_seq INTEGER DEFAULT 0,
|
|
13
|
+
last_summarized_seq INTEGER DEFAULT 0
|
|
14
|
+
);
|
|
15
|
+
CREATE TABLE IF NOT EXISTS traces (
|
|
16
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
17
|
+
session_id TEXT NOT NULL REFERENCES sessions(id),
|
|
18
|
+
turn INTEGER NOT NULL,
|
|
19
|
+
step INTEGER,
|
|
20
|
+
kind TEXT NOT NULL,
|
|
21
|
+
seq INTEGER NOT NULL,
|
|
22
|
+
ts_ms INTEGER NOT NULL,
|
|
23
|
+
payload TEXT NOT NULL,
|
|
24
|
+
UNIQUE(session_id, seq)
|
|
25
|
+
);
|
|
26
|
+
CREATE INDEX IF NOT EXISTS idx_traces_session ON traces(session_id, seq);
|
|
27
|
+
CREATE INDEX IF NOT EXISTS idx_traces_kind ON traces(kind);
|
|
28
|
+
CREATE TABLE IF NOT EXISTS patterns (
|
|
29
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
30
|
+
kind TEXT NOT NULL,
|
|
31
|
+
key TEXT NOT NULL,
|
|
32
|
+
count INTEGER NOT NULL,
|
|
33
|
+
sessions_seen INTEGER DEFAULT 0,
|
|
34
|
+
compiled INTEGER DEFAULT 0,
|
|
35
|
+
sample_session TEXT NOT NULL,
|
|
36
|
+
first_seen_ms INTEGER,
|
|
37
|
+
last_seen_ms INTEGER,
|
|
38
|
+
UNIQUE(kind, key)
|
|
39
|
+
);
|
|
40
|
+
CREATE TABLE IF NOT EXISTS artifacts (
|
|
41
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
42
|
+
type TEXT NOT NULL,
|
|
43
|
+
name TEXT NOT NULL UNIQUE,
|
|
44
|
+
title TEXT,
|
|
45
|
+
description TEXT,
|
|
46
|
+
file_path TEXT NOT NULL,
|
|
47
|
+
source_pattern_id INTEGER,
|
|
48
|
+
status TEXT DEFAULT 'active',
|
|
49
|
+
feedback_mode TEXT,
|
|
50
|
+
llm_provider TEXT,
|
|
51
|
+
llm_model TEXT,
|
|
52
|
+
summary TEXT,
|
|
53
|
+
created_ms INTEGER,
|
|
54
|
+
updated_ms INTEGER,
|
|
55
|
+
use_count INTEGER DEFAULT 0,
|
|
56
|
+
last_used_ms INTEGER
|
|
57
|
+
);
|
|
58
|
+
`;
|
|
59
|
+
/**
|
|
60
|
+
* Heuristic artifact quality: success rate weighted by usage volume.
|
|
61
|
+
* log2 dampens volume so a rarely-used artifact isn't over-rated.
|
|
62
|
+
*/
|
|
63
|
+
export function qualityScore(useCount, successCount) {
|
|
64
|
+
if (useCount <= 0)
|
|
65
|
+
return 0;
|
|
66
|
+
const rate = Math.min(1, successCount / useCount);
|
|
67
|
+
return Math.round(rate * Math.log2(1 + useCount) * 100) / 100;
|
|
68
|
+
}
|
|
69
|
+
export class DeepJitStore {
|
|
70
|
+
db;
|
|
71
|
+
constructor(dbPath) {
|
|
72
|
+
if (dbPath !== ':memory:') {
|
|
73
|
+
mkdirSync(path.dirname(dbPath), { recursive: true });
|
|
74
|
+
}
|
|
75
|
+
this.db = new DatabaseSync(dbPath);
|
|
76
|
+
this.db.exec('PRAGMA journal_mode=WAL');
|
|
77
|
+
this.db.exec('PRAGMA busy_timeout=5000');
|
|
78
|
+
this.migrate();
|
|
79
|
+
}
|
|
80
|
+
migrate() {
|
|
81
|
+
const version = this.db.prepare('PRAGMA user_version').get().user_version;
|
|
82
|
+
if (version >= 3)
|
|
83
|
+
return;
|
|
84
|
+
this.db.exec('BEGIN');
|
|
85
|
+
try {
|
|
86
|
+
this.db.exec(SCHEMA_V1);
|
|
87
|
+
if (version === 1) {
|
|
88
|
+
this.db.exec('ALTER TABLE artifacts ADD COLUMN use_count INTEGER DEFAULT 0');
|
|
89
|
+
this.db.exec('ALTER TABLE artifacts ADD COLUMN last_used_ms INTEGER');
|
|
90
|
+
}
|
|
91
|
+
if (version <= 2) {
|
|
92
|
+
this.db.exec('ALTER TABLE artifacts ADD COLUMN success_count INTEGER DEFAULT 0');
|
|
93
|
+
}
|
|
94
|
+
this.db.exec('PRAGMA user_version=3');
|
|
95
|
+
this.db.exec('COMMIT');
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
this.db.exec('ROLLBACK');
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
upsertSession(sessionId, startedMs, cwd) {
|
|
103
|
+
this.db
|
|
104
|
+
.prepare(`INSERT INTO sessions (id, cwd, started_ms)
|
|
105
|
+
VALUES (?, ?, ?)
|
|
106
|
+
ON CONFLICT(id) DO UPDATE SET cwd = COALESCE(excluded.cwd, sessions.cwd)`)
|
|
107
|
+
.run(sessionId, cwd ?? null, startedMs);
|
|
108
|
+
}
|
|
109
|
+
touchSession(sessionId, endedMs) {
|
|
110
|
+
this.db
|
|
111
|
+
.prepare('UPDATE sessions SET ended_ms = ? WHERE id = ?')
|
|
112
|
+
.run(endedMs, sessionId);
|
|
113
|
+
}
|
|
114
|
+
setSessionContext(sessionId, provider, model) {
|
|
115
|
+
this.db
|
|
116
|
+
.prepare('UPDATE sessions SET provider = COALESCE(?, provider), model = COALESCE(?, model) WHERE id = ?')
|
|
117
|
+
.run(provider ?? null, model ?? null, sessionId);
|
|
118
|
+
}
|
|
119
|
+
getSessionWatermark(sessionId) {
|
|
120
|
+
const row = this.db
|
|
121
|
+
.prepare('SELECT last_seq, last_summarized_seq FROM sessions WHERE id = ?')
|
|
122
|
+
.get(sessionId);
|
|
123
|
+
return row ?? { last_seq: 0, last_summarized_seq: 0 };
|
|
124
|
+
}
|
|
125
|
+
/** Insert a batch of traces in one transaction and advance the session watermark. */
|
|
126
|
+
insertTraces(rows) {
|
|
127
|
+
if (rows.length === 0)
|
|
128
|
+
return;
|
|
129
|
+
const stmt = this.db.prepare(`INSERT OR IGNORE INTO traces (session_id, turn, step, kind, seq, ts_ms, payload)
|
|
130
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`);
|
|
131
|
+
this.db.exec('BEGIN');
|
|
132
|
+
try {
|
|
133
|
+
const lastBySession = new Map();
|
|
134
|
+
for (const row of rows) {
|
|
135
|
+
stmt.run(row.session_id, row.turn, row.step, row.kind, row.seq, row.ts_ms, row.payload);
|
|
136
|
+
const prev = lastBySession.get(row.session_id) ?? -1;
|
|
137
|
+
if (row.seq > prev)
|
|
138
|
+
lastBySession.set(row.session_id, row.seq);
|
|
139
|
+
}
|
|
140
|
+
const upd = this.db.prepare('UPDATE sessions SET last_seq = MAX(last_seq, ?), ended_ms = MAX(ended_ms, ?) WHERE id = ?');
|
|
141
|
+
for (const [sid, seq] of lastBySession) {
|
|
142
|
+
const ts = rows.filter((r) => r.session_id === sid).reduce((m, r) => Math.max(m, r.ts_ms), 0);
|
|
143
|
+
upd.run(seq, ts, sid);
|
|
144
|
+
}
|
|
145
|
+
this.db.exec('COMMIT');
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
this.db.exec('ROLLBACK');
|
|
149
|
+
throw err;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/** Tool / user traces after the summarization watermark, ordered by seq. */
|
|
153
|
+
readTracesSince(sessionId, fromSeq, kinds, limit) {
|
|
154
|
+
const placeholders = kinds.map(() => '?').join(',');
|
|
155
|
+
const sql = `SELECT session_id, turn, step, kind, seq, ts_ms, payload
|
|
156
|
+
FROM traces WHERE session_id = ? AND seq > ? AND kind IN (${placeholders})
|
|
157
|
+
ORDER BY seq ASC${limit !== undefined ? ' LIMIT ?' : ''}`;
|
|
158
|
+
const params = [sessionId, fromSeq, ...kinds];
|
|
159
|
+
if (limit !== undefined)
|
|
160
|
+
params.push(limit);
|
|
161
|
+
return this.db.prepare(sql).all(...params);
|
|
162
|
+
}
|
|
163
|
+
advanceSummarizeWatermark(sessionId, upToSeq) {
|
|
164
|
+
this.db
|
|
165
|
+
.prepare('UPDATE sessions SET last_summarized_seq = MAX(last_summarized_seq, ?) WHERE id = ?')
|
|
166
|
+
.run(upToSeq, sessionId);
|
|
167
|
+
}
|
|
168
|
+
listSummarizableSessions() {
|
|
169
|
+
return this.db
|
|
170
|
+
.prepare('SELECT id, last_seq, last_summarized_seq FROM sessions WHERE last_seq > last_summarized_seq')
|
|
171
|
+
.all();
|
|
172
|
+
}
|
|
173
|
+
/** Most recently observed provider/model across sessions (from request/context events). */
|
|
174
|
+
latestSessionContext() {
|
|
175
|
+
const row = this.db
|
|
176
|
+
.prepare('SELECT provider, model FROM sessions WHERE provider IS NOT NULL OR model IS NOT NULL ORDER BY started_ms DESC LIMIT 1')
|
|
177
|
+
.get();
|
|
178
|
+
return { provider: row?.provider ?? undefined, model: row?.model ?? undefined };
|
|
179
|
+
}
|
|
180
|
+
upsertPattern(kind, key, count, sessionsSeen, sampleSession, tsMs) {
|
|
181
|
+
this.db
|
|
182
|
+
.prepare(`INSERT INTO patterns (kind, key, count, sessions_seen, sample_session, first_seen_ms, last_seen_ms)
|
|
183
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
184
|
+
ON CONFLICT(kind, key) DO UPDATE SET
|
|
185
|
+
count = patterns.count + excluded.count,
|
|
186
|
+
sessions_seen = patterns.sessions_seen + excluded.sessions_seen,
|
|
187
|
+
last_seen_ms = MAX(patterns.last_seen_ms, excluded.last_seen_ms),
|
|
188
|
+
sample_session = patterns.sample_session`)
|
|
189
|
+
.run(kind, key, count, sessionsSeen, sampleSession, tsMs, tsMs);
|
|
190
|
+
}
|
|
191
|
+
getHotPatterns(kind, minCount, minSessions, limit) {
|
|
192
|
+
return this.db
|
|
193
|
+
.prepare(`SELECT * FROM patterns
|
|
194
|
+
WHERE kind = ? AND count >= ? AND sessions_seen >= ? AND compiled = 0
|
|
195
|
+
ORDER BY count DESC, last_seen_ms DESC LIMIT ?`)
|
|
196
|
+
.all(kind, minCount, minSessions, limit);
|
|
197
|
+
}
|
|
198
|
+
markPatternCompiled(id) {
|
|
199
|
+
this.db.prepare('UPDATE patterns SET compiled = 1 WHERE id = ?').run(id);
|
|
200
|
+
}
|
|
201
|
+
getPatternByKey(kind, key) {
|
|
202
|
+
return this.db
|
|
203
|
+
.prepare('SELECT * FROM patterns WHERE kind = ? AND key = ?')
|
|
204
|
+
.get(kind, key);
|
|
205
|
+
}
|
|
206
|
+
getPatternById(id) {
|
|
207
|
+
return this.db.prepare('SELECT * FROM patterns WHERE id = ?').get(id);
|
|
208
|
+
}
|
|
209
|
+
hasArtifact(name) {
|
|
210
|
+
return !!this.db.prepare('SELECT 1 FROM artifacts WHERE name = ?').get(name);
|
|
211
|
+
}
|
|
212
|
+
insertArtifact(row) {
|
|
213
|
+
const now = Date.now();
|
|
214
|
+
this.db
|
|
215
|
+
.prepare(`INSERT OR REPLACE INTO artifacts
|
|
216
|
+
(type, name, title, description, file_path, source_pattern_id, status, feedback_mode, llm_provider, llm_model, summary, created_ms, updated_ms)
|
|
217
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
218
|
+
.run(row.type, row.name, row.title ?? null, row.description ?? null, row.file_path, row.source_pattern_id ?? null, row.status ?? 'active', row.feedback_mode ?? null, row.llm_provider ?? null, row.llm_model ?? null, row.summary ?? null, row.created_ms ?? now, now);
|
|
219
|
+
}
|
|
220
|
+
listArtifacts(type) {
|
|
221
|
+
if (type) {
|
|
222
|
+
return this.db
|
|
223
|
+
.prepare('SELECT * FROM artifacts WHERE type = ? ORDER BY updated_ms DESC')
|
|
224
|
+
.all(type);
|
|
225
|
+
}
|
|
226
|
+
return this.db
|
|
227
|
+
.prepare('SELECT * FROM artifacts ORDER BY updated_ms DESC')
|
|
228
|
+
.all();
|
|
229
|
+
}
|
|
230
|
+
getArtifact(name) {
|
|
231
|
+
return this.db
|
|
232
|
+
.prepare('SELECT * FROM artifacts WHERE name = ?')
|
|
233
|
+
.get(name);
|
|
234
|
+
}
|
|
235
|
+
updateArtifactStatus(name, status) {
|
|
236
|
+
this.db
|
|
237
|
+
.prepare('UPDATE artifacts SET status = ?, updated_ms = ? WHERE name = ?')
|
|
238
|
+
.run(status, Date.now(), name);
|
|
239
|
+
}
|
|
240
|
+
deleteArtifact(name) {
|
|
241
|
+
this.db.prepare('DELETE FROM artifacts WHERE name = ?').run(name);
|
|
242
|
+
}
|
|
243
|
+
/** Bump usage counters when an artifact is invoked (skill load or flow replay). */
|
|
244
|
+
recordUsage(name, now = Date.now()) {
|
|
245
|
+
this.db
|
|
246
|
+
.prepare('UPDATE artifacts SET use_count = use_count + 1, last_used_ms = ? WHERE name = ?')
|
|
247
|
+
.run(now, name);
|
|
248
|
+
}
|
|
249
|
+
/** Record whether an invocation succeeded (drives promotion / deoptimization). */
|
|
250
|
+
recordOutcome(name, ok) {
|
|
251
|
+
if (ok)
|
|
252
|
+
this.db.prepare('UPDATE artifacts SET success_count = success_count + 1 WHERE name = ?').run(name);
|
|
253
|
+
}
|
|
254
|
+
/** Flows used enough but failing too often — candidates for deoptimization. */
|
|
255
|
+
listDeoptCandidates(minUses, maxSuccessRate) {
|
|
256
|
+
return this.db
|
|
257
|
+
.prepare(`SELECT * FROM artifacts
|
|
258
|
+
WHERE type = 'flow' AND status = 'active' AND use_count >= ?
|
|
259
|
+
AND (CAST(success_count AS REAL) / use_count) <= ?`)
|
|
260
|
+
.all(minUses, maxSuccessRate);
|
|
261
|
+
}
|
|
262
|
+
/** Skills used often and reliably — candidates for promotion to flow (tier 2). */
|
|
263
|
+
listPromoteCandidates(minUses, minSuccessRate) {
|
|
264
|
+
return this.db
|
|
265
|
+
.prepare(`SELECT * FROM artifacts
|
|
266
|
+
WHERE type = 'skill' AND status = 'active' AND use_count >= ?
|
|
267
|
+
AND source_pattern_id > 0
|
|
268
|
+
AND (CAST(success_count AS REAL) / use_count) >= ?`)
|
|
269
|
+
.all(minUses, minSuccessRate);
|
|
270
|
+
}
|
|
271
|
+
/** Active artifacts with at least minUses (candidates for quality pruning). */
|
|
272
|
+
listActiveWithUsage(minUses) {
|
|
273
|
+
return this.db
|
|
274
|
+
.prepare('SELECT * FROM artifacts WHERE status = \'active\' AND use_count >= ?')
|
|
275
|
+
.all(minUses);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Disable active artifacts that are old enough (past the protection window)
|
|
279
|
+
* and unused for longer than the stale window. Returns the disabled names.
|
|
280
|
+
*/
|
|
281
|
+
gcStale(now, staleMs, protectMs) {
|
|
282
|
+
const rows = this.db
|
|
283
|
+
.prepare(`SELECT name FROM artifacts
|
|
284
|
+
WHERE status = 'active'
|
|
285
|
+
AND created_ms <= ?
|
|
286
|
+
AND COALESCE(last_used_ms, created_ms) <= ?`)
|
|
287
|
+
.all(now - protectMs, now - staleMs);
|
|
288
|
+
for (const r of rows)
|
|
289
|
+
this.updateArtifactStatus(r.name, 'disabled');
|
|
290
|
+
return rows.map((r) => r.name);
|
|
291
|
+
}
|
|
292
|
+
/** Delete trace rows older than the cutoff; returns the number removed. */
|
|
293
|
+
pruneTraces(olderThanMs, now = Date.now()) {
|
|
294
|
+
const res = this.db.prepare('DELETE FROM traces WHERE ts_ms < ?').run(now - olderThanMs);
|
|
295
|
+
return Number(res.changes);
|
|
296
|
+
}
|
|
297
|
+
/** Delete uncompiled patterns not seen within the retention window. */
|
|
298
|
+
prunePatterns(olderThanMs, now = Date.now()) {
|
|
299
|
+
const res = this.db
|
|
300
|
+
.prepare('DELETE FROM patterns WHERE compiled = 0 AND last_seen_ms < ?')
|
|
301
|
+
.run(now - olderThanMs);
|
|
302
|
+
return Number(res.changes);
|
|
303
|
+
}
|
|
304
|
+
stats() {
|
|
305
|
+
const one = (sql) => this.db.prepare(sql).get().n;
|
|
306
|
+
return {
|
|
307
|
+
traces: one('SELECT COUNT(*) AS n FROM traces'),
|
|
308
|
+
sessions: one('SELECT COUNT(*) AS n FROM sessions'),
|
|
309
|
+
patterns: one('SELECT COUNT(*) AS n FROM patterns'),
|
|
310
|
+
artifacts: one('SELECT COUNT(*) AS n FROM artifacts'),
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
close() {
|
|
314
|
+
this.db.close();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=store.js.map
|