@jangts/agent-core 0.1.1 → 0.2.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 (523) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/development/docs/api/reference.md +1907 -1874
  3. package/development/docs/api/support.md +27 -0
  4. package/development/skills/agent-core-app/scripts/create-app.mjs +267 -70
  5. package/development/skills/agent-core-app/scripts/lib/knowledge.mjs +40 -15
  6. package/development/skills/agent-core-app/scripts/lib/source.mjs +30 -2
  7. package/development/skills/agent-core-app/scripts/plan.mjs +37 -12
  8. package/development/skills/agent-core-app/scripts/prepare-source.mjs +61 -10
  9. package/development/skills/agent-core-app/scripts/resources.mjs +45 -17
  10. package/development/skills/agent-core-app/scripts/validate-knowledge.mjs +18 -1
  11. package/development/skills/agent-core-app/templates/catalog.json +36 -22
  12. package/dist/cjs/capabilities/index.js +13 -0
  13. package/dist/cjs/capabilities/invocation.js +80 -10
  14. package/dist/cjs/capabilities/model.js +126 -13
  15. package/dist/cjs/capabilities/tool-runtime.js +64 -12
  16. package/dist/cjs/capabilities/tools.js +266 -31
  17. package/dist/cjs/context/assembly.js +46 -5
  18. package/dist/cjs/context/audit.js +31 -6
  19. package/dist/cjs/context/fragments.js +54 -11
  20. package/dist/cjs/context/index.js +12 -0
  21. package/dist/cjs/context/journal.js +84 -7
  22. package/dist/cjs/context/plan.js +30 -2
  23. package/dist/cjs/diagnostics/catalog.js +11 -3
  24. package/dist/cjs/diagnostics/index.js +149 -29
  25. package/dist/cjs/diagnostics/sub-flow.js +240 -40
  26. package/dist/cjs/errors.js +99 -17
  27. package/dist/cjs/execution/branch.js +20 -4
  28. package/dist/cjs/execution/engine.js +470 -56
  29. package/dist/cjs/execution/events.js +136 -18
  30. package/dist/cjs/execution/index.js +7 -0
  31. package/dist/cjs/execution/reporting.js +75 -6
  32. package/dist/cjs/execution/state.js +161 -22
  33. package/dist/cjs/execution/workflow.js +224 -32
  34. package/dist/cjs/index.js +18 -0
  35. package/dist/cjs/kits/aggregation.js +45 -3
  36. package/dist/cjs/kits/answering/batch.js +23 -4
  37. package/dist/cjs/kits/answering/check-result.js +31 -8
  38. package/dist/cjs/kits/answering/checks.js +24 -3
  39. package/dist/cjs/kits/answering/flow.js +192 -36
  40. package/dist/cjs/kits/answering/index.js +19 -1
  41. package/dist/cjs/kits/answering/tasks.js +88 -13
  42. package/dist/cjs/kits/artifacts.js +36 -4
  43. package/dist/cjs/kits/candidates.js +47 -5
  44. package/dist/cjs/kits/delivery.js +40 -5
  45. package/dist/cjs/kits/durable.js +155 -31
  46. package/dist/cjs/kits/evidence.js +66 -15
  47. package/dist/cjs/kits/family.js +152 -22
  48. package/dist/cjs/kits/index.js +12 -1
  49. package/dist/cjs/kits/inference.js +104 -16
  50. package/dist/cjs/kits/intents/catalog.js +67 -16
  51. package/dist/cjs/kits/intents/index.js +11 -0
  52. package/dist/cjs/kits/intents/registry.js +188 -43
  53. package/dist/cjs/kits/intents/scopes.js +215 -46
  54. package/dist/cjs/kits/interaction/command.js +140 -36
  55. package/dist/cjs/kits/interaction/commands.js +86 -11
  56. package/dist/cjs/kits/interaction/handlers.js +27 -10
  57. package/dist/cjs/kits/interaction/index.js +10 -0
  58. package/dist/cjs/kits/interaction/transfer.js +80 -14
  59. package/dist/cjs/kits/knowledge/catalog.js +62 -11
  60. package/dist/cjs/kits/knowledge/index.js +16 -1
  61. package/dist/cjs/kits/knowledge/publication.js +99 -23
  62. package/dist/cjs/kits/knowledge/sections.js +33 -4
  63. package/dist/cjs/kits/normalization.js +51 -7
  64. package/dist/cjs/kits/policies.js +79 -15
  65. package/dist/cjs/kits/presentation/events.js +54 -10
  66. package/dist/cjs/kits/presentation/index.js +24 -1
  67. package/dist/cjs/kits/presentation/outputs.js +176 -38
  68. package/dist/cjs/kits/presentation/templates.js +33 -5
  69. package/dist/cjs/kits/presentation/variants.js +31 -2
  70. package/dist/cjs/kits/projection.js +63 -8
  71. package/dist/cjs/kits/rank-fusion.js +27 -4
  72. package/dist/cjs/kits/reflection-log-source.js +89 -16
  73. package/dist/cjs/kits/reflection.js +234 -60
  74. package/dist/cjs/kits/retrieval.js +98 -18
  75. package/dist/cjs/kits/search.js +180 -27
  76. package/dist/cjs/kits/text-skills.js +104 -19
  77. package/dist/cjs/kits/tools.js +415 -74
  78. package/dist/cjs/kits/vector-search.js +50 -16
  79. package/dist/cjs/mock/node.js +7 -1
  80. package/dist/cjs/mock/web.js +7 -1
  81. package/dist/cjs/mock.js +7 -1
  82. package/dist/cjs/model/binding.js +68 -17
  83. package/dist/cjs/model/call-budget.js +45 -4
  84. package/dist/cjs/model/decision-retry.js +19 -1
  85. package/dist/cjs/model/defaults.js +27 -4
  86. package/dist/cjs/model/index.js +7 -0
  87. package/dist/cjs/model/interactions/arguments.js +36 -1
  88. package/dist/cjs/model/interactions/json-object.js +48 -12
  89. package/dist/cjs/model/interactions/native-functions.js +52 -10
  90. package/dist/cjs/model/message-diagnostics.js +17 -4
  91. package/dist/cjs/model/options.js +9 -1
  92. package/dist/cjs/model/preparation.js +86 -12
  93. package/dist/cjs/model/runner.js +413 -79
  94. package/dist/cjs/model/selection-transport.js +48 -8
  95. package/dist/cjs/model/settings.js +67 -13
  96. package/dist/cjs/model/token-budget.js +69 -11
  97. package/dist/cjs/model/transports.js +59 -6
  98. package/dist/cjs/structs/common.js +11 -0
  99. package/dist/cjs/structs/debug.js +34 -5
  100. package/dist/cjs/structs/errors.js +26 -1
  101. package/dist/cjs/structs/index.js +11 -1
  102. package/dist/cjs/structs/kits/durable.js +7 -0
  103. package/dist/cjs/structs/kits/family.js +1 -0
  104. package/dist/cjs/structs/kits/interaction.js +8 -1
  105. package/dist/cjs/structs/kits/knowledge-publication.js +1 -0
  106. package/dist/cjs/structs/kits/reflection.js +18 -3
  107. package/dist/cjs/structs/model/chat-provider.js +6 -0
  108. package/dist/cjs/structs/support/model/completion.js +2 -0
  109. package/dist/cjs/structs/support/model/messages.js +2 -0
  110. package/dist/cjs/support/capabilities.js +43 -6
  111. package/dist/cjs/support/context/assembly.js +88 -16
  112. package/dist/cjs/support/context/compression.js +48 -6
  113. package/dist/cjs/support/context/fragments.js +6 -0
  114. package/dist/cjs/support/context/history.js +36 -1
  115. package/dist/cjs/support/context/index.js +11 -0
  116. package/dist/cjs/support/context/nodes.js +164 -35
  117. package/dist/cjs/support/context/processing.js +319 -61
  118. package/dist/cjs/support/context/selection-policy.js +98 -21
  119. package/dist/cjs/support/context/selection.js +61 -10
  120. package/dist/cjs/support/context/snapshot.js +29 -7
  121. package/dist/cjs/support/context/strategies.js +120 -28
  122. package/dist/cjs/support/index.js +9 -1
  123. package/dist/cjs/support/model/capabilities.js +20 -1
  124. package/dist/cjs/support/model/chat-completions.js +92 -20
  125. package/dist/cjs/support/model/children.js +34 -6
  126. package/dist/cjs/support/model/compatible-provider.js +189 -59
  127. package/dist/cjs/support/model/completion/calls.js +61 -0
  128. package/dist/cjs/support/model/completion/default.js +32 -0
  129. package/dist/cjs/support/model/completion/index.js +28 -0
  130. package/dist/cjs/support/model/completion/session.js +102 -0
  131. package/dist/cjs/support/model/index.js +12 -0
  132. package/dist/cjs/support/model/interactions/index.js +12 -1
  133. package/dist/cjs/support/model/interactions/json-object.js +6 -0
  134. package/dist/cjs/support/model/interactions/native-functions.js +6 -0
  135. package/dist/cjs/support/model/observer.js +32 -6
  136. package/dist/cjs/support/model/preview-rules.js +66 -16
  137. package/dist/cjs/support/model/reply-preview.js +77 -17
  138. package/dist/cjs/support/model/stage-transport.js +33 -7
  139. package/dist/cjs/support/model/strategies.js +75 -14
  140. package/dist/cjs/support/model/transports.js +53 -11
  141. package/dist/cjs/support/registration.js +49 -7
  142. package/dist/cjs/support/schema.js +46 -4
  143. package/dist/cjs/support/stream-events.js +60 -8
  144. package/dist/cjs/support/tool-runtime.js +6 -0
  145. package/dist/cjs/support/tools.js +79 -10
  146. package/dist/cjs/support/transport/index.js +7 -0
  147. package/dist/cjs/support/transport/json.js +28 -4
  148. package/dist/cjs/support/transport/sse.js +25 -2
  149. package/dist/cjs/utils/break-observer.js +20 -2
  150. package/dist/cjs/utils/cancellation.js +77 -9
  151. package/dist/cjs/utils/catalog.js +19 -4
  152. package/dist/cjs/utils/debug.js +14 -2
  153. package/dist/cjs/utils/index.js +8 -0
  154. package/dist/cjs/utils/interaction-definition.js +26 -6
  155. package/dist/cjs/utils/invocation.js +42 -4
  156. package/dist/cjs/utils/model-protocol.js +20 -1
  157. package/dist/cjs/utils/object.js +16 -0
  158. package/dist/cjs/utils/observer.js +22 -2
  159. package/dist/cjs/utils/protocol-registry.js +47 -4
  160. package/dist/cjs/utils/query-key.js +21 -2
  161. package/dist/cjs/utils/registration.js +18 -2
  162. package/dist/cjs/utils/rules.js +39 -11
  163. package/dist/cjs/utils/schema-adapter.js +25 -2
  164. package/dist/cjs/utils/synchronous.js +64 -7
  165. package/dist/cjs/utils/text.js +15 -1
  166. package/dist/esm/capabilities/index.d.ts +13 -0
  167. package/dist/esm/capabilities/index.js +13 -0
  168. package/dist/esm/capabilities/invocation.d.ts +16 -2
  169. package/dist/esm/capabilities/invocation.js +80 -10
  170. package/dist/esm/capabilities/model.d.ts +68 -1
  171. package/dist/esm/capabilities/model.js +126 -13
  172. package/dist/esm/capabilities/tool-runtime.d.ts +11 -0
  173. package/dist/esm/capabilities/tool-runtime.js +64 -12
  174. package/dist/esm/capabilities/tools.d.ts +96 -3
  175. package/dist/esm/capabilities/tools.js +267 -32
  176. package/dist/esm/context/assembly.d.ts +13 -2
  177. package/dist/esm/context/assembly.js +46 -5
  178. package/dist/esm/context/audit.d.ts +23 -1
  179. package/dist/esm/context/audit.js +31 -6
  180. package/dist/esm/context/fragments.d.ts +37 -3
  181. package/dist/esm/context/fragments.js +54 -11
  182. package/dist/esm/context/index.d.ts +12 -0
  183. package/dist/esm/context/index.js +12 -0
  184. package/dist/esm/context/journal.d.ts +32 -1
  185. package/dist/esm/context/journal.js +84 -7
  186. package/dist/esm/context/plan.d.ts +11 -1
  187. package/dist/esm/context/plan.js +30 -2
  188. package/dist/esm/diagnostics/catalog.js +11 -3
  189. package/dist/esm/diagnostics/index.d.ts +30 -2
  190. package/dist/esm/diagnostics/index.js +149 -29
  191. package/dist/esm/diagnostics/sub-flow.d.ts +41 -3
  192. package/dist/esm/diagnostics/sub-flow.js +240 -40
  193. package/dist/esm/errors.d.ts +22 -2
  194. package/dist/esm/errors.js +99 -17
  195. package/dist/esm/execution/branch.d.ts +19 -1
  196. package/dist/esm/execution/branch.js +20 -4
  197. package/dist/esm/execution/engine.d.ts +291 -5
  198. package/dist/esm/execution/engine.js +471 -57
  199. package/dist/esm/execution/events.d.ts +16 -2
  200. package/dist/esm/execution/events.js +136 -18
  201. package/dist/esm/execution/index.d.ts +7 -0
  202. package/dist/esm/execution/index.js +7 -0
  203. package/dist/esm/execution/reporting.d.ts +49 -1
  204. package/dist/esm/execution/reporting.js +75 -6
  205. package/dist/esm/execution/state.d.ts +126 -10
  206. package/dist/esm/execution/state.js +161 -22
  207. package/dist/esm/execution/workflow.d.ts +121 -3
  208. package/dist/esm/execution/workflow.js +224 -32
  209. package/dist/esm/index.d.ts +17 -1
  210. package/dist/esm/index.js +18 -0
  211. package/dist/esm/kits/aggregation.d.ts +34 -2
  212. package/dist/esm/kits/aggregation.js +45 -3
  213. package/dist/esm/kits/answering/batch.d.ts +17 -0
  214. package/dist/esm/kits/answering/batch.js +23 -4
  215. package/dist/esm/kits/answering/check-result.d.ts +18 -1
  216. package/dist/esm/kits/answering/check-result.js +31 -8
  217. package/dist/esm/kits/answering/checks.d.ts +11 -0
  218. package/dist/esm/kits/answering/checks.js +24 -3
  219. package/dist/esm/kits/answering/flow.d.ts +25 -2
  220. package/dist/esm/kits/answering/flow.js +192 -36
  221. package/dist/esm/kits/answering/index.d.ts +12 -0
  222. package/dist/esm/kits/answering/index.js +19 -1
  223. package/dist/esm/kits/answering/tasks.d.ts +32 -1
  224. package/dist/esm/kits/answering/tasks.js +88 -13
  225. package/dist/esm/kits/artifacts.d.ts +11 -0
  226. package/dist/esm/kits/artifacts.js +36 -4
  227. package/dist/esm/kits/candidates.d.ts +23 -1
  228. package/dist/esm/kits/candidates.js +47 -5
  229. package/dist/esm/kits/delivery.d.ts +34 -0
  230. package/dist/esm/kits/delivery.js +40 -5
  231. package/dist/esm/kits/durable.d.ts +19 -0
  232. package/dist/esm/kits/durable.js +155 -31
  233. package/dist/esm/kits/evidence.d.ts +28 -5
  234. package/dist/esm/kits/evidence.js +66 -15
  235. package/dist/esm/kits/family.d.ts +17 -1
  236. package/dist/esm/kits/family.js +152 -22
  237. package/dist/esm/kits/index.d.ts +12 -1
  238. package/dist/esm/kits/index.js +12 -1
  239. package/dist/esm/kits/inference.d.ts +64 -0
  240. package/dist/esm/kits/inference.js +104 -16
  241. package/dist/esm/kits/intents/catalog.d.ts +13 -1
  242. package/dist/esm/kits/intents/catalog.js +67 -16
  243. package/dist/esm/kits/intents/index.d.ts +11 -0
  244. package/dist/esm/kits/intents/index.js +11 -0
  245. package/dist/esm/kits/intents/registry.d.ts +61 -3
  246. package/dist/esm/kits/intents/registry.js +188 -43
  247. package/dist/esm/kits/intents/scopes.d.ts +73 -3
  248. package/dist/esm/kits/intents/scopes.js +215 -46
  249. package/dist/esm/kits/interaction/command.d.ts +38 -4
  250. package/dist/esm/kits/interaction/command.js +140 -36
  251. package/dist/esm/kits/interaction/commands.d.ts +66 -2
  252. package/dist/esm/kits/interaction/commands.js +86 -11
  253. package/dist/esm/kits/interaction/handlers.d.ts +19 -2
  254. package/dist/esm/kits/interaction/handlers.js +27 -10
  255. package/dist/esm/kits/interaction/index.d.ts +10 -0
  256. package/dist/esm/kits/interaction/index.js +10 -0
  257. package/dist/esm/kits/interaction/transfer.d.ts +39 -2
  258. package/dist/esm/kits/interaction/transfer.js +80 -14
  259. package/dist/esm/kits/knowledge/catalog.d.ts +13 -0
  260. package/dist/esm/kits/knowledge/catalog.js +62 -11
  261. package/dist/esm/kits/knowledge/index.d.ts +11 -0
  262. package/dist/esm/kits/knowledge/index.js +16 -1
  263. package/dist/esm/kits/knowledge/publication.d.ts +15 -1
  264. package/dist/esm/kits/knowledge/publication.js +99 -23
  265. package/dist/esm/kits/knowledge/sections.d.ts +31 -1
  266. package/dist/esm/kits/knowledge/sections.js +33 -4
  267. package/dist/esm/kits/normalization.d.ts +25 -2
  268. package/dist/esm/kits/normalization.js +51 -7
  269. package/dist/esm/kits/policies.d.ts +26 -3
  270. package/dist/esm/kits/policies.js +79 -15
  271. package/dist/esm/kits/presentation/events.d.ts +51 -4
  272. package/dist/esm/kits/presentation/events.js +54 -10
  273. package/dist/esm/kits/presentation/index.d.ts +12 -0
  274. package/dist/esm/kits/presentation/index.js +25 -2
  275. package/dist/esm/kits/presentation/outputs.d.ts +30 -1
  276. package/dist/esm/kits/presentation/outputs.js +176 -38
  277. package/dist/esm/kits/presentation/templates.d.ts +32 -3
  278. package/dist/esm/kits/presentation/templates.js +33 -5
  279. package/dist/esm/kits/presentation/variants.d.ts +29 -0
  280. package/dist/esm/kits/presentation/variants.js +31 -2
  281. package/dist/esm/kits/projection.d.ts +42 -5
  282. package/dist/esm/kits/projection.js +63 -8
  283. package/dist/esm/kits/rank-fusion.d.ts +21 -1
  284. package/dist/esm/kits/rank-fusion.js +28 -5
  285. package/dist/esm/kits/reflection-log-source.d.ts +28 -1
  286. package/dist/esm/kits/reflection-log-source.js +89 -16
  287. package/dist/esm/kits/reflection.d.ts +17 -1
  288. package/dist/esm/kits/reflection.js +235 -61
  289. package/dist/esm/kits/retrieval.d.ts +18 -2
  290. package/dist/esm/kits/retrieval.js +98 -18
  291. package/dist/esm/kits/search.d.ts +56 -3
  292. package/dist/esm/kits/search.js +180 -27
  293. package/dist/esm/kits/text-skills.d.ts +16 -2
  294. package/dist/esm/kits/text-skills.js +104 -19
  295. package/dist/esm/kits/tools.d.ts +122 -2
  296. package/dist/esm/kits/tools.js +416 -74
  297. package/dist/esm/kits/vector-search.d.ts +47 -1
  298. package/dist/esm/kits/vector-search.js +51 -17
  299. package/dist/esm/mock/node.d.ts +7 -0
  300. package/dist/esm/mock/node.js +7 -1
  301. package/dist/esm/mock/web.d.ts +7 -0
  302. package/dist/esm/mock/web.js +7 -1
  303. package/dist/esm/mock.d.ts +7 -0
  304. package/dist/esm/mock.js +7 -1
  305. package/dist/esm/model/binding.d.ts +32 -3
  306. package/dist/esm/model/binding.js +68 -17
  307. package/dist/esm/model/call-budget.d.ts +30 -2
  308. package/dist/esm/model/call-budget.js +45 -4
  309. package/dist/esm/model/decision-retry.d.ts +10 -1
  310. package/dist/esm/model/decision-retry.js +19 -1
  311. package/dist/esm/model/defaults.d.ts +13 -2
  312. package/dist/esm/model/defaults.js +27 -4
  313. package/dist/esm/model/index.d.ts +7 -0
  314. package/dist/esm/model/index.js +7 -0
  315. package/dist/esm/model/interactions/arguments.d.ts +27 -0
  316. package/dist/esm/model/interactions/arguments.js +36 -1
  317. package/dist/esm/model/interactions/json-object.d.ts +7 -1
  318. package/dist/esm/model/interactions/json-object.js +48 -12
  319. package/dist/esm/model/interactions/native-functions.d.ts +6 -0
  320. package/dist/esm/model/interactions/native-functions.js +52 -10
  321. package/dist/esm/model/message-diagnostics.d.ts +17 -1
  322. package/dist/esm/model/message-diagnostics.js +17 -4
  323. package/dist/esm/model/options.d.ts +18 -1
  324. package/dist/esm/model/options.js +9 -1
  325. package/dist/esm/model/preparation.d.ts +30 -2
  326. package/dist/esm/model/preparation.js +86 -12
  327. package/dist/esm/model/runner.d.ts +129 -5
  328. package/dist/esm/model/runner.js +414 -80
  329. package/dist/esm/model/selection-transport.d.ts +14 -1
  330. package/dist/esm/model/selection-transport.js +48 -8
  331. package/dist/esm/model/settings.d.ts +11 -0
  332. package/dist/esm/model/settings.js +67 -13
  333. package/dist/esm/model/token-budget.d.ts +59 -1
  334. package/dist/esm/model/token-budget.js +69 -11
  335. package/dist/esm/model/transports.d.ts +20 -2
  336. package/dist/esm/model/transports.js +59 -6
  337. package/dist/esm/structs/capabilities/invocation.d.ts +36 -0
  338. package/dist/esm/structs/capabilities/model.d.ts +27 -0
  339. package/dist/esm/structs/capabilities/tools.d.ts +38 -0
  340. package/dist/esm/structs/common.d.ts +62 -2
  341. package/dist/esm/structs/common.js +11 -0
  342. package/dist/esm/structs/context/fragments.d.ts +28 -0
  343. package/dist/esm/structs/context/journal.d.ts +28 -3
  344. package/dist/esm/structs/context/processing.d.ts +11 -0
  345. package/dist/esm/structs/debug.d.ts +58 -1
  346. package/dist/esm/structs/debug.js +34 -5
  347. package/dist/esm/structs/diagnostics.d.ts +119 -1
  348. package/dist/esm/structs/errors.d.ts +42 -1
  349. package/dist/esm/structs/errors.js +26 -1
  350. package/dist/esm/structs/execution/engine.d.ts +24 -1
  351. package/dist/esm/structs/execution/events.d.ts +12 -0
  352. package/dist/esm/structs/execution/workflow.d.ts +71 -0
  353. package/dist/esm/structs/index.d.ts +11 -1
  354. package/dist/esm/structs/index.js +11 -1
  355. package/dist/esm/structs/invocation.d.ts +30 -0
  356. package/dist/esm/structs/kits/aggregation.d.ts +12 -0
  357. package/dist/esm/structs/kits/answering/checks.d.ts +11 -0
  358. package/dist/esm/structs/kits/answering/flow.d.ts +35 -1
  359. package/dist/esm/structs/kits/answering/state.d.ts +21 -0
  360. package/dist/esm/structs/kits/answering/tasks.d.ts +21 -0
  361. package/dist/esm/structs/kits/artifacts.d.ts +14 -0
  362. package/dist/esm/structs/kits/candidates.d.ts +19 -0
  363. package/dist/esm/structs/kits/delivery.d.ts +22 -0
  364. package/dist/esm/structs/kits/durable.d.ts +56 -3
  365. package/dist/esm/structs/kits/durable.js +7 -0
  366. package/dist/esm/structs/kits/evidence.d.ts +23 -0
  367. package/dist/esm/structs/kits/family.d.ts +49 -1
  368. package/dist/esm/structs/kits/family.js +1 -0
  369. package/dist/esm/structs/kits/intents/catalog.d.ts +26 -0
  370. package/dist/esm/structs/kits/intents/registry.d.ts +34 -0
  371. package/dist/esm/structs/kits/intents/scopes.d.ts +36 -1
  372. package/dist/esm/structs/kits/interaction.d.ts +64 -0
  373. package/dist/esm/structs/kits/interaction.js +8 -1
  374. package/dist/esm/structs/kits/knowledge-publication.d.ts +43 -1
  375. package/dist/esm/structs/kits/knowledge-publication.js +1 -0
  376. package/dist/esm/structs/kits/knowledge.d.ts +39 -2
  377. package/dist/esm/structs/kits/normalization.d.ts +15 -0
  378. package/dist/esm/structs/kits/policies.d.ts +25 -1
  379. package/dist/esm/structs/kits/presentation/events.d.ts +28 -4
  380. package/dist/esm/structs/kits/presentation/outputs.d.ts +38 -1
  381. package/dist/esm/structs/kits/presentation/templates.d.ts +15 -0
  382. package/dist/esm/structs/kits/projection.d.ts +21 -0
  383. package/dist/esm/structs/kits/reflection.d.ts +61 -2
  384. package/dist/esm/structs/kits/reflection.js +18 -3
  385. package/dist/esm/structs/kits/retrieval.d.ts +38 -0
  386. package/dist/esm/structs/kits/search.d.ts +22 -0
  387. package/dist/esm/structs/kits/text-skills.d.ts +36 -0
  388. package/dist/esm/structs/kits/tools.d.ts +87 -0
  389. package/dist/esm/structs/model/chat-provider.d.ts +24 -1
  390. package/dist/esm/structs/model/chat-provider.js +6 -0
  391. package/dist/esm/structs/model/interactions.d.ts +38 -0
  392. package/dist/esm/structs/model/messages.d.ts +30 -0
  393. package/dist/esm/structs/model/runtime.d.ts +104 -6
  394. package/dist/esm/structs/support/capabilities.d.ts +19 -2
  395. package/dist/esm/structs/support/context-processing.d.ts +88 -9
  396. package/dist/esm/structs/support/context.d.ts +29 -1
  397. package/dist/esm/structs/support/model/completion.d.ts +50 -0
  398. package/dist/esm/structs/support/model/completion.js +1 -0
  399. package/dist/esm/structs/support/model/interactions.d.ts +13 -1
  400. package/dist/esm/structs/support/model/messages.d.ts +52 -0
  401. package/dist/esm/structs/support/model/messages.js +1 -0
  402. package/dist/esm/structs/support/model/provider-observer.d.ts +22 -1
  403. package/dist/esm/structs/support/model/provider.d.ts +71 -6
  404. package/dist/esm/structs/support/registration.d.ts +13 -0
  405. package/dist/esm/structs/support/schema.d.ts +14 -0
  406. package/dist/esm/structs/support/tools.d.ts +28 -0
  407. package/dist/esm/structs/support/transport/json.d.ts +16 -0
  408. package/dist/esm/structs/support/transport/sse.d.ts +15 -0
  409. package/dist/esm/structs/utils/rules.d.ts +19 -0
  410. package/dist/esm/support/capabilities.d.ts +25 -2
  411. package/dist/esm/support/capabilities.js +43 -6
  412. package/dist/esm/support/context/assembly.d.ts +35 -4
  413. package/dist/esm/support/context/assembly.js +88 -16
  414. package/dist/esm/support/context/compression.d.ts +17 -1
  415. package/dist/esm/support/context/compression.js +48 -6
  416. package/dist/esm/support/context/fragments.d.ts +6 -0
  417. package/dist/esm/support/context/fragments.js +6 -0
  418. package/dist/esm/support/context/history.d.ts +43 -0
  419. package/dist/esm/support/context/history.js +36 -1
  420. package/dist/esm/support/context/index.d.ts +13 -2
  421. package/dist/esm/support/context/index.js +12 -1
  422. package/dist/esm/support/context/nodes.d.ts +49 -3
  423. package/dist/esm/support/context/nodes.js +165 -36
  424. package/dist/esm/support/context/processing.d.ts +145 -1
  425. package/dist/esm/support/context/processing.js +320 -62
  426. package/dist/esm/support/context/selection-policy.d.ts +42 -2
  427. package/dist/esm/support/context/selection-policy.js +98 -21
  428. package/dist/esm/support/context/selection.d.ts +14 -1
  429. package/dist/esm/support/context/selection.js +61 -10
  430. package/dist/esm/support/context/snapshot.d.ts +23 -1
  431. package/dist/esm/support/context/snapshot.js +29 -7
  432. package/dist/esm/support/context/strategies.d.ts +35 -2
  433. package/dist/esm/support/context/strategies.js +120 -28
  434. package/dist/esm/support/index.d.ts +9 -1
  435. package/dist/esm/support/index.js +9 -1
  436. package/dist/esm/support/model/capabilities.d.ts +10 -0
  437. package/dist/esm/support/model/capabilities.js +20 -1
  438. package/dist/esm/support/model/chat-completions.d.ts +44 -15
  439. package/dist/esm/support/model/chat-completions.js +92 -20
  440. package/dist/esm/support/model/children.d.ts +32 -2
  441. package/dist/esm/support/model/children.js +34 -6
  442. package/dist/esm/support/model/compatible-provider.d.ts +29 -3
  443. package/dist/esm/support/model/compatible-provider.js +190 -60
  444. package/dist/esm/support/model/completion/calls.d.ts +40 -0
  445. package/dist/esm/support/model/completion/calls.js +58 -0
  446. package/dist/esm/support/model/completion/default.d.ts +10 -0
  447. package/dist/esm/support/model/completion/default.js +29 -0
  448. package/dist/esm/support/model/completion/index.d.ts +10 -0
  449. package/dist/esm/support/model/completion/index.js +22 -0
  450. package/dist/esm/support/model/completion/session.d.ts +11 -0
  451. package/dist/esm/support/model/completion/session.js +99 -0
  452. package/dist/esm/support/model/index.d.ts +14 -0
  453. package/dist/esm/support/model/index.js +12 -0
  454. package/dist/esm/support/model/interactions/index.d.ts +1 -1
  455. package/dist/esm/support/model/interactions/index.js +12 -1
  456. package/dist/esm/support/model/interactions/json-object.d.ts +6 -0
  457. package/dist/esm/support/model/interactions/json-object.js +6 -0
  458. package/dist/esm/support/model/interactions/native-functions.d.ts +6 -0
  459. package/dist/esm/support/model/interactions/native-functions.js +6 -0
  460. package/dist/esm/support/model/observer.d.ts +25 -2
  461. package/dist/esm/support/model/observer.js +32 -6
  462. package/dist/esm/support/model/preview-rules.d.ts +20 -2
  463. package/dist/esm/support/model/preview-rules.js +66 -16
  464. package/dist/esm/support/model/reply-preview.d.ts +15 -1
  465. package/dist/esm/support/model/reply-preview.js +77 -17
  466. package/dist/esm/support/model/stage-transport.d.ts +9 -1
  467. package/dist/esm/support/model/stage-transport.js +33 -7
  468. package/dist/esm/support/model/strategies.d.ts +24 -2
  469. package/dist/esm/support/model/strategies.js +75 -14
  470. package/dist/esm/support/model/transports.d.ts +17 -1
  471. package/dist/esm/support/model/transports.js +53 -11
  472. package/dist/esm/support/registration.d.ts +20 -1
  473. package/dist/esm/support/registration.js +49 -7
  474. package/dist/esm/support/schema.d.ts +31 -1
  475. package/dist/esm/support/schema.js +46 -4
  476. package/dist/esm/support/stream-events.d.ts +22 -1
  477. package/dist/esm/support/stream-events.js +60 -8
  478. package/dist/esm/support/tool-runtime.d.ts +6 -0
  479. package/dist/esm/support/tool-runtime.js +6 -0
  480. package/dist/esm/support/tools.d.ts +22 -0
  481. package/dist/esm/support/tools.js +79 -10
  482. package/dist/esm/support/transport/index.d.ts +7 -0
  483. package/dist/esm/support/transport/index.js +7 -0
  484. package/dist/esm/support/transport/json.d.ts +29 -2
  485. package/dist/esm/support/transport/json.js +28 -4
  486. package/dist/esm/support/transport/sse.d.ts +31 -1
  487. package/dist/esm/support/transport/sse.js +25 -2
  488. package/dist/esm/types.d.ts +9 -1
  489. package/dist/esm/utils/break-observer.d.ts +27 -2
  490. package/dist/esm/utils/break-observer.js +20 -2
  491. package/dist/esm/utils/cancellation.d.ts +56 -5
  492. package/dist/esm/utils/cancellation.js +77 -9
  493. package/dist/esm/utils/catalog.d.ts +20 -1
  494. package/dist/esm/utils/catalog.js +19 -4
  495. package/dist/esm/utils/debug.d.ts +20 -1
  496. package/dist/esm/utils/debug.js +14 -2
  497. package/dist/esm/utils/index.d.ts +8 -0
  498. package/dist/esm/utils/index.js +8 -0
  499. package/dist/esm/utils/interaction-definition.d.ts +18 -1
  500. package/dist/esm/utils/interaction-definition.js +26 -6
  501. package/dist/esm/utils/invocation.d.ts +36 -1
  502. package/dist/esm/utils/invocation.js +42 -4
  503. package/dist/esm/utils/model-protocol.d.ts +8 -0
  504. package/dist/esm/utils/model-protocol.js +20 -1
  505. package/dist/esm/utils/object.d.ts +16 -0
  506. package/dist/esm/utils/object.js +16 -0
  507. package/dist/esm/utils/observer.d.ts +19 -1
  508. package/dist/esm/utils/observer.js +22 -2
  509. package/dist/esm/utils/protocol-registry.d.ts +38 -1
  510. package/dist/esm/utils/protocol-registry.js +47 -4
  511. package/dist/esm/utils/query-key.d.ts +11 -1
  512. package/dist/esm/utils/query-key.js +21 -2
  513. package/dist/esm/utils/registration.d.ts +34 -2
  514. package/dist/esm/utils/registration.js +18 -2
  515. package/dist/esm/utils/rules.d.ts +81 -4
  516. package/dist/esm/utils/rules.js +39 -11
  517. package/dist/esm/utils/schema-adapter.d.ts +12 -1
  518. package/dist/esm/utils/schema-adapter.js +25 -2
  519. package/dist/esm/utils/synchronous.d.ts +60 -4
  520. package/dist/esm/utils/synchronous.js +64 -7
  521. package/dist/esm/utils/text.d.ts +15 -1
  522. package/dist/esm/utils/text.js +15 -1
  523. package/package.json +3 -2
