@fusionkit/protocol 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.
Files changed (45) hide show
  1. package/dist/api.d.ts +106 -0
  2. package/dist/api.js +6 -0
  3. package/dist/chain.d.ts +14 -0
  4. package/dist/chain.js +49 -0
  5. package/dist/constants.d.ts +25 -0
  6. package/dist/constants.js +36 -0
  7. package/dist/contract.d.ts +6 -0
  8. package/dist/contract.js +32 -0
  9. package/dist/execution.d.ts +67 -0
  10. package/dist/execution.js +27 -0
  11. package/dist/generated/model-fusion-openapi.d.ts +44 -0
  12. package/dist/generated/model-fusion-openapi.js +23 -0
  13. package/dist/hash.d.ts +10 -0
  14. package/dist/hash.js +31 -0
  15. package/dist/index.d.ts +42 -0
  16. package/dist/index.js +30 -0
  17. package/dist/jcs.d.ts +14 -0
  18. package/dist/jcs.js +49 -0
  19. package/dist/keys.d.ts +14 -0
  20. package/dist/keys.js +36 -0
  21. package/dist/model-fusion.d.ts +167 -0
  22. package/dist/model-fusion.js +596 -0
  23. package/dist/receipt-story.d.ts +27 -0
  24. package/dist/receipt-story.js +127 -0
  25. package/dist/receipt.d.ts +20 -0
  26. package/dist/receipt.js +162 -0
  27. package/dist/test/model-fusion.test.d.ts +1 -0
  28. package/dist/test/model-fusion.test.js +213 -0
  29. package/dist/test/protocol.test.d.ts +1 -0
  30. package/dist/test/protocol.test.js +240 -0
  31. package/dist/test/tool-executor.test.d.ts +1 -0
  32. package/dist/test/tool-executor.test.js +86 -0
  33. package/dist/test/trace.test.d.ts +1 -0
  34. package/dist/test/trace.test.js +75 -0
  35. package/dist/tool-executor.d.ts +58 -0
  36. package/dist/tool-executor.js +80 -0
  37. package/dist/trace.d.ts +119 -0
  38. package/dist/trace.js +248 -0
  39. package/dist/types.d.ts +375 -0
  40. package/dist/types.js +14 -0
  41. package/dist/validators.d.ts +7 -0
  42. package/dist/validators.js +32 -0
  43. package/dist/vocabulary.d.ts +12 -0
  44. package/dist/vocabulary.js +79 -0
  45. package/package.json +27 -0
