deepclause-sdk 0.0.87 → 0.0.89

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 (42) hide show
  1. package/README.md +2 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +2 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/judge/index.d.ts +9 -0
  7. package/dist/judge/index.d.ts.map +1 -0
  8. package/dist/judge/index.js +6 -0
  9. package/dist/judge/index.js.map +1 -0
  10. package/dist/judge/jev.d.ts +21 -0
  11. package/dist/judge/jev.d.ts.map +1 -0
  12. package/dist/judge/jev.js +218 -0
  13. package/dist/judge/jev.js.map +1 -0
  14. package/dist/judge/llm.d.ts +23 -0
  15. package/dist/judge/llm.d.ts.map +1 -0
  16. package/dist/judge/llm.js +120 -0
  17. package/dist/judge/llm.js.map +1 -0
  18. package/dist/judge/marshal.d.ts +26 -0
  19. package/dist/judge/marshal.d.ts.map +1 -0
  20. package/dist/judge/marshal.js +266 -0
  21. package/dist/judge/marshal.js.map +1 -0
  22. package/dist/judge/mock.d.ts +28 -0
  23. package/dist/judge/mock.d.ts.map +1 -0
  24. package/dist/judge/mock.js +98 -0
  25. package/dist/judge/mock.js.map +1 -0
  26. package/dist/judge/types.d.ts +95 -0
  27. package/dist/judge/types.d.ts.map +1 -0
  28. package/dist/judge/types.js +23 -0
  29. package/dist/judge/types.js.map +1 -0
  30. package/dist/prolog-src/deepclause_mi.pl +224 -1
  31. package/dist/runner.d.ts +12 -0
  32. package/dist/runner.d.ts.map +1 -1
  33. package/dist/runner.js +158 -0
  34. package/dist/runner.js.map +1 -1
  35. package/dist/sdk.d.ts.map +1 -1
  36. package/dist/sdk.js +55 -0
  37. package/dist/sdk.js.map +1 -1
  38. package/dist/system/assets/docs/DML_REFERENCE.md +82 -1
  39. package/dist/types.d.ts +28 -0
  40. package/dist/types.d.ts.map +1 -1
  41. package/package.json +1 -1
  42. package/src/prolog-src/deepclause_mi.pl +224 -1
@@ -24,6 +24,7 @@
24
24
  post_exec_result/3,
25
25
  post_sample_token_result/3,
26
26
  post_llm_result/3,
27
+ post_judgment_result/3,
27
28
  provide_input/2,
28
29
  mi/3,
29
30
  % Tool engine predicates for isolated tool execution
@@ -50,6 +51,7 @@
50
51
  :- dynamic session_exec_result/2. % session_exec_result(SessionId, Result)
51
52
  :- dynamic session_sample_token_result/2. % session_sample_token_result(SessionId, Result)
52
53
  :- dynamic session_llm_result/2. % session_llm_result(SessionId, Result)
54
+ :- dynamic session_judgment_result/2. % session_judgment_result(SessionId, Result)
53
55
  :- dynamic session_trace_log/2. % session_trace_log(SessionId, TraceLog) - accumulated trace entries
54
56
  :- dynamic session_trace_enabled/2. % session_trace_enabled(SessionId, true/false)
55
57
  :- dynamic session_pending_signal/2. % session_pending_signal(SessionId, Signal) - fallback for engine_fetch
@@ -576,6 +578,7 @@ process_engine_result(request_sample_token(Prompt, Allowed), request_sample_toke
576
578
  payload{prompt: Prompt, allowedTokens: Allowed}) :- !.
577
579
  process_engine_result(request_llm(Messages), request_llm, '',
578
580
  payload{messages: Messages}) :- !.
581
+ process_engine_result(request_judgment(Payload), request_judgment, '', Payload) :- !.
579
582
  %% Tool result from inline tool execution
580
583
  process_engine_result(tool_result(Result), tool_result, '',
581
584
  payload{result: Result}) :- !.