@@ -167,6 +167,33 @@ modelInteractionCatalog 按明确登记的交互 ID 选择原生函数或 JSON a
167
167
 
168
168
  兼容 Provider 的 `requestBody` 用于供应商扩展字段。模型身份、输入消息、流式协议和 token 上限由适配器与 Core 调用合同控制。覆盖这些字段会在发送请求前报错。需要使用另一种请求协议时,可以直接实现同一个 `ChatProvider` 接口。
169
169
 
170
+ 完成判定通过 `ports.completionPolicy` 选择,缺省为 `Support.completionPolicyCatalog.default`,是否接受函数分片、期望的 `finish_reason`、`[DONE]` 前的完整性都按调用是否声明 `functions` 判定,缺结束标记的断流仍按 `MODEL_INCOMPLETE` 结束。`Support.completionPolicyCatalog.session` 按线上 `tool_choice` 判定:`auto` 要求已开始的调用全部完整并允许伴随正文,`required` 与指定函数对象要求至少一个完整调用,`none` 拒绝任何调用分片,字段省略采用 default 的完成规则,未知值在发请求前按配置错误拒绝。策略只判定响应是否满足请求,不接管请求循环、传输保护或工具执行;取消与传输失败不会因为策略而变成成功。
171
+
172
+ `Support.createToolCallCollector` 按 index 聚合调用分片,完成策略与直接调用方共用同一实现。分片 ID 冲突、跨 index 重复 ID 与残缺调用都按协议错误拒绝,一个完整调用不会掩盖另一个残缺调用。
173
+
174
+ 协议层从不限制接收多个调用分片,`parallel_tool_calls` 只是发送字段,不表达执行授权或调度策略。Agent 路径的单提案限制由 `nativeFunctionInteraction` 的 collector 决定;直接使用 Provider 不受该限制,也不因此获得工具执行、授权或循环能力。
175
+
176
+ `ProviderMessage` 提供直连所需的 `tool` 结果与 assistant `toolCalls` 形状,`chatCompletionMessages` 显式映射为 `tool_call_id` 与嵌套 `tool_calls`;角色与字段不匹配、调用字段不完整时按 `TypeError` 拒绝。只发送声明字段,额外字段(包括原始 wire 字段)不透传;`toolCallId` 必须是非空字符串,`role` 与 `content` 按消息合同校验。Core `ModelMessage` 与 `ChatProvider` 抽象签名不变。
177
+
178
+ 直连工具线程使用声明字段,assistant 的 `content` 可以为空字符串;工具结果通过同一个调用 ID 关联:
179
+
180
+ ```ts
181
+ import { Support } from '@jangts/agent-core';
182
+
183
+ const messages: Support.ProviderMessage[] = [
184
+ { role: 'user', content: '查询资料' },
185
+ {
186
+ role: 'assistant', content: '',
187
+ toolCalls: [{ id: 'call-1', name: 'lookup', arguments: '{"query":"资料"}' }],
188
+ },
189
+ { role: 'tool', content: '{"found":true}', toolCallId: 'call-1' },
190
+ ];
191
+ const wireMessages = Support.chatCompletionMessages(messages);
192
+ // 工具声明映射为 tool_calls,工具结果映射为 tool_call_id。
193
+ ```
194
+
195
+ 工具的注册、参数业务校验、授权和执行由宿主负责。`createToolCallCollector.complete()` 检查调用 ID 与名称的完整性,不解析或验证业务参数 JSON。
196
+
170
197
  多个请求复用同一个 Provider 时,可以用 `Support.createProviderObservationScope` 绑定应用自己的输出规则。将返回的 `observer` 配给 Provider,每次请求用 `attach(diagnostics, destination)` 关联日志目标。子作用域会自动继承关联。应用负责脱敏、保留期和写入策略,Provider 事件按现有应用日志出口记录。
