oh-my-knowledge 0.52.3 → 0.54.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 +21 -1
- package/README.zh.md +21 -1
- package/dist/assets/agent-skills/omk/SKILL.md +6 -0
- package/dist/assets/agent-skills/omk/references/commands.md +1 -1
- package/dist/authoring/evolver.js +1 -1
- package/dist/authoring/generator.js +1 -1
- package/dist/cli/commands/eval/index.js +7 -6
- package/dist/cli/commands/install.js +5 -1
- package/dist/cli/lib/generation-failure-hint.js +6 -8
- package/dist/cli/lib/runtime-defaults.d.ts +2 -0
- package/dist/cli/lib/runtime-defaults.js +7 -4
- package/dist/dsh-plugin/cordis.patch.yml +3 -0
- package/dist/dsh-plugin/host-executor.d.ts +93 -0
- package/dist/dsh-plugin/host-executor.js +232 -0
- package/dist/dsh-plugin/index.d.ts +30 -0
- package/dist/dsh-plugin/index.js +275 -0
- package/dist/dsh-plugin/observe.d.ts +47 -0
- package/dist/dsh-plugin/observe.js +359 -0
- package/dist/dsh-plugin/protocol.d.ts +21 -0
- package/dist/dsh-plugin/protocol.js +229 -0
- package/dist/dsh-plugin/trace-adapter.d.ts +48 -0
- package/dist/dsh-plugin/trace-adapter.js +590 -0
- package/dist/eval-core/comparability.js +3 -0
- package/dist/eval-core/evaluation-execution.js +5 -13
- package/dist/eval-core/evaluation-reporting.d.ts +7 -4
- package/dist/eval-core/evaluation-reporting.js +39 -18
- package/dist/eval-core/judge-independence.d.ts +1 -1
- package/dist/eval-core/judge-independence.js +1 -1
- package/dist/eval-core/report-document.js +6 -0
- package/dist/eval-core/resume-compatibility.d.ts +1 -0
- package/dist/eval-core/resume-compatibility.js +5 -4
- package/dist/eval-workflows/batch-evaluation-workflow.js +1 -1
- package/dist/eval-workflows/evaluation-pipeline/preflight-warnings.js +4 -2
- package/dist/eval-workflows/evaluation-pipeline.d.ts +3 -1
- package/dist/eval-workflows/evaluation-pipeline.js +7 -3
- package/dist/eval-workflows/run-evaluation.d.ts +4 -2
- package/dist/eval-workflows/run-evaluation.js +7 -3
- package/dist/executors/{anthropic-api.d.ts → anthropic/api.d.ts} +1 -1
- package/dist/executors/{anthropic-api.js → anthropic/api.js} +4 -2
- package/dist/executors/{claude-cli.d.ts → anthropic/claude/cli.d.ts} +1 -1
- package/dist/executors/{claude-cli.js → anthropic/claude/cli.js} +5 -3
- package/dist/executors/anthropic/claude/protocol.d.ts +87 -0
- package/dist/executors/{claude-protocol.js → anthropic/claude/protocol.js} +6 -6
- package/dist/executors/{claude-sdk.d.ts → anthropic/claude/sdk.d.ts} +2 -2
- package/dist/executors/{claude-sdk.js → anthropic/claude/sdk.js} +8 -5
- package/dist/executors/anthropic/claude/trace.d.ts +9 -0
- package/dist/executors/{claude-sdk-trace.js → anthropic/claude/trace.js} +5 -5
- package/dist/executors/{capabilities.d.ts → core/capabilities.d.ts} +3 -5
- package/dist/executors/{capabilities.js → core/capabilities.js} +4 -11
- package/dist/executors/core/http.d.ts +6 -0
- package/dist/executors/core/http.js +19 -0
- package/dist/executors/core/limits.d.ts +2 -0
- package/dist/executors/core/limits.js +2 -0
- package/dist/executors/core/optional-dependencies.d.ts +7 -0
- package/dist/executors/core/optional-dependencies.js +35 -0
- package/dist/executors/core/registry.d.ts +145 -0
- package/dist/executors/core/registry.js +127 -0
- package/dist/executors/core/runtime-fingerprint.d.ts +13 -0
- package/dist/executors/{runtime-fingerprint.js → core/runtime-fingerprint.js} +119 -59
- package/dist/executors/core/runtime.d.ts +12 -0
- package/dist/executors/core/runtime.js +61 -0
- package/dist/executors/core/subprocess.d.ts +44 -0
- package/dist/executors/{shared.js → core/subprocess.js} +20 -156
- package/dist/executors/index.d.ts +4 -4
- package/dist/executors/index.js +26 -15
- package/dist/executors/{openai-api.d.ts → openai/api.d.ts} +1 -1
- package/dist/executors/{openai-api.js → openai/api.js} +4 -2
- package/dist/executors/{codex-cli.d.ts → openai/codex/cli.d.ts} +3 -3
- package/dist/executors/{codex-cli.js → openai/codex/cli.js} +5 -3
- package/dist/executors/openai/codex/protocol.d.ts +72 -0
- package/dist/executors/{codex-protocol.js → openai/codex/protocol.js} +33 -2
- package/dist/executors/{codex-sdk.d.ts → openai/codex/sdk.d.ts} +18 -4
- package/dist/executors/{codex-sdk.js → openai/codex/sdk.js} +7 -4
- package/dist/executors/{codex-cli-trace.d.ts → openai/codex/trace.d.ts} +2 -2
- package/dist/executors/{codex-cli-trace.js → openai/codex/trace.js} +4 -4
- package/dist/executors/{script.d.ts → script/index.d.ts} +1 -1
- package/dist/executors/{script.js → script/index.js} +6 -4
- package/dist/grading/judge.d.ts +1 -1
- package/dist/grading/judge.js +1 -1
- package/dist/observability/conversation-catalog.js +1 -1
- package/dist/observability/experience.js +4 -0
- package/dist/observability/inbox.d.ts +4 -1
- package/dist/observability/inbox.js +7 -2
- package/dist/observability/trace-ir.d.ts +6 -3
- package/dist/observability/turn-index.js +4 -0
- package/dist/renderer/conversation-renderer.js +20 -6
- package/dist/renderer/html-renderer.js +30 -11
- package/dist/renderer/knowledge-debugger-renderer.js +6 -1
- package/dist/renderer/observation-inbox-renderer.js +2 -2
- package/dist/renderer/trajectory-live.d.ts +1 -0
- package/dist/renderer/trajectory-live.js +5 -2
- package/dist/shared/trace-source-kind.js +1 -0
- package/dist/types/executor.d.ts +13 -2
- package/dist/types/judge.d.ts +2 -2
- package/dist/types/observability.d.ts +1 -1
- package/dist/types/trace.d.ts +1 -1
- package/package.json +25 -5
- package/dist/executors/claude-protocol.d.ts +0 -28
- package/dist/executors/claude-sdk-trace.d.ts +0 -9
- package/dist/executors/codex-protocol.d.ts +0 -24
- package/dist/executors/gemini.d.ts +0 -2
- package/dist/executors/gemini.js +0 -156
- package/dist/executors/runtime-fingerprint.d.ts +0 -6
- package/dist/executors/shared.d.ts +0 -226
- /package/dist/executors/{script-command.d.ts → script/command.d.ts} +0 -0
- /package/dist/executors/{script-command.js → script/command.js} +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export async function readJsonResponse(response) {
|
|
2
|
+
const rawBody = await response.text();
|
|
3
|
+
if (!rawBody.trim())
|
|
4
|
+
return { data: null, rawBody };
|
|
5
|
+
try {
|
|
6
|
+
return { data: JSON.parse(rawBody), rawBody };
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return { data: null, rawBody };
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function responseBodyPreview(rawBody, maxLength = 500) {
|
|
13
|
+
const normalized = rawBody.replace(/\s+/g, ' ').trim();
|
|
14
|
+
if (!normalized)
|
|
15
|
+
return '';
|
|
16
|
+
return normalized.length > maxLength
|
|
17
|
+
? `${normalized.slice(0, maxLength)}...`
|
|
18
|
+
: normalized;
|
|
19
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ExecutableExecutorName } from './registry.js';
|
|
2
|
+
export interface OptionalExecutorDependency {
|
|
3
|
+
readonly packageName: string;
|
|
4
|
+
readonly installSpec: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function getOptionalExecutorDependency(executorName: ExecutableExecutorName): OptionalExecutorDependency | undefined;
|
|
7
|
+
export declare function assertOptionalExecutorDependency(executorName: ExecutableExecutorName, available?: (packageName: string) => boolean): void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const OPTIONAL_EXECUTOR_DEPENDENCIES = {
|
|
2
|
+
'claude-sdk': {
|
|
3
|
+
packageName: '@anthropic-ai/claude-agent-sdk',
|
|
4
|
+
installSpec: '@anthropic-ai/claude-agent-sdk@^0.3.143',
|
|
5
|
+
},
|
|
6
|
+
'codex-sdk': {
|
|
7
|
+
packageName: '@openai/codex-sdk',
|
|
8
|
+
installSpec: '@openai/codex-sdk@^0.149.0',
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
export function getOptionalExecutorDependency(executorName) {
|
|
12
|
+
return OPTIONAL_EXECUTOR_DEPENDENCIES[executorName];
|
|
13
|
+
}
|
|
14
|
+
function packageAvailable(packageName) {
|
|
15
|
+
try {
|
|
16
|
+
// Use ESM resolution because @openai/codex-sdk only exposes an `import`
|
|
17
|
+
// condition; createRequire().resolve() reports ERR_PACKAGE_PATH_NOT_EXPORTED
|
|
18
|
+
// even when that optional peer is correctly installed.
|
|
19
|
+
import.meta.resolve(packageName);
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function assertOptionalExecutorDependency(executorName, available = packageAvailable) {
|
|
27
|
+
const dependency = getOptionalExecutorDependency(executorName);
|
|
28
|
+
if (!dependency || available(dependency.packageName))
|
|
29
|
+
return;
|
|
30
|
+
throw new Error([
|
|
31
|
+
`执行器「${executorName}」需要可选依赖「${dependency.packageName}」,但当前 OMK 安装作用域中未找到。`,
|
|
32
|
+
`本地安装:npm install ${dependency.installSpec}`,
|
|
33
|
+
`全局安装:npm install -g ${dependency.installSpec}`,
|
|
34
|
+
].join('\n'));
|
|
35
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
export type ExecutorVendor = 'anthropic' | 'openai' | 'unknown';
|
|
2
|
+
export type ExecutorFamily = 'claude' | 'codex' | 'dsh' | 'anthropic-api' | 'openai-api';
|
|
3
|
+
export type SampleMockSupport = 'native-hooks' | 'delegated-script' | 'unsupported';
|
|
4
|
+
export interface ExecutorCapabilities {
|
|
5
|
+
sampleMocks: SampleMockSupport;
|
|
6
|
+
}
|
|
7
|
+
export type ExecutorFingerprintSpec = {
|
|
8
|
+
readonly strategy: 'path-cli';
|
|
9
|
+
readonly command: 'claude' | 'codex';
|
|
10
|
+
} | {
|
|
11
|
+
readonly strategy: 'claude-sdk';
|
|
12
|
+
} | {
|
|
13
|
+
readonly strategy: 'codex-sdk';
|
|
14
|
+
} | {
|
|
15
|
+
readonly strategy: 'api';
|
|
16
|
+
} | {
|
|
17
|
+
readonly strategy: 'dsh-host';
|
|
18
|
+
};
|
|
19
|
+
declare const EXECUTOR_DESCRIPTORS: readonly [{
|
|
20
|
+
readonly name: "claude";
|
|
21
|
+
readonly execution: "builtin";
|
|
22
|
+
readonly family: "claude";
|
|
23
|
+
readonly vendor: "anthropic";
|
|
24
|
+
readonly sampleMocks: "native-hooks";
|
|
25
|
+
readonly runtimeKind: "agent-cli";
|
|
26
|
+
readonly runtimeCapabilities: {
|
|
27
|
+
readonly systemPrompt: "native";
|
|
28
|
+
readonly costUSD: "reported";
|
|
29
|
+
readonly trace: "native";
|
|
30
|
+
readonly skillIsolation: "full-no-partial";
|
|
31
|
+
};
|
|
32
|
+
readonly fingerprint: {
|
|
33
|
+
readonly strategy: "path-cli";
|
|
34
|
+
readonly command: "claude";
|
|
35
|
+
};
|
|
36
|
+
}, {
|
|
37
|
+
readonly name: "claude-sdk";
|
|
38
|
+
readonly execution: "builtin";
|
|
39
|
+
readonly family: "claude";
|
|
40
|
+
readonly vendor: "anthropic";
|
|
41
|
+
readonly sampleMocks: "native-hooks";
|
|
42
|
+
readonly runtimeKind: "agent-sdk";
|
|
43
|
+
readonly runtimeCapabilities: {
|
|
44
|
+
readonly systemPrompt: "native";
|
|
45
|
+
readonly costUSD: "reported";
|
|
46
|
+
readonly trace: "native";
|
|
47
|
+
readonly skillIsolation: "full";
|
|
48
|
+
};
|
|
49
|
+
readonly fingerprint: {
|
|
50
|
+
readonly strategy: "claude-sdk";
|
|
51
|
+
};
|
|
52
|
+
}, {
|
|
53
|
+
readonly name: "codex";
|
|
54
|
+
readonly execution: "builtin";
|
|
55
|
+
readonly family: "codex";
|
|
56
|
+
readonly vendor: "openai";
|
|
57
|
+
readonly sampleMocks: "unsupported";
|
|
58
|
+
readonly runtimeKind: "agent-cli";
|
|
59
|
+
readonly runtimeCapabilities: {
|
|
60
|
+
readonly systemPrompt: "prepended";
|
|
61
|
+
readonly costUSD: "not-reported";
|
|
62
|
+
readonly trace: "best-effort";
|
|
63
|
+
readonly skillIsolation: "cwd-only";
|
|
64
|
+
};
|
|
65
|
+
readonly fingerprint: {
|
|
66
|
+
readonly strategy: "path-cli";
|
|
67
|
+
readonly command: "codex";
|
|
68
|
+
};
|
|
69
|
+
}, {
|
|
70
|
+
readonly name: "codex-sdk";
|
|
71
|
+
readonly execution: "builtin";
|
|
72
|
+
readonly family: "codex";
|
|
73
|
+
readonly vendor: "openai";
|
|
74
|
+
readonly sampleMocks: "unsupported";
|
|
75
|
+
readonly runtimeKind: "agent-sdk";
|
|
76
|
+
readonly runtimeCapabilities: {
|
|
77
|
+
readonly systemPrompt: "prepended";
|
|
78
|
+
readonly costUSD: "not-reported";
|
|
79
|
+
readonly trace: "best-effort";
|
|
80
|
+
readonly skillIsolation: "cwd-only";
|
|
81
|
+
};
|
|
82
|
+
readonly fingerprint: {
|
|
83
|
+
readonly strategy: "codex-sdk";
|
|
84
|
+
};
|
|
85
|
+
}, {
|
|
86
|
+
readonly name: "dsh-host";
|
|
87
|
+
readonly execution: "host-only";
|
|
88
|
+
readonly family: "dsh";
|
|
89
|
+
readonly vendor: "unknown";
|
|
90
|
+
readonly sampleMocks: "unsupported";
|
|
91
|
+
readonly runtimeKind: "agent-sdk";
|
|
92
|
+
readonly runtimeCapabilities: {
|
|
93
|
+
readonly systemPrompt: "native";
|
|
94
|
+
readonly costUSD: "not-reported";
|
|
95
|
+
readonly trace: "native";
|
|
96
|
+
readonly skillIsolation: "full-no-partial";
|
|
97
|
+
};
|
|
98
|
+
readonly fingerprint: {
|
|
99
|
+
readonly strategy: "dsh-host";
|
|
100
|
+
};
|
|
101
|
+
}, {
|
|
102
|
+
readonly name: "anthropic-api";
|
|
103
|
+
readonly execution: "builtin";
|
|
104
|
+
readonly family: "anthropic-api";
|
|
105
|
+
readonly vendor: "anthropic";
|
|
106
|
+
readonly sampleMocks: "unsupported";
|
|
107
|
+
readonly runtimeKind: "api";
|
|
108
|
+
readonly runtimeCapabilities: {
|
|
109
|
+
readonly systemPrompt: "native";
|
|
110
|
+
readonly costUSD: "not-reported";
|
|
111
|
+
readonly trace: "none";
|
|
112
|
+
readonly skillIsolation: "none";
|
|
113
|
+
};
|
|
114
|
+
readonly fingerprint: {
|
|
115
|
+
readonly strategy: "api";
|
|
116
|
+
};
|
|
117
|
+
}, {
|
|
118
|
+
readonly name: "openai-api";
|
|
119
|
+
readonly execution: "builtin";
|
|
120
|
+
readonly family: "openai-api";
|
|
121
|
+
readonly vendor: "openai";
|
|
122
|
+
readonly sampleMocks: "unsupported";
|
|
123
|
+
readonly runtimeKind: "api";
|
|
124
|
+
readonly runtimeCapabilities: {
|
|
125
|
+
readonly systemPrompt: "native";
|
|
126
|
+
readonly costUSD: "not-reported";
|
|
127
|
+
readonly trace: "none";
|
|
128
|
+
readonly skillIsolation: "none";
|
|
129
|
+
};
|
|
130
|
+
readonly fingerprint: {
|
|
131
|
+
readonly strategy: "api";
|
|
132
|
+
};
|
|
133
|
+
}];
|
|
134
|
+
export type RegisteredExecutorDescriptor = (typeof EXECUTOR_DESCRIPTORS)[number];
|
|
135
|
+
export type RegisteredExecutorName = RegisteredExecutorDescriptor['name'];
|
|
136
|
+
export type ExecutableExecutorName = Extract<RegisteredExecutorDescriptor, {
|
|
137
|
+
execution: 'builtin';
|
|
138
|
+
}>['name'];
|
|
139
|
+
export declare function executorDescriptors(): readonly RegisteredExecutorDescriptor[];
|
|
140
|
+
export declare function getExecutorDescriptor(name: string): RegisteredExecutorDescriptor | undefined;
|
|
141
|
+
export declare function isRegisteredExecutorName(name: string): name is RegisteredExecutorName;
|
|
142
|
+
export declare function executorVendor(executor: string): ExecutorVendor;
|
|
143
|
+
export declare function executorFamily(executor: string): ExecutorFamily | 'custom';
|
|
144
|
+
export declare function executorNamesForFamily(family: ExecutorFamily): ReadonlySet<string>;
|
|
145
|
+
export {};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
const EXECUTOR_DESCRIPTORS = [
|
|
2
|
+
{
|
|
3
|
+
name: 'claude',
|
|
4
|
+
execution: 'builtin',
|
|
5
|
+
family: 'claude',
|
|
6
|
+
vendor: 'anthropic',
|
|
7
|
+
sampleMocks: 'native-hooks',
|
|
8
|
+
runtimeKind: 'agent-cli',
|
|
9
|
+
runtimeCapabilities: {
|
|
10
|
+
systemPrompt: 'native',
|
|
11
|
+
costUSD: 'reported',
|
|
12
|
+
trace: 'native',
|
|
13
|
+
skillIsolation: 'full-no-partial',
|
|
14
|
+
},
|
|
15
|
+
fingerprint: { strategy: 'path-cli', command: 'claude' },
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'claude-sdk',
|
|
19
|
+
execution: 'builtin',
|
|
20
|
+
family: 'claude',
|
|
21
|
+
vendor: 'anthropic',
|
|
22
|
+
sampleMocks: 'native-hooks',
|
|
23
|
+
runtimeKind: 'agent-sdk',
|
|
24
|
+
runtimeCapabilities: {
|
|
25
|
+
systemPrompt: 'native',
|
|
26
|
+
costUSD: 'reported',
|
|
27
|
+
trace: 'native',
|
|
28
|
+
skillIsolation: 'full',
|
|
29
|
+
},
|
|
30
|
+
fingerprint: { strategy: 'claude-sdk' },
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'codex',
|
|
34
|
+
execution: 'builtin',
|
|
35
|
+
family: 'codex',
|
|
36
|
+
vendor: 'openai',
|
|
37
|
+
sampleMocks: 'unsupported',
|
|
38
|
+
runtimeKind: 'agent-cli',
|
|
39
|
+
runtimeCapabilities: {
|
|
40
|
+
systemPrompt: 'prepended',
|
|
41
|
+
costUSD: 'not-reported',
|
|
42
|
+
trace: 'best-effort',
|
|
43
|
+
skillIsolation: 'cwd-only',
|
|
44
|
+
},
|
|
45
|
+
fingerprint: { strategy: 'path-cli', command: 'codex' },
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'codex-sdk',
|
|
49
|
+
execution: 'builtin',
|
|
50
|
+
family: 'codex',
|
|
51
|
+
vendor: 'openai',
|
|
52
|
+
sampleMocks: 'unsupported',
|
|
53
|
+
runtimeKind: 'agent-sdk',
|
|
54
|
+
runtimeCapabilities: {
|
|
55
|
+
systemPrompt: 'prepended',
|
|
56
|
+
costUSD: 'not-reported',
|
|
57
|
+
trace: 'best-effort',
|
|
58
|
+
skillIsolation: 'cwd-only',
|
|
59
|
+
},
|
|
60
|
+
fingerprint: { strategy: 'codex-sdk' },
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'dsh-host',
|
|
64
|
+
execution: 'host-only',
|
|
65
|
+
family: 'dsh',
|
|
66
|
+
vendor: 'unknown',
|
|
67
|
+
sampleMocks: 'unsupported',
|
|
68
|
+
runtimeKind: 'agent-sdk',
|
|
69
|
+
runtimeCapabilities: {
|
|
70
|
+
systemPrompt: 'native',
|
|
71
|
+
costUSD: 'not-reported',
|
|
72
|
+
trace: 'native',
|
|
73
|
+
skillIsolation: 'full-no-partial',
|
|
74
|
+
},
|
|
75
|
+
fingerprint: { strategy: 'dsh-host' },
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'anthropic-api',
|
|
79
|
+
execution: 'builtin',
|
|
80
|
+
family: 'anthropic-api',
|
|
81
|
+
vendor: 'anthropic',
|
|
82
|
+
sampleMocks: 'unsupported',
|
|
83
|
+
runtimeKind: 'api',
|
|
84
|
+
runtimeCapabilities: {
|
|
85
|
+
systemPrompt: 'native',
|
|
86
|
+
costUSD: 'not-reported',
|
|
87
|
+
trace: 'none',
|
|
88
|
+
skillIsolation: 'none',
|
|
89
|
+
},
|
|
90
|
+
fingerprint: { strategy: 'api' },
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'openai-api',
|
|
94
|
+
execution: 'builtin',
|
|
95
|
+
family: 'openai-api',
|
|
96
|
+
vendor: 'openai',
|
|
97
|
+
sampleMocks: 'unsupported',
|
|
98
|
+
runtimeKind: 'api',
|
|
99
|
+
runtimeCapabilities: {
|
|
100
|
+
systemPrompt: 'native',
|
|
101
|
+
costUSD: 'not-reported',
|
|
102
|
+
trace: 'none',
|
|
103
|
+
skillIsolation: 'none',
|
|
104
|
+
},
|
|
105
|
+
fingerprint: { strategy: 'api' },
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
export function executorDescriptors() {
|
|
109
|
+
return EXECUTOR_DESCRIPTORS;
|
|
110
|
+
}
|
|
111
|
+
export function getExecutorDescriptor(name) {
|
|
112
|
+
return EXECUTOR_DESCRIPTORS.find((descriptor) => descriptor.name === name);
|
|
113
|
+
}
|
|
114
|
+
export function isRegisteredExecutorName(name) {
|
|
115
|
+
return getExecutorDescriptor(name) !== undefined;
|
|
116
|
+
}
|
|
117
|
+
export function executorVendor(executor) {
|
|
118
|
+
return getExecutorDescriptor(executor)?.vendor ?? 'unknown';
|
|
119
|
+
}
|
|
120
|
+
export function executorFamily(executor) {
|
|
121
|
+
return getExecutorDescriptor(executor)?.family ?? 'custom';
|
|
122
|
+
}
|
|
123
|
+
export function executorNamesForFamily(family) {
|
|
124
|
+
return new Set(EXECUTOR_DESCRIPTORS
|
|
125
|
+
.filter((descriptor) => descriptor.family === family)
|
|
126
|
+
.map((descriptor) => descriptor.name));
|
|
127
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ExecutorFn, ExecutorRuntimeFingerprint } from '../../types/index.js';
|
|
2
|
+
export interface DshHostRuntimeIdentity {
|
|
3
|
+
provider?: string;
|
|
4
|
+
agentPreset?: string;
|
|
5
|
+
toolSchemas?: readonly unknown[];
|
|
6
|
+
}
|
|
7
|
+
export interface ExecutorRuntimeFingerprintOptions {
|
|
8
|
+
skillDir?: string | null;
|
|
9
|
+
env?: NodeJS.ProcessEnv;
|
|
10
|
+
}
|
|
11
|
+
export declare function createDshHostRuntimeFingerprint(model: string, identity?: DshHostRuntimeIdentity): ExecutorRuntimeFingerprint;
|
|
12
|
+
export declare function resolveExecutorRuntimeFingerprint(executorName: string, model: string, options?: ExecutorRuntimeFingerprintOptions, executor?: ExecutorFn): ExecutorRuntimeFingerprint;
|
|
13
|
+
export declare function getExecutorRuntimeFingerprint(executorName: string, model: string, options?: ExecutorRuntimeFingerprintOptions): ExecutorRuntimeFingerprint;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
|
-
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
3
|
+
import { existsSync, readFileSync, realpathSync, statSync } from 'node:fs';
|
|
4
4
|
import { createRequire } from 'node:module';
|
|
5
5
|
import { delimiter, dirname, isAbsolute, join } from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
|
-
import { buildExecEnv } from './
|
|
8
|
-
import { isScriptFileInterpreter, resolveScriptCommand, } from '
|
|
7
|
+
import { buildExecEnv } from './runtime.js';
|
|
8
|
+
import { isScriptFileInterpreter, resolveScriptCommand, } from '../script/command.js';
|
|
9
|
+
import { getExecutorDescriptor } from './registry.js';
|
|
9
10
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
11
|
const requireFromHere = createRequire(import.meta.url);
|
|
11
12
|
const RUNTIME_CACHE = new Map();
|
|
@@ -56,6 +57,50 @@ function findNearestPackageJson(fromPath) {
|
|
|
56
57
|
}
|
|
57
58
|
return null;
|
|
58
59
|
}
|
|
60
|
+
function readInvokingDshPackage() {
|
|
61
|
+
const invokedEntrypoint = process.argv[1];
|
|
62
|
+
if (!invokedEntrypoint || !isAbsolute(invokedEntrypoint)) {
|
|
63
|
+
return {
|
|
64
|
+
package: { name: '@deepseek-ai/dsh', error: 'DSH host entrypoint not found' },
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
let entrypoint = invokedEntrypoint;
|
|
68
|
+
try {
|
|
69
|
+
entrypoint = realpathSync(invokedEntrypoint);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Keep the invoked path so the audit record still explains the lookup failure.
|
|
73
|
+
}
|
|
74
|
+
let dir = dirname(entrypoint);
|
|
75
|
+
for (let i = 0; i < 10; i++) {
|
|
76
|
+
const candidate = join(dir, 'package.json');
|
|
77
|
+
if (existsSync(candidate)) {
|
|
78
|
+
try {
|
|
79
|
+
const pkg = JSON.parse(readFileSync(candidate, 'utf-8'));
|
|
80
|
+
if (pkg.name === '@deepseek-ai/dsh') {
|
|
81
|
+
return {
|
|
82
|
+
entrypoint,
|
|
83
|
+
package: {
|
|
84
|
+
name: pkg.name,
|
|
85
|
+
...(pkg.version ? { version: pkg.version } : {}),
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// Keep walking: a parent package may still be the DSH CLI package.
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const parent = dirname(dir);
|
|
95
|
+
if (parent === dir)
|
|
96
|
+
break;
|
|
97
|
+
dir = parent;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
entrypoint,
|
|
101
|
+
package: { name: '@deepseek-ai/dsh', error: 'invoking @deepseek-ai/dsh package.json not found' },
|
|
102
|
+
};
|
|
103
|
+
}
|
|
59
104
|
function resolvePackageJson(packageName, from) {
|
|
60
105
|
const req = from ? createRequire(from) : requireFromHere;
|
|
61
106
|
try {
|
|
@@ -165,6 +210,7 @@ function withFingerprint(input) {
|
|
|
165
210
|
status: input.sdk.version ? 'ok' : input.sdk.error ? 'error' : 'missing',
|
|
166
211
|
}
|
|
167
212
|
: undefined,
|
|
213
|
+
...(input.auditability ? { auditability: input.auditability } : {}),
|
|
168
214
|
capabilities: input.capabilities,
|
|
169
215
|
};
|
|
170
216
|
return { ...input, fingerprint: hashString(canonicalStringify(stablePayload)) };
|
|
@@ -178,6 +224,32 @@ function runtime(executor, model, kind, capabilities, extra = {}) {
|
|
|
178
224
|
...extra,
|
|
179
225
|
});
|
|
180
226
|
}
|
|
227
|
+
function ownPackage() {
|
|
228
|
+
const packageJson = findNearestPackageJson(fileURLToPath(import.meta.url));
|
|
229
|
+
if (!packageJson)
|
|
230
|
+
return { name: 'oh-my-knowledge', error: 'package.json not found' };
|
|
231
|
+
try {
|
|
232
|
+
const pkg = JSON.parse(readFileSync(packageJson, 'utf-8'));
|
|
233
|
+
return {
|
|
234
|
+
name: pkg.name ?? 'oh-my-knowledge',
|
|
235
|
+
...(pkg.version ? { version: pkg.version } : {}),
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
return {
|
|
240
|
+
name: 'oh-my-knowledge',
|
|
241
|
+
error: error instanceof Error ? error.message : String(error),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
function dshCompositionHash(identity) {
|
|
246
|
+
return createHash('sha256').update(canonicalStringify({
|
|
247
|
+
adapter: 'omk-dsh-host-v1',
|
|
248
|
+
provider: identity.provider ?? null,
|
|
249
|
+
agentPreset: identity.agentPreset ?? null,
|
|
250
|
+
toolSchemas: identity.toolSchemas ?? null,
|
|
251
|
+
})).digest('hex');
|
|
252
|
+
}
|
|
181
253
|
function runtimeEnv(options) {
|
|
182
254
|
return options?.env ?? buildExecEnv(options?.skillDir);
|
|
183
255
|
}
|
|
@@ -245,48 +317,63 @@ function scriptRuntime(executorName, model, env) {
|
|
|
245
317
|
},
|
|
246
318
|
});
|
|
247
319
|
}
|
|
320
|
+
export function createDshHostRuntimeFingerprint(model, identity = {}) {
|
|
321
|
+
const descriptor = getExecutorDescriptor('dsh-host');
|
|
322
|
+
if (!descriptor || descriptor.name !== 'dsh-host') {
|
|
323
|
+
throw new Error('dsh-host executor descriptor is missing');
|
|
324
|
+
}
|
|
325
|
+
const host = readInvokingDshPackage();
|
|
326
|
+
return runtime(descriptor.name, model, descriptor.runtimeKind, descriptor.runtimeCapabilities, {
|
|
327
|
+
binary: {
|
|
328
|
+
name: '@deepseek-ai/dsh',
|
|
329
|
+
source: host.package.version ? 'path' : 'unknown',
|
|
330
|
+
...(host.package.version ? { version: host.package.version } : {}),
|
|
331
|
+
...(host.entrypoint ? { path: host.entrypoint } : {}),
|
|
332
|
+
contentHash: dshCompositionHash(identity),
|
|
333
|
+
package: host.package,
|
|
334
|
+
...(host.package.error ? { error: host.package.error } : {}),
|
|
335
|
+
},
|
|
336
|
+
sdk: ownPackage(),
|
|
337
|
+
auditability: {
|
|
338
|
+
status: 'partial',
|
|
339
|
+
reasons: [
|
|
340
|
+
'DSH does not expose a canonical digest for every active plugin and policy; the fingerprint covers provider, agent preset, and effective tool schemas',
|
|
341
|
+
],
|
|
342
|
+
},
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
export function resolveExecutorRuntimeFingerprint(executorName, model, options = {}, executor) {
|
|
346
|
+
return executor?.runtimeFingerprint?.(model, options)
|
|
347
|
+
?? getExecutorRuntimeFingerprint(executorName, model, options);
|
|
348
|
+
}
|
|
248
349
|
export function getExecutorRuntimeFingerprint(executorName, model, options = {}) {
|
|
249
350
|
const env = runtimeEnv(options);
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
'claude-sdk',
|
|
253
|
-
'codex',
|
|
254
|
-
'codex-sdk',
|
|
255
|
-
'gemini',
|
|
256
|
-
'anthropic-api',
|
|
257
|
-
'openai-api',
|
|
258
|
-
].includes(executorName)) {
|
|
351
|
+
const descriptor = getExecutorDescriptor(executorName);
|
|
352
|
+
if (!descriptor) {
|
|
259
353
|
// Custom executors are local code. Re-read their referenced files so a
|
|
260
354
|
// long-running Studio process cannot reuse stale outputs after the script
|
|
261
355
|
// changes while the command line remains identical.
|
|
262
356
|
return scriptRuntime(executorName, model, env);
|
|
263
357
|
}
|
|
358
|
+
if (descriptor.fingerprint.strategy === 'dsh-host') {
|
|
359
|
+
return createDshHostRuntimeFingerprint(model);
|
|
360
|
+
}
|
|
264
361
|
const pathHash = hashString(env.PATH || '');
|
|
265
362
|
const cacheKey = `${executorName}\0${model}\0${pathHash}`;
|
|
266
363
|
const cached = RUNTIME_CACHE.get(cacheKey);
|
|
267
364
|
if (cached)
|
|
268
365
|
return structuredClone(cached);
|
|
269
366
|
let fp;
|
|
270
|
-
switch (
|
|
271
|
-
case '
|
|
272
|
-
fp = runtime(
|
|
273
|
-
systemPrompt: 'native',
|
|
274
|
-
costUSD: 'reported',
|
|
275
|
-
trace: 'native',
|
|
276
|
-
skillIsolation: 'full-no-partial',
|
|
277
|
-
}, { binary: readPathBinary('claude', env) });
|
|
367
|
+
switch (descriptor.fingerprint.strategy) {
|
|
368
|
+
case 'path-cli': {
|
|
369
|
+
fp = runtime(descriptor.name, model, descriptor.runtimeKind, descriptor.runtimeCapabilities, { binary: readPathBinary(descriptor.fingerprint.command, env) });
|
|
278
370
|
break;
|
|
279
371
|
}
|
|
280
372
|
case 'claude-sdk': {
|
|
281
373
|
const sdkPackageJson = resolvePackageJson('@anthropic-ai/claude-agent-sdk');
|
|
282
374
|
const sdk = readPackage('@anthropic-ai/claude-agent-sdk', sdkPackageJson ?? undefined);
|
|
283
375
|
const claudeCodeVersion = readPackageField('@anthropic-ai/claude-agent-sdk', 'claudeCodeVersion', sdkPackageJson ?? undefined);
|
|
284
|
-
fp = runtime(
|
|
285
|
-
systemPrompt: 'native',
|
|
286
|
-
costUSD: 'reported',
|
|
287
|
-
trace: 'native',
|
|
288
|
-
skillIsolation: 'full',
|
|
289
|
-
}, {
|
|
376
|
+
fp = runtime(descriptor.name, model, descriptor.runtimeKind, descriptor.runtimeCapabilities, {
|
|
290
377
|
sdk,
|
|
291
378
|
binary: {
|
|
292
379
|
name: 'claude-code',
|
|
@@ -297,25 +384,11 @@ export function getExecutorRuntimeFingerprint(executorName, model, options = {})
|
|
|
297
384
|
});
|
|
298
385
|
break;
|
|
299
386
|
}
|
|
300
|
-
case 'codex': {
|
|
301
|
-
fp = runtime(executorName, model, 'agent-cli', {
|
|
302
|
-
systemPrompt: 'prepended',
|
|
303
|
-
costUSD: 'not-reported',
|
|
304
|
-
trace: 'best-effort',
|
|
305
|
-
skillIsolation: 'cwd-only',
|
|
306
|
-
}, { binary: readPathBinary('codex', env) });
|
|
307
|
-
break;
|
|
308
|
-
}
|
|
309
387
|
case 'codex-sdk': {
|
|
310
388
|
const sdkPackageJson = resolvePackageJson('@openai/codex-sdk');
|
|
311
389
|
const sdk = readPackage('@openai/codex-sdk', sdkPackageJson ?? undefined);
|
|
312
390
|
const bundledCodex = readPackage('@openai/codex', sdkPackageJson ?? undefined);
|
|
313
|
-
fp = runtime(
|
|
314
|
-
systemPrompt: 'prepended',
|
|
315
|
-
costUSD: 'not-reported',
|
|
316
|
-
trace: 'best-effort',
|
|
317
|
-
skillIsolation: 'cwd-only',
|
|
318
|
-
}, {
|
|
391
|
+
fp = runtime(descriptor.name, model, descriptor.runtimeKind, descriptor.runtimeCapabilities, {
|
|
319
392
|
sdk,
|
|
320
393
|
binary: {
|
|
321
394
|
name: 'codex',
|
|
@@ -326,27 +399,14 @@ export function getExecutorRuntimeFingerprint(executorName, model, options = {})
|
|
|
326
399
|
});
|
|
327
400
|
break;
|
|
328
401
|
}
|
|
329
|
-
case '
|
|
330
|
-
fp = runtime(
|
|
331
|
-
systemPrompt: 'prepended',
|
|
332
|
-
costUSD: 'not-reported',
|
|
333
|
-
trace: 'none',
|
|
334
|
-
skillIsolation: 'none',
|
|
335
|
-
}, { binary: readPathBinary('gemini', env) });
|
|
402
|
+
case 'api': {
|
|
403
|
+
fp = runtime(descriptor.name, model, descriptor.runtimeKind, descriptor.runtimeCapabilities, { binary: { name: descriptor.name, source: 'none' } });
|
|
336
404
|
break;
|
|
337
405
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
systemPrompt: 'native',
|
|
342
|
-
costUSD: 'not-reported',
|
|
343
|
-
trace: 'none',
|
|
344
|
-
skillIsolation: 'none',
|
|
345
|
-
}, { binary: { name: executorName, source: 'none' } });
|
|
346
|
-
break;
|
|
406
|
+
default: {
|
|
407
|
+
const unreachable = descriptor.fingerprint;
|
|
408
|
+
throw new Error(`unreachable executor fingerprint strategy: ${JSON.stringify(unreachable)}`);
|
|
347
409
|
}
|
|
348
|
-
default:
|
|
349
|
-
throw new Error(`unreachable executor runtime: ${executorName}`);
|
|
350
410
|
}
|
|
351
411
|
RUNTIME_CACHE.set(cacheKey, structuredClone(fp));
|
|
352
412
|
return structuredClone(fp);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ExecResult } from '../../types/index.js';
|
|
2
|
+
export interface ExecutorErrorLike {
|
|
3
|
+
message?: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
killed?: boolean;
|
|
6
|
+
stdout?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function asErrorLike(err: unknown): ExecutorErrorLike;
|
|
9
|
+
export declare function errorMessage(err: unknown, fallback?: string): string;
|
|
10
|
+
export declare function buildExecEnv(skillDir?: string | null): NodeJS.ProcessEnv;
|
|
11
|
+
export declare function timeoutExecResult(timeoutMs: number, durationMs: number): ExecResult;
|
|
12
|
+
export declare function interruptedExecResult(durationMs: number): ExecResult;
|