newmark-agent 0.6.2 → 0.6.4
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 +2149 -475
- package/dist/core/agent.d.ts +37 -0
- package/dist/core/agent.js +104 -7
- package/dist/core/agentKernelRunner.js +37 -2
- package/dist/core/branchIdentity.d.ts +29 -0
- package/dist/core/branchIdentity.js +54 -0
- package/dist/core/continuation/contracts.d.ts +197 -0
- package/dist/core/continuation/contracts.js +72 -0
- package/dist/core/continuation/store.d.ts +206 -0
- package/dist/core/continuation/store.js +1077 -0
- package/dist/core/conversationKernel.d.ts +93 -2
- package/dist/core/conversationKernel.js +648 -36
- package/dist/core/requestContextEstimate.d.ts +5 -1
- package/dist/llm/provider.js +9 -2
- package/dist/main.js +40 -5
- 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 +413 -55
- package/dist/wsl-agent-host.bundle.cjs +2152 -478
- package/package.json +5 -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
|
@@ -3123,7 +3123,7 @@ else {
|
|
|
3123
3123
|
};
|
|
3124
3124
|
const mutateConversationQueue = async (target, rawAction, input = {}) => {
|
|
3125
3125
|
const action = rawAction.replace(/^queue_/, '');
|
|
3126
|
-
if (!['enqueue', 'update', 'delete', 'reorder', 'toggle_pause', 'set_pause', 'guide'].includes(action))
|
|
3126
|
+
if (!['enqueue', 'update', 'delete', 'reorder', 'toggle_pause', 'set_pause', 'repair_blocked', 'guide'].includes(action))
|
|
3127
3127
|
throw new Error('Unknown queue action');
|
|
3128
3128
|
const key = activeFlowStateKey(target);
|
|
3129
3129
|
const flow = activeFlowStateFor(target);
|
|
@@ -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([
|