171
198
 
172
199
  ## 拒绝检查
@@ -1,149 +1,346 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { execFile } from 'node:child_process';
3
3
  import { promisify } from 'node:util';
4
- import { lstat, mkdir, mkdtemp, readFile, readdir, rename, rm, rmdir, writeFile } from 'node:fs/promises';
4
+ import {
5
+ lstat,
6
+ mkdir,
7
+ mkdtemp,
8
+ readFile,
9
+ readdir,
10
+ rename,
11
+ rm,
12
+ rmdir,
13
+ writeFile,
14
+ } from 'node:fs/promises';
5
15
  import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
6
16
  import { fileURLToPath, pathToFileURL } from 'node:url';
7
17
  import { resolveSdkResources } from './resources.mjs';
8
18
 
9
- const execute = promisify(execFile), receiptName = 'agent-core.template.json';
10
- const usage = 'node create-app.mjs TARGET [--name PACKAGE_NAME] [--purpose TEXT] [--template node-ts] [--sdk-from PROJECT] [--source UTF8_FILE --id DOCUMENT_ID] [--write | --check]';
11
- const hash = value => createHash('sha256').update(value).digest('hex');
12
- const pathInside = value => typeof value === 'string' && !!value && !isAbsolute(value) && !value.includes('\\')
13
- && value.split('/').every(part => !!part && !['.', '..'].includes(part));
14
- async function exists(path) { try { return await lstat(path); } catch (error) { if (error.code !== 'ENOENT') throw error; } }
19
+ const execute = promisify(execFile),
20
+ receiptName = 'agent-core.template.json';
21
+ const usage =
22
+ 'node create-app.mjs TARGET [--name PACKAGE_NAME] [--purpose TEXT] [--template node-ts] [--sdk-from PROJECT] [--source UTF8_FILE --id DOCUMENT_ID] [--write | --check]';
23
+ const hash = (value) => createHash('sha256').update(value).digest('hex');
24
+ const pathInside = (value) =>
25
+ typeof value === 'string' &&
26
+ !!value &&
27
+ !isAbsolute(value) &&
28
+ !value.includes('\\') &&
29
+ value.split('/').every((part) => !!part && !['.', '..'].includes(part));
30
+ async function exists(path) {
31
+ try {
32
+ return await lstat(path);
33
+ } catch (error) {
34
+ if (error.code !== 'ENOENT') throw error;
35
+ }
36
+ }
15
37
  function inputs(name, purpose) {
16
- if (typeof name !== 'string' || name.length > 214 || !/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/.test(name)) throw new TypeError('Use a lowercase npm package name');
17
- if (typeof purpose !== 'string' || purpose.length > 800 || !purpose.trim()) throw new TypeError('Use a purpose of 1–800 characters');
38
+ if (
39
+ typeof name !== 'string' ||
40
+ name.length > 214 ||
41
+ !/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/.test(name)
42
+ )
43
+ throw new TypeError('Use a lowercase npm package name');
44
+ if (typeof purpose !== 'string' || purpose.length > 800 || !purpose.trim())
45
+ throw new TypeError('Use a purpose of 1–800 characters');
18
46
  return { name, purpose: purpose.trim() };
19
47
  }
