maka-agent 0.2.0-dev.14.20260902 → 0.2.0-dev.16.20260903
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/cli-core.js +0 -1
- package/dist/pi-transcript.js +48 -0
- package/dist/pi-tui-form-interaction.js +497 -0
- package/dist/pi-tui-pickers.js +256 -55
- package/dist/pi-tui-runner.js +215 -12
- package/dist/runtime-host-cli.js +17 -42
- package/dist/runtime-host-lifecycle-transaction.js +31 -13
- package/dist/runtime-host-managed-lifecycle-manager.js +1 -1
- package/dist/runtime-host-onboarding.js +3 -1
- package/dist/runtime-host-openrc-service.js +469 -0
- package/dist/runtime-host-run-command.js +6 -2
- package/dist/runtime-host-service-command.js +3 -3
- package/dist/runtime-host-service-management-command.js +43 -15
- package/dist/runtime-host-session-channel.js +3 -0
- package/dist/runtime-host-session-driver.js +21 -6
- package/dist/runtime-host-setup-command.js +30 -31
- package/dist/tui-context-refresh.js +103 -0
- package/dist/tui-copy-catalog.js +73 -0
- package/native/runtime-host-peer/prebuilds/darwin-arm64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/linux-arm64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/linux-x64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/win32-x64/maka_runtime_host_peer.node +0 -0
- package/node_modules/@maka/core/dist/chat-model-choice.js +4 -0
- package/node_modules/@maka/core/dist/computer-use.js +27 -92
- package/node_modules/@maka/core/dist/interaction.js +577 -3
- package/node_modules/@maka/core/dist/llm-connections.js +4 -0
- package/node_modules/@maka/core/dist/local-memory.js +2 -2
- package/node_modules/@maka/core/dist/model-call-usage-projection.js +3 -0
- package/node_modules/@maka/core/dist/model-metadata.js +26 -7
- package/node_modules/@maka/core/dist/model-thinking.js +17 -0
- package/node_modules/@maka/core/dist/provider-registry.js +1 -0
- package/node_modules/@maka/core/dist/runtime-event.js +23 -1
- package/node_modules/@maka/core/dist/scheduled-task.js +4 -0
- package/node_modules/@maka/core/dist/session.js +95 -2
- package/node_modules/@maka/core/dist/text-sanitize.js +19 -0
- package/node_modules/@maka/core/dist/usage-ledger-merge.js +3 -0
- package/node_modules/@maka/core/dist/usage-record-schema.js +11 -5
- package/node_modules/@maka/core/dist/workhub-creation-intent.js +75 -9
- package/node_modules/@maka/core/dist/workhub-session-resolver.js +50 -0
- package/node_modules/@maka/core/package.json +2 -0
- package/node_modules/@maka/eval/dist/harbor-external-subject.js +2 -1
- package/node_modules/@maka/eval/dist/harness-executor.js +3 -2
- package/node_modules/@maka/eval/dist/install-preflight.js +39 -10
- package/node_modules/@maka/eval/dist/process-termination.js +83 -0
- package/node_modules/@maka/mcp/dist/sep-2243.js +3 -3
- package/node_modules/@maka/runtime/dist/agent-run.js +6 -3
- package/node_modules/@maka/runtime/dist/ai-sdk-backend.js +332 -118
- package/node_modules/@maka/runtime/dist/ai-sdk-compaction-contract.js +6 -1
- package/node_modules/@maka/runtime/dist/ai-sdk-compaction.js +171 -341
- package/node_modules/@maka/runtime/dist/bots/telegram-bridge.js +3 -26
- package/node_modules/@maka/runtime/dist/bundled-skill-catalog.generated.js +1 -1
- package/node_modules/@maka/runtime/dist/computer-use-codec.js +1 -141
- package/node_modules/@maka/runtime/dist/computer-use-tools.js +23 -105
- package/node_modules/@maka/runtime/dist/context-budget-policy.js +20 -26
- package/node_modules/@maka/runtime/dist/context-budget.js +18 -20
- package/node_modules/@maka/runtime/dist/conversation-copy.js +23 -19
- package/node_modules/@maka/runtime/dist/cua-frame-state.js +1 -69
- package/node_modules/@maka/runtime/dist/github-copilot-oauth-enrollment.js +267 -0
- package/node_modules/@maka/runtime/dist/history-compact-checkpoint.js +6 -9
- package/node_modules/@maka/runtime/dist/history-compact-summarizer.js +67 -23
- package/node_modules/@maka/runtime/dist/history-compact-summary-validation.js +11 -18
- package/node_modules/@maka/runtime/dist/history-compaction.js +66 -73
- package/node_modules/@maka/runtime/dist/interaction-authority.js +69 -0
- package/node_modules/@maka/runtime/dist/mcp-tools.js +13 -1
- package/node_modules/@maka/runtime/dist/memory-extraction.js +11 -11
- package/node_modules/@maka/runtime/dist/model-adapter.js +24 -6
- package/node_modules/@maka/runtime/dist/model-factory.js +14 -5
- package/node_modules/@maka/runtime/dist/oauth-provider-contracts.js +28 -1
- package/node_modules/@maka/runtime/dist/openai-codex-history-compactor.js +7 -6
- package/node_modules/@maka/runtime/dist/opencode-session-header.js +29 -0
- package/node_modules/@maka/runtime/dist/runtime-event-read-model.js +11 -1
- package/node_modules/@maka/runtime/dist/runtime-kernel.js +12 -11
- package/node_modules/@maka/runtime/dist/runtime-read-model.js +51 -13
- package/node_modules/@maka/runtime/dist/scheduled-task-tools.js +3 -0
- package/node_modules/@maka/runtime/dist/session-event-runtime-mapper.js +26 -0
- package/node_modules/@maka/runtime/dist/session-manager.js +1 -0
- package/node_modules/@maka/runtime/dist/session-projection-helpers.js +16 -1
- package/node_modules/@maka/runtime/dist/stream-graph-projection.js +6 -0
- package/node_modules/@maka/runtime/dist/stream-graph-read-model.js +5 -0
- package/node_modules/@maka/runtime/dist/stream-usage-fallback-fetch.js +74 -0
- package/node_modules/@maka/runtime/dist/subscription-credentials.js +51 -4
- package/node_modules/@maka/runtime/dist/subscription-model-fetch.js +47 -3
- package/node_modules/@maka/runtime/dist/system-prompt/main-session-prompt.js +20 -1
- package/node_modules/@maka/runtime/dist/test-connection.js +18 -11
- package/node_modules/@maka/runtime/dist/tool-runtime.js +183 -0
- package/node_modules/@maka/runtime/package.json +1 -0
- package/node_modules/@maka/runtime-host/dist/adapter/session-projector.js +14 -0
- package/node_modules/@maka/runtime-host/dist/client/client-capability-channel.js +84 -1
- package/node_modules/@maka/runtime-host/dist/client/host-profile.js +68 -51
- package/node_modules/@maka/runtime-host/dist/client/index.js +1 -1
- package/node_modules/@maka/runtime-host/dist/client/owner-connection-code.js +8 -5
- package/node_modules/@maka/runtime-host/dist/client/peer-client.js +342 -36
- package/node_modules/@maka/runtime-host/dist/client/reconnect-lifecycle.js +60 -4
- package/node_modules/@maka/runtime-host/dist/peer-mesh/index.js +3 -3
- package/node_modules/@maka/runtime-host/dist/peer-mesh/limits.js +1 -1
- package/node_modules/@maka/runtime-host/dist/peer-mesh/model.js +48 -60
- package/node_modules/@maka/runtime-host/dist/peer-mesh/node.js +847 -431
- package/node_modules/@maka/runtime-host/dist/peer-mesh/owner.js +33 -74
- package/node_modules/@maka/runtime-host/dist/peer-mesh/store.js +82 -69
- package/node_modules/@maka/runtime-host/dist/peer-reachability/index.js +21 -0
- package/node_modules/@maka/runtime-host/dist/peer-reachability/model.js +202 -0
- package/node_modules/@maka/runtime-host/dist/peer-reachability/owner.js +119 -0
- package/node_modules/@maka/runtime-host/dist/peer-reachability/publisher.js +245 -0
- package/node_modules/@maka/runtime-host/dist/protocol/agent-graph.js +4 -1
- package/node_modules/@maka/runtime-host/dist/protocol/client-capability.js +68 -0
- package/node_modules/@maka/runtime-host/dist/protocol/connection-effects.js +15 -8
- package/node_modules/@maka/runtime-host/dist/protocol/host-status.js +7 -23
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +47 -1
- package/node_modules/@maka/runtime-host/dist/protocol/oauth.js +25 -1
- package/node_modules/@maka/runtime-host/dist/protocol/operations.js +1 -0
- package/node_modules/@maka/runtime-host/dist/protocol/peer-mesh.js +14 -31
- package/node_modules/@maka/runtime-host/dist/protocol/scheduled-task.js +19 -6
- package/node_modules/@maka/runtime-host/dist/protocol/session-collaboration.js +36 -1
- package/node_modules/@maka/runtime-host/dist/protocol/session-revision.js +11 -2
- package/node_modules/@maka/runtime-host/dist/protocol/usage-pricing.js +16 -2
- package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +51 -2
- package/node_modules/@maka/runtime-host/dist/server/access-authority.js +35 -2
- package/node_modules/@maka/runtime-host/dist/server/access-credential-store.js +1 -0
- package/node_modules/@maka/runtime-host/dist/server/client-capability-coordinator.js +12 -10
- package/node_modules/@maka/runtime-host/dist/server/client-capability-invocation-broker.js +163 -30
- package/node_modules/@maka/runtime-host/dist/server/connection-effect-coordinator.js +38 -14
- package/node_modules/@maka/runtime-host/dist/server/daily-review-coordinator.js +45 -22
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +78 -20
- package/node_modules/@maka/runtime-host/dist/server/execution-model-authority.js +4 -2
- package/node_modules/@maka/runtime-host/dist/server/execution-model-composition.js +2 -1
- package/node_modules/@maka/runtime-host/dist/server/execution-service.js +49 -28
- package/node_modules/@maka/runtime-host/dist/server/host-kernel.js +3 -6
- package/node_modules/@maka/runtime-host/dist/server/interaction-coordinator.js +130 -27
- package/node_modules/@maka/runtime-host/dist/server/interaction-projection.js +30 -1
- package/node_modules/@maka/runtime-host/dist/server/listener-set.js +2 -4
- package/node_modules/@maka/runtime-host/dist/server/message-coordinator.js +16 -3
- package/node_modules/@maka/runtime-host/dist/server/oauth-coordinator.js +66 -3
- package/node_modules/@maka/runtime-host/dist/server/oauth-execution-authority.js +20 -3
- package/node_modules/@maka/runtime-host/dist/server/peer-listener.js +8 -21
- package/node_modules/@maka/runtime-host/dist/server/peer-mesh-authority.js +1 -1
- package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +6 -3
- package/node_modules/@maka/runtime-host/dist/server/scheduled-task-coordinator.js +72 -12
- package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +48 -18
- package/node_modules/@maka/runtime-host/dist/server/session-turn-access-request-coordinator.js +43 -26
- package/node_modules/@maka/runtime-host/dist/server/usage-pricing-coordinator.js +15 -1
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-action-gate.js +229 -4
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +146 -8
- package/node_modules/@maka/runtime-host/dist/transport/peer-native.js +32 -6
- package/node_modules/@maka/runtime-host/package.json +1 -0
- package/node_modules/@maka/storage/dist/agent-run-store.js +18 -5
- package/node_modules/@maka/storage/dist/codex-session-adapter.js +14 -0
- package/node_modules/@maka/storage/dist/execution-stores.js +5 -0
- package/node_modules/@maka/storage/dist/interaction-store.js +13 -1
- package/node_modules/@maka/storage/dist/runtime-policy/connection-catalog-document.js +9 -3
- package/node_modules/@maka/storage/dist/runtime-policy/coordinator.js +49 -19
- package/node_modules/@maka/storage/dist/runtime-policy/oauth-login-receipt-document.js +3 -1
- package/node_modules/@maka/storage/dist/runtime-policy/onboarding-transaction.js +13 -5
- package/node_modules/@maka/storage/dist/session-copy-cleanup.js +4 -2
- package/node_modules/@maka/storage/dist/session-store.js +39 -6
- package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +16 -9
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-schema.js +30 -3
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-store.js +117 -0
- package/node_modules/@maka/storage/dist/sqlite-usage-store.js +29 -6
- package/node_modules/@maka/storage/dist/usage-stores.js +3 -1
- package/package.json +1 -1
|
@@ -308,6 +308,10 @@ function interactiveOAuthConnectionSlugBase(providerType) {
|
|
|
308
308
|
return 'codex-subscription';
|
|
309
309
|
case 'xai-oauth':
|
|
310
310
|
return 'xai-oauth';
|
|
311
|
+
// Shared with the local `gh` credential import so both routes to a Copilot
|
|
312
|
+
// account land on one Connection instead of two.
|
|
313
|
+
case 'github-copilot':
|
|
314
|
+
return 'github-copilot';
|
|
311
315
|
}
|
|
312
316
|
}
|
|
313
317
|
/** Derive an unused OAuth Connection slug without moving allocation into a surface. */
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
19
|
import { redactSecrets } from './redaction.js';
|
|
20
|
+
import { truncateUtf16Safe } from './text-sanitize.js';
|
|
20
21
|
export const LOCAL_MEMORY_MAX_BYTES = 128 * 1024;
|
|
21
22
|
export const LOCAL_MEMORY_PROMPT_MAX_CHARS = 12_000;
|
|
22
23
|
export const LOCAL_MEMORY_PROMPT_TRUNCATION_MARKER = '[本地记忆已按长度截断]';
|
|
@@ -69,8 +70,7 @@ export function buildLocalMemoryPromptBody(input, context = {}) {
|
|
|
69
70
|
return undefined;
|
|
70
71
|
if (body.length <= LOCAL_MEMORY_PROMPT_MAX_CHARS)
|
|
71
72
|
return body;
|
|
72
|
-
const
|
|
73
|
-
const boundarySafe = /[\uD800-\uDBFF]$/.test(truncated) ? truncated.slice(0, -1) : truncated;
|
|
73
|
+
const boundarySafe = truncateUtf16Safe(body, LOCAL_MEMORY_PROMPT_MAX_CHARS);
|
|
74
74
|
return `${boundarySafe.trimEnd()}\n\n${LOCAL_MEMORY_PROMPT_TRUNCATION_MARKER}`;
|
|
75
75
|
}
|
|
76
76
|
export function appendManualLocalMemoryEntryDraft(currentDraft, input) {
|
|
@@ -106,6 +106,7 @@ export function projectModelCallUsageSummary(attempts, query, now) {
|
|
|
106
106
|
total: 0,
|
|
107
107
|
};
|
|
108
108
|
let totalCostUsd = 0;
|
|
109
|
+
let totalDurationMs = 0;
|
|
109
110
|
let cacheHitRequests = 0;
|
|
110
111
|
let cacheCreateRequests = 0;
|
|
111
112
|
let errorRequests = 0;
|
|
@@ -119,6 +120,7 @@ export function projectModelCallUsageSummary(attempts, query, now) {
|
|
|
119
120
|
totals.reasoning += t.reasoning;
|
|
120
121
|
totals.total += t.total;
|
|
121
122
|
totalCostUsd += pricedCost(attempt);
|
|
123
|
+
totalDurationMs += attempt.latencyMs;
|
|
122
124
|
if (t.cacheRead > 0)
|
|
123
125
|
cacheHitRequests += 1;
|
|
124
126
|
if (t.cacheWrite > 0)
|
|
@@ -130,6 +132,7 @@ export function projectModelCallUsageSummary(attempts, query, now) {
|
|
|
130
132
|
range,
|
|
131
133
|
totalRequests: rows.length,
|
|
132
134
|
totalCostUsd,
|
|
135
|
+
totalDurationMs,
|
|
133
136
|
totalTokens: totals,
|
|
134
137
|
cacheHitRequests,
|
|
135
138
|
cacheCreateRequests,
|
|
@@ -215,11 +215,18 @@ const VOLCENGINE_CODING_PLAN_MODEL_METADATA = {
|
|
|
215
215
|
'kimi-k2.6': planModel('Kimi-K2.6', true, 256_000, 32_000),
|
|
216
216
|
'kimi-k2.7-code': planModel('Kimi-K2.7-Code', true, 256_000, 32_000),
|
|
217
217
|
};
|
|
218
|
+
// Hand-maintained mirror of the official Agent Plan personal plan page
|
|
219
|
+
// (docs.volcengine.com/docs/82379/2366394) and its model release/retirement
|
|
220
|
+
// announcements (82379/2578669, 82379/2578673): the gateway has no
|
|
221
|
+
// model-list endpoint its plan key can reach and models.dev has no snapshot.
|
|
222
|
+
// The page's table lists windows as "1024k"/"128k"; transcribe those
|
|
223
|
+
// literals as 1_024_000/128_000 (its prose "1M" is the same figure rounded).
|
|
224
|
+
// Re-check the page before editing an entry here.
|
|
218
225
|
const VOLCENGINE_AGENT_PLAN_MODEL_METADATA = {
|
|
219
226
|
'ark-code-latest': agentPlanModel('Ark Code Latest', 256_000, 32_000, { vision: true }),
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
'glm-5.3': agentPlanModel('GLM-5.3',
|
|
227
|
+
// The plan page lists "glm-5.3 (glm-latest)": thinking is on by default and
|
|
228
|
+
// cannot be turned off.
|
|
229
|
+
'glm-5.3': agentPlanModel('GLM-5.3', 1_024_000, 128_000),
|
|
223
230
|
'doubao-seed-2.0-mini': agentPlanModel('Doubao Seed 2.0 Mini', 256_000, 128_000, {
|
|
224
231
|
vision: true,
|
|
225
232
|
}),
|
|
@@ -239,11 +246,23 @@ const VOLCENGINE_AGENT_PLAN_MODEL_METADATA = {
|
|
|
239
246
|
'doubao-seed-2.0-pro': agentPlanModel('Doubao Seed 2.0 Pro', 256_000, 128_000, {
|
|
240
247
|
lifecycle: 'deprecated',
|
|
241
248
|
}),
|
|
242
|
-
'minimax-m2.7': agentPlanModel('MiniMax-M2.7', 200_000, 128_000
|
|
243
|
-
|
|
244
|
-
|
|
249
|
+
'minimax-m2.7': agentPlanModel('MiniMax-M2.7', 200_000, 128_000, {
|
|
250
|
+
// Upstream retirement notice of 2026-08-04; the gateway routes to minimax-m3.
|
|
251
|
+
lifecycle: 'deprecated',
|
|
252
|
+
}),
|
|
253
|
+
'minimax-m3': agentPlanModel('MiniMax-M3', 1_024_000, 128_000, { vision: true }),
|
|
254
|
+
'glm-5.2': agentPlanModel('GLM-5.2', 1_024_000, 128_000, {
|
|
255
|
+
// Upstream service ended 2026-08-31; the gateway routes to glm-5.3.
|
|
256
|
+
lifecycle: 'deprecated',
|
|
257
|
+
}),
|
|
258
|
+
// Official alias of glm-5.3 (the plan page lists "glm-5.3 (glm-latest)").
|
|
245
259
|
'glm-latest': agentPlanModel('GLM Latest', 1_024_000, 128_000),
|
|
246
|
-
'
|
|
260
|
+
'glm-5.3-flash': agentPlanModel('GLM-5.3-Flash', 1_024_000, 128_000, { vision: true }),
|
|
261
|
+
'kimi-k2.6': agentPlanModel('Kimi-K2.6', 256_000, 32_000, {
|
|
262
|
+
// Upstream service ended 2026-08-18; migrate to kimi-k2.7-code or kimi-k3.
|
|
263
|
+
lifecycle: 'deprecated',
|
|
264
|
+
vision: true,
|
|
265
|
+
}),
|
|
247
266
|
'kimi-k2.7-code': agentPlanModel('Kimi-K2.7-Code', 256_000, 32_000, { vision: true }),
|
|
248
267
|
'deepseek-v4-pro': agentPlanModel('DeepSeek-V4-Pro', 1_024_000, 384_000),
|
|
249
268
|
'kimi-k3': agentPlanModel('Kimi-K3', 1_024_000, 128_000, { vision: true }),
|
|
@@ -143,6 +143,23 @@ export function pruneRelayModelProfiles(table, enabledModelIds) {
|
|
|
143
143
|
export function relayModelProfile(connection, modelId) {
|
|
144
144
|
return normalizeRelayModelProfile(connection.relayModelProfiles?.[modelId]);
|
|
145
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* The context window the USER declared for a model — the Maka window: the
|
|
148
|
+
* proactive compaction target, and nothing else. Exactly two sources count as
|
|
149
|
+
* a declaration: a model-facts pin (`factOverriddenFields` includes
|
|
150
|
+
* `contextWindow`, narrowest of window/input limit) and a relay model profile.
|
|
151
|
+
* A provider's `/models` report and generated metadata describe the model and
|
|
152
|
+
* are shown as a hint; they never become a threshold on their own. This is the
|
|
153
|
+
* single owner of that rule for runtime and UI (#4559).
|
|
154
|
+
*/
|
|
155
|
+
export function declaredContextWindow(connection, modelId) {
|
|
156
|
+
const model = connection.models?.find((candidate) => candidate.id === modelId);
|
|
157
|
+
if (model?.factOverriddenFields?.includes('contextWindow')) {
|
|
158
|
+
const values = [model.contextWindow, model.inputLimit].filter((value) => typeof value === 'number' && Number.isFinite(value) && value > 0);
|
|
159
|
+
return values.length > 0 ? Math.min(...values) : undefined;
|
|
160
|
+
}
|
|
161
|
+
return relayModelProfile(connection, modelId)?.contextWindow;
|
|
162
|
+
}
|
|
146
163
|
/**
|
|
147
164
|
* Mirrors @ai-sdk/openai@4.0.42 priority-processing detection. The UI and
|
|
148
165
|
* runtime share this gate so a saved Fast declaration always reaches the wire.
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
* projection, or ledger logic lives here. Those arrive in later nodes.
|
|
33
33
|
*/
|
|
34
34
|
import { isMessageContent, normalizeMessageContent, } from './events.js';
|
|
35
|
-
import { INTERACTION_ID_MAX_BYTES, INTERACTION_TOOL_NAME_MAX_BYTES } from './interaction.js';
|
|
35
|
+
import { INTERACTION_ID_MAX_BYTES, INTERACTION_TOOL_NAME_MAX_BYTES, decodeInteractionRequest, } from './interaction.js';
|
|
36
36
|
import { decodeTurnOrigin } from './turn-origin.js';
|
|
37
37
|
import { defineObjectShape, hasExactShape, isFiniteNumber, isOptionalMember, isOptionalString, isRecord, isStringArray, } from './record-schema.js';
|
|
38
38
|
import { isPermissionDecisionFields, isPermissionRequestPayload, isUserQuestionRequest, } from './interaction-record-schema.js';
|
|
@@ -183,6 +183,8 @@ const RUNTIME_ACTIONS_SHAPE = defineObjectShape()([], [
|
|
|
183
183
|
'permissionClosureAccepted',
|
|
184
184
|
'userQuestionRequest',
|
|
185
185
|
'userQuestionAnswerAccepted',
|
|
186
|
+
'formRequest',
|
|
187
|
+
'formAnswerAccepted',
|
|
186
188
|
'transferToAgent',
|
|
187
189
|
'endInvocation',
|
|
188
190
|
'tokenUsage',
|
|
@@ -415,6 +417,9 @@ function isRuntimeEventActions(value) {
|
|
|
415
417
|
(value.userQuestionRequest === undefined || isUserQuestionRequest(value.userQuestionRequest)) &&
|
|
416
418
|
(value.userQuestionAnswerAccepted === undefined ||
|
|
417
419
|
isRuntimeEventAnswerAcceptedIdentity(value.userQuestionAnswerAccepted)) &&
|
|
420
|
+
(value.formRequest === undefined || isRuntimeEventFormRequest(value.formRequest)) &&
|
|
421
|
+
(value.formAnswerAccepted === undefined ||
|
|
422
|
+
isRuntimeEventAnswerAcceptedIdentity(value.formAnswerAccepted)) &&
|
|
418
423
|
isOptionalString(value.transferToAgent) &&
|
|
419
424
|
(value.endInvocation === undefined || typeof value.endInvocation === 'boolean') &&
|
|
420
425
|
(value.tokenUsage === undefined || isRuntimeTokenUsage(value.tokenUsage)) &&
|
|
@@ -428,6 +433,23 @@ function isRuntimeEventActions(value) {
|
|
|
428
433
|
(value.managedMutationTerminal === undefined ||
|
|
429
434
|
isRuntimeManagedMutationTerminal(value.managedMutationTerminal)));
|
|
430
435
|
}
|
|
436
|
+
function isRuntimeEventFormRequest(value) {
|
|
437
|
+
if (!isRecord(value))
|
|
438
|
+
return false;
|
|
439
|
+
const { requestId, ...request } = value;
|
|
440
|
+
if (typeof requestId !== 'string' ||
|
|
441
|
+
requestId.length === 0 ||
|
|
442
|
+
UTF8.encode(requestId).byteLength > INTERACTION_ID_MAX_BYTES) {
|
|
443
|
+
return false;
|
|
444
|
+
}
|
|
445
|
+
try {
|
|
446
|
+
decodeInteractionRequest({ kind: 'form', ...request });
|
|
447
|
+
return true;
|
|
448
|
+
}
|
|
449
|
+
catch {
|
|
450
|
+
return false;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
431
453
|
function isRuntimeManagedMutationTerminal(value) {
|
|
432
454
|
return (isRecord(value) &&
|
|
433
455
|
hasExactShape(value, RUNTIME_MANAGED_MUTATION_TERMINAL_SHAPE) &&
|
|
@@ -399,6 +399,9 @@ function normalizeExecution(value) {
|
|
|
399
399
|
return fail('agent_run requires execution template');
|
|
400
400
|
if (typeof value.cwd !== 'string' || !value.cwd.trim())
|
|
401
401
|
return fail('execution.cwd is required');
|
|
402
|
+
if (typeof value.llmConnectionId !== 'string' || !value.llmConnectionId.trim()) {
|
|
403
|
+
return fail('execution.llmConnectionId is required');
|
|
404
|
+
}
|
|
402
405
|
if (typeof value.llmConnectionSlug !== 'string' || !value.llmConnectionSlug.trim()) {
|
|
403
406
|
return fail('execution.llmConnectionSlug is required');
|
|
404
407
|
}
|
|
@@ -428,6 +431,7 @@ function normalizeExecution(value) {
|
|
|
428
431
|
value: {
|
|
429
432
|
cwd: value.cwd.trim(),
|
|
430
433
|
...(projectId === undefined ? {} : { projectId }),
|
|
434
|
+
llmConnectionId: value.llmConnectionId.trim(),
|
|
431
435
|
llmConnectionSlug: value.llmConnectionSlug.trim(),
|
|
432
436
|
model: value.model.trim(),
|
|
433
437
|
...(value.thinkingLevel === undefined ? {} : { thinkingLevel: value.thinkingLevel }),
|
|
@@ -101,7 +101,7 @@ const SUBAGENT_SESSION_RUNTIME_SHAPE = defineObjectShape()([
|
|
|
101
101
|
*/
|
|
102
102
|
const RETIRED_SUBAGENT_RUNTIME_KEYS = ['permissionCeiling'];
|
|
103
103
|
const SUBAGENT_SESSION_SPAWN_IDENTITY_SHAPE = defineObjectShape()(['schemaVersion', 'requestFingerprint', 'initialTurnId', 'initialRunId'], []);
|
|
104
|
-
const SESSION_CONVERSATION_COPY_SHAPE = defineObjectShape()(['kind', 'sourceSessionId', '
|
|
104
|
+
const SESSION_CONVERSATION_COPY_SHAPE = defineObjectShape()(['kind', 'sourceSessionId', 'requestFingerprint', 'state'], ['sourceTurnId', 'intent']);
|
|
105
105
|
const SESSION_LINEAGE_ID_MAX_CHARS = 512;
|
|
106
106
|
const SESSION_LINEAGE_CONTROL_CHARACTERS = /[\u0000-\u001f\u007f]/;
|
|
107
107
|
const SUBAGENT_RUNTIME_NAME_MAX_CHARS = 512;
|
|
@@ -185,7 +185,9 @@ export function isSessionConversationCopy(value) {
|
|
|
185
185
|
(value.intent === undefined ||
|
|
186
186
|
(value.kind === 'branch' && value.intent === 'side_conversation')) &&
|
|
187
187
|
isSessionLineageId(value.sourceSessionId) &&
|
|
188
|
-
|
|
188
|
+
(value.sourceTurnId === undefined
|
|
189
|
+
? value.kind === 'branch' && value.intent === 'side_conversation'
|
|
190
|
+
: isSessionLineageId(value.sourceTurnId)) &&
|
|
189
191
|
typeof value.requestFingerprint === 'string' &&
|
|
190
192
|
/^sha256:[0-9a-f]{64}$/.test(value.requestFingerprint) &&
|
|
191
193
|
(value.state === 'preparing' || value.state === 'committed'));
|
|
@@ -287,6 +289,11 @@ export function userFacingText(message) {
|
|
|
287
289
|
const USER_VISIBLE_SESSION_SYSTEM_NOTES = new Set([
|
|
288
290
|
'context_compacted',
|
|
289
291
|
'context_compaction_failed_open',
|
|
292
|
+
'context_provider_dropping',
|
|
293
|
+
'context_window_suggestion',
|
|
294
|
+
'context_window_overrun',
|
|
295
|
+
'context_reported_window_exceeded',
|
|
296
|
+
'context_overflow_after_compaction',
|
|
290
297
|
'step_limit',
|
|
291
298
|
]);
|
|
292
299
|
/** Closed policy for system notes that are part of the user-visible transcript. */
|
|
@@ -295,6 +302,15 @@ export function isUserVisibleSessionSystemNote(kind) {
|
|
|
295
302
|
}
|
|
296
303
|
export const WORKHUB_COORDINATION_RECORD_SCHEMA_VERSION = 1;
|
|
297
304
|
export const WORKHUB_COORDINATION_REPLACEMENT_SCHEMA_VERSION = 2;
|
|
305
|
+
export const WORKHUB_COORDINATION_STOP_SCHEMA_VERSION = 3;
|
|
306
|
+
function isWorkHubDelegationStopResolution(outcome, targetTurnId) {
|
|
307
|
+
const hasTargetTurnId = typeof targetTurnId === 'string' && targetTurnId.length > 0;
|
|
308
|
+
if (outcome === 'stop_delivered' || outcome === 'not_owned')
|
|
309
|
+
return hasTargetTurnId;
|
|
310
|
+
if (outcome === 'cancelled_pending')
|
|
311
|
+
return targetTurnId === undefined;
|
|
312
|
+
return outcome === 'already_terminal' && (targetTurnId === undefined || hasTargetTurnId);
|
|
313
|
+
}
|
|
298
314
|
const USER_MESSAGE_SHAPE = defineObjectShape()(['type', 'id', 'turnId', 'ts', 'text'], [
|
|
299
315
|
'displayText',
|
|
300
316
|
'attachments',
|
|
@@ -426,6 +442,38 @@ const WORKHUB_DELEGATION_REPLACEMENT_ABORTED_MESSAGE_SHAPE = defineObjectShape()
|
|
|
426
442
|
'targetSessionId',
|
|
427
443
|
'reason',
|
|
428
444
|
], []);
|
|
445
|
+
const WORKHUB_DELEGATION_STOP_REQUESTED_MESSAGE_SHAPE = defineObjectShape()([
|
|
446
|
+
'type',
|
|
447
|
+
'id',
|
|
448
|
+
'turnId',
|
|
449
|
+
'ts',
|
|
450
|
+
'schemaVersion',
|
|
451
|
+
'kind',
|
|
452
|
+
'actionId',
|
|
453
|
+
'actionFingerprint',
|
|
454
|
+
'coordinationTurnId',
|
|
455
|
+
'stopsActionId',
|
|
456
|
+
'stopsDelegationId',
|
|
457
|
+
'targetSessionId',
|
|
458
|
+
'targetMessageId',
|
|
459
|
+
'targetSessionName',
|
|
460
|
+
'userText',
|
|
461
|
+
], []);
|
|
462
|
+
const WORKHUB_DELEGATION_STOP_RESOLVED_MESSAGE_SHAPE = defineObjectShape()([
|
|
463
|
+
'type',
|
|
464
|
+
'id',
|
|
465
|
+
'turnId',
|
|
466
|
+
'ts',
|
|
467
|
+
'schemaVersion',
|
|
468
|
+
'kind',
|
|
469
|
+
'actionId',
|
|
470
|
+
'actionFingerprint',
|
|
471
|
+
'coordinationTurnId',
|
|
472
|
+
'stopsActionId',
|
|
473
|
+
'stopsDelegationId',
|
|
474
|
+
'targetSessionId',
|
|
475
|
+
'outcome',
|
|
476
|
+
], ['targetTurnId']);
|
|
429
477
|
const WORKHUB_DELEGATION_CREATE_SHAPE = defineObjectShape()(['title', 'workspace'], []);
|
|
430
478
|
const WORKHUB_DELEGATION_PROJECT_WORKSPACE_SHAPE = defineObjectShape()(['kind', 'projectId'], []);
|
|
431
479
|
const WORKHUB_DELEGATION_HOST_PATH_WORKSPACE_SHAPE = defineObjectShape()(['kind', 'path'], []);
|
|
@@ -439,6 +487,11 @@ const SYSTEM_NOTE_KINDS = new Set([
|
|
|
439
487
|
'model_change',
|
|
440
488
|
'context_compacted',
|
|
441
489
|
'context_compaction_failed_open',
|
|
490
|
+
'context_provider_dropping',
|
|
491
|
+
'context_window_suggestion',
|
|
492
|
+
'context_window_overrun',
|
|
493
|
+
'context_reported_window_exceeded',
|
|
494
|
+
'context_overflow_after_compaction',
|
|
442
495
|
'step_limit',
|
|
443
496
|
'error',
|
|
444
497
|
'abort',
|
|
@@ -562,6 +615,37 @@ function decodeMessage(value, decodeToolResultContent) {
|
|
|
562
615
|
throw new Error('Invalid stored message schema');
|
|
563
616
|
}
|
|
564
617
|
function isWorkHubCoordinationMessage(message) {
|
|
618
|
+
if (message.kind === 'delegation_stop_requested') {
|
|
619
|
+
return (hasMessageEnvelope(message, true) &&
|
|
620
|
+
hasExactShape(message, WORKHUB_DELEGATION_STOP_REQUESTED_MESSAGE_SHAPE) &&
|
|
621
|
+
message.schemaVersion === WORKHUB_COORDINATION_STOP_SCHEMA_VERSION &&
|
|
622
|
+
isWorkHubActionIdentity(message) &&
|
|
623
|
+
typeof message.stopsActionId === 'string' &&
|
|
624
|
+
message.stopsActionId.length > 0 &&
|
|
625
|
+
typeof message.stopsDelegationId === 'string' &&
|
|
626
|
+
message.stopsDelegationId.length > 0 &&
|
|
627
|
+
typeof message.targetSessionId === 'string' &&
|
|
628
|
+
message.targetSessionId.length > 0 &&
|
|
629
|
+
typeof message.targetMessageId === 'string' &&
|
|
630
|
+
message.targetMessageId.length > 0 &&
|
|
631
|
+
typeof message.targetSessionName === 'string' &&
|
|
632
|
+
message.targetSessionName.trim().length > 0 &&
|
|
633
|
+
typeof message.userText === 'string' &&
|
|
634
|
+
message.userText.trim().length > 0);
|
|
635
|
+
}
|
|
636
|
+
if (message.kind === 'delegation_stop_resolved') {
|
|
637
|
+
return (hasMessageEnvelope(message, true) &&
|
|
638
|
+
hasExactShape(message, WORKHUB_DELEGATION_STOP_RESOLVED_MESSAGE_SHAPE) &&
|
|
639
|
+
message.schemaVersion === WORKHUB_COORDINATION_STOP_SCHEMA_VERSION &&
|
|
640
|
+
isWorkHubActionIdentity(message) &&
|
|
641
|
+
typeof message.stopsActionId === 'string' &&
|
|
642
|
+
message.stopsActionId.length > 0 &&
|
|
643
|
+
typeof message.stopsDelegationId === 'string' &&
|
|
644
|
+
message.stopsDelegationId.length > 0 &&
|
|
645
|
+
typeof message.targetSessionId === 'string' &&
|
|
646
|
+
message.targetSessionId.length > 0 &&
|
|
647
|
+
isWorkHubDelegationStopResolution(message.outcome, message.targetTurnId));
|
|
648
|
+
}
|
|
565
649
|
if (message.kind === 'delegation_replacement_aborted') {
|
|
566
650
|
return (hasMessageEnvelope(message, true) &&
|
|
567
651
|
hasExactShape(message, WORKHUB_DELEGATION_REPLACEMENT_ABORTED_MESSAGE_SHAPE) &&
|
|
@@ -642,6 +726,15 @@ function isWorkHubCoordinationMessage(message) {
|
|
|
642
726
|
typeof message.replacesDelegationId === 'string' &&
|
|
643
727
|
message.replacesDelegationId.length > 0)));
|
|
644
728
|
}
|
|
729
|
+
function isWorkHubActionIdentity(message) {
|
|
730
|
+
return (typeof message.actionId === 'string' &&
|
|
731
|
+
message.actionId.length > 0 &&
|
|
732
|
+
typeof message.actionFingerprint === 'string' &&
|
|
733
|
+
/^sha256:[a-f0-9]{64}$/u.test(message.actionFingerprint) &&
|
|
734
|
+
typeof message.coordinationTurnId === 'string' &&
|
|
735
|
+
message.coordinationTurnId.length > 0 &&
|
|
736
|
+
message.turnId === message.coordinationTurnId);
|
|
737
|
+
}
|
|
645
738
|
function isWorkHubDelegationCreateSpec(value) {
|
|
646
739
|
if (!isRecord(value) ||
|
|
647
740
|
!hasExactShape(value, WORKHUB_DELEGATION_CREATE_SHAPE) ||
|
|
@@ -96,3 +96,22 @@ export function sanitizeUnicodeText(text, opts) {
|
|
|
96
96
|
return cleaned;
|
|
97
97
|
return points.slice(0, opts.maxCodePoints).join('') + suffix;
|
|
98
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Truncate to at most `maxUnits` UTF-16 code units without ending on an
|
|
101
|
+
* unpaired high surrogate: when the cut lands inside a surrogate pair, the
|
|
102
|
+
* dangling high half is dropped with the rest of the clipped tail, so the
|
|
103
|
+
* result survives a UTF-8 round trip (durable storage, model requests)
|
|
104
|
+
* instead of decoding as U+FFFD.
|
|
105
|
+
*
|
|
106
|
+
* Budgets here are code *units*, not code points — callers clip against
|
|
107
|
+
* provider/storage limits measured in UTF-16 lengths. Marker/suffix policy
|
|
108
|
+
* stays with the caller, per the boundary note above.
|
|
109
|
+
*/
|
|
110
|
+
export function truncateUtf16Safe(text, maxUnits) {
|
|
111
|
+
if (maxUnits <= 0)
|
|
112
|
+
return '';
|
|
113
|
+
if (text.length <= maxUnits)
|
|
114
|
+
return text;
|
|
115
|
+
const kept = text.slice(0, maxUnits);
|
|
116
|
+
return /[\uD800-\uDBFF]$/.test(kept) ? kept.slice(0, -1) : kept;
|
|
117
|
+
}
|
|
@@ -72,6 +72,9 @@ export function mergeUsageSummary(legacy, canonical, query, now) {
|
|
|
72
72
|
range: projected.range,
|
|
73
73
|
totalRequests: legacy.totalRequests + projected.totalRequests,
|
|
74
74
|
totalCostUsd: legacy.totalCostUsd + projected.totalCostUsd,
|
|
75
|
+
// The projection always measures the attempts it counted, and every legacy
|
|
76
|
+
// summary carries the same field.
|
|
77
|
+
totalDurationMs: legacy.totalDurationMs + projected.totalDurationMs,
|
|
75
78
|
totalTokens: {
|
|
76
79
|
input: legacy.totalTokens.input + projected.totalTokens.input,
|
|
77
80
|
output: legacy.totalTokens.output + projected.totalTokens.output,
|
|
@@ -54,7 +54,6 @@ const CURRENT_CONTEXT_BUDGET_SHAPE = defineObjectShape()([
|
|
|
54
54
|
'droppedEvents',
|
|
55
55
|
], [
|
|
56
56
|
'policyName',
|
|
57
|
-
'maxHistoryEstimatedTokens',
|
|
58
57
|
'prunedToolResults',
|
|
59
58
|
'prunedToolResultEstimatedTokensBefore',
|
|
60
59
|
'prunedToolResultEstimatedTokensAfter',
|
|
@@ -75,6 +74,7 @@ const CURRENT_CONTEXT_BUDGET_SHAPE = defineObjectShape()([
|
|
|
75
74
|
* produce them through ContextBudgetDiagnostic.
|
|
76
75
|
*/
|
|
77
76
|
const RETIRED_CONTEXT_BUDGET_KEYS = [
|
|
77
|
+
'maxHistoryEstimatedTokens',
|
|
78
78
|
'maxHistoryTurns',
|
|
79
79
|
'semanticCompactEnabled',
|
|
80
80
|
'semanticCompactMode',
|
|
@@ -213,14 +213,20 @@ const CONTEXT_NUMBERS = [
|
|
|
213
213
|
'activeEstimatedTokensSaved',
|
|
214
214
|
];
|
|
215
215
|
const CONTEXT_REASON_COUNTS = ['archivePlaceholderReasonCounts'];
|
|
216
|
-
const LAST_REQUEST_ANCHOR_SHAPE = defineObjectShape()(['inputTokens', '
|
|
216
|
+
const LAST_REQUEST_ANCHOR_SHAPE = defineObjectShape()(['inputTokens'], ['outputTokens', 'modelId', 'connectionId']);
|
|
217
|
+
const RETIRED_LAST_REQUEST_ANCHOR_KEYS = ['payloadChars'];
|
|
218
|
+
const LAST_REQUEST_ANCHOR_DECODE_SHAPE = {
|
|
219
|
+
required: LAST_REQUEST_ANCHOR_SHAPE.required,
|
|
220
|
+
allowed: new Set([...LAST_REQUEST_ANCHOR_SHAPE.allowed, ...RETIRED_LAST_REQUEST_ANCHOR_KEYS]),
|
|
221
|
+
};
|
|
217
222
|
export function isLastRequestAnchor(value) {
|
|
218
223
|
return (isRecord(value) &&
|
|
219
|
-
hasExactShape(value,
|
|
224
|
+
hasExactShape(value, LAST_REQUEST_ANCHOR_DECODE_SHAPE) &&
|
|
220
225
|
isFiniteNumber(value.inputTokens) &&
|
|
221
|
-
isFiniteNumber(value.payloadChars) &&
|
|
222
226
|
value.inputTokens > 0 &&
|
|
223
|
-
value.
|
|
227
|
+
(value.outputTokens === undefined ||
|
|
228
|
+
(isFiniteNumber(value.outputTokens) && value.outputTokens >= 0)) &&
|
|
229
|
+
(value.payloadChars === undefined || isFiniteNumber(value.payloadChars)));
|
|
224
230
|
}
|
|
225
231
|
export function isTokenUsageFields(value) {
|
|
226
232
|
if (!isRecord(value))
|
|
@@ -65,6 +65,9 @@ const TERMINAL_CHINESE_WITHDRAWAL = /(?:^|[\r\n,。;!?—–-]|然后|
|
|
|
65
65
|
const CREATION_REQUEST_PREFIX = /^(?:(?:please|kindly|(?:can|could|would)\s+you|i\s+(?:want|need|would\s+like)\s+to|we\s+need\s+to|let['’]s)|(?:请|帮我|请帮我|麻烦(?:你)?|我想|我要|我们需要))?\s*$/iu;
|
|
66
66
|
const NAMED_CREATION_TITLE_INTRODUCER = /\b(?:new|brand[- ]new)\s+(?:session|work|task)[\s,,::-]+(?:(?:called|named|titled)|with\s+(?:the\s+)?title)\s+|(?:新的?|全新的?)?\s*(?:Session|会话|工作|任务)[\s,,::-]*(?:叫做?|名叫|名为|命名为|标题为|名称为|名字为)\s*/iu;
|
|
67
67
|
const LEADING_CORRECTION_SEPARATOR = /^[\s,.;:!?,。;:!?—–-]+/u;
|
|
68
|
+
const DIRECT_STOP_REQUEST = /^\s*(?:(?:please|kindly)\s+)?(?:stop|cancel|terminate|halt)\s+(?:(?:the|this)\s+)?(?:(?:session|work|task|job)\s+)?(.+?)\s*[.!。!]?\s*$/iu;
|
|
69
|
+
const DIRECT_CHINESE_STOP_REQUEST = /^\s*(?:(?:请|请帮我|帮我|麻烦你?)\s*)?(?:停止|取消|终止|中止)\s*(?:(?:这个|该)?(?:会话|工作|任务)\s*)?(.+?)\s*[。!]?\s*$/iu;
|
|
70
|
+
const UNSAFE_STOP_TARGET = /^(?:it|this|that|one|everything|all|current|session|work|task|job|(?:this|that|current)\s+(?:session|work|task|job)|它|这个|那个|全部|当前|会话|工作|任务|(?:这个|那个|当前)(?:会话|工作|任务))$/iu;
|
|
68
71
|
/**
|
|
69
72
|
* Whether trusted user text affirmatively asks WorkHub to create a new Session.
|
|
70
73
|
*
|
|
@@ -202,6 +205,8 @@ export function readWorkHubRequestIntent(value) {
|
|
|
202
205
|
: { kind: 'unusable' };
|
|
203
206
|
const correctionCue = hasWorkHubCorrectionCue(source);
|
|
204
207
|
const existingTarget = affirmativeWorkHubExistingCorrectionTarget(source);
|
|
208
|
+
const stopCue = directWorkHubStopCue(source, literalMask.malformed);
|
|
209
|
+
const stopTarget = stopCue ? directWorkHubStopTarget(source, false) : undefined;
|
|
205
210
|
const actions = allMatches(masked, EXECUTION_ACTION);
|
|
206
211
|
const execution = literalMask.malformed || naming.kind === 'unusable' || hasDominatingDeliberation(masked)
|
|
207
212
|
? 'non_executable'
|
|
@@ -217,6 +222,11 @@ export function readWorkHubRequestIntent(value) {
|
|
|
217
222
|
cue: correctionCue,
|
|
218
223
|
...(existingTarget ? { existingTarget } : {}),
|
|
219
224
|
},
|
|
225
|
+
stop: {
|
|
226
|
+
cue: stopCue,
|
|
227
|
+
imperative: Boolean(stopTarget),
|
|
228
|
+
...(stopTarget ? { target: stopTarget } : {}),
|
|
229
|
+
},
|
|
220
230
|
};
|
|
221
231
|
}
|
|
222
232
|
/** Whether a parsed correction names exactly this Session. */
|
|
@@ -270,11 +280,20 @@ function affirmativeWorkHubExistingCorrectionTarget(value) {
|
|
|
270
280
|
}
|
|
271
281
|
return lastTarget;
|
|
272
282
|
}
|
|
273
|
-
|
|
274
|
-
|
|
283
|
+
/**
|
|
284
|
+
* The one rule for reading a Session name out of a trusted reference.
|
|
285
|
+
*
|
|
286
|
+
* It is deliberately action-agnostic: it reports where the name matched and
|
|
287
|
+
* what text was left over, and says nothing about whether that leftover is
|
|
288
|
+
* acceptable. Each action's policy owns that question, because the answer
|
|
289
|
+
* genuinely differs — a stop reference may carry only punctuation after the
|
|
290
|
+
* name, while a correction may carry a further instruction.
|
|
291
|
+
*/
|
|
292
|
+
export function matchWorkHubSessionName(reference, sessionName) {
|
|
293
|
+
const normalizedTarget = normalizeCorrectionIdentity(reference);
|
|
275
294
|
const normalizedName = normalizeCorrectionIdentity(sessionName);
|
|
276
295
|
if (!normalizedName)
|
|
277
|
-
return
|
|
296
|
+
return { kind: 'none' };
|
|
278
297
|
const quotedNames = [
|
|
279
298
|
`"${normalizedName}"`,
|
|
280
299
|
`“${normalizedName}”`,
|
|
@@ -285,15 +304,32 @@ function correctionTargetMatchesSession(target, sessionName) {
|
|
|
285
304
|
.sort((left, right) => right.length - left.length)
|
|
286
305
|
.find((candidate) => normalizedTarget.startsWith(candidate) &&
|
|
287
306
|
!/[\p{L}\p{N}]/u.test(normalizedTarget[candidate.length] ?? ''));
|
|
288
|
-
if (!matchedName)
|
|
289
|
-
|
|
307
|
+
if (!matchedName) {
|
|
308
|
+
// A name whose own trailing punctuation the reference dropped still names
|
|
309
|
+
// it, but nothing may follow: there is no boundary left to trust.
|
|
310
|
+
return /[.!。!]$/u.test(normalizedName) &&
|
|
311
|
+
normalizedTarget === normalizedName.replace(/[.!。!]+$/u, '').trim()
|
|
312
|
+
? { kind: 'elided_name_punctuation' }
|
|
313
|
+
: { kind: 'none' };
|
|
314
|
+
}
|
|
290
315
|
if (matchedName === normalizedName && hasUnsafeUnquotedHardClauseBoundary(sessionName)) {
|
|
291
|
-
return
|
|
316
|
+
return { kind: 'none' };
|
|
292
317
|
}
|
|
293
|
-
|
|
318
|
+
return { kind: 'named', remainder: normalizedTarget.slice(matchedName.length).trim() };
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* The correction policy's tail rule. A correction may name its target and then
|
|
322
|
+
* say what to do with it, but a withdrawal anywhere in the reference retracts
|
|
323
|
+
* the whole thing.
|
|
324
|
+
*
|
|
325
|
+
* It takes a match rather than a Session name so that a caller which already
|
|
326
|
+
* resolved candidates through the shared Session Resolver applies exactly this
|
|
327
|
+
* rule to exactly that recall, instead of matching names a second time.
|
|
328
|
+
*/
|
|
329
|
+
export function workHubCorrectionAdmitsReference(reference, match) {
|
|
330
|
+
if (match.kind !== 'named' || hasUnquotedTerminalWithdrawal(reference))
|
|
294
331
|
return false;
|
|
295
|
-
}
|
|
296
|
-
const remainder = normalizedTarget.slice(matchedName.length).trim();
|
|
332
|
+
const { remainder } = match;
|
|
297
333
|
if (!remainder || /^(?:instead\s*)?[.!?。!?]?$/iu.test(remainder))
|
|
298
334
|
return true;
|
|
299
335
|
const supplemental = remainder.match(/^[,;,;]\s*(.+)$/u)?.[1]?.trim();
|
|
@@ -302,6 +338,36 @@ function correctionTargetMatchesSession(target, sessionName) {
|
|
|
302
338
|
!/[\r\n,.!?;,。!?;—–]|\b(?:and|then|but|however|actually)\b|(?:然后|随后|但|不过|其实)/iu.test(supplementalBody) &&
|
|
303
339
|
readWorkHubRequestIntent(supplementalBody).execution === 'imperative');
|
|
304
340
|
}
|
|
341
|
+
function correctionTargetMatchesSession(target, sessionName) {
|
|
342
|
+
return workHubCorrectionAdmitsReference(target, matchWorkHubSessionName(target, sessionName));
|
|
343
|
+
}
|
|
344
|
+
function directWorkHubStopTarget(value, malformedLiteral) {
|
|
345
|
+
if (malformedLiteral || /[??]\s*$/u.test(value))
|
|
346
|
+
return undefined;
|
|
347
|
+
const match = DIRECT_STOP_REQUEST.exec(value) ?? DIRECT_CHINESE_STOP_REQUEST.exec(value);
|
|
348
|
+
const rawTarget = match?.[1]?.trim();
|
|
349
|
+
if (!rawTarget)
|
|
350
|
+
return undefined;
|
|
351
|
+
const target = stripMatchingStopQuotes(rawTarget.replace(/[.!。!]+\s*$/u, '').trim());
|
|
352
|
+
if (!target || UNSAFE_STOP_TARGET.test(target))
|
|
353
|
+
return undefined;
|
|
354
|
+
return target;
|
|
355
|
+
}
|
|
356
|
+
function directWorkHubStopCue(value, malformedLiteral) {
|
|
357
|
+
if (malformedLiteral || /[??]\s*$/u.test(value))
|
|
358
|
+
return false;
|
|
359
|
+
return Boolean(DIRECT_STOP_REQUEST.test(value) || DIRECT_CHINESE_STOP_REQUEST.test(value));
|
|
360
|
+
}
|
|
361
|
+
function stripMatchingStopQuotes(value) {
|
|
362
|
+
const pairs = new Map([
|
|
363
|
+
['"', '"'],
|
|
364
|
+
["'", "'"],
|
|
365
|
+
['“', '”'],
|
|
366
|
+
['‘', '’'],
|
|
367
|
+
]);
|
|
368
|
+
const closer = pairs.get(value[0] ?? '');
|
|
369
|
+
return closer && value.endsWith(closer) ? value.slice(1, -1).trim() : value;
|
|
370
|
+
}
|
|
305
371
|
function normalizeCorrectionIdentity(value) {
|
|
306
372
|
return value.normalize('NFKC').toLocaleLowerCase().replace(/\s+/gu, ' ').trim();
|
|
307
373
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
|
4
|
+
* distributed with this work for additional information
|
|
5
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
|
7
|
+
* "License"); you may not use this file except in compliance
|
|
8
|
+
* with the License. You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing,
|
|
13
|
+
* software distributed under the License is distributed on an
|
|
14
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
* KIND, either express or implied. See the License for the
|
|
16
|
+
* specific language governing permissions and limitations
|
|
17
|
+
* under the License.
|
|
18
|
+
*/
|
|
19
|
+
import { matchWorkHubSessionName, } from './workhub-creation-intent.js';
|
|
20
|
+
/**
|
|
21
|
+
* The temporary deterministic baseline: a reference resolves only when it names
|
|
22
|
+
* one visible Session exactly. Exact display names are conservative retrieval
|
|
23
|
+
* evidence, not the long-term product boundary, and this implementation exists
|
|
24
|
+
* to keep the port real while a ranked resolver is built behind it.
|
|
25
|
+
*
|
|
26
|
+
* It can be removed once every target-bearing WorkHub action resolves through
|
|
27
|
+
* this port, the replacement resolver passes the common routing evaluation, and
|
|
28
|
+
* its rollout retains a tested rollback path.
|
|
29
|
+
*/
|
|
30
|
+
export function createExactNameSessionResolver() {
|
|
31
|
+
return {
|
|
32
|
+
resolve({ reference, sessions }) {
|
|
33
|
+
const candidates = [];
|
|
34
|
+
for (const session of sessions) {
|
|
35
|
+
const match = matchWorkHubSessionName(reference.text, session.sessionName);
|
|
36
|
+
if (match.kind === 'none')
|
|
37
|
+
continue;
|
|
38
|
+
candidates.push({ ref: session.ref, evidence: match });
|
|
39
|
+
}
|
|
40
|
+
const [first, ...rest] = candidates;
|
|
41
|
+
if (!first)
|
|
42
|
+
return { kind: 'none' };
|
|
43
|
+
// Exact naming has no score to separate equals by, so more than one match
|
|
44
|
+
// is ambiguity rather than a ranking a policy could safely act on.
|
|
45
|
+
if (rest.length > 0)
|
|
46
|
+
return { kind: 'ambiguous', candidates };
|
|
47
|
+
return { kind: 'ranked', candidates: [first] };
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -77,6 +77,7 @@
|
|
|
77
77
|
"./daily-review": "./dist/daily-review.js",
|
|
78
78
|
"./work-board": "./dist/work-board.js",
|
|
79
79
|
"./workhub-creation-intent": "./dist/workhub-creation-intent.js",
|
|
80
|
+
"./workhub-session-resolver": "./dist/workhub-session-resolver.js",
|
|
80
81
|
"./deep-research": "./dist/deep-research.js",
|
|
81
82
|
"./session-start-mode": "./dist/session-start-mode.js",
|
|
82
83
|
"./long-term-memory": "./dist/long-term-memory.js",
|
|
@@ -140,6 +141,7 @@
|
|
|
140
141
|
"./task-submission-readiness": "./dist/task-submission-readiness.js",
|
|
141
142
|
"./terminal-input": "./dist/terminal-input.js",
|
|
142
143
|
"./terminal-mouse-input": "./dist/terminal-mouse-input.js",
|
|
144
|
+
"./text-sanitize": "./dist/text-sanitize.js",
|
|
143
145
|
"./tool-activity-args": "./dist/tool-activity-args.js",
|
|
144
146
|
"./tool-quiet-preview": "./dist/tool-quiet-preview.js",
|
|
145
147
|
"./tool-result-record-schema": "./dist/tool-result-record-schema.js",
|
|
@@ -28,6 +28,7 @@ import { decodePreverifiedToolchain, isExternalProfile, } from './toolchain-veri
|
|
|
28
28
|
import { isInferenceAdmissionEvent } from './provider-admission.js';
|
|
29
29
|
import { DEEPSEEK_V4_FLASH_COST, deriveMetering, } from './provider-metering.js';
|
|
30
30
|
import { removeEvalWebTools } from './provider-web-tool-surface.js';
|
|
31
|
+
import { terminateProcess } from './process-termination.js';
|
|
31
32
|
import { takeRelayResultToken, writeRelayResult } from './relay-result-frame.js';
|
|
32
33
|
const resultToken = takeRelayResultToken();
|
|
33
34
|
// The profile directory this wrapper writes. `dsh` has no environment variable
|
|
@@ -277,7 +278,7 @@ let stopped = false;
|
|
|
277
278
|
const stop = (signal) => {
|
|
278
279
|
stopped = true;
|
|
279
280
|
removeCredential();
|
|
280
|
-
child
|
|
281
|
+
void terminateProcess(child, signal);
|
|
281
282
|
};
|
|
282
283
|
const terminate = () => stop('SIGTERM');
|
|
283
284
|
const interrupt = () => stop('SIGINT');
|