dominds 1.23.3 → 1.23.5
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/dialog.d.ts +20 -0
- package/dist/dialog.js +60 -0
- package/dist/llm/defaults.yaml +2 -0
- package/dist/llm/gen/anthropic.js +6 -2
- package/dist/llm/gen/mock.js +25 -7
- package/dist/llm/gen/openai-compatible.d.ts +2 -1
- package/dist/llm/gen/openai-compatible.js +87 -18
- package/dist/llm/gen.d.ts +12 -0
- package/dist/llm/kernel-driver/drive.js +105 -1
- package/dist/llm/kernel-driver/flow.js +37 -7
- package/dist/log.js +35 -2
- package/dist/persistence.d.ts +1 -0
- package/dist/persistence.js +24 -1
- package/dist/runtime/driver-messages.js +12 -8
- package/package.json +3 -3
package/dist/dialog.d.ts
CHANGED
|
@@ -354,6 +354,25 @@ export declare abstract class Dialog {
|
|
|
354
354
|
skipTaskdoc?: boolean;
|
|
355
355
|
sideDialogReplyTarget: DialogSideDialogReplyTarget;
|
|
356
356
|
}): DialogQueuedPromptState;
|
|
357
|
+
private persistPendingRuntimePrompt;
|
|
358
|
+
private runtimePromptCommon;
|
|
359
|
+
queueRuntimeReplyPrompt(options: {
|
|
360
|
+
prompt: string;
|
|
361
|
+
msgId: string;
|
|
362
|
+
grammar: 'markdown';
|
|
363
|
+
userLanguageCode?: LanguageCode;
|
|
364
|
+
tellaskReplyDirective: TellaskReplyDirective;
|
|
365
|
+
skipTaskdoc?: boolean;
|
|
366
|
+
}): Promise<DialogQueuedPromptState>;
|
|
367
|
+
queueRuntimeSideDialogPrompt(options: {
|
|
368
|
+
prompt: string;
|
|
369
|
+
msgId: string;
|
|
370
|
+
grammar: 'markdown';
|
|
371
|
+
userLanguageCode?: LanguageCode;
|
|
372
|
+
tellaskReplyDirective: TellaskReplyDirective;
|
|
373
|
+
skipTaskdoc?: boolean;
|
|
374
|
+
sideDialogReplyTarget: DialogSideDialogReplyTarget;
|
|
375
|
+
}): Promise<DialogQueuedPromptState>;
|
|
357
376
|
hasUpNext(): boolean;
|
|
358
377
|
peekUpNext(): DialogQueuedPromptState | undefined;
|
|
359
378
|
takeUpNext(): DialogQueuedPromptState | undefined;
|
|
@@ -678,6 +697,7 @@ export declare abstract class DialogStore {
|
|
|
678
697
|
* Start a new course in storage
|
|
679
698
|
*/
|
|
680
699
|
startNewCourse(_dialog: Dialog, _newCoursePrompt: DialogRuntimePrompt): Promise<void>;
|
|
700
|
+
persistPendingRuntimePrompt(_dialog: Dialog, _prompt: DialogRuntimePrompt): Promise<void>;
|
|
681
701
|
/**
|
|
682
702
|
* Handle stream error
|
|
683
703
|
*/
|
package/dist/dialog.js
CHANGED
|
@@ -1018,6 +1018,65 @@ class Dialog {
|
|
|
1018
1018
|
this._updatedAt = (0, time_1.formatUnifiedTimestamp)(new Date());
|
|
1019
1019
|
return merged;
|
|
1020
1020
|
}
|
|
1021
|
+
async persistPendingRuntimePrompt(prompt) {
|
|
1022
|
+
await this.dlgStore.persistPendingRuntimePrompt(this, prompt);
|
|
1023
|
+
}
|
|
1024
|
+
runtimePromptCommon(options) {
|
|
1025
|
+
const trimmed = options.prompt.trim();
|
|
1026
|
+
if (!trimmed) {
|
|
1027
|
+
throw new Error('Prompt is required to queue runtime prompt');
|
|
1028
|
+
}
|
|
1029
|
+
return {
|
|
1030
|
+
prompt: trimmed,
|
|
1031
|
+
msgId: options.msgId,
|
|
1032
|
+
grammar: options.grammar,
|
|
1033
|
+
userLanguageCode: options.userLanguageCode ?? this._lastUserLanguageCode,
|
|
1034
|
+
origin: 'runtime',
|
|
1035
|
+
runControl: undefined,
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
async queueRuntimeReplyPrompt(options) {
|
|
1039
|
+
const common = this.runtimePromptCommon(options);
|
|
1040
|
+
const created = {
|
|
1041
|
+
...common,
|
|
1042
|
+
kind: 'new_course_runtime_reply',
|
|
1043
|
+
tellaskReplyDirective: options.tellaskReplyDirective,
|
|
1044
|
+
skipTaskdoc: options.skipTaskdoc,
|
|
1045
|
+
};
|
|
1046
|
+
this.enqueueQueuedPromptState(created);
|
|
1047
|
+
await this.persistPendingRuntimePrompt({
|
|
1048
|
+
content: created.prompt,
|
|
1049
|
+
msgId: created.msgId,
|
|
1050
|
+
grammar: created.grammar ?? 'markdown',
|
|
1051
|
+
userLanguageCode: created.userLanguageCode,
|
|
1052
|
+
origin: 'runtime',
|
|
1053
|
+
tellaskReplyDirective: created.tellaskReplyDirective,
|
|
1054
|
+
skipTaskdoc: created.skipTaskdoc,
|
|
1055
|
+
});
|
|
1056
|
+
return created;
|
|
1057
|
+
}
|
|
1058
|
+
async queueRuntimeSideDialogPrompt(options) {
|
|
1059
|
+
const common = this.runtimePromptCommon(options);
|
|
1060
|
+
const created = {
|
|
1061
|
+
...common,
|
|
1062
|
+
kind: 'new_course_runtime_sideDialog',
|
|
1063
|
+
tellaskReplyDirective: options.tellaskReplyDirective,
|
|
1064
|
+
skipTaskdoc: options.skipTaskdoc,
|
|
1065
|
+
sideDialogReplyTarget: options.sideDialogReplyTarget,
|
|
1066
|
+
};
|
|
1067
|
+
this.enqueueQueuedPromptState(created);
|
|
1068
|
+
await this.persistPendingRuntimePrompt({
|
|
1069
|
+
content: created.prompt,
|
|
1070
|
+
msgId: created.msgId,
|
|
1071
|
+
grammar: created.grammar ?? 'markdown',
|
|
1072
|
+
userLanguageCode: created.userLanguageCode,
|
|
1073
|
+
origin: 'runtime',
|
|
1074
|
+
tellaskReplyDirective: created.tellaskReplyDirective,
|
|
1075
|
+
skipTaskdoc: created.skipTaskdoc,
|
|
1076
|
+
sideDialogReplyTarget: created.sideDialogReplyTarget,
|
|
1077
|
+
});
|
|
1078
|
+
return created;
|
|
1079
|
+
}
|
|
1021
1080
|
hasUpNext() {
|
|
1022
1081
|
return this._upNextQueue.length > 0;
|
|
1023
1082
|
}
|
|
@@ -1905,6 +1964,7 @@ class DialogStore {
|
|
|
1905
1964
|
* Start a new course in storage
|
|
1906
1965
|
*/
|
|
1907
1966
|
async startNewCourse(_dialog, _newCoursePrompt) { }
|
|
1967
|
+
async persistPendingRuntimePrompt(_dialog, _prompt) { }
|
|
1908
1968
|
/**
|
|
1909
1969
|
* Handle stream error
|
|
1910
1970
|
*/
|
package/dist/llm/defaults.yaml
CHANGED
|
@@ -581,6 +581,7 @@ providers:
|
|
|
581
581
|
context_window: '204K'
|
|
582
582
|
glm-5.1:
|
|
583
583
|
name: GLM-5.1
|
|
584
|
+
optimal_max_tokens: 180000
|
|
584
585
|
supports_thinking: true
|
|
585
586
|
default_thinking: true
|
|
586
587
|
supports_image_input: false
|
|
@@ -590,6 +591,7 @@ providers:
|
|
|
590
591
|
context_window: '256K'
|
|
591
592
|
glm-4.7:
|
|
592
593
|
name: GLM-4.7
|
|
594
|
+
optimal_max_tokens: 180000
|
|
593
595
|
supports_thinking: true
|
|
594
596
|
default_thinking: false
|
|
595
597
|
supports_image_input: false
|
|
@@ -1955,9 +1955,13 @@ class AnthropicGen {
|
|
|
1955
1955
|
completionTokens,
|
|
1956
1956
|
totalTokens: promptTokens + completionTokens,
|
|
1957
1957
|
};
|
|
1958
|
+
const messages = anthropicToChatMessages(response, genseq, forceJsonResponse ? ANTHROPIC_JSON_RESPONSE_TOOL_NAME : undefined);
|
|
1959
|
+
const orderedOutputs = outputs.length > 0
|
|
1960
|
+
? [...outputs, ...messages.map((message) => ({ kind: 'message', message }))]
|
|
1961
|
+
: [];
|
|
1958
1962
|
return {
|
|
1959
|
-
messages
|
|
1960
|
-
...(
|
|
1963
|
+
messages,
|
|
1964
|
+
...(orderedOutputs.length > 0 ? { outputs: orderedOutputs } : {}),
|
|
1961
1965
|
usage,
|
|
1962
1966
|
llmGenModel: returnedModel,
|
|
1963
1967
|
};
|
package/dist/llm/gen/mock.js
CHANGED
|
@@ -474,6 +474,10 @@ responses:
|
|
|
474
474
|
: `mock_func_${String(i + 1)}_${call.name}`;
|
|
475
475
|
await receiver.funcCall(callId, call.name, this.normalizeFuncCallArgs(call.arguments));
|
|
476
476
|
}
|
|
477
|
+
const invalidFuncCalls = matched?.invalidFuncCalls ?? [];
|
|
478
|
+
for (const call of invalidFuncCalls) {
|
|
479
|
+
await receiver.invalidFuncCall?.(call);
|
|
480
|
+
}
|
|
477
481
|
return { usage, llmGenModel: modelName };
|
|
478
482
|
}
|
|
479
483
|
async genMoreMessages(providerConfig, agent, systemPrompt, _funcTools, _requestContext, context, genseq, abortSignal) {
|
|
@@ -575,14 +579,28 @@ responses:
|
|
|
575
579
|
arguments: this.normalizeFuncCallArgs(call.arguments),
|
|
576
580
|
};
|
|
577
581
|
}) ?? [];
|
|
582
|
+
const invalidFuncCalls = matched?.invalidFuncCalls ?? [];
|
|
583
|
+
const invalidFuncCallOutputs = invalidFuncCalls.map((call) => ({
|
|
584
|
+
kind: 'invalid_func_call',
|
|
585
|
+
call,
|
|
586
|
+
}));
|
|
587
|
+
const messages = thinking !== undefined
|
|
588
|
+
? saying
|
|
589
|
+
? [thinking, saying, ...funcMsgs]
|
|
590
|
+
: [thinking, ...funcMsgs]
|
|
591
|
+
: saying
|
|
592
|
+
? [saying, ...funcMsgs]
|
|
593
|
+
: [...funcMsgs];
|
|
578
594
|
return {
|
|
579
|
-
messages
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
: [
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
595
|
+
messages,
|
|
596
|
+
...(invalidFuncCallOutputs.length > 0
|
|
597
|
+
? {
|
|
598
|
+
outputs: [
|
|
599
|
+
...messages.map((message) => ({ kind: 'message', message })),
|
|
600
|
+
...invalidFuncCallOutputs,
|
|
601
|
+
],
|
|
602
|
+
}
|
|
603
|
+
: {}),
|
|
586
604
|
usage,
|
|
587
605
|
llmGenModel: modelName,
|
|
588
606
|
};
|
|
@@ -14,7 +14,7 @@ import type { ChatCompletion, ChatCompletionChunk, ChatCompletionMessageParam }
|
|
|
14
14
|
import type { Team } from '../../team';
|
|
15
15
|
import type { FuncTool } from '../../tool';
|
|
16
16
|
import type { ChatMessage, ModelInfo, ProviderConfig } from '../client';
|
|
17
|
-
import { type LlmBatchResult, type LlmFailureDisposition, type LlmGenerator, type LlmRequestContext, type LlmStreamReceiver, type LlmStreamResult } from '../gen';
|
|
17
|
+
import { type LlmBatchOutput, type LlmBatchResult, type LlmFailureDisposition, type LlmGenerator, type LlmRequestContext, type LlmStreamReceiver, type LlmStreamResult } from '../gen';
|
|
18
18
|
type OpenAiCompatibleChatExtraParams = {
|
|
19
19
|
thinking?: boolean | Record<string, unknown>;
|
|
20
20
|
reasoning_effort?: NonNullable<Team.ModelParams['openai-compatible']>['reasoning_effort'];
|
|
@@ -48,6 +48,7 @@ export declare function consumeOpenAiCompatibleChatCompletionStreamForTest(args:
|
|
|
48
48
|
abortSignal?: AbortSignal;
|
|
49
49
|
}): Promise<LlmStreamResult>;
|
|
50
50
|
export declare function chatCompletionToChatMessagesForTest(response: ChatCompletion, genseq: number): ChatMessage[];
|
|
51
|
+
export declare function chatCompletionToBatchOutputsForTest(response: ChatCompletion, genseq: number): LlmBatchOutput[];
|
|
51
52
|
export declare class OpenAiCompatibleGen implements LlmGenerator {
|
|
52
53
|
get apiType(): string;
|
|
53
54
|
classifyFailure(error: unknown): LlmFailureDisposition | undefined;
|
|
@@ -22,6 +22,7 @@ exports.wrapOpenAiCompatibleRejectedRequestErrorForTest = wrapOpenAiCompatibleRe
|
|
|
22
22
|
exports.buildOpenAiCompatibleRequestMessagesWrapper = buildOpenAiCompatibleRequestMessagesWrapper;
|
|
23
23
|
exports.consumeOpenAiCompatibleChatCompletionStreamForTest = consumeOpenAiCompatibleChatCompletionStreamForTest;
|
|
24
24
|
exports.chatCompletionToChatMessagesForTest = chatCompletionToChatMessagesForTest;
|
|
25
|
+
exports.chatCompletionToBatchOutputsForTest = chatCompletionToBatchOutputsForTest;
|
|
25
26
|
const events_1 = require("events");
|
|
26
27
|
const fs_1 = require("fs");
|
|
27
28
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
@@ -1475,6 +1476,24 @@ function throwOpenAiCompatibleMalformedBatchToolCall(detail) {
|
|
|
1475
1476
|
log.error(message, error);
|
|
1476
1477
|
throw error;
|
|
1477
1478
|
}
|
|
1479
|
+
function buildInvalidStreamedToolFunctionNameCall(state) {
|
|
1480
|
+
return {
|
|
1481
|
+
provider: 'openai-compatible',
|
|
1482
|
+
callId: state.callId,
|
|
1483
|
+
detail: `OPENAI-COMPATIBLE missing streamed tool function name for callId=${state.callId}`,
|
|
1484
|
+
toolCallIndex: state.index,
|
|
1485
|
+
rawArgumentsText: state.argsJson,
|
|
1486
|
+
};
|
|
1487
|
+
}
|
|
1488
|
+
function buildInvalidToolFunctionNameCall(args) {
|
|
1489
|
+
return {
|
|
1490
|
+
provider: 'openai-compatible',
|
|
1491
|
+
callId: args.callId,
|
|
1492
|
+
detail: `OPENAI-COMPATIBLE missing tool function name for callId=${args.callId}`,
|
|
1493
|
+
toolCallIndex: args.toolCallIndex,
|
|
1494
|
+
rawArgumentsText: args.rawArgumentsText,
|
|
1495
|
+
};
|
|
1496
|
+
}
|
|
1478
1497
|
async function maybeEmitFuncCall(state, receiver, genseq) {
|
|
1479
1498
|
if (state.emitted)
|
|
1480
1499
|
return;
|
|
@@ -1482,17 +1501,32 @@ async function maybeEmitFuncCall(state, receiver, genseq) {
|
|
|
1482
1501
|
state.callId = synthesizeCallId(genseq, state.index);
|
|
1483
1502
|
}
|
|
1484
1503
|
if (state.name.trim().length === 0) {
|
|
1485
|
-
|
|
1504
|
+
if (state.argsJson.trim().length === 0) {
|
|
1505
|
+
log.warn('OPENAI-COMPATIBLE ignored empty streamed tool call placeholder', undefined, {
|
|
1506
|
+
callId: state.callId,
|
|
1507
|
+
index: state.index,
|
|
1508
|
+
});
|
|
1509
|
+
state.emitted = true;
|
|
1510
|
+
return;
|
|
1511
|
+
}
|
|
1512
|
+
const invalidCall = buildInvalidStreamedToolFunctionNameCall(state);
|
|
1513
|
+
const detail = invalidCall.detail;
|
|
1486
1514
|
log.error(detail, new Error('openai_compatible_missing_tool_call_name'), {
|
|
1487
1515
|
callId: state.callId,
|
|
1516
|
+
index: state.index,
|
|
1488
1517
|
});
|
|
1489
|
-
if (receiver.
|
|
1490
|
-
|
|
1518
|
+
if (!receiver.invalidFuncCall) {
|
|
1519
|
+
if (receiver.streamError) {
|
|
1520
|
+
await receiver.streamError(detail);
|
|
1521
|
+
}
|
|
1522
|
+
throw buildOpenAiCompatibleStreamError({
|
|
1523
|
+
detail,
|
|
1524
|
+
kind: 'invalid_tool_call',
|
|
1525
|
+
});
|
|
1491
1526
|
}
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
});
|
|
1527
|
+
state.emitted = true;
|
|
1528
|
+
await receiver.invalidFuncCall(invalidCall);
|
|
1529
|
+
return;
|
|
1496
1530
|
}
|
|
1497
1531
|
state.emitted = true;
|
|
1498
1532
|
const args = state.argsJson.trim().length > 0 ? state.argsJson : '{}';
|
|
@@ -1694,25 +1728,27 @@ async function consumeOpenAiCompatibleChatCompletionStreamForTest(args) {
|
|
|
1694
1728
|
abortSignal: args.abortSignal,
|
|
1695
1729
|
});
|
|
1696
1730
|
}
|
|
1697
|
-
function
|
|
1698
|
-
const
|
|
1731
|
+
function chatCompletionToBatchOutputs(response, genseq) {
|
|
1732
|
+
const outputs = [];
|
|
1699
1733
|
const choice = response.choices && response.choices.length > 0 ? response.choices[0] : undefined;
|
|
1700
1734
|
const msg = choice ? choice.message : undefined;
|
|
1701
1735
|
if (!msg)
|
|
1702
|
-
return
|
|
1736
|
+
return outputs;
|
|
1703
1737
|
const reasoningContent = extractReasoningContentField(msg);
|
|
1704
1738
|
if (reasoningContent && reasoningContent.length > 0) {
|
|
1705
|
-
|
|
1739
|
+
const message = {
|
|
1706
1740
|
type: 'thinking_msg',
|
|
1707
1741
|
role: 'assistant',
|
|
1708
1742
|
genseq,
|
|
1709
1743
|
content: reasoningContent,
|
|
1710
1744
|
reasoning: buildReasoningPayloadFromText(reasoningContent),
|
|
1711
|
-
}
|
|
1745
|
+
};
|
|
1746
|
+
outputs.push({ kind: 'message', message });
|
|
1712
1747
|
}
|
|
1713
1748
|
const content = typeof msg.content === 'string' ? msg.content : null;
|
|
1714
1749
|
if (content && content.length > 0) {
|
|
1715
|
-
|
|
1750
|
+
const message = { type: 'saying_msg', role: 'assistant', genseq, content };
|
|
1751
|
+
outputs.push({ kind: 'message', message });
|
|
1716
1752
|
}
|
|
1717
1753
|
const toolCalls = msg.tool_calls;
|
|
1718
1754
|
if (Array.isArray(toolCalls)) {
|
|
@@ -1730,23 +1766,48 @@ function chatCompletionToChatMessages(response, genseq) {
|
|
|
1730
1766
|
const name = typeof call.function?.name === 'string' ? call.function.name : '';
|
|
1731
1767
|
const args = typeof call.function?.arguments === 'string' ? call.function.arguments : '';
|
|
1732
1768
|
if (name.trim().length === 0) {
|
|
1733
|
-
|
|
1769
|
+
const invalidCall = buildInvalidToolFunctionNameCall({
|
|
1770
|
+
callId,
|
|
1771
|
+
toolCallIndex: index,
|
|
1772
|
+
rawArgumentsText: args,
|
|
1773
|
+
});
|
|
1774
|
+
log.error(invalidCall.detail, new Error('openai_compatible_missing_tool_call_name'), {
|
|
1775
|
+
callId,
|
|
1776
|
+
index,
|
|
1777
|
+
});
|
|
1778
|
+
outputs.push({ kind: 'invalid_func_call', call: invalidCall });
|
|
1779
|
+
continue;
|
|
1734
1780
|
}
|
|
1735
|
-
|
|
1781
|
+
const message = {
|
|
1736
1782
|
type: 'func_call_msg',
|
|
1737
1783
|
role: 'assistant',
|
|
1738
1784
|
genseq,
|
|
1739
1785
|
id: callId,
|
|
1740
1786
|
name,
|
|
1741
1787
|
arguments: args,
|
|
1742
|
-
}
|
|
1788
|
+
};
|
|
1789
|
+
outputs.push({ kind: 'message', message });
|
|
1743
1790
|
}
|
|
1744
1791
|
}
|
|
1792
|
+
return outputs;
|
|
1793
|
+
}
|
|
1794
|
+
function batchOutputsToChatMessages(outputs) {
|
|
1795
|
+
return outputs
|
|
1796
|
+
.filter((output) => {
|
|
1797
|
+
return output.kind === 'message';
|
|
1798
|
+
})
|
|
1799
|
+
.map((output) => output.message);
|
|
1800
|
+
}
|
|
1801
|
+
function chatCompletionToChatMessages(response, genseq) {
|
|
1802
|
+
const out = batchOutputsToChatMessages(chatCompletionToBatchOutputs(response, genseq));
|
|
1745
1803
|
return out;
|
|
1746
1804
|
}
|
|
1747
1805
|
function chatCompletionToChatMessagesForTest(response, genseq) {
|
|
1748
1806
|
return chatCompletionToChatMessages(response, genseq);
|
|
1749
1807
|
}
|
|
1808
|
+
function chatCompletionToBatchOutputsForTest(response, genseq) {
|
|
1809
|
+
return chatCompletionToBatchOutputs(response, genseq);
|
|
1810
|
+
}
|
|
1750
1811
|
class OpenAiCompatibleGen {
|
|
1751
1812
|
get apiType() {
|
|
1752
1813
|
return 'openai-compatible';
|
|
@@ -1898,7 +1959,15 @@ class OpenAiCompatibleGen {
|
|
|
1898
1959
|
const response = await client.chat.completions.create(payload, {
|
|
1899
1960
|
...(abortSignal ? { signal: abortSignal } : {}),
|
|
1900
1961
|
});
|
|
1901
|
-
const
|
|
1962
|
+
const batchOutputs = chatCompletionToBatchOutputs(response, genseq);
|
|
1963
|
+
const messagesOut = batchOutputsToChatMessages(batchOutputs);
|
|
1964
|
+
const orderedOutputs = outputs.length > 0
|
|
1965
|
+
? [
|
|
1966
|
+
...outputs,
|
|
1967
|
+
...messagesOut.map((message) => ({ kind: 'message', message })),
|
|
1968
|
+
...batchOutputs.filter((output) => output.kind !== 'message'),
|
|
1969
|
+
]
|
|
1970
|
+
: batchOutputs;
|
|
1902
1971
|
const usage = response.usage
|
|
1903
1972
|
? tryExtractChatUsage(response.usage)
|
|
1904
1973
|
: { kind: 'unavailable' };
|
|
@@ -1907,7 +1976,7 @@ class OpenAiCompatibleGen {
|
|
|
1907
1976
|
: undefined;
|
|
1908
1977
|
return {
|
|
1909
1978
|
messages: messagesOut,
|
|
1910
|
-
...(
|
|
1979
|
+
...(orderedOutputs.length > 0 ? { outputs: orderedOutputs } : {}),
|
|
1911
1980
|
usage,
|
|
1912
1981
|
...(model ? { llmGenModel: model } : {}),
|
|
1913
1982
|
};
|
package/dist/llm/gen.d.ts
CHANGED
|
@@ -20,6 +20,9 @@ export declare class LlmStreamErrorEmittedError extends Error {
|
|
|
20
20
|
export type LlmBatchOutput = {
|
|
21
21
|
kind: 'message';
|
|
22
22
|
message: ChatMessage;
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'invalid_func_call';
|
|
25
|
+
call: LlmInvalidFuncCall;
|
|
23
26
|
} | {
|
|
24
27
|
kind: 'web_search_call';
|
|
25
28
|
call: LlmWebSearchCall;
|
|
@@ -138,6 +141,14 @@ export type OpenAiResponsesCustomToolCall = {
|
|
|
138
141
|
detail?: string;
|
|
139
142
|
};
|
|
140
143
|
export type OpenAiResponsesNativeToolCall = OpenAiResponsesNonCustomNativeToolCall | OpenAiResponsesCustomToolCall;
|
|
144
|
+
export type LlmInvalidFuncCall = Readonly<{
|
|
145
|
+
provider: string;
|
|
146
|
+
callId: string;
|
|
147
|
+
detail: string;
|
|
148
|
+
toolCallIndex?: number;
|
|
149
|
+
rawFunctionName?: string;
|
|
150
|
+
rawArgumentsText?: string;
|
|
151
|
+
}>;
|
|
141
152
|
export interface LlmStreamReceiver {
|
|
142
153
|
thinkingStart: () => Promise<void>;
|
|
143
154
|
thinkingChunk: (chunk: string) => Promise<void>;
|
|
@@ -149,6 +160,7 @@ export interface LlmStreamReceiver {
|
|
|
149
160
|
rawCallId?: string;
|
|
150
161
|
effectiveCallId?: string;
|
|
151
162
|
}) => Promise<void>;
|
|
163
|
+
invalidFuncCall?: (call: LlmInvalidFuncCall) => Promise<void>;
|
|
152
164
|
webSearchCall?: (call: LlmWebSearchCall) => Promise<void>;
|
|
153
165
|
nativeToolCall?: (call: OpenAiResponsesNativeToolCall) => Promise<void>;
|
|
154
166
|
toolResultImageIngest?: (ingest: ToolResultImageIngest) => Promise<void>;
|
|
@@ -205,6 +205,9 @@ async function persistAndEmitRuntimeGuide(dlg, content) {
|
|
|
205
205
|
role: 'assistant',
|
|
206
206
|
content,
|
|
207
207
|
});
|
|
208
|
+
await persistAndPostRuntimeGuide(dlg, content);
|
|
209
|
+
}
|
|
210
|
+
async function persistAndPostRuntimeGuide(dlg, content) {
|
|
208
211
|
await persistence_1.DialogPersistence.persistRuntimeGuide(dlg, content, dlg.activeGenSeq);
|
|
209
212
|
(0, evt_registry_1.postDialogEvent)(dlg, {
|
|
210
213
|
type: 'runtime_guide_evt',
|
|
@@ -301,6 +304,9 @@ function hasMeaningfulBatchOutput(batch) {
|
|
|
301
304
|
if (output.kind === 'user_image_ingest') {
|
|
302
305
|
continue;
|
|
303
306
|
}
|
|
307
|
+
if (output.kind === 'invalid_func_call') {
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
304
310
|
if (output.kind !== 'message') {
|
|
305
311
|
return true;
|
|
306
312
|
}
|
|
@@ -910,6 +916,75 @@ async function emitAssistantSaying(dlg, content) {
|
|
|
910
916
|
await dlg.sayingChunk(content);
|
|
911
917
|
await dlg.sayingFinish();
|
|
912
918
|
}
|
|
919
|
+
function formatInvalidFuncCallRuntimeGuide(language, call) {
|
|
920
|
+
const rawName = call.rawFunctionName !== undefined && call.rawFunctionName.trim() !== ''
|
|
921
|
+
? call.rawFunctionName.trim()
|
|
922
|
+
: '<missing>';
|
|
923
|
+
const rawArguments = call.rawArgumentsText !== undefined && call.rawArgumentsText.trim() !== ''
|
|
924
|
+
? call.rawArgumentsText
|
|
925
|
+
: '<empty>';
|
|
926
|
+
const indexLine = call.toolCallIndex === undefined ? undefined : `- toolCallIndex: ${String(call.toolCallIndex)}`;
|
|
927
|
+
if (language === 'en') {
|
|
928
|
+
return [
|
|
929
|
+
'[Runtime notice] The previous model output contained an invalid tool-call payload that could not be represented as a normal provider tool call in the next generation context.',
|
|
930
|
+
'',
|
|
931
|
+
`- provider: ${call.provider}`,
|
|
932
|
+
`- callId: ${call.callId}`,
|
|
933
|
+
`- problem: ${call.detail}`,
|
|
934
|
+
`- rawFunctionName: ${rawName}`,
|
|
935
|
+
`- rawArgumentsText:`,
|
|
936
|
+
'```json',
|
|
937
|
+
rawArguments,
|
|
938
|
+
'```',
|
|
939
|
+
...(indexLine === undefined ? [] : [indexLine]),
|
|
940
|
+
'',
|
|
941
|
+
'Treat that payload as failed. Do not assume the tool ran. Continue from the current task, and if a tool call is still needed, emit a new valid tool call with a non-empty function name and valid arguments.',
|
|
942
|
+
]
|
|
943
|
+
.filter((line) => line.length > 0)
|
|
944
|
+
.join('\n');
|
|
945
|
+
}
|
|
946
|
+
return [
|
|
947
|
+
'[运行时提示] 上一轮模型输出包含一个无效工具调用载荷,无法按正常 provider tool call 形态进入下一轮生成上下文。',
|
|
948
|
+
'',
|
|
949
|
+
`- provider: ${call.provider}`,
|
|
950
|
+
`- callId: ${call.callId}`,
|
|
951
|
+
`- 问题: ${call.detail}`,
|
|
952
|
+
`- rawFunctionName: ${rawName}`,
|
|
953
|
+
`- rawArgumentsText:`,
|
|
954
|
+
'```json',
|
|
955
|
+
rawArguments,
|
|
956
|
+
'```',
|
|
957
|
+
...(indexLine === undefined ? [] : [indexLine]),
|
|
958
|
+
'',
|
|
959
|
+
'请把该载荷视为调用失败,不要假设工具已经执行。继续当前任务;如果仍需要调用工具,请重新发起一个函数名非空、参数有效的新工具调用。',
|
|
960
|
+
]
|
|
961
|
+
.filter((line) => line.length > 0)
|
|
962
|
+
.join('\n');
|
|
963
|
+
}
|
|
964
|
+
async function persistInvalidFuncCallRuntimeGuide(args) {
|
|
965
|
+
const { dlg, call } = args;
|
|
966
|
+
const sourceText = args.source === 'streamed' ? 'streamed' : 'batch';
|
|
967
|
+
log_1.log.error(`kernel-driver received invalid ${sourceText} function call payload`, new Error(`kernel_driver_invalid_${sourceText}_function_call_payload`), {
|
|
968
|
+
rootId: dlg.id.rootId,
|
|
969
|
+
selfId: dlg.id.selfId,
|
|
970
|
+
course: dlg.activeGenCourseOrUndefined ?? dlg.currentCourse,
|
|
971
|
+
genseq: dlg.activeGenSeq,
|
|
972
|
+
callId: call.callId,
|
|
973
|
+
provider: call.provider,
|
|
974
|
+
detail: call.detail,
|
|
975
|
+
toolCallIndex: call.toolCallIndex,
|
|
976
|
+
});
|
|
977
|
+
if (args.emitStreamError) {
|
|
978
|
+
await dlg.streamError(call.detail);
|
|
979
|
+
}
|
|
980
|
+
const content = formatInvalidFuncCallRuntimeGuide((0, work_language_1.getWorkLanguage)(), call);
|
|
981
|
+
args.newMsgs.push({
|
|
982
|
+
type: 'transient_guide_msg',
|
|
983
|
+
role: 'assistant',
|
|
984
|
+
content,
|
|
985
|
+
});
|
|
986
|
+
await persistAndPostRuntimeGuide(dlg, content);
|
|
987
|
+
}
|
|
913
988
|
function resolveFuncToolFollowupMode(tool) {
|
|
914
989
|
return tool?.followupMode ?? 'immediate';
|
|
915
990
|
}
|
|
@@ -1895,6 +1970,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
1895
1970
|
const streamedFuncCalls = [];
|
|
1896
1971
|
let sawWebSearchSideChannelOutput = false;
|
|
1897
1972
|
let sawNativeToolSideChannelOutput = false;
|
|
1973
|
+
let invalidFuncCallCount = 0;
|
|
1898
1974
|
const streamOrBatch = async () => {
|
|
1899
1975
|
let batchAttemptCourse;
|
|
1900
1976
|
let batchAttemptCheckpointOffset;
|
|
@@ -1911,6 +1987,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
1911
1987
|
});
|
|
1912
1988
|
sawWebSearchSideChannelOutput = false;
|
|
1913
1989
|
sawNativeToolSideChannelOutput = false;
|
|
1990
|
+
invalidFuncCallCount = 0;
|
|
1914
1991
|
streamedFuncCalls.length = 0;
|
|
1915
1992
|
newMsgs.length = 0;
|
|
1916
1993
|
};
|
|
@@ -2004,6 +2081,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
2004
2081
|
sawWebSearchSideChannelOutput = false;
|
|
2005
2082
|
sawNativeToolSideChannelOutput = false;
|
|
2006
2083
|
streamedFuncCalls.length = 0;
|
|
2084
|
+
invalidFuncCallCount = 0;
|
|
2007
2085
|
newMsgs.length = 0;
|
|
2008
2086
|
};
|
|
2009
2087
|
const receiver = {
|
|
@@ -2127,6 +2205,17 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
2127
2205
|
arguments: argsStr,
|
|
2128
2206
|
});
|
|
2129
2207
|
},
|
|
2208
|
+
invalidFuncCall: async (call) => {
|
|
2209
|
+
throwIfAborted(abortSignal, dlg);
|
|
2210
|
+
invalidFuncCallCount += 1;
|
|
2211
|
+
await persistInvalidFuncCallRuntimeGuide({
|
|
2212
|
+
dlg,
|
|
2213
|
+
call,
|
|
2214
|
+
source: 'streamed',
|
|
2215
|
+
newMsgs,
|
|
2216
|
+
emitStreamError: true,
|
|
2217
|
+
});
|
|
2218
|
+
},
|
|
2130
2219
|
webSearchCall: async (call) => {
|
|
2131
2220
|
throwIfAborted(abortSignal, dlg);
|
|
2132
2221
|
sawWebSearchSideChannelOutput = true;
|
|
@@ -2177,6 +2266,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
2177
2266
|
sawWebSearchSideChannelOutput = false;
|
|
2178
2267
|
sawNativeToolSideChannelOutput = false;
|
|
2179
2268
|
streamedFuncCalls.length = 0;
|
|
2269
|
+
invalidFuncCallCount = 0;
|
|
2180
2270
|
newMsgs.length = 0;
|
|
2181
2271
|
const promptCacheKey = prepareLlmRequestContextKey();
|
|
2182
2272
|
const streamResult = await llmGen.genToReceiver(providerCfg, agent, systemPrompt, funcTools, {
|
|
@@ -2192,6 +2282,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
2192
2282
|
const hasFunctionCall = streamedFuncCalls.length > 0;
|
|
2193
2283
|
if (!hasFinishedMessageContent &&
|
|
2194
2284
|
!hasFunctionCall &&
|
|
2285
|
+
invalidFuncCallCount === 0 &&
|
|
2195
2286
|
!sawWebSearchSideChannelOutput &&
|
|
2196
2287
|
!sawNativeToolSideChannelOutput) {
|
|
2197
2288
|
throw {
|
|
@@ -2259,6 +2350,17 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
2259
2350
|
}
|
|
2260
2351
|
break;
|
|
2261
2352
|
}
|
|
2353
|
+
case 'invalid_func_call': {
|
|
2354
|
+
invalidFuncCallCount += 1;
|
|
2355
|
+
await persistInvalidFuncCallRuntimeGuide({
|
|
2356
|
+
dlg,
|
|
2357
|
+
call: output.call,
|
|
2358
|
+
source: 'batch',
|
|
2359
|
+
newMsgs,
|
|
2360
|
+
emitStreamError: true,
|
|
2361
|
+
});
|
|
2362
|
+
break;
|
|
2363
|
+
}
|
|
2262
2364
|
case 'web_search_call': {
|
|
2263
2365
|
sawWebSearchSideChannelOutput = true;
|
|
2264
2366
|
await dlg.webSearchCall(projectLlmWebSearchCall(output.call));
|
|
@@ -2468,7 +2570,9 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
|
|
|
2468
2570
|
// warrant same-drive LLM reaction right away. Provider-native side-channel UI events are
|
|
2469
2571
|
// meaningful output, but they are not transcript/context inputs and therefore must not
|
|
2470
2572
|
// trigger another immediate generation round by themselves.
|
|
2471
|
-
const shouldStartImmediatePostToolGeneration = routed.hasImmediateFollowupToolCalls ||
|
|
2573
|
+
const shouldStartImmediatePostToolGeneration = routed.hasImmediateFollowupToolCalls ||
|
|
2574
|
+
routed.tellaskToolOutputs.length > 0 ||
|
|
2575
|
+
invalidFuncCallCount > 0;
|
|
2472
2576
|
if (!shouldStartImmediatePostToolGeneration) {
|
|
2473
2577
|
const healthFirst = await maybeContinueWithHealthPromptBeforeDiligence({
|
|
2474
2578
|
dlg,
|
|
@@ -23,6 +23,28 @@ const idle_reminder_wake_1 = require("./idle-reminder-wake");
|
|
|
23
23
|
const reply_guidance_1 = require("./reply-guidance");
|
|
24
24
|
const sideDialog_1 = require("./sideDialog");
|
|
25
25
|
const tellask_special_1 = require("./tellask-special");
|
|
26
|
+
async function queueReplyReminderFollowUp(args) {
|
|
27
|
+
if (args.followUp.kind === 'runtime_sideDialog_reply_reminder') {
|
|
28
|
+
await args.dialog.queueRuntimeSideDialogPrompt({
|
|
29
|
+
prompt: args.followUp.prompt,
|
|
30
|
+
msgId: args.followUp.msgId,
|
|
31
|
+
grammar: args.followUp.grammar ?? 'markdown',
|
|
32
|
+
userLanguageCode: args.followUp.userLanguageCode,
|
|
33
|
+
tellaskReplyDirective: args.followUp.tellaskReplyDirective,
|
|
34
|
+
skipTaskdoc: args.followUp.skipTaskdoc,
|
|
35
|
+
sideDialogReplyTarget: args.followUp.sideDialogReplyTarget,
|
|
36
|
+
});
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
await args.dialog.queueRuntimeReplyPrompt({
|
|
40
|
+
prompt: args.followUp.prompt,
|
|
41
|
+
msgId: args.followUp.msgId,
|
|
42
|
+
grammar: args.followUp.grammar ?? 'markdown',
|
|
43
|
+
userLanguageCode: args.followUp.userLanguageCode,
|
|
44
|
+
tellaskReplyDirective: args.followUp.tellaskReplyDirective,
|
|
45
|
+
skipTaskdoc: args.followUp.skipTaskdoc,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
26
48
|
function isReplyToolReminderPrompt(prompt) {
|
|
27
49
|
return typeof prompt?.content === 'string' && (0, reply_prompt_copy_1.isReplyToolReminderPromptContent)(prompt.content);
|
|
28
50
|
}
|
|
@@ -1084,6 +1106,18 @@ async function executeDriveRound(args) {
|
|
|
1084
1106
|
}
|
|
1085
1107
|
}
|
|
1086
1108
|
if (followUp) {
|
|
1109
|
+
if (followUp.kind === 'runtime_reply_reminder' ||
|
|
1110
|
+
followUp.kind === 'runtime_sideDialog_reply_reminder') {
|
|
1111
|
+
await queueReplyReminderFollowUp({ dialog, followUp });
|
|
1112
|
+
args.scheduleDrive(dialog, {
|
|
1113
|
+
waitInQue: true,
|
|
1114
|
+
driveOptions: {
|
|
1115
|
+
source: 'kernel_driver_follow_up',
|
|
1116
|
+
reason: 'follow_up_prompt',
|
|
1117
|
+
},
|
|
1118
|
+
});
|
|
1119
|
+
return driveResult;
|
|
1120
|
+
}
|
|
1087
1121
|
args.scheduleDrive(dialog, {
|
|
1088
1122
|
waitInQue: true,
|
|
1089
1123
|
driveOptions: {
|
|
@@ -1116,9 +1150,7 @@ async function executeDriveRound(args) {
|
|
|
1116
1150
|
case 'registered_assignment_update':
|
|
1117
1151
|
case 'new_course_runtime_guide':
|
|
1118
1152
|
case 'new_course_runtime_reply':
|
|
1119
|
-
case 'new_course_runtime_sideDialog':
|
|
1120
|
-
case 'runtime_reply_reminder':
|
|
1121
|
-
case 'runtime_sideDialog_reply_reminder': {
|
|
1153
|
+
case 'new_course_runtime_sideDialog': {
|
|
1122
1154
|
const runtimeCommon = {
|
|
1123
1155
|
...common,
|
|
1124
1156
|
origin: 'runtime',
|
|
@@ -1127,8 +1159,7 @@ async function executeDriveRound(args) {
|
|
|
1127
1159
|
: { skipTaskdoc: followUp.skipTaskdoc }),
|
|
1128
1160
|
};
|
|
1129
1161
|
if (followUp.kind === 'registered_assignment_update' ||
|
|
1130
|
-
followUp.kind === 'new_course_runtime_sideDialog'
|
|
1131
|
-
followUp.kind === 'runtime_sideDialog_reply_reminder') {
|
|
1162
|
+
followUp.kind === 'new_course_runtime_sideDialog') {
|
|
1132
1163
|
const prompt = {
|
|
1133
1164
|
...runtimeCommon,
|
|
1134
1165
|
tellaskReplyDirective: followUp.tellaskReplyDirective,
|
|
@@ -1136,8 +1167,7 @@ async function executeDriveRound(args) {
|
|
|
1136
1167
|
};
|
|
1137
1168
|
return prompt;
|
|
1138
1169
|
}
|
|
1139
|
-
if (followUp.kind === 'new_course_runtime_reply'
|
|
1140
|
-
followUp.kind === 'runtime_reply_reminder') {
|
|
1170
|
+
if (followUp.kind === 'new_course_runtime_reply') {
|
|
1141
1171
|
const prompt = {
|
|
1142
1172
|
...runtimeCommon,
|
|
1143
1173
|
tellaskReplyDirective: followUp.tellaskReplyDirective,
|
package/dist/log.js
CHANGED
|
@@ -78,6 +78,39 @@ const DETAIL_INSPECT_PROFILES = [
|
|
|
78
78
|
maxStringLength: 192,
|
|
79
79
|
},
|
|
80
80
|
];
|
|
81
|
+
const LOG_KEY_PRIORITY = new Map([
|
|
82
|
+
'rootId',
|
|
83
|
+
'selfId',
|
|
84
|
+
'dialogId',
|
|
85
|
+
'course',
|
|
86
|
+
'genseq',
|
|
87
|
+
'callId',
|
|
88
|
+
'questionId',
|
|
89
|
+
'agentId',
|
|
90
|
+
'toolName',
|
|
91
|
+
'provider',
|
|
92
|
+
'model',
|
|
93
|
+
'dialogClass',
|
|
94
|
+
'status',
|
|
95
|
+
'error',
|
|
96
|
+
'detail',
|
|
97
|
+
'message',
|
|
98
|
+
'code',
|
|
99
|
+
'name',
|
|
100
|
+
'type',
|
|
101
|
+
].map((key, index) => [key, index]));
|
|
102
|
+
function compareLogObjectKeys(left, right) {
|
|
103
|
+
const leftPriority = LOG_KEY_PRIORITY.get(left);
|
|
104
|
+
const rightPriority = LOG_KEY_PRIORITY.get(right);
|
|
105
|
+
if (leftPriority !== undefined || rightPriority !== undefined) {
|
|
106
|
+
return (leftPriority ?? Number.MAX_SAFE_INTEGER) - (rightPriority ?? Number.MAX_SAFE_INTEGER);
|
|
107
|
+
}
|
|
108
|
+
const leftInternal = left.startsWith('_') || left.startsWith('__');
|
|
109
|
+
const rightInternal = right.startsWith('_') || right.startsWith('__');
|
|
110
|
+
if (leftInternal !== rightInternal)
|
|
111
|
+
return leftInternal ? 1 : -1;
|
|
112
|
+
return left.localeCompare(right);
|
|
113
|
+
}
|
|
81
114
|
function truncateText(value, maxChars, suffix) {
|
|
82
115
|
if (maxChars <= 0) {
|
|
83
116
|
return { text: '', truncated: value.length > 0 };
|
|
@@ -248,7 +281,7 @@ function pruneForLog(value, profile, depth, seen) {
|
|
|
248
281
|
return { value: `[${ctorName} byteLength=${byteLen}]`, pruned: true };
|
|
249
282
|
}
|
|
250
283
|
const source = value;
|
|
251
|
-
const allKeys = Object.keys(source).sort();
|
|
284
|
+
const allKeys = Object.keys(source).sort(compareLogObjectKeys);
|
|
252
285
|
const visibleKeys = allKeys.slice(0, profile.maxObjectKeys);
|
|
253
286
|
const ctorName = getConstructorName(value);
|
|
254
287
|
const reduced = {};
|
|
@@ -286,7 +319,7 @@ function inspectAdaptive(value, maxChars) {
|
|
|
286
319
|
depth: null,
|
|
287
320
|
breakLength: 120,
|
|
288
321
|
compact: false,
|
|
289
|
-
sorted:
|
|
322
|
+
sorted: false,
|
|
290
323
|
maxArrayLength: profile.maxArrayItems,
|
|
291
324
|
maxStringLength: profile.maxStringLength,
|
|
292
325
|
});
|
package/dist/persistence.d.ts
CHANGED
|
@@ -131,6 +131,7 @@ export declare class DiskFileDialogStore extends DialogStore {
|
|
|
131
131
|
* Start new course (append-only JSONL + exceptional reminder persistence)
|
|
132
132
|
*/
|
|
133
133
|
startNewCourse(dialog: Dialog, newCoursePrompt: DialogRuntimePrompt): Promise<void>;
|
|
134
|
+
persistPendingRuntimePrompt(dialog: Dialog, prompt: DialogRuntimePrompt): Promise<void>;
|
|
134
135
|
/**
|
|
135
136
|
* Persist reminder state (exceptional overwrite pattern)
|
|
136
137
|
* Note: Event emission is handled by processReminderUpdates() in Dialog
|
package/dist/persistence.js
CHANGED
|
@@ -2573,9 +2573,20 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
2573
2573
|
* Emit stream error for current generation lifecycle (uses active genseq when present)
|
|
2574
2574
|
*/
|
|
2575
2575
|
async streamError(dialog, error) {
|
|
2576
|
-
log_1.log.error(`Dialog stream error '${error}'`, new Error(), { dialog });
|
|
2577
2576
|
const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
|
|
2578
2577
|
const genseq = dialog.activeGenSeqOrUndefined;
|
|
2578
|
+
log_1.log.error(`Dialog stream error '${error}'`, new Error(), {
|
|
2579
|
+
dialogId: dialog.id.valueOf(),
|
|
2580
|
+
rootId: dialog.id.rootId,
|
|
2581
|
+
selfId: dialog.id.selfId,
|
|
2582
|
+
course,
|
|
2583
|
+
genseq,
|
|
2584
|
+
agentId: dialog.agentId,
|
|
2585
|
+
dialogClass: dialog.constructor.name,
|
|
2586
|
+
status: dialog.status,
|
|
2587
|
+
activeGeneration: dialog.hasActiveGeneration,
|
|
2588
|
+
dialogSnapshot: dialog,
|
|
2589
|
+
});
|
|
2579
2590
|
// Enhanced stream error event with better error classification
|
|
2580
2591
|
const streamErrorEvent = {
|
|
2581
2592
|
type: 'stream_error_evt',
|
|
@@ -2628,6 +2639,18 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
|
|
|
2628
2639
|
};
|
|
2629
2640
|
(0, evt_registry_1.postDialogEvent)(dialog, courseUpdateEvt);
|
|
2630
2641
|
}
|
|
2642
|
+
async persistPendingRuntimePrompt(dialog, prompt) {
|
|
2643
|
+
if (prompt.origin !== 'runtime') {
|
|
2644
|
+
throw new Error(`persistPendingRuntimePrompt invariant violation: pending prompt must have runtime origin for dialog=${dialog.id.valueOf()}`);
|
|
2645
|
+
}
|
|
2646
|
+
await DialogPersistence.mutateDialogLatest(dialog.id, () => ({
|
|
2647
|
+
kind: 'patch',
|
|
2648
|
+
patch: {
|
|
2649
|
+
needsDrive: true,
|
|
2650
|
+
pendingCourseStartPrompt: prompt,
|
|
2651
|
+
},
|
|
2652
|
+
}), dialog.status);
|
|
2653
|
+
}
|
|
2631
2654
|
/**
|
|
2632
2655
|
* Persist reminder state (exceptional overwrite pattern)
|
|
2633
2656
|
* Note: Event emission is handled by processReminderUpdates() in Dialog
|
|
@@ -217,14 +217,14 @@ function formatReminderContextGuide(language) {
|
|
|
217
217
|
if (language === 'zh') {
|
|
218
218
|
return [
|
|
219
219
|
`${formatSystemNoticePrefix(language)} 提醒项上下文块开始`,
|
|
220
|
-
'以下是当前可见提醒项的运行时上下文投影。由于当前 LLM Provider 通常不支持 role=environment,Dominds 默认把系统运行时提醒包装投影为 role=user;个别提醒项可由其 owner 按自身契约选择 role。无论最终 role
|
|
220
|
+
'以下是当前可见提醒项的运行时上下文投影。由于当前 LLM Provider 通常不支持 role=environment,Dominds 默认把系统运行时提醒包装投影为 role=user;个别提醒项可由其 owner 按自身契约选择 role。无论最终 role 如何,它们都不是用户的新诉求/指令,也不是聊天正文。',
|
|
221
221
|
'在 WebUI 中,用户通过独立的 Reminder 小组件/面板项看到这些提醒,并能把它们和聊天正文区分开。',
|
|
222
222
|
'请把提醒项作为工作集/状态参考;只有实际改变你的判断、计划或风险的信息,才需要提炼进后续有实质内容的对外回复。不要为了提醒项单独回复“收到/已了解/静默吸收”。',
|
|
223
223
|
].join('\n');
|
|
224
224
|
}
|
|
225
225
|
return [
|
|
226
226
|
`${formatSystemNoticePrefix(language)} Reminder context block begins`,
|
|
227
|
-
'The following visible reminders are runtime-added context projections. Because current LLM providers usually do not support role=environment, Dominds projects default system-runtime reminder wrappers as role=user; individual reminder owners may choose the role required by their own contract. Regardless of their final role, these reminders are not new user instructions
|
|
227
|
+
'The following visible reminders are runtime-added context projections. Because current LLM providers usually do not support role=environment, Dominds projects default system-runtime reminder wrappers as role=user; individual reminder owners may choose the role required by their own contract. Regardless of their final role, these reminders are not new user requests/instructions, and not chat transcript text.',
|
|
228
228
|
'In the WebUI, the user sees these reminders through a separate Reminder widget/panel item and can distinguish them from the chat transcript.',
|
|
229
229
|
'Use reminders as workset/state references; only carry information into a later substantive outward reply when it materially changes your current judgment, plan, or risk. Do not send a standalone "acknowledged/noted/silently absorbed" reply for reminder items.',
|
|
230
230
|
].join('\n');
|
|
@@ -234,23 +234,27 @@ function formatReminderItemProjectionNote(language) {
|
|
|
234
234
|
}
|
|
235
235
|
function formatReminderContextFooter(language, followingState) {
|
|
236
236
|
if (language === 'zh') {
|
|
237
|
-
const base = `${formatSystemNoticePrefix(language)}
|
|
237
|
+
const base = `${formatSystemNoticePrefix(language)} 提醒项上下文块结束。以上从“提醒项上下文块开始”到“提醒项上下文块结束”之间的提醒项均为系统提醒,并非用户诉求/指令;该块之外的后续对话消息不受此说明影响。`;
|
|
238
238
|
if (followingState === 'user_message') {
|
|
239
|
-
return `${base}
|
|
239
|
+
return (`${base}本轮提醒项块之后会紧接一条本轮真实的新用户消息;后续消息是用户的新诉求/指令,不是提醒项投影。` +
|
|
240
|
+
'提醒项块说明到此为止,不得外溢到那条消息:不要把后续用户消息称为“系统提示/没有新消息”,也不要因为本块说明而降低它的指令优先级。' +
|
|
241
|
+
'请按那条用户消息的原始语义继续处理;若它要求更新你的职责、偏好或心智资产,应照常落实。');
|
|
240
242
|
}
|
|
241
243
|
if (followingState === 'runtime_notice') {
|
|
242
|
-
return `${base}
|
|
244
|
+
return `${base}本轮提醒项块之后会接着出现一条运行时提示;它不是用户的新诉求/指令,请按其中的运行时要求继续推进。`;
|
|
243
245
|
}
|
|
244
246
|
return `${base}本轮没有新的用户消息或运行时提示;这是工具调用后的自动续推,请基于已有任务状态继续推进,不要把“没有新消息”理解为空系统提示。`;
|
|
245
247
|
}
|
|
246
248
|
const base = `${formatSystemNoticePrefix(language)} Reminder context block ends. The reminder items between ` +
|
|
247
249
|
'"Reminder context block begins" and "Reminder context block ends" are system reminders, ' +
|
|
248
|
-
'not user instructions; this
|
|
250
|
+
'not user requests/instructions; this reminder-block guidance does not apply to subsequent dialog messages outside this block. ';
|
|
249
251
|
if (followingState === 'user_message') {
|
|
250
|
-
return `${base}A new user message for this round follows this reminder block;
|
|
252
|
+
return (`${base}A real new user message for this round immediately follows this reminder block; the following message is a new user request/instruction, not a reminder projection. ` +
|
|
253
|
+
'The reminder-block guidance ends here and must not spill over onto that message: do not label the following user message as a "system notice" or "no new message", and do not lower its instruction priority because of this block. ' +
|
|
254
|
+
'Handle that user message according to its original meaning; if it asks you to update your responsibilities, preferences, or mind assets, carry that out normally.');
|
|
251
255
|
}
|
|
252
256
|
if (followingState === 'runtime_notice') {
|
|
253
|
-
return `${base}A runtime notice follows this reminder block in this round; it is not a new user request, so follow that runtime guidance and continue the work.`;
|
|
257
|
+
return `${base}A runtime notice follows this reminder block in this round; it is not a new user request/instruction, so follow that runtime guidance and continue the work.`;
|
|
254
258
|
}
|
|
255
259
|
return `${base}There is no new user message or runtime notice in this round; this is an automatic continuation after a tool call. Continue from the existing task state, and do not interpret the absence of a new message as an empty system notice.`;
|
|
256
260
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dominds",
|
|
3
|
-
"version": "1.23.
|
|
3
|
+
"version": "1.23.5",
|
|
4
4
|
"description": "Dominds CLI and aggregation shell for the LongRun AI kernel/runtime packages.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"publishConfig": {
|
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
"yaml": "^2.8.2",
|
|
54
54
|
"zod": "^4.3.6",
|
|
55
55
|
"@longrun-ai/codex-auth": "0.13.0",
|
|
56
|
-
"@longrun-ai/kernel": "1.13.
|
|
57
|
-
"@longrun-ai/shell": "1.13.
|
|
56
|
+
"@longrun-ai/kernel": "1.13.2",
|
|
57
|
+
"@longrun-ai/shell": "1.13.2"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/node": "^25.3.5",
|