deepclause-sdk 0.0.11 → 0.0.13
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.
|
@@ -241,6 +241,7 @@ process_clause((:- Directive), SessionId) :-
|
|
|
241
241
|
%% Handle tool/2 with description: tool(Head, Description) :- Body
|
|
242
242
|
process_clause((tool(ToolHead, Description) :- Body), SessionId) :-
|
|
243
243
|
!,
|
|
244
|
+
(catch(expand_dict_dots(Body, ExpandedBody), _, fail) -> true ; ExpandedBody = Body),
|
|
244
245
|
extract_tool_schema(ToolHead, Description, ToolName, Schema),
|
|
245
246
|
assertz(session_user_tools(SessionId, ToolName)),
|
|
246
247
|
assertz(session_user_tool_schema(SessionId, ToolName, Schema)),
|
|
@@ -248,11 +249,12 @@ process_clause((tool(ToolHead, Description) :- Body), SessionId) :-
|
|
|
248
249
|
format(string(SourceCode), "tool(~w, ~q) :-~n ~w.", [ToolHead, Description, Body]),
|
|
249
250
|
assertz(SessionId:tool_source(ToolName, SourceCode)),
|
|
250
251
|
% Assert the tool implementation (use just ToolHead for execution)
|
|
251
|
-
assertz(SessionId:(tool(ToolHead) :-
|
|
252
|
+
assertz(SessionId:(tool(ToolHead) :- ExpandedBody)).
|
|
252
253
|
|
|
253
254
|
%% Handle tool/1 without description: tool(Head) :- Body
|
|
254
255
|
process_clause((tool(ToolHead) :- Body), SessionId) :-
|
|
255
256
|
!,
|
|
257
|
+
(catch(expand_dict_dots(Body, ExpandedBody), _, fail) -> true ; ExpandedBody = Body),
|
|
256
258
|
extract_tool_schema(ToolHead, none, ToolName, Schema),
|
|
257
259
|
assertz(session_user_tools(SessionId, ToolName)),
|
|
258
260
|
assertz(session_user_tool_schema(SessionId, ToolName, Schema)),
|
|
@@ -260,17 +262,86 @@ process_clause((tool(ToolHead) :- Body), SessionId) :-
|
|
|
260
262
|
format(string(SourceCode), "tool(~w) :-~n ~w.", [ToolHead, Body]),
|
|
261
263
|
assertz(SessionId:tool_source(ToolName, SourceCode)),
|
|
262
264
|
% Assert the tool implementation
|
|
263
|
-
assertz(SessionId:(tool(ToolHead) :-
|
|
265
|
+
assertz(SessionId:(tool(ToolHead) :- ExpandedBody)).
|
|
264
266
|
|
|
265
267
|
process_clause((Head :- Body), SessionId) :-
|
|
266
268
|
!,
|
|
267
|
-
%
|
|
268
|
-
|
|
269
|
+
% Expand dict dot-notation (Dict.Key → get_dict), then assert
|
|
270
|
+
( catch(expand_dict_dots(Body, ExpandedBody), _, fail)
|
|
271
|
+
-> true
|
|
272
|
+
; ExpandedBody = Body
|
|
273
|
+
),
|
|
274
|
+
assertz(SessionId:(Head :- ExpandedBody)).
|
|
269
275
|
|
|
270
276
|
process_clause(Fact, SessionId) :-
|
|
271
277
|
% Simple fact
|
|
272
278
|
assertz(SessionId:Fact).
|
|
273
279
|
|
|
280
|
+
%% ============================================================
|
|
281
|
+
%% Dict Dot-Notation Expansion (compile-time)
|
|
282
|
+
%% ============================================================
|
|
283
|
+
%% SWI-Prolog's dict functional notation (Dict.Key) is normally
|
|
284
|
+
%% expanded by goal_expansion during compilation. Since DML clauses
|
|
285
|
+
%% are loaded via assertz (no goal expansion), we must expand
|
|
286
|
+
%% Dict.Key → get_dict(Key, Dict, Value) manually before asserting.
|
|
287
|
+
%%
|
|
288
|
+
%% Handles:
|
|
289
|
+
%% Dict.Key = Value → get_dict(Key, Dict, Value)
|
|
290
|
+
%% Value = Dict.Key → get_dict(Key, Dict, Value)
|
|
291
|
+
%% Dict.Key == Value → get_dict(Key, Dict, Tmp), Tmp == Value
|
|
292
|
+
%% Value == Dict.Key → get_dict(Key, Dict, Tmp), Tmp == Value
|
|
293
|
+
|
|
294
|
+
%% expand_dict_dots(+GoalIn, -GoalOut)
|
|
295
|
+
%% Top-level expansion for goal bodies
|
|
296
|
+
expand_dict_dots(Var, Var) :- var(Var), !.
|
|
297
|
+
expand_dict_dots((A, B), (EA, EB)) :- !, expand_dict_dots(A, EA), expand_dict_dots(B, EB).
|
|
298
|
+
expand_dict_dots((A ; B), (EA ; EB)) :- !, expand_dict_dots(A, EA), expand_dict_dots(B, EB).
|
|
299
|
+
expand_dict_dots((A -> B), (EA -> EB)) :- !, expand_dict_dots(A, EA), expand_dict_dots(B, EB).
|
|
300
|
+
|
|
301
|
+
%% Unification with dict dot access: Dict.Key = Value
|
|
302
|
+
expand_dict_dots(Goal, Result) :-
|
|
303
|
+
nonvar(Goal),
|
|
304
|
+
functor(Goal, =, 2),
|
|
305
|
+
!,
|
|
306
|
+
arg(1, Goal, A),
|
|
307
|
+
arg(2, Goal, B),
|
|
308
|
+
( nonvar(A), is_dot_access(A, Dict, Key)
|
|
309
|
+
-> Result = get_dict(Key, Dict, B)
|
|
310
|
+
; nonvar(B), is_dot_access(B, Dict, Key)
|
|
311
|
+
-> Result = get_dict(Key, Dict, A)
|
|
312
|
+
; Result = Goal
|
|
313
|
+
).
|
|
314
|
+
|
|
315
|
+
%% Equality check with dict dot access: Dict.Key == Value
|
|
316
|
+
expand_dict_dots(Goal, Result) :-
|
|
317
|
+
nonvar(Goal),
|
|
318
|
+
functor(Goal, ==, 2),
|
|
319
|
+
!,
|
|
320
|
+
arg(1, Goal, A),
|
|
321
|
+
arg(2, Goal, B),
|
|
322
|
+
( nonvar(A), is_dot_access(A, Dict, Key)
|
|
323
|
+
-> Result = (get_dict(Key, Dict, Tmp), Tmp == B)
|
|
324
|
+
; nonvar(B), is_dot_access(B, Dict, Key)
|
|
325
|
+
-> Result = (get_dict(Key, Dict, Tmp), Tmp == A)
|
|
326
|
+
; Result = Goal
|
|
327
|
+
).
|
|
328
|
+
|
|
329
|
+
expand_dict_dots(Goal, Goal).
|
|
330
|
+
|
|
331
|
+
%% is_dot_access(+Term, -Dict, -Key)
|
|
332
|
+
%% Check if Term is a dict dot-access expression: '.'(Dict, Key) where Key is atom
|
|
333
|
+
is_dot_access(Term, Dict, Key) :-
|
|
334
|
+
compound(Term),
|
|
335
|
+
compound_name_arity(Term, '.', 2),
|
|
336
|
+
arg(1, Term, Dict),
|
|
337
|
+
arg(2, Term, Key),
|
|
338
|
+
atom(Key).
|
|
339
|
+
|
|
340
|
+
%% expand_dict_expr(+ExprIn, -ExprOut)
|
|
341
|
+
%% Expand dict access in value-level expressions (just pass through for now)
|
|
342
|
+
expand_dict_expr(Var, Var) :- var(Var), !.
|
|
343
|
+
expand_dict_expr(Expr, Expr).
|
|
344
|
+
|
|
274
345
|
%% ============================================================
|
|
275
346
|
%% Tool Schema Extraction
|
|
276
347
|
%% ============================================================
|
|
@@ -560,6 +631,12 @@ set_context_stack(StateIn, Stack, StateOut) :-
|
|
|
560
631
|
set_memory(StateIn, Memory, StateOut) :-
|
|
561
632
|
StateOut = StateIn.put(memory, Memory).
|
|
562
633
|
|
|
634
|
+
%% is_system_memory_message(+Message)
|
|
635
|
+
%% True if the memory message has role=system
|
|
636
|
+
is_system_memory_message(Message) :-
|
|
637
|
+
is_dict(Message),
|
|
638
|
+
get_dict(role, Message, system).
|
|
639
|
+
|
|
563
640
|
%% ============================================================
|
|
564
641
|
%% Tool Scope Helpers
|
|
565
642
|
%% ============================================================
|
|
@@ -928,8 +1005,11 @@ mi_call(task(Desc), StateIn, StateOut) :-
|
|
|
928
1005
|
),
|
|
929
1006
|
% Use full messages from agent loop result
|
|
930
1007
|
( get_dict(messages, Result, Messages), Messages \= []
|
|
931
|
-
-> %
|
|
932
|
-
|
|
1008
|
+
-> % Preserve system messages from current memory (agent only returns user/assistant)
|
|
1009
|
+
get_memory(StateAfterAgent, OldMemory),
|
|
1010
|
+
include(is_system_memory_message, OldMemory, SystemMessages),
|
|
1011
|
+
append(SystemMessages, Messages, NewMemory),
|
|
1012
|
+
set_memory(StateAfterAgent, NewMemory, StateOut)
|
|
933
1013
|
; % Fallback: just add task description and response (old behavior)
|
|
934
1014
|
add_memory(StateAfterAgent, user, InterpDesc, State1),
|
|
935
1015
|
( get_dict(response, Result, Response), Response \= ""
|
|
@@ -1040,8 +1120,11 @@ mi_call_task_n(Desc, Vars, VarNames, StateIn, StateOut) :-
|
|
|
1040
1120
|
bind_task_variables(Result.variables, VarNames, Vars),
|
|
1041
1121
|
% Use full messages from agent loop result
|
|
1042
1122
|
( get_dict(messages, Result, Messages), Messages \= []
|
|
1043
|
-
-> %
|
|
1044
|
-
|
|
1123
|
+
-> % Preserve system messages from current memory (agent only returns user/assistant)
|
|
1124
|
+
get_memory(StateAfterAgent, OldMemory),
|
|
1125
|
+
include(is_system_memory_message, OldMemory, SystemMessages),
|
|
1126
|
+
append(SystemMessages, Messages, NewMemory),
|
|
1127
|
+
set_memory(StateAfterAgent, NewMemory, StateOut)
|
|
1045
1128
|
; % Fallback: just add task description and response (old behavior)
|
|
1046
1129
|
add_memory(StateAfterAgent, user, InterpDesc, State1),
|
|
1047
1130
|
( get_dict(response, Result, Response), Response \= ""
|
|
@@ -1585,9 +1668,10 @@ consult_process_term((tool(ToolHead) :- Body), SessionId) :-
|
|
|
1585
1668
|
assertz(SessionId:(tool(ToolHead) :- Body)).
|
|
1586
1669
|
|
|
1587
1670
|
consult_process_term((Head :- Body), SessionId) :-
|
|
1588
|
-
%
|
|
1671
|
+
% Expand dict dot-notation, then assert
|
|
1589
1672
|
!,
|
|
1590
|
-
|
|
1673
|
+
(catch(expand_dict_dots(Body, ExpandedBody), _, fail) -> true ; ExpandedBody = Body),
|
|
1674
|
+
assertz(SessionId:(Head :- ExpandedBody)).
|
|
1591
1675
|
|
|
1592
1676
|
consult_process_term(Head, SessionId) :-
|
|
1593
1677
|
% Assert a fact
|
package/package.json
CHANGED
|
@@ -241,6 +241,7 @@ process_clause((:- Directive), SessionId) :-
|
|
|
241
241
|
%% Handle tool/2 with description: tool(Head, Description) :- Body
|
|
242
242
|
process_clause((tool(ToolHead, Description) :- Body), SessionId) :-
|
|
243
243
|
!,
|
|
244
|
+
(catch(expand_dict_dots(Body, ExpandedBody), _, fail) -> true ; ExpandedBody = Body),
|
|
244
245
|
extract_tool_schema(ToolHead, Description, ToolName, Schema),
|
|
245
246
|
assertz(session_user_tools(SessionId, ToolName)),
|
|
246
247
|
assertz(session_user_tool_schema(SessionId, ToolName, Schema)),
|
|
@@ -248,11 +249,12 @@ process_clause((tool(ToolHead, Description) :- Body), SessionId) :-
|
|
|
248
249
|
format(string(SourceCode), "tool(~w, ~q) :-~n ~w.", [ToolHead, Description, Body]),
|
|
249
250
|
assertz(SessionId:tool_source(ToolName, SourceCode)),
|
|
250
251
|
% Assert the tool implementation (use just ToolHead for execution)
|
|
251
|
-
assertz(SessionId:(tool(ToolHead) :-
|
|
252
|
+
assertz(SessionId:(tool(ToolHead) :- ExpandedBody)).
|
|
252
253
|
|
|
253
254
|
%% Handle tool/1 without description: tool(Head) :- Body
|
|
254
255
|
process_clause((tool(ToolHead) :- Body), SessionId) :-
|
|
255
256
|
!,
|
|
257
|
+
(catch(expand_dict_dots(Body, ExpandedBody), _, fail) -> true ; ExpandedBody = Body),
|
|
256
258
|
extract_tool_schema(ToolHead, none, ToolName, Schema),
|
|
257
259
|
assertz(session_user_tools(SessionId, ToolName)),
|
|
258
260
|
assertz(session_user_tool_schema(SessionId, ToolName, Schema)),
|
|
@@ -260,17 +262,86 @@ process_clause((tool(ToolHead) :- Body), SessionId) :-
|
|
|
260
262
|
format(string(SourceCode), "tool(~w) :-~n ~w.", [ToolHead, Body]),
|
|
261
263
|
assertz(SessionId:tool_source(ToolName, SourceCode)),
|
|
262
264
|
% Assert the tool implementation
|
|
263
|
-
assertz(SessionId:(tool(ToolHead) :-
|
|
265
|
+
assertz(SessionId:(tool(ToolHead) :- ExpandedBody)).
|
|
264
266
|
|
|
265
267
|
process_clause((Head :- Body), SessionId) :-
|
|
266
268
|
!,
|
|
267
|
-
%
|
|
268
|
-
|
|
269
|
+
% Expand dict dot-notation (Dict.Key → get_dict), then assert
|
|
270
|
+
( catch(expand_dict_dots(Body, ExpandedBody), _, fail)
|
|
271
|
+
-> true
|
|
272
|
+
; ExpandedBody = Body
|
|
273
|
+
),
|
|
274
|
+
assertz(SessionId:(Head :- ExpandedBody)).
|
|
269
275
|
|
|
270
276
|
process_clause(Fact, SessionId) :-
|
|
271
277
|
% Simple fact
|
|
272
278
|
assertz(SessionId:Fact).
|
|
273
279
|
|
|
280
|
+
%% ============================================================
|
|
281
|
+
%% Dict Dot-Notation Expansion (compile-time)
|
|
282
|
+
%% ============================================================
|
|
283
|
+
%% SWI-Prolog's dict functional notation (Dict.Key) is normally
|
|
284
|
+
%% expanded by goal_expansion during compilation. Since DML clauses
|
|
285
|
+
%% are loaded via assertz (no goal expansion), we must expand
|
|
286
|
+
%% Dict.Key → get_dict(Key, Dict, Value) manually before asserting.
|
|
287
|
+
%%
|
|
288
|
+
%% Handles:
|
|
289
|
+
%% Dict.Key = Value → get_dict(Key, Dict, Value)
|
|
290
|
+
%% Value = Dict.Key → get_dict(Key, Dict, Value)
|
|
291
|
+
%% Dict.Key == Value → get_dict(Key, Dict, Tmp), Tmp == Value
|
|
292
|
+
%% Value == Dict.Key → get_dict(Key, Dict, Tmp), Tmp == Value
|
|
293
|
+
|
|
294
|
+
%% expand_dict_dots(+GoalIn, -GoalOut)
|
|
295
|
+
%% Top-level expansion for goal bodies
|
|
296
|
+
expand_dict_dots(Var, Var) :- var(Var), !.
|
|
297
|
+
expand_dict_dots((A, B), (EA, EB)) :- !, expand_dict_dots(A, EA), expand_dict_dots(B, EB).
|
|
298
|
+
expand_dict_dots((A ; B), (EA ; EB)) :- !, expand_dict_dots(A, EA), expand_dict_dots(B, EB).
|
|
299
|
+
expand_dict_dots((A -> B), (EA -> EB)) :- !, expand_dict_dots(A, EA), expand_dict_dots(B, EB).
|
|
300
|
+
|
|
301
|
+
%% Unification with dict dot access: Dict.Key = Value
|
|
302
|
+
expand_dict_dots(Goal, Result) :-
|
|
303
|
+
nonvar(Goal),
|
|
304
|
+
functor(Goal, =, 2),
|
|
305
|
+
!,
|
|
306
|
+
arg(1, Goal, A),
|
|
307
|
+
arg(2, Goal, B),
|
|
308
|
+
( nonvar(A), is_dot_access(A, Dict, Key)
|
|
309
|
+
-> Result = get_dict(Key, Dict, B)
|
|
310
|
+
; nonvar(B), is_dot_access(B, Dict, Key)
|
|
311
|
+
-> Result = get_dict(Key, Dict, A)
|
|
312
|
+
; Result = Goal
|
|
313
|
+
).
|
|
314
|
+
|
|
315
|
+
%% Equality check with dict dot access: Dict.Key == Value
|
|
316
|
+
expand_dict_dots(Goal, Result) :-
|
|
317
|
+
nonvar(Goal),
|
|
318
|
+
functor(Goal, ==, 2),
|
|
319
|
+
!,
|
|
320
|
+
arg(1, Goal, A),
|
|
321
|
+
arg(2, Goal, B),
|
|
322
|
+
( nonvar(A), is_dot_access(A, Dict, Key)
|
|
323
|
+
-> Result = (get_dict(Key, Dict, Tmp), Tmp == B)
|
|
324
|
+
; nonvar(B), is_dot_access(B, Dict, Key)
|
|
325
|
+
-> Result = (get_dict(Key, Dict, Tmp), Tmp == A)
|
|
326
|
+
; Result = Goal
|
|
327
|
+
).
|
|
328
|
+
|
|
329
|
+
expand_dict_dots(Goal, Goal).
|
|
330
|
+
|
|
331
|
+
%% is_dot_access(+Term, -Dict, -Key)
|
|
332
|
+
%% Check if Term is a dict dot-access expression: '.'(Dict, Key) where Key is atom
|
|
333
|
+
is_dot_access(Term, Dict, Key) :-
|
|
334
|
+
compound(Term),
|
|
335
|
+
compound_name_arity(Term, '.', 2),
|
|
336
|
+
arg(1, Term, Dict),
|
|
337
|
+
arg(2, Term, Key),
|
|
338
|
+
atom(Key).
|
|
339
|
+
|
|
340
|
+
%% expand_dict_expr(+ExprIn, -ExprOut)
|
|
341
|
+
%% Expand dict access in value-level expressions (just pass through for now)
|
|
342
|
+
expand_dict_expr(Var, Var) :- var(Var), !.
|
|
343
|
+
expand_dict_expr(Expr, Expr).
|
|
344
|
+
|
|
274
345
|
%% ============================================================
|
|
275
346
|
%% Tool Schema Extraction
|
|
276
347
|
%% ============================================================
|
|
@@ -560,6 +631,12 @@ set_context_stack(StateIn, Stack, StateOut) :-
|
|
|
560
631
|
set_memory(StateIn, Memory, StateOut) :-
|
|
561
632
|
StateOut = StateIn.put(memory, Memory).
|
|
562
633
|
|
|
634
|
+
%% is_system_memory_message(+Message)
|
|
635
|
+
%% True if the memory message has role=system
|
|
636
|
+
is_system_memory_message(Message) :-
|
|
637
|
+
is_dict(Message),
|
|
638
|
+
get_dict(role, Message, system).
|
|
639
|
+
|
|
563
640
|
%% ============================================================
|
|
564
641
|
%% Tool Scope Helpers
|
|
565
642
|
%% ============================================================
|
|
@@ -928,8 +1005,11 @@ mi_call(task(Desc), StateIn, StateOut) :-
|
|
|
928
1005
|
),
|
|
929
1006
|
% Use full messages from agent loop result
|
|
930
1007
|
( get_dict(messages, Result, Messages), Messages \= []
|
|
931
|
-
-> %
|
|
932
|
-
|
|
1008
|
+
-> % Preserve system messages from current memory (agent only returns user/assistant)
|
|
1009
|
+
get_memory(StateAfterAgent, OldMemory),
|
|
1010
|
+
include(is_system_memory_message, OldMemory, SystemMessages),
|
|
1011
|
+
append(SystemMessages, Messages, NewMemory),
|
|
1012
|
+
set_memory(StateAfterAgent, NewMemory, StateOut)
|
|
933
1013
|
; % Fallback: just add task description and response (old behavior)
|
|
934
1014
|
add_memory(StateAfterAgent, user, InterpDesc, State1),
|
|
935
1015
|
( get_dict(response, Result, Response), Response \= ""
|
|
@@ -1040,8 +1120,11 @@ mi_call_task_n(Desc, Vars, VarNames, StateIn, StateOut) :-
|
|
|
1040
1120
|
bind_task_variables(Result.variables, VarNames, Vars),
|
|
1041
1121
|
% Use full messages from agent loop result
|
|
1042
1122
|
( get_dict(messages, Result, Messages), Messages \= []
|
|
1043
|
-
-> %
|
|
1044
|
-
|
|
1123
|
+
-> % Preserve system messages from current memory (agent only returns user/assistant)
|
|
1124
|
+
get_memory(StateAfterAgent, OldMemory),
|
|
1125
|
+
include(is_system_memory_message, OldMemory, SystemMessages),
|
|
1126
|
+
append(SystemMessages, Messages, NewMemory),
|
|
1127
|
+
set_memory(StateAfterAgent, NewMemory, StateOut)
|
|
1045
1128
|
; % Fallback: just add task description and response (old behavior)
|
|
1046
1129
|
add_memory(StateAfterAgent, user, InterpDesc, State1),
|
|
1047
1130
|
( get_dict(response, Result, Response), Response \= ""
|
|
@@ -1585,9 +1668,10 @@ consult_process_term((tool(ToolHead) :- Body), SessionId) :-
|
|
|
1585
1668
|
assertz(SessionId:(tool(ToolHead) :- Body)).
|
|
1586
1669
|
|
|
1587
1670
|
consult_process_term((Head :- Body), SessionId) :-
|
|
1588
|
-
%
|
|
1671
|
+
% Expand dict dot-notation, then assert
|
|
1589
1672
|
!,
|
|
1590
|
-
|
|
1673
|
+
(catch(expand_dict_dots(Body, ExpandedBody), _, fail) -> true ; ExpandedBody = Body),
|
|
1674
|
+
assertz(SessionId:(Head :- ExpandedBody)).
|
|
1591
1675
|
|
|
1592
1676
|
consult_process_term(Head, SessionId) :-
|
|
1593
1677
|
% Assert a fact
|