deepclause-sdk 0.0.1
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/README.md +446 -0
- package/dist/agent.d.ts +44 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +518 -0
- package/dist/agent.js.map +1 -0
- package/dist/cli/commands.d.ts +37 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +105 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/compile.d.ts +88 -0
- package/dist/cli/compile.d.ts.map +1 -0
- package/dist/cli/compile.js +362 -0
- package/dist/cli/compile.js.map +1 -0
- package/dist/cli/config.d.ts +265 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +272 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +287 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/mcp.d.ts +56 -0
- package/dist/cli/mcp.d.ts.map +1 -0
- package/dist/cli/mcp.js +138 -0
- package/dist/cli/mcp.js.map +1 -0
- package/dist/cli/prompt.d.ts +20 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +669 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/run.d.ts +33 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +429 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/search.d.ts +25 -0
- package/dist/cli/search.d.ts.map +1 -0
- package/dist/cli/search.js +125 -0
- package/dist/cli/search.js.map +1 -0
- package/dist/cli/tools.d.ts +36 -0
- package/dist/cli/tools.d.ts.map +1 -0
- package/dist/cli/tools.js +204 -0
- package/dist/cli/tools.js.map +1 -0
- package/dist/cli/tui/index.d.ts +22 -0
- package/dist/cli/tui/index.d.ts.map +1 -0
- package/dist/cli/tui/index.js +29 -0
- package/dist/cli/tui/index.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/prolog/bridge.d.ts +21 -0
- package/dist/prolog/bridge.d.ts.map +1 -0
- package/dist/prolog/bridge.js +226 -0
- package/dist/prolog/bridge.js.map +1 -0
- package/dist/prolog/loader.d.ts +40 -0
- package/dist/prolog/loader.d.ts.map +1 -0
- package/dist/prolog/loader.js +133 -0
- package/dist/prolog/loader.js.map +1 -0
- package/dist/prolog-src/deepclause_memory.pl +45 -0
- package/dist/prolog-src/deepclause_mi.pl +1978 -0
- package/dist/prolog-src/deepclause_mi.pl.bak +570 -0
- package/dist/prolog-src/deepclause_strings.pl +89 -0
- package/dist/runner.d.ts +143 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +1095 -0
- package/dist/runner.js.map +1 -0
- package/dist/sdk.d.ts +9 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +131 -0
- package/dist/sdk.js.map +1 -0
- package/dist/tools.d.ts +22 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +138 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +186 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +79 -0
- package/src/prolog-src/deepclause_memory.pl +45 -0
- package/src/prolog-src/deepclause_mi.pl +1978 -0
- package/src/prolog-src/deepclause_mi.pl.bak +570 -0
- package/src/prolog-src/deepclause_strings.pl +89 -0
- package/vendor/swipl-wasm/LICENSE.txt +41 -0
- package/vendor/swipl-wasm/dist/bin/index.js +25 -0
- package/vendor/swipl-wasm/dist/common.d.ts +88 -0
- package/vendor/swipl-wasm/dist/generateImage.d.ts +6 -0
- package/vendor/swipl-wasm/dist/generateImage.js +76 -0
- package/vendor/swipl-wasm/dist/index.d.ts +2 -0
- package/vendor/swipl-wasm/dist/index.js +1 -0
- package/vendor/swipl-wasm/dist/loadImage.d.ts +2 -0
- package/vendor/swipl-wasm/dist/loadImage.js +10 -0
- package/vendor/swipl-wasm/dist/loadImageDefault.d.ts +2 -0
- package/vendor/swipl-wasm/dist/loadImageDefault.js +11 -0
- package/vendor/swipl-wasm/dist/strToBuffer.d.ts +8 -0
- package/vendor/swipl-wasm/dist/strToBuffer.js +41 -0
- package/vendor/swipl-wasm/dist/swipl/swipl-bundle-no-data.d.ts +2 -0
- package/vendor/swipl-wasm/dist/swipl/swipl-bundle-no-data.js +2 -0
- package/vendor/swipl-wasm/dist/swipl/swipl-bundle.d.ts +2 -0
- package/vendor/swipl-wasm/dist/swipl/swipl-bundle.js +2 -0
- package/vendor/swipl-wasm/dist/swipl/swipl-web.d.ts +2 -0
- package/vendor/swipl-wasm/dist/swipl/swipl-web.data +0 -0
- package/vendor/swipl-wasm/dist/swipl/swipl-web.js +2 -0
- package/vendor/swipl-wasm/dist/swipl/swipl-web.wasm +0 -0
- package/vendor/swipl-wasm/dist/swipl/swipl-win.js +1 -0
- package/vendor/swipl-wasm/dist/swipl/swipl-win.wasm +0 -0
- package/vendor/swipl-wasm/dist/swipl/swipl.d.ts +2 -0
- package/vendor/swipl-wasm/dist/swipl/swipl.js +1 -0
- package/vendor/swipl-wasm/dist/swipl/swipl.wasm +0 -0
- package/vendor/swipl-wasm/dist/swipl-node.d.ts +2 -0
- package/vendor/swipl-wasm/dist/swipl-node.js +17 -0
- package/vendor/swipl-wasm/package.json +129 -0
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deepclause_mi.pl - Meta-interpreter for DeepClause SDK
|
|
3
|
+
*
|
|
4
|
+
* The simplified meta-interpreter that handles:
|
|
5
|
+
* - task/1 and task/N predicates (agent loops)
|
|
6
|
+
* - exec/2 predicate (external tool calls)
|
|
7
|
+
* - Memory predicates (system, user, push_context, pop_context)
|
|
8
|
+
* - Output predicates (answer, yield, log)
|
|
9
|
+
* - Parameter handling
|
|
10
|
+
*
|
|
11
|
+
* Key design decisions:
|
|
12
|
+
* - No @-predicates - all LLM interaction via task()
|
|
13
|
+
* - Cooperative execution via engine yields
|
|
14
|
+
* - Backtrackable memory via push_context/pop_context
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
:- module(deepclause_mi, [
|
|
18
|
+
parse_dml/4,
|
|
19
|
+
create_engine/4,
|
|
20
|
+
step_engine/4,
|
|
21
|
+
destroy_engine/1,
|
|
22
|
+
post_agent_result/3,
|
|
23
|
+
post_exec_result/3,
|
|
24
|
+
provide_input/2,
|
|
25
|
+
mi/4
|
|
26
|
+
]).
|
|
27
|
+
|
|
28
|
+
:- use_module(deepclause_memory).
|
|
29
|
+
:- use_module(deepclause_strings).
|
|
30
|
+
|
|
31
|
+
%% Dynamic predicates for session state
|
|
32
|
+
:- dynamic session_engine/2. % session_engine(SessionId, Engine)
|
|
33
|
+
:- dynamic session_memory/2. % session_memory(SessionId, MemoryId)
|
|
34
|
+
:- dynamic session_params/2. % session_params(SessionId, ParamsDict)
|
|
35
|
+
:- dynamic session_user_tools/2. % session_user_tools(SessionId, ToolName)
|
|
36
|
+
:- dynamic session_user_tool_schema/3. % session_user_tool_schema(SessionId, ToolName, Schema)
|
|
37
|
+
:- dynamic session_pending_input/2. % session_pending_input(SessionId, Input)
|
|
38
|
+
:- dynamic session_agent_result/2. % session_agent_result(SessionId, Result)
|
|
39
|
+
:- dynamic session_exec_result/2. % session_exec_result(SessionId, Result)
|
|
40
|
+
|
|
41
|
+
%% ============================================================
|
|
42
|
+
%% DML Parsing
|
|
43
|
+
%% ============================================================
|
|
44
|
+
|
|
45
|
+
%% parse_dml(+FilePath, +SessionId, +MemoryId, -Error)
|
|
46
|
+
%% Parse a DML file and load its clauses into the session module
|
|
47
|
+
parse_dml(FilePath, SessionId, MemoryId, Error) :-
|
|
48
|
+
catch(
|
|
49
|
+
(
|
|
50
|
+
read_file_to_string(FilePath, Code, []),
|
|
51
|
+
parse_dml_string(Code, SessionId, MemoryId),
|
|
52
|
+
Error = none
|
|
53
|
+
),
|
|
54
|
+
ParseError,
|
|
55
|
+
format(atom(Error), '~w', [ParseError])
|
|
56
|
+
).
|
|
57
|
+
|
|
58
|
+
%% parse_dml_string(+Code, +SessionId, +MemoryId)
|
|
59
|
+
%% Parse DML code from a string
|
|
60
|
+
parse_dml_string(Code, SessionId, MemoryId) :-
|
|
61
|
+
open_string(Code, Stream),
|
|
62
|
+
parse_clauses(Stream, SessionId, MemoryId),
|
|
63
|
+
close(Stream).
|
|
64
|
+
|
|
65
|
+
%% parse_clauses(+Stream, +SessionId, +MemoryId)
|
|
66
|
+
%% Read and process all clauses from a stream
|
|
67
|
+
parse_clauses(Stream, SessionId, MemoryId) :-
|
|
68
|
+
read_term(Stream, Term, [module(SessionId)]),
|
|
69
|
+
( Term == end_of_file
|
|
70
|
+
-> true
|
|
71
|
+
; process_clause(Term, SessionId, MemoryId),
|
|
72
|
+
parse_clauses(Stream, SessionId, MemoryId)
|
|
73
|
+
).
|
|
74
|
+
|
|
75
|
+
%% process_clause(+Term, +SessionId, +MemoryId)
|
|
76
|
+
%% Process a single clause and add to session
|
|
77
|
+
process_clause((:- Directive), SessionId, _MemoryId) :-
|
|
78
|
+
!,
|
|
79
|
+
process_directive(Directive, SessionId).
|
|
80
|
+
|
|
81
|
+
%% Handle tool/2 with description: tool(Head, Description) :- Body
|
|
82
|
+
process_clause((tool(ToolHead, Description) :- Body), SessionId, _MemoryId) :-
|
|
83
|
+
!,
|
|
84
|
+
extract_tool_schema(ToolHead, Description, ToolName, Schema),
|
|
85
|
+
assertz(session_user_tools(SessionId, ToolName)),
|
|
86
|
+
assertz(session_user_tool_schema(SessionId, ToolName, Schema)),
|
|
87
|
+
% Store the source code for the tool description
|
|
88
|
+
format(string(SourceCode), "tool(~w, ~q) :-~n ~w.", [ToolHead, Description, Body]),
|
|
89
|
+
assertz(SessionId:tool_source(ToolName, SourceCode)),
|
|
90
|
+
% Assert the tool implementation (use just ToolHead for execution)
|
|
91
|
+
assertz(SessionId:(tool(ToolHead) :- Body)).
|
|
92
|
+
|
|
93
|
+
%% Handle tool/1 without description: tool(Head) :- Body
|
|
94
|
+
process_clause((tool(ToolHead) :- Body), SessionId, _MemoryId) :-
|
|
95
|
+
!,
|
|
96
|
+
extract_tool_schema(ToolHead, none, ToolName, Schema),
|
|
97
|
+
assertz(session_user_tools(SessionId, ToolName)),
|
|
98
|
+
assertz(session_user_tool_schema(SessionId, ToolName, Schema)),
|
|
99
|
+
% Store the source code for the tool description
|
|
100
|
+
format(string(SourceCode), "tool(~w) :-~n ~w.", [ToolHead, Body]),
|
|
101
|
+
assertz(SessionId:tool_source(ToolName, SourceCode)),
|
|
102
|
+
% Assert the tool implementation
|
|
103
|
+
assertz(SessionId:(tool(ToolHead) :- Body)).
|
|
104
|
+
|
|
105
|
+
process_clause((Head :- Body), SessionId, _MemoryId) :-
|
|
106
|
+
!,
|
|
107
|
+
% Regular clause - assert it
|
|
108
|
+
assertz(SessionId:(Head :- Body)).
|
|
109
|
+
|
|
110
|
+
process_clause(Fact, SessionId, _MemoryId) :-
|
|
111
|
+
% Simple fact
|
|
112
|
+
assertz(SessionId:Fact).
|
|
113
|
+
|
|
114
|
+
%% ============================================================
|
|
115
|
+
%% Tool Schema Extraction
|
|
116
|
+
%% ============================================================
|
|
117
|
+
|
|
118
|
+
%% extract_tool_schema(+ToolHead, +Description, -ToolName, -Schema)
|
|
119
|
+
%% Parse tool head to extract schema information
|
|
120
|
+
%% Schema = schema{name, description, inputs, outputs}
|
|
121
|
+
%% Each param = param{name, type, direction}
|
|
122
|
+
extract_tool_schema(ToolHead, Description, ToolName, Schema) :-
|
|
123
|
+
ToolHead =.. [ToolName|Args],
|
|
124
|
+
length(Args, Arity),
|
|
125
|
+
extract_params(Args, 1, Arity, Inputs, Outputs),
|
|
126
|
+
(Description == none -> Desc = "" ; Desc = Description),
|
|
127
|
+
Schema = schema{
|
|
128
|
+
name: ToolName,
|
|
129
|
+
description: Desc,
|
|
130
|
+
inputs: Inputs,
|
|
131
|
+
outputs: Outputs
|
|
132
|
+
}.
|
|
133
|
+
|
|
134
|
+
%% extract_params(+Args, +Index, +Arity, -Inputs, -Outputs)
|
|
135
|
+
%% Extract input and output parameters from argument list
|
|
136
|
+
%% Uses positional inference: first N-1 args are inputs, last arg is output
|
|
137
|
+
%% Parameter names are generic: arg1, arg2, etc.
|
|
138
|
+
extract_params([], _, _, [], []) :- !.
|
|
139
|
+
extract_params([_Arg|Rest], Index, Arity, Inputs, Outputs) :-
|
|
140
|
+
format(atom(Name), 'arg~w', [Index]),
|
|
141
|
+
Type = string, % Default type
|
|
142
|
+
NextIndex is Index + 1,
|
|
143
|
+
extract_params(Rest, NextIndex, Arity, RestInputs, RestOutputs),
|
|
144
|
+
Param = param{name: Name, type: Type},
|
|
145
|
+
% Last arg is output, all others are inputs
|
|
146
|
+
( Index == Arity
|
|
147
|
+
-> Inputs = RestInputs, Outputs = [Param|RestOutputs]
|
|
148
|
+
; Inputs = [Param|RestInputs], Outputs = RestOutputs
|
|
149
|
+
).
|
|
150
|
+
|
|
151
|
+
%% process_directive(+Directive, +SessionId)
|
|
152
|
+
%% Handle directives like :- param(...)
|
|
153
|
+
process_directive(param(Key, Desc), SessionId) :-
|
|
154
|
+
!,
|
|
155
|
+
assertz(SessionId:param_decl(Key, Desc)).
|
|
156
|
+
process_directive(param(Key, Desc, Default), SessionId) :-
|
|
157
|
+
!,
|
|
158
|
+
assertz(SessionId:param_decl(Key, Desc, Default)).
|
|
159
|
+
process_directive(_, _).
|
|
160
|
+
|
|
161
|
+
%% ============================================================
|
|
162
|
+
%% Engine Management
|
|
163
|
+
%% ============================================================
|
|
164
|
+
|
|
165
|
+
%% create_engine(+SessionId, +MemoryId, +Params, -Engine)
|
|
166
|
+
%% Create a cooperative execution engine for agent_main
|
|
167
|
+
create_engine(SessionId, MemoryId, Params, Engine) :-
|
|
168
|
+
assertz(session_memory(SessionId, MemoryId)),
|
|
169
|
+
assertz(session_params(SessionId, Params)),
|
|
170
|
+
% Determine goal based on what agent_main arity is defined
|
|
171
|
+
determine_agent_goal(SessionId, Params, Goal),
|
|
172
|
+
% Create the engine - pass SessionId to mi/4
|
|
173
|
+
engine_create(_,
|
|
174
|
+
deepclause_mi:mi(Goal, MemoryId, Params, SessionId),
|
|
175
|
+
Engine),
|
|
176
|
+
assertz(session_engine(SessionId, Engine)).
|
|
177
|
+
|
|
178
|
+
%% determine_agent_goal(+SessionId, +Params, -Goal)
|
|
179
|
+
%% Determine the correct agent_main goal to call based on arity
|
|
180
|
+
determine_agent_goal(SessionId, _Params, SessionId:agent_main) :-
|
|
181
|
+
current_predicate(SessionId:agent_main/0), !.
|
|
182
|
+
determine_agent_goal(SessionId, Params, Goal) :-
|
|
183
|
+
current_predicate(SessionId:agent_main/1), !,
|
|
184
|
+
% Get first parameter value from dict
|
|
185
|
+
dict_pairs(Params, _, Pairs),
|
|
186
|
+
( Pairs = [_-V1|_]
|
|
187
|
+
-> Goal = SessionId:agent_main(V1)
|
|
188
|
+
; Goal = SessionId:agent_main(_)
|
|
189
|
+
).
|
|
190
|
+
determine_agent_goal(SessionId, Params, Goal) :-
|
|
191
|
+
current_predicate(SessionId:agent_main/2), !,
|
|
192
|
+
dict_pairs(Params, _, Pairs),
|
|
193
|
+
( Pairs = [_-V1, _-V2|_]
|
|
194
|
+
-> Goal = SessionId:agent_main(V1, V2)
|
|
195
|
+
; Pairs = [_-V1|_]
|
|
196
|
+
-> Goal = SessionId:agent_main(V1, _)
|
|
197
|
+
; Goal = SessionId:agent_main(_, _)
|
|
198
|
+
).
|
|
199
|
+
determine_agent_goal(SessionId, _Params, SessionId:agent_main).
|
|
200
|
+
|
|
201
|
+
%% step_engine(+SessionId, -Status, -Content, -Payload)
|
|
202
|
+
%% Execute one step of the engine and return the result
|
|
203
|
+
step_engine(SessionId, Status, Content, Payload) :-
|
|
204
|
+
session_engine(SessionId, Engine),
|
|
205
|
+
( engine_next(Engine, Result)
|
|
206
|
+
-> process_engine_result(Result, Status, Content, Payload)
|
|
207
|
+
; Status = finished,
|
|
208
|
+
Content = '',
|
|
209
|
+
Payload = none
|
|
210
|
+
).
|
|
211
|
+
|
|
212
|
+
%% process_engine_result(+Result, -Status, -Content, -Payload)
|
|
213
|
+
process_engine_result(output(Text), output, Text, none) :- !.
|
|
214
|
+
process_engine_result(log(Text), log, Text, none) :- !.
|
|
215
|
+
process_engine_result(answer(Text), answer, Text, none) :- !.
|
|
216
|
+
process_engine_result(request_agent_loop(Desc, Vars, Tools), request_agent_loop, '',
|
|
217
|
+
payload{taskDescription: Desc, outputVars: Vars, userTools: Tools}) :- !.
|
|
218
|
+
process_engine_result(request_exec(Tool, Args), request_exec, '',
|
|
219
|
+
payload{toolName: Tool, args: Args}) :- !.
|
|
220
|
+
process_engine_result(wait_input(Prompt), wait_input, Prompt, none) :- !.
|
|
221
|
+
process_engine_result(error(Msg), error, Msg, none) :- !.
|
|
222
|
+
process_engine_result(Other, error, Msg, none) :-
|
|
223
|
+
format(atom(Msg), 'Unknown engine result: ~w', [Other]).
|
|
224
|
+
|
|
225
|
+
%% destroy_engine(+SessionId)
|
|
226
|
+
%% Clean up engine and session state
|
|
227
|
+
destroy_engine(SessionId) :-
|
|
228
|
+
( session_engine(SessionId, Engine)
|
|
229
|
+
-> catch(engine_destroy(Engine), _, true)
|
|
230
|
+
; true
|
|
231
|
+
),
|
|
232
|
+
retractall(session_engine(SessionId, _)),
|
|
233
|
+
retractall(session_memory(SessionId, _)),
|
|
234
|
+
retractall(session_params(SessionId, _)),
|
|
235
|
+
retractall(session_user_tools(SessionId, _)),
|
|
236
|
+
retractall(session_user_tool_schema(SessionId, _, _)),
|
|
237
|
+
retractall(session_pending_input(SessionId, _)),
|
|
238
|
+
retractall(session_agent_result(SessionId, _)),
|
|
239
|
+
retractall(session_exec_result(SessionId, _)),
|
|
240
|
+
% Clean up session module (if it exists)
|
|
241
|
+
( current_module(SessionId)
|
|
242
|
+
-> catch(
|
|
243
|
+
( findall(Head,
|
|
244
|
+
(current_predicate(SessionId:Name/Arity),
|
|
245
|
+
functor(Head, Name, Arity),
|
|
246
|
+
clause(SessionId:Head, _)),
|
|
247
|
+
Heads),
|
|
248
|
+
forall(member(H, Heads), retractall(SessionId:H))
|
|
249
|
+
),
|
|
250
|
+
_,
|
|
251
|
+
true
|
|
252
|
+
)
|
|
253
|
+
; true
|
|
254
|
+
).
|
|
255
|
+
|
|
256
|
+
%% ============================================================
|
|
257
|
+
%% Result Posting (from JavaScript)
|
|
258
|
+
%% ============================================================
|
|
259
|
+
|
|
260
|
+
%% post_agent_result(+SessionId, +Success, +Variables)
|
|
261
|
+
%% Post the result of an agent loop back to the waiting engine
|
|
262
|
+
post_agent_result(SessionId, Success, Variables) :-
|
|
263
|
+
assertz(session_agent_result(SessionId, result{success: Success, variables: Variables})),
|
|
264
|
+
session_engine(SessionId, Engine),
|
|
265
|
+
engine_post(Engine, agent_done).
|
|
266
|
+
|
|
267
|
+
%% post_exec_result(+SessionId, +Status, +Result)
|
|
268
|
+
%% Post the result of an exec call back to the waiting engine
|
|
269
|
+
post_exec_result(SessionId, Status, Result) :-
|
|
270
|
+
assertz(session_exec_result(SessionId, result{status: Status, result: Result})),
|
|
271
|
+
session_engine(SessionId, Engine),
|
|
272
|
+
engine_post(Engine, exec_done).
|
|
273
|
+
|
|
274
|
+
%% provide_input(+SessionId, +Input)
|
|
275
|
+
%% Provide user input to a waiting engine
|
|
276
|
+
provide_input(SessionId, Input) :-
|
|
277
|
+
assertz(session_pending_input(SessionId, Input)),
|
|
278
|
+
session_engine(SessionId, Engine),
|
|
279
|
+
engine_post(Engine, input_provided).
|
|
280
|
+
|
|
281
|
+
%% ============================================================
|
|
282
|
+
%% Meta-Interpreter Core
|
|
283
|
+
%% ============================================================
|
|
284
|
+
|
|
285
|
+
%% mi(+Goal, +MemoryId, +Params, +SessionId)
|
|
286
|
+
%% Main meta-interpreter entry point
|
|
287
|
+
mi(Goal, MemoryId, Params, SessionId) :-
|
|
288
|
+
% Store session ID for use by get_session_id/1
|
|
289
|
+
nb_setval(current_session_id, SessionId),
|
|
290
|
+
catch(
|
|
291
|
+
mi_call(Goal, MemoryId, Params),
|
|
292
|
+
Error,
|
|
293
|
+
( format(atom(ErrMsg), 'Runtime error: ~w', [Error]),
|
|
294
|
+
engine_yield(error(ErrMsg)),
|
|
295
|
+
fail
|
|
296
|
+
)
|
|
297
|
+
).
|
|
298
|
+
|
|
299
|
+
%% ============================================================
|
|
300
|
+
%% Task Handling
|
|
301
|
+
%% ============================================================
|
|
302
|
+
|
|
303
|
+
%% collect_user_tools(+SessionId, -ToolSchemas)
|
|
304
|
+
%% Collect all user tool schemas for the session
|
|
305
|
+
collect_user_tools(SessionId, ToolSchemas) :-
|
|
306
|
+
findall(
|
|
307
|
+
tool_info{name: Name, schema: Schema, source: Source},
|
|
308
|
+
(
|
|
309
|
+
session_user_tool_schema(SessionId, Name, Schema),
|
|
310
|
+
(SessionId:tool_source(Name, Source) -> true ; Source = "")
|
|
311
|
+
),
|
|
312
|
+
ToolSchemas
|
|
313
|
+
).
|
|
314
|
+
|
|
315
|
+
%% mi_call(task(Desc), +MemoryId, +Params)
|
|
316
|
+
%% Handle task/1 - simple task without output variables
|
|
317
|
+
mi_call(task(Desc), MemoryId, Params) :-
|
|
318
|
+
!,
|
|
319
|
+
interpolate_desc(Desc, Params, InterpDesc),
|
|
320
|
+
get_session_id(SessionId),
|
|
321
|
+
collect_user_tools(SessionId, UserTools),
|
|
322
|
+
% Yield request to JavaScript with tool schemas
|
|
323
|
+
engine_yield(request_agent_loop(InterpDesc, [], UserTools)),
|
|
324
|
+
% Wait for result
|
|
325
|
+
engine_fetch(_Signal),
|
|
326
|
+
% Get and process result
|
|
327
|
+
session_agent_result(SessionId, Result),
|
|
328
|
+
retract(session_agent_result(SessionId, _)),
|
|
329
|
+
Result.success == true.
|
|
330
|
+
|
|
331
|
+
%% mi_call(task(Desc, Var1), +MemoryId, +Params)
|
|
332
|
+
%% Handle task/2 - task with one output variable
|
|
333
|
+
mi_call(task(Desc, Var1), MemoryId, Params) :-
|
|
334
|
+
!,
|
|
335
|
+
mi_call_task_n(Desc, [Var1], ['Var1'], MemoryId, Params).
|
|
336
|
+
|
|
337
|
+
%% mi_call(task(Desc, Var1, Var2), +MemoryId, +Params)
|
|
338
|
+
%% Handle task/3 - task with two output variables
|
|
339
|
+
mi_call(task(Desc, Var1, Var2), MemoryId, Params) :-
|
|
340
|
+
!,
|
|
341
|
+
mi_call_task_n(Desc, [Var1, Var2], ['Var1', 'Var2'], MemoryId, Params).
|
|
342
|
+
|
|
343
|
+
%% mi_call(task(Desc, Var1, Var2, Var3), +MemoryId, +Params)
|
|
344
|
+
%% Handle task/4 - task with three output variables
|
|
345
|
+
mi_call(task(Desc, Var1, Var2, Var3), MemoryId, Params) :-
|
|
346
|
+
!,
|
|
347
|
+
mi_call_task_n(Desc, [Var1, Var2, Var3], ['Var1', 'Var2', 'Var3'], MemoryId, Params).
|
|
348
|
+
|
|
349
|
+
%% mi_call_task_n(+Desc, +Vars, +VarNames, +MemoryId, +Params)
|
|
350
|
+
%% Generic handler for task/N with N-1 output variables
|
|
351
|
+
mi_call_task_n(Desc, Vars, VarNames, _MemoryId, Params) :-
|
|
352
|
+
interpolate_desc(Desc, Params, InterpDesc),
|
|
353
|
+
get_session_id(SessionId),
|
|
354
|
+
collect_user_tools(SessionId, UserTools),
|
|
355
|
+
% Yield request to JavaScript with tool schemas
|
|
356
|
+
engine_yield(request_agent_loop(InterpDesc, VarNames, UserTools)),
|
|
357
|
+
% Wait for result
|
|
358
|
+
engine_fetch(_Signal),
|
|
359
|
+
% Get and process result
|
|
360
|
+
session_agent_result(SessionId, Result),
|
|
361
|
+
retract(session_agent_result(SessionId, _)),
|
|
362
|
+
Result.success == true,
|
|
363
|
+
% Bind output variables
|
|
364
|
+
bind_task_variables(Result.variables, VarNames, Vars).
|
|
365
|
+
|
|
366
|
+
%% bind_task_variables(+VarsDict, +Names, -Values)
|
|
367
|
+
bind_task_variables(_, [], []) :- !.
|
|
368
|
+
bind_task_variables(VarsDict, [Name|Names], [Value|Values]) :-
|
|
369
|
+
( get_dict(Name, VarsDict, Value)
|
|
370
|
+
-> true
|
|
371
|
+
; true % Leave unbound if not present
|
|
372
|
+
),
|
|
373
|
+
bind_task_variables(VarsDict, Names, Values).
|
|
374
|
+
|
|
375
|
+
%% ============================================================
|
|
376
|
+
%% Exec Handling
|
|
377
|
+
%% ============================================================
|
|
378
|
+
|
|
379
|
+
%% mi_call(exec(ToolCall, Output), +MemoryId, +Params)
|
|
380
|
+
%% Handle exec/2 - external tool execution
|
|
381
|
+
mi_call(exec(ToolCall, Output), _MemoryId, _Params) :-
|
|
382
|
+
!,
|
|
383
|
+
ToolCall =.. [ToolName|Args],
|
|
384
|
+
get_session_id(SessionId),
|
|
385
|
+
% Yield request to JavaScript
|
|
386
|
+
engine_yield(request_exec(ToolName, Args)),
|
|
387
|
+
% Wait for result
|
|
388
|
+
engine_fetch(_Signal),
|
|
389
|
+
% Get and process result
|
|
390
|
+
session_exec_result(SessionId, Result),
|
|
391
|
+
retract(session_exec_result(SessionId, _)),
|
|
392
|
+
( Result.status == success
|
|
393
|
+
-> Output = Result.result
|
|
394
|
+
; fail
|
|
395
|
+
).
|
|
396
|
+
|
|
397
|
+
%% ============================================================
|
|
398
|
+
%% Memory Predicates
|
|
399
|
+
%% ============================================================
|
|
400
|
+
|
|
401
|
+
%% mi_call(system(Text), +MemoryId, +Params)
|
|
402
|
+
mi_call(system(Text), MemoryId, Params) :-
|
|
403
|
+
!,
|
|
404
|
+
interpolate_desc(Text, Params, InterpText),
|
|
405
|
+
deepclause_memory:push_memory(MemoryId, message{role: system, content: InterpText}).
|
|
406
|
+
|
|
407
|
+
%% mi_call(user(Text), +MemoryId, +Params)
|
|
408
|
+
mi_call(user(Text), MemoryId, Params) :-
|
|
409
|
+
!,
|
|
410
|
+
interpolate_desc(Text, Params, InterpText),
|
|
411
|
+
deepclause_memory:push_memory(MemoryId, message{role: user, content: InterpText}).
|
|
412
|
+
|
|
413
|
+
%% mi_call(push_context, +MemoryId, +Params)
|
|
414
|
+
mi_call(push_context, MemoryId, _Params) :-
|
|
415
|
+
!,
|
|
416
|
+
deepclause_memory:push_context(MemoryId).
|
|
417
|
+
|
|
418
|
+
%% mi_call(pop_context, +MemoryId, +Params)
|
|
419
|
+
mi_call(pop_context, MemoryId, _Params) :-
|
|
420
|
+
!,
|
|
421
|
+
deepclause_memory:pop_context(MemoryId).
|
|
422
|
+
|
|
423
|
+
%% ============================================================
|
|
424
|
+
%% Output Predicates
|
|
425
|
+
%% ============================================================
|
|
426
|
+
|
|
427
|
+
%% mi_call(answer(Text), +MemoryId, +Params)
|
|
428
|
+
mi_call(answer(Text), _MemoryId, Params) :-
|
|
429
|
+
!,
|
|
430
|
+
interpolate_desc(Text, Params, InterpText),
|
|
431
|
+
engine_yield(answer(InterpText)).
|
|
432
|
+
|
|
433
|
+
%% mi_call(yield(Text), +MemoryId, +Params)
|
|
434
|
+
mi_call(yield(Text), _MemoryId, Params) :-
|
|
435
|
+
!,
|
|
436
|
+
interpolate_desc(Text, Params, InterpText),
|
|
437
|
+
engine_yield(output(InterpText)).
|
|
438
|
+
|
|
439
|
+
%% mi_call(log(Text), +MemoryId, +Params)
|
|
440
|
+
mi_call(log(Text), _MemoryId, Params) :-
|
|
441
|
+
!,
|
|
442
|
+
interpolate_desc(Text, Params, InterpText),
|
|
443
|
+
engine_yield(log(InterpText)).
|
|
444
|
+
|
|
445
|
+
%% ============================================================
|
|
446
|
+
%% Parameter Handling
|
|
447
|
+
%% ============================================================
|
|
448
|
+
|
|
449
|
+
%% mi_call(param(Key, Desc, Value), +MemoryId, +Params)
|
|
450
|
+
mi_call(param(Key, _Desc, Value), _MemoryId, Params) :-
|
|
451
|
+
!,
|
|
452
|
+
( atom(Key)
|
|
453
|
+
-> KeyAtom = Key
|
|
454
|
+
; atom_string(KeyAtom, Key)
|
|
455
|
+
),
|
|
456
|
+
get_dict(KeyAtom, Params, Value).
|
|
457
|
+
|
|
458
|
+
%% ============================================================
|
|
459
|
+
%% Control Flow
|
|
460
|
+
%% ============================================================
|
|
461
|
+
|
|
462
|
+
%% mi_call((A, B), +MemoryId, +Params)
|
|
463
|
+
mi_call((A, B), MemoryId, Params) :-
|
|
464
|
+
!,
|
|
465
|
+
mi_call(A, MemoryId, Params),
|
|
466
|
+
mi_call(B, MemoryId, Params).
|
|
467
|
+
|
|
468
|
+
%% mi_call((A ; B), +MemoryId, +Params)
|
|
469
|
+
mi_call((A ; B), MemoryId, Params) :-
|
|
470
|
+
!,
|
|
471
|
+
( mi_call(A, MemoryId, Params)
|
|
472
|
+
; mi_call(B, MemoryId, Params)
|
|
473
|
+
).
|
|
474
|
+
|
|
475
|
+
%% mi_call((Cond -> Then ; Else), +MemoryId, +Params)
|
|
476
|
+
mi_call((Cond -> Then ; Else), MemoryId, Params) :-
|
|
477
|
+
!,
|
|
478
|
+
( mi_call(Cond, MemoryId, Params)
|
|
479
|
+
-> mi_call(Then, MemoryId, Params)
|
|
480
|
+
; mi_call(Else, MemoryId, Params)
|
|
481
|
+
).
|
|
482
|
+
|
|
483
|
+
%% mi_call((Cond -> Then), +MemoryId, +Params)
|
|
484
|
+
mi_call((Cond -> Then), MemoryId, Params) :-
|
|
485
|
+
!,
|
|
486
|
+
( mi_call(Cond, MemoryId, Params)
|
|
487
|
+
-> mi_call(Then, MemoryId, Params)
|
|
488
|
+
).
|
|
489
|
+
|
|
490
|
+
%% mi_call(\+(Goal), +MemoryId, +Params)
|
|
491
|
+
mi_call(\+(Goal), MemoryId, Params) :-
|
|
492
|
+
!,
|
|
493
|
+
\+ mi_call(Goal, MemoryId, Params).
|
|
494
|
+
|
|
495
|
+
%% mi_call(!, +MemoryId, +Params)
|
|
496
|
+
mi_call(!, _MemoryId, _Params) :-
|
|
497
|
+
!.
|
|
498
|
+
|
|
499
|
+
%% mi_call(true, +MemoryId, +Params)
|
|
500
|
+
mi_call(true, _MemoryId, _Params) :-
|
|
501
|
+
!.
|
|
502
|
+
|
|
503
|
+
%% mi_call(fail, +MemoryId, +Params)
|
|
504
|
+
mi_call(fail, _MemoryId, _Params) :-
|
|
505
|
+
!,
|
|
506
|
+
fail.
|
|
507
|
+
|
|
508
|
+
%% mi_call(false, +MemoryId, +Params)
|
|
509
|
+
mi_call(false, _MemoryId, _Params) :-
|
|
510
|
+
!,
|
|
511
|
+
fail.
|
|
512
|
+
|
|
513
|
+
%% ============================================================
|
|
514
|
+
%% Module-Qualified Goals
|
|
515
|
+
%% ============================================================
|
|
516
|
+
|
|
517
|
+
%% mi_call(Module:Goal, +MemoryId, +Params)
|
|
518
|
+
mi_call(Module:Goal, MemoryId, Params) :-
|
|
519
|
+
!,
|
|
520
|
+
( % Check if it's a user-defined predicate that needs meta-interpretation
|
|
521
|
+
callable(Module:Goal), clause(Module:Goal, Body),
|
|
522
|
+
Body \== true
|
|
523
|
+
-> mi_call(Body, MemoryId, Params)
|
|
524
|
+
; % Try direct call
|
|
525
|
+
call(Module:Goal)
|
|
526
|
+
).
|
|
527
|
+
|
|
528
|
+
%% ============================================================
|
|
529
|
+
%% Built-in and User-Defined Predicates
|
|
530
|
+
%% ============================================================
|
|
531
|
+
|
|
532
|
+
%% mi_call(Goal, +MemoryId, +Params)
|
|
533
|
+
%% Default handler - try built-in first, then user-defined
|
|
534
|
+
mi_call(Goal, MemoryId, Params) :-
|
|
535
|
+
% Guard: Goal must be callable (not a variable)
|
|
536
|
+
( var(Goal)
|
|
537
|
+
-> throw(error(instantiation_error, mi_call/3))
|
|
538
|
+
; true
|
|
539
|
+
),
|
|
540
|
+
% Try as built-in
|
|
541
|
+
( predicate_property(Goal, built_in)
|
|
542
|
+
-> call(Goal)
|
|
543
|
+
; % Try as user-defined with meta-interpretation
|
|
544
|
+
get_session_id(SessionId),
|
|
545
|
+
callable(Goal),
|
|
546
|
+
catch(clause(SessionId:Goal, Body), _, fail)
|
|
547
|
+
-> mi_call(Body, MemoryId, Params)
|
|
548
|
+
; % Final fallback - direct call
|
|
549
|
+
call(Goal)
|
|
550
|
+
).
|
|
551
|
+
|
|
552
|
+
%% ============================================================
|
|
553
|
+
%% Helper Predicates
|
|
554
|
+
%% ============================================================
|
|
555
|
+
|
|
556
|
+
%% interpolate_desc(+Template, +Params, -Result)
|
|
557
|
+
%% Expand {Variable} patterns using params
|
|
558
|
+
interpolate_desc(Template, Params, Result) :-
|
|
559
|
+
( is_dict(Params)
|
|
560
|
+
-> dict_pairs(Params, _, Pairs),
|
|
561
|
+
maplist([K-V, K=V]>>true, Pairs, Bindings),
|
|
562
|
+
deepclause_strings:interpolate_string(Template, Bindings, Result)
|
|
563
|
+
; Result = Template
|
|
564
|
+
).
|
|
565
|
+
|
|
566
|
+
%% get_session_id(-SessionId)
|
|
567
|
+
%% Extract session ID from current execution context
|
|
568
|
+
get_session_id(SessionId) :-
|
|
569
|
+
nb_current(current_session_id, SessionId), !.
|
|
570
|
+
get_session_id(default_session).
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deepclause_strings.pl - String interpolation for DeepClause SDK
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - interpolate_string/3: Replace {Variable} patterns with values
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
:- module(deepclause_strings, [
|
|
9
|
+
interpolate_string/3,
|
|
10
|
+
dml_string_expand/3
|
|
11
|
+
]).
|
|
12
|
+
|
|
13
|
+
%% interpolate_string(+Template, +Bindings, -Result)
|
|
14
|
+
%% Replace {VariableName} patterns in Template with values from Bindings
|
|
15
|
+
%% Bindings is a list of Name=Value pairs
|
|
16
|
+
interpolate_string(Template, Bindings, Result) :-
|
|
17
|
+
( string(Template)
|
|
18
|
+
-> atom_string(TemplateAtom, Template)
|
|
19
|
+
; TemplateAtom = Template
|
|
20
|
+
),
|
|
21
|
+
interpolate_atom(TemplateAtom, Bindings, ResultAtom),
|
|
22
|
+
atom_string(ResultAtom, Result).
|
|
23
|
+
|
|
24
|
+
%% interpolate_atom(+Template, +Bindings, -Result)
|
|
25
|
+
interpolate_atom(Template, Bindings, Result) :-
|
|
26
|
+
atom_codes(Template, Codes),
|
|
27
|
+
interpolate_codes(Codes, Bindings, ResultCodes),
|
|
28
|
+
atom_codes(Result, ResultCodes).
|
|
29
|
+
|
|
30
|
+
%% interpolate_codes(+Codes, +Bindings, -ResultCodes)
|
|
31
|
+
%% Process character codes, replacing {var} patterns
|
|
32
|
+
interpolate_codes([], _, []) :- !.
|
|
33
|
+
|
|
34
|
+
% Found opening brace - extract variable name
|
|
35
|
+
interpolate_codes([0'{|Rest], Bindings, Result) :-
|
|
36
|
+
!,
|
|
37
|
+
extract_var_name(Rest, VarNameCodes, AfterVar),
|
|
38
|
+
atom_codes(VarName, VarNameCodes),
|
|
39
|
+
( find_binding(VarName, Bindings, Value)
|
|
40
|
+
-> format(atom(ValueAtom), '~w', [Value]),
|
|
41
|
+
atom_codes(ValueAtom, ValueCodes),
|
|
42
|
+
interpolate_codes(AfterVar, Bindings, RestResult),
|
|
43
|
+
append(ValueCodes, RestResult, Result)
|
|
44
|
+
; % Variable not found - keep as is
|
|
45
|
+
interpolate_codes(AfterVar, Bindings, RestResult),
|
|
46
|
+
append([0'{|VarNameCodes], [0'}|RestResult], Result)
|
|
47
|
+
).
|
|
48
|
+
|
|
49
|
+
% Regular character - keep it
|
|
50
|
+
interpolate_codes([C|Rest], Bindings, [C|Result]) :-
|
|
51
|
+
interpolate_codes(Rest, Bindings, Result).
|
|
52
|
+
|
|
53
|
+
%% extract_var_name(+Codes, -VarNameCodes, -RemainingCodes)
|
|
54
|
+
%% Extract characters until closing brace
|
|
55
|
+
extract_var_name([0'}|Rest], [], Rest) :- !.
|
|
56
|
+
extract_var_name([C|Rest], [C|VarRest], Final) :-
|
|
57
|
+
C \= 0'},
|
|
58
|
+
extract_var_name(Rest, VarRest, Final).
|
|
59
|
+
extract_var_name([], [], []). % Handle unclosed brace gracefully
|
|
60
|
+
|
|
61
|
+
%% find_binding(+VarName, +Bindings, -Value)
|
|
62
|
+
%% Look up a variable in the bindings list
|
|
63
|
+
find_binding(VarName, Bindings, Value) :-
|
|
64
|
+
( member(VarName=Value, Bindings)
|
|
65
|
+
-> true
|
|
66
|
+
; % Also try with atom version
|
|
67
|
+
atom_string(VarNameAtom, VarName),
|
|
68
|
+
member(VarNameAtom=Value, Bindings)
|
|
69
|
+
; % Try dict-style binding
|
|
70
|
+
is_dict(Bindings),
|
|
71
|
+
get_dict(VarName, Bindings, Value)
|
|
72
|
+
).
|
|
73
|
+
|
|
74
|
+
%% dml_string_expand(+Term, +Bindings, -Expanded)
|
|
75
|
+
%% Expand strings within a term
|
|
76
|
+
dml_string_expand(Term, Bindings, Expanded) :-
|
|
77
|
+
( string(Term)
|
|
78
|
+
-> interpolate_string(Term, Bindings, Expanded)
|
|
79
|
+
; atom(Term)
|
|
80
|
+
-> interpolate_string(Term, Bindings, ExpandedStr),
|
|
81
|
+
atom_string(Expanded, ExpandedStr)
|
|
82
|
+
; is_list(Term)
|
|
83
|
+
-> maplist({Bindings}/[T, E]>>dml_string_expand(T, Bindings, E), Term, Expanded)
|
|
84
|
+
; compound(Term)
|
|
85
|
+
-> Term =.. [Functor|Args],
|
|
86
|
+
maplist({Bindings}/[A, EA]>>dml_string_expand(A, Bindings, EA), Args, ExpandedArgs),
|
|
87
|
+
Expanded =.. [Functor|ExpandedArgs]
|
|
88
|
+
; Expanded = Term
|
|
89
|
+
).
|