newmark-agent 0.5.3 → 0.5.7
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/conversation-utility-host.bundle.cjs +147 -29
- package/dist/core/agent.d.ts +7 -0
- package/dist/core/agent.js +111 -26
- package/dist/core/agentKernelRunner.js +30 -2
- package/dist/core/autoRouter.d.ts +1 -0
- package/dist/core/autoRouter.js +9 -0
- package/dist/core/conversationKernel.d.ts +12 -0
- package/dist/core/conversationKernel.js +32 -1
- package/dist/core/electronUtilityRuntimePool.js +7 -2
- package/dist/core/types.d.ts +21 -0
- package/dist/core/wslAgentRuntimePool.js +6 -2
- package/dist/main.js +34 -0
- package/dist/preload.js +1 -0
- package/dist/providers/provider-events.d.ts +6 -0
- package/dist/providers/provider-events.js +15 -4
- package/dist/server.js +21 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.js +4 -0
- package/dist/ui/index.html +2345 -197
- package/dist/ui/lucide-sprite.svg +4 -0
- package/dist/wsl-agent-host.bundle.cjs +147 -29
- package/package.json +8 -3
|
@@ -220,6 +220,10 @@
|
|
|
220
220
|
<symbol id="minus" viewBox="0 0 24 24">
|
|
221
221
|
<path d="M5 12h14" />
|
|
222
222
|
</symbol>
|
|
223
|
+
<symbol id="mouse" viewBox="0 0 24 24">
|
|
224
|
+
<rect x="5" y="2" width="14" height="20" rx="7" />
|
|
225
|
+
<path d="M12 6v4" />
|
|
226
|
+
</symbol>
|
|
223
227
|
<symbol id="move" viewBox="0 0 24 24">
|
|
224
228
|
<path d="M12 2v20" />
|
|
225
229
|
<path d="m15 19-3 3-3-3" />
|
|
@@ -328674,7 +328674,7 @@ function providerStreamTimeoutError(timeoutMs) {
|
|
|
328674
328674
|
error.message = `Stream read timeout after ${timeoutMs}ms`;
|
|
328675
328675
|
return error;
|
|
328676
328676
|
}
|
|
328677
|
-
async function readProviderStreamChunk(reader, signal, timeoutMs =
|
|
328677
|
+
async function readProviderStreamChunk(reader, signal, timeoutMs = 0) {
|
|
328678
328678
|
if (signal.aborted) throw providerAbortError(signal);
|
|
328679
328679
|
let timer;
|
|
328680
328680
|
let onAbort;
|
|
@@ -328682,9 +328682,9 @@ async function readProviderStreamChunk(reader, signal, timeoutMs = 3e4) {
|
|
|
328682
328682
|
onAbort = () => reject(providerAbortError(signal));
|
|
328683
328683
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
328684
328684
|
});
|
|
328685
|
-
const timeoutPromise = new Promise((_3, reject) => {
|
|
328685
|
+
const timeoutPromise = timeoutMs > 0 ? new Promise((_3, reject) => {
|
|
328686
328686
|
timer = setTimeout(() => reject(providerStreamTimeoutError(timeoutMs)), timeoutMs);
|
|
328687
|
-
});
|
|
328687
|
+
}) : new Promise(() => void 0);
|
|
328688
328688
|
try {
|
|
328689
328689
|
return await Promise.race([reader.read(), abortPromise, timeoutPromise]);
|
|
328690
328690
|
} catch (error) {
|
|
@@ -336937,6 +336937,10 @@ var ToolExecutor = class {
|
|
|
336937
336937
|
async webSearch(query) {
|
|
336938
336938
|
return this.wsearch(query);
|
|
336939
336939
|
}
|
|
336940
|
+
/** OCR entry point for the runtime's final visual fallback. */
|
|
336941
|
+
async finalVisualFallbackOcr(dataUrl, signal) {
|
|
336942
|
+
return await this.localOcr.recognizeDataUrl(dataUrl, signal, "sparse-ui");
|
|
336943
|
+
}
|
|
336940
336944
|
setHostProfile(profile) {
|
|
336941
336945
|
this.hostProfile = { ...profile };
|
|
336942
336946
|
}
|
|
@@ -340850,9 +340854,20 @@ async function runAgentKernel(agent) {
|
|
|
340850
340854
|
try {
|
|
340851
340855
|
const linkedPlanRevisionBeforeRun = agent.getLinkedPlan().revision;
|
|
340852
340856
|
const modelBeforeKernelRun = agent.model;
|
|
340853
|
-
|
|
340857
|
+
const preflightVisualFallback = !agent.activeModelConfig()?.vision ? await agent.finalVisualFallback("vision input not supported by the selected model", processSignal) : null;
|
|
340858
|
+
let lastTurn = preflightVisualFallback ? { text: preflightVisualFallback, stopReason: "stop", errorMessage: "" } : await runWithCompressionResume([], false);
|
|
340859
|
+
if (preflightVisualFallback) {
|
|
340860
|
+
tokens.push({ type: "text", text: preflightVisualFallback });
|
|
340861
|
+
agent.recordWorkStatus("Final visual fallback used: local mini OCR plus conservative text correction.");
|
|
340862
|
+
}
|
|
340854
340863
|
if (modelBeforeKernelRun && modelBeforeKernelRun !== agent.model && !tokens.some((t3) => t3.text?.includes("[Model fallback]"))) {
|
|
340855
|
-
|
|
340864
|
+
const notice = `[Model fallback] ${modelBeforeKernelRun} unavailable; switched to ${agent.model}.`;
|
|
340865
|
+
tokens.unshift({ type: "text", text: notice });
|
|
340866
|
+
agent.emitWorkEvent({
|
|
340867
|
+
type: "status",
|
|
340868
|
+
content: notice,
|
|
340869
|
+
fallback: { from: modelBeforeKernelRun, to: agent.model, providerId: agent.activeDeployment()?.providerId }
|
|
340870
|
+
});
|
|
340856
340871
|
}
|
|
340857
340872
|
let emptyResponseRetries = 0;
|
|
340858
340873
|
while (providerTurnIsEmpty(lastTurn) && emptyResponseRetries < 2) {
|
|
@@ -340873,6 +340888,11 @@ async function runAgentKernel(agent) {
|
|
|
340873
340888
|
const notice = routeTransitionNotice(agent, previous);
|
|
340874
340889
|
tokens.push({ type: "text", text: notice });
|
|
340875
340890
|
agent.recordWorkStatus(notice);
|
|
340891
|
+
agent.emitWorkEvent({
|
|
340892
|
+
type: "status",
|
|
340893
|
+
content: notice,
|
|
340894
|
+
fallback: { from: previous, to: agent.model, providerId: agent.activeDeployment()?.providerId }
|
|
340895
|
+
});
|
|
340876
340896
|
kernel2.state.model = toKernelModel(agent);
|
|
340877
340897
|
const fallbackToolSurface = refreshToolSurface(true);
|
|
340878
340898
|
kernel2.state.systemPrompt = [agent.buildSystemPrompt(), fallbackToolSurface.systemPromptNotice].filter(Boolean).join("\n\n");
|
|
@@ -340880,6 +340900,14 @@ async function runAgentKernel(agent) {
|
|
|
340880
340900
|
await agent.waitForPlannedRouteRetry();
|
|
340881
340901
|
lastTurn = await runWithCompressionResume([], false);
|
|
340882
340902
|
}
|
|
340903
|
+
if (kernelTurnFailed(agent, lastTurn)) {
|
|
340904
|
+
const visualFallback = await agent.finalVisualFallback(lastTurn.errorMessage || lastTurn.text, processSignal);
|
|
340905
|
+
if (visualFallback) {
|
|
340906
|
+
tokens.push({ type: "text", text: visualFallback });
|
|
340907
|
+
agent.recordWorkStatus("Final visual fallback used: local mini OCR plus conservative text correction.");
|
|
340908
|
+
lastTurn = { ...lastTurn, text: visualFallback, errorMessage: "", stopReason: "stop" };
|
|
340909
|
+
}
|
|
340910
|
+
}
|
|
340883
340911
|
if (kernelTurnFailed(agent, lastTurn)) {
|
|
340884
340912
|
throw new ProviderRunError(normalizePublicProviderError(lastTurn.errorMessage || lastTurn.text, [agent.activeModelConfig()?.api_key]));
|
|
340885
340913
|
}
|
|
@@ -343289,14 +343317,16 @@ var AutoRouter = class {
|
|
|
343289
343317
|
retryDelayMs
|
|
343290
343318
|
});
|
|
343291
343319
|
}
|
|
343320
|
+
if (failure.allowModelFallback === false) return attempts.slice(0, remainingAttempts);
|
|
343292
343321
|
const selection = decision.requestedSelection;
|
|
343293
343322
|
if (selection.kind === "fixed") return attempts.slice(0, remainingAttempts);
|
|
343294
343323
|
const scope = selection.kind === "auto" ? selection.scope : { kind: "provider", providerId: current.providerId };
|
|
343295
343324
|
const subset = selection.kind === "auto" ? selection.subset : void 0;
|
|
343296
343325
|
const currentGroup = current.logicalModelGroupId;
|
|
343326
|
+
const currentProviderId = current.providerId;
|
|
343297
343327
|
const now2 = this.now();
|
|
343298
343328
|
const attemptedDeployments = decision.attempts.map((attempt) => attempt.deployment);
|
|
343299
|
-
const eligible = candidates.filter((candidate) => candidate.enabled && inScope(candidate.deployment, scope) && inSubset(candidate.deployment, subset) && !sameDeployment(candidate.deployment, current) && !attemptedDeployments.some((attempted) => sameDeployment(candidate.deployment, attempted)) && validationEligible(candidate, now2).length === 0 && this.passedInitialHardFilters(decision, candidate) && this.circuitState(candidate.deployment, now2, false) !== "open");
|
|
343329
|
+
const eligible = candidates.filter((candidate) => candidate.enabled && candidate.deployment.providerId === currentProviderId && inScope(candidate.deployment, scope) && inSubset(candidate.deployment, subset) && !sameDeployment(candidate.deployment, current) && !attemptedDeployments.some((attempted) => sameDeployment(candidate.deployment, attempted)) && validationEligible(candidate, now2).length === 0 && this.passedInitialHardFilters(decision, candidate) && this.circuitState(candidate.deployment, now2, false) !== "open");
|
|
343300
343330
|
const equivalent = currentGroup ? eligible.find((candidate) => candidate.deployment.logicalModelGroupId === currentGroup && !candidate.fallbackOnly) : void 0;
|
|
343301
343331
|
const fallback = eligible.find((candidate) => candidate.fallbackOnly);
|
|
343302
343332
|
const rankedAlternates = decision.rankedCandidates.map((ranked) => eligible.find((candidate) => sameDeployment(candidate.deployment, ranked.deployment))).filter((candidate) => !!candidate && candidate !== equivalent && candidate !== fallback && !candidate.fallbackOnly);
|
|
@@ -346734,7 +346764,8 @@ ${String(event.toolArgs || "")}`;
|
|
|
346734
346764
|
sequence,
|
|
346735
346765
|
status: input2.status,
|
|
346736
346766
|
guide: !isToolEvent && input2.guide ? this.normalizeGuideReceipt(input2.guide) : void 0,
|
|
346737
|
-
displayImage: isToolEvent ? this.hydrateDisplayImage(input2.displayImage) : void 0
|
|
346767
|
+
displayImage: isToolEvent ? this.hydrateDisplayImage(input2.displayImage) : void 0,
|
|
346768
|
+
fallback: input2.fallback
|
|
346738
346769
|
};
|
|
346739
346770
|
if (activeRun && this.isPersistablePublicWorkEvent(event)) {
|
|
346740
346771
|
activeRun.sequence = Number(sequence || activeRun.sequence + 1);
|
|
@@ -349653,9 +349684,15 @@ ${summary}`, segment, "local-summarize", true);
|
|
|
349653
349684
|
}
|
|
349654
349685
|
compressionBuildBlockStart(messages) {
|
|
349655
349686
|
const activeRunId = this.currentWorkRunId();
|
|
349656
|
-
if (
|
|
349657
|
-
|
|
349658
|
-
|
|
349687
|
+
if (activeRunId) {
|
|
349688
|
+
const index = messages.findIndex((message) => String(message.run_id || message.runId || "") === activeRunId);
|
|
349689
|
+
if (index >= 0) return index;
|
|
349690
|
+
}
|
|
349691
|
+
let lastRunBoundary = -1;
|
|
349692
|
+
for (let index = 0; index < messages.length; index += 1) {
|
|
349693
|
+
if (String(messages[index]?.run_id || messages[index]?.runId || "")) lastRunBoundary = index + 1;
|
|
349694
|
+
}
|
|
349695
|
+
return lastRunBoundary >= 0 ? lastRunBoundary : messages.length;
|
|
349659
349696
|
}
|
|
349660
349697
|
recentContextSuffix(messages, maxMessages, tokenBudget) {
|
|
349661
349698
|
if (!messages.length) return [];
|
|
@@ -350584,17 +350621,12 @@ ${msg.content}
|
|
|
350584
350621
|
currentAttempt.sideEffectBoundary = this.routeSideEffectCommitted;
|
|
350585
350622
|
if (this.routeAttemptStartedAt > 0) currentAttempt.durationMs = Math.max(0, Date.now() - this.routeAttemptStartedAt);
|
|
350586
350623
|
}
|
|
350587
|
-
if (!fallbackEnabled) {
|
|
350588
|
-
this.lastRouteDecision.finalStatus = "failed";
|
|
350589
|
-
this.routeAttemptStartedAt = 0;
|
|
350590
|
-
this.persistRouteDecision(this.lastRouteDecision);
|
|
350591
|
-
return null;
|
|
350592
|
-
}
|
|
350593
350624
|
if (!this.pendingAutoAttempts.length) {
|
|
350594
350625
|
this.pendingAutoAttempts = this.autoRouter.planAttempts(this.lastRouteDecision, this.autoRouteCandidates(), {
|
|
350595
350626
|
error: failure,
|
|
350596
350627
|
streamCommitted: this.routeStreamCommitted,
|
|
350597
|
-
sideEffectCommitted: this.routeSideEffectCommitted
|
|
350628
|
+
sideEffectCommitted: this.routeSideEffectCommitted,
|
|
350629
|
+
allowModelFallback: fallbackEnabled
|
|
350598
350630
|
});
|
|
350599
350631
|
}
|
|
350600
350632
|
const next2 = this.pendingAutoAttempts.shift();
|
|
@@ -350629,7 +350661,6 @@ ${msg.content}
|
|
|
350629
350661
|
if (!next?.name) return null;
|
|
350630
350662
|
this.model = next.name;
|
|
350631
350663
|
this.fixedDeployment = this.deploymentRef(next);
|
|
350632
|
-
if (next.provider) this.config.set("models", "auto_switch_anchor_provider", next.provider);
|
|
350633
350664
|
return current;
|
|
350634
350665
|
}
|
|
350635
350666
|
isLlmErrorText(text) {
|
|
@@ -350637,12 +350668,10 @@ ${msg.content}
|
|
|
350637
350668
|
}
|
|
350638
350669
|
scopedSwitchModels(currentModelName) {
|
|
350639
350670
|
const all = this.config.allModels();
|
|
350640
|
-
|
|
350641
|
-
const
|
|
350642
|
-
|
|
350643
|
-
|
|
350644
|
-
const provider = this.config.findProvider(providerId);
|
|
350645
|
-
return all.filter((m2) => m2.provider_id === (provider?.id || providerId));
|
|
350671
|
+
const current = currentModelName === "auto" ? this.activeModelConfig() : this.config.findModel(currentModelName);
|
|
350672
|
+
const providerId = current?.provider_id || this.fixedDeployment?.providerId || (currentModelName !== "auto" ? this.activeDeployment()?.providerId : void 0);
|
|
350673
|
+
if (!providerId) return [];
|
|
350674
|
+
return all.filter((m2) => m2.provider_id === providerId);
|
|
350646
350675
|
}
|
|
350647
350676
|
async validateModels(selectedNames, options = {}) {
|
|
350648
350677
|
if (this.modelValidationPromise) return this.modelValidationPromise;
|
|
@@ -350824,6 +350853,60 @@ ${msg.content}
|
|
|
350824
350853
|
};
|
|
350825
350854
|
return results;
|
|
350826
350855
|
}
|
|
350856
|
+
/**
|
|
350857
|
+
* Final visual safety net: OCR each submitted image and ask a text-only
|
|
350858
|
+
* request to conservatively repair the OCR. This is intentionally callable
|
|
350859
|
+
* only after a visual-input refusal and after same-provider vision routing
|
|
350860
|
+
* has been exhausted; the original image is never sent again.
|
|
350861
|
+
*/
|
|
350862
|
+
async finalVisualFallback(errorText, signal) {
|
|
350863
|
+
if (!/(?:vision|image|multimodal|image_url|input_image).*(?:not supported|unsupported|拒绝|不支持|failed|failure|invalid)|(?:not supported|unsupported|拒绝|不支持).*(?:vision|image|multimodal|image_url|input_image)/i.test(String(errorText || ""))) return null;
|
|
350864
|
+
const current = this.activeModelConfig();
|
|
350865
|
+
if (!current) return null;
|
|
350866
|
+
const alternateVision = this.config.allModels().some(
|
|
350867
|
+
(model) => model.enabled !== false && model.provider_id === current.provider_id && model.name !== current.name && !!model.vision && !!model.api_key && !!model.provider_url && !["unavailable", "auth_error", "invalid_config"].includes(String(model.evaluation?.status || model.validation?.status || "").toLowerCase())
|
|
350868
|
+
);
|
|
350869
|
+
if (alternateVision) return null;
|
|
350870
|
+
const latest = [...this.history].reverse().find((item) => item?.role === "user");
|
|
350871
|
+
const parts = latest?.content && Array.isArray(latest.content) ? latest.content : [];
|
|
350872
|
+
const images = parts.map((part) => {
|
|
350873
|
+
const image = part.image_url;
|
|
350874
|
+
return image && typeof image === "object" ? String(image.url || "") : "";
|
|
350875
|
+
}).filter((value) => /^data:image\/(?:png|jpeg);base64,/i.test(value)).slice(0, 4);
|
|
350876
|
+
if (!images.length) return null;
|
|
350877
|
+
const ocr = [];
|
|
350878
|
+
for (const [index, image] of images.entries()) {
|
|
350879
|
+
try {
|
|
350880
|
+
const result = await this.tools.finalVisualFallbackOcr(image, signal);
|
|
350881
|
+
if (result.ok && result.text.trim()) ocr.push({ index: index + 1, text: result.text.slice(0, 5e4), confidence: result.confidence });
|
|
350882
|
+
} catch {
|
|
350883
|
+
}
|
|
350884
|
+
}
|
|
350885
|
+
if (!ocr.length) return JSON.stringify({ ok: false, fallback: "mini_ocr_llm", error: "Local OCR returned no readable text; no visual content was fabricated." });
|
|
350886
|
+
const task = typeof latest?.content === "string" ? latest.content : "";
|
|
350887
|
+
const evidence = ocr.map((item) => `Image ${item.index} (OCR confidence ${item.confidence.toFixed(1)}):
|
|
350888
|
+
${item.text}`).join("\n\n");
|
|
350889
|
+
const prompt = `The provider rejected image input. Answer the user's task using only this approximate OCR evidence. Correct obvious character, spacing, and line-break errors only when supported by context. Preserve [uncertain] markers for ambiguity and never invent missing visual content.
|
|
350890
|
+
User task:
|
|
350891
|
+
${task.slice(0, 12e3)}
|
|
350892
|
+
OCR evidence:
|
|
350893
|
+
${evidence}`;
|
|
350894
|
+
let corrected = "";
|
|
350895
|
+
try {
|
|
350896
|
+
const provider = this.engineModel();
|
|
350897
|
+
if (provider) corrected = String(await provider.chat(this.activeModelName(), [{ role: "user", content: prompt }], "You are a text-only OCR correction assistant. Be conservative and explicit about uncertainty.", 0.05, 3e3, signal) || "").trim();
|
|
350898
|
+
} catch {
|
|
350899
|
+
}
|
|
350900
|
+
return JSON.stringify({
|
|
350901
|
+
ok: !!(corrected || ocr.length),
|
|
350902
|
+
fallback: "mini_ocr_llm",
|
|
350903
|
+
approximate: true,
|
|
350904
|
+
warning: "\u89C6\u89C9\u8F93\u5165\u88AB\u62D2\u7EDD\uFF1B\u4EE5\u4E0B\u5185\u5BB9\u6765\u81EA\u672C\u5730 OCR\uFF0C\u5E76\u7ECF\u6587\u672C\u6A21\u578B\u4FDD\u5B88\u6821\u6B63\uFF0C\u53EF\u80FD\u4E0D\u5B8C\u6574\u3002",
|
|
350905
|
+
raw_ocr: ocr,
|
|
350906
|
+
corrected: corrected || ocr.map((item) => item.text).join("\n\n"),
|
|
350907
|
+
uncertainty: corrected ? "preserved" : "raw_ocr_only"
|
|
350908
|
+
}, null, 2);
|
|
350909
|
+
}
|
|
350827
350910
|
engineModel() {
|
|
350828
350911
|
if (this.forcedProvider) {
|
|
350829
350912
|
const active = this.activeDeployment();
|
|
@@ -351206,8 +351289,10 @@ ${persisted.map((guide, index) => `Guide ${index + 1}: ${guide.text}`).join("\n"
|
|
|
351206
351289
|
}
|
|
351207
351290
|
const selectedModel = this.activeModelConfig();
|
|
351208
351291
|
if (images.length && !selectedModel?.vision) {
|
|
351209
|
-
|
|
351210
|
-
|
|
351292
|
+
const hasSameProviderVision = selectedModel && this.config.allModels().some(
|
|
351293
|
+
(model) => model.enabled !== false && model.provider_id === selectedModel.provider_id && model.name !== selectedModel.name && !!model.vision
|
|
351294
|
+
);
|
|
351295
|
+
if (hasSameProviderVision) this.switchToFallbackModel("vision input not supported by the selected model");
|
|
351211
351296
|
}
|
|
351212
351297
|
const now2 = this.nowLabel();
|
|
351213
351298
|
const visibleUserInput = inputEnvelope?.visibleUserInput === void 0 ? text : String(inputEnvelope.visibleUserInput || "");
|
|
@@ -351968,7 +352053,10 @@ ${items.map((item) => this.formatAutomation(item)).join("\n")}`;
|
|
|
351968
352053
|
if (!sa) return "[Subagent] Not found.";
|
|
351969
352054
|
const requestedModel = this.normalizeSubagentModelSelection(sa.model && sa.model !== "default" ? sa.model : this.modelSelectionValue() || this.model);
|
|
351970
352055
|
const requestedDeployment = parseDeploymentSelectionValue2(requestedModel);
|
|
351971
|
-
|
|
352056
|
+
let assignedModel = requestedModel === "auto" ? this.activeModelConfig() : requestedDeployment ? this.config.findDeployment(requestedDeployment) : this.config.findModel(requestedModel);
|
|
352057
|
+
if (!assignedModel && !requestedDeployment && requestedModel !== "auto") {
|
|
352058
|
+
assignedModel = this.activeModelConfig();
|
|
352059
|
+
}
|
|
351972
352060
|
const model = assignedModel?.name || (requestedModel === "auto" ? this.activeModelName() : requestedModel);
|
|
351973
352061
|
const activeModel = this.activeModelConfig();
|
|
351974
352062
|
const activeProvider = this.engineModel();
|
|
@@ -353397,6 +353485,32 @@ var ConversationKernel = class {
|
|
|
353397
353485
|
followUp: queued?.followUp.slice() || []
|
|
353398
353486
|
};
|
|
353399
353487
|
}
|
|
353488
|
+
/**
|
|
353489
|
+
* dev-0.5.6: 排队 followUp 消息 drain 时转成普通用户消息载荷。
|
|
353490
|
+
*
|
|
353491
|
+
* 入队时(enqueueSameSession)为去重/编辑保留了 clientMessageId,并把
|
|
353492
|
+
* runId 固定为入队时运行的 runId;若原样传给 process,写入 chatMessages
|
|
353493
|
+
* 的用户消息会携带旧 runId + clientMessageId,渲染端(PC renderTranscript /
|
|
353494
|
+
* 移动端 projectRemoteConversationItems)会把「clientMessageId + runId 命中
|
|
353495
|
+
* workRuns」的消息误判为 guide 消息而跳过气泡,导致排队自动发送的消息不
|
|
353496
|
+
* 显示在用户输入时间线。清除这两个字段后 process 走普通用户消息分支
|
|
353497
|
+
* (chatMessages.push,mode 取 visibleMode,runId 取当前 run)。
|
|
353498
|
+
*/
|
|
353499
|
+
drainQueuedFollowUpMessage(message) {
|
|
353500
|
+
if (typeof message === "string") return message;
|
|
353501
|
+
const text = String(message.text || "");
|
|
353502
|
+
const images = message.images;
|
|
353503
|
+
const attachments = message.attachments;
|
|
353504
|
+
const visible = message.visibleUserInput;
|
|
353505
|
+
const visibleMode = message.visibleMode;
|
|
353506
|
+
return {
|
|
353507
|
+
text,
|
|
353508
|
+
...images?.length ? { images } : {},
|
|
353509
|
+
...attachments?.length ? { attachments } : {},
|
|
353510
|
+
...visible ? { visibleUserInput: visible } : {},
|
|
353511
|
+
...visibleMode ? { visibleMode } : {}
|
|
353512
|
+
};
|
|
353513
|
+
}
|
|
353400
353514
|
queueItems(target) {
|
|
353401
353515
|
const runtime = this.findRuntime(target);
|
|
353402
353516
|
if (!runtime) return [];
|
|
@@ -354138,7 +354252,7 @@ ${batchText}`,
|
|
|
354138
354252
|
};
|
|
354139
354253
|
lastTokens = await this.runSingle(runtime, batchMessage, "steer");
|
|
354140
354254
|
} else {
|
|
354141
|
-
lastTokens = await this.runSingle(runtime, next.message, next.queueMode);
|
|
354255
|
+
lastTokens = await this.runSingle(runtime, this.drainQueuedFollowUpMessage(next.message), next.queueMode);
|
|
354142
354256
|
}
|
|
354143
354257
|
}
|
|
354144
354258
|
const rootMessage = runtime.runner.subagents.readRootInbox()[0];
|
|
@@ -354597,7 +354711,11 @@ ${text}`;
|
|
|
354597
354711
|
type: "queue_update",
|
|
354598
354712
|
content: "Conversation queue updated.",
|
|
354599
354713
|
conversationId: runtime.id,
|
|
354600
|
-
queue: this.queued(runtime.target)
|
|
354714
|
+
queue: this.queued(runtime.target),
|
|
354715
|
+
// Structured rows with stable kernel ids so every consumer (PC UI and
|
|
354716
|
+
// the paired mobile client) can render/edit/delete the same items.
|
|
354717
|
+
queueItems: this.queueItems(runtime.target),
|
|
354718
|
+
queuePaused: runtime.queuePaused === true
|
|
354601
354719
|
});
|
|
354602
354720
|
}
|
|
354603
354721
|
clearQueued(runtime) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newmark-agent",
|
|
3
3
|
"productName": "Newmark Agent",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.7",
|
|
5
5
|
"description": "Newmark Agent — Portable AI coding agent with rich GUI and CLI (TypeScript)",
|
|
6
6
|
"homepage": "https://github.com/positer/Newmark-Agent",
|
|
7
7
|
"repository": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"test:desktop": "npm run build && node dist/tests/conversationHistoryFirstVerify.js && npm run test:desktop:built",
|
|
54
54
|
"test:deletion-safety": "npm run build && npm run test:deletion-safety:built",
|
|
55
55
|
"test:deletion-safety:built": "node scripts/deletion-safety-stress.cjs",
|
|
56
|
-
"test:desktop:built": "node dist/tests/verify.js && node dist/tests/thinkingTierMapCacheStressVerify.js && node dist/tests/computerUseSessionVerify.js && node dist/tests/contextSystemV2Verify.js && node dist/tests/contextSystemV2StressVerify.js && node dist/tests/providerAdapterV2Verify.js && node dist/tests/providerTimeoutRecoveryVerify.js && node dist/tests/agentRuntimeV2Verify.js && node dist/tests/toolchainExposureV2Verify.js && node dist/tests/localOcrFallbackVerify.js && node dist/tests/dev018ModeSubagentStressVerify.js && node dist/tests/conversationBranchStressVerify.js && node dist/tests/conversationArchiveConcurrencyVerify.js && node dist/tests/conversationArchiveRuntimeVerify.js && node dist/tests/dev040ComprehensiveStressVerify.js && node dist/tests/memoryPolicyVerify.js && node dist/tests/newmarkSelectVerify.js && node dist/tests/mcpManagerVerify.js && node dist/tests/dshCompatibilityVerify.js && node dist/tests/performanceOptimizationVerify.js && node scripts/compression-pressure-stress.cjs && node dist/tests/compressionFidelityVerify.js && node dist/tests/responseTrajectoryVerify.js && node dist/tests/normalChatRegressionVerify.js && node dist/tests/dev008-subagent.js && node dist/tests/dev009Verify.js && node dist/tests/runtimeIsolationVerify.js && node dist/tests/runtimePoolCapacityVerify.js && node dist/tests/guideWorkRunVerify.js && node dist/tests/modelSwitchBehaviorVerify.js && node scripts/flow-pause-stop-draft-stress.cjs && node dist/tests/guideUiReconcileVerify.js && node dist/tests/queueAttachmentIsolationVerify.js && node dist/tests/workspaceMenuVerify.js && node dist/tests/userImagePersistenceVerify.js && node dist/tests/displayImageVerify.js && node dist/tests/visualPreferencesVerify.js && node dist/tests/browserUseVerify.js && node dist/tests/toolProcessVerify.js && node dist/tests/toolProvisioningVerify.js && node dist/tests/taskToolsVerify.js && node dist/tests/contextCacheHitStressVerify.js && node dist/tests/startupPrewarmVerify.js && node dist/tests/pdfPreviewServerVerify.js && node dist/tests/editorLifecycleVerify.js && node dist/tests/terminalTakeoverVerify.js && node dist/tests/workspaceFileRouterVerify.js && node dist/tests/screenCaptureIndependentVerify.js && node dist/tests/computerUsePerformanceVerify.js && node dist/tests/autoRouterVerify.js && node dist/tests/autoAgentIntegrationVerify.js && node dist/tests/modelRecoveryStressVerify.js && node dist/tests/autoRouteRatingVerify.js && node dist/tests/providerIdentityVerify.js && node dist/tests/modelValidationVerify.js && node dist/tests/modelValidationAgentIntegrationVerify.js && node scripts/deletion-safety-stress.cjs",
|
|
56
|
+
"test:desktop:built": "node dist/tests/verify.js && node dist/tests/thinkingTierMapCacheStressVerify.js && node dist/tests/computerUseSessionVerify.js && node dist/tests/contextSystemV2Verify.js && node dist/tests/contextSystemV2StressVerify.js && node dist/tests/providerAdapterV2Verify.js && node dist/tests/providerTimeoutRecoveryVerify.js && node dist/tests/agentRuntimeV2Verify.js && node dist/tests/toolchainExposureV2Verify.js && node dist/tests/localOcrFallbackVerify.js && node dist/tests/dev018ModeSubagentStressVerify.js && node dist/tests/conversationBranchStressVerify.js && node dist/tests/conversationArchiveConcurrencyVerify.js && node dist/tests/conversationArchiveRuntimeVerify.js && node dist/tests/dev040ComprehensiveStressVerify.js && node dist/tests/memoryPolicyVerify.js && node dist/tests/newmarkSelectVerify.js && node dist/tests/mcpManagerVerify.js && node dist/tests/dshCompatibilityVerify.js && node dist/tests/performanceOptimizationVerify.js && node scripts/compression-pressure-stress.cjs && node dist/tests/compressionFidelityVerify.js && node dist/tests/responseTrajectoryVerify.js && node dist/tests/normalChatRegressionVerify.js && node dist/tests/dev008-subagent.js && node dist/tests/dev009Verify.js && node dist/tests/runtimeIsolationVerify.js && node dist/tests/runtimePoolCapacityVerify.js && node dist/tests/guideWorkRunVerify.js && node dist/tests/modelSwitchBehaviorVerify.js && node scripts/flow-pause-stop-draft-stress.cjs && node dist/tests/guideUiReconcileVerify.js && node dist/tests/workReviewDedupVerify.js && node dist/tests/queueAttachmentIsolationVerify.js && node dist/tests/queueDrainUserMessageVerify.js && node dist/tests/pcGlassMigrationVerify.js && node dist/tests/longHistoryDisplayVerify.js && node dist/tests/workspaceMenuVerify.js && node dist/tests/userImagePersistenceVerify.js && node dist/tests/displayImageVerify.js && node dist/tests/visualPreferencesVerify.js && node dist/tests/browserUseVerify.js && node dist/tests/toolProcessVerify.js && node dist/tests/toolProvisioningVerify.js && node dist/tests/taskToolsVerify.js && node dist/tests/contextCacheHitStressVerify.js && node dist/tests/startupPrewarmVerify.js && node dist/tests/pdfPreviewServerVerify.js && node dist/tests/editorLifecycleVerify.js && node dist/tests/terminalTakeoverVerify.js && node dist/tests/workspaceFileRouterVerify.js && node dist/tests/screenCaptureIndependentVerify.js && node dist/tests/computerUsePerformanceVerify.js && node dist/tests/autoRouterVerify.js && node dist/tests/autoAgentIntegrationVerify.js && node dist/tests/modelRecoveryStressVerify.js && node dist/tests/autoRouteRatingVerify.js && node dist/tests/providerIdentityVerify.js && node dist/tests/modelValidationVerify.js && node dist/tests/modelValidationAgentIntegrationVerify.js && node scripts/deletion-safety-stress.cjs",
|
|
57
57
|
"test:conversation-branch-stress": "npm run build && node dist/tests/conversationBranchStressVerify.js",
|
|
58
58
|
"test:conversation-archive-concurrency": "npm run build && node dist/tests/conversationArchiveConcurrencyVerify.js",
|
|
59
59
|
"test:memory-policy": "npm run build && node dist/tests/memoryPolicyVerify.js",
|
|
@@ -126,6 +126,9 @@
|
|
|
126
126
|
"release:ui-gemma-removal-smoke": "node scripts/release-ui-gemma-removal-smoke.cjs",
|
|
127
127
|
"release:ui-icon-smoke": "node scripts/release-ui-icon-smoke.cjs",
|
|
128
128
|
"release:ui-render-performance-smoke": "node scripts/release-ui-render-performance-smoke.cjs",
|
|
129
|
+
"test:liquid-renderer-calls": "node scripts/measure-liquid-renderer-calls.cjs",
|
|
130
|
+
"test:liquid-renderer-electron": "node scripts/dev-liquid-renderer-performance-smoke.cjs",
|
|
131
|
+
"release:ui-incremental-render-stress": "node scripts/release-ui-incremental-render-stress.cjs",
|
|
129
132
|
"release:ui-flow-subagent-smoke": "node scripts/release-ui-flow-subagent-smoke.cjs",
|
|
130
133
|
"release:ui-media-md-smoke": "node scripts/release-ui-media-md-smoke.cjs",
|
|
131
134
|
"release:ui-native-editor-smoke": "node scripts/release-ui-native-editor-smoke.cjs",
|
|
@@ -184,7 +187,9 @@
|
|
|
184
187
|
"dist:mac": "npm run build:clean && electron-builder --mac",
|
|
185
188
|
"dist:windows-release": "npm run test:full-release && npm run build:clean && node scripts/dist-portable.cjs",
|
|
186
189
|
"release:ocr-budget-smoke": "node scripts/verify-ocr-package-budget.cjs",
|
|
187
|
-
"release:packaged-ocr-smoke": "node scripts/release-packaged-ocr-smoke.cjs"
|
|
190
|
+
"release:packaged-ocr-smoke": "node scripts/release-packaged-ocr-smoke.cjs",
|
|
191
|
+
"test:stream-unlimited-timeout-stress": "npm run build && node dist/tests/streamUnlimitedTimeoutStressVerify.js",
|
|
192
|
+
"test:queue-unify-stress": "npm run build && node dist/tests/queueUnifyStressVerify.js && node dist/tests/queueDrainUserMessageVerify.js"
|
|
188
193
|
},
|
|
189
194
|
"build": {
|
|
190
195
|
"npmRebuild": false,
|