deepclause-sdk 0.0.88 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (318) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +418 -914
  3. package/dist/agent.d.ts +19 -2
  4. package/dist/agent.d.ts.map +1 -1
  5. package/dist/agent.js +221 -4
  6. package/dist/agent.js.map +1 -1
  7. package/dist/cli/config.d.ts +323 -176
  8. package/dist/cli/config.d.ts.map +1 -1
  9. package/dist/cli/config.js +146 -188
  10. package/dist/cli/config.js.map +1 -1
  11. package/dist/cli/index.d.ts +3 -2
  12. package/dist/cli/index.d.ts.map +1 -1
  13. package/dist/cli/index.js +61 -425
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/cli/login.d.ts +29 -0
  16. package/dist/cli/login.d.ts.map +1 -0
  17. package/dist/cli/login.js +184 -0
  18. package/dist/cli/login.js.map +1 -0
  19. package/dist/cli/readline.d.ts +6 -0
  20. package/dist/cli/readline.d.ts.map +1 -0
  21. package/dist/cli/readline.js +15 -0
  22. package/dist/cli/readline.js.map +1 -0
  23. package/dist/cli/repl-bin.d.ts +9 -0
  24. package/dist/cli/repl-bin.d.ts.map +1 -0
  25. package/dist/cli/repl-bin.js +16 -0
  26. package/dist/cli/repl-bin.js.map +1 -0
  27. package/dist/cli/repl.d.ts +191 -0
  28. package/dist/cli/repl.d.ts.map +1 -0
  29. package/dist/cli/repl.js +1232 -0
  30. package/dist/cli/repl.js.map +1 -0
  31. package/dist/cli/run.d.ts +17 -18
  32. package/dist/cli/run.d.ts.map +1 -1
  33. package/dist/cli/run.js +196 -183
  34. package/dist/cli/run.js.map +1 -1
  35. package/dist/cli/set-backend.d.ts +53 -0
  36. package/dist/cli/set-backend.d.ts.map +1 -0
  37. package/dist/cli/set-backend.js +259 -0
  38. package/dist/cli/set-backend.js.map +1 -0
  39. package/dist/cli/visualize.d.ts +38 -0
  40. package/dist/cli/visualize.d.ts.map +1 -0
  41. package/dist/cli/visualize.js +125 -0
  42. package/dist/cli/visualize.js.map +1 -0
  43. package/dist/compiler.d.ts +5 -52
  44. package/dist/compiler.d.ts.map +1 -1
  45. package/dist/compiler.js +4 -768
  46. package/dist/compiler.js.map +1 -1
  47. package/dist/index.d.ts +29 -2
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +20 -2
  50. package/dist/index.js.map +1 -1
  51. package/dist/judge/index.d.ts +9 -0
  52. package/dist/judge/index.d.ts.map +1 -0
  53. package/dist/judge/index.js +6 -0
  54. package/dist/judge/index.js.map +1 -0
  55. package/dist/judge/jev.d.ts +21 -0
  56. package/dist/judge/jev.d.ts.map +1 -0
  57. package/dist/judge/jev.js +218 -0
  58. package/dist/judge/jev.js.map +1 -0
  59. package/dist/judge/llm.d.ts +23 -0
  60. package/dist/judge/llm.d.ts.map +1 -0
  61. package/dist/judge/llm.js +120 -0
  62. package/dist/judge/llm.js.map +1 -0
  63. package/dist/judge/marshal.d.ts +26 -0
  64. package/dist/judge/marshal.d.ts.map +1 -0
  65. package/dist/judge/marshal.js +266 -0
  66. package/dist/judge/marshal.js.map +1 -0
  67. package/dist/judge/mock.d.ts +28 -0
  68. package/dist/judge/mock.d.ts.map +1 -0
  69. package/dist/judge/mock.js +98 -0
  70. package/dist/judge/mock.js.map +1 -0
  71. package/dist/judge/types.d.ts +95 -0
  72. package/dist/judge/types.d.ts.map +1 -0
  73. package/dist/judge/types.js +23 -0
  74. package/dist/judge/types.js.map +1 -0
  75. package/dist/prolog/bridge.d.ts +5 -1
  76. package/dist/prolog/bridge.d.ts.map +1 -1
  77. package/dist/prolog/bridge.js +29 -1
  78. package/dist/prolog/bridge.js.map +1 -1
  79. package/dist/prolog-src/deepclause_analysis.pl +10 -2
  80. package/dist/prolog-src/deepclause_mi.pl +2522 -118
  81. package/dist/repl/agent.d.ts +72 -0
  82. package/dist/repl/agent.d.ts.map +1 -0
  83. package/dist/repl/agent.js +366 -0
  84. package/dist/repl/agent.js.map +1 -0
  85. package/dist/repl/auth.d.ts +45 -0
  86. package/dist/repl/auth.d.ts.map +1 -0
  87. package/dist/repl/auth.js +116 -0
  88. package/dist/repl/auth.js.map +1 -0
  89. package/dist/repl/backend.d.ts +290 -0
  90. package/dist/repl/backend.d.ts.map +1 -0
  91. package/dist/repl/backend.js +370 -0
  92. package/dist/repl/backend.js.map +1 -0
  93. package/dist/repl/compaction.d.ts +122 -0
  94. package/dist/repl/compaction.d.ts.map +1 -0
  95. package/dist/repl/compaction.js +318 -0
  96. package/dist/repl/compaction.js.map +1 -0
  97. package/dist/repl/export.d.ts +30 -0
  98. package/dist/repl/export.d.ts.map +1 -0
  99. package/dist/repl/export.js +23 -0
  100. package/dist/repl/export.js.map +1 -0
  101. package/dist/repl/frames.d.ts +21 -0
  102. package/dist/repl/frames.d.ts.map +1 -0
  103. package/dist/repl/frames.js +79 -0
  104. package/dist/repl/frames.js.map +1 -0
  105. package/dist/repl/harness-tools.d.ts +74 -0
  106. package/dist/repl/harness-tools.d.ts.map +1 -0
  107. package/dist/repl/harness-tools.js +121 -0
  108. package/dist/repl/harness-tools.js.map +1 -0
  109. package/dist/repl/highlight.d.ts +30 -0
  110. package/dist/repl/highlight.d.ts.map +1 -0
  111. package/dist/repl/highlight.js +285 -0
  112. package/dist/repl/highlight.js.map +1 -0
  113. package/dist/repl/history.d.ts +234 -0
  114. package/dist/repl/history.d.ts.map +1 -0
  115. package/dist/repl/history.js +661 -0
  116. package/dist/repl/history.js.map +1 -0
  117. package/dist/repl/index.d.ts +120 -0
  118. package/dist/repl/index.d.ts.map +1 -0
  119. package/dist/repl/index.js +107 -0
  120. package/dist/repl/index.js.map +1 -0
  121. package/dist/repl/judge.d.ts +51 -0
  122. package/dist/repl/judge.d.ts.map +1 -0
  123. package/dist/repl/judge.js +58 -0
  124. package/dist/repl/judge.js.map +1 -0
  125. package/dist/repl/markdown.d.ts +25 -0
  126. package/dist/repl/markdown.d.ts.map +1 -0
  127. package/dist/repl/markdown.js +103 -0
  128. package/dist/repl/markdown.js.map +1 -0
  129. package/dist/repl/picker.d.ts +34 -0
  130. package/dist/repl/picker.d.ts.map +1 -0
  131. package/dist/repl/picker.js +81 -0
  132. package/dist/repl/picker.js.map +1 -0
  133. package/dist/repl/project-context.d.ts +16 -0
  134. package/dist/repl/project-context.d.ts.map +1 -0
  135. package/dist/repl/project-context.js +23 -0
  136. package/dist/repl/project-context.js.map +1 -0
  137. package/dist/repl/render.d.ts +160 -0
  138. package/dist/repl/render.d.ts.map +1 -0
  139. package/dist/repl/render.js +715 -0
  140. package/dist/repl/render.js.map +1 -0
  141. package/dist/repl/session.d.ts +356 -0
  142. package/dist/repl/session.d.ts.map +1 -0
  143. package/dist/repl/session.js +1275 -0
  144. package/dist/repl/session.js.map +1 -0
  145. package/dist/repl/status.d.ts +100 -0
  146. package/dist/repl/status.d.ts.map +1 -0
  147. package/dist/repl/status.js +218 -0
  148. package/dist/repl/status.js.map +1 -0
  149. package/dist/repl/tools.d.ts +53 -0
  150. package/dist/repl/tools.d.ts.map +1 -0
  151. package/dist/repl/tools.js +307 -0
  152. package/dist/repl/tools.js.map +1 -0
  153. package/dist/repl/toolset.d.ts +32 -0
  154. package/dist/repl/toolset.d.ts.map +1 -0
  155. package/dist/repl/toolset.js +82 -0
  156. package/dist/repl/toolset.js.map +1 -0
  157. package/dist/repl/tui/editor.d.ts +17 -0
  158. package/dist/repl/tui/editor.d.ts.map +1 -0
  159. package/dist/repl/tui/editor.js +39 -0
  160. package/dist/repl/tui/editor.js.map +1 -0
  161. package/dist/repl/tui/status-bar.d.ts +26 -0
  162. package/dist/repl/tui/status-bar.d.ts.map +1 -0
  163. package/dist/repl/tui/status-bar.js +47 -0
  164. package/dist/repl/tui/status-bar.js.map +1 -0
  165. package/dist/repl/tui/theme.d.ts +30 -0
  166. package/dist/repl/tui/theme.d.ts.map +1 -0
  167. package/dist/repl/tui/theme.js +81 -0
  168. package/dist/repl/tui/theme.js.map +1 -0
  169. package/dist/repl/tui/transcript.d.ts +39 -0
  170. package/dist/repl/tui/transcript.d.ts.map +1 -0
  171. package/dist/repl/tui/transcript.js +123 -0
  172. package/dist/repl/tui/transcript.js.map +1 -0
  173. package/dist/runner.d.ts +145 -13
  174. package/dist/runner.d.ts.map +1 -1
  175. package/dist/runner.js +600 -282
  176. package/dist/runner.js.map +1 -1
  177. package/dist/sdk.d.ts.map +1 -1
  178. package/dist/sdk.js +56 -32
  179. package/dist/sdk.js.map +1 -1
  180. package/dist/system/assets/docs/AGENT_PROMPT.md +1373 -0
  181. package/dist/system/assets/docs/DML_AUTHORING.md +195 -0
  182. package/dist/system/assets/docs/DML_REFERENCE.md +393 -72
  183. package/dist/system/assets/docs/HARNESS_EXAMPLES.md +172 -0
  184. package/dist/system/assets/docs/HARNESS_PATTERNS.md +562 -0
  185. package/dist/system/assets/docs/META_PROMPT.md +68 -0
  186. package/dist/system/assets/docs/PROLOG_SNIPPETS.md +117 -0
  187. package/dist/system/assets/index.d.ts +9 -17
  188. package/dist/system/assets/index.d.ts.map +1 -1
  189. package/dist/system/assets/index.js +26 -85
  190. package/dist/system/assets/index.js.map +1 -1
  191. package/dist/system/runtime/agentvm-manager.d.ts +9 -2
  192. package/dist/system/runtime/agentvm-manager.d.ts.map +1 -1
  193. package/dist/system/runtime/agentvm-manager.js +70 -44
  194. package/dist/system/runtime/agentvm-manager.js.map +1 -1
  195. package/dist/system/runtime/media.d.ts +23 -0
  196. package/dist/system/runtime/media.d.ts.map +1 -0
  197. package/dist/system/runtime/media.js +55 -0
  198. package/dist/system/runtime/media.js.map +1 -0
  199. package/dist/system/runtime/shell-limits.d.ts +21 -0
  200. package/dist/system/runtime/shell-limits.d.ts.map +1 -0
  201. package/dist/system/runtime/shell-limits.js +39 -0
  202. package/dist/system/runtime/shell-limits.js.map +1 -0
  203. package/dist/system/runtime/shell-manager.d.ts +8 -3
  204. package/dist/system/runtime/shell-manager.d.ts.map +1 -1
  205. package/dist/system/runtime/shell-manager.js +56 -39
  206. package/dist/system/runtime/shell-manager.js.map +1 -1
  207. package/dist/system/runtime/shell-tool-events.js +5 -0
  208. package/dist/system/runtime/shell-tool-events.js.map +1 -1
  209. package/dist/system/runtime/token-usage.d.ts +2 -0
  210. package/dist/system/runtime/token-usage.d.ts.map +1 -1
  211. package/dist/system/runtime/token-usage.js +7 -0
  212. package/dist/system/runtime/token-usage.js.map +1 -1
  213. package/dist/tools.d.ts +3 -21
  214. package/dist/tools.d.ts.map +1 -1
  215. package/dist/tools.js +14 -168
  216. package/dist/tools.js.map +1 -1
  217. package/dist/types.d.ts +149 -118
  218. package/dist/types.d.ts.map +1 -1
  219. package/dist/validate.d.ts +19 -0
  220. package/dist/validate.d.ts.map +1 -0
  221. package/dist/validate.js +338 -0
  222. package/dist/validate.js.map +1 -0
  223. package/dist/visualize/index.d.ts +52 -0
  224. package/dist/visualize/index.d.ts.map +1 -0
  225. package/dist/visualize/index.js +189 -0
  226. package/dist/visualize/index.js.map +1 -0
  227. package/package.json +17 -15
  228. package/src/prolog-src/deepclause_analysis.pl +10 -2
  229. package/src/prolog-src/deepclause_mi.pl +2522 -118
  230. package/dist/cli/commands.d.ts +0 -42
  231. package/dist/cli/commands.d.ts.map +0 -1
  232. package/dist/cli/commands.js +0 -246
  233. package/dist/cli/commands.js.map +0 -1
  234. package/dist/cli/compile.d.ts +0 -99
  235. package/dist/cli/compile.d.ts.map +0 -1
  236. package/dist/cli/compile.js +0 -363
  237. package/dist/cli/compile.js.map +0 -1
  238. package/dist/cli/default-skills.d.ts +0 -10
  239. package/dist/cli/default-skills.d.ts.map +0 -1
  240. package/dist/cli/default-skills.js +0 -206
  241. package/dist/cli/default-skills.js.map +0 -1
  242. package/dist/cli/interactive.d.ts +0 -2
  243. package/dist/cli/interactive.d.ts.map +0 -1
  244. package/dist/cli/interactive.js +0 -20
  245. package/dist/cli/interactive.js.map +0 -1
  246. package/dist/cli/mcp.d.ts +0 -56
  247. package/dist/cli/mcp.d.ts.map +0 -1
  248. package/dist/cli/mcp.js +0 -138
  249. package/dist/cli/mcp.js.map +0 -1
  250. package/dist/cli/prompt.d.ts +0 -2
  251. package/dist/cli/prompt.d.ts.map +0 -1
  252. package/dist/cli/prompt.js +0 -2
  253. package/dist/cli/prompt.js.map +0 -1
  254. package/dist/cli/search.d.ts +0 -19
  255. package/dist/cli/search.d.ts.map +0 -1
  256. package/dist/cli/search.js +0 -189
  257. package/dist/cli/search.js.map +0 -1
  258. package/dist/cli/tool-args.d.ts +0 -2
  259. package/dist/cli/tool-args.d.ts.map +0 -1
  260. package/dist/cli/tool-args.js +0 -39
  261. package/dist/cli/tool-args.js.map +0 -1
  262. package/dist/cli/tools.d.ts +0 -36
  263. package/dist/cli/tools.d.ts.map +0 -1
  264. package/dist/cli/tools.js +0 -229
  265. package/dist/cli/tools.js.map +0 -1
  266. package/dist/cli/tui/index.d.ts +0 -22
  267. package/dist/cli/tui/index.d.ts.map +0 -1
  268. package/dist/cli/tui/index.js +0 -29
  269. package/dist/cli/tui/index.js.map +0 -1
  270. package/dist/cli/tui.d.ts +0 -167
  271. package/dist/cli/tui.d.ts.map +0 -1
  272. package/dist/cli/tui.js +0 -5228
  273. package/dist/cli/tui.js.map +0 -1
  274. package/dist/compiler_prompt.d.ts +0 -20
  275. package/dist/compiler_prompt.d.ts.map +0 -1
  276. package/dist/compiler_prompt.js +0 -870
  277. package/dist/compiler_prompt.js.map +0 -1
  278. package/dist/deepclause-cli.skill +0 -0
  279. package/dist/prolog-src/deepclause_mi.pl.bak +0 -570
  280. package/dist/system/assets/compactors/default-memory-compactor.dml +0 -6
  281. package/dist/system/assets/docs/CONDUCTOR_PROMPT.md +0 -105
  282. package/dist/system/assets/docs/DML_COMPILER_PROMPT.md +0 -700
  283. package/dist/system/assets/docs/TUI.md +0 -150
  284. package/dist/system/assets/recipes/deepclause-coding-workflow/SKILL.md +0 -100
  285. package/dist/system/assets/skills/conductor.dml +0 -76
  286. package/dist/system/assets/skills/deep-planner.dml +0 -412
  287. package/dist/system/assets/skills/plan.dml +0 -429
  288. package/dist/system/assets/skills/security-planner.dml +0 -337
  289. package/dist/system/assets/skills/skill-creator.dml +0 -187
  290. package/dist/system/runtime/catalog-recipes.d.ts +0 -24
  291. package/dist/system/runtime/catalog-recipes.d.ts.map +0 -1
  292. package/dist/system/runtime/catalog-recipes.js +0 -273
  293. package/dist/system/runtime/catalog-recipes.js.map +0 -1
  294. package/dist/system/runtime/catalog-skills.d.ts +0 -50
  295. package/dist/system/runtime/catalog-skills.d.ts.map +0 -1
  296. package/dist/system/runtime/catalog-skills.js +0 -152
  297. package/dist/system/runtime/catalog-skills.js.map +0 -1
  298. package/dist/system/runtime/conductor.d.ts +0 -105
  299. package/dist/system/runtime/conductor.d.ts.map +0 -1
  300. package/dist/system/runtime/conductor.js +0 -732
  301. package/dist/system/runtime/conductor.js.map +0 -1
  302. package/dist/system/runtime/console-capture.d.ts +0 -9
  303. package/dist/system/runtime/console-capture.d.ts.map +0 -1
  304. package/dist/system/runtime/console-capture.js +0 -67
  305. package/dist/system/runtime/console-capture.js.map +0 -1
  306. package/dist/system/runtime/dml-executor.d.ts +0 -52
  307. package/dist/system/runtime/dml-executor.d.ts.map +0 -1
  308. package/dist/system/runtime/dml-executor.js +0 -203
  309. package/dist/system/runtime/dml-executor.js.map +0 -1
  310. package/dist/system/runtime/runtime-tools.d.ts +0 -31
  311. package/dist/system/runtime/runtime-tools.d.ts.map +0 -1
  312. package/dist/system/runtime/runtime-tools.js +0 -312
  313. package/dist/system/runtime/runtime-tools.js.map +0 -1
  314. package/dist/system/runtime/skill-creator.d.ts +0 -38
  315. package/dist/system/runtime/skill-creator.d.ts.map +0 -1
  316. package/dist/system/runtime/skill-creator.js +0 -763
  317. package/dist/system/runtime/skill-creator.js.map +0 -1
  318. package/src/prolog-src/deepclause_mi.pl.bak +0 -570
