@soimy/dingtalk 3.6.11 → 3.7.0
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/index.d.ts +1 -1
- package/dist/index.js +11684 -10583
- package/dist/src/{ack-reaction-service.d.ts → ack-reaction/ack-reaction-service.d.ts} +1 -1
- package/dist/src/ack-reaction/dynamic-ack-reaction-controller.d.ts +3 -3
- package/dist/src/card/ask-user-question-context.d.ts +1 -1
- package/dist/src/card/ask-user-question-store.d.ts +1 -1
- package/dist/src/card/ask-user-question.d.ts +1 -1
- package/dist/src/card/card-action-handler.d.ts +2 -2
- package/dist/src/{card-draft-controller.d.ts → card/card-draft-controller.d.ts} +5 -1
- package/dist/src/card/card-run-registry.d.ts +2 -2
- package/dist/src/{card-service.d.ts → card/card-service.d.ts} +1 -1
- package/dist/src/card/card-stop-handler.d.ts +1 -1
- package/dist/src/card/card-streaming-mode.d.ts +1 -1
- package/dist/src/card/card-task-progress.d.ts +60 -0
- package/dist/src/channel.d.ts +6 -6
- package/dist/src/command/card-stop-command.d.ts +1 -1
- package/dist/src/{feedback-learning-service.d.ts → command/feedback-learning-service.d.ts} +1 -1
- package/dist/src/command/inbound-command-dispatch-service.d.ts +2 -2
- package/dist/src/{learning-command-service.d.ts → command/learning-command-service.d.ts} +1 -1
- package/dist/src/gateway/channel-gateway.d.ts +1 -1
- package/dist/src/{connection-manager.d.ts → gateway/connection-manager.d.ts} +1 -1
- package/dist/src/{docs-service.d.ts → gateway/docs-service.d.ts} +1 -1
- package/dist/src/{inbound-handler.d.ts → gateway/inbound-handler.d.ts} +1 -1
- package/dist/src/gateway/inbound-session-queue-dispatcher.d.ts +1 -1
- package/dist/src/messaging/attachment-text-extractor.d.ts +1 -1
- package/dist/src/messaging/btw-deliver.d.ts +1 -1
- package/dist/src/messaging/channel-outbound.d.ts +1 -1
- package/dist/src/{media-utils.d.ts → messaging/media-utils.d.ts} +1 -1
- package/dist/src/{message-context-store.d.ts → messaging/message-context-store.d.ts} +7 -1
- package/dist/src/{message-utils.d.ts → messaging/message-utils.d.ts} +1 -1
- package/dist/src/messaging/quoted-context.d.ts +2 -2
- package/dist/src/messaging/quoted-file-service.d.ts +1 -1
- package/dist/src/messaging/quoted-ref.d.ts +2 -2
- package/dist/src/{reply-strategy-card.d.ts → messaging/reply-strategy-card.d.ts} +1 -1
- package/dist/src/{reply-strategy-types.d.ts → messaging/reply-strategy-types.d.ts} +10 -1
- package/dist/src/{reply-strategy-with-reaction.d.ts → messaging/reply-strategy-with-reaction.d.ts} +1 -1
- package/dist/src/{reply-strategy.d.ts → messaging/reply-strategy.d.ts} +1 -1
- package/dist/src/{send-service.d.ts → messaging/send-service.d.ts} +1 -1
- package/dist/src/platform/channel-status.d.ts +1 -1
- package/dist/src/platform/config.d.ts +110 -0
- package/dist/src/platform/runtime-events.d.ts +67 -0
- package/dist/src/{types.d.ts → platform/types.d.ts} +74 -1
- package/dist/src/{persistence-store.d.ts → shared/persistence-store.d.ts} +1 -1
- package/dist/src/{utils.d.ts → shared/utils.d.ts} +1 -1
- package/dist/src/targeting/agent-name-matcher.d.ts +1 -1
- package/dist/src/targeting/agent-routing.d.ts +3 -3
- package/dist/src/{session-routing.d.ts → targeting/session-routing.d.ts} +1 -1
- package/index.ts +193 -69
- package/openclaw.plugin.json +158 -2
- package/package.json +16 -16
- package/src/{ack-reaction-classifier.ts → ack-reaction/ack-reaction-classifier.ts} +85 -13
- package/src/{ack-reaction-service.ts → ack-reaction/ack-reaction-service.ts} +13 -7
- package/src/ack-reaction/dynamic-ack-reaction-controller.ts +46 -31
- package/src/ack-reaction/dynamic-ack-reaction-progress.ts +4 -1
- package/src/card/ask-user-question-context.ts +1 -1
- package/src/card/ask-user-question-store.ts +2 -2
- package/src/card/ask-user-question.ts +11 -7
- package/src/card/card-action-handler.ts +2 -2
- package/src/{card-callback-service.ts → card/card-callback-service.ts} +7 -9
- package/src/card/card-draft-controller.ts +770 -0
- package/src/card/card-markdown-image-reroute.ts +8 -2
- package/src/card/card-run-registry.ts +17 -7
- package/src/{card-service.ts → card/card-service.ts} +91 -61
- package/src/card/card-stop-handler.ts +12 -8
- package/src/card/card-streaming-mode.ts +1 -1
- package/src/card/card-task-progress.ts +330 -0
- package/src/card/draft-stream-loop.ts +119 -0
- package/src/card/reasoning-answer-split.ts +125 -121
- package/src/card/reasoning-block-assembler.ts +122 -123
- package/src/{run-usage-store.ts → card/run-usage-store.ts} +18 -6
- package/src/card/statusline-renderer.ts +14 -5
- package/src/card/task-model-metadata.ts +8 -3
- package/src/channel.ts +14 -16
- package/src/command/card-stop-command.ts +2 -2
- package/src/{feedback-learning-service.ts → command/feedback-learning-service.ts} +36 -16
- package/src/{feedback-learning-store.ts → command/feedback-learning-store.ts} +133 -81
- package/src/command/inbound-command-dispatch-service.ts +12 -6
- package/src/{learning-command-service.ts → command/learning-command-service.ts} +36 -29
- package/src/{session-command-service.ts → command/session-command-service.ts} +3 -1
- package/src/gateway/channel-gateway.ts +106 -28
- package/src/{connection-manager.ts → gateway/connection-manager.ts} +45 -30
- package/src/{docs-service.ts → gateway/docs-service.ts} +5 -5
- package/src/{inbound-handler.ts → gateway/inbound-handler.ts} +139 -84
- package/src/gateway/inbound-session-queue-dispatcher.ts +18 -14
- package/src/{session-lock.ts → gateway/session-lock.ts} +14 -14
- package/src/messaging/attachment-text-extractor.ts +21 -7
- package/src/messaging/btw-deliver.ts +2 -2
- package/src/messaging/channel-actions.ts +15 -7
- package/src/messaging/channel-outbound.ts +16 -11
- package/src/{media-utils.ts → messaging/media-utils.ts} +276 -72
- package/src/{message-context-store.ts → messaging/message-context-store.ts} +11 -2
- package/src/{message-utils.ts → messaging/message-utils.ts} +46 -11
- package/src/messaging/quoted-context.ts +2 -2
- package/src/messaging/quoted-file-service.ts +311 -294
- package/src/messaging/quoted-ref.ts +11 -7
- package/src/{reply-strategy-card.ts → messaging/reply-strategy-card.ts} +178 -101
- package/src/{reply-strategy-markdown.ts → messaging/reply-strategy-markdown.ts} +8 -2
- package/src/{reply-strategy-types.ts → messaging/reply-strategy-types.ts} +11 -1
- package/src/{reply-strategy-with-reaction.ts → messaging/reply-strategy-with-reaction.ts} +6 -1
- package/src/{reply-strategy.ts → messaging/reply-strategy.ts} +2 -2
- package/src/{send-service.ts → messaging/send-service.ts} +100 -65
- package/src/{auth.ts → platform/auth.ts} +2 -2
- package/src/platform/channel-status.ts +3 -3
- package/src/{config-schema.ts → platform/config-schema.ts} +81 -4
- package/src/{config.ts → platform/config.ts} +167 -19
- package/src/{device-registration.ts → platform/device-registration.ts} +5 -4
- package/src/{onboarding.ts → platform/onboarding.ts} +1 -4
- package/src/{plugin-sdk-channel-actions-augment.ts → platform/plugin-sdk-channel-actions-augment.ts} +6 -5
- package/src/platform/runtime-events.ts +202 -0
- package/src/{secret-input.ts → platform/secret-input.ts} +117 -11
- package/src/{types.ts → platform/types.ts} +76 -1
- package/src/{http-client.ts → shared/http-client.ts} +1 -3
- package/src/{persistence-store.ts → shared/persistence-store.ts} +6 -6
- package/src/{utils.ts → shared/utils.ts} +30 -13
- package/src/targeting/agent-name-matcher.ts +1 -1
- package/src/targeting/agent-routing.ts +7 -7
- package/src/targeting/group-members-store.ts +1 -1
- package/src/{session-peer-store.ts → targeting/session-peer-store.ts} +9 -4
- package/src/{session-routing.ts → targeting/session-routing.ts} +1 -1
- package/src/targeting/target-directory-adapter.ts +3 -3
- package/src/targeting/target-directory-store.ts +1 -1
- package/src/targeting/target-input.ts +1 -1
- package/dist/src/ack-reaction/dynamic-ack-reaction-events.d.ts +0 -35
- package/dist/src/config.d.ts +0 -59
- package/src/ack-reaction/dynamic-ack-reaction-events.ts +0 -123
- package/src/card-draft-controller.ts +0 -637
- package/src/draft-stream-loop.ts +0 -119
- /package/dist/src/{ack-reaction-classifier.d.ts → ack-reaction/ack-reaction-classifier.d.ts} +0 -0
- /package/dist/src/{card-callback-service.d.ts → card/card-callback-service.d.ts} +0 -0
- /package/dist/src/{draft-stream-loop.d.ts → card/draft-stream-loop.d.ts} +0 -0
- /package/dist/src/{run-usage-store.d.ts → card/run-usage-store.d.ts} +0 -0
- /package/dist/src/{feedback-learning-store.d.ts → command/feedback-learning-store.d.ts} +0 -0
- /package/dist/src/{session-command-service.d.ts → command/session-command-service.d.ts} +0 -0
- /package/dist/src/{session-lock.d.ts → gateway/session-lock.d.ts} +0 -0
- /package/dist/src/{proactive-risk-registry.d.ts → messaging/proactive-risk-registry.d.ts} +0 -0
- /package/dist/src/{reply-strategy-markdown.d.ts → messaging/reply-strategy-markdown.d.ts} +0 -0
- /package/dist/src/{access-control.d.ts → platform/access-control.d.ts} +0 -0
- /package/dist/src/{auth.d.ts → platform/auth.d.ts} +0 -0
- /package/dist/src/{config-schema.d.ts → platform/config-schema.d.ts} +0 -0
- /package/dist/src/{device-registration.d.ts → platform/device-registration.d.ts} +0 -0
- /package/dist/src/{logger-context.d.ts → platform/logger-context.d.ts} +0 -0
- /package/dist/src/{onboarding.d.ts → platform/onboarding.d.ts} +0 -0
- /package/dist/src/{plugin-sdk-channel-actions-augment.d.ts → platform/plugin-sdk-channel-actions-augment.d.ts} +0 -0
- /package/dist/src/{runtime.d.ts → platform/runtime.d.ts} +0 -0
- /package/dist/src/{secret-input.d.ts → platform/secret-input.d.ts} +0 -0
- /package/dist/src/{session-state.d.ts → platform/session-state.d.ts} +0 -0
- /package/dist/src/{signature.d.ts → platform/signature.d.ts} +0 -0
- /package/dist/src/{dedup.d.ts → shared/dedup.d.ts} +0 -0
- /package/dist/src/{http-client.d.ts → shared/http-client.d.ts} +0 -0
- /package/dist/src/{path-utils.d.ts → shared/path-utils.d.ts} +0 -0
- /package/dist/src/{peer-id-registry.d.ts → targeting/peer-id-registry.d.ts} +0 -0
- /package/dist/src/{session-peer-store.d.ts → targeting/session-peer-store.d.ts} +0 -0
- /package/src/{proactive-risk-registry.ts → messaging/proactive-risk-registry.ts} +0 -0
- /package/src/{access-control.ts → platform/access-control.ts} +0 -0
- /package/src/{logger-context.ts → platform/logger-context.ts} +0 -0
- /package/src/{runtime.ts → platform/runtime.ts} +0 -0
- /package/src/{session-state.ts → platform/session-state.ts} +0 -0
- /package/src/{signature.ts → platform/signature.ts} +0 -0
- /package/src/{dedup.ts → shared/dedup.ts} +0 -0
- /package/src/{path-utils.ts → shared/path-utils.ts} +0 -0
- /package/src/{peer-id-registry.ts → targeting/peer-id-registry.ts} +0 -0
|
@@ -1,162 +1,166 @@
|
|
|
1
1
|
export interface CardReasoningAnswerSplit {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
reasoningText?: string;
|
|
3
|
+
answerText?: string;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
const THINKING_TAG_RE = /<\s*(\/?)\s*(?:think(?:ing)?|thought|antthinking)\b[^<>]*>/gi;
|
|
7
7
|
|
|
8
8
|
function isWrappedReasoningLine(line: string): boolean {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
const trimmed = line.trim();
|
|
10
|
+
return trimmed.startsWith("_") && trimmed.endsWith("_") && trimmed.length >= 3;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
function cleanReasoningLine(line: string): string {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
const trimmed = line.trim();
|
|
15
|
+
if (!trimmed) {
|
|
16
|
+
return "";
|
|
17
|
+
}
|
|
18
|
+
return trimmed.replace(/^_/, "").replace(/_$/, "").trim();
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
function joinAnswerParts(parts: string[]): string | undefined {
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
const joined = parts
|
|
23
|
+
.map((part) => part.trim())
|
|
24
|
+
.filter(Boolean)
|
|
25
|
+
.join("\n\n")
|
|
26
|
+
.trim();
|
|
27
|
+
return joined || undefined;
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
function hasStructuredMarkdown(text: string): boolean {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
const trimmed = text.trim();
|
|
32
|
+
if (!trimmed) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
return (
|
|
36
|
+
trimmed.includes("**") ||
|
|
37
|
+
trimmed.includes("```") ||
|
|
38
|
+
/(^|\n)\s*(?:[-*+]\s|#{1,6}\s|>\s|\d+\.\s)/.test(trimmed)
|
|
39
|
+
);
|
|
36
40
|
}
|
|
37
41
|
|
|
38
42
|
function splitTopLevelReasoningPrefix(text: string): CardReasoningAnswerSplit | null {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
const markerIndex = text.indexOf("Reasoning:");
|
|
44
|
+
if (markerIndex < 0) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const before = text.slice(0, markerIndex).trim();
|
|
49
|
+
if (before && hasStructuredMarkdown(before)) {
|
|
50
|
+
return {
|
|
51
|
+
answerText: text,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const trailing = text.slice(markerIndex + "Reasoning:".length);
|
|
56
|
+
const lines = trailing.split("\n");
|
|
57
|
+
const reasoningLines: string[] = [];
|
|
58
|
+
let started = false;
|
|
59
|
+
let remainderIndex = -1;
|
|
43
60
|
|
|
44
|
-
|
|
45
|
-
|
|
61
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
62
|
+
const line = lines[index];
|
|
63
|
+
const trimmed = line.trim();
|
|
64
|
+
|
|
65
|
+
if (!started) {
|
|
66
|
+
if (!trimmed) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (!isWrappedReasoningLine(trimmed)) {
|
|
46
70
|
return {
|
|
47
|
-
|
|
71
|
+
answerText: text,
|
|
48
72
|
};
|
|
73
|
+
}
|
|
74
|
+
started = true;
|
|
75
|
+
reasoningLines.push(cleanReasoningLine(trimmed));
|
|
76
|
+
continue;
|
|
49
77
|
}
|
|
50
78
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const reasoningLines: string[] = [];
|
|
54
|
-
let started = false;
|
|
55
|
-
let remainderIndex = -1;
|
|
56
|
-
|
|
57
|
-
for (let index = 0; index < lines.length; index += 1) {
|
|
58
|
-
const line = lines[index];
|
|
59
|
-
const trimmed = line.trim();
|
|
60
|
-
|
|
61
|
-
if (!started) {
|
|
62
|
-
if (!trimmed) {
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
if (!isWrappedReasoningLine(trimmed)) {
|
|
66
|
-
return {
|
|
67
|
-
answerText: text,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
started = true;
|
|
71
|
-
reasoningLines.push(cleanReasoningLine(trimmed));
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (!trimmed) {
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (isWrappedReasoningLine(trimmed)) {
|
|
80
|
-
reasoningLines.push(cleanReasoningLine(trimmed));
|
|
81
|
-
continue;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
remainderIndex = index;
|
|
85
|
-
break;
|
|
79
|
+
if (!trimmed) {
|
|
80
|
+
continue;
|
|
86
81
|
}
|
|
87
82
|
|
|
88
|
-
if (
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
};
|
|
83
|
+
if (isWrappedReasoningLine(trimmed)) {
|
|
84
|
+
reasoningLines.push(cleanReasoningLine(trimmed));
|
|
85
|
+
continue;
|
|
92
86
|
}
|
|
93
87
|
|
|
94
|
-
|
|
88
|
+
remainderIndex = index;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (reasoningLines.length === 0) {
|
|
95
93
|
return {
|
|
96
|
-
|
|
97
|
-
answerText: joinAnswerParts([before, after]),
|
|
94
|
+
answerText: text,
|
|
98
95
|
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const after = remainderIndex >= 0 ? lines.slice(remainderIndex).join("\n").trim() : "";
|
|
99
|
+
return {
|
|
100
|
+
reasoningText: reasoningLines.join("\n").trim() || undefined,
|
|
101
|
+
answerText: joinAnswerParts([before, after]),
|
|
102
|
+
};
|
|
99
103
|
}
|
|
100
104
|
|
|
101
105
|
function splitTopLevelThinkingTags(text: string): CardReasoningAnswerSplit | null {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (inThinking) {
|
|
116
|
-
reasoning += segment;
|
|
117
|
-
} else {
|
|
118
|
-
answer += segment;
|
|
119
|
-
}
|
|
120
|
-
inThinking = match[1] !== "/";
|
|
121
|
-
lastIndex = matchIndex + match[0].length;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const tail = text.slice(lastIndex);
|
|
106
|
+
if (!THINKING_TAG_RE.test(text)) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
THINKING_TAG_RE.lastIndex = 0;
|
|
110
|
+
|
|
111
|
+
let reasoning = "";
|
|
112
|
+
let answer = "";
|
|
113
|
+
let lastIndex = 0;
|
|
114
|
+
let inThinking = false;
|
|
115
|
+
|
|
116
|
+
for (const match of text.matchAll(THINKING_TAG_RE)) {
|
|
117
|
+
const matchIndex = match.index ?? 0;
|
|
118
|
+
const segment = text.slice(lastIndex, matchIndex);
|
|
125
119
|
if (inThinking) {
|
|
126
|
-
|
|
120
|
+
reasoning += segment;
|
|
127
121
|
} else {
|
|
128
|
-
|
|
122
|
+
answer += segment;
|
|
129
123
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
124
|
+
inThinking = match[1] !== "/";
|
|
125
|
+
lastIndex = matchIndex + match[0].length;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const tail = text.slice(lastIndex);
|
|
129
|
+
if (inThinking) {
|
|
130
|
+
reasoning += tail;
|
|
131
|
+
} else {
|
|
132
|
+
answer += tail;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const cleanedReasoning = reasoning.trim();
|
|
136
|
+
if (!cleanedReasoning) {
|
|
138
137
|
return {
|
|
139
|
-
|
|
140
|
-
answerText: answer.trim() || undefined,
|
|
138
|
+
answerText: text,
|
|
141
139
|
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
reasoningText: cleanedReasoning,
|
|
144
|
+
answerText: answer.trim() || undefined,
|
|
145
|
+
};
|
|
142
146
|
}
|
|
143
147
|
|
|
144
148
|
export function splitCardReasoningAnswerText(text?: string): CardReasoningAnswerSplit {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
149
|
+
if (typeof text !== "string") {
|
|
150
|
+
return {};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const prefixed = splitTopLevelReasoningPrefix(text);
|
|
154
|
+
if (prefixed) {
|
|
155
|
+
return prefixed;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const tagged = splitTopLevelThinkingTags(text);
|
|
159
|
+
if (tagged) {
|
|
160
|
+
return tagged;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
answerText: text,
|
|
165
|
+
};
|
|
162
166
|
}
|
|
@@ -1,157 +1,156 @@
|
|
|
1
1
|
export interface ReasoningBlockAssembler {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
ingestSnapshot: (text: string | undefined) => string[];
|
|
3
|
+
flushPendingAtBoundary: () => string[];
|
|
4
|
+
reset: () => void;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
function stripReasoningPrefix(text: string): string {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
const trimmed = text.trim();
|
|
9
|
+
if (trimmed.startsWith("Reasoning:")) {
|
|
10
|
+
return trimmed.slice("Reasoning:".length).trimStart();
|
|
11
|
+
}
|
|
12
|
+
return trimmed;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
function cleanReasoningLine(line: string): string {
|
|
16
|
-
|
|
16
|
+
return line.trim().replace(/^_/, "").replace(/_$/, "").trim();
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
function isClosedReasoningLine(line: string): boolean {
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
const trimmed = line.trim();
|
|
21
|
+
return trimmed.startsWith("_") && trimmed.endsWith("_") && trimmed.length >= 2;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
function startsReasonBlock(line: string): boolean {
|
|
25
|
-
|
|
25
|
+
return cleanReasoningLine(line).startsWith("Reason:");
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function blocksStartWithPrefix(blocks: string[], prefix: string[]): boolean {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
if (prefix.length > blocks.length) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
return prefix.every((entry, index) => blocks[index] === entry);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
function parseReasoningSnapshot(text: string | undefined): {
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
completeBlocks: string[];
|
|
37
|
+
pendingBlock: string;
|
|
38
38
|
} {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const lines = normalized
|
|
48
|
-
.split("\n")
|
|
49
|
-
.map((line) => line.trim())
|
|
50
|
-
.filter((line) => line.length > 0);
|
|
51
|
-
|
|
52
|
-
const completeBlocks: string[] = [];
|
|
53
|
-
let currentLines: string[] = [];
|
|
54
|
-
let currentMode: "explicit" | "implicit" | null = null;
|
|
55
|
-
let currentComplete = true;
|
|
56
|
-
|
|
57
|
-
const finalizeCurrent = () => {
|
|
58
|
-
if (currentLines.length === 0) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
if (currentMode === "explicit" && currentComplete) {
|
|
62
|
-
completeBlocks.push(currentLines.join("\n"));
|
|
63
|
-
}
|
|
39
|
+
const normalized = typeof text === "string" ? stripReasoningPrefix(text) : "";
|
|
40
|
+
if (!normalized.trim()) {
|
|
41
|
+
return {
|
|
42
|
+
completeBlocks: [],
|
|
43
|
+
pendingBlock: "",
|
|
64
44
|
};
|
|
45
|
+
}
|
|
65
46
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (currentLines.length === 0) {
|
|
76
|
-
const trimmedLine = line.trim();
|
|
77
|
-
const cleanedLine = cleanReasoningLine(line);
|
|
78
|
-
if (!cleanedLine) {
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
if (!trimmedLine.startsWith("_")) {
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
currentLines = [cleanedLine];
|
|
85
|
-
currentMode = "implicit";
|
|
86
|
-
currentComplete = false;
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
currentLines.push(cleanReasoningLine(line));
|
|
91
|
-
currentComplete = currentMode === "explicit"
|
|
92
|
-
? currentComplete && isClosedReasoningLine(line)
|
|
93
|
-
: false;
|
|
94
|
-
}
|
|
47
|
+
const lines = normalized
|
|
48
|
+
.split("\n")
|
|
49
|
+
.map((line) => line.trim())
|
|
50
|
+
.filter((line) => line.length > 0);
|
|
51
|
+
|
|
52
|
+
const completeBlocks: string[] = [];
|
|
53
|
+
let currentLines: string[] = [];
|
|
54
|
+
let currentMode: "explicit" | "implicit" | null = null;
|
|
55
|
+
let currentComplete = true;
|
|
95
56
|
|
|
57
|
+
const finalizeCurrent = () => {
|
|
96
58
|
if (currentLines.length === 0) {
|
|
97
|
-
|
|
98
|
-
completeBlocks,
|
|
99
|
-
pendingBlock: "",
|
|
100
|
-
};
|
|
59
|
+
return;
|
|
101
60
|
}
|
|
102
|
-
|
|
103
61
|
if (currentMode === "explicit" && currentComplete) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
62
|
+
completeBlocks.push(currentLines.join("\n"));
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
for (const line of lines) {
|
|
67
|
+
if (startsReasonBlock(line)) {
|
|
68
|
+
finalizeCurrent();
|
|
69
|
+
currentLines = [cleanReasoningLine(line)];
|
|
70
|
+
currentMode = "explicit";
|
|
71
|
+
currentComplete = isClosedReasoningLine(line);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (currentLines.length === 0) {
|
|
76
|
+
const trimmedLine = line.trim();
|
|
77
|
+
const cleanedLine = cleanReasoningLine(line);
|
|
78
|
+
if (!cleanedLine) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (!trimmedLine.startsWith("_")) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
currentLines = [cleanedLine];
|
|
85
|
+
currentMode = "implicit";
|
|
86
|
+
currentComplete = false;
|
|
87
|
+
continue;
|
|
109
88
|
}
|
|
110
89
|
|
|
90
|
+
currentLines.push(cleanReasoningLine(line));
|
|
91
|
+
currentComplete =
|
|
92
|
+
currentMode === "explicit" ? currentComplete && isClosedReasoningLine(line) : false;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (currentLines.length === 0) {
|
|
111
96
|
return {
|
|
112
|
-
|
|
113
|
-
|
|
97
|
+
completeBlocks,
|
|
98
|
+
pendingBlock: "",
|
|
114
99
|
};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export function createReasoningBlockAssembler(): ReasoningBlockAssembler {
|
|
118
|
-
let emittedBlocks: string[] = [];
|
|
119
|
-
let pendingBlock = "";
|
|
100
|
+
}
|
|
120
101
|
|
|
102
|
+
if (currentMode === "explicit" && currentComplete) {
|
|
103
|
+
completeBlocks.push(currentLines.join("\n"));
|
|
121
104
|
return {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
pendingBlock = parsed.pendingBlock;
|
|
125
|
-
|
|
126
|
-
if (parsed.completeBlocks.length === 0) {
|
|
127
|
-
return [];
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (blocksStartWithPrefix(parsed.completeBlocks, emittedBlocks)) {
|
|
131
|
-
const nextBlocks = parsed.completeBlocks.slice(emittedBlocks.length);
|
|
132
|
-
emittedBlocks = [...parsed.completeBlocks];
|
|
133
|
-
return nextBlocks;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (blocksStartWithPrefix(emittedBlocks, parsed.completeBlocks)) {
|
|
137
|
-
return [];
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return [];
|
|
141
|
-
},
|
|
142
|
-
|
|
143
|
-
flushPendingAtBoundary(): string[] {
|
|
144
|
-
if (!pendingBlock.trim()) {
|
|
145
|
-
return [];
|
|
146
|
-
}
|
|
147
|
-
const flushed = pendingBlock;
|
|
148
|
-
pendingBlock = "";
|
|
149
|
-
return [flushed];
|
|
150
|
-
},
|
|
151
|
-
|
|
152
|
-
reset(): void {
|
|
153
|
-
emittedBlocks = [];
|
|
154
|
-
pendingBlock = "";
|
|
155
|
-
},
|
|
105
|
+
completeBlocks,
|
|
106
|
+
pendingBlock: "",
|
|
156
107
|
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
completeBlocks,
|
|
112
|
+
pendingBlock: currentLines.join("\n").trim(),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function createReasoningBlockAssembler(): ReasoningBlockAssembler {
|
|
117
|
+
let emittedBlocks: string[] = [];
|
|
118
|
+
let pendingBlock = "";
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
ingestSnapshot(text: string | undefined): string[] {
|
|
122
|
+
const parsed = parseReasoningSnapshot(text);
|
|
123
|
+
pendingBlock = parsed.pendingBlock;
|
|
124
|
+
|
|
125
|
+
if (parsed.completeBlocks.length === 0) {
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (blocksStartWithPrefix(parsed.completeBlocks, emittedBlocks)) {
|
|
130
|
+
const nextBlocks = parsed.completeBlocks.slice(emittedBlocks.length);
|
|
131
|
+
emittedBlocks = [...parsed.completeBlocks];
|
|
132
|
+
return nextBlocks;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (blocksStartWithPrefix(emittedBlocks, parsed.completeBlocks)) {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return [];
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
flushPendingAtBoundary(): string[] {
|
|
143
|
+
if (!pendingBlock.trim()) {
|
|
144
|
+
return [];
|
|
145
|
+
}
|
|
146
|
+
const flushed = pendingBlock;
|
|
147
|
+
pendingBlock = "";
|
|
148
|
+
return [flushed];
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
reset(): void {
|
|
152
|
+
emittedBlocks = [];
|
|
153
|
+
pendingBlock = "";
|
|
154
|
+
},
|
|
155
|
+
};
|
|
157
156
|
}
|
|
@@ -16,7 +16,9 @@ export function recordRunStart(runId: string): void {
|
|
|
16
16
|
|
|
17
17
|
export function accumulateUsage(runId: string, usage: UsageAccumulation): void {
|
|
18
18
|
const existing = usageStore.get(runId);
|
|
19
|
-
if (!existing) {
|
|
19
|
+
if (!existing) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
20
22
|
|
|
21
23
|
for (const field of ["input", "output", "cacheRead", "cacheWrite", "total"] as const) {
|
|
22
24
|
const value = usage[field];
|
|
@@ -32,10 +34,14 @@ export function getUsageByRunId(runId: string): UsageAccumulation | undefined {
|
|
|
32
34
|
|
|
33
35
|
export function getAggregatedUsage(runIds: Set<string> | undefined): UsageAccumulation {
|
|
34
36
|
const result: UsageAccumulation = {};
|
|
35
|
-
if (!runIds) {
|
|
37
|
+
if (!runIds) {
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
36
40
|
for (const runId of runIds) {
|
|
37
41
|
const usage = usageStore.get(runId);
|
|
38
|
-
if (!usage) {
|
|
42
|
+
if (!usage) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
39
45
|
for (const field of ["input", "output", "cacheRead", "cacheWrite", "total"] as const) {
|
|
40
46
|
if (typeof usage[field] === "number") {
|
|
41
47
|
result[field] = (result[field] ?? 0) + usage[field];
|
|
@@ -46,12 +52,18 @@ export function getAggregatedUsage(runIds: Set<string> | undefined): UsageAccumu
|
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
export function clearRun(runId: string | undefined): void {
|
|
49
|
-
if (runId) {
|
|
55
|
+
if (runId) {
|
|
56
|
+
usageStore.delete(runId);
|
|
57
|
+
}
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
export function clearRuns(runIds: Set<string> | undefined): void {
|
|
53
|
-
if (!runIds) {
|
|
54
|
-
|
|
61
|
+
if (!runIds) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
for (const runId of runIds) {
|
|
65
|
+
usageStore.delete(runId);
|
|
66
|
+
}
|
|
55
67
|
}
|
|
56
68
|
|
|
57
69
|
export function clearAllForTest(): void {
|
|
@@ -67,8 +67,16 @@ const SEGMENTS: Segment[] = [
|
|
|
67
67
|
{ key: "effort", defaultOn: true, render: (d) => d.effort || undefined },
|
|
68
68
|
{ key: "agent", defaultOn: true, render: (d) => d.agent || undefined },
|
|
69
69
|
{ key: "tokens", defaultOn: false, render: renderTokenSegment },
|
|
70
|
-
{
|
|
71
|
-
|
|
70
|
+
{
|
|
71
|
+
key: "taskTime",
|
|
72
|
+
defaultOn: false,
|
|
73
|
+
render: (d) => (typeof d.taskTime === "number" ? formatDuration(d.taskTime) : undefined),
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
key: "dapiUsage",
|
|
77
|
+
defaultOn: false,
|
|
78
|
+
render: (d) => (typeof d.dapi_usage === "number" ? `DAPI+${d.dapi_usage}` : undefined),
|
|
79
|
+
},
|
|
72
80
|
];
|
|
73
81
|
|
|
74
82
|
const SEGMENTS_PER_LINE = 3;
|
|
@@ -79,12 +87,13 @@ function resolveSegmentEnabled(seg: Segment, config: StatusLineConfig): boolean
|
|
|
79
87
|
}
|
|
80
88
|
|
|
81
89
|
export function renderStatusLine(data: StatusLineData, config: StatusLineConfig): string {
|
|
82
|
-
const rendered = SEGMENTS
|
|
83
|
-
.filter((seg) => resolveSegmentEnabled(seg, config))
|
|
90
|
+
const rendered = SEGMENTS.filter((seg) => resolveSegmentEnabled(seg, config))
|
|
84
91
|
.map((seg) => seg.render(data))
|
|
85
92
|
.filter(Boolean) as string[];
|
|
86
93
|
|
|
87
|
-
if (rendered.length === 0) {
|
|
94
|
+
if (rendered.length === 0) {
|
|
95
|
+
return "";
|
|
96
|
+
}
|
|
88
97
|
|
|
89
98
|
const lines: string[] = [];
|
|
90
99
|
for (let i = 0; i < rendered.length; i += SEGMENTS_PER_LINE) {
|
|
@@ -22,7 +22,10 @@ export function normalizeModelDisplayName(modelRef: string | undefined): string
|
|
|
22
22
|
if (!trimmed) {
|
|
23
23
|
return undefined;
|
|
24
24
|
}
|
|
25
|
-
const parts = trimmed
|
|
25
|
+
const parts = trimmed
|
|
26
|
+
.split("/")
|
|
27
|
+
.map((part) => part.trim())
|
|
28
|
+
.filter(Boolean);
|
|
26
29
|
return parts.at(-1) || undefined;
|
|
27
30
|
}
|
|
28
31
|
|
|
@@ -36,11 +39,13 @@ export function resolveConfiguredTaskModelMetadata(params: {
|
|
|
36
39
|
? agents.list.find((entry) => String(entry.id || "").trim() === agentId)
|
|
37
40
|
: undefined;
|
|
38
41
|
|
|
39
|
-
const modelRef =
|
|
42
|
+
const modelRef =
|
|
43
|
+
readPrimaryModelRef(agent?.model) ?? readPrimaryModelRef(agents?.defaults?.model);
|
|
40
44
|
const effort =
|
|
41
45
|
typeof agent?.thinkingDefault === "string" && agent.thinkingDefault.trim()
|
|
42
46
|
? agent.thinkingDefault.trim()
|
|
43
|
-
: typeof agents?.defaults?.thinkingDefault === "string" &&
|
|
47
|
+
: typeof agents?.defaults?.thinkingDefault === "string" &&
|
|
48
|
+
agents.defaults.thinkingDefault.trim()
|
|
44
49
|
? agents.defaults.thinkingDefault.trim()
|
|
45
50
|
: undefined;
|
|
46
51
|
|