abelien-harness 0.4.0 → 0.6.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/.env.example +4 -0
- package/README.md +11 -18
- package/package.json +2 -3
- package/skills/abelien-appearance/SKILL.md +1 -0
- package/skills/abelien-clarify/SKILL.md +12 -2
- package/skills/abelien-clarify/references/examples.md +22 -0
- package/skills/abelien-clarify/scripts/check_result.py +38 -3
- package/skills/abelien-clarify/scripts/test_check_result.py +32 -1
- package/skills/abelien-guide/SKILL.md +1 -1
- package/skills/abelien-hardware/SKILL.md +10 -5
- package/skills/abelien-hardware/domain.json +3 -3
- package/skills/abelien-hardware/references/search-index-format.md +13 -1
- package/skills/abelien-hardware/references/search-index-release.md +4 -2
- package/skills/abelien-hardware/references/web-evidence-contract.md +3 -3
- package/skills/abelien-hardware/scripts/dimensions.mjs +23 -8
- package/skills/abelien-hardware/scripts/electrical.mjs +168 -0
- package/skills/abelien-hardware/scripts/finalize-selection.mjs +4 -2
- package/skills/abelien-hardware/scripts/provider-chain-contract.mjs +27 -6
- package/skills/abelien-hardware/scripts/public-page.mjs +11 -121
- package/skills/abelien-hardware/scripts/response-redaction.mjs +1 -130
- package/skills/abelien-hardware/scripts/search-index-release.mjs +30 -17
- package/skills/abelien-hardware/scripts/selection-request.mjs +6 -5
- package/skills/abelien-hardware/scripts/tos-wiki-search.mjs +13 -8
- package/skills/abelien-hardware/scripts/volc-web-search.mjs +10 -27
- package/skills/abelien-hardware/scripts/web-common.mjs +8 -11
- package/skills/abelien-hardware/scripts/web-integrity.mjs +1 -1
- package/skills/abelien-hardware/scripts/web-provider-chain.mjs +10 -3
- package/skills/abelien-hardware/scripts/web-receipt.mjs +4 -2
- package/skills/abelien-hardware/scripts/web-search-plan.mjs +21 -2
- package/skills/abelien-hardware/scripts/web-search.mjs +5 -2
- package/skills/abelien-hardware-selection/SKILL.md +1 -1
- package/skills/abelien-hardware-selection/domain.json +2 -2
- package/skills/abelien-hardware-selection/references/selection-service-contract.md +30 -3
- package/skills/abelien-hardware-selection/scripts/select.mjs +35 -8
- package/skills/abelien-harness/scripts/ab.mjs +24 -2
- package/skills/abelien-harness/scripts/web/common.mjs +20 -0
- package/skills/abelien-harness/scripts/web/public-read.mjs +168 -0
- package/skills/abelien-harness/scripts/web/redact.mjs +136 -0
- package/skills/abelien-harness/scripts/web/volc.mjs +49 -0
- package/skills/abelien-reference/SKILL.md +51 -0
- package/skills/abelien-reference/domain.json +92 -0
- package/skills/abelien-reference/fixtures/create.final.json +102 -0
- package/skills/abelien-reference/fixtures/restore.collected.json +189 -0
- package/skills/abelien-reference/fixtures/restore.final.json +267 -0
- package/skills/abelien-reference/references/research-contract.md +74 -0
- package/skills/abelien-reference/schemas/reference-evidence.v1.json +140 -0
- package/skills/abelien-reference/scripts/evidence.mjs +60 -0
- package/skills/abelien-reference/scripts/finalize.mjs +116 -0
- package/skills/abelien-reference/scripts/measure.mjs +62 -0
- package/skills/abelien-reference/scripts/png.mjs +86 -0
- package/skills/abelien-reference/scripts/research.mjs +179 -0
- package/skills/abelien-structure/SKILL.md +2 -2
- package/skills/abelien-structure/domain.json +64 -0
- package/skills/abelien-structure/references/build123d-execution.md +1 -1
- package/skills/abelien-structure/references/handoff.md +1 -1
- package/skills/abelien-structure/worker/abelien_cad.py +585 -0
- package/skills/abelien-structure/worker/assembly-validation.mjs +106 -0
- package/skills/abelien-structure/worker/cad.py +1623 -0
- package/skills/abelien-structure/worker/cli-adapter.mjs +207 -0
- package/skills/abelien-structure/worker/component-fit-glb.mjs +173 -0
- package/skills/abelien-structure/worker/component-fit.d.mts +82 -0
- package/skills/abelien-structure/worker/component-fit.mjs +167 -0
- package/skills/abelien-structure/worker/component-target-image.d.mts +23 -0
- package/skills/abelien-structure/worker/component-target-image.mjs +107 -0
- package/skills/abelien-structure/worker/component-target-render.py +58 -0
- package/skills/abelien-structure/worker/config.mjs +6 -0
- package/skills/abelien-structure/worker/engineering-fit.d.mts +48 -0
- package/skills/abelien-structure/worker/engineering-fit.mjs +118 -0
- package/skills/abelien-structure/worker/engineering-policy.json +16 -0
- package/skills/abelien-structure/worker/engineering-repair.py +147 -0
- package/skills/abelien-structure/worker/engineering.py +324 -0
- package/skills/abelien-structure/worker/identity.mjs +98 -0
- package/skills/abelien-structure/worker/inspection-geometry.mjs +71 -0
- package/skills/abelien-structure/worker/jobs.mjs +451 -0
- package/skills/abelien-structure/worker/library-runtime.mjs +15 -0
- package/skills/abelien-structure/worker/main.mjs +102 -0
- package/skills/abelien-structure/worker/manifest-digest.mjs +11 -0
- package/skills/abelien-structure/worker/materials.mjs +52 -0
- package/skills/abelien-structure/worker/native-launcher.py +13 -0
- package/skills/abelien-structure/worker/native.mjs +157 -0
- package/skills/abelien-structure/worker/representation.mjs +47 -0
- package/skills/abelien-structure/worker/sandbox.mjs +41 -0
- package/skills/abelien-structure/worker/source-contract.mjs +143 -0
- package/skills/abelien-structure/worker/source_call_stats.py +59 -0
- package/skills/abelien-structure/worker/supervisor.mjs +38 -0
- package/skills/abelien-workspace/SKILL.md +11 -0
- package/skills/abelien-workspace/assets/journey-stage-plan.json +155 -0
- package/skills/abelien-workspace/domain.json +25 -2
- package/skills/abelien-workspace/references/hardware-journey-orchestration.md +1 -1
- package/skills/abelien-workspace/references/harness-binding.md +2 -2
- package/skills/abelien-workspace/references/user-journey.md +10 -0
- package/skills/abelien-workspace/scripts/journey-next.mjs +38 -0
- package/skills/abelien-workspace/workflows/definitions/0852e4949f5a6246880c1a26bf5ccaa42f8cda06b960e7c7ce234a0a176878f9.json +229 -0
- package/skills/abelien-workspace/workflows/definitions/399ef372790b7330d0ef88ce5096e7f69943d4793de97b2ed6c25165a332612f.json +230 -0
- package/skills/abelien-workspace/workflows/definitions/591a7f21e0b0ad586e340163f7533ac910356091ba8d2a26e250c0acbc80cd8b.json +176 -0
- package/skills/abelien-workspace/workflows/definitions/7c69ea0d51099b1ae947f08b056ea67f5cad6b40ae8bcb00efb496fa5b9d5ed3.json +149 -0
- package/skills/abelien-workspace/workflows/definitions/9b5c65ad03fdecc0148931a7677cfa684a3fb04ab2738d6f7a1086a2c79ac86c.json +149 -0
- package/skills/abelien-workspace/workflows/definitions/c1b5c6c653f0c4761d51efee923aafbbeea05512e7f35c60f7f7d36ec49fc1d1.json +229 -0
- package/skills/abelien-workspace/workflows/definitions/d9f8c6cdf0b2c41cdeb1c72ac5d1e37d95a7caac3272d434a3c7e8483fc565de.json +150 -0
- package/skills/abelien-workspace/workflows/definitions/e391e14c14cb39408a0a9e226ed54ffab7a36badea305ae4a3eafbac8124fc02.json +175 -0
- package/skills/abelien-workspace/workflows/definitions/fd8ce7074e2044985778446e93153864940bb9465471c1c71c41328cefff70bf.json +175 -0
- package/skills/abelien-workspace/workflows/user-journey-hardware-algorithm.json +5 -4
- package/skills/abelien-workspace/workflows/user-journey-hardware-candidates.json +5 -4
- package/skills/abelien-workspace/workflows/user-journey-hardware.json +5 -4
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"budget": {
|
|
3
|
+
"images": 0,
|
|
4
|
+
"pages": 1,
|
|
5
|
+
"queries": 1
|
|
6
|
+
},
|
|
7
|
+
"changeable": [
|
|
8
|
+
"外形",
|
|
9
|
+
"尺寸"
|
|
10
|
+
],
|
|
11
|
+
"depth": null,
|
|
12
|
+
"id": "ref-c26edd6284aed5b5-f89f84f29",
|
|
13
|
+
"images": [],
|
|
14
|
+
"intent": "create",
|
|
15
|
+
"items": [
|
|
16
|
+
{
|
|
17
|
+
"id": "u1",
|
|
18
|
+
"image": null,
|
|
19
|
+
"kind": "user_input",
|
|
20
|
+
"query": null,
|
|
21
|
+
"role": "做一个放在床头、能讲睡前故事的小音箱",
|
|
22
|
+
"source": null,
|
|
23
|
+
"status": "ready",
|
|
24
|
+
"title": "你的输入",
|
|
25
|
+
"verdict": null
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "p1",
|
|
29
|
+
"image": null,
|
|
30
|
+
"kind": "similar",
|
|
31
|
+
"query": "bedside story speaker teardown",
|
|
32
|
+
"role": "相似产品",
|
|
33
|
+
"source": {
|
|
34
|
+
"site": "shop.example.com",
|
|
35
|
+
"url": "https://shop.example.com/story-a"
|
|
36
|
+
},
|
|
37
|
+
"status": "ready",
|
|
38
|
+
"title": "床头故事机 A",
|
|
39
|
+
"verdict": {
|
|
40
|
+
"code": "borrowed",
|
|
41
|
+
"basis": "借用:300 mL 声腔与 40 mm 全频喇叭;原因:体积与床头摆放相近;不照搬:外观与按键布局"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"keep": [],
|
|
46
|
+
"pages": [
|
|
47
|
+
{
|
|
48
|
+
"excerpt": "床头故事机 A 腔体容积 300 mL,40 mm 全频喇叭,电池 2000 mAh。",
|
|
49
|
+
"final_url": "https://shop.example.com/story-a",
|
|
50
|
+
"id": "p1",
|
|
51
|
+
"image_url": null,
|
|
52
|
+
"purpose": "similar",
|
|
53
|
+
"raw_sha256": "db701b787482d7ae3c2967323df3013d93df7c7e628a801ab091218f55a1b87d",
|
|
54
|
+
"reason": null,
|
|
55
|
+
"search_id": "s1",
|
|
56
|
+
"status": "read",
|
|
57
|
+
"text_blob_ref": "sha256:a871926ca4bf9606ff9abc75f7b5da5a99a41c7535f03e9572095b1a272b32bc",
|
|
58
|
+
"text_sha256": "58a51339bbda6d0a69d726e2768faf47752f8529630a4705e5fe81552e187dff",
|
|
59
|
+
"title": "床头故事机 A",
|
|
60
|
+
"url": "https://shop.example.com/story-a"
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"request_digest": "c26edd6284aed5b521396a1093bc0aeb9ff60d24f2c68d6bcf98a6529bd9c325",
|
|
64
|
+
"schema": "abelien.reference-evidence.v1",
|
|
65
|
+
"searches": [
|
|
66
|
+
{
|
|
67
|
+
"count": 3,
|
|
68
|
+
"error_code": null,
|
|
69
|
+
"id": "s1",
|
|
70
|
+
"purpose": "similar",
|
|
71
|
+
"query": "bedside story speaker teardown",
|
|
72
|
+
"receipt_sha256": "b4f07afb377bbf9556aef08b61cebb2bf0264df8924f91b712227186cd7157bc",
|
|
73
|
+
"request_id": "req-[redacted]",
|
|
74
|
+
"results": [
|
|
75
|
+
{
|
|
76
|
+
"rank": 1,
|
|
77
|
+
"snippet": "",
|
|
78
|
+
"title": "Story box A",
|
|
79
|
+
"url": "https://shop.example.com/story-a"
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
"status": "completed"
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
"status": "final",
|
|
86
|
+
"text": "做一个放在床头、能讲睡前故事的小音箱",
|
|
87
|
+
"unknowns": [],
|
|
88
|
+
"user_image": null,
|
|
89
|
+
"collected_id": "ref-c26edd6284aed5b5",
|
|
90
|
+
"judgement_digest": "89f84f293a6781fed8f80ea7f03d57da892c67f70bfdd836003421f88b2b0730",
|
|
91
|
+
"identity": null,
|
|
92
|
+
"similar": [
|
|
93
|
+
{
|
|
94
|
+
"item_id": "p1",
|
|
95
|
+
"decision": "borrow",
|
|
96
|
+
"borrowed": "300 mL 声腔与 40 mm 全频喇叭",
|
|
97
|
+
"why": "体积与床头摆放相近",
|
|
98
|
+
"not_copied": "外观与按键布局"
|
|
99
|
+
}
|
|
100
|
+
],
|
|
101
|
+
"spec_quotes": []
|
|
102
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "ref-40ece5312c4ecbf6",
|
|
3
|
+
"schema": "abelien.reference-evidence.v1",
|
|
4
|
+
"status": "collected",
|
|
5
|
+
"request_digest": "40ece5312c4ecbf6f5548d36589de25734706b8a333d22e1a3c32adeb75e09f5",
|
|
6
|
+
"intent": "restore",
|
|
7
|
+
"keep": [
|
|
8
|
+
"外形尺寸与比例"
|
|
9
|
+
],
|
|
10
|
+
"changeable": [],
|
|
11
|
+
"depth": "assembly",
|
|
12
|
+
"text": "帮我根据图片还原小爱音箱",
|
|
13
|
+
"user_image": {
|
|
14
|
+
"blob_ref": "sha256:e2273b5b355a38441b20796072e08921b9ab30c4f37bb92070a53307af34a6f6",
|
|
15
|
+
"sha256": "da0fadd6fd3ab5ccfbac94ca4e3f2b48e440987eee6834f1c30f04c02abd5d11",
|
|
16
|
+
"media_type": "image/png",
|
|
17
|
+
"measurement": {
|
|
18
|
+
"status": "measured",
|
|
19
|
+
"method": "silhouette-v1",
|
|
20
|
+
"image": {
|
|
21
|
+
"width": 400,
|
|
22
|
+
"height": 600
|
|
23
|
+
},
|
|
24
|
+
"bbox": {
|
|
25
|
+
"x": 62,
|
|
26
|
+
"y": 49,
|
|
27
|
+
"width": 276,
|
|
28
|
+
"height": 502
|
|
29
|
+
},
|
|
30
|
+
"aspect_h_over_w": 1.8188,
|
|
31
|
+
"background": {
|
|
32
|
+
"mode": "color",
|
|
33
|
+
"rgb": [
|
|
34
|
+
255,
|
|
35
|
+
255,
|
|
36
|
+
255
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"searches": [
|
|
42
|
+
{
|
|
43
|
+
"id": "s1",
|
|
44
|
+
"purpose": "identify",
|
|
45
|
+
"query": "Xiaomi XiaoAI speaker Pro dimensions",
|
|
46
|
+
"count": 5,
|
|
47
|
+
"status": "completed",
|
|
48
|
+
"error_code": null,
|
|
49
|
+
"request_id": "req-[redacted]",
|
|
50
|
+
"receipt_sha256": "099206543e4389fde6c4838d3fc0b125dce0fb98cd57384db3062e1abcede7a8",
|
|
51
|
+
"results": [
|
|
52
|
+
{
|
|
53
|
+
"rank": 1,
|
|
54
|
+
"url": "https://www.mi.example.com/pro/specs",
|
|
55
|
+
"title": "XiaoAI Speaker Pro",
|
|
56
|
+
"snippet": ""
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"rank": 2,
|
|
60
|
+
"url": "https://www.mi.example.com/gen1/specs",
|
|
61
|
+
"title": "Mi AI Speaker",
|
|
62
|
+
"snippet": ""
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"pages": [
|
|
68
|
+
{
|
|
69
|
+
"id": "p1",
|
|
70
|
+
"url": "https://www.mi.example.com/pro/specs",
|
|
71
|
+
"purpose": "identify",
|
|
72
|
+
"search_id": "s1",
|
|
73
|
+
"status": "read",
|
|
74
|
+
"reason": null,
|
|
75
|
+
"final_url": "https://www.mi.example.com/pro/specs",
|
|
76
|
+
"title": "小爱音箱 Pro 参数",
|
|
77
|
+
"raw_sha256": "109cbac90dd51ef3dddfd21c4a97168a25f097b4211b2146d21669281d06e3b8",
|
|
78
|
+
"text_blob_ref": "sha256:a9d6a6d8668de3346efe1d94c1afd76e71faf37bee5a6e55d3a82f9bc60b9bf0",
|
|
79
|
+
"text_sha256": "bae09c2d8ac69290d90e7cf69d7809858b1149a391400d40030037db41896415",
|
|
80
|
+
"excerpt": "小爱音箱 Pro 参数 产品尺寸:118 × 118 × 215 mm,重量 1187 g。",
|
|
81
|
+
"image_url": "https://img.example.com/pro.png"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "p2",
|
|
85
|
+
"url": "https://www.mi.example.com/gen1/specs",
|
|
86
|
+
"purpose": "identify",
|
|
87
|
+
"search_id": "s1",
|
|
88
|
+
"status": "read",
|
|
89
|
+
"reason": null,
|
|
90
|
+
"final_url": "https://www.mi.example.com/gen1/specs",
|
|
91
|
+
"title": "小米AI音箱 规格",
|
|
92
|
+
"raw_sha256": "c139f165c41dc34c2cd30a816a80d7cbef9ecbda49e7496d46163c8692da33c7",
|
|
93
|
+
"text_blob_ref": "sha256:3dd43ad1e906a2e95af747cc8f8386c00b43df981af8b8bafe45bb2d173e7e3c",
|
|
94
|
+
"text_sha256": "2de9e3c9406bd62a2e9eef887fd42008382616377ac49fb751cd5a109f1e9a00",
|
|
95
|
+
"excerpt": "小米AI音箱 规格 尺寸 88 mm × 88 mm × 211.6 mm",
|
|
96
|
+
"image_url": null
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"images": [
|
|
100
|
+
{
|
|
101
|
+
"id": "i1",
|
|
102
|
+
"url": "https://img.example.com/pro.png",
|
|
103
|
+
"page_id": "p1",
|
|
104
|
+
"status": "read",
|
|
105
|
+
"reason": null,
|
|
106
|
+
"blob_ref": "sha256:e2273b5b355a38441b20796072e08921b9ab30c4f37bb92070a53307af34a6f6",
|
|
107
|
+
"sha256": "da0fadd6fd3ab5ccfbac94ca4e3f2b48e440987eee6834f1c30f04c02abd5d11",
|
|
108
|
+
"media_type": "image/png",
|
|
109
|
+
"measurement": {
|
|
110
|
+
"status": "measured",
|
|
111
|
+
"method": "silhouette-v1",
|
|
112
|
+
"image": {
|
|
113
|
+
"width": 400,
|
|
114
|
+
"height": 600
|
|
115
|
+
},
|
|
116
|
+
"bbox": {
|
|
117
|
+
"x": 62,
|
|
118
|
+
"y": 49,
|
|
119
|
+
"width": 276,
|
|
120
|
+
"height": 502
|
|
121
|
+
},
|
|
122
|
+
"aspect_h_over_w": 1.8188,
|
|
123
|
+
"background": {
|
|
124
|
+
"mode": "color",
|
|
125
|
+
"rgb": [
|
|
126
|
+
255,
|
|
127
|
+
255,
|
|
128
|
+
255
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
],
|
|
134
|
+
"items": [
|
|
135
|
+
{
|
|
136
|
+
"id": "u1",
|
|
137
|
+
"kind": "user_input",
|
|
138
|
+
"title": "你的输入",
|
|
139
|
+
"role": "帮我根据图片还原小爱音箱",
|
|
140
|
+
"source": null,
|
|
141
|
+
"image": {
|
|
142
|
+
"blob_ref": "sha256:e2273b5b355a38441b20796072e08921b9ab30c4f37bb92070a53307af34a6f6",
|
|
143
|
+
"sha256": "da0fadd6fd3ab5ccfbac94ca4e3f2b48e440987eee6834f1c30f04c02abd5d11",
|
|
144
|
+
"media_type": "image/png"
|
|
145
|
+
},
|
|
146
|
+
"verdict": null,
|
|
147
|
+
"status": "ready",
|
|
148
|
+
"query": null
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"id": "p1",
|
|
152
|
+
"kind": "candidate",
|
|
153
|
+
"title": "小爱音箱 Pro 参数",
|
|
154
|
+
"role": "候选产品",
|
|
155
|
+
"source": {
|
|
156
|
+
"url": "https://www.mi.example.com/pro/specs",
|
|
157
|
+
"site": "www.mi.example.com"
|
|
158
|
+
},
|
|
159
|
+
"image": {
|
|
160
|
+
"blob_ref": "sha256:e2273b5b355a38441b20796072e08921b9ab30c4f37bb92070a53307af34a6f6",
|
|
161
|
+
"sha256": "da0fadd6fd3ab5ccfbac94ca4e3f2b48e440987eee6834f1c30f04c02abd5d11",
|
|
162
|
+
"media_type": "image/png"
|
|
163
|
+
},
|
|
164
|
+
"verdict": null,
|
|
165
|
+
"status": "ready",
|
|
166
|
+
"query": "Xiaomi XiaoAI speaker Pro dimensions"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"id": "p2",
|
|
170
|
+
"kind": "candidate",
|
|
171
|
+
"title": "小米AI音箱 规格",
|
|
172
|
+
"role": "候选产品",
|
|
173
|
+
"source": {
|
|
174
|
+
"url": "https://www.mi.example.com/gen1/specs",
|
|
175
|
+
"site": "www.mi.example.com"
|
|
176
|
+
},
|
|
177
|
+
"image": null,
|
|
178
|
+
"verdict": null,
|
|
179
|
+
"status": "ready",
|
|
180
|
+
"query": "Xiaomi XiaoAI speaker Pro dimensions"
|
|
181
|
+
}
|
|
182
|
+
],
|
|
183
|
+
"unknowns": [],
|
|
184
|
+
"budget": {
|
|
185
|
+
"queries": 1,
|
|
186
|
+
"pages": 2,
|
|
187
|
+
"images": 1
|
|
188
|
+
}
|
|
189
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
{
|
|
2
|
+
"budget": {
|
|
3
|
+
"images": 1,
|
|
4
|
+
"pages": 2,
|
|
5
|
+
"queries": 1
|
|
6
|
+
},
|
|
7
|
+
"changeable": [],
|
|
8
|
+
"depth": "assembly",
|
|
9
|
+
"id": "ref-40ece5312c4ecbf6-fd2b162cb",
|
|
10
|
+
"images": [
|
|
11
|
+
{
|
|
12
|
+
"blob_ref": "sha256:e2273b5b355a38441b20796072e08921b9ab30c4f37bb92070a53307af34a6f6",
|
|
13
|
+
"id": "i1",
|
|
14
|
+
"measurement": {
|
|
15
|
+
"aspect_h_over_w": 1.8188,
|
|
16
|
+
"background": {
|
|
17
|
+
"mode": "color",
|
|
18
|
+
"rgb": [
|
|
19
|
+
255,
|
|
20
|
+
255,
|
|
21
|
+
255
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
"bbox": {
|
|
25
|
+
"height": 502,
|
|
26
|
+
"width": 276,
|
|
27
|
+
"x": 62,
|
|
28
|
+
"y": 49
|
|
29
|
+
},
|
|
30
|
+
"image": {
|
|
31
|
+
"height": 600,
|
|
32
|
+
"width": 400
|
|
33
|
+
},
|
|
34
|
+
"method": "silhouette-v1",
|
|
35
|
+
"status": "measured"
|
|
36
|
+
},
|
|
37
|
+
"media_type": "image/png",
|
|
38
|
+
"page_id": "p1",
|
|
39
|
+
"reason": null,
|
|
40
|
+
"sha256": "da0fadd6fd3ab5ccfbac94ca4e3f2b48e440987eee6834f1c30f04c02abd5d11",
|
|
41
|
+
"status": "read",
|
|
42
|
+
"url": "https://img.example.com/pro.png"
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"intent": "restore",
|
|
46
|
+
"items": [
|
|
47
|
+
{
|
|
48
|
+
"id": "u1",
|
|
49
|
+
"image": {
|
|
50
|
+
"blob_ref": "sha256:e2273b5b355a38441b20796072e08921b9ab30c4f37bb92070a53307af34a6f6",
|
|
51
|
+
"media_type": "image/png",
|
|
52
|
+
"sha256": "da0fadd6fd3ab5ccfbac94ca4e3f2b48e440987eee6834f1c30f04c02abd5d11"
|
|
53
|
+
},
|
|
54
|
+
"kind": "user_input",
|
|
55
|
+
"query": null,
|
|
56
|
+
"role": "帮我根据图片还原小爱音箱",
|
|
57
|
+
"source": null,
|
|
58
|
+
"status": "ready",
|
|
59
|
+
"title": "你的输入",
|
|
60
|
+
"verdict": null
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"id": "p1",
|
|
64
|
+
"image": {
|
|
65
|
+
"blob_ref": "sha256:e2273b5b355a38441b20796072e08921b9ab30c4f37bb92070a53307af34a6f6",
|
|
66
|
+
"media_type": "image/png",
|
|
67
|
+
"sha256": "da0fadd6fd3ab5ccfbac94ca4e3f2b48e440987eee6834f1c30f04c02abd5d11"
|
|
68
|
+
},
|
|
69
|
+
"kind": "candidate",
|
|
70
|
+
"query": "Xiaomi XiaoAI speaker Pro dimensions",
|
|
71
|
+
"role": "候选产品",
|
|
72
|
+
"source": {
|
|
73
|
+
"site": "www.mi.example.com",
|
|
74
|
+
"url": "https://www.mi.example.com/pro/specs"
|
|
75
|
+
},
|
|
76
|
+
"status": "ready",
|
|
77
|
+
"title": "小爱音箱 Pro",
|
|
78
|
+
"verdict": {
|
|
79
|
+
"code": "closest",
|
|
80
|
+
"basis": "选定为「小爱音箱 Pro」;实测高宽比 1.8188,规格 1.822,相差 0.2%"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "p2",
|
|
85
|
+
"image": null,
|
|
86
|
+
"kind": "candidate",
|
|
87
|
+
"query": "Xiaomi XiaoAI speaker Pro dimensions",
|
|
88
|
+
"role": "候选产品",
|
|
89
|
+
"source": {
|
|
90
|
+
"site": "www.mi.example.com",
|
|
91
|
+
"url": "https://www.mi.example.com/gen1/specs"
|
|
92
|
+
},
|
|
93
|
+
"status": "ready",
|
|
94
|
+
"title": "小米AI音箱",
|
|
95
|
+
"verdict": {
|
|
96
|
+
"code": "ratio_mismatch",
|
|
97
|
+
"basis": "实测高宽比 1.8188,规格 2.4045,相差 24.4%"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"id": "sp1",
|
|
102
|
+
"kind": "spec",
|
|
103
|
+
"title": "外形尺寸",
|
|
104
|
+
"role": "Ø118 × 215 mm(引自 p1)",
|
|
105
|
+
"source": {
|
|
106
|
+
"url": "https://www.mi.example.com/pro/specs",
|
|
107
|
+
"site": "www.mi.example.com"
|
|
108
|
+
},
|
|
109
|
+
"image": null,
|
|
110
|
+
"verdict": null,
|
|
111
|
+
"status": "ready",
|
|
112
|
+
"query": null
|
|
113
|
+
}
|
|
114
|
+
],
|
|
115
|
+
"keep": [
|
|
116
|
+
"外形尺寸与比例"
|
|
117
|
+
],
|
|
118
|
+
"pages": [
|
|
119
|
+
{
|
|
120
|
+
"excerpt": "小爱音箱 Pro 参数 产品尺寸:118 × 118 × 215 mm,重量 1187 g。",
|
|
121
|
+
"final_url": "https://www.mi.example.com/pro/specs",
|
|
122
|
+
"id": "p1",
|
|
123
|
+
"image_url": "https://img.example.com/pro.png",
|
|
124
|
+
"purpose": "identify",
|
|
125
|
+
"raw_sha256": "109cbac90dd51ef3dddfd21c4a97168a25f097b4211b2146d21669281d06e3b8",
|
|
126
|
+
"reason": null,
|
|
127
|
+
"search_id": "s1",
|
|
128
|
+
"status": "read",
|
|
129
|
+
"text_blob_ref": "sha256:a9d6a6d8668de3346efe1d94c1afd76e71faf37bee5a6e55d3a82f9bc60b9bf0",
|
|
130
|
+
"text_sha256": "bae09c2d8ac69290d90e7cf69d7809858b1149a391400d40030037db41896415",
|
|
131
|
+
"title": "小爱音箱 Pro 参数",
|
|
132
|
+
"url": "https://www.mi.example.com/pro/specs"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"excerpt": "小米AI音箱 规格 尺寸 88 mm × 88 mm × 211.6 mm",
|
|
136
|
+
"final_url": "https://www.mi.example.com/gen1/specs",
|
|
137
|
+
"id": "p2",
|
|
138
|
+
"image_url": null,
|
|
139
|
+
"purpose": "identify",
|
|
140
|
+
"raw_sha256": "c139f165c41dc34c2cd30a816a80d7cbef9ecbda49e7496d46163c8692da33c7",
|
|
141
|
+
"reason": null,
|
|
142
|
+
"search_id": "s1",
|
|
143
|
+
"status": "read",
|
|
144
|
+
"text_blob_ref": "sha256:3dd43ad1e906a2e95af747cc8f8386c00b43df981af8b8bafe45bb2d173e7e3c",
|
|
145
|
+
"text_sha256": "2de9e3c9406bd62a2e9eef887fd42008382616377ac49fb751cd5a109f1e9a00",
|
|
146
|
+
"title": "小米AI音箱 规格",
|
|
147
|
+
"url": "https://www.mi.example.com/gen1/specs"
|
|
148
|
+
}
|
|
149
|
+
],
|
|
150
|
+
"request_digest": "40ece5312c4ecbf6f5548d36589de25734706b8a333d22e1a3c32adeb75e09f5",
|
|
151
|
+
"schema": "abelien.reference-evidence.v1",
|
|
152
|
+
"searches": [
|
|
153
|
+
{
|
|
154
|
+
"count": 5,
|
|
155
|
+
"error_code": null,
|
|
156
|
+
"id": "s1",
|
|
157
|
+
"purpose": "identify",
|
|
158
|
+
"query": "Xiaomi XiaoAI speaker Pro dimensions",
|
|
159
|
+
"receipt_sha256": "099206543e4389fde6c4838d3fc0b125dce0fb98cd57384db3062e1abcede7a8",
|
|
160
|
+
"request_id": "req-[redacted]",
|
|
161
|
+
"results": [
|
|
162
|
+
{
|
|
163
|
+
"rank": 1,
|
|
164
|
+
"snippet": "",
|
|
165
|
+
"title": "XiaoAI Speaker Pro",
|
|
166
|
+
"url": "https://www.mi.example.com/pro/specs"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"rank": 2,
|
|
170
|
+
"snippet": "",
|
|
171
|
+
"title": "Mi AI Speaker",
|
|
172
|
+
"url": "https://www.mi.example.com/gen1/specs"
|
|
173
|
+
}
|
|
174
|
+
],
|
|
175
|
+
"status": "completed"
|
|
176
|
+
}
|
|
177
|
+
],
|
|
178
|
+
"status": "final",
|
|
179
|
+
"text": "帮我根据图片还原小爱音箱",
|
|
180
|
+
"unknowns": [],
|
|
181
|
+
"user_image": {
|
|
182
|
+
"blob_ref": "sha256:e2273b5b355a38441b20796072e08921b9ab30c4f37bb92070a53307af34a6f6",
|
|
183
|
+
"measurement": {
|
|
184
|
+
"aspect_h_over_w": 1.8188,
|
|
185
|
+
"background": {
|
|
186
|
+
"mode": "color",
|
|
187
|
+
"rgb": [
|
|
188
|
+
255,
|
|
189
|
+
255,
|
|
190
|
+
255
|
|
191
|
+
]
|
|
192
|
+
},
|
|
193
|
+
"bbox": {
|
|
194
|
+
"height": 502,
|
|
195
|
+
"width": 276,
|
|
196
|
+
"x": 62,
|
|
197
|
+
"y": 49
|
|
198
|
+
},
|
|
199
|
+
"image": {
|
|
200
|
+
"height": 600,
|
|
201
|
+
"width": 400
|
|
202
|
+
},
|
|
203
|
+
"method": "silhouette-v1",
|
|
204
|
+
"status": "measured"
|
|
205
|
+
},
|
|
206
|
+
"media_type": "image/png",
|
|
207
|
+
"sha256": "da0fadd6fd3ab5ccfbac94ca4e3f2b48e440987eee6834f1c30f04c02abd5d11"
|
|
208
|
+
},
|
|
209
|
+
"collected_id": "ref-40ece5312c4ecbf6",
|
|
210
|
+
"judgement_digest": "d2b162cb00ce8cc52049f321226a89e4e0328b55d54fb022fb4a4539088882c0",
|
|
211
|
+
"identity": {
|
|
212
|
+
"candidates": [
|
|
213
|
+
{
|
|
214
|
+
"item_id": "p1",
|
|
215
|
+
"name": "小爱音箱 Pro",
|
|
216
|
+
"dimensions_mm": {
|
|
217
|
+
"width": 118,
|
|
218
|
+
"depth": 118,
|
|
219
|
+
"height": 215
|
|
220
|
+
},
|
|
221
|
+
"quote": {
|
|
222
|
+
"page_id": "p1",
|
|
223
|
+
"text": "产品尺寸:118 × 118 × 215 mm"
|
|
224
|
+
},
|
|
225
|
+
"ratio_check": {
|
|
226
|
+
"status": "consistent",
|
|
227
|
+
"measured": 1.8188,
|
|
228
|
+
"spec": 1.822,
|
|
229
|
+
"relative_error": 0.0018,
|
|
230
|
+
"tolerance": 0.1
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"item_id": "p2",
|
|
235
|
+
"name": "小米AI音箱",
|
|
236
|
+
"dimensions_mm": {
|
|
237
|
+
"width": 88,
|
|
238
|
+
"depth": 88,
|
|
239
|
+
"height": 211.6
|
|
240
|
+
},
|
|
241
|
+
"quote": {
|
|
242
|
+
"page_id": "p2",
|
|
243
|
+
"text": "尺寸 88 mm × 88 mm × 211.6 mm"
|
|
244
|
+
},
|
|
245
|
+
"ratio_check": {
|
|
246
|
+
"status": "mismatch",
|
|
247
|
+
"measured": 1.8188,
|
|
248
|
+
"spec": 2.4045,
|
|
249
|
+
"relative_error": 0.2436,
|
|
250
|
+
"tolerance": 0.1
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
],
|
|
254
|
+
"chosen_item_id": "p1",
|
|
255
|
+
"conflict": null
|
|
256
|
+
},
|
|
257
|
+
"similar": [],
|
|
258
|
+
"spec_quotes": [
|
|
259
|
+
{
|
|
260
|
+
"id": "sp1",
|
|
261
|
+
"quote": {
|
|
262
|
+
"page_id": "p1",
|
|
263
|
+
"text": "118 × 118 × 215 mm"
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# 参考研究契约(reference.research / reference.finalize)
|
|
2
|
+
|
|
3
|
+
本文是 `abelien-reference` 两个 capability 的输入、输出、上限与错误码的正文。数据格式以 `schemas/reference-evidence.v1.json` 为准,样例见 `fixtures/`;判定逻辑在 `scripts/` 中,并有测试覆盖。
|
|
4
|
+
|
|
5
|
+
## reference.research
|
|
6
|
+
|
|
7
|
+
### 输入
|
|
8
|
+
|
|
9
|
+
只接受下列字段,出现其他字段一律 `VALIDATION`:
|
|
10
|
+
|
|
11
|
+
| 字段 | 规则 |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| `intent` | `restore` / `create` / `modify`,取自需求的 `intent.kind`(clarify 判定) |
|
|
14
|
+
| `keep` / `changeable` | 保留项与可改项,各最多 20 条,每条 1–500 字 |
|
|
15
|
+
| `depth` | `appearance` / `assembly` / `functional`,或 `null` |
|
|
16
|
+
| `text` | 用户原话,1–4000 字 |
|
|
17
|
+
| `links` | 最多 5 个公开 HTTPS 链接,不得带凭据或指向内网 |
|
|
18
|
+
| `user_image` | 可选,`{media_type: "image/png", base64}`,不超过 16MB;其他格式由宿主先转成 PNG |
|
|
19
|
+
| `plan.queries` | 最多 6 条,每条为 `{purpose: identify / teardown / similar, query, count?: 1–5}` |
|
|
20
|
+
| `plan.max_pages` / `plan.max_images` | 页面最多读几页(0–12,默认 8)、主图最多抓几张(0–8,默认 6) |
|
|
21
|
+
|
|
22
|
+
### 执行
|
|
23
|
+
|
|
24
|
+
- **检索**:只用宿主环境变量 `WEB_SEARCH_API_KEY` 调 Volc。原始回执先脱敏,再计算摘要。单条检索失败时,该条记为 `failed`,并写明错误码,其余照常进行;缺少 key 时,在发出任何请求之前就以 `REFERENCE_WEB_CONFIG` 失败。
|
|
25
|
+
- **页面**:先读链接,再从各条检索结果中轮流取页面,避免某一条检索占满读取预算。读取只走内核的安全直读:只读公网 HTTPS,每一跳都重新解析并钉住地址,限制重定向次数。每页最多读 8MB,超出时记为 `too_large`、不可用。正文存为内容 blob,资源里只保留前 1200 字的摘录。
|
|
26
|
+
- **主图**:取页面的 `og:image`、`twitter:image` 或 `image_src`。图片同样走钉住地址的直读,每张不超过 4MB,只接受 PNG、JPEG、WebP,原始字节存为内容 blob。其中的 PNG 会额外测量轮廓。
|
|
27
|
+
- **用户原图**:存为内容 blob 并测量轮廓(`silhouette-v1`),得到包围盒和高宽比;背景必须是单色或透明。背景杂乱、没有主体、隔行 PNG、超大图都记为 `unknown`,并写明原因。
|
|
28
|
+
- **幂等**:结果 id 由完整请求摘要(包括原图哈希)派生。已有同 id 的收集结果时直接返回,不再检索、不再读取。因此单条检索或页面的临时失败不会因为原样重试而自动恢复;要重试,就改写检索计划(比如换个检索词、改结果数),形成新的请求。
|
|
29
|
+
|
|
30
|
+
### 输出
|
|
31
|
+
|
|
32
|
+
输出 `reference-evidence`,status=collected。`items` 中第一项是 `user_input`,其后每个页面对应一格:识别用途为 `candidate`,逆向用途为 `teardown`,相似用途为 `similar`。读不到的页面状态为 `unavailable`。此时还没有任何 `verdict`。
|
|
33
|
+
|
|
34
|
+
## reference.finalize
|
|
35
|
+
|
|
36
|
+
### 输入
|
|
37
|
+
|
|
38
|
+
| 字段 | 规则 |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| `evidence_id` | 必须指向一份 status=collected 的 `reference-evidence:ref-…` |
|
|
41
|
+
| `identity` | 可选,`{candidates: [{item_id, name, dimensions_mm?: {width, depth?, height}, quote: {page_id, text}}], chosen_item_id}`,最多 6 个候选;只要有候选,`chosen_item_id` 就必须是其中之一。引用是必填的识别依据;页面没有给出尺寸时,可以不填 `dimensions_mm`,此时比例记为未核对 |
|
|
42
|
+
| `similar` | 可选,最多 12 条,每条为 `{item_id, decision: borrow / skip, borrowed?, why, not_copied?}`;`borrow` 时必须写明 `borrowed` |
|
|
43
|
+
| `excluded` | 可选,最多 12 条,每条为 `{item_id, reason}` |
|
|
44
|
+
| `specs` | 可选,最多 12 条,每条为 `{title, value, quote}`,生成 `spec` 格 |
|
|
45
|
+
|
|
46
|
+
### 核验
|
|
47
|
+
|
|
48
|
+
- 引用经过空白归一后,必须逐字出现在该页已保存的正文里。只能引用读取成功的页面。
|
|
49
|
+
- 给出尺寸时,宽、高(以及给出时的深)这些数字必须都出现在引用里;没给尺寸时,比例核对为 `unknown`(`no_dimensions`),并写入 `unknowns`。
|
|
50
|
+
- 条目种类必须匹配:候选必须是 `candidate` 格,相似必须是 `similar` 格;排除不能作用于 `user_input`。
|
|
51
|
+
|
|
52
|
+
### 判定(确定性)
|
|
53
|
+
|
|
54
|
+
- 正面视角下,比较高宽比:规格比例为 `height / width`,与用户原图的实测值比较,相对误差不超过 10% 记为 `consistent`,否则记为 `mismatch`;没有测量或缺尺寸时记为 `unknown`。
|
|
55
|
+
- 所选候选:比例一致或无法核对时,判定为 `closest`,依据中写明比例情况;比例不符时,判定为 `ratio_mismatch`,并在 `identity.conflict` 中写明。
|
|
56
|
+
- 其他候选:比例不符时判定为 `ratio_mismatch`,其余不加判定,仍保留为候选,供用户切换。
|
|
57
|
+
- 相似产品:`borrow` 判定为 `borrowed`,依据中写明借用了什么、原因、哪些不照搬;`skip` 判定为 `not_copied`。
|
|
58
|
+
- 排除项:状态改为 `excluded`,判定为 `excluded`。
|
|
59
|
+
- 同一份收集结果可以多次提交不同判断,每次生成一份新的 final 结果(id 带判断摘要),收集结果本身不变。
|
|
60
|
+
|
|
61
|
+
## 错误码
|
|
62
|
+
|
|
63
|
+
| 码 | 含义 |
|
|
64
|
+
| --- | --- |
|
|
65
|
+
| `VALIDATION` | 输入不合规、引用不在原文、尺寸不在引用中、条目种类不符 |
|
|
66
|
+
| `REFERENCE_WEB_CONFIG` | 缺少 `WEB_SEARCH_API_KEY`,或 DNS 配置非法 |
|
|
67
|
+
| `REFERENCE_WEB_*` | 单条检索、读取的失败码,只记在对应的检索、页面或图片里,不使整次运行失败 |
|
|
68
|
+
| `REFERENCE_HOST` | 宿主没有提供可信的资源读取、内容读写端口 |
|
|
69
|
+
|
|
70
|
+
## 宿主责任
|
|
71
|
+
|
|
72
|
+
- 把上传的图片转成 PNG,写入作品目录中的输入文件,再用 `--input-file` 传入。
|
|
73
|
+
- 只展示 `items` 和 `unknowns`;`verdict` 原样展示,不重新解释,也不改写。
|
|
74
|
+
- 第三方图片从内容 blob 转存到私有存储,展示时附来源,不进入图鉴或公开分享。
|