@zhin.js/agent 1.1.39 → 1.1.41
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/lib/assistant/job-storage.d.ts +238 -0
- package/lib/assistant/job-storage.js +143 -0
- package/lib/assistant/job-storage.js.map +1 -0
- package/lib/assistant/job-store.d.ts +7 -0
- package/lib/assistant/job-store.js +41 -3
- package/lib/assistant/job-store.js.map +1 -1
- package/lib/config/perception-config.d.ts +9 -0
- package/lib/config/perception-config.js +27 -0
- package/lib/config/perception-config.js.map +1 -1
- package/lib/context/context-system.d.ts +1 -0
- package/lib/context/context-system.js +8 -8
- package/lib/context/context-system.js.map +1 -1
- package/lib/context/im-turn-context-adapter.js +2 -0
- package/lib/context/im-turn-context-adapter.js.map +1 -1
- package/lib/context/skill-context.d.ts +3 -0
- package/lib/context/skill-context.js +6 -0
- package/lib/context/skill-context.js.map +1 -0
- package/lib/context/turn-envelope.d.ts +4 -0
- package/lib/context/turn-envelope.js +24 -7
- package/lib/context/turn-envelope.js.map +1 -1
- package/lib/context/turn-user-message.d.ts +3 -1
- package/lib/context/turn-user-message.js +14 -1
- package/lib/context/turn-user-message.js.map +1 -1
- package/lib/core/agent-core-run.d.ts +1 -0
- package/lib/core/agent-core-run.js +47 -20
- package/lib/core/agent-core-run.js.map +1 -1
- package/lib/core/structured-reply-recovery.d.ts +6 -2
- package/lib/core/structured-reply-recovery.js +22 -8
- package/lib/core/structured-reply-recovery.js.map +1 -1
- package/lib/core/turn-completion-usage.d.ts +2 -1
- package/lib/core/turn-completion-usage.js +14 -5
- package/lib/core/turn-completion-usage.js.map +1 -1
- package/lib/core/turn-event-mapper.d.ts +1 -1
- package/lib/core/turn-event-mapper.js +8 -5
- package/lib/core/turn-event-mapper.js.map +1 -1
- package/lib/decision/config.d.ts +1 -1
- package/lib/decision/config.js +1 -1
- package/lib/decision/config.js.map +1 -1
- package/lib/decision/types.d.ts +1 -1
- package/lib/decision/types.js.map +1 -1
- package/lib/event/turn-event.d.ts +7 -1
- package/lib/event/turn-event.js.map +1 -1
- package/lib/index.d.ts +4 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/media/perception.d.ts +3 -4
- package/lib/media/perception.js +59 -37
- package/lib/media/perception.js.map +1 -1
- package/lib/memory/compaction-runtime.d.ts +3 -2
- package/lib/memory/compaction-runtime.js +22 -14
- package/lib/memory/compaction-runtime.js.map +1 -1
- package/lib/outbound/agent-output.js +2 -0
- package/lib/outbound/agent-output.js.map +1 -1
- package/lib/outbound/chat-failure.d.ts +27 -0
- package/lib/outbound/chat-failure.js +53 -0
- package/lib/outbound/chat-failure.js.map +1 -0
- package/lib/outbound/structured-reply.d.ts +7 -0
- package/lib/outbound/structured-reply.js +52 -16
- package/lib/outbound/structured-reply.js.map +1 -1
- package/lib/plugin-runtime/agent-runtime.js +49 -8
- package/lib/plugin-runtime/agent-runtime.js.map +1 -1
- package/lib/plugin-runtime/ai-completion.d.ts +4 -3
- package/lib/plugin-runtime/ai-completion.js +64 -10
- package/lib/plugin-runtime/ai-completion.js.map +1 -1
- package/lib/plugin-runtime/capability-ingress.js +3 -1
- package/lib/plugin-runtime/capability-ingress.js.map +1 -1
- package/lib/plugin-runtime/decision-runtime.d.ts +1 -0
- package/lib/plugin-runtime/deferred-capability-plan.d.ts +4 -1
- package/lib/plugin-runtime/deferred-capability-plan.js +25 -9
- package/lib/plugin-runtime/deferred-capability-plan.js.map +1 -1
- package/lib/plugin-runtime/full-agent-turn-engine.js +1 -0
- package/lib/plugin-runtime/full-agent-turn-engine.js.map +1 -1
- package/lib/plugin-runtime/index.d.ts +2 -0
- package/lib/plugin-runtime/index.js +2 -0
- package/lib/plugin-runtime/index.js.map +1 -1
- package/lib/prompt/assembly.js +0 -9
- package/lib/prompt/assembly.js.map +1 -1
- package/lib/prompt/git-context.js +1 -1
- package/lib/prompt/git-context.js.map +1 -1
- package/lib/prompt/rules/chat-rules.js +8 -9
- package/lib/prompt/rules/chat-rules.js.map +1 -1
- package/lib/prompt/rules/critical-rules.js +10 -10
- package/lib/prompt/rules/critical-rules.js.map +1 -1
- package/lib/prompt/system-prompt.js +4 -5
- package/lib/prompt/system-prompt.js.map +1 -1
- package/lib/security/file-role-policy.js +6 -6
- package/lib/security/file-role-policy.js.map +1 -1
- package/lib/security/policy-facade.js +1 -1
- package/lib/security/policy-facade.js.map +1 -1
- package/lib/security/usage-quota.d.ts +4 -0
- package/lib/security/usage-quota.js +23 -2
- package/lib/security/usage-quota.js.map +1 -1
- package/lib/session/approval-port.d.ts +2 -0
- package/lib/session/approval-port.js.map +1 -1
- package/lib/session/approval-review-agent.d.ts +1 -1
- package/lib/session/approval-review-agent.js +19 -4
- package/lib/session/approval-review-agent.js.map +1 -1
- package/lib/session/turn-ingress-session.js +7 -1
- package/lib/session/turn-ingress-session.js.map +1 -1
- package/lib/tool/tool-approval-gate.js +4 -2
- package/lib/tool/tool-approval-gate.js.map +1 -1
- package/lib/tool/turn-tool-runtime.js +24 -5
- package/lib/tool/turn-tool-runtime.js.map +1 -1
- package/lib/tool-catalog/deferred-turn-controller.js +1 -4
- package/lib/tool-catalog/deferred-turn-controller.js.map +1 -1
- package/lib/trace/context-budget.d.ts +4 -3
- package/lib/trace/context-budget.js +28 -8
- package/lib/trace/context-budget.js.map +1 -1
- package/lib/trace/turn-trace-format.js +4 -1
- package/lib/trace/turn-trace-format.js.map +1 -1
- package/lib/trace/turn-trace.d.ts +6 -0
- package/lib/trace/turn-trace.js +8 -2
- package/lib/trace/turn-trace.js.map +1 -1
- package/lib/trace/turn-usage-log.d.ts +14 -0
- package/lib/trace/turn-usage-log.js +83 -0
- package/lib/trace/turn-usage-log.js.map +1 -0
- package/lib/usage/usage-store.d.ts +199 -0
- package/lib/usage/usage-store.js +121 -0
- package/lib/usage/usage-store.js.map +1 -0
- package/package.json +12 -12
|
@@ -5,7 +5,7 @@ import { decodeStructuredReply, structuredReplyInstruction, structuredReplySchem
|
|
|
5
5
|
import { renderAgentOutput } from '../outbound/agent-output.js';
|
|
6
6
|
import { mergeToolOutboundElements } from '../media/media-tool-bridge.js';
|
|
7
7
|
import { formatCompact, truncatePreview, getLogger } from '@zhin.js/logger';
|
|
8
|
-
import { parseOutput, agentLoop, agentContextFrom, assistantText, createUserMessage, agentToolsToLlmTools, createResilientCompletionPort, isProviderFailureMessage, resolveProviderConfigResilience, resolveProviderResilienceConfig } from '@zhin.js/ai';
|
|
8
|
+
import { createPromptContextBlock, projectPromptContext, estimateContextFixedTokens, parseOutput, agentLoop, agentContextFrom, assistantText, createUserMessage, agentToolsToLlmTools, createResilientCompletionPort, isProviderFailureMessage, resolveProviderConfigResilience, resolveProviderResilienceConfig } from '@zhin.js/ai';
|
|
9
9
|
import { tokenUsageToLegacy } from './agent-run-shared.js';
|
|
10
10
|
import { applyExecPolicyToTools } from '../security/exec-policy.js';
|
|
11
11
|
import { resolveModelHarness } from '../config/model-harness-runtime.js';
|
|
@@ -15,7 +15,8 @@ import { planToolRun } from '../tool/runtime.js';
|
|
|
15
15
|
import { sanitizeAssistantReply, unwrapJsonStringLayers } from './text-sanitize.js';
|
|
16
16
|
import { formatToolCallsForUser } from './tool-calls-user-format.js';
|
|
17
17
|
import { summarizeExhaustedTurn } from './exhausted-turn-reply.js';
|
|
18
|
-
import { decodeLenientStructuredReply, recoverStructuredReply
|
|
18
|
+
import { decodeLenientStructuredReply, recoverStructuredReply } from './structured-reply-recovery.js';
|
|
19
|
+
import { chatFailureKindOf, chatFailureLine } from '../outbound/chat-failure.js';
|
|
19
20
|
import { trackTurnCompletionUsage } from './turn-completion-usage.js';
|
|
20
21
|
import { shouldSuppressReplyForSpawnDelegation } from './spawn-delegation.js';
|
|
21
22
|
import { logPhase, tokenUsageLogFields, logAgentLoopIterationEnd } from '../internal/phase-trace.js';
|
|
@@ -24,7 +25,7 @@ import { buildLlmToolsForProvider } from '../tool/deferred-resolution.js';
|
|
|
24
25
|
import { applyToolToModelOutput } from '../tool/tool-model-output.js';
|
|
25
26
|
import { resolveAlwaysLoadedSet } from '../tool-catalog/resolve-config.js';
|
|
26
27
|
import { resolveDeferredApiTools, residentToolNames } from '../tool-catalog/tool-catalog.js';
|
|
27
|
-
import { createTurnEventMapperState, mapAgentEventToTurnEvents,
|
|
28
|
+
import { createTurnEventMapperState, mapAgentEventToTurnEvents, } from './turn-event-mapper.js';
|
|
28
29
|
import { TurnJournalCommitError } from '../turn/journal-integrity.js';
|
|
29
30
|
import { ExecutableToolRegistry } from '../tool/executable-tool-registry.js';
|
|
30
31
|
import { withoutForbiddenShell } from '../plugin-runtime/native-bash-tool.js';
|
|
@@ -33,7 +34,6 @@ import { createMissingToolResolver } from './missing-tool-resolver.js';
|
|
|
33
34
|
import { DEFAULT_EXPLORATION_BUDGET, EXPLORATION_GUIDANCE, ExplorationBudget, } from './exploration-budget.js';
|
|
34
35
|
import { TurnProgressTracker, autoContinueAllowed, buildContinuationInstruction, isProgress, resolveToolBudget, } from './turn-progress.js';
|
|
35
36
|
import { TurnProgressReporter, summarizeProgress } from './progress-reporter.js';
|
|
36
|
-
import { estimatePromptTokens } from '../prompt/estimate-tokens.js';
|
|
37
37
|
import { noteTurnTrace } from '../trace/turn-trace-registry.js';
|
|
38
38
|
import { buildContextBudgetReport } from '../trace/context-budget.js';
|
|
39
39
|
import { renderDeferredToolIndex } from '../skill/capability-catalog.js';
|
|
@@ -46,11 +46,14 @@ function normalizeAssistantMessageText(assistant) {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
function resolveAssistantReplyText(assistant) {
|
|
49
|
+
function resolveAssistantReplyText(assistant, chat) {
|
|
50
50
|
normalizeAssistantMessageText(assistant);
|
|
51
51
|
const text = assistantText(assistant);
|
|
52
52
|
if (text.trim())
|
|
53
53
|
return text;
|
|
54
|
+
// In a chat the failure is said like a member would say it; operators read the logs.
|
|
55
|
+
if (assistant.errorMessage && chat)
|
|
56
|
+
return chatFailureLine(chatFailureKindOf(assistant.errorMessage), chat);
|
|
54
57
|
if (assistant.errorMessage && isProviderFailureMessage(assistant.errorMessage)) {
|
|
55
58
|
return `${assistant.errorMessage}。`;
|
|
56
59
|
}
|
|
@@ -184,7 +187,7 @@ async function* runAgentLoopVisionTurnOnceRun(input) {
|
|
|
184
187
|
modelId,
|
|
185
188
|
label: 'vision',
|
|
186
189
|
}),
|
|
187
|
-
convertToLlm:
|
|
190
|
+
convertToLlm: projectPromptContext,
|
|
188
191
|
getSteeringMessages: promptHooks?.getSteeringMessages,
|
|
189
192
|
getFollowUpMessages: promptHooks?.getFollowUpMessages,
|
|
190
193
|
};
|
|
@@ -320,7 +323,7 @@ export async function* runAgentLoopTextTurnRun(input) {
|
|
|
320
323
|
const loaded = persistentConversation
|
|
321
324
|
? await repo.loadContext(sessionId)
|
|
322
325
|
: { messages: [] };
|
|
323
|
-
|
|
326
|
+
let promptMessages = input.initialMessages?.length
|
|
324
327
|
? input.initialMessages
|
|
325
328
|
: [createUserMessage(input.rawContent)];
|
|
326
329
|
const directTools = input.toolLoading === 'direct';
|
|
@@ -336,6 +339,9 @@ export async function* runAgentLoopTextTurnRun(input) {
|
|
|
336
339
|
const messagePreset = configuredSchema === true || configuredSchema === 'segments';
|
|
337
340
|
const imReply = messagePreset && input.turnContext.origin.kind === 'im'
|
|
338
341
|
&& input.conversationPersistence !== 'none';
|
|
342
|
+
const chatFailure = input.turnContext.origin.kind === 'im'
|
|
343
|
+
? { master: input.turnContext.principal.roles.includes('master') }
|
|
344
|
+
: undefined;
|
|
339
345
|
const outputSchema = imReply ? structuredReplySchema(input.replySegments)
|
|
340
346
|
: messagePreset || !configuredSchema ? undefined : configuredSchema;
|
|
341
347
|
const turnShellPolicy = input.turnContext.policy?.shell;
|
|
@@ -433,8 +439,15 @@ export async function* runAgentLoopTextTurnRun(input) {
|
|
|
433
439
|
if (hasTools && !directTools) {
|
|
434
440
|
const toolIndex = renderDeferredToolIndex(deferredCatalogTools(catalog, agentTools)
|
|
435
441
|
.map((item) => ({ name: item.name, description: item.brief })));
|
|
436
|
-
if (toolIndex)
|
|
437
|
-
|
|
442
|
+
if (toolIndex) {
|
|
443
|
+
const block = createPromptContextBlock('deferred-tools', toolIndex);
|
|
444
|
+
const userIndex = promptMessages.map(message => message.role === 'user' && Array.isArray(message.content)).lastIndexOf(true);
|
|
445
|
+
promptMessages = userIndex < 0
|
|
446
|
+
? [...promptMessages, { ...createUserMessage(''), content: [block] }]
|
|
447
|
+
: promptMessages.map((message, index) => index === userIndex && Array.isArray(message.content)
|
|
448
|
+
? { ...message, content: [...message.content, block] }
|
|
449
|
+
: message);
|
|
450
|
+
}
|
|
438
451
|
}
|
|
439
452
|
if (networkWithheld)
|
|
440
453
|
systemPrompt = `${systemPrompt}\n\n${NETWORK_DISABLED_PROMPT_NOTE}`;
|
|
@@ -447,6 +460,7 @@ export async function* runAgentLoopTextTurnRun(input) {
|
|
|
447
460
|
kind: 'context_budget',
|
|
448
461
|
report: buildContextBudgetReport({
|
|
449
462
|
systemPrompt,
|
|
463
|
+
outputSchema,
|
|
450
464
|
sections: promptSections,
|
|
451
465
|
bootstrapContext: input.promptRuntime?.bootstrapContext,
|
|
452
466
|
activeSkillsContext: input.promptRuntime?.activeSkillsContext,
|
|
@@ -490,8 +504,16 @@ export async function* runAgentLoopTextTurnRun(input) {
|
|
|
490
504
|
const contextWindow = llmModel.contextWindow ?? host.config.contextTokens;
|
|
491
505
|
// System prompt and tool schemas count against the window too, so the
|
|
492
506
|
// compaction threshold is measured on what is left for messages (#730).
|
|
493
|
-
|
|
494
|
-
|
|
507
|
+
let budgetTools;
|
|
508
|
+
let fixedBudget;
|
|
509
|
+
const fixedPromptTokens = () => {
|
|
510
|
+
// 本回合系统提示不变;工具渐进披露替换数组后重新计算完整 Schema。
|
|
511
|
+
if (!fixedBudget || budgetTools !== llmTools) {
|
|
512
|
+
budgetTools = llmTools;
|
|
513
|
+
fixedBudget = estimateContextFixedTokens({ systemPrompt, tools: llmTools, model: llmModel, outputSchema });
|
|
514
|
+
}
|
|
515
|
+
return fixedBudget;
|
|
516
|
+
};
|
|
495
517
|
const loopHooks = input.loopHooks;
|
|
496
518
|
const completionPort = createTurnCompletionPort({
|
|
497
519
|
host,
|
|
@@ -544,7 +566,7 @@ export async function* runAgentLoopTextTurnRun(input) {
|
|
|
544
566
|
}),
|
|
545
567
|
...(outputSchema ? { outputSchema } : {}),
|
|
546
568
|
},
|
|
547
|
-
convertToLlm:
|
|
569
|
+
convertToLlm: projectPromptContext,
|
|
548
570
|
transformContext: async (messages, ctxSignal) => persistentConversation ? host.compactionRuntime.transformContext(messages, ctxSignal, {
|
|
549
571
|
host,
|
|
550
572
|
sessionId,
|
|
@@ -552,7 +574,7 @@ export async function* runAgentLoopTextTurnRun(input) {
|
|
|
552
574
|
model: llmModel,
|
|
553
575
|
compactionConfig: host.config.compaction,
|
|
554
576
|
contextWindow,
|
|
555
|
-
reservedTokens: fixedPromptTokens(),
|
|
577
|
+
reservedTokens: await fixedPromptTokens(),
|
|
556
578
|
toldLedger: host.toldLedger?.render(sessionId),
|
|
557
579
|
mode: 'text',
|
|
558
580
|
loopHooks,
|
|
@@ -564,7 +586,7 @@ export async function* runAgentLoopTextTurnRun(input) {
|
|
|
564
586
|
model: llmModel,
|
|
565
587
|
compactionConfig: host.config.compaction,
|
|
566
588
|
contextWindow,
|
|
567
|
-
reservedTokens: fixedPromptTokens(),
|
|
589
|
+
reservedTokens: await fixedPromptTokens(),
|
|
568
590
|
toldLedger: host.toldLedger?.render(sessionId),
|
|
569
591
|
mode: 'text',
|
|
570
592
|
force: true,
|
|
@@ -644,7 +666,9 @@ export async function* runAgentLoopTextTurnRun(input) {
|
|
|
644
666
|
const budgetNote = explorationBudget?.record(resolvedName, isProgress(progressKind));
|
|
645
667
|
const finalText = budgetNote ? `${resultText}\n\n${budgetNote}` : resultText;
|
|
646
668
|
toolCalls.push({ tool: resolvedName, args: effectiveArgs, result: finalText });
|
|
647
|
-
|
|
669
|
+
const result = toolResultToAgentMessage(toolCall, finalText, false);
|
|
670
|
+
const blocks = deferredController?.modelOutputBlocks?.(resolvedName, effectiveArgs, finalText);
|
|
671
|
+
return blocks ? { ...result, content: blocks } : result;
|
|
648
672
|
}
|
|
649
673
|
catch (err) {
|
|
650
674
|
if (err instanceof TurnJournalCommitError)
|
|
@@ -719,8 +743,7 @@ export async function* runAgentLoopTextTurnRun(input) {
|
|
|
719
743
|
// Messages of the running segment, for progress summaries before agent_end.
|
|
720
744
|
let segmentMessages = [];
|
|
721
745
|
function* drainCompletionUsage() {
|
|
722
|
-
for (const
|
|
723
|
-
const event = turnUsageEvent(usage);
|
|
746
|
+
for (const event of completionUsage.drainEvents()) {
|
|
724
747
|
emitTurnEvent(event);
|
|
725
748
|
yield event;
|
|
726
749
|
}
|
|
@@ -773,7 +796,7 @@ export async function* runAgentLoopTextTurnRun(input) {
|
|
|
773
796
|
lastAssistantNeedsHostReply = Boolean(assistant.errorMessage)
|
|
774
797
|
|| (!lastAssistantHadToolCalls && !answerText.trim());
|
|
775
798
|
lastAssistantText = imReply && !lastAssistantNeedsHostReply ? answerText
|
|
776
|
-
: resolveAssistantReplyText(imReply ? { ...assistant, content: [] } : assistant);
|
|
799
|
+
: resolveAssistantReplyText(imReply ? { ...assistant, content: [] } : assistant, chatFailure);
|
|
777
800
|
logAssistantIterationFailure(assistant, modelId, sessionId);
|
|
778
801
|
const toolNames = assistant.content
|
|
779
802
|
.filter((b) => b.type === 'toolCall')
|
|
@@ -904,7 +927,10 @@ export async function* runAgentLoopTextTurnRun(input) {
|
|
|
904
927
|
const continuationPrefix = continuations > 0 && input.turnContext.origin.kind !== 'im'
|
|
905
928
|
? `(任务步骤较多,已自动续跑 ${continuations} 次)\n\n` : '';
|
|
906
929
|
const proseReply = structuredReply ? ''
|
|
907
|
-
: sanitizeAssistantReply(rawReply, {
|
|
930
|
+
: sanitizeAssistantReply(rawReply, {
|
|
931
|
+
toolSummary: formatToolCallsForUser(toolCalls),
|
|
932
|
+
...(chatFailure ? { emptyMessage: chatFailureLine('malformed_tool_call', chatFailure) } : {}),
|
|
933
|
+
});
|
|
908
934
|
const textReply = delegatedOnly ? '' : proseReply.trim() ? continuationPrefix + proseReply : proseReply;
|
|
909
935
|
let output = delegatedOnly || structuredReply ? [] : parseOutput(textReply);
|
|
910
936
|
if (!delegatedOnly && structuredReply) {
|
|
@@ -926,13 +952,14 @@ export async function* runAgentLoopTextTurnRun(input) {
|
|
|
926
952
|
transport: completionUsage.transport, model: llmModel, raw: rawReply,
|
|
927
953
|
error: error instanceof Error ? error : new Error('Invalid structured reply'), signal,
|
|
928
954
|
segments: input.replySegments,
|
|
955
|
+
failureText: chatFailureLine('format', { ...chatFailure, random: 0 }),
|
|
929
956
|
});
|
|
930
957
|
output = recovery.output;
|
|
931
958
|
// History must match what the user saw: the corrected reply, or the failure text. Never the
|
|
932
959
|
// correction prompt (it embeds the rejected raw text) and never the rejected raw reply.
|
|
933
960
|
if (messages && rejected?.role === 'assistant') {
|
|
934
961
|
messages[messages.length - 1] = recovery.assistant
|
|
935
|
-
?? { ...rejected, content: [{ type: 'text', text:
|
|
962
|
+
?? { ...rejected, content: [{ type: 'text', text: renderAgentOutput(recovery.output) }] };
|
|
936
963
|
}
|
|
937
964
|
}
|
|
938
965
|
}
|