newmark-agent 0.3.12 → 0.4.2

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.
Files changed (60) hide show
  1. package/dist/cli-commands.d.ts +1 -0
  2. package/dist/cli-commands.js +11 -2
  3. package/dist/context/domain/types.d.ts +37 -0
  4. package/dist/context/services/context-orchestrator.js +2 -0
  5. package/dist/conversation-utility-host.bundle.cjs +1259 -132
  6. package/dist/conversation-utility-host.js +3 -0
  7. package/dist/core/agent.d.ts +139 -5
  8. package/dist/core/agent.js +964 -82
  9. package/dist/core/agentKernel/agent-loop.js +29 -3
  10. package/dist/core/agentKernel/types.d.ts +7 -0
  11. package/dist/core/agentKernelRunner.d.ts +2 -0
  12. package/dist/core/agentKernelRunner.js +121 -19
  13. package/dist/core/conversationKernel.d.ts +5 -0
  14. package/dist/core/conversationKernel.js +29 -0
  15. package/dist/core/dshCompatibility.d.ts +198 -0
  16. package/dist/core/dshCompatibility.js +600 -0
  17. package/dist/core/electronUtilityAgentClient.d.ts +4 -0
  18. package/dist/core/electronUtilityAgentClient.js +4 -0
  19. package/dist/core/electronUtilityRuntimePool.d.ts +8 -0
  20. package/dist/core/electronUtilityRuntimePool.js +14 -0
  21. package/dist/core/mcpManager.d.ts +1 -0
  22. package/dist/core/mcpManager.js +100 -10
  23. package/dist/core/subagent.d.ts +6 -0
  24. package/dist/core/subagent.js +22 -1
  25. package/dist/core/toolPolicy.d.ts +15 -0
  26. package/dist/core/toolPolicy.js +174 -1
  27. package/dist/core/types.d.ts +1 -1
  28. package/dist/core/utilityAgentProtocol.d.ts +8 -1
  29. package/dist/core/workspace.d.ts +9 -0
  30. package/dist/core/workspace.js +48 -1
  31. package/dist/core/wslAgentClient.d.ts +4 -0
  32. package/dist/core/wslAgentClient.js +4 -0
  33. package/dist/core/wslAgentProtocol.d.ts +8 -1
  34. package/dist/core/wslAgentRuntimePool.d.ts +8 -0
  35. package/dist/core/wslAgentRuntimePool.js +15 -0
  36. package/dist/launcher.js +8 -0
  37. package/dist/llm/provider.d.ts +1 -1
  38. package/dist/llm/provider.js +4 -3
  39. package/dist/main.js +163 -11
  40. package/dist/preload.js +11 -0
  41. package/dist/providers/chat-completions.adapter.js +41 -15
  42. package/dist/providers/provider-adapter.d.ts +3 -0
  43. package/dist/toolchain/registry/tool-registry.d.ts +13 -1
  44. package/dist/toolchain/registry/tool-registry.js +8 -0
  45. package/dist/toolchain/registry-seeder.js +52 -6
  46. package/dist/tools/index.d.ts +1 -0
  47. package/dist/tools/index.js +39 -2
  48. package/dist/tools/nativeTools.js +6 -1
  49. package/dist/tui/src/app.js +24 -0
  50. package/dist/tui/src/i18n.js +151 -0
  51. package/dist/tui/src/render.js +152 -61
  52. package/dist/tui/src/state.js +83 -0
  53. package/dist/ui/index.html +2669 -234
  54. package/dist/ui/lucide-sprite.svg +31 -0
  55. package/dist/wsl-agent-host.bundle.cjs +1259 -132
  56. package/dist/wsl-agent-host.js +3 -0
  57. package/package.json +6 -10
  58. package/Flow/Electron-Debug-Release.Flow.json +0 -43
  59. package/Flow/Flow.md +0 -9
  60. package/Flow/UI-Feature-Integration.Flow.json +0 -96
@@ -81,6 +81,9 @@ async function handle(request) {
81
81
  }
82
82
  if (request.method === 'checkpoint')
83
83
  return kernel.checkpoint(checkedTarget(request.params.target));
84
+ if (request.method === 'context_compress') {
85
+ return kernel.compressContext(checkedTarget(request.params.target), request.params.options);
86
+ }
84
87
  if (request.method === 'rate_auto_route') {
85
88
  return kernel.rateAutoRoute(checkedTarget(request.params.target), request.params.score, request.params.routeId);
86
89
  }
@@ -61,6 +61,19 @@ export interface AutoRouteRatingResult {
61
61
  }
62
62
  export declare const ROOT_AGENT_ACTOR_ID = "00000000-0000-4000-8000-000000000001";
63
63
  export declare function normalizeIntelligenceTier(value: unknown): 'low' | 'medium' | 'high' | 'xhigh' | 'max' | 'ultra';
64
+ export interface BranchMessage {
65
+ id: string;
66
+ conversationId: string;
67
+ sequence: number;
68
+ fromBranchId: string;
69
+ toBranchId: string;
70
+ kind: 'message' | 'directive' | 'result';
71
+ body: string;
72
+ correlationId?: string;
73
+ replyTo?: string;
74
+ createdAt: string;
75
+ readAt?: string;
76
+ }
64
77
  export interface CompressionCacheEntry {
65
78
  id: string;
66
79
  at: string;
@@ -175,6 +188,8 @@ export interface ConversationTreeState {
175
188
  rootNodeId: string;
176
189
  activeNodeId: string;
177
190
  activeGroupId: string;
191
+ /** Branch-communication mode only: every branch id that is currently running (removes single-runtime uniqueness). */
192
+ runningNodeIds?: string[];
178
193
  nodes: Record<string, ConversationTreeNode>;
179
194
  branchGroups: Record<string, ConversationBranchGroupState>;
180
195
  nodeIndex: Record<string, ConversationTreeNodeIndexEntry>;
@@ -300,6 +315,11 @@ export declare class Agent {
300
315
  fallback: boolean;
301
316
  } | null;
302
317
  private compressionCache;
318
+ private pendingHistoryRemovals;
319
+ private branchMailbox;
320
+ private nextBranchMessageSequence;
321
+ private branchCommunicationEnabled;
322
+ private compressionArchiveCountCache;
303
323
  private nextCompressionCacheId;
304
324
  private readonly compressionHistoryArchive;
305
325
  private workspaceConversations;
@@ -358,6 +378,10 @@ export declare class Agent {
358
378
  readonly runtimeLifecycleRole: RuntimeLifecycleRole;
359
379
  /** dev-0.3.0 context system facade (feature-flagged, default off). */
360
380
  readonly contextV2: AgentContextManager;
381
+ /** 工具结果的持久化引用(artifact_id -> 状态 + 内容)。
382
+ * 两种来源:超大结果落盘(content 立即可得)与后台工具(status=running 直到完成)。
383
+ * 压缩前/后台中的大内容不进上下文,只通过 artifact_id 引用;读取后再释放。 */
384
+ private readonly toolResultArtifacts;
361
385
  private readonly runtimeLifecycle;
362
386
  /** dev-0.3.0 toolchain core (registry + capability catalog). Seeded lazily from cachedToolDefinitions; not consumed by the legacy path. */
363
387
  private toolchainCore;
@@ -386,6 +410,11 @@ export declare class Agent {
386
410
  private branchGroupMetadata;
387
411
  private treeAncestry;
388
412
  private treePath;
413
+ /** 确定性消息 ID:基于角色+内容+索引的 sha256,保证旧数据缺失 messageId 时补生成稳定、
414
+ * 不漂移,且跨分支共享 fork 前缀消息得到一致 ID。 */
415
+ private deterministicMessageId;
416
+ /** 确定性 Guide ID:基于消息 ID + 索引,保证补生成稳定唯一。 */
417
+ private deterministicGuideId;
389
418
  private rebuildConversationTreeIndex;
390
419
  private validateConversationTree;
391
420
  private resolveConversationTreePath;
@@ -483,6 +512,19 @@ export declare class Agent {
483
512
  setConversationWorkRunFlowMetadata(runId: string, flow: NonNullable<ConversationWorkRun['flow']>): boolean;
484
513
  replaceConversationWorkRunFinalResponse(runId: string, content: string): boolean;
485
514
  resumeConversationWorkRun(runId: string): boolean;
515
+ /**
516
+ * Close any running Build ledger entries owned by an explicitly interrupted
517
+ * lifecycle before a Flow is resumed or a conversation is archived.
518
+ *
519
+ * The normal Flow runner guard must continue to reject a genuinely
520
+ * concurrent Build. This method is deliberately explicit and target-scoped:
521
+ * callers use it only after the owning Flow has been stopped/paused or when
522
+ * archive has won the lifecycle race. Without this boundary, an isolated
523
+ * Agent created during resume can legitimately reload the previous snapshot
524
+ * while its runtime owner is still this Electron process and the guard would
525
+ * mistake that stale ledger entry for an active Build.
526
+ */
527
+ interruptRunningConversationWorkRuns(target?: ConversationTarget, status?: Extract<ConversationWorkRunStatus, 'interrupted' | 'force_interrupted'>): number;
486
528
  recordGuideReceipt(input: GuideReceipt): GuideReceipt;
487
529
  private durableAttachmentsFromHistoryContent;
488
530
  private normalizeConversationChatMessages;
@@ -564,6 +606,7 @@ export declare class Agent {
564
606
  pinned: boolean;
565
607
  pinnedAt: string;
566
608
  order: number;
609
+ branchCommunication: boolean;
567
610
  }>;
568
611
  private normalizeLinkedPlan;
569
612
  private subagentManagerKey;
@@ -582,9 +625,18 @@ export declare class Agent {
582
625
  ensureConversationSnapshot(conversationId?: string): ConversationSnapshot;
583
626
  rewindConversation(conversationId: string, messageIndex: number): ConversationSnapshot;
584
627
  branchConversation(conversationId: string, messageIndex: number, editedText: string, locator?: ConversationBranchLocator): ConversationSnapshot;
628
+ setBranchCommunication(enabled: boolean): boolean;
629
+ isBranchCommunicationEnabled(): boolean;
585
630
  switchConversationBranch(conversationId: string, branchId: string, branchGroupId?: string): ConversationSnapshot;
586
631
  setConversationPinned(id: string, pinned: boolean): boolean;
587
632
  renameConversation(id: string, title: string): boolean;
633
+ /**
634
+ * 首 Build 命名提示判定:仅当 (1) 当前对话尚无历史 Build(排除当前 run)且
635
+ * (2) 其持久化 title 仍是自动生成(含为空)时返回 true。满足条件时运行时会
636
+ * 在首个 provider request 的 bootstrap 注入一次性命名指令,让 Agent 调用
637
+ * conversation_rename 自行命名。判定本身只读存储、无副作用,保缓存稳定。
638
+ */
639
+ shouldPromptConversationRename(): boolean;
588
640
  reorderConversations(ids: string[]): boolean;
589
641
  flushConversationState(): void;
590
642
  private titleFromMessages;
@@ -619,6 +671,71 @@ export declare class Agent {
619
671
  }>;
620
672
  handleBuildHistoryQuery(args: string): string;
621
673
  handleContextCompress(args: string, signal?: AbortSignal): Promise<NewmarkToolResult>;
674
+ /**
675
+ * 落盘一个超大工具结果,返回 artifact_id。完整内容不进上下文——上下文只保留
676
+ * tiny 引用;compress_tool_result 按 id 读取后再压缩。落盘后状态即 done。
677
+ */
678
+ storeToolResultArtifact(tool: string, content: string): string;
679
+ /**
680
+ * 注册一个后台工具任务,立即返回 background_id(status=running)。真实工具在
681
+ * 后台执行,完成后由 finishToolResultArtifact 标记 done/error。后台结果持久化
682
+ * 等待 read_tool_result 读取后再释放。
683
+ */
684
+ beginBackgroundTool(tool: string): string;
685
+ /** 标记后台任务完成(写结果)或失败(写错误)。 */
686
+ finishToolResultArtifact(id: string, content: string, error?: string): void;
687
+ /**
688
+ * 按 artifact_id 读取工具结果引用(compress_tool_result / read_tool_result 共用)。
689
+ */
690
+ readToolResultArtifact(id: string): {
691
+ tool: string;
692
+ content: string;
693
+ status: 'running' | 'done' | 'error';
694
+ error?: string;
695
+ createdAt: number;
696
+ } | null;
697
+ /**
698
+ * 压缩一个极大的工具调用结果(保留格式),供 Agent 主动选用以替代硬截断。
699
+ *
700
+ * 入参为 artifact_id(而非完整 content),故压缩前的大内容不进入上下文。
701
+ * 缓存命中隔离:压缩 LLM 调用使用独立 system + 单条 user 消息,与主对话
702
+ * system/历史前缀不相交,不污染缓存命中。
703
+ */
704
+ handleCompressToolResult(args: string, signal?: AbortSignal): Promise<NewmarkToolResult>;
705
+ /**
706
+ * 工具后台化:把一个工具调用派发到后台运行,立即返回 background_id,不阻塞
707
+ * 对话回合。真实工具在后台执行,完成后持久化到 toolResultArtifacts,
708
+ * read_tool_result 按 background_id 读取后再释放。
709
+ *
710
+ * 缓存命中优化:后台化工具只返回 tiny 的 background_id(不进大结果到上下文),
711
+ * 真实结果按需读取,避免大结果撑爆上下文、破坏前缀缓存。
712
+ */
713
+ handleBackgroundTool(args: string, signal?: AbortSignal): Promise<NewmarkToolResult>;
714
+ /**
715
+ * 读取后台工具结果:done 时返回结果(按需释放),running 时返回状态,error
716
+ * 时返回错误。与 compress_tool_result 共享 toolResultArtifacts。
717
+ */
718
+ handleReadToolResult(args: string): NewmarkToolResult;
719
+ /**
720
+ * Agent 主动管理 Goal 状态:进入 / 编辑 objective / 标记完成 / 退出。
721
+ * 兼容原有 Goal 机制:enter/update 复用 updateGoal(记录 change、mode=goal、
722
+ * 尊重已暂停状态),complete 复用 markGoalComplete(verified + clearGoal),
723
+ * exit 复用 clearGoal(回 build 不声称完成)。不破坏「用户 Stop 暂停」边界:
724
+ * 本工具不提供 pause/resume,避免 Agent 绕过用户的显式暂停。
725
+ */
726
+ handleGoalManage(args: string): NewmarkToolResult;
727
+ /**
728
+ * Agent 自行命名当前对话。首 Build Block 上运行时通过 bootstrap 提示(见
729
+ * agentKernelRunner.buildBuildContextBootstrap)请求 Agent 调用一次;这里复用
730
+ * 已有的 renameConversation 持久化路径。返回简短结果以保缓存友好。
731
+ */
732
+ handleConversationRename(args: string): NewmarkToolResult;
733
+ private conversationTree;
734
+ private currentRuntimeBranchId;
735
+ handleBranchList(args: string): NewmarkToolResult;
736
+ handleBranchSend(args: string): NewmarkToolResult;
737
+ handleBranchRead(args: string): NewmarkToolResult;
738
+ handleBranchCreate(args: string): NewmarkToolResult;
622
739
  handleContextHistoryManage(args: string): NewmarkToolResult;
623
740
  recordContextCompressionStep(): void;
624
741
  compressionContinuationPrompt(): string;
@@ -655,16 +772,28 @@ export declare class Agent {
655
772
  removeWorkspace(name: string): boolean;
656
773
  modelLabel(): string;
657
774
  estimateContextTokens(messages?: Array<Record<string, unknown>>): number;
775
+ private estimateContextTokenComponents;
658
776
  contextWindow(modelName?: string): {
659
777
  estimatedTokens: number;
660
778
  maxTokens: number;
661
779
  ratio: number;
662
780
  warning: 'ok' | 'near_limit' | 'over_limit';
663
781
  model: string;
782
+ buildBlockTokens?: number;
783
+ longHistoryTokens?: number;
784
+ buildBlockTriggerTokens?: number;
785
+ longHistoryTriggerTokens?: number;
786
+ buildBlockRetentionTokens?: number;
787
+ longHistoryRetentionTokens?: number;
788
+ thresholdReached?: boolean;
789
+ compressionEnabled?: boolean;
790
+ cacheEntries?: number;
791
+ archiveEntries?: number;
664
792
  };
665
793
  private resolveWindowModel;
666
794
  private contextMaxTokens;
667
795
  private compressionBudget;
796
+ private compressionBuildBlockStart;
668
797
  private recentContextSuffix;
669
798
  private compressionSegments;
670
799
  compressForModelSwitch(signal?: AbortSignal): Promise<{
@@ -772,6 +901,7 @@ export declare class Agent {
772
901
  instruction?: string;
773
902
  completion?: boolean;
774
903
  preferCopilot?: boolean;
904
+ onTextDelta?: (text: string) => void;
775
905
  }, signal?: AbortSignal): Promise<{
776
906
  ok: boolean;
777
907
  text: string;
@@ -844,16 +974,22 @@ export declare class Agent {
844
974
  private buildCompressionSummary;
845
975
  private localCompressionSummary;
846
976
  private latestUserHistoryText;
977
+ /** 裁剪超长工具结果:保留头部结论性内容 + 尾部证据(路径/错误/收尾),
978
+ * 中间用占位标记省略。与 DSH toolResultPruner 的语义一致。 */
979
+ private pruneToolResultContent;
847
980
  private compressionHistoryContent;
848
981
  private compactSummaryBody;
849
982
  private formatCompressionSummary;
850
983
  private persistCompressedHistory;
851
984
  private compressionArchiveScopeKey;
852
985
  private coldCompressionEntries;
986
+ private compressionArchiveEntryCount;
853
987
  private archiveColdCompressionEntries;
854
988
  private markColdCompressionRestored;
855
989
  private pushCompressionCacheEntry;
856
990
  private contextHistoryProtectedStartIndex;
991
+ private historyRecordFingerprint;
992
+ private flushPendingHistoryRemovals;
857
993
  private contextHistoryProtectedZone;
858
994
  private snippetAround;
859
995
  buildSystemPrompt(): string;
@@ -861,11 +997,9 @@ export declare class Agent {
861
997
  * dev-0.3.0: assemble the model-request system prompt through the Context
862
998
  * Orchestrator, the single assembly point for every model request. No inline
863
999
  * prompt concatenation remains in agent.ts: buildSystemPrompt() itself
864
- * routes its section content through the orchestrator (byte-identical to the
865
- * legacy parts.join), and this method appends the tool surface notice.
866
- * Later iterations split content into the fixed 18 sections with exact
867
- * semantics; for now the legacy sections occupy the first string slots in
868
- * their original order and empty sections are skipped.
1000
+ * routes its stable base prompt through the orchestrator, and this method
1001
+ * appends the tool surface notice. The linked-plan section is deliberately
1002
+ * empty here; linked-plan content is tool-retrieved on demand.
869
1003
  */
870
1004
  assembleContextV2(toolSurfaceNotice: string): AssembledContext;
871
1005
  cachedToolDefinitions(): unknown[];