20
48
  function parse(args, cwd) {
21
49
  if (!args.length || args[0].startsWith('--')) throw new TypeError(usage);
22
- const values = {}, switches = new Set(['--write', '--check']), options = new Set(['--name', '--purpose', '--template', '--sdk-from', '--source', '--id']);
50
+ const values = {},
51
+ switches = new Set(['--write', '--check']),
52
+ options = new Set(['--name', '--purpose', '--template', '--sdk-from', '--source', '--id']);
23
53
  for (let index = 1; index < args.length; index++) {
24
54
  const key = args[index];
25
55
  if (Object.hasOwn(values, key)) throw new TypeError(`Duplicate option: ${key}`);
26
56
  if (switches.has(key)) values[key] = true;
27
- else if (options.has(key) && args[index + 1] !== undefined && !args[index + 1].startsWith('--')) values[key] = args[++index];
57
+ else if (options.has(key) && args[index + 1] !== undefined && !args[index + 1].startsWith('--'))
58
+ values[key] = args[++index];
28
59
  else throw new TypeError(usage);
29
60
  }
30
- if (values['--write'] && values['--check'] || !!values['--source'] !== !!values['--id']
31
- || values['--check'] && ['--name', '--purpose', '--source', '--id'].some(key => Object.hasOwn(values, key))) throw new TypeError(usage);
61
+ if (
62
+ (values['--write'] && values['--check']) ||
63
+ !!values['--source'] !== !!values['--id'] ||
64
+ (values['--check'] &&
65
+ ['--name', '--purpose', '--source', '--id'].some((key) => Object.hasOwn(values, key)))
66
+ )
67
+ throw new TypeError(usage);
32
68
  return { target: resolve(cwd, args[0]), values };
33
69
  }