@@ -1,870 +0,0 @@
1
- /**
2
- * DeepClause SDK - MD to DML Conversion Prompt
3
- *
4
- * Contains the base prompt template for converting Markdown task descriptions to DML.
5
- */
6
- // =============================================================================
7
- // Prompt Template
8
- // =============================================================================
9
- export const DML_CONVERSION_PROMPT = `# Markdown to DML Conversion Prompt
10
-
11
- You are an expert DML (DeepClause Meta Language) programmer. Your task is to convert
12
- natural language task descriptions written in Markdown into executable DML programs.
13
-
14
- ## Tool Types in DML
15
-
16
- There are two kinds of tools in DML:
17
-
18
- ### 1. DML Tool Wrappers (via \`tool/3\`)
19
- These are predicates you define in DML using the \`tool/3\` syntax. They are pure DML logic
20
- and typically wrap one or more external tools for convenience or composition. They are
21
- **not** registered as external dependencies.
22
-
23
- \`\`\`prolog
24
- tool(search(Query, Results), "Search the web for information") :-
25
- exec(web_search(query: Query), Results).
26
- \`\`\`
27
-
28
- ### 2. External Tools (MCP/Built-ins)
29
- These are provided by the runtime (via MCP servers or built-in runtime tools) and are invoked
30
- directly with \`exec/2\`. Only these are registered as dependencies in the meta file.
31
-
32
- ## Available External Tools
33
-
34
- {TOOLS_TABLE}
35
-
36
- **Note:** Only tools invoked via \`exec/2\` that correspond to external MCP or built-in runtime
37
- tools are registered as dependencies. DML tool wrappers are not registered unless they
38
- call external tools.
39
-
40
- ## DML Language Overview
41
-
42
- DML is a simplified Prolog dialect designed for AI agent programming. It combines
43
- declarative logic programming with LLM-powered task execution.
44
-
45
- ### Program Structure
46
-
47
- Every DML program must have an \`agent_main\` entry point that accepts 0+ arguments:
48
-
49
- \`\`\`prolog
50
- % No arguments
51
- agent_main :- ...
52
-
53
- % One argument
54
- agent_main(Topic) :- ...
55
-
56
- % Two arguments (alphabetical order for dict unpacking)
57
- agent_main(MaxResults, Topic) :- ...
58
- \`\`\`
59
-
60
- ### Core Predicates
61
-
62
- #### Task Execution
63
-
64
- | Predicate | Description |
65
- |-----------|-------------|
66
- | \`task(Description)\` | Execute an LLM task with accumulated memory |
67
- | \`task(Description, Var)\` | Execute task, bind result to Var |
68
- | \`task(Description, Var1, Var2)\` | Execute task, bind two results |
69
- | \`task(Description, Var1, Var2, Var3)\` | Execute task, bind three results |
70
-
71
- **Type-Safe Output Variables:**
72
- You can wrap output variables with type specifiers to enforce strict validation:
73
- - \`string(Var)\` (Default)
74
- - \`integer(Var)\` - Enforces integer type
75
- - \`number(Var)\` or \`float(Var)\` - Enforces numeric type
76
- - \`boolean(Var)\` - Enforces boolean type
77
- - \`list(string(Var))\` - Enforces array of strings (or other types)
78
- - \`object(Var)\` - Enforces object/dict type
79
-
80
- \`\`\`prolog
81
- task("Calculate result", integer(Result))
82
- task("List items", list(string(Items)))
83
- task("Check status", boolean(IsComplete))
84
- \`\`\`
85
-
86
- **Important:** Variable names in the description must match the Prolog variables:
87
- \`\`\`prolog
88
- task("Analyze this and store the result in Summary.", Summary)
89
- \`\`\`
90
-
91
- #### Fresh LLM Calls (No Memory)
92
-
93
- | Predicate | Description |
94
- |-----------|-------------|
95
- | \`prompt(Description)\` | Execute LLM with **empty memory** (fresh context) |
96
- | \`prompt(Description, Var)\` | Fresh LLM call, bind result to Var |
97
- | \`prompt(Description, Var1, Var2)\` | Fresh LLM call, bind two results |
98
- | \`prompt(Description, Var1, Var2, Var3)\` | Fresh LLM call, bind three results |
99
-
100
- **When to use \`prompt()\` vs \`task()\`:**
101
- - Use \`task()\` when you want the LLM to have context from previous \`system()\`, \`user()\`, and \`task()\` calls
102
- - Use \`prompt()\` when you want a completely fresh LLM call without any prior conversation context
103
-
104
- \`\`\`prolog
105
- agent_main :-
106
- system("You are a helpful assistant."),
107
- task("What is 2+2?"), % LLM sees the system message
108
- prompt("What is 3+3?"). % LLM does NOT see any prior context
109
- \`\`\`
110
-
111
- #### Direct Tool Execution
112
-
113
- | Predicate | Description |
114
- |-----------|-------------|
115
- | \`exec(Tool, Result)\` | Execute external tool directly |
116
-
117
- \`\`\`prolog
118
- exec(web_search(query: "AI news"), Results)
119
- exec(vm_exec(command: "echo hello"), Result)
120
- \`\`\`
121
-
122
- **Important:** \`vm_exec\` returns a dict with \`stdout\`, \`stderr\`, and \`exitCode\` fields.
123
- Use \`get_dict/3\` to extract values:
124
- \`\`\`prolog
125
- exec(vm_exec(command: "echo hello"), Result),
126
- get_dict(stdout, Result, Output),
127
- output(Output).
128
- \`\`\`
129
-
130
- **Working Directory:** Shell tools run in the active workspace directory. When AgentVM sandboxing is enabled, that workspace is mounted at \`/workspace\` inside the sandbox. Files are directly accessible:
131
- \`\`\`prolog
132
- exec(vm_exec(command: "cat README.md"), Result), % Reads workspace/README.md
133
- get_dict(stdout, Result, Content).
134
- \`\`\`
135
-
136
- #### Memory Management
137
-
138
- | Predicate | Description |
139
- |-----------|-------------|
140
- | \`system(Text)\` | Add system message (LLM instructions) |
141
- | \`user(Text)\` | Add user message to context |
142
- | \`push_context\` | Save memory state (for isolation) |
143
- | \`push_context(clear)\` | Save and clear memory |
144
- | \`pop_context\` | Restore previous memory state |
145
- | \`clear_memory\` | Clear all accumulated memory |
146
-
147
- **Note:** Memory is automatically restored on backtracking, so \`push_context\`/\`pop_context\`
148
- are primarily useful for manual isolation within a clause.
149
-
150
- #### Output
151
-
152
- | Predicate | Description |
153
- |-----------|-------------|
154
- | \`output(Text)\` | Emit progress/intermediate output |
155
- | \`yield(Text)\` | Alias for output/1 |
156
- | \`log(Text)\` | Emit debug/log message |
157
- | \`answer(Text)\` | Emit final answer (commits execution) |
158
-
159
- #### Tool Definitions
160
-
161
- Define tools that the LLM can call during \`task()\` execution:
162
-
163
- \`\`\`prolog
164
- % Tool wrapper (description is second arg, body calls exec)
165
- tool(search(Query, Results), "Search the web for information") :-
166
- exec(web_search(query: Query), Results).
167
- \`\`\`
168
-
169
- **CRITICAL: Tools are LLM-only!** Tools defined with \`tool/3\` can ONLY be called by the
170
- LLM during \`task()\` execution. You CANNOT call tools directly from DML code:
171
-
172
- \`\`\`prolog
173
- % WRONG - tools cannot be called directly from DML!
174
- agent_main :-
175
- search("AI news", Results), % ERROR: search/2 is not a regular predicate
176
- output(Results).
177
-
178
- % CORRECT - let the LLM call the tool via task()
179
- agent_main :-
180
- system("You are a research assistant. Use the search tool to find information."),
181
- task("Search for AI news and summarize the results.", Summary),
182
- output(Summary).
183
-
184
- % CORRECT - use exec() directly if you need to call the external tool from DML
185
- agent_main :-
186
- exec(web_search(query: "AI news"), Results), % Direct external tool call
187
- get_dict(results, Results, Data),
188
- output(Data).
189
- \`\`\`
190
- #### Using \`task()\` and \`prompt()\` Inside Tools
191
-
192
- Tools can use \`task()\` or \`prompt()\` internally to combine Prolog logic with LLM reasoning:
193
-
194
- \`\`\`prolog
195
- % A tool that computes then explains
196
- tool(explain_calculation(A, B, Explanation), "Calculate and explain the result") :-
197
- Sum is A + B, % Prolog computation
198
- format(string(Desc), "Explain ~w + ~w = ~w to a child", [A, B, Sum]),
199
- task(Desc, Explanation). % LLM explanation
200
- \`\`\`
201
-
202
- **Memory Isolation:** Nested \`task()\` calls inside tools run with **fresh memory** - they
203
- do NOT have access to the parent's accumulated memory. If you need context, either:
204
- 1. Pass it as a tool argument
205
- 2. Add it explicitly with \`system()\` inside the tool
206
-
207
- \`\`\`prolog
208
- % Pass context explicitly as an argument
209
- tool(analyze_with_context(Context, Data, Result), "Analyze data with given context") :-
210
- system(Context), % Add context to this tool's memory
211
- format(string(Desc), "Analyze: ~w", [Data]),
212
- task(Desc, Result).
213
- \`\`\`
214
-
215
- **Automatic Recursion Prevention:** When \`task()\` runs inside a tool, the nested agent
216
- cannot call the tool that is currently executing. This prevents infinite recursion.
217
-
218
- #### Tool Scoping
219
-
220
- Control which tools are available to nested \`task()\` calls:
221
-
222
- | Predicate | Description |
223
- |-----------|-------------|
224
- | \`with_tools(ToolList, Goal)\` | Run Goal with only specified tools available |
225
- | \`without_tools(ToolList, Goal)\` | Run Goal excluding specified tools |
226
-
227
- \`\`\`prolog
228
- % Only allow search tool in nested task
229
- tool(safe_research(Topic, Result), "Research with limited tools") :-
230
- with_tools([search], (
231
- format(string(Desc), "Research ~w using search", [Topic]),
232
- task(Desc, Result)
233
- )).
234
-
235
- % Exclude expensive tools from nested task
236
- tool(cheap_task(Input, Output), "Process without expensive tools") :-
237
- without_tools([expensive_api], (
238
- task("Process {Input} cheaply", Output)
239
- )).
240
- \`\`\`
241
- #### Built-in Agent Tools
242
-
243
- During \`task()\` execution, the LLM has access to these built-in tools (plus any you define with \`tool/3\`):
244
-
245
- | Tool | Description |
246
- |------|-------------|
247
- | \`store(variable, value)\` | Store a result in an output variable |
248
- | \`ask_user(prompt)\` | Ask the user for input or clarification |
249
- | \`finish(success)\` | Complete the task |
250
-
251
- **Remember:** These tools (and your custom \`tool/3\` definitions) are only available to the
252
- LLM during \`task()\` calls. DML code uses \`exec()\` for direct external tool access.
253
-
254
- **Important:** If your task might need user input (clarification, choices, confirmation),
255
- you should define an \`ask_user\` tool wrapper so the LLM can request input:
256
-
257
- \`\`\`prolog
258
- % Define ask_user wrapper so LLM can request user input during task()
259
- tool(ask_user(Prompt, Response), "Ask the user a question and get their response") :-
260
- exec(ask_user(prompt: Prompt), Result),
261
- get_dict(user_response, Result, Response).
262
- \`\`\`
263
-
264
- ### String Interpolation
265
-
266
- DML supports **automatic string interpolation** using \`{Variable}\` syntax in task descriptions
267
- and output predicates. This is the preferred method:
268
-
269
- \`\`\`prolog
270
- agent_main(Topic) :-
271
- task("Research the topic: {Topic}"),
272
- output("Finished researching {Topic}"),
273
- answer("Done").
274
- \`\`\`
275
-
276
- **IMPORTANT:** Never mix \`{Variable}\` interpolation with \`format/3\`. Choose one approach:
277
-
278
- **Option 1: String Interpolation (preferred for simple cases)**
279
- \`\`\`prolog
280
- % Variables are automatically substituted
281
- task("Analyze {Data} and summarize in Summary.", Summary),
282
- output("Analysis complete for {Data}")
283
- \`\`\`
284
-
285
- **Option 2: format/3 for complex string building (Prolog-style)**
286
- \`\`\`prolog
287
- % format/3 writes to a string variable - use ~w for terms, ~s for strings
288
- format(string(Message), "Found ~d results for query: ~w", [Count, Query]),
289
- output(Message)
290
- \`\`\`
291
-
292
- **WRONG - Never do this:**
293
- \`\`\`prolog
294
- % DON'T mix interpolation and format
295
- output(format("Value: {X}", [X])) % WRONG! format doesn't return a value
296
-
297
- % DON'T use {Var} inside format strings
298
- format(string(S), "Topic: {Topic}", []) % WRONG! Use ~w instead
299
- \`\`\`
300
-
301
- ### Control Flow
302
-
303
- \`\`\`prolog
304
- % Conjunction (and)
305
- goal1, goal2, goal3
306
-
307
- % Disjunction (or)
308
- (goal1 ; goal2)
309
-
310
- % If-then-else
311
- (Condition -> Then ; Else)
312
-
313
- % Negation as failure
314
- \\+ goal
315
-
316
- % Cut (commit to this branch)
317
- !
318
-
319
- % Exception handling
320
- catch(Goal, Error, Recovery)
321
- throw(some_error)
322
- \`\`\`
323
-
324
- ### Module Directives & Logic (CLP)
325
-
326
- DML supports top-level \`:- use_module(...)\` directives for standard SWI-Prolog libraries, such as \`library(clpfd)\`.
327
- Use them when the skill needs built-in library predicates. For workspace-local shared DML code, prefer \`:- consult('relative/path.dml').\`.
328
- Local \`:- use_module('relative/path.dml').\` is accepted as a convenience alias, but it currently loads the file with consult-style semantics rather than full SWI module export filtering.
329
-
330
- - **CLP(FD)**: Finite domains (integers). Use \`:- use_module(library(clpfd)).\`
331
- - **CLP(Q)**: Rational numbers (exact fractions). Use \`:- use_module(library(clpq)).\`
332
- - **CLP(R)**: Real numbers (floating point). Use \`:- use_module(library(clpr)).\`
333
-
334
- \`\`\`prolog
335
- :- use_module(library(clpfd)).
336
-
337
- % Solve: find X and Y such that X+Y=10 and X*Y=24
338
- solve(X, Y) :-
339
- [X,Y] ins 0..10,
340
- X + Y #= 10,
341
- X * Y #= 24,
342
- label([X,Y]).
343
- \`\`\`
344
-
345
- ### Backtracking
346
-
347
- DML supports full Prolog backtracking across LLM calls:
348
-
349
- \`\`\`prolog
350
- % Try multiple approaches
351
- agent_main :-
352
- ( try_approach_1
353
- ; try_approach_2 % Falls back if first fails
354
- ; fallback_approach
355
- ),
356
- answer("Done").
357
- \`\`\`
358
-
359
- ### List Processing
360
-
361
- \`\`\`prolog
362
- % Recursive list processing
363
- process_items([]).
364
- process_items([H|T]) :-
365
- process_one(H),
366
- process_items(T).
367
-
368
- % Using findall
369
- findall(X, some_condition(X), Results)
370
-
371
- % Using maplist
372
- maplist(process_one, Items)
373
- \`\`\`
374
-
375
- ---
376
-
377
- ## Common Patterns
378
-
379
- ### Pattern 1: Simple Task Agent
380
- \`\`\`prolog
381
- agent_main(Topic) :-
382
- system("You are a helpful research assistant."),
383
- task("Research {Topic} and provide a comprehensive summary."),
384
- answer("Research complete!").
385
- \`\`\`
386
-
387
- ### Pattern 2: Multi-Step Workflow
388
- \`\`\`prolog
389
- agent_main(Topic) :-
390
- system("You are a thorough research assistant."),
391
-
392
- output("Step 1: Gathering information..."),
393
- task("Search for recent information about {Topic}. Store findings in Findings.", Findings),
394
-
395
- output("Step 2: Analyzing..."),
396
- task("Analyze these findings: {Findings}. Store your analysis in Analysis.", Analysis),
397
-
398
- output("Step 3: Generating report..."),
399
- task("Create a comprehensive report based on this analysis: {Analysis}"),
400
-
401
- answer("Report generated!").
402
- \`\`\`
403
-
404
- ### Pattern 3: Tool-Enabled Agent
405
- \`\`\`prolog
406
- tool(search(Query, Results), "Search the web") :-
407
- exec(web_search(query: Query), Results).
408
-
409
- agent_main(Topic) :-
410
- system("You are a research assistant with web search. Use the search tool."),
411
- task("Research {Topic} using available tools."),
412
- answer("Research complete!").
413
- \`\`\`
414
-
415
- ### Pattern 3b: Tool with Nested LLM Call
416
- \`\`\`prolog
417
- % A tool that uses LLM to analyze search results
418
- tool(smart_search(Query, Summary), "Search and summarize results") :-
419
- exec(web_search(query: Query), Results),
420
- format(string(Desc), "Summarize these search results: ~w", [Results]),
421
- task(Desc, Summary). % Nested task CANNOT call smart_search (recursion prevention)
422
-
423
- agent_main(Topic) :-
424
- system("Use smart_search to research topics."),
425
- task("Research {Topic}."),
426
- answer("Done!").
427
- \`\`\`
428
-
429
- ### Pattern 4: Code Execution (Use Sparingly!)
430
- \`\`\`prolog
431
- % ONLY use exec/Python when you need:
432
- % - External packages (pandas, numpy, etc.)
433
- % - Shell commands (find, grep, sed, awk, curl)
434
- % - Complex imperative logic that's awkward in Prolog
435
- %
436
- % NOTE: vm_exec returns a dict with stdout, stderr, exitCode - use get_dict to extract
437
- % NOTE: The VM starts in /workspace which is your actual workspace directory
438
-
439
- agent_main(Task) :-
440
- system("You are a coding assistant."),
441
-
442
- task("Write Python code to solve: {Task}. Store only the code in Code.", Code),
443
-
444
- % Write code to a file in the workspace (VM cwd is /workspace)
445
- open('script.py', write, S),
446
- write(S, Code),
447
- close(S),
448
-
449
- output("Executing code..."),
450
- exec(vm_exec(command: "python3 script.py"), Result), % Runs in /workspace
451
- get_dict(stdout, Result, Output),
452
-
453
- task("Explain this execution result: {Output}"),
454
-
455
- answer("Done!").
456
- \`\`\`
457
-
458
- ### Pattern 5: Data Analysis with VM
459
- \`\`\`prolog
460
- % Good use of exec: requires pandas package
461
- % NOTE: vm_exec returns a dict - use get_dict to extract stdout
462
- agent_main(CsvPath, Question) :-
463
- system("You are a data analyst."),
464
-
465
- output("Setting up environment..."),
466
- exec(vm_exec(command: "pip install pandas"), _),
467
-
468
- output("Analyzing data..."),
469
- task("Write Python code to load {CsvPath} with pandas and answer: {Question}. Store only the code in Code.", Code),
470
-
471
- % Write code to file and execute
472
- open('analysis.py', write, S),
473
- write(S, Code),
474
- close(S),
475
- exec(vm_exec(command: "python3 analysis.py"), Result),
476
- get_dict(stdout, Result, Output),
477
-
478
- task("Interpret and explain these analysis results: {Output}"),
479
-
480
- answer("Analysis complete!").
481
- \`\`\`
482
-
483
- ### Pattern 6: File I/O (Use Prolog, NOT Python!)
484
- \`\`\`prolog
485
- % GOOD: Use Prolog's native file I/O
486
- agent_main(Content) :-
487
- task("Generate a report about {Content}. Store in Report.", Report),
488
-
489
- % Write to file using Prolog (not Python!)
490
- open('output.md', write, Stream),
491
- write(Stream, Report),
492
- close(Stream),
493
-
494
- answer("Report saved to output.md").
495
-
496
- % Build filename from parts
497
- agent_main(Name, Content) :-
498
- task("Generate content about {Name}. Store in Text.", Text),
499
-
500
- % Construct filename using atom operations
501
- atom_string(NameAtom, Name),
502
- atom_concat(NameAtom, '_report.md', FilenameAtom),
503
- atom_string(FilenameAtom, Filename),
504
-
505
- open(Filename, write, Stream),
506
- write(Stream, Text),
507
- close(Stream),
508
-
509
- output("Saved to {Filename}"),
510
- answer("Done!").
511
- \`\`\`
512
-
513
- ### Pattern 7: Using format/3 for Complex Strings
514
- \`\`\`prolog
515
- % When you need to build strings with numbers or complex formatting
516
- agent_main(Items) :-
517
- length(Items, Count),
518
- format(string(StatusMsg), "Processing ~d items", [Count]),
519
- output(StatusMsg),
520
-
521
- process_all(Items),
522
-
523
- format(string(DoneMsg), "Completed processing ~d items successfully", [Count]),
524
- answer(DoneMsg).
525
- \`\`\`
526
-
527
- ### Pattern 8: Interactive Agent (User Input)
528
- \`\`\`prolog
529
- % When the task may need user clarification or choices
530
- % Define ask_user wrapper so LLM can interact with user
531
- tool(ask_user(Prompt, Response), "Ask the user a question") :-
532
- exec(ask_user(prompt: Prompt), Result),
533
- get_dict(user_response, Result, Response).
534
-
535
- agent_main(Task) :-
536
- system("You are a helpful assistant. If you need clarification, use the ask_user tool."),
537
-
538
- task("Help the user with: {Task}. If anything is unclear, ask for clarification."),
539
-
540
- answer("Task completed!").
541
- \`\`\`
542
-
543
- ### Pattern 9: Error Handling with catch/throw
544
- \`\`\`prolog
545
- % Safe tool call with error recovery
546
- agent_main(Query) :-
547
- catch(
548
- (
549
- exec(web_search(query: Query), Results),
550
- task("Summarize: {Results}")
551
- ),
552
- Error,
553
- (
554
- format(string(ErrMsg), "Search failed: ~w. Proceeding without search.", [Error]),
555
- output(ErrMsg),
556
- task("Answer based on your knowledge: {Query}")
557
- )
558
- ),
559
- answer("Done!").
560
- \`\`\`
561
-
562
- ### Pattern 10: Fresh Context with prompt()
563
- \`\`\`prolog
564
- % Use prompt() for independent sub-tasks that shouldn't share context
565
- agent_main(Topic) :-
566
- system("You are a research assistant."),
567
-
568
- % Main research with accumulated context
569
- task("Research {Topic} deeply.", MainFindings),
570
-
571
- % Independent critique - fresh context, no bias from main research
572
- prompt("As a skeptical reviewer, critique this research: {MainFindings}. Store critique in Critique.", Critique),
573
-
574
- % Back to main context for final synthesis
575
- task("Address this critique: {Critique}"),
576
-
577
- answer("Research complete with peer review!").
578
- \`\`\`
579
-
580
- ---
581
-
582
- ## When to Use exec() vs Prolog
583
-
584
- ### Use Prolog Native Functionality For:
585
- - **File I/O**: \`open/3\`, \`write/2\`, \`read/2\`, \`close/1\`
586
- - **String manipulation**: \`atom_concat/3\`, \`atom_string/2\`, \`split_string/4\`
587
- - **List operations**: \`append/3\`, \`member/2\`, \`findall/3\`, \`maplist/2\`
588
- - **Arithmetic**: \`is/2\`, comparison operators
589
- - **Logic and control flow**: conjunctions, disjunctions, conditionals
590
-
591
- ### Use exec() ONLY For:
592
- - **External packages**: pandas, numpy, requests, matplotlib, etc.
593
- - **Shell commands**: find, grep, sed, awk, curl, git
594
- - **System operations**: environment variables, process management
595
- - **Complex imperative logic**: loops with side effects, mutable state
596
-
597
- ### BAD Example - Unnecessary Python:
598
- \`\`\`prolog
599
- % DON'T do this - Python for simple file writing
600
- exec(vm_exec(command: "python3 -c \"open('out.txt','w').write('hello')\""), _)
601
- \`\`\`
602
-
603
- ### GOOD Example - Use Prolog:
604
- \`\`\`prolog
605
- % DO this instead - native Prolog file I/O
606
- open('out.txt', write, S),
607
- write(S, Content),
608
- close(S)
609
- \`\`\`
610
-
611
- ---
612
-
613
- ## File Access Patterns with vm_exec
614
-
615
- When \`vm_exec\` is backed by AgentVM, it runs in a sandboxed Alpine Linux environment using **BusyBox** (not GNU coreutils), and the workspace is mounted at \`/workspace\`. When the runtime uses the local workspace shell instead, standard local tooling and paths apply. Prefer relative paths when possible.
616
-
617
- **Important:** \`vm_exec\` returns a dict - always extract stdout:
618
- \`\`\`prolog
619
- exec(vm_exec(command: "ls /workspace"), Result),
620
- get_dict(stdout, Result, Output).
621
- \`\`\`
622
-
623
- ### Common File Operations
624
-
625
- | Operation | Command | Example |
626
- |-----------|---------|---------|
627
- | List files | \`ls {dir}\` | \`ls /workspace/src\` |
628
- | Find by name | \`find {dir} -name '{pattern}' -type f\` | \`find /workspace -name '*.ts' -type f\` |
629
- | Find shallow | \`find {dir} -maxdepth 1 -name '{pattern}'\` | \`find /workspace/src -maxdepth 1 -name '*.ts'\` |
630
- | Read file | \`cat {path}\` | \`cat /workspace/README.md\` |
631
- | Read first N lines | \`head -{n} {path}\` | \`head -10 /workspace/file.ts\` |
632
- | Read last N lines | \`tail -{n} {path}\` | \`tail -5 /workspace/file.ts\` |
633
- | Read line range | \`sed -n '{start},{end}p' {path}\` | \`sed -n '1,10p' /workspace/file.ts\` |
634
- | Grep in file | \`grep '{pattern}' {path}\` | \`grep 'import' /workspace/file.ts\` |
635
- | Grep with line nums | \`grep -n '{pattern}' {path}\` | \`grep -n 'export' /workspace/file.ts\` |
636
- | Grep recursive | \`grep -rn '{pattern}' {dir}\` | \`grep -rn 'TODO' /workspace/src\` |
637
- | File exists | \`test -f {path} && echo yes\` | \`test -f /workspace/file.ts && echo yes\` |
638
- | Dir exists | \`test -d {path} && echo yes\` | \`test -d /workspace/src && echo yes\` |
639
- | File size | \`stat -c %s {path}\` | \`stat -c %s /workspace/file.ts\` |
640
- | Line count | \`wc -l < {path}\` | \`wc -l < /workspace/file.ts\` |
641
- | Count files | \`find ... \\| wc -l\` | \`find /workspace -name '*.ts' \\| wc -l\` |
642
- | Basename | \`basename {path}\` | \`basename /workspace/src/file.ts\` |
643
- | Dirname | \`dirname {path}\` | \`dirname /workspace/src/file.ts\` |
644
-
645
- ### DML File Access Patterns
646
-
647
- #### List Directory
648
- \`\`\`prolog
649
- list_files(Dir, Files) :-
650
- format(string(Cmd), "ls ~w", [Dir]),
651
- exec(vm_exec(command: Cmd), Result),
652
- get_dict(stdout, Result, Output),
653
- split_string(Output, "\\n", "\\s\\t\\r\\n", Files).
654
- \`\`\`
655
-
656
- #### Find Files by Pattern
657
- \`\`\`prolog
658
- find_files(Dir, Pattern, Files) :-
659
- format(string(Cmd), "find ~w -name '~w' -type f", [Dir, Pattern]),
660
- exec(vm_exec(command: Cmd), Result),
661
- get_dict(stdout, Result, Output),
662
- split_string(Output, "\\n", "\\s\\t\\r\\n", Files).
663
- \`\`\`
664
-
665
- #### Read File
666
- \`\`\`prolog
667
- read_file(Path, Content) :-
668
- format(string(Cmd), "cat ~w", [Path]),
669
- exec(vm_exec(command: Cmd), Result),
670
- get_dict(stdout, Result, Content).
671
- \`\`\`
672
-
673
- #### Read First N Lines
674
- \`\`\`prolog
675
- read_head(Path, N, Content) :-
676
- format(string(Cmd), "head -~d ~w", [N, Path]),
677
- exec(vm_exec(command: Cmd), Result),
678
- get_dict(stdout, Result, Content).
679
- \`\`\`
680
-
681
- #### Read Line Range
682
- \`\`\`prolog
683
- read_lines(Path, Start, End, Content) :-
684
- format(string(Cmd), "sed -n '~d,~dp' ~w", [Start, End, Path]),
685
- exec(vm_exec(command: Cmd), Result),
686
- get_dict(stdout, Result, Content).
687
- \`\`\`
688
-
689
- #### Grep in File
690
- \`\`\`prolog
691
- grep(Path, Pattern, Matches) :-
692
- format(string(Cmd), "grep -n '~w' ~w || true", [Pattern, Path]),
693
- exec(vm_exec(command: Cmd), Result),
694
- get_dict(stdout, Result, Matches).
695
- \`\`\`
696
-
697
- #### Recursive Grep
698
- \`\`\`prolog
699
- grep_recursive(Dir, Pattern, Matches) :-
700
- format(string(Cmd), "grep -rn '~w' ~w || true", [Pattern, Dir]),
701
- exec(vm_exec(command: Cmd), Result),
702
- get_dict(stdout, Result, Matches).
703
- \`\`\`
704
-
705
- #### File Exists Check
706
- \`\`\`prolog
707
- file_exists(Path) :-
708
- format(string(Cmd), "test -f ~w && echo yes || echo no", [Path]),
709
- exec(vm_exec(command: Cmd), Result),
710
- get_dict(stdout, Result, "yes").
711
- \`\`\`
712
-
713
- #### Line Count
714
- \`\`\`prolog
715
- line_count(Path, Count) :-
716
- format(string(Cmd), "wc -l < ~w", [Path]),
717
- exec(vm_exec(command: Cmd), Result),
718
- get_dict(stdout, Result, Output),
719
- normalize_space(atom(CountAtom), Output),
720
- atom_number(CountAtom, Count).
721
- \`\`\`
722
-
723
- ### BusyBox Limitations (AgentVM Sandbox)
724
-
725
- When AgentVM sandboxing is enabled, BusyBox in Alpine Linux has limited options compared to GNU coreutils:
726
- - \`grep --include\` is NOT supported - use \`find ... -exec grep\` instead
727
- - Some \`find\` options may differ
728
- - Use \`|| true\` with grep to prevent failures when no matches found
729
-
730
- ---
731
-
732
- ## Conversion Guidelines
733
-
734
- 1. **Identify the core task** - What is the primary goal?
735
- 2. **Determine parameters** - What inputs does the agent need?
736
- 3. **Map to patterns** - Which DML pattern best fits?
737
- 4. **Prefer Prolog native operations** - Use Prolog for file I/O, strings, lists
738
- 5. **Use exec() sparingly** - Only for packages, shell commands, imperative logic
739
- 6. **Define required tools** - What external capabilities are needed?
740
- 7. **Handle edge cases** - Add fallbacks and error handling
741
- 8. **Add progress output** - Keep users informed with \`output/1\`
742
- 9. **Add ask_user wrapper** - If the task might need user input, clarification, or choices
743
-
744
- ## CRITICAL: Tools are LLM-Only
745
-
746
- **Tools defined with \`tool/3\` can ONLY be called by the LLM during \`task()\` execution.**
747
-
748
- - \`tool/3\` defines capabilities for the LLM to use
749
- - DML code CANNOT call tools directly as predicates
750
- - If DML code needs external functionality, use \`exec()\` directly
751
-
752
- \`\`\`prolog
753
- % WRONG - cannot call tool from DML code
754
- agent_main :-
755
- my_search("query", Results). % ERROR!
756
-
757
- % CORRECT - use exec() for direct access
758
- agent_main :-
759
- exec(web_search(query: "query"), Results).
760
-
761
- % CORRECT - let LLM use the tool via task()
762
- agent_main :-
763
- task("Search for information about X.", Summary).
764
- \`\`\`
765
-
766
- ## CRITICAL: String Handling Rules
767
-
768
- **NEVER do any of these:**
769
- - \`output(format(...))\` - format/3 doesn't return a value, it binds to first arg
770
- - \`answer(format(...))\` - same issue
771
- - Mixing \`{Var}\` and \`~w\` in the same string
772
- - Using \`{Var}\` inside format/3 format strings
773
-
774
- **DO this instead:**
775
- - Use \`{Variable}\` interpolation directly: \`output("Processing {Item}")\`
776
- - Or use format/3 properly: \`format(string(Msg), "Count: ~d", [N]), output(Msg)\`
777
-
778
- ## CRITICAL: Prolog vs exec() Rules
779
-
780
- **Use Prolog for:**
781
- - File I/O: \`open/3\`, \`write/2\`, \`close/1\`
782
- - String building: \`atom_concat/3\`, \`atom_string/2\`
783
- - All standard logic and data manipulation
784
-
785
- **Use exec() ONLY for:**
786
- - External packages (pandas, numpy)
787
- - Shell commands (grep, curl, find)
788
- - Complex imperative tasks
789
-
790
- ## Output Requirements
791
-
792
- Your DML output must:
793
-
794
- 1. Start with a comment header describing the program
795
- 2. Define any tool wrappers needed with \`tool/3\`
796
- 3. **If the task may need user input, define an \`ask_user\` tool wrapper**
797
- 4. Have a single \`agent_main\` entry point
798
- 5. Use appropriate system prompts
799
- 6. Include progress outputs for long-running tasks
800
- 7. End with \`answer/1\` to signal completion
801
- 8. Handle stated edge cases
802
- 9. **Only use tools from the Available External Tools list**
803
- 10. **Use ONLY {Variable} interpolation OR format/3, never mix them**
804
- 11. **NEVER pass format(...) directly to output/1 or answer/1**
805
- 12. **Use Prolog native file I/O, NOT Python exec() for simple file operations**
806
-
807
- Output ONLY the DML code, no explanations or markdown code fences.
808
- `;
809
- // =============================================================================
810
- // Tool Table Building
811
- // =============================================================================
812
- /**
813
- * Build the tools table for the prompt
814
- */
815
- export function buildToolsTable(tools) {
816
- if (tools.length === 0) {
817
- return 'No additional tools configured.';
818
- }
819
- const lines = [];
820
- // Group by provider
821
- const byProvider = new Map();
822
- for (const tool of tools) {
823
- const existing = byProvider.get(tool.provider) || [];
824
- existing.push(tool);
825
- byProvider.set(tool.provider, existing);
826
- }
827
- for (const [provider, providerTools] of byProvider) {
828
- const isBuiltIn = provider === 'agentvm';
829
- lines.push(`### ${isBuiltIn ? 'Built-in Runtime Tools' : `${provider} (MCP)`}`);
830
- lines.push('');
831
- lines.push('| Tool | Description |');
832
- lines.push('|------|-------------|');
833
- for (const tool of providerTools) {
834
- // Format tool signature
835
- let signature = tool.name;
836
- if (tool.schema && typeof tool.schema === 'object') {
837
- const schema = tool.schema;
838
- if (schema.properties) {
839
- const params = Object.keys(schema.properties).join(', ');
840
- signature = `${tool.name}(${params})`;
841
- }
842
- }
843
- lines.push(`| \`${signature}\` | ${tool.description} |`);
844
- }
845
- lines.push('');
846
- }
847
- return lines.join('\n');
848
- }
849
- /**
850
- * Build the complete compilation prompt with tools injected
851
- */
852
- export function buildCompilationPrompt(tools) {
853
- const toolsTable = buildToolsTable(tools);
854
- return DML_CONVERSION_PROMPT.replace('{TOOLS_TABLE}', toolsTable);
855
- }
856
- /**
857
- * Build the user message containing the markdown to convert
858
- */
859
- export function buildUserMessage(markdown) {
860
- return `Convert the following Markdown task description into a DML program:
861
-
862
- ---
863
-
864
- ${markdown}
865
-
866
- ---
867
-
868
- Output only valid DML code.`;
869
- }
870
- //# sourceMappingURL=compiler_prompt.js.map