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.
Files changed (104) hide show
  1. package/.env.example +4 -0
  2. package/README.md +11 -18
  3. package/package.json +2 -3
  4. package/skills/abelien-appearance/SKILL.md +1 -0
  5. package/skills/abelien-clarify/SKILL.md +12 -2
  6. package/skills/abelien-clarify/references/examples.md +22 -0
  7. package/skills/abelien-clarify/scripts/check_result.py +38 -3
  8. package/skills/abelien-clarify/scripts/test_check_result.py +32 -1
  9. package/skills/abelien-guide/SKILL.md +1 -1
  10. package/skills/abelien-hardware/SKILL.md +10 -5
  11. package/skills/abelien-hardware/domain.json +3 -3
  12. package/skills/abelien-hardware/references/search-index-format.md +13 -1
  13. package/skills/abelien-hardware/references/search-index-release.md +4 -2
  14. package/skills/abelien-hardware/references/web-evidence-contract.md +3 -3
  15. package/skills/abelien-hardware/scripts/dimensions.mjs +23 -8
  16. package/skills/abelien-hardware/scripts/electrical.mjs +168 -0
  17. package/skills/abelien-hardware/scripts/finalize-selection.mjs +4 -2
  18. package/skills/abelien-hardware/scripts/provider-chain-contract.mjs +27 -6
  19. package/skills/abelien-hardware/scripts/public-page.mjs +11 -121
  20. package/skills/abelien-hardware/scripts/response-redaction.mjs +1 -130
  21. package/skills/abelien-hardware/scripts/search-index-release.mjs +30 -17
  22. package/skills/abelien-hardware/scripts/selection-request.mjs +6 -5
  23. package/skills/abelien-hardware/scripts/tos-wiki-search.mjs +13 -8
  24. package/skills/abelien-hardware/scripts/volc-web-search.mjs +10 -27
  25. package/skills/abelien-hardware/scripts/web-common.mjs +8 -11
  26. package/skills/abelien-hardware/scripts/web-integrity.mjs +1 -1
  27. package/skills/abelien-hardware/scripts/web-provider-chain.mjs +10 -3
  28. package/skills/abelien-hardware/scripts/web-receipt.mjs +4 -2
  29. package/skills/abelien-hardware/scripts/web-search-plan.mjs +21 -2
  30. package/skills/abelien-hardware/scripts/web-search.mjs +5 -2
  31. package/skills/abelien-hardware-selection/SKILL.md +1 -1
  32. package/skills/abelien-hardware-selection/domain.json +2 -2
  33. package/skills/abelien-hardware-selection/references/selection-service-contract.md +30 -3
  34. package/skills/abelien-hardware-selection/scripts/select.mjs +35 -8
  35. package/skills/abelien-harness/scripts/ab.mjs +24 -2
  36. package/skills/abelien-harness/scripts/web/common.mjs +20 -0
  37. package/skills/abelien-harness/scripts/web/public-read.mjs +168 -0
  38. package/skills/abelien-harness/scripts/web/redact.mjs +136 -0
  39. package/skills/abelien-harness/scripts/web/volc.mjs +49 -0
  40. package/skills/abelien-reference/SKILL.md +51 -0
  41. package/skills/abelien-reference/domain.json +92 -0
  42. package/skills/abelien-reference/fixtures/create.final.json +102 -0
  43. package/skills/abelien-reference/fixtures/restore.collected.json +189 -0
  44. package/skills/abelien-reference/fixtures/restore.final.json +267 -0
  45. package/skills/abelien-reference/references/research-contract.md +74 -0
  46. package/skills/abelien-reference/schemas/reference-evidence.v1.json +140 -0
  47. package/skills/abelien-reference/scripts/evidence.mjs +60 -0
  48. package/skills/abelien-reference/scripts/finalize.mjs +116 -0
  49. package/skills/abelien-reference/scripts/measure.mjs +62 -0
  50. package/skills/abelien-reference/scripts/png.mjs +86 -0
  51. package/skills/abelien-reference/scripts/research.mjs +179 -0
  52. package/skills/abelien-structure/SKILL.md +2 -2
  53. package/skills/abelien-structure/domain.json +64 -0
  54. package/skills/abelien-structure/references/build123d-execution.md +1 -1
  55. package/skills/abelien-structure/references/handoff.md +1 -1
  56. package/skills/abelien-structure/worker/abelien_cad.py +585 -0
  57. package/skills/abelien-structure/worker/assembly-validation.mjs +106 -0
  58. package/skills/abelien-structure/worker/cad.py +1623 -0
  59. package/skills/abelien-structure/worker/cli-adapter.mjs +207 -0
  60. package/skills/abelien-structure/worker/component-fit-glb.mjs +173 -0
  61. package/skills/abelien-structure/worker/component-fit.d.mts +82 -0
  62. package/skills/abelien-structure/worker/component-fit.mjs +167 -0
  63. package/skills/abelien-structure/worker/component-target-image.d.mts +23 -0
  64. package/skills/abelien-structure/worker/component-target-image.mjs +107 -0
  65. package/skills/abelien-structure/worker/component-target-render.py +58 -0
  66. package/skills/abelien-structure/worker/config.mjs +6 -0
  67. package/skills/abelien-structure/worker/engineering-fit.d.mts +48 -0
  68. package/skills/abelien-structure/worker/engineering-fit.mjs +118 -0
  69. package/skills/abelien-structure/worker/engineering-policy.json +16 -0
  70. package/skills/abelien-structure/worker/engineering-repair.py +147 -0
  71. package/skills/abelien-structure/worker/engineering.py +324 -0
  72. package/skills/abelien-structure/worker/identity.mjs +98 -0
  73. package/skills/abelien-structure/worker/inspection-geometry.mjs +71 -0
  74. package/skills/abelien-structure/worker/jobs.mjs +451 -0
  75. package/skills/abelien-structure/worker/library-runtime.mjs +15 -0
  76. package/skills/abelien-structure/worker/main.mjs +102 -0
  77. package/skills/abelien-structure/worker/manifest-digest.mjs +11 -0
  78. package/skills/abelien-structure/worker/materials.mjs +52 -0
  79. package/skills/abelien-structure/worker/native-launcher.py +13 -0
  80. package/skills/abelien-structure/worker/native.mjs +157 -0
  81. package/skills/abelien-structure/worker/representation.mjs +47 -0
  82. package/skills/abelien-structure/worker/sandbox.mjs +41 -0
  83. package/skills/abelien-structure/worker/source-contract.mjs +143 -0
  84. package/skills/abelien-structure/worker/source_call_stats.py +59 -0
  85. package/skills/abelien-structure/worker/supervisor.mjs +38 -0
  86. package/skills/abelien-workspace/SKILL.md +11 -0
  87. package/skills/abelien-workspace/assets/journey-stage-plan.json +155 -0
  88. package/skills/abelien-workspace/domain.json +25 -2
  89. package/skills/abelien-workspace/references/hardware-journey-orchestration.md +1 -1
  90. package/skills/abelien-workspace/references/harness-binding.md +2 -2
  91. package/skills/abelien-workspace/references/user-journey.md +10 -0
  92. package/skills/abelien-workspace/scripts/journey-next.mjs +38 -0
  93. package/skills/abelien-workspace/workflows/definitions/0852e4949f5a6246880c1a26bf5ccaa42f8cda06b960e7c7ce234a0a176878f9.json +229 -0
  94. package/skills/abelien-workspace/workflows/definitions/399ef372790b7330d0ef88ce5096e7f69943d4793de97b2ed6c25165a332612f.json +230 -0
  95. package/skills/abelien-workspace/workflows/definitions/591a7f21e0b0ad586e340163f7533ac910356091ba8d2a26e250c0acbc80cd8b.json +176 -0
  96. package/skills/abelien-workspace/workflows/definitions/7c69ea0d51099b1ae947f08b056ea67f5cad6b40ae8bcb00efb496fa5b9d5ed3.json +149 -0
  97. package/skills/abelien-workspace/workflows/definitions/9b5c65ad03fdecc0148931a7677cfa684a3fb04ab2738d6f7a1086a2c79ac86c.json +149 -0
  98. package/skills/abelien-workspace/workflows/definitions/c1b5c6c653f0c4761d51efee923aafbbeea05512e7f35c60f7f7d36ec49fc1d1.json +229 -0
  99. package/skills/abelien-workspace/workflows/definitions/d9f8c6cdf0b2c41cdeb1c72ac5d1e37d95a7caac3272d434a3c7e8483fc565de.json +150 -0
  100. package/skills/abelien-workspace/workflows/definitions/e391e14c14cb39408a0a9e226ed54ffab7a36badea305ae4a3eafbac8124fc02.json +175 -0
  101. package/skills/abelien-workspace/workflows/definitions/fd8ce7074e2044985778446e93153864940bb9465471c1c71c41328cefff70bf.json +175 -0
  102. package/skills/abelien-workspace/workflows/user-journey-hardware-algorithm.json +5 -4
  103. package/skills/abelien-workspace/workflows/user-journey-hardware-candidates.json +5 -4
  104. 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 转存到私有存储,展示时附来源,不进入图鉴或公开分享。