34
70
  async function emptyTarget(target) {
35
71
  const item = await exists(target);
36
- if (item && (!item.isDirectory() || item.isSymbolicLink() || (await readdir(target)).length)) throw new Error('TARGET must be absent or an empty real directory; existing files are preserved');
72
+ if (item && (!item.isDirectory() || item.isSymbolicLink() || (await readdir(target)).length))
73
+ throw new Error(
74
+ 'TARGET must be absent or an empty real directory; existing files are preserved',
75
+ );
37
76
  }
38
77
  async function templateResources(resources, id) {
39
78
  const root = join(resources.sdk.root, 'development/skills/agent-core-app');
40
79
  const catalog = JSON.parse(await readFile(join(root, 'templates/catalog.json'), 'utf8'));
41
- if (catalog.schemaVersion !== 1 || !Array.isArray(catalog.templates)) throw new Error('Unsupported template catalog');
42
- const template = catalog.templates.find(item => item.id === id);
43
- if (!template || typeof template.revision !== 'string' || !pathInside(template.directory) || !Array.isArray(template.files)
44
- || template.files.some(file => !pathInside(file.source) || !pathInside(file.target) || !['template', 'skill'].includes(file.origin))
45
- || new Set(template.files.map(file => file.target)).size !== template.files.length || template.files.some(file => file.target === receiptName)) throw new Error('Invalid or unknown template');
80
+ if (catalog.schemaVersion !== 1 || !Array.isArray(catalog.templates))
81
+ throw new Error('Unsupported template catalog');
82
+ const template = catalog.templates.find((item) => item.id === id);
83
+ if (
84
+ !template ||
85
+ typeof template.revision !== 'string' ||
86
+ !pathInside(template.directory) ||
87
+ !Array.isArray(template.files) ||
88
+ template.files.some(
89
+ (file) =>
90
+ !pathInside(file.source) ||
91
+ !pathInside(file.target) ||
92
+ !['template', 'skill'].includes(file.origin),
93
+ ) ||
94
+ new Set(template.files.map((file) => file.target)).size !== template.files.length ||
95
+ template.files.some((file) => file.target === receiptName)
96
+ )
97
+ throw new Error('Invalid or unknown template');
46
98
  return { root, template };
47
99
  }
