deepclause-sdk 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.d.ts +12 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +116 -9
- package/dist/agent.js.map +1 -1
- package/dist/cli/config.d.ts +24 -24
- package/dist/cli/repl.d.ts +21 -4
- package/dist/cli/repl.d.ts.map +1 -1
- package/dist/cli/repl.js +293 -44
- package/dist/cli/repl.js.map +1 -1
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +10 -0
- package/dist/cli/run.js.map +1 -1
- package/dist/prolog/loader.d.ts +32 -0
- package/dist/prolog/loader.d.ts.map +1 -1
- package/dist/prolog/loader.js +87 -0
- package/dist/prolog/loader.js.map +1 -1
- package/dist/prolog-src/deepclause_mi.pl +1028 -118
- package/dist/repl/agent.d.ts +15 -1
- package/dist/repl/agent.d.ts.map +1 -1
- package/dist/repl/agent.js +44 -5
- package/dist/repl/agent.js.map +1 -1
- package/dist/repl/backend.d.ts.map +1 -1
- package/dist/repl/backend.js +18 -5
- package/dist/repl/backend.js.map +1 -1
- package/dist/repl/harness-tools.d.ts +24 -2
- package/dist/repl/harness-tools.d.ts.map +1 -1
- package/dist/repl/harness-tools.js +14 -5
- package/dist/repl/harness-tools.js.map +1 -1
- package/dist/repl/index.d.ts +8 -0
- package/dist/repl/index.d.ts.map +1 -1
- package/dist/repl/index.js +1 -0
- package/dist/repl/index.js.map +1 -1
- package/dist/repl/render.d.ts +60 -3
- package/dist/repl/render.d.ts.map +1 -1
- package/dist/repl/render.js +114 -28
- package/dist/repl/render.js.map +1 -1
- package/dist/repl/session.d.ts +61 -4
- package/dist/repl/session.d.ts.map +1 -1
- package/dist/repl/session.js +174 -9
- package/dist/repl/session.js.map +1 -1
- package/dist/repl/status.d.ts +3 -1
- package/dist/repl/status.d.ts.map +1 -1
- package/dist/repl/status.js +4 -0
- package/dist/repl/status.js.map +1 -1
- package/dist/repl/tool-arguments.d.ts +36 -0
- package/dist/repl/tool-arguments.d.ts.map +1 -0
- package/dist/repl/tool-arguments.js +123 -0
- package/dist/repl/tool-arguments.js.map +1 -0
- package/dist/repl/toolset.d.ts +28 -1
- package/dist/repl/toolset.d.ts.map +1 -1
- package/dist/repl/toolset.js +52 -4
- package/dist/repl/toolset.js.map +1 -1
- package/dist/repl/tui/autocomplete.d.ts +19 -0
- package/dist/repl/tui/autocomplete.d.ts.map +1 -0
- package/dist/repl/tui/autocomplete.js +41 -0
- package/dist/repl/tui/autocomplete.js.map +1 -0
- package/dist/repl/tui/document.d.ts +51 -0
- package/dist/repl/tui/document.d.ts.map +1 -0
- package/dist/repl/tui/document.js +160 -0
- package/dist/repl/tui/document.js.map +1 -0
- package/dist/repl/tui/picker.d.ts +31 -0
- package/dist/repl/tui/picker.d.ts.map +1 -0
- package/dist/repl/tui/picker.js +43 -0
- package/dist/repl/tui/picker.js.map +1 -0
- package/dist/repl/tui/renderer.d.ts +98 -0
- package/dist/repl/tui/renderer.d.ts.map +1 -0
- package/dist/repl/tui/renderer.js +284 -0
- package/dist/repl/tui/renderer.js.map +1 -0
- package/dist/repl/tui/status-bar.d.ts +4 -2
- package/dist/repl/tui/status-bar.d.ts.map +1 -1
- package/dist/repl/tui/status-bar.js +80 -24
- package/dist/repl/tui/status-bar.js.map +1 -1
- package/dist/repl/tui/terminal.d.ts +28 -0
- package/dist/repl/tui/terminal.d.ts.map +1 -0
- package/dist/repl/tui/terminal.js +94 -0
- package/dist/repl/tui/terminal.js.map +1 -0
- package/dist/repl/tui/theme.d.ts +60 -0
- package/dist/repl/tui/theme.d.ts.map +1 -1
- package/dist/repl/tui/theme.js +142 -0
- package/dist/repl/tui/theme.js.map +1 -1
- package/dist/repl/tui/tool-pane.d.ts +68 -0
- package/dist/repl/tui/tool-pane.d.ts.map +1 -0
- package/dist/repl/tui/tool-pane.js +257 -0
- package/dist/repl/tui/tool-pane.js.map +1 -0
- package/dist/repl/tui/working-line.d.ts +23 -0
- package/dist/repl/tui/working-line.d.ts.map +1 -0
- package/dist/repl/tui/working-line.js +58 -0
- package/dist/repl/tui/working-line.js.map +1 -0
- package/dist/runner.d.ts +31 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +192 -17
- package/dist/runner.js.map +1 -1
- package/dist/system/assets/docs/AGENT_PROMPT.md +925 -43
- package/dist/system/assets/docs/DML_AUTHORING.md +96 -17
- package/dist/system/assets/docs/DML_REFERENCE.md +620 -39
- package/dist/system/assets/docs/PROLOG_SNIPPETS.md +45 -1
- package/dist/system/assets/docs/TASK_PROMPT.md +2 -0
- package/dist/system/environment.d.ts +36 -0
- package/dist/system/environment.d.ts.map +1 -0
- package/dist/system/environment.js +81 -0
- package/dist/system/environment.js.map +1 -0
- package/dist/system/runtime/shell-manager.d.ts +40 -2
- package/dist/system/runtime/shell-manager.d.ts.map +1 -1
- package/dist/system/runtime/shell-manager.js +82 -16
- package/dist/system/runtime/shell-manager.js.map +1 -1
- package/dist/system/runtime/shell-tool-events.js +25 -1
- package/dist/system/runtime/shell-tool-events.js.map +1 -1
- package/dist/types.d.ts +27 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/prolog-src/deepclause_mi.pl +1028 -118
- package/dist/compaction.d.ts +0 -98
- package/dist/compaction.d.ts.map +0 -1
- package/dist/compaction.js +0 -471
- package/dist/compaction.js.map +0 -1
- package/dist/repl/tools.d.ts +0 -53
- package/dist/repl/tools.d.ts.map +0 -1
- package/dist/repl/tools.js +0 -307
- package/dist/repl/tools.js.map +0 -1
- package/dist/system/assets/compactors/default-loop-compactor.dml +0 -43
- package/dist/system/assets/compactors/default-session-compactor.dml +0 -30
- package/dist/system/assets/docs/META_PROMPT.md +0 -68
|
@@ -41,6 +41,63 @@ plausibly reuse the predicate with different arguments; if only this request
|
|
|
41
41
|
would, do not add it. A harness of many task-shaped helpers is as bad as one
|
|
42
42
|
hard-coded script.
|
|
43
43
|
|
|
44
|
+
**Declare the shape of structured model output.** `list(object(B))` does not say
|
|
45
|
+
what is in the dicts, so every consumer re-derives defaults and tolerates missing
|
|
46
|
+
fields by hand. `schema(Name, [field(Field, Type, Option)])` is checked when the
|
|
47
|
+
result binds: defaults filled, a missing `required` field or a wrong type reported
|
|
48
|
+
against the field name, an undeclared field kept so a mistake stays visible. Name it
|
|
49
|
+
in the output — `task(…, list(schema(author, Authors)))` — or apply it by hand with
|
|
50
|
+
`schema_fill(author, Raw, Author)`.
|
|
51
|
+
|
|
52
|
+
**Know which conversation the model sees.** `task/N` is sent the memory built so
|
|
53
|
+
far and writes its reply back, so consecutive `task/N` calls accumulate history —
|
|
54
|
+
pass values as explicit arguments instead of relying on the model to remember them.
|
|
55
|
+
`prompt/N` is fresh (no memory, no tools) and is the right choice for a classifier,
|
|
56
|
+
extractor, or transformation that must not be swayed by the conversation;
|
|
57
|
+
`with_fresh_memory(Goal)` does the same for a group of steps, and restores the
|
|
58
|
+
caller's memory on exit. A `task/N` inside a `tool/2` body starts empty: give it the
|
|
59
|
+
context as an argument.
|
|
60
|
+
|
|
61
|
+
**Start small, then improve.** Write the smallest harness that answers the actual
|
|
62
|
+
request end to end — often a single predicate — run it on a real input, and show
|
|
63
|
+
the user the result *before* extending it. Say what it does, what it does not do
|
|
64
|
+
yet, and what you would add next, then let the next request decide. A harness grows
|
|
65
|
+
in the direction the user actually takes it.
|
|
66
|
+
|
|
67
|
+
Adding capability speculatively is the expensive mistake, and it costs more here
|
|
68
|
+
than in a normal codebase: every predicate is part of the harness the next turn has
|
|
69
|
+
to reason about, and every helper is one more thing the model can be offered as a
|
|
70
|
+
tool. Do not write an error taxonomy before an error has occurred, retry and
|
|
71
|
+
fallback policies before something has failed, caching or configuration layers
|
|
72
|
+
before there is a reason, or a predicate per case for cases you have not seen.
|
|
73
|
+
Prefer the smallest change that makes the failing input work.
|
|
74
|
+
|
|
75
|
+
Signs you are overengineering:
|
|
76
|
+
|
|
77
|
+
- a predicate with one caller whose arguments are all literals from the request;
|
|
78
|
+
- an abstraction (a schema, an options list, a dispatch table) built for a single
|
|
79
|
+
shape or a single value;
|
|
80
|
+
- a helper "framework" written before the first end-to-end run;
|
|
81
|
+
- generalizing across cases that no one has asked for yet;
|
|
82
|
+
- a harness that does not run yet, because the parts are still being made tidy.
|
|
83
|
+
|
|
84
|
+
A small change is also easier to trust: each commit is one reviewable unit, the
|
|
85
|
+
`end_turn` probes report on a small surface, and `rollback` stays cheap. A harness
|
|
86
|
+
that is incomplete but working is a better answer than one that is complete and
|
|
87
|
+
unverified.
|
|
88
|
+
|
|
89
|
+
**Do not parse in DML — shell out or ask the model.** Prolog string handling is
|
|
90
|
+
the fiddliest thing here, and a hand-rolled parser (`sub_string/5`,
|
|
91
|
+
`split_string/4`, `atom_concat/3`, `format/2`, an accumulator) is the easiest way
|
|
92
|
+
to write DML that looks right and is quietly wrong. Split the work by what it is.
|
|
93
|
+
Mechanical work — pull a field, change a format, count, filter — belongs in a
|
|
94
|
+
**helper script** (`script_file/2` + `exec(bash(argv: [...]))`), which is testable
|
|
95
|
+
outside DML and written in a language made for text; have it emit **JSON** and read
|
|
96
|
+
it with `json_get/3`/`json_gets/3`/`json_text/2` instead of splitting stdout.
|
|
97
|
+
Work that needs *understanding* — find the field named X, classify, summarise —
|
|
98
|
+
belongs in a **model call** with a typed output (`task("…", list(string(Items)))`,
|
|
99
|
+
`schema/2`, `choose`/`rate`/`verify`). DML sequences and checks; it does not parse.
|
|
100
|
+
|
|
44
101
|
**Prefer orchestration over algorithms.** A skill should read as a short
|
|
45
102
|
sequence of steps. Describe each step with `task/N` (which sees the conversation
|
|
46
103
|
memory) or `prompt/N` (fresh context) and let the model extract, classify,
|
|
@@ -131,6 +188,12 @@ doc(tally/2, "Count occurrences of each item. tally(+List, -Counts) yields Key-N
|
|
|
131
188
|
same predicate is callable from `execute` / `/goal` **and** from `task/N`. Logic
|
|
132
189
|
placed only inside `tool/2` is unreachable from `execute` (the loader asserts
|
|
133
190
|
`tool(Head)`, never `Head`).
|
|
191
|
+
- Annotate **capabilities** (file I/O, search, a script) that a nested agent
|
|
192
|
+
should use — not the LLM steps themselves. A `tool/2` whose implementation
|
|
193
|
+
calls `task/N` and advertises the same job is offered to the agent inside that
|
|
194
|
+
`task/N`, which then calls it. Absent the tool call stack, wrapper predicates
|
|
195
|
+
are the same job twice; keep the step a skill, or scope the task with
|
|
196
|
+
`without_tools([Head], task(…))`.
|
|
134
197
|
- `doc(Name/Arity, Text)` — one fact per skill, helper, or tool; terse, with
|
|
135
198
|
arguments (`+in` / `-out`) and an example goal.
|
|
136
199
|
|
|
@@ -159,24 +222,33 @@ text-only — never attach media to them.
|
|
|
159
222
|
## 6. Guard rails
|
|
160
223
|
|
|
161
224
|
- Read first: call `listing`.
|
|
162
|
-
- **Paths
|
|
163
|
-
`/workspace
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
225
|
+
- **Paths: use `/workspace/...`.** The workspace is the working directory, so
|
|
226
|
+
`out/report.txt` and `/workspace/out/report.txt` are the same file — but write
|
|
227
|
+
the `/workspace` form, because it means the same thing from DML, from
|
|
228
|
+
`exec(bash(...))`, and from the shell tool on every backend. Everything outside
|
|
229
|
+
`/workspace` is the session's ephemeral VM filesystem: fine for scratch, never
|
|
230
|
+
for a result, because **only files under `/workspace` reach the host**. Scratch
|
|
231
|
+
goes in `$TMPDIR` (per-session in every backend), not a bare `/tmp`.
|
|
232
|
+
`directory_files/2` returns **bare names**, so build one
|
|
233
|
+
(`atom_concat('images/', Name, Path)`). Prefer `bash`/host file tools for file
|
|
234
|
+
operations; use the DML file predicates only for content you must reason over
|
|
235
|
+
in Prolog.
|
|
170
236
|
- **Side-effecting skills must be deterministic.** Any skill that calls
|
|
171
237
|
`task/N`, `prompt/N`, `exec/2`, `read_media/2`, `attach_media/1`, or writes a
|
|
172
238
|
file must yield exactly one solution with no choicepoint left across the side
|
|
173
239
|
effect (`once/1`, `->`, or a cut). Otherwise backtracking re-runs the model
|
|
174
240
|
call: slow, costly, and a different answer each time.
|
|
175
|
-
- Replace a predicate with `define(head, clauses)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
-
|
|
179
|
-
|
|
241
|
+
- Replace a predicate with `define(head, clauses)`, where the head names the
|
|
242
|
+
predicate being replaced and must be one of the predicates the block defines.
|
|
243
|
+
Never patch it clause by clause.
|
|
244
|
+
- `assert`/`assert_many` are for a **new** predicate: they append, so against an
|
|
245
|
+
existing one both versions would stay live with their clauses interleaved, and
|
|
246
|
+
the runtime refuses the call rather than let that happen.
|
|
247
|
+
- `retract` removes the clauses matching its pattern and says how many; `delete`
|
|
248
|
+
removes a whole predicate. `retract` fails when nothing matched — check that
|
|
249
|
+
the pattern is the one you meant.
|
|
250
|
+
- Clause order matters: base case before a recursive rule; give a whole predicate
|
|
251
|
+
to `define`/`assert_many` at once (clauses in the order written).
|
|
180
252
|
- Verify after changing a predicate: `listing(Name/Arity)`.
|
|
181
253
|
- Bounded iteration only: finite recursion or an explicit bound. `execute` is
|
|
182
254
|
gas-limited and the turn has a model-call budget, but a single builtin call
|
|
@@ -185,10 +257,17 @@ text-only — never attach media to them.
|
|
|
185
257
|
domain (`X ins 0..N`) before `label/1`, prefer `once/1`, and keep the model
|
|
186
258
|
small: an under-specified or unsatisfiable model searches forever, and there
|
|
187
259
|
is no per-goal timeout. Never reach for CLP as a shortcut for arithmetic.
|
|
188
|
-
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
260
|
+
- **Know whether you are sandboxed.** The session's environment block says which
|
|
261
|
+
backend is in effect. With a sandbox (`bwrap`, AgentVM, `sandbox-exec`),
|
|
262
|
+
`bash` is isolated and writes outside the workspace are confined. With
|
|
263
|
+
`clean-room` there is **no** sandbox: commands run as the user, writes outside
|
|
264
|
+
the workspace are real files that persist, and a `rm` is a real `rm`. Explore
|
|
265
|
+
what is available (`python3 --version`, `pip list`, `which jq`) and install a
|
|
266
|
+
dependency when a skill genuinely needs one; installs are sandbox/session-local
|
|
267
|
+
and do not travel with an exported harness, so prefer the standard library.
|
|
268
|
+
- If a harness genuinely requires isolation, the **user** can add
|
|
269
|
+
`:- require_sandbox.` (through `/set-require-sandbox`). It makes the load fail
|
|
270
|
+
rather than run unsandboxed. Do not add it yourself.
|
|
192
271
|
- Do **not** use `agent_main` unless the user asks for a `deepclause run` /
|
|
193
272
|
`/dc-run` skill.
|
|
194
273
|
- Media: reference images with `media(Path, Mime)` (`read_media/2` +
|