package/dist/keys.js ADDED
@@ -0,0 +1,36 @@
1
+ import { createPrivateKey, createPublicKey, generateKeyPairSync, sign as cryptoSign, verify as cryptoVerify } from "node:crypto";
2
+ import { KEY_ID_HEX_LENGTH } from "./constants.js";
3
+ import { sha256Hex } from "./hash.js";
4
+ export function generateEd25519KeyPair() {
5
+ const { publicKey, privateKey } = generateKeyPairSync("ed25519");
6
+ return {
7
+ publicKeyPem: publicKey.export({ type: "spki", format: "pem" }).toString(),
8
+ privateKeyPem: privateKey
9
+ .export({ type: "pkcs8", format: "pem" })
10
+ .toString()
11
+ };
12
+ }
13
+ /**
14
+ * Stable identifier for a public key: the algorithm tag plus a truncated
15
+ * SHA-256 fingerprint of its PEM. The fingerprint length is a deliberate,
16
+ * shared constant (KEY_ID_HEX_LENGTH) — 64 bits is ample to identify an
17
+ * enrolled key while keeping ids short.
18
+ */
19
+ export function keyIdFromPublicPem(publicKeyPem) {
20
+ return `ed25519:${sha256Hex(publicKeyPem.trim()).slice(0, KEY_ID_HEX_LENGTH)}`;
21
+ }
22
+ export function signData(privateKeyPem, data) {
23
+ const key = createPrivateKey(privateKeyPem);
24
+ const payload = typeof data === "string" ? Buffer.from(data, "utf8") : data;
25
+ return cryptoSign(null, payload, key).toString("base64");
26
+ }
27
+ export function verifyData(publicKeyPem, data, signatureB64) {
28
+ const key = createPublicKey(publicKeyPem);
29
+ const payload = typeof data === "string" ? Buffer.from(data, "utf8") : data;
30
+ try {
31
+ return cryptoVerify(null, payload, key, Buffer.from(signatureB64, "base64"));
32
+ }
33
+ catch {
34
+ return false;
35
+ }
36
+ }
@@ -0,0 +1,167 @@
1
+ import type { JsonValue } from "./jcs.js";
2
+ export declare const MODEL_FUSION_SCHEMA_NAMES: readonly ["model-call-record.v1", "harness-run-request.v1", "harness-run-result.v1", "harness-candidate-record.v1", "judge-synthesis-record.v1", "benchmark-task-record.v1", "artifact-ref.v1", "tool-call-plan.v1", "tool-execution-record.v1", "ensemble-receipt.v1"];
3
+ export declare const MODEL_FUSION_SCHEMA_BUNDLE_HASH = "sha256:75792f89c091b6ab4fd317a15fb03fd73438563dceff5ccf9f5d7c752dbf35f3";
4
+ export type ModelFusionSchemaName = (typeof MODEL_FUSION_SCHEMA_NAMES)[number];
5
+ export type ModelFusionStatus = "pending" | "running" | "succeeded" | "failed" | "canceled" | "requires_action" | "skipped" | "unsupported";
6
+ export type ModelFusionSideEffects = "none" | "read_only" | "writes_workspace" | "network" | "tool_execution" | "unknown";
7
+ export type ModelFusionHarnessKind = "generic" | "cursor" | "claude_code" | "codex" | "openai_responses";
8
+ export type ModelFusionCapabilityStatus = "supported" | "unsupported" | "degraded" | "unknown";
9
+ export type ModelFusionArtifactKind = "patch" | "log" | "transcript" | "metrics" | "benchmark_task" | "worktree" | "receipt" | "other";
10
+ export type ModelFusionRedactionStatus = "synthetic" | "redacted" | "raw";
11
+ export type ModelFusionErrorKind = "none" | "provider_error" | "validation_error" | "timeout" | "rate_limited" | "tool_denied" | "secret_denied" | "capability_missing" | "internal_error";
12
+ export type ModelFusionChatRole = "system" | "user" | "assistant" | "tool";
13
+ export type BenchmarkTaskKind = "model_fusion" | "harness_coding";
14
+ export type BenchmarkSourceRepo = "fusionkit" | "handoffkit" | "cursorkit" | "mlx-lm";
15
+ export type BenchmarkScorerKind = "exact" | "contains" | "record_join" | "custom";
16
+ export type JudgeSynthesisDecision = "synthesize" | "select_candidate" | "repair_required" | "failed";
17
+ export type ContractMetadataV1<S extends ModelFusionSchemaName> = {
18
+ schema: S;
19
+ schema_version: "v1";
20
+ schema_bundle_hash: string;
21
+ producer: string;
22
+ producer_version: string;
23
+ producer_git_sha: string;
24
+ created_at: string;
25
+ };
26
+ export type ModelFusionChatMessage = {
27
+ role: ModelFusionChatRole;
28
+ content: string;
29
+ };
30
+ export type ModelFusionUsage = {
31
+ prompt_tokens?: number;
32
+ completion_tokens?: number;
33
+ total_tokens?: number;
34
+ };
35
+ export type ModelFusionError = {
36
+ kind: ModelFusionErrorKind;
37
+ message?: string;
38
+ retryable?: boolean;
39
+ };
40
+ export type ArtifactRef = {
41
+ artifact_id: string;
42
+ kind: ModelFusionArtifactKind;
43
+ uri?: string;
44
+ hash: string;
45
+ redaction_status?: ModelFusionRedactionStatus;
46
+ };
47
+ export type ArtifactRefV1 = ContractMetadataV1<"artifact-ref.v1"> & ArtifactRef;
48
+ export type ModelCallRecordV1 = ContractMetadataV1<"model-call-record.v1"> & {
49
+ call_id: string;
50
+ endpoint_id: string;
51
+ provider_request_id?: string;
52
+ model: string;
53
+ request_hash: string;
54
+ response_hash?: string;
55
+ messages: ModelFusionChatMessage[];
56
+ status: ModelFusionStatus;
57
+ side_effects: ModelFusionSideEffects;
58
+ started_at: string;
59
+ finished_at?: string;
60
+ latency_ms?: number;
61
+ usage?: ModelFusionUsage;
62
+ output_text?: string;
63
+ error?: ModelFusionError;
64
+ metadata?: Record<string, JsonValue>;
65
+ };
66
+ export type HarnessRunRequestV1 = ContractMetadataV1<"harness-run-request.v1"> & {
67
+ request_id: string;
68
+ harness_kind: ModelFusionHarnessKind;
69
+ source_repo: string;
70
+ base_git_sha: string;
71
+ prompt: string;
72
+ prompt_hash: string;
73
+ allowed_tools?: string[];
74
+ side_effects: ModelFusionSideEffects;
75
+ requested_capabilities: Record<string, ModelFusionCapabilityStatus>;
76
+ metadata?: Record<string, JsonValue>;
77
+ };
78
+ export type HarnessRunResultV1 = ContractMetadataV1<"harness-run-result.v1"> & {
79
+ result_id: string;
80
+ request_id: string;
81
+ harness_kind: ModelFusionHarnessKind;
82
+ status: ModelFusionStatus;
83
+ candidate_ids: string[];
84
+ output_summary?: string;
85
+ artifacts?: ArtifactRef[];
86
+ capabilities: Record<string, ModelFusionCapabilityStatus>;
87
+ started_at: string;
88
+ finished_at?: string;
89
+ errors?: ModelFusionError[];
90
+ metadata?: Record<string, JsonValue>;
91
+ };
92
+ export type HarnessCandidateRecordV1 = ContractMetadataV1<"harness-candidate-record.v1"> & {
93
+ candidate_id: string;
94
+ request_id: string;
95
+ harness_kind: ModelFusionHarnessKind;
96
+ model_call_id?: string;
97
+ status: ModelFusionStatus;
98
+ side_effects: ModelFusionSideEffects;
99
+ branch_name?: string;
100
+ worktree_path?: string;
101
+ artifacts?: ArtifactRef[];
102
+ score?: number;
103
+ error?: ModelFusionError;
104
+ metadata?: Record<string, JsonValue>;
105
+ };
106
+ export type JudgeSynthesisRecordV1 = ContractMetadataV1<"judge-synthesis-record.v1"> & {
107
+ synthesis_id: string;
108
+ judge_model_call_id?: string;
109
+ input_candidate_ids: string[];
110
+ status: ModelFusionStatus;
111
+ decision: JudgeSynthesisDecision;
112
+ selected_candidate_id?: string;
113
+ rationale?: string;
114
+ final_output: string;
115
+ score?: number;
116
+ metrics?: Record<string, JsonValue>;
117
+ };
118
+ export type BenchmarkScorer = {
119
+ kind: BenchmarkScorerKind;
120
+ params?: Record<string, JsonValue>;
121
+ };
122
+ export type BenchmarkTaskRecordV1 = ContractMetadataV1<"benchmark-task-record.v1"> & {
123
+ task_id: string;
124
+ task_kind: BenchmarkTaskKind;
125
+ source_repo: BenchmarkSourceRepo;
126
+ source_sha: string;
127
+ prompt?: string;
128
+ prompt_hash: string;
129
+ setup_hash: string;
130
+ expected_evidence: string[];
131
+ scorer: BenchmarkScorer;
132
+ holdout: boolean;
133
+ contamination_notes: string;
134
+ allowed_tools: string[];
135
+ };
136
+ export type ToolCallPlanV1 = ContractMetadataV1<"tool-call-plan.v1"> & {
137
+ plan_id: string;
138
+ tool_name: string;
139
+ arguments_hash: string;
140
+ side_effects: ModelFusionSideEffects;
141
+ status: ModelFusionStatus;
142
+ };
143
+ export type ToolExecutionRecordV1 = ContractMetadataV1<"tool-execution-record.v1"> & {
144
+ execution_id: string;
145
+ plan_id: string;
146
+ status: ModelFusionStatus;
147
+ output_hash?: string;
148
+ error?: ModelFusionError;
149
+ };
150
+ export type EnsembleReceiptV1 = ContractMetadataV1<"ensemble-receipt.v1"> & {
151
+ receipt_id: string;
152
+ run_id: string;
153
+ status: ModelFusionStatus;
154
+ artifact_hashes: string[];
155
+ };
156
+ export type ModelFusionRecordV1 = ModelCallRecordV1 | HarnessRunRequestV1 | HarnessRunResultV1 | HarnessCandidateRecordV1 | JudgeSynthesisRecordV1 | BenchmarkTaskRecordV1 | ArtifactRefV1 | ToolCallPlanV1 | ToolExecutionRecordV1 | EnsembleReceiptV1;
157
+ export declare function assertArtifactRefV1(value: unknown): asserts value is ArtifactRefV1;
158
+ export declare function assertModelCallRecordV1(value: unknown): asserts value is ModelCallRecordV1;
159
+ export declare function assertHarnessRunRequestV1(value: unknown): asserts value is HarnessRunRequestV1;
160
+ export declare function assertHarnessRunResultV1(value: unknown): asserts value is HarnessRunResultV1;
161
+ export declare function assertHarnessCandidateRecordV1(value: unknown): asserts value is HarnessCandidateRecordV1;
162
+ export declare function assertJudgeSynthesisRecordV1(value: unknown): asserts value is JudgeSynthesisRecordV1;
163
+ export declare function assertBenchmarkTaskRecordV1(value: unknown): asserts value is BenchmarkTaskRecordV1;
164
+ export declare function assertToolCallPlanV1(value: unknown): asserts value is ToolCallPlanV1;
165
+ export declare function assertToolExecutionRecordV1(value: unknown): asserts value is ToolExecutionRecordV1;
166
+ export declare function assertEnsembleReceiptV1(value: unknown): asserts value is EnsembleReceiptV1;
167
+ export declare function assertModelFusionRecord(value: unknown): asserts value is ModelFusionRecordV1;