newmark-agent 0.6.2 → 0.6.3
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 +1947 -470
- package/dist/core/agent.d.ts +14 -0
- package/dist/core/agent.js +44 -3
- package/dist/core/agentKernelRunner.js +24 -2
- package/dist/core/continuation/contracts.d.ts +197 -0
- package/dist/core/continuation/contracts.js +72 -0
- package/dist/core/continuation/store.d.ts +178 -0
- package/dist/core/continuation/store.js +989 -0
- package/dist/core/conversationKernel.d.ts +80 -1
- package/dist/core/conversationKernel.js +586 -36
- package/dist/core/requestContextEstimate.d.ts +5 -1
- package/dist/llm/provider.js +9 -2
- package/dist/main.js +39 -4
- package/dist/providers/chat-completions.adapter.js +6 -1
- package/dist/providers/responses.adapter.js +4 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.js +1 -0
- package/dist/ui/index.html +70 -11
- package/dist/wsl-agent-host.bundle.cjs +1950 -473
- package/package.json +3 -2
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
export interface RequestContextEstimate {
|
|
3
3
|
requestId: string;
|
|
4
4
|
runId: string;
|
|
5
|
+
/** Immutable runtime branch that owned this model request. */
|
|
6
|
+
branchId: string;
|
|
7
|
+
/** Content hash of the actual submitted system/messages/tools payload. */
|
|
8
|
+
contextHash: string;
|
|
5
9
|
model: string;
|
|
6
10
|
at: string;
|
|
7
11
|
estimatedTokens: number;
|
|
@@ -14,5 +18,5 @@ export interface RequestContextEstimate {
|
|
|
14
18
|
inputTokens?: number;
|
|
15
19
|
cacheReadTokens?: number;
|
|
16
20
|
}
|
|
17
|
-
export declare function estimateSubmittedContext(messages: Array<Record<string, unknown>>, systemPrompt: string, tools: unknown[], buildBlockStart: number): Omit<RequestContextEstimate, 'requestId' | 'runId' | 'model' | 'at'>;
|
|
21
|
+
export declare function estimateSubmittedContext(messages: Array<Record<string, unknown>>, systemPrompt: string, tools: unknown[], buildBlockStart: number): Omit<RequestContextEstimate, 'requestId' | 'runId' | 'model' | 'at' | 'branchId' | 'contextHash'>;
|
|
18
22
|
//# sourceMappingURL=requestContextEstimate.d.ts.map
|
package/dist/llm/provider.js
CHANGED
|
@@ -1311,12 +1311,19 @@ class LLMProvider {
|
|
|
1311
1311
|
async *chatStreamWithTools(model, messages, systemPrompt, temperature, maxTokens, tools, signal, reasoningTier, sessionId) {
|
|
1312
1312
|
if (signal?.aborted)
|
|
1313
1313
|
throw abortFailure(signal);
|
|
1314
|
+
// A non-positive value means "provider owns the output limit". Protocols
|
|
1315
|
+
// whose wire format requires a positive max_tokens (Anthropic, GitHub
|
|
1316
|
+
// Models) fall back to the selected reasoning tier's budget; OpenAI-style
|
|
1317
|
+
// adapters omit the field entirely so the endpoint decides.
|
|
1318
|
+
const requiredMaxTokens = maxTokens > 0
|
|
1319
|
+
? maxTokens
|
|
1320
|
+
: this.intelligenceConfig(reasoningTier || 'medium').maxTokens;
|
|
1314
1321
|
if (this.protocol() === 'anthropic') {
|
|
1315
|
-
yield* this.anthropicChatWithTools(model, messages, systemPrompt, temperature,
|
|
1322
|
+
yield* this.anthropicChatWithTools(model, messages, systemPrompt, temperature, requiredMaxTokens, tools, signal);
|
|
1316
1323
|
return;
|
|
1317
1324
|
}
|
|
1318
1325
|
if (this.protocol() === 'github_models') {
|
|
1319
|
-
yield* this.githubModelsChatStreamWithTools(model, messages, systemPrompt, temperature,
|
|
1326
|
+
yield* this.githubModelsChatStreamWithTools(model, messages, systemPrompt, temperature, requiredMaxTokens, tools, signal);
|
|
1320
1327
|
return;
|
|
1321
1328
|
}
|
|
1322
1329
|
if (this.useProviderAdaptersV2) {
|
package/dist/main.js
CHANGED
|
@@ -3292,6 +3292,10 @@ else {
|
|
|
3292
3292
|
// Other conversations' paused Flows are never touched by this send.
|
|
3293
3293
|
const flow = activeFlowStateFor(target);
|
|
3294
3294
|
const snapshot = await runtimeSnapshotForTarget(target);
|
|
3295
|
+
// The renderer's visible composer selection is authoritative for this
|
|
3296
|
+
// send. It is provider-qualified (deployment:providerId:modelId), so it
|
|
3297
|
+
// can never fall back to a same-named model on another provider.
|
|
3298
|
+
const requestedModelSelection = String(requested.model || '').trim();
|
|
3295
3299
|
const structured = typeof message === 'string' ? { text: message } : { ...message };
|
|
3296
3300
|
const requestedMode = String(requested.requestedMode || structured.visibleMode || snapshot.mode || 'build');
|
|
3297
3301
|
const inputMode = String(requested.inputMode || snapshot.inputMode || 'guide') === 'next' ? 'next' : 'guide';
|
|
@@ -3319,9 +3323,18 @@ else {
|
|
|
3319
3323
|
});
|
|
3320
3324
|
return { ok: receipt.status !== 'rejected', accepted: receipt.status !== 'rejected', receipt, ...await runtimeSnapshotForTarget(target) };
|
|
3321
3325
|
}
|
|
3326
|
+
const requestedBranchPath = Array.isArray(structured.branchPath)
|
|
3327
|
+
? (structured.branchPath || []).map(id => String(id || '')).filter(Boolean)
|
|
3328
|
+
: String(structured.branchPath || '').split('>').map(id => id.trim()).filter(Boolean);
|
|
3329
|
+
const requestedBranchNodeId = String(structured.branchNodeId
|
|
3330
|
+
|| requestedBranchPath[requestedBranchPath.length - 1]
|
|
3331
|
+
|| '');
|
|
3322
3332
|
return await applyConversationAction(target, 'queue_enqueue', '', {
|
|
3323
3333
|
id, text: structured.visibleUserInput || structured.text, requestedMode: requestedMode === 'flow' ? 'build' : requestedMode,
|
|
3324
3334
|
goalObjective: objective, images: structured.images, createdAt: new Date().toISOString(),
|
|
3335
|
+
branchNodeId: requestedBranchNodeId || undefined,
|
|
3336
|
+
branchPath: requestedBranchPath.length ? requestedBranchPath : undefined,
|
|
3337
|
+
modelSelection: requestedModelSelection || undefined,
|
|
3325
3338
|
});
|
|
3326
3339
|
}
|
|
3327
3340
|
await selectConversationMode(target, requestedMode);
|
|
@@ -3335,10 +3348,10 @@ else {
|
|
|
3335
3348
|
// 发送命令时锁定输入框选择的模型:接受命令后的整个运行过程都以该
|
|
3336
3349
|
// 模型为准(唯一例外是显式的不可用回退,且回退会以结构化事件同步
|
|
3337
3350
|
// 到前端输入框下方的选择区,而不是隐藏的参数回退)。
|
|
3338
|
-
const requestedModel = String(snapshot.model || agent.model);
|
|
3351
|
+
const requestedModel = String(requestedModelSelection || snapshot.model || agent.model);
|
|
3339
3352
|
const options = {
|
|
3340
3353
|
mode: requestedMode === 'goal' ? 'goal' : requestedMode,
|
|
3341
|
-
model: String(snapshot.model || agent.ensureUsableModelSelection()),
|
|
3354
|
+
model: String(requestedModelSelection || snapshot.model || agent.ensureUsableModelSelection()),
|
|
3342
3355
|
intelligence: String(snapshot.intelligence || agent.intelligence),
|
|
3343
3356
|
inputMode: inputMode,
|
|
3344
3357
|
engine: agent.engine,
|
|
@@ -3460,6 +3473,16 @@ else {
|
|
|
3460
3473
|
settlement: new Promise(resolve => { resolvePendingSettlement = resolve; }),
|
|
3461
3474
|
};
|
|
3462
3475
|
pendingFlowStarts.set(flowKey, pending);
|
|
3476
|
+
// Admit the Flow build at command-acceptance time. It may wait behind a
|
|
3477
|
+
// running Build, but its queue position fixes the parent of every later
|
|
3478
|
+
// Next item; the actual Flow start only claims this existing build.
|
|
3479
|
+
const flowCommandId = `flow-${flowKey}-${(0, crypto_1.randomUUID)()}`;
|
|
3480
|
+
const flowBuildId = ensureConversationKernel(root).admitExternalBuild(flowTarget, {
|
|
3481
|
+
commandId: flowCommandId,
|
|
3482
|
+
text: String(input || ''),
|
|
3483
|
+
requestedMode: 'flow',
|
|
3484
|
+
modelSelection: agent.modelSelectionValue(),
|
|
3485
|
+
});
|
|
3463
3486
|
let previousQueuePaused = false;
|
|
3464
3487
|
try {
|
|
3465
3488
|
let state = await runtimeSnapshotForTarget(flowTarget);
|
|
@@ -3485,7 +3508,13 @@ else {
|
|
|
3485
3508
|
}
|
|
3486
3509
|
const flowAgent = ensureConversationKernel(root).beginExternalRun(flowTarget, {
|
|
3487
3510
|
mode: 'flow', model: agent.model, intelligence: agent.intelligence, inputMode: agent.inputMode, engine: agent.engine,
|
|
3488
|
-
}, () => isolatedConversationAgent(flowTarget), previousQueuePaused
|
|
3511
|
+
}, () => isolatedConversationAgent(flowTarget), previousQueuePaused, {
|
|
3512
|
+
commandId: flowCommandId,
|
|
3513
|
+
text: String(input || ''),
|
|
3514
|
+
requestedMode: 'flow',
|
|
3515
|
+
modelSelection: agent.modelSelectionValue(),
|
|
3516
|
+
existingBuildId: flowBuildId || undefined,
|
|
3517
|
+
});
|
|
3489
3518
|
mainConversationOwners.add(flowKey);
|
|
3490
3519
|
conversationSelections.set(flowKey, { ...conversationSelections.get(flowKey), mode: 'flow' });
|
|
3491
3520
|
const previousMode = flowAgent.mode;
|
|
@@ -3655,7 +3684,13 @@ else {
|
|
|
3655
3684
|
const flowAgent = ensureConversationKernel(root).beginExternalRun(flowTarget, {
|
|
3656
3685
|
mode: 'flow', model: suspension.flowAgent?.model || agent.model, intelligence: suspension.flowAgent?.intelligence || agent.intelligence,
|
|
3657
3686
|
inputMode: suspension.flowAgent?.inputMode || agent.inputMode, engine: agent.engine,
|
|
3658
|
-
}, () => suspension.flowAgent || isolatedConversationAgent(flowTarget), suspension.queueWasPaused ?? true
|
|
3687
|
+
}, () => suspension.flowAgent || isolatedConversationAgent(flowTarget), suspension.queueWasPaused ?? true, {
|
|
3688
|
+
commandId: `flow-resume-${flowKey}-${(0, crypto_1.randomUUID)()}`,
|
|
3689
|
+
text: String(response || ''),
|
|
3690
|
+
requestedMode: 'flow',
|
|
3691
|
+
modelSelection: agent.modelSelectionValue(),
|
|
3692
|
+
resume: true,
|
|
3693
|
+
});
|
|
3659
3694
|
mainConversationOwners.add(flowKey);
|
|
3660
3695
|
suspension.flowAgent = flowAgent;
|
|
3661
3696
|
// A previous Flow may have been interrupted just before its isolated
|
|
@@ -44,8 +44,13 @@ class ChatCompletionsAdapter {
|
|
|
44
44
|
model: request.model,
|
|
45
45
|
messages,
|
|
46
46
|
temperature: request.temperature,
|
|
47
|
-
max_tokens: request.maxOutputTokens,
|
|
48
47
|
};
|
|
48
|
+
// Omit the cap entirely for provider-owned output. Only auxiliary
|
|
49
|
+
// requests that explicitly need a bounded completion send a positive
|
|
50
|
+
// max_tokens value.
|
|
51
|
+
if (Number.isFinite(request.maxOutputTokens) && request.maxOutputTokens > 0) {
|
|
52
|
+
body.max_tokens = request.maxOutputTokens;
|
|
53
|
+
}
|
|
49
54
|
if (tools.length) {
|
|
50
55
|
body.tools = tools;
|
|
51
56
|
body.tool_choice = 'auto';
|
|
@@ -69,8 +69,11 @@ class ResponsesAdapter {
|
|
|
69
69
|
model: request.model,
|
|
70
70
|
input: input.length ? input : [{ role: 'user', content: '' }],
|
|
71
71
|
temperature: request.temperature,
|
|
72
|
-
max_output_tokens: request.maxOutputTokens,
|
|
73
72
|
};
|
|
73
|
+
// Omit the cap entirely for provider-owned output.
|
|
74
|
+
if (Number.isFinite(request.maxOutputTokens) && request.maxOutputTokens > 0) {
|
|
75
|
+
body.max_output_tokens = request.maxOutputTokens;
|
|
76
|
+
}
|
|
74
77
|
if (request.reasoningEffort)
|
|
75
78
|
body.reasoning = { effort: request.reasoningEffort, summary: 'auto' };
|
|
76
79
|
if (request.systemPrompt)
|
package/dist/server.d.ts
CHANGED
package/dist/server.js
CHANGED
|
@@ -153,6 +153,7 @@ function hostedCommandOptions(params) {
|
|
|
153
153
|
clientMessageId: String(params.clientMessageId || ''),
|
|
154
154
|
flowName: String(params.flowName || params.defaultFlow || ''),
|
|
155
155
|
flowStart: typeof params.flowStart === 'number' && Number.isFinite(params.flowStart) ? params.flowStart : undefined,
|
|
156
|
+
model: String(params.model || ''),
|
|
156
157
|
};
|
|
157
158
|
}
|
|
158
159
|
const MOBILE_EDITABLE_EXTENSIONS = new Set([
|
package/dist/ui/index.html
CHANGED
|
@@ -7143,6 +7143,10 @@ var state = {
|
|
|
7143
7143
|
_conversationLoadingMsgEl: null,
|
|
7144
7144
|
_syncedMode: null,
|
|
7145
7145
|
_syncedModel: null,
|
|
7146
|
+
// Monotonic revision for explicit renderer model changes. Activation
|
|
7147
|
+
// snapshots may restore the conversation's remembered model only when no
|
|
7148
|
+
// newer local selection was made while the snapshot was in flight.
|
|
7149
|
+
modelSelectionRevision: 0,
|
|
7146
7150
|
_syncedInputMode: null,
|
|
7147
7151
|
_editingQueueIndex: -1,
|
|
7148
7152
|
_editingGoalText: '',
|
|
@@ -9353,7 +9357,7 @@ var api = window.api || {
|
|
|
9353
9357
|
conversationId: target.conversationId,
|
|
9354
9358
|
action: action
|
|
9355
9359
|
};
|
|
9356
|
-
['id', 'text', 'value', 'requestedMode', 'goalObjective', 'createdAt', 'images', 'paused', 'orderedIds'].forEach(function(field) {
|
|
9360
|
+
['id', 'text', 'value', 'requestedMode', 'goalObjective', 'createdAt', 'images', 'paused', 'orderedIds', 'branchNodeId', 'branchPath'].forEach(function(field) {
|
|
9357
9361
|
if (input && Object.prototype.hasOwnProperty.call(input, field)) body[field] = input[field];
|
|
9358
9362
|
});
|
|
9359
9363
|
var r = await fetch('/api/queue-action', {
|
|
@@ -13287,6 +13291,35 @@ function hydrateConversationBranchState(snapshot) {
|
|
|
13287
13291
|
rememberRuntimeConversationBranchPath(currentConversationTarget(s.conversationId || activeConversationId()));
|
|
13288
13292
|
}
|
|
13289
13293
|
|
|
13294
|
+
// Apply the conversation's remembered provider-qualified model to the
|
|
13295
|
+
// composer selector. The backend snapshot is authoritative; a newer explicit
|
|
13296
|
+
// user selection made while the snapshot was in flight wins via the revision
|
|
13297
|
+
// guard passed by the activation caller.
|
|
13298
|
+
function applyConversationModelSelection(snapshot) {
|
|
13299
|
+
var nextModel = String(snapshot && snapshot.model || '').trim();
|
|
13300
|
+
if (!nextModel) return;
|
|
13301
|
+
state.model = nextModel;
|
|
13302
|
+
if (typeof snapshot.modelLabel === 'string' && snapshot.modelLabel) state.modelLabel = snapshot.modelLabel;
|
|
13303
|
+
state._syncedModel = nextModel;
|
|
13304
|
+
var sel = els['model-select'] || document.getElementById('model-select');
|
|
13305
|
+
if (!sel) {
|
|
13306
|
+
if (window.syncModelSelectSurface) window.syncModelSelectSurface();
|
|
13307
|
+
return;
|
|
13308
|
+
}
|
|
13309
|
+
var hasOption = Array.prototype.some.call(sel.options, function(option) {
|
|
13310
|
+
return String(option.value || '') === nextModel;
|
|
13311
|
+
});
|
|
13312
|
+
if (hasOption) {
|
|
13313
|
+
sel.value = nextModel;
|
|
13314
|
+
window.syncModelSelectSurface();
|
|
13315
|
+
} else if (window.refreshModelSelect) {
|
|
13316
|
+
// The remembered deployment is not in the current enabled catalog (for
|
|
13317
|
+
// example its provider was explicitly disabled). Reuse the existing
|
|
13318
|
+
// visibility fallback instead of displaying a model that cannot run.
|
|
13319
|
+
window.refreshModelSelect();
|
|
13320
|
+
}
|
|
13321
|
+
}
|
|
13322
|
+
|
|
13290
13323
|
function applyConversationSnapshot(s, requestedConversationId, options) {
|
|
13291
13324
|
if (!s) return;
|
|
13292
13325
|
if (s.computerUse) {
|
|
@@ -13309,6 +13342,11 @@ function applyConversationSnapshot(s, requestedConversationId, options) {
|
|
|
13309
13342
|
if (s && s.runtimeKey) registerRuntimeKey(snapshotTarget, s.runtimeKey);
|
|
13310
13343
|
hydrateConversationDraftSnapshot(s, snapshotTarget);
|
|
13311
13344
|
hydrateConversationBranchState(s);
|
|
13345
|
+
var modelRevisionMatches = !options || options.modelRevision === undefined
|
|
13346
|
+
|| Number(state.modelSelectionRevision || 0) === Number(options.modelRevision || 0);
|
|
13347
|
+
if (modelRevisionMatches && isActiveConversationTarget(snapshotTarget)) {
|
|
13348
|
+
applyConversationModelSelection(s);
|
|
13349
|
+
}
|
|
13312
13350
|
rebindQueueToRuntimeBranch(snapshotTarget);
|
|
13313
13351
|
if (s && Array.isArray(s.workRuns) && !preserveReadableHistory) {
|
|
13314
13352
|
var viewedBranchIdForSync = Array.isArray(s.viewedBranchNodePath) && s.viewedBranchNodePath.length
|
|
@@ -14443,6 +14481,7 @@ function applyModelFallbackToInputSurface(event) {
|
|
|
14443
14481
|
var nextValue = modelDeploymentValueForName(f.to, f.providerId || '');
|
|
14444
14482
|
if (!nextValue || String(state.model || '') === nextValue) return;
|
|
14445
14483
|
state.model = nextValue;
|
|
14484
|
+
state.modelSelectionRevision = Number(state.modelSelectionRevision || 0) + 1;
|
|
14446
14485
|
state.modelLabel = '';
|
|
14447
14486
|
// 不预置 _syncedModel:下一次发送前的 syncConversationExecutionState 会把
|
|
14448
14487
|
// 回退模型正式同步到后端 host agent(并持久化为该对话的首选模型)。
|
|
@@ -17208,6 +17247,11 @@ function bindBackendQueuedRequestToTarget(text, target, occurrence) {
|
|
|
17208
17247
|
request.createdAt = queueItem.createdAt;
|
|
17209
17248
|
request.runId = queueItem.runId;
|
|
17210
17249
|
request.images = (queueItem.images || []).map(function(image) { return Object.assign({}, image); });
|
|
17250
|
+
if (Array.isArray(queueItem.branchPath) && queueItem.branchPath.length) {
|
|
17251
|
+
request.branchPath = queueItem.branchPath.join('>');
|
|
17252
|
+
} else if (queueItem.branchNodeId) {
|
|
17253
|
+
request.branchPath = String(queueItem.branchNodeId);
|
|
17254
|
+
}
|
|
17211
17255
|
}
|
|
17212
17256
|
return request;
|
|
17213
17257
|
}
|
|
@@ -17920,7 +17964,15 @@ window.sendMessage = async function(modeOverride, queuedText, opts) {
|
|
|
17920
17964
|
queuedModeRequest.goalDeclaration = true;
|
|
17921
17965
|
queuedModeRequest.goalObjective = rawText;
|
|
17922
17966
|
}
|
|
17923
|
-
var
|
|
17967
|
+
var queuedBranchPath = Array.isArray(queuedModeRequest.branchPath)
|
|
17968
|
+
? queuedModeRequest.branchPath
|
|
17969
|
+
: String(queuedModeRequest.branchPath || '').split('>').filter(Boolean);
|
|
17970
|
+
var queueResult = await api.sendMessage({
|
|
17971
|
+
text: rawText,
|
|
17972
|
+
images: queuedModeRequest.images,
|
|
17973
|
+
branchPath: queuedBranchPath,
|
|
17974
|
+
branchNodeId: String(queuedBranchPath[queuedBranchPath.length - 1] || '')
|
|
17975
|
+
}, lockedTarget, {
|
|
17924
17976
|
clientMessageId: queuedModeRequest.clientMessageId,
|
|
17925
17977
|
inputMode: 'next',
|
|
17926
17978
|
requestedMode: requestedMode,
|
|
@@ -18117,12 +18169,6 @@ window.sendMessage = async function(modeOverride, queuedText, opts) {
|
|
|
18117
18169
|
updateSubmitButtonState();
|
|
18118
18170
|
var executionMode = opts.goalDeclaration || requestedMode === 'goal' ? 'build'
|
|
18119
18171
|
: ((opts.forceBuild || idleBuildNextImmediate) && requestedMode === 'build' ? 'build' : requestedMode);
|
|
18120
|
-
// The command freezes its mode and delivery policy; selector persistence
|
|
18121
|
-
// must not rewrite the mode of an already running target before acceptance.
|
|
18122
|
-
if (api.setModel && state.model !== state._syncedModel) {
|
|
18123
|
-
var selectedModelResult = await api.setModel(state.model);
|
|
18124
|
-
if (selectedModelResult != null) state._syncedModel = state.model;
|
|
18125
|
-
}
|
|
18126
18172
|
if (consumeProvisionalStop(lockedTarget, localRunId)) {
|
|
18127
18173
|
// Stop/Escape won before the backend accepted the prompt. Do not send the
|
|
18128
18174
|
// provider request after the user has already cancelled it.
|
|
@@ -18166,10 +18212,20 @@ window.sendMessage = async function(modeOverride, queuedText, opts) {
|
|
|
18166
18212
|
try {
|
|
18167
18213
|
var activationBeforeSend = pendingConversationActivation(lockedTarget);
|
|
18168
18214
|
if (activationBeforeSend) await activationBeforeSend;
|
|
18215
|
+
// Bind the model actually shown in the composer to the exact target
|
|
18216
|
+
// conversation after its activation snapshot restored the remembered
|
|
18217
|
+
// selection. This makes the visible provider/model authoritative for the
|
|
18218
|
+
// send and prevents a stale renderer selection from reaching another
|
|
18219
|
+
// conversation's remembered deployment.
|
|
18220
|
+
if (api.setModel && state.model && state.model !== state._syncedModel) {
|
|
18221
|
+
var selectedModelResult = await api.setModel(state.model);
|
|
18222
|
+
if (selectedModelResult != null) state._syncedModel = state.model;
|
|
18223
|
+
}
|
|
18169
18224
|
var sendPromise = api.sendMessage(requestMessage, lockedTarget, {
|
|
18170
18225
|
requestedMode: requestedMode, inputMode: effectiveInputMode,
|
|
18171
18226
|
goalObjective: opts.goalObjective || '',
|
|
18172
|
-
clientMessageId: String(requestMessage && requestMessage.clientMessageId || localRunId)
|
|
18227
|
+
clientMessageId: String(requestMessage && requestMessage.clientMessageId || localRunId),
|
|
18228
|
+
model: state.model
|
|
18173
18229
|
});
|
|
18174
18230
|
if (requestedMode === 'goal') activateSubmittedGoal(opts.goalObjective || rawText);
|
|
18175
18231
|
var r = await sendPromise;
|
|
@@ -23965,6 +24021,7 @@ function syncBackendConversation() {
|
|
|
23965
24021
|
}
|
|
23966
24022
|
if (conv && api.ensureConversation) {
|
|
23967
24023
|
var requestedTarget = currentConversationTarget(conv.id);
|
|
24024
|
+
var modelRevisionAtActivation = Number(state.modelSelectionRevision || 0);
|
|
23968
24025
|
state.activeBackendConversationId = conv.id;
|
|
23969
24026
|
var historyPromise = loadActiveConversationMessages(conv.id);
|
|
23970
24027
|
requestedLoadGeneration = state.conversationLoadGeneration;
|
|
@@ -23973,7 +24030,7 @@ function syncBackendConversation() {
|
|
|
23973
24030
|
var id = (s && s.conversationId) || conv.id;
|
|
23974
24031
|
if (!requestIsCurrent() || String(id) !== requestedConversationId) return;
|
|
23975
24032
|
state.activeBackendConversationId = id;
|
|
23976
|
-
applyConversationSnapshot(s, id, { preserveReadableHistory: true });
|
|
24033
|
+
applyConversationSnapshot(s, id, { preserveReadableHistory: true, modelRevision: modelRevisionAtActivation });
|
|
23977
24034
|
}).catch(function(error) {
|
|
23978
24035
|
if (!requestIsCurrent()) return;
|
|
23979
24036
|
showUiNotice(
|
|
@@ -24505,12 +24562,13 @@ window.newConversation = function(workspaceReference, branchCommunication) {
|
|
|
24505
24562
|
renderConversations();
|
|
24506
24563
|
els['chat-area'].innerHTML = '';
|
|
24507
24564
|
var target = currentConversationTarget(id);
|
|
24565
|
+
var modelRevisionAtActivation = Number(state.modelSelectionRevision || 0);
|
|
24508
24566
|
var activation = api.activateConversation ? api.activateConversation(target) : (api.ensureConversation ? api.ensureConversation(target) : Promise.resolve(null));
|
|
24509
24567
|
var activationKey = runtimeKeyFor(target.workspaceId, target.conversationId);
|
|
24510
24568
|
var activationReady = activation.then(function(s) {
|
|
24511
24569
|
if (createdWorkspaceKey !== currentWorkspaceKey() || id !== String(activeConversationId() || 'default')) return;
|
|
24512
24570
|
state.activeBackendConversationId = String((s && s.conversationId) || id);
|
|
24513
|
-
if (s) applyConversationSnapshot(s, id, { preserveReadableHistory: true });
|
|
24571
|
+
if (s) applyConversationSnapshot(s, id, { preserveReadableHistory: true, modelRevision: modelRevisionAtActivation });
|
|
24514
24572
|
if (branchCommunication && api.setConversationBranchCommunication) {
|
|
24515
24573
|
api.setConversationBranchCommunication(target, true).then(function() {
|
|
24516
24574
|
var convsNow = currentWorkspaceConversations();
|
|
@@ -28307,6 +28365,7 @@ function schedulePostStartupUiRendering() {
|
|
|
28307
28365
|
var selectedContextGeneration = state.conversationLoadGeneration;
|
|
28308
28366
|
var selectedContextModel = this.value;
|
|
28309
28367
|
state.model = selectedContextModel;
|
|
28368
|
+
state.modelSelectionRevision = Number(state.modelSelectionRevision || 0) + 1;
|
|
28310
28369
|
window.syncModelSelectSurface();
|
|
28311
28370
|
if (state.model !== state._syncedModel) {
|
|
28312
28371
|
var modelResult = await api.setModel(selectedContextModel);
|