48
100
  async function render(resources, definition, input) {
49
101
  const manifest = JSON.parse(await readFile(join(resources.sdk.root, 'package.json'), 'utf8'));
50
- if (manifest.name !== '@jangts/agent-core' || manifest.version !== resources.sdk.version || typeof manifest.devDependencies?.typescript !== 'string') throw new Error('SDK manifest does not describe the selected template dependencies');
51
- const configuration = { name: input.name, purpose: input.purpose, maxCalls: 4, maxRounds: 8,
52
- callTimeoutMs: 30000, maxInputChars: 48000, maxOutputChars: 8000 };
53
- const substitutions = { '__APP_CONFIG__': JSON.stringify(configuration, null, 2), '__PACKAGE_NAME__': JSON.stringify(input.name),
54
- '__SDK_VERSION__': JSON.stringify(manifest.version), '__TYPESCRIPT_VERSION__': JSON.stringify(manifest.devDependencies.typescript) };
55
- return Promise.all(definition.template.files.map(async file => {
56
- const source = file.origin === 'skill' ? join(definition.root, file.source) : join(definition.root, 'templates', definition.template.directory, file.source);
57
- const info = await lstat(source); if (!info.isFile() || info.isSymbolicLink()) throw new Error('Template assets must be regular files');
58
- let content = new TextDecoder('utf-8', { fatal: true }).decode(await readFile(source));
59
- // One pass: user-provided purpose text cannot become another substitution instruction.
60
- if (file.origin === 'template') content = content.replace(/__APP_CONFIG__|__PACKAGE_NAME__|__SDK_VERSION__|__TYPESCRIPT_VERSION__/g, token => substitutions[token]);
61
- const bytes = Buffer.from(content); return { path: file.target, bytes, sha256: hash(bytes) };
62
- }));
102
+ if (
103
+ manifest.name !== '@jangts/agent-core' ||
104
+ manifest.version !== resources.sdk.version ||
105
+ typeof manifest.devDependencies?.typescript !== 'string'
106
+ )
107
+ throw new Error('SDK manifest does not describe the selected template dependencies');
108
+ const configuration = {
109
+ name: input.name,
110
+ purpose: input.purpose,
111
+ maxCalls: 4,
112
+ maxRounds: 8,
113
+ callTimeoutMs: 30000,
114
+ maxInputChars: 48000,
115
+ maxOutputChars: 8000,
116
+ };
117
+ const substitutions = {
118
+ __APP_CONFIG__: JSON.stringify(configuration, null, 2),
119
+ __PACKAGE_NAME__: JSON.stringify(input.name),
120
+ __SDK_VERSION__: JSON.stringify(manifest.version),
121
+ __TYPESCRIPT_VERSION__: JSON.stringify(manifest.devDependencies.typescript),
122
+ };
123
+ return Promise.all(
124
+ definition.template.files.map(async (file) => {
125
+ const source =
126
+ file.origin === 'skill'
127
+ ? join(definition.root, file.source)
128
+ : join(definition.root, 'templates', definition.template.directory, file.source);
129
+ const info = await lstat(source);
130
+ if (!info.isFile() || info.isSymbolicLink())
131
+ throw new Error('Template assets must be regular files');
132
+ let content = new TextDecoder('utf-8', { fatal: true }).decode(await readFile(source));
133
+ // One pass: user-provided purpose text cannot become another substitution instruction.
134
+ if (file.origin === 'template')
135
+ content = content.replace(
136
+ /__APP_CONFIG__|__PACKAGE_NAME__|__SDK_VERSION__|__TYPESCRIPT_VERSION__/g,
137
+ (token) => substitutions[token],
138
+ );
139
+ const bytes = Buffer.from(content);
140
+ return { path: file.target, bytes, sha256: hash(bytes) };
141
+ }),
142
+ );
63
143
  }
64
144
  async function compare(target, resources, definition) {
65
145
  const directory = await lstat(target);
66
- if (!directory.isDirectory() || directory.isSymbolicLink()) throw new Error('TARGET must be a real directory');
67
- const receiptPath = join(target, receiptName), info = await lstat(receiptPath);
68
- if (!info.isFile() || info.isSymbolicLink()) throw new Error('Template receipt must be a regular file');
146
+ if (!directory.isDirectory() || directory.isSymbolicLink())
147
+ throw new Error('TARGET must be a real directory');
148
+ const receiptPath = join(target, receiptName),
149
+ info = await lstat(receiptPath);
150
+ if (!info.isFile() || info.isSymbolicLink())
151
+ throw new Error('Template receipt must be a regular file');
69
152
  const receipt = JSON.parse(await readFile(receiptPath, 'utf8'));
70
- if (receipt.schemaVersion !== 1 || receipt.template?.id !== definition.template.id || !Array.isArray(receipt.files)
71
- || receipt.files.some(file => !pathInside(file.path) || !/^[a-f0-9]{64}$/.test(file.sha256))
72
- || new Set(receipt.files.map(file => file.path)).size !== receipt.files.length) throw new Error('Invalid template receipt');
73
- const files = await render(resources, definition, inputs(receipt.inputs?.name, receipt.inputs?.purpose));
74
- const baseline = new Map(receipt.files.map(file => [file.path, file.sha256])), currentTemplate = new Map(files.map(file => [file.path, file.sha256]));
153
+ if (
154
+ receipt.schemaVersion !== 1 ||
155
+ receipt.template?.id !== definition.template.id ||
156
+ !Array.isArray(receipt.files) ||
157
+ receipt.files.some((file) => !pathInside(file.path) || !/^[a-f0-9]{64}$/.test(file.sha256)) ||
158
+ new Set(receipt.files.map((file) => file.path)).size !== receipt.files.length
159
+ )
160
+ throw new Error('Invalid template receipt');
161
+ const files = await render(
162
+ resources,
163
+ definition,
164
+ inputs(receipt.inputs?.name, receipt.inputs?.purpose),
165
+ );
166
+ const baseline = new Map(receipt.files.map((file) => [file.path, file.sha256])),
167
+ currentTemplate = new Map(files.map((file) => [file.path, file.sha256]));
75
168
  const changes = [];
76
169
  for (const path of [...new Set([...baseline.keys(), ...currentTemplate.keys()])].sort()) {
77
- if (!currentTemplate.has(path)) { changes.push({ path, state: 'not-in-current-template', baselineSha256: baseline.get(path), templateChanged: true }); continue; }
170
+ if (!currentTemplate.has(path)) {
171
+ changes.push({
172
+ path,
173
+ state: 'not-in-current-template',
174
+ baselineSha256: baseline.get(path),
175
+ templateChanged: true,
176
+ });
177
+ continue;
178
+ }
78
179
  // Reject symlinks at every managed path component, without reading their destinations.
79
180
  let blocked = false;
80
181
  for (let index = 1; index <= path.split('/').length; index++) {
81
182
  const part = await exists(join(target, ...path.split('/').slice(0, index)));
82
- if (part?.isSymbolicLink()) { blocked = true; break; }
183
+ if (part?.isSymbolicLink()) {
184
+ blocked = true;
185
+ break;
186
+ }
83
187
  }
84
188
  const item = blocked ? undefined : await exists(join(target, path));
85
189
  const actual = item?.isFile() ? hash(await readFile(join(target, path))) : undefined;
86
- changes.push({ path, state: blocked ? 'symlink' : actual === undefined ? 'missing' : actual === baseline.get(path) ? 'unchanged' : 'modified',
87
- baselineSha256: baseline.get(path), currentSha256: actual, templateSha256: currentTemplate.get(path), templateChanged: currentTemplate.get(path) !== baseline.get(path) });
190
+ changes.push({
191
+ path,
192
+ state: blocked
193
+ ? 'symlink'
194
+ : actual === undefined
195
+ ? 'missing'
196
+ : actual === baseline.get(path)
197
+ ? 'unchanged'
198
+ : 'modified',
199
+ baselineSha256: baseline.get(path),
200
+ currentSha256: actual,
201
+ templateSha256: currentTemplate.get(path),
202
+ templateChanged: currentTemplate.get(path) !== baseline.get(path),
203
+ });
88
204
  }
89
- return { status: 'checked', target, installed: { template: receipt.template, sdk: receipt.sdk }, available: { template: { id: definition.template.id, revision: definition.template.revision }, sdk: { name: manifestName, version: resources.sdk.version } }, files: changes, changedFiles: [] };
205
+ return {
206
+ status: 'checked',
207
+ target,
208
+ installed: { template: receipt.template, sdk: receipt.sdk },
209
+ available: {
210
+ template: { id: definition.template.id, revision: definition.template.revision },
211
+ sdk: { name: manifestName, version: resources.sdk.version },
212
+ },
213
+ files: changes,
214
+ changedFiles: [],
215
+ };
90
216
  }
91
217
  const manifestName = '@jangts/agent-core';
92
218
  export async function createApplication(args, cwd = process.cwd()) {
93
219
  const { target, values } = parse(args, cwd);
94
- if (basename(target) === '.local') throw new TypeError('Choose an application directory outside the temporary .local directory itself');
220
+ if (basename(target) === '.local')
221
+ throw new TypeError(
222
+ 'Choose an application directory outside the temporary .local directory itself',
223
+ );
95
224
  const resources = await resolveSdkResources(resolve(cwd, values['--sdk-from'] ?? '.'));
96
225
  const definition = await templateResources(resources, values['--template'] ?? 'node-ts');
97
226
  if (values['--check']) return compare(target, resources, definition);
98
227
  await emptyTarget(target);
99
- const defaultName = basename(target).toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^[._-]+|[._-]+$/g, '') || 'agent-app';
100
- const input = inputs(values['--name'] ?? defaultName, values['--purpose'] ?? '依据当前问题和获准读取的资料提供帮助。');
228
+ const defaultName =
229
+ basename(target)
230
+ .toLowerCase()
231
+ .replace(/[^a-z0-9._-]+/g, '-')
232
+ .replace(/^[._-]+|[._-]+$/g, '') || 'agent-app';
233
+ const input = inputs(
234
+ values['--name'] ?? defaultName,
235
+ values['--purpose'] ?? '依据当前问题和获准读取的资料提供帮助。',
236
+ );
101
237
  const files = await render(resources, definition, input);
102
238
  let source;
103
239
  if (values['--source']) {
104
240
  const path = resolve(cwd, values['--source']);
105
- const info = await lstat(path); if (!info.isFile() || info.isSymbolicLink() || info.size > 32000) throw new TypeError('Source must be a regular UTF-8 file within 32000 bytes');
106
- const library = await import(pathToFileURL(join(dirname(resources.knowledgeLoader), 'source.mjs')));
241
+ const info = await lstat(path);
242
+ if (!info.isFile() || info.isSymbolicLink() || info.size > 32000)
243
+ throw new TypeError('Source must be a regular UTF-8 file within 32000 bytes');
244
+ const library = await import(
245
+ pathToFileURL(join(dirname(resources.knowledgeLoader), 'source.mjs'))
246
+ );
107
247
  source = await library.readSuppliedSource(path, values['--id'], 32000);
108
248
  const knowledge = await import(pathToFileURL(resources.knowledgeLoader));
109
- const policy = JSON.parse(files.find(file => file.path === 'knowledge/knowledge.config.json').bytes.toString('utf8'));
249
+ const policy = JSON.parse(
250
+ files.find((file) => file.path === 'knowledge/knowledge.config.json').bytes.toString('utf8'),
251
+ );
110
252
  knowledge.compileApplicationKnowledge([source.document], policy);
111
253
  }
112
- const receipt = { schemaVersion: 1, template: { id: definition.template.id, revision: definition.template.revision },
113
- sdk: { name: manifestName, version: resources.sdk.version }, inputs: input,
114
- files: files.map(({ path, sha256 }) => ({ path, sha256 })) };
115
- const plan = { status: 'planned', target, ...receipt, files: [...receipt.files, { path: receiptName }],
116
- source: source ? { documentId: values['--id'], originalName: source.name, sha256: source.digest, status: 'candidate-only' } : null,
117
- changedFiles: [], installedDependencies: false, modelCalled: false, published: false };
254
+ const receipt = {
255
+ schemaVersion: 1,
256
+ template: { id: definition.template.id, revision: definition.template.revision },
257
+ sdk: { name: manifestName, version: resources.sdk.version },
258
+ inputs: input,
259
+ files: files.map(({ path, sha256 }) => ({ path, sha256 })),
260
+ };
261
+ const plan = {
262
+ status: 'planned',
263
+ target,
264
+ ...receipt,
265
+ files: [...receipt.files, { path: receiptName }],
266
+ source: source
267
+ ? {
268
+ documentId: values['--id'],
269
+ originalName: source.name,
270
+ sha256: source.digest,
271
+ status: 'candidate-only',
272
+ }
273
+ : null,
274
+ changedFiles: [],
275
+ installedDependencies: false,
276
+ modelCalled: false,
277
+ published: false,
278
+ };
118
279
  if (!values['--write']) return plan;
119
- const parent = dirname(target), temporary = join(parent, '.local');
280
+ const parent = dirname(target),
281
+ temporary = join(parent, '.local');
120
282
  await mkdir(parent, { recursive: true });
121
- let madeTemporary = false, staging;
283
+ let madeTemporary = false,
284
+ staging;
122
285
  try {
123
- try { await mkdir(temporary); madeTemporary = true; } catch (error) { if (error.code !== 'EEXIST') throw error; }
124
- const info = await lstat(temporary); if (!info.isDirectory() || info.isSymbolicLink()) throw new Error('Temporary directory must be a real directory');
286
+ try {
287
+ await mkdir(temporary);
288
+ madeTemporary = true;
289
+ } catch (error) {
290
+ if (error.code !== 'EEXIST') throw error;
291
+ }
292
+ const info = await lstat(temporary);
293
+ if (!info.isDirectory() || info.isSymbolicLink())
294
+ throw new Error('Temporary directory must be a real directory');
125
295
  staging = await mkdtemp(join(temporary, 'agent-core-create-'));
126
- for (const file of files) { await mkdir(dirname(join(staging, file.path)), { recursive: true }); await writeFile(join(staging, file.path), file.bytes, { flag: 'wx' }); }
296
+ for (const file of files) {
297
+ await mkdir(dirname(join(staging, file.path)), { recursive: true });
298
+ await writeFile(join(staging, file.path), file.bytes, { flag: 'wx' });
299
+ }
127
300
  let candidate;
128
301
  if (source) {
129
302
  const snapshot = join(staging, '.local/initial-source', source.name);
130
- await mkdir(dirname(snapshot), { recursive: true }); await writeFile(snapshot, source.bytes, { flag: 'wx' });
131
- const output = await execute(process.execPath, [resources.tools['prepare-source'], join(staging, 'knowledge'), '--source', snapshot, '--id', values['--id']]);
303
+ await mkdir(dirname(snapshot), { recursive: true });
304
+ await writeFile(snapshot, source.bytes, { flag: 'wx' });
305
+ const output = await execute(process.execPath, [
306
+ resources.tools['prepare-source'],
307
+ join(staging, 'knowledge'),
308
+ '--source',
309
+ snapshot,
310
+ '--id',
311
+ values['--id'],
312
+ ]);
132
313
  candidate = relative(staging, JSON.parse(output.stdout).candidate);
133
- if (!pathInside(candidate.split(sep).join('/'))) throw new Error('Candidate escaped the generated project');
314
+ if (!pathInside(candidate.split(sep).join('/')))
315
+ throw new Error('Candidate escaped the generated project');
134
316
  await rm(join(staging, '.local/initial-source'), { recursive: true });
135
317
  await rmdir(join(staging, '.local'));
136
318
  }
137
- await writeFile(join(staging, receiptName), JSON.stringify({ ...receipt, createdAtMs: Date.now() }, null, 2) + '\n', { flag: 'wx' });
319
+ await writeFile(
320
+ join(staging, receiptName),
321
+ JSON.stringify({ ...receipt, createdAtMs: Date.now() }, null, 2) + '\n',
322
+ { flag: 'wx' },
323
+ );
138
324
  // Recheck before the atomic directory rename; a concurrent writer's non-empty target is preserved.
139
- await emptyTarget(target); await rename(staging, target); staging = undefined;
140
- return { ...plan, status: 'created', changedFiles: [...files.map(file => file.path), receiptName], ...(candidate ? { candidate: join(target, candidate) } : {}) };
325
+ await emptyTarget(target);
326
+ await rename(staging, target);
327
+ staging = undefined;
328
+ return {
329
+ ...plan,
330
+ status: 'created',
331
+ changedFiles: [...files.map((file) => file.path), receiptName],
332
+ ...(candidate ? { candidate: join(target, candidate) } : {}),
333
+ };
141
334
  } finally {
142
335
  if (staging) await rm(staging, { recursive: true });
143
336
  if (madeTemporary) await rmdir(temporary).catch(() => {});
144
337
  }
145
338
  }
146
339
  if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
147
- try { console.log(JSON.stringify(await createApplication(process.argv.slice(2)), null, 2)); }
148
- catch (error) { console.error(error instanceof Error ? error.message : String(error)); process.exitCode = 1; }
340
+ try {
341
+ console.log(JSON.stringify(await createApplication(process.argv.slice(2)), null, 2));
342
+ } catch (error) {
343
+ console.error(error instanceof Error ? error.message : String(error));
344
+ process.exitCode = 1;
345
+ }
149
346
  }
@@ -4,8 +4,14 @@ import { Knowledge } from '@jangts/agent-core/kits/knowledge';
4
4
 
5
5
  // This is App-owned configuration and loading code, not a Core file-store API.
6
6
  export function compileApplicationKnowledge(documents, policy) {
7
- if (!policy || policy.schemaVersion !== 1 || !Number.isSafeInteger(policy.maxReadChars) || policy.maxReadChars < 1
8
- || !Array.isArray(policy.requiredReads)) throw new TypeError('Invalid application knowledge policy');
7
+ if (
8
+ !policy ||
9
+ policy.schemaVersion !== 1 ||
10
+ !Number.isSafeInteger(policy.maxReadChars) ||
11
+ policy.maxReadChars < 1 ||
12
+ !Array.isArray(policy.requiredReads)
13
+ )
14
+ throw new TypeError('Invalid application knowledge policy');
9
15
  const catalog = Knowledge.defineKnowledgeCatalog(documents, { maxChars: policy.maxReadChars });
10
16
  // Required task reads must fit their runtime content budget as well as resolve.
11
17
  for (const read of policy.requiredReads) catalog.read(read);
@@ -17,19 +23,38 @@ export async function readApplicationKnowledge(directory = new URL('./', import.
17
23
  const configBytes = await readFile(new URL('knowledge.config.json', directory));
18
24
  const baseConfigSha256 = createHash('sha256').update(configBytes).digest('hex');
19
25
  const policy = JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(configBytes));
20
- if (!Array.isArray(policy.documents) || !Number.isSafeInteger(policy.maxDocumentBytes)
21
- || policy.maxDocumentBytes < 1) throw new TypeError('Invalid application document catalog');
22
- const documents = await Promise.all(policy.documents.map(async entry => {
23
- // The allowlist is App-maintained. Neither a model nor a request supplies this filesystem path.
24
- if (!entry || typeof entry.id !== 'string' || typeof entry.file !== 'string'
25
- || !/^[a-z0-9][a-z0-9.-]*\.knowledge\.md$/.test(entry.file)
26
- || (entry.locale !== undefined && typeof entry.locale !== 'string')) throw new TypeError('Invalid application document entry');
27
- const bytes = await readFile(new URL(entry.file, directory));
28
- if (bytes.length > policy.maxDocumentBytes) throw new RangeError('Source document exceeds the App limit');
29
- const text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
30
- const revision = createHash('sha256').update(JSON.stringify([entry.id, entry.locale, text])).digest('hex');
31
- return Knowledge.parseKnowledgeDocument({ id: entry.id, revision, locale: entry.locale, text });
32
- }));
26
+ if (
27
+ !Array.isArray(policy.documents) ||
28
+ !Number.isSafeInteger(policy.maxDocumentBytes) ||
29
+ policy.maxDocumentBytes < 1
30
+ )
31
+ throw new TypeError('Invalid application document catalog');
32
+ const documents = await Promise.all(
33
+ policy.documents.map(async (entry) => {
34
+ // The allowlist is App-maintained. Neither a model nor a request supplies this filesystem path.
35
+ if (
36
+ !entry ||
37
+ typeof entry.id !== 'string' ||
38
+ typeof entry.file !== 'string' ||
39
+ !/^[a-z0-9][a-z0-9.-]*\.knowledge\.md$/.test(entry.file) ||
40
+ (entry.locale !== undefined && typeof entry.locale !== 'string')
41
+ )
42
+ throw new TypeError('Invalid application document entry');
43
+ const bytes = await readFile(new URL(entry.file, directory));
44
+ if (bytes.length > policy.maxDocumentBytes)
45
+ throw new RangeError('Source document exceeds the App limit');
46
+ const text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
47
+ const revision = createHash('sha256')
48
+ .update(JSON.stringify([entry.id, entry.locale, text]))
49
+ .digest('hex');
50
+ return Knowledge.parseKnowledgeDocument({
51
+ id: entry.id,
52
+ revision,
53
+ locale: entry.locale,
54
+ text,
55
+ });
56
+ }),
57
+ );
33
58
  return { documents, policy, baseConfigSha256 };
34
59
  }
35
60
 
@@ -1,16 +1,44 @@
1
+ /*
2
+ * Reader for a knowledge source file supplied by the operator.
3
+ *
4
+ * The file belongs to the App's development skills (开发技能). It turns one UTF-8 source
5
+ * file into a parsed knowledge document plus the hashes that identify it. The Knowledge
6
+ * Kit owns the document contract; this module only owns the file access, the byte budget
7
+ * and the identity derivation.
8
+ *
9
+ * Main exports: `readSuppliedSource`.
10
+ */
1
11
  import { readFile } from 'node:fs/promises';
2
12
  import { basename } from 'node:path';
3
13
  import { createHash } from 'node:crypto';
4
14
  import { Knowledge } from '@jangts/agent-core/kits/knowledge';
5
15
 
16
+ /**
17
+ * Read and parse one supplied knowledge source file.
18
+ *
19
+ * @param file - Path of the UTF-8 source file.
20
+ * @param id - Stable document id; must be a lowercase slug of at most 64 characters.
21
+ * @param maxBytes - Maximum accepted file size in bytes.
22
+ * @param locale - Optional locale carried over from the document this one replaces.
23
+ * @returns The raw bytes, the parsed document, the original file name and the content hash.
24
+ * @throws TypeError For an invalid document id or a file that is not valid UTF-8.
25
+ * @throws RangeError When the file is empty or exceeds the byte budget.
26
+ * @throws Error When the decoded text is blank, or the anchors of the document are invalid.
27
+ */
6
28
  export async function readSuppliedSource(file, id, maxBytes = 32000, locale) {
29
+ // The id becomes part of the published document identity, so its shape is fixed.
7
30
  if (!/^[a-z][a-z0-9_.:-]{0,63}$/.test(id)) throw new TypeError('Choose a stable document ID');
8
31
  const bytes = await readFile(file);
9
- if (!bytes.length || bytes.length > maxBytes) throw new RangeError('Source must contain text within the configured byte budget');
32
+ if (!bytes.length || bytes.length > maxBytes)
33
+ throw new RangeError('Source must contain text within the configured byte budget');
34
+ // `fatal` rejects malformed UTF-8 instead of replacing the invalid bytes.
10
35
  const text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
11
36
  if (!text.trim()) throw new Error('Source has no content; use empty initialization instead');
37
+ // The content hash covers the raw bytes; the revision covers the parsed identity.
12
38
  const digest = createHash('sha256').update(bytes).digest('hex');
13
- const revision = createHash('sha256').update(JSON.stringify([id, locale, text])).digest('hex');
39
+ const revision = createHash('sha256')
40
+ .update(JSON.stringify([id, locale, text]))
41
+ .digest('hex');
14
42
  const document = Knowledge.parseKnowledgeDocument({ id, revision, locale, text });
15
43
  return { bytes, document, name: basename(file), digest };
16
44
  }
@@ -9,28 +9,53 @@ if (![1, 3].includes(args.length) || (args.length === 3 && args[1] !== '--source
9
9
  throw new Error('Usage: node plan.mjs PROJECT [--source UTF8_FILE]');
10
10
  const project = resolve(args[0]);
11
11
  let exists = true;
12
- try { if (!(await stat(project)).isDirectory()) throw new TypeError('PROJECT must be a directory'); }
13
- catch (error) { if (error.code !== 'ENOENT') throw error; exists = false; }
12
+ try {
13
+ if (!(await stat(project)).isDirectory()) throw new TypeError('PROJECT must be a directory');
14
+ } catch (error) {
15
+ if (error.code !== 'ENOENT') throw error;
16
+ exists = false;
17
+ }
14
18
  const { sdk, tools, docs, knowledgeLoader } = await resolveSdkResources(project);
15
19
  let documents = [];
16
20
  let knowledgeConfigured = false;
17
21
  let knowledgeStatus = 'unconfigured';
18
22
  let baseConfigSha256;
19
23
  if (exists) {
20
- try { await stat(resolve(project, 'knowledge.config.json')); knowledgeConfigured = true; }
21
- catch (error) { if (error.code !== 'ENOENT') throw error; }
24
+ try {
25
+ await stat(resolve(project, 'knowledge.config.json'));
26
+ knowledgeConfigured = true;
27
+ } catch (error) {
28
+ if (error.code !== 'ENOENT') throw error;
29
+ }
22
30
  if (knowledgeConfigured) {
23
- const { readApplicationKnowledge, compileApplicationKnowledge } = await import(pathToFileURL(knowledgeLoader));
31
+ const { readApplicationKnowledge, compileApplicationKnowledge } = await import(
32
+ pathToFileURL(knowledgeLoader)
33
+ );
24
34
  const snapshot = await readApplicationKnowledge(pathToFileURL(project + sep));
25
35
  const catalog = compileApplicationKnowledge(snapshot.documents, snapshot.policy);
26
- documents = snapshot.policy.documents.map(item => ({ id: item.id, file: item.file }));
36
+ documents = snapshot.policy.documents.map((item) => ({ id: item.id, file: item.file }));
27
37
  knowledgeStatus = catalog.ids().length ? 'valid' : 'empty-awaiting-source';
28
38
  baseConfigSha256 = snapshot.baseConfigSha256;
29
39
  }
30
40
  }
31
- console.log(JSON.stringify({ project, mode: exists ? 'integrate-or-maintain' : 'create-application', sdk,
32
- knowledgeConfigured, knowledgeStatus, baseConfigSha256, suppliedSource: args[2] ? resolve(args[2]) : null,
33
- factsPolicy: 'Use only supplied source; with ideas only, keep knowledge files empty.',
34
- documents, tools, docs,
35
- changedFiles: [], published: false,
36
- }, null, 2));
41
+ console.log(
42
+ JSON.stringify(
43
+ {
44
+ project,
45
+ mode: exists ? 'integrate-or-maintain' : 'create-application',
46
+ sdk,
47
+ knowledgeConfigured,
48
+ knowledgeStatus,
49
+ baseConfigSha256,
50
+ suppliedSource: args[2] ? resolve(args[2]) : null,
51
+ factsPolicy: 'Use only supplied source; with ideas only, keep knowledge files empty.',
52
+ documents,
53
+ tools,
54
+ docs,
55
+ changedFiles: [],
56
+ published: false,
57
+ },
58
+ null,
59
+ 2,
60
+ ),
61
+ );