@@ -599,6 +602,7 @@ destroy_engine(SessionId) :-
599
602
  retractall(session_exec_result(SessionId, _)),
600
603
  retractall(session_sample_token_result(SessionId, _)),
601
604
  retractall(session_llm_result(SessionId, _)),
605
+ retractall(session_judgment_result(SessionId, _)),
602
606
  retractall(session_trace_log(SessionId, _)),
603
607
  retractall(session_trace_enabled(SessionId, _)),
604
608
  ( current_module(SessionId)
@@ -645,6 +649,17 @@ post_sample_token_result(SessionId, Status, TokenOrError) :-
645
649
  assertz(session_sample_token_result(SessionId, result{status: Status, token: TokenOrError})),
646
650
  post_signal_to_engine(SessionId, sample_token_done).
647
651
 
652
+ %% post_judgment_result(+SessionId, +Status, +ValuesOrError)
653
+ %% On success Values is the list of answer values in question order.
654
+ post_judgment_result(SessionId, success, Values) :-
655
+ retractall(session_judgment_result(SessionId, _)),
656
+ assertz(session_judgment_result(SessionId, result{status: success, values: Values})),
657
+ post_signal_to_engine(SessionId, judgment_done).
658
+ post_judgment_result(SessionId, failure, Error) :-
659
+ retractall(session_judgment_result(SessionId, _)),
660
+ assertz(session_judgment_result(SessionId, result{status: failure, error: Error})),
661
+ post_signal_to_engine(SessionId, judgment_done).
662
+
648
663
  %% post_llm_result(+SessionId, +Status, +TextOrError)
649
664
  post_llm_result(SessionId, Status, TextOrError) :-
650
665
  retractall(session_llm_result(SessionId, _)),
@@ -1042,6 +1057,7 @@ process_tool_engine_result(request_sample_token(Prompt, Allowed), request_sample
1042
1057
  payload{prompt: Prompt, allowedTokens: Allowed}) :- !.
1043
1058
  process_tool_engine_result(request_llm(Messages), request_llm, '',
1044
1059
  payload{messages: Messages}) :- !.
1060
+ process_tool_engine_result(request_judgment(Payload), request_judgment, '', Payload) :- !.
1045
1061
  process_tool_engine_result(request_agent_loop(Desc, Vars, Tools, Memory, ToolScope, ReasoningEffort, RecipeContext), request_agent_loop, '',
1046
1062
  payload{taskDescription: Desc, outputVars: Vars, userTools: Tools, memory: Memory, toolScope: ToolScope, reasoningEffort: ReasoningEffort, recipeContext: RecipeContext}) :- !.
1047
1063
  %% Legacy 5-arg format (no reasoning/recipe)
@@ -1313,6 +1329,175 @@ wait_sample_token_signal(SessionId) :-
1313
1329
  ; wait_sample_token_signal(SessionId)
1314
1330
  ).
1315
1331
 
1332
+ %% ============================================================
1333
+ %% Semantic Judgment Predicates
1334
+ %% ============================================================
1335
+ %% judge/2 asks one batch of typed questions about an explicit state and binds
1336
+ %% the answers into output variables carried by the spec terms. The one-off
1337
+ %% predicates are sugar over the same request.
1338
+ %%
1339
+ %% judge(Message, [
1340
+ %% choose("Which team?", [billing, orders, account]) - Team,
1341
+ %% rate("How frustrated?", [calm, frustrated, angry]) - Frustration,
1342
+ %% verify("Does it ask for a refund?") - Refund
1343
+ %% ]).
1344
+ %%
1345
+ %% Backends (llm, jev, mock) are selected with with_judgment/2, the workspace
1346
+ %% configuration, or a per-run override. require_judgment/2 gates a goal on a
1347
+ %% backend capability such as calibrated.
1348
+
1349
+ mi_call(judge(State, Specs), StateIn, StateOut) :-
1350
+ !,
1351
+ mi_call_judgment(State, Specs, StateIn, StateOut).
1352
+
1353
+ mi_call(choose(State, Question, Options, Choice), StateIn, StateOut) :-
1354
+ !,
1355
+ mi_call_judgment(State, [choose(Question, Options) - Choice], StateIn, StateOut).
1356
+
1357
+ mi_call(rate(State, Question, Levels, Level), StateIn, StateOut) :-
1358
+ !,
1359
+ mi_call_judgment(State, [rate(Question, Levels) - Level], StateIn, StateOut).
1360
+
1361
+ mi_call(verify(State, Question, Truth), StateIn, StateOut) :-
1362
+ !,
1363
+ mi_call_judgment(State, [verify(Question) - Truth], StateIn, StateOut).
1364
+
1365
+ mi_call(probability(State, Question, Probability), StateIn, StateOut) :-
1366
+ !,
1367
+ mi_call_judgment(State, [probability(Question) - Probability], StateIn, StateOut).
1368
+
1369
+ mi_call(holds(State, Question), StateIn, StateOut) :-
1370
+ !,
1371
+ mi_call_judgment(State, [verify(Question) - Truth], StateIn, StateOut),
1372
+ ( Truth == yes
1373
+ -> true
1374
+ ; fail
1375
+ ).
1376
+
1377
+ mi_call(holds(State, Question, Threshold), StateIn, StateOut) :-
1378
+ !,
1379
+ mi_call_judgment(State, [probability(Question) - Probability], StateIn, StateOut),
1380
+ ( number(Probability), Probability >= Threshold
1381
+ -> true
1382
+ ; fail
1383
+ ).
1384
+
1385
+ mi_call(with_judgment(Backend, Goal), StateIn, StateOut) :-
1386
+ !,
1387
+ set_judge_backend(StateIn, Backend, ScopedState),
1388
+ mi_call(Goal, ScopedState, StateWithScope),
1389
+ clear_judge_backend(StateWithScope, StateOut).
1390
+
1391
+ mi_call(require_judgment(Capability, Goal), StateIn, StateOut) :-
1392
+ !,
1393
+ push_required_judgment(StateIn, Capability, ScopedState),
1394
+ mi_call(Goal, ScopedState, StateWithScope),
1395
+ pop_required_judgment(StateWithScope, StateOut).
1396
+
1397
+ %% mi_call_judgment(+State, +Specs, +StateIn, -StateOut)
1398
+ mi_call_judgment(State, Specs, StateIn, StateOut) :-
1399
+ consume_gas(StateIn, State1),
1400
+ get_session_id(SessionId),
1401
+ get_depth(State1, Depth),
1402
+ split_specs(Specs, Questions, Outputs),
1403
+ length(Questions, Count),
1404
+ add_trace_entry(SessionId, llm_call, judgment, [Count], Depth),
1405
+ get_judge_backend(State1, Backend),
1406
+ get_required_judgments(State1, Requires),
1407
+ engine_yield(request_judgment(payload{
1408
+ state: State,
1409
+ questions: Questions,
1410
+ backend: Backend,
1411
+ requires: Requires
1412
+ })),
1413
+ wait_judgment_signal(SessionId),
1414
+ ( session_judgment_result(SessionId, Result)
1415
+ -> retract(session_judgment_result(SessionId, _)),
1416
+ ( Result.status == success
1417
+ -> add_trace_with_result(SessionId, exit, judgment, [Count], Result.values, Depth),
1418
+ bind_judgment_outputs(Outputs, Result.values),
1419
+ StateOut = State1
1420
+ ; ( get_dict(error, Result, ErrorMsg), ErrorMsg \= ""
1421
+ -> format(atom(WarnMsg), 'Warning: judgment failed: ~w', [ErrorMsg])
1422
+ ; format(atom(WarnMsg), 'Warning: judgment failed (status=~w)', [Result.status])
1423
+ ),
1424
+ add_trace_entry(SessionId, fail, judgment, [Count], Depth),
1425
+ engine_yield(output(WarnMsg)),
1426
+ fail
1427
+ )
1428
+ ; add_trace_entry(SessionId, fail, judgment, [Count], Depth),
1429
+ engine_yield(output('Warning: judgment failed (no result returned)')),
1430
+ fail
1431
+ ).
1432
+
1433
+ wait_judgment_signal(SessionId) :-
1434
+ get_next_signal(SessionId, Signal),
1435
+ ( Signal == judgment_done
1436
+ -> true
1437
+ ; Signal = error_signal(_)
1438
+ -> true
1439
+ ; wait_judgment_signal(SessionId)
1440
+ ).
1441
+
1442
+ %% split_specs(+Specs, -Questions, -Outputs)
1443
+ %% Each spec is `Question - Output`. Outputs are bound after the batch.
1444
+ split_specs([], [], []).
1445
+ split_specs([Spec-Output|Rest], [Question|Questions], [Output|Outputs]) :-
1446
+ spec_question(Spec, Question),
1447
+ split_specs(Rest, Questions, Outputs).
1448
+
1449
+ spec_question(choose(Instruction, Options),
1450
+ question{kind: choose, instruction: Instruction, options: Options}).
1451
+ spec_question(rate(Instruction, Levels),
1452
+ question{kind: rate, instruction: Instruction, levels: Levels}).
1453
+ spec_question(verify(Instruction),
1454
+ question{kind: verify, instruction: Instruction}).
1455
+ spec_question(verify(Instruction, Criteria),
1456
+ question{kind: verify, instruction: Instruction, criteria: Criteria}).
1457
+ spec_question(probability(Instruction),
1458
+ question{kind: probability, instruction: Instruction}).
1459
+
1460
+ bind_judgment_outputs([], []).
1461
+ bind_judgment_outputs([Output|Outputs], [Value|Values]) :-
1462
+ Output = Value,
1463
+ bind_judgment_outputs(Outputs, Values).
1464
+
1465
+ %% get_judge_backend(+State, -Backend)
1466
+ get_judge_backend(State, Backend) :-
1467
+ ( get_dict(judge_backend, State, Scoped)
1468
+ -> Backend = Scoped
1469
+ ; Backend = default
1470
+ ).
1471
+
1472
+ set_judge_backend(StateIn, Backend, StateOut) :-
1473
+ StateOut = StateIn.put(judge_backend, Backend).
1474
+
1475
+ clear_judge_backend(StateIn, StateOut) :-
1476
+ ( get_dict(judge_backend, StateIn, _)
1477
+ -> del_dict(judge_backend, StateIn, _, StateOut)
1478
+ ; StateOut = StateIn
1479
+ ).
1480
+
1481
+ get_required_judgments(State, Requires) :-
1482
+ ( get_dict(judgment_requires, State, Requires)
1483
+ -> true
1484
+ ; Requires = []
1485
+ ).
1486
+
1487
+ push_required_judgment(StateIn, Capability, StateOut) :-
1488
+ get_required_judgments(StateIn, Existing),
1489
+ ( member(Capability, Existing)
1490
+ -> StateOut = StateIn
1491
+ ; append(Existing, [Capability], Updated),
1492
+ StateOut = StateIn.put(judgment_requires, Updated)
1493
+ ).
1494
+
1495
+ pop_required_judgment(StateIn, StateOut) :-
1496
+ ( get_dict(judgment_requires, StateIn, _)
1497
+ -> del_dict(judgment_requires, StateIn, _, StateOut)
1498
+ ; StateOut = StateIn
1499
+ ).
1500
+
1316
1501
  mi_call(llm(Messages, Reply), StateIn, StateOut) :-
1317
1502
  !,
1318
1503
  consume_gas(StateIn, State1),
@@ -1687,6 +1872,28 @@ mi_call(fail, _StateIn, _StateOut) :-
1687
1872
  mi_call(false, _StateIn, _StateOut) :-
1688
1873
  fail.
1689
1874
 
1875
+ %% mi_call(assertz(Head), +StateIn, -StateOut)
1876
+ %% mi_call(asserta(Head), +StateIn, -StateOut)
1877
+ %% mi_call(retract(Head), +StateIn, -StateOut)
1878
+ %% mi_call(retractall(Head), +StateIn, -StateOut)
1879
+ %% Database predicates must operate on the session module so DML-side facts
1880
+ %% (draft/4, claim/3, ...) are asserted/retracted in the right module.
1881
+ mi_call(assertz(Head), StateIn, StateIn) :-
1882
+ get_session_id(SessionId),
1883
+ assertz(SessionId:Head).
1884
+
1885
+ mi_call(asserta(Head), StateIn, StateIn) :-
1886
+ get_session_id(SessionId),
1887
+ asserta(SessionId:Head).
1888
+
1889
+ mi_call(retract(Head), StateIn, StateIn) :-
1890
+ get_session_id(SessionId),
1891
+ retract(SessionId:Head).
1892
+
1893
+ mi_call(retractall(Head), StateIn, StateIn) :-
1894
+ get_session_id(SessionId),
1895
+ retractall(SessionId:Head).
1896
+
1690
1897
  %% ============================================================
1691
1898
  %% List Predicates - Interpreted for proper state threading
1692
1899
  %% ============================================================
@@ -2183,6 +2390,16 @@ is_mi_special_predicate(without_tools(_,_)).
2183
2390
  is_mi_special_predicate(with_reasoning(_,_)).
2184
2391
  %% Recipe context scoping
2185
2392
  is_mi_special_predicate(with_recipe(_,_)).
2393
+ %% Semantic judgment predicates
2394
+ is_mi_special_predicate(judge(_,_)).
2395
+ is_mi_special_predicate(choose(_,_,_,_)).
2396
+ is_mi_special_predicate(rate(_,_,_,_)).
2397
+ is_mi_special_predicate(verify(_,_,_)).
2398
+ is_mi_special_predicate(probability(_,_,_)).
2399
+ is_mi_special_predicate(holds(_,_)).
2400
+ is_mi_special_predicate(holds(_,_,_)).
2401
+ is_mi_special_predicate(with_judgment(_,_)).
2402
+ is_mi_special_predicate(require_judgment(_,_)).
2186
2403
  %% Context stack management
2187
2404
  is_mi_special_predicate(get_memory(_)).
2188
2405
  is_mi_special_predicate(push_context).
@@ -2201,6 +2418,10 @@ is_mi_special_predicate(!).
2201
2418
  is_mi_special_predicate(true).
2202
2419
  is_mi_special_predicate(fail).
2203
2420
  is_mi_special_predicate(false).
2421
+ is_mi_special_predicate(assertz(_)).
2422
+ is_mi_special_predicate(asserta(_)).
2423
+ is_mi_special_predicate(retract(_)).
2424
+ is_mi_special_predicate(retractall(_)).
2204
2425
  is_mi_special_predicate(_:_).
2205
2426
  %% List predicates
2206
2427
  is_mi_special_predicate(member(_,_)).
@@ -2305,8 +2526,10 @@ mi_call_dispatch(Goal, StateIn, StateOut) :-
2305
2526
  clause(SessionId:Goal, Body),
2306
2527
  NewDepth is Depth + 1,
2307
2528
  set_depth(StateIn, NewDepth, State1),
2529
+ % Soft cut: execute the body for every solution (so findall/backtracking
2530
+ % works), but still record a fail trace when the body has none.
2308
2531
  ( mi_call(Body, State1, State2)
2309
- -> add_trace_entry(SessionId, exit, Functor, Args, Depth),
2532
+ *-> add_trace_entry(SessionId, exit, Functor, Args, Depth),
2310
2533
  set_depth(State2, Depth, StateOut)
2311
2534
  ; add_trace_entry(SessionId, fail, Functor, Args, Depth),
2312
2535
  fail
package/dist/runner.d.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import type { SWIPLModule } from './prolog/loader.js';
5
5
  import type { CompactionOptions, DMLEvent, MemoryMessage, LLMBackend, ToolDefinition, ToolPolicy, TypedVar } from './types.js';
6
+ import type { JudgeSelection } from './judge/types.js';
6
7
  import { type ReasoningType } from './system/config/model-database.js';
7
8
  export declare function decodeAgentOutputVars(rawOutputVars: unknown): (string | TypedVar)[];
8
9
  export interface RunnerOptions {
@@ -20,6 +21,7 @@ export interface RunnerOptions {
20
21
  reasoningBudgetMap?: Record<string, number>;
21
22
  contextWindow?: number;
22
23
  llmBackend?: LLMBackend;
24
+ judgeSelection?: JudgeSelection;
23
25
  }
24
26
  export interface InternalRunOptions {
25
27
  args?: unknown[];
@@ -32,6 +34,8 @@ export interface InternalRunOptions {
32
34
  signal?: AbortSignal;
33
35
  initialMessages?: MemoryMessage[];
34
36
  compaction?: CompactionOptions;
37
+ /** Per-run default judgment backend name override. */
38
+ judgeBackend?: string;
35
39
  }
36
40
  /**
37
41
  * DML execution engine
@@ -48,6 +52,7 @@ export declare class DMLRunner {
48
52
  private sessionId;
49
53
  private currentMemory;
50
54
  private stepCounter;
55
+ private judgeCache;
51
56
  constructor(swipl: SWIPLModule, options: RunnerOptions);
52
57
  /**
53
58
  * Get the current conversation memory
@@ -98,6 +103,13 @@ export declare class DMLRunner {
98
103
  * Handle direct one-shot LLM request (llm/2)
99
104
  */
100
105
  private handleLlm;
106
+ /**
107
+ * Handle a semantic judgment request (judge/2 and the one-off predicates).
108
+ */
109
+ private handleJudgment;
110
+ private parseJudgmentPayload;
111
+ private completeJudgment;
112
+ private postJudgmentResult;
101
113
  /**
102
114
  * Handle exec request (exec() predicate)
103
115
  */
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
package/dist/runner.js CHANGED
@@ -5,6 +5,7 @@ import * as fs from 'fs/promises';
5
5
  import * as path from 'path';
6
6
  import { mountWorkspace } from './prolog/loader.js';
7
7
  import { runAgentLoop } from './agent.js';
8
+ import { judgeAnswersToValues, judgeCacheKey, normalizeJudgeState, parseJudgeQuestions, validateJudgeAnswers, valuesToPrologList } from './judge/marshal.js';
8
9
  import { executeCompactor, getCompactionBindings, resolveCompactionOptions, } from './compaction.js';
9
10
  import { buildToolCompletionEvent, buildToolFailureEvent, buildToolStartEvent, } from './system/runtime/shell-tool-events.js';
10
11
  import { checkToolPolicy } from './tools.js';
@@ -145,6 +146,7 @@ export class DMLRunner {
145
146
  sessionId = '';
146
147
  currentMemory = [];
147
148
  stepCounter = 0;
149
+ judgeCache = new Map();
148
150
  constructor(swipl, options) {
149
151
  this.swipl = swipl;
150
152
  this.options = options;
@@ -162,6 +164,7 @@ export class DMLRunner {
162
164
  // Generate unique session ID
163
165
  this.sessionId = `sess_${Date.now()}_${Math.random().toString(36).slice(2)}`;
164
166
  const memoryId = `mem_${this.sessionId}`; // Kept for API compatibility
167
+ this.judgeCache.clear();
165
168
  try {
166
169
  // Mount workspace if path provided
167
170
  if (options.workspacePath) {
@@ -243,6 +246,9 @@ export class DMLRunner {
243
246
  case 'request_llm':
244
247
  yield* this.handleLlm(step.payload, options);
245
248
  break;
249
+ case 'request_judgment':
250
+ yield* this.handleJudgment(step.payload, options);
251
+ break;
246
252
  case 'wait_input':
247
253
  // Request user input
248
254
  yield { type: 'input_required', prompt: step.prompt };
@@ -739,6 +745,115 @@ export class DMLRunner {
739
745
  yield { type: 'task_activity', taskState: succeeded ? 'completed' : 'failed', taskId: stepId };
740
746
  }
741
747
  }
748
+ /**
749
+ * Handle a semantic judgment request (judge/2 and the one-off predicates).
750
+ */
751
+ async *handleJudgment(payload, options) {
752
+ const parsed = this.parseJudgmentPayload(payload);
753
+ const ids = parsed.questions.map((question) => question.id);
754
+ const backendName = parsed.requestedName === 'default'
755
+ ? options.judgeBackend ?? this.options.judgeSelection?.defaultName ?? 'llm'
756
+ : parsed.requestedName;
757
+ const stepId = `judge_${this.stepCounter++}`;
758
+ yield {
759
+ type: 'task_activity',
760
+ taskState: 'started',
761
+ taskDescription: `judge[${backendName}]: ${ids.join(', ')}`,
762
+ taskId: stepId,
763
+ judgeBackend: backendName,
764
+ judgeQuestionIds: ids,
765
+ judgeState: 'started',
766
+ };
767
+ const result = await this.completeJudgment(parsed, { signal: options.signal, judgeBackend: options.judgeBackend });
768
+ if (result.error) {
769
+ this.postJudgmentResult({ success: false, error: result.error });
770
+ yield { type: 'log', content: `judgment failed: ${result.error}` };
771
+ }
772
+ else {
773
+ this.postJudgmentResult({ success: true, values: result.values ?? [] });
774
+ if (result.usage) {
775
+ yield {
776
+ type: 'usage',
777
+ usage: {
778
+ inputTokens: result.usage.inputTokens,
779
+ outputTokens: result.usage.outputTokens,
780
+ totalTokens: result.usage.totalTokens ?? result.usage.inputTokens + result.usage.outputTokens,
781
+ },
782
+ usageSource: 'judge',
783
+ usageModel: result.usageModel,
784
+ };
785
+ }
786
+ }
787
+ yield {
788
+ type: 'task_activity',
789
+ taskState: result.error ? 'failed' : 'completed',
790
+ taskId: stepId,
791
+ judgeBackend: result.backendName,
792
+ judgeQuestionIds: result.ids,
793
+ judgeState: result.error ? 'failed' : 'completed',
794
+ };
795
+ }
796
+ parseJudgmentPayload(payload) {
797
+ const data = (payload ?? {});
798
+ return {
799
+ questions: parseJudgeQuestions(data.questions),
800
+ state: normalizeJudgeState(data.state),
801
+ requiredCapabilities: Array.isArray(data.requires) ? data.requires.map(String) : [],
802
+ requestedName: typeof data.backend === 'string' ? data.backend : 'default',
803
+ };
804
+ }
805
+ async completeJudgment(parsed, context) {
806
+ const selection = this.options.judgeSelection;
807
+ const defaultName = context.judgeBackend ?? selection?.defaultName ?? 'llm';
808
+ const backendName = parsed.requestedName === 'default' ? defaultName : parsed.requestedName;
809
+ const ids = parsed.questions.map((question) => question.id);
810
+ try {
811
+ const backend = selection?.backends.get(backendName);
812
+ if (!backend)
813
+ throw new Error(`Unknown judgment backend: ${backendName}`);
814
+ const missing = parsed.requiredCapabilities.filter((capability) => !backend.capabilities[capability]);
815
+ if (missing.length > 0) {
816
+ throw new Error(`Judgment backend '${backendName}' lacks required capabilities: ${missing.join(', ')}`);
817
+ }
818
+ const model = this.options.model;
819
+ const key = judgeCacheKey(backend.id, model, parsed.state, parsed.questions);
820
+ const cached = this.judgeCache.get(key);
821
+ if (cached) {
822
+ return { backendName, ids, values: judgeAnswersToValues(parsed.questions, cached) };
823
+ }
824
+ const response = await backend.complete({
825
+ state: parsed.state,
826
+ questions: parsed.questions,
827
+ signal: context.signal,
828
+ model,
829
+ requiredCapabilities: parsed.requiredCapabilities,
830
+ });
831
+ const answers = validateJudgeAnswers(parsed.questions, response.answers);
832
+ this.judgeCache.set(key, answers);
833
+ return {
834
+ backendName,
835
+ ids,
836
+ values: judgeAnswersToValues(parsed.questions, answers),
837
+ usage: response.usage,
838
+ usageModel: response.model ?? model,
839
+ };
840
+ }
841
+ catch (error) {
842
+ return {
843
+ backendName,
844
+ ids,
845
+ error: error instanceof Error ? error.message : String(error),
846
+ };
847
+ }
848
+ }
849
+ postJudgmentResult(result) {
850
+ if (result.success) {
851
+ this.query(`deepclause_mi:post_judgment_result('${this.sessionId}', success, ${valuesToPrologList(result.values ?? [])})`);
852
+ }
853
+ else {
854
+ this.query(`deepclause_mi:post_judgment_result('${this.sessionId}', failure, ${this.toPrologTerm(result.error ?? 'Unknown error')})`);
855
+ }
856
+ }
742
857
  /**
743
858
  * Handle exec request (exec() predicate)
744
859
  */
@@ -1145,6 +1260,49 @@ export class DMLRunner {
1145
1260
  }
1146
1261
  break;
1147
1262
  }
1263
+ case 'request_judgment': {
1264
+ const parsed = this.parseJudgmentPayload(payload);
1265
+ const nestedStepId = `judge_${this.stepCounter++}`;
1266
+ const nestedIds = parsed.questions.map((question) => question.id);
1267
+ onToolEvent?.({
1268
+ type: 'task_activity',
1269
+ taskState: 'started',
1270
+ taskDescription: `judge[${parsed.requestedName}]: ${nestedIds.join(', ')}`,
1271
+ taskId: nestedStepId,
1272
+ judgeBackend: parsed.requestedName,
1273
+ judgeQuestionIds: nestedIds,
1274
+ judgeState: 'started',
1275
+ });
1276
+ const judgeResult = await this.completeJudgment(parsed, { signal: runContext.signal, judgeBackend: undefined });
1277
+ if (judgeResult.error) {
1278
+ this.postJudgmentResult({ success: false, error: judgeResult.error });
1279
+ }
1280
+ else {
1281
+ this.postJudgmentResult({ success: true, values: judgeResult.values ?? [] });
1282
+ if (judgeResult.usage) {
1283
+ onToolEvent?.({
1284
+ type: 'usage',
1285
+ usage: {
1286
+ inputTokens: judgeResult.usage.inputTokens,
1287
+ outputTokens: judgeResult.usage.outputTokens,
1288
+ totalTokens: judgeResult.usage.totalTokens ??
1289
+ judgeResult.usage.inputTokens + judgeResult.usage.outputTokens,
1290
+ },
1291
+ usageSource: 'judge',
1292
+ usageModel: judgeResult.usageModel,
1293
+ });
1294
+ }
1295
+ }
1296
+ onToolEvent?.({
1297
+ type: 'task_activity',
1298
+ taskState: judgeResult.error ? 'failed' : 'completed',
1299
+ taskId: nestedStepId,
1300
+ judgeBackend: judgeResult.backendName,
1301
+ judgeQuestionIds: judgeResult.ids,
1302
+ judgeState: judgeResult.error ? 'failed' : 'completed',
1303
+ });
1304
+ break;
1305
+ }
1148
1306
  case 'request_agent_loop': {
1149
1307
  // Tool is calling task() or prompt() - run nested agent loop
1150
1308
  const taskDescription = String(payload?.taskDescription ?? '');