@kirosnn/mosaic 0.0.91 → 0.73.0

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 (99) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +2 -6
  3. package/package.json +55 -48
  4. package/src/agent/Agent.ts +353 -131
  5. package/src/agent/context.ts +4 -4
  6. package/src/agent/prompts/systemPrompt.ts +209 -70
  7. package/src/agent/prompts/toolsPrompt.ts +285 -138
  8. package/src/agent/provider/anthropic.ts +109 -105
  9. package/src/agent/provider/google.ts +111 -107
  10. package/src/agent/provider/mistral.ts +95 -95
  11. package/src/agent/provider/ollama.ts +73 -17
  12. package/src/agent/provider/openai.ts +146 -102
  13. package/src/agent/provider/rateLimit.ts +178 -0
  14. package/src/agent/provider/reasoning.ts +29 -0
  15. package/src/agent/provider/xai.ts +108 -104
  16. package/src/agent/tools/definitions.ts +15 -1
  17. package/src/agent/tools/executor.ts +717 -98
  18. package/src/agent/tools/exploreExecutor.ts +20 -22
  19. package/src/agent/tools/fetch.ts +58 -0
  20. package/src/agent/tools/glob.ts +20 -4
  21. package/src/agent/tools/grep.ts +64 -9
  22. package/src/agent/tools/plan.ts +27 -0
  23. package/src/agent/tools/question.ts +7 -1
  24. package/src/agent/tools/read.ts +2 -0
  25. package/src/agent/types.ts +15 -14
  26. package/src/components/App.tsx +50 -8
  27. package/src/components/CustomInput.tsx +461 -77
  28. package/src/components/Main.tsx +1459 -1112
  29. package/src/components/Setup.tsx +1 -1
  30. package/src/components/ShortcutsModal.tsx +11 -8
  31. package/src/components/Welcome.tsx +1 -1
  32. package/src/components/main/ApprovalPanel.tsx +4 -3
  33. package/src/components/main/ChatPage.tsx +858 -516
  34. package/src/components/main/HomePage.tsx +58 -39
  35. package/src/components/main/QuestionPanel.tsx +52 -7
  36. package/src/components/main/ThinkingIndicator.tsx +13 -2
  37. package/src/components/main/types.ts +11 -10
  38. package/src/index.tsx +53 -25
  39. package/src/mcp/approvalPolicy.ts +148 -0
  40. package/src/mcp/cli/add.ts +185 -0
  41. package/src/mcp/cli/doctor.ts +77 -0
  42. package/src/mcp/cli/index.ts +85 -0
  43. package/src/mcp/cli/list.ts +50 -0
  44. package/src/mcp/cli/logs.ts +24 -0
  45. package/src/mcp/cli/manage.ts +99 -0
  46. package/src/mcp/cli/show.ts +53 -0
  47. package/src/mcp/cli/tools.ts +77 -0
  48. package/src/mcp/config.ts +223 -0
  49. package/src/mcp/index.ts +80 -0
  50. package/src/mcp/processManager.ts +299 -0
  51. package/src/mcp/rateLimiter.ts +50 -0
  52. package/src/mcp/registry.ts +151 -0
  53. package/src/mcp/schemaConverter.ts +100 -0
  54. package/src/mcp/servers/navigation.ts +854 -0
  55. package/src/mcp/toolCatalog.ts +169 -0
  56. package/src/mcp/types.ts +95 -0
  57. package/src/utils/approvalBridge.ts +45 -12
  58. package/src/utils/approvalModeBridge.ts +17 -0
  59. package/src/utils/commands/approvals.ts +48 -0
  60. package/src/utils/commands/compact.ts +30 -0
  61. package/src/utils/commands/echo.ts +1 -1
  62. package/src/utils/commands/image.ts +109 -0
  63. package/src/utils/commands/index.ts +9 -7
  64. package/src/utils/commands/new.ts +15 -0
  65. package/src/utils/commands/types.ts +3 -0
  66. package/src/utils/config.ts +3 -1
  67. package/src/utils/diffRendering.tsx +13 -16
  68. package/src/utils/exploreBridge.ts +10 -0
  69. package/src/utils/history.ts +82 -40
  70. package/src/utils/imageBridge.ts +28 -0
  71. package/src/utils/images.ts +31 -0
  72. package/src/utils/markdown.tsx +163 -99
  73. package/src/utils/models.ts +31 -16
  74. package/src/utils/notificationBridge.ts +23 -0
  75. package/src/utils/questionBridge.ts +36 -1
  76. package/src/utils/tokenEstimator.ts +32 -0
  77. package/src/utils/toolFormatting.ts +428 -48
  78. package/src/web/app.tsx +65 -5
  79. package/src/web/assets/css/ChatPage.css +102 -30
  80. package/src/web/assets/css/MessageItem.css +26 -29
  81. package/src/web/assets/css/ThinkingIndicator.css +44 -6
  82. package/src/web/assets/css/ToolMessage.css +36 -14
  83. package/src/web/components/ChatPage.tsx +228 -105
  84. package/src/web/components/HomePage.tsx +3 -3
  85. package/src/web/components/MessageItem.tsx +80 -81
  86. package/src/web/components/QuestionPanel.tsx +72 -12
  87. package/src/web/components/Setup.tsx +1 -1
  88. package/src/web/components/Sidebar.tsx +1 -3
  89. package/src/web/components/ThinkingIndicator.tsx +41 -21
  90. package/src/web/router.ts +1 -1
  91. package/src/web/server.tsx +894 -662
  92. package/src/web/storage.ts +23 -1
  93. package/src/web/types.ts +7 -6
  94. package/src/utils/commands/redo.ts +0 -74
  95. package/src/utils/commands/sessions.ts +0 -129
  96. package/src/utils/commands/undo.ts +0 -75
  97. package/src/utils/undoRedo.ts +0 -429
  98. package/src/utils/undoRedoBridge.ts +0 -45
  99. package/src/utils/undoRedoDb.ts +0 -338
@@ -1,12 +1,15 @@
1
1
  export interface QuestionOption {
2
2
  label: string;
3
3
  value?: string | null;
4
+ group?: string;
4
5
  }
5
6
 
6
7
  export interface QuestionRequest {
7
8
  id: string;
8
9
  prompt: string;
9
10
  options: QuestionOption[];
11
+ timeout?: number;
12
+ validation?: { pattern: string; message?: string };
10
13
  }
11
14
 
12
15
  export interface QuestionAnswer {
@@ -23,6 +26,7 @@ let currentRequest: QuestionRequest | null = null;
23
26
  let listeners = new Set<QuestionListener>();
24
27
  let pendingResolve: ((answer: QuestionAnswer) => void) | null = null;
25
28
  let pendingReject: ((reason?: any) => void) | null = null;
29
+ let pendingTimeoutId: ReturnType<typeof setTimeout> | null = null;
26
30
 
27
31
  function notify(): void {
28
32
  for (const listener of listeners) {
@@ -46,7 +50,12 @@ export function getCurrentQuestion(): QuestionRequest | null {
46
50
  return currentRequest;
47
51
  }
48
52
 
49
- export async function askQuestion(prompt: string, options: QuestionOption[]): Promise<QuestionAnswer> {
53
+ export async function askQuestion(
54
+ prompt: string,
55
+ options: QuestionOption[],
56
+ timeout?: number,
57
+ validation?: { pattern: string; message?: string },
58
+ ): Promise<QuestionAnswer> {
50
59
  if (pendingResolve) {
51
60
  throw new Error('A question is already pending');
52
61
  }
@@ -63,6 +72,8 @@ export async function askQuestion(prompt: string, options: QuestionOption[]): Pr
63
72
  id: createId(),
64
73
  prompt,
65
74
  options,
75
+ ...(timeout !== undefined && { timeout }),
76
+ ...(validation !== undefined && { validation }),
66
77
  };
67
78
 
68
79
  currentRequest = request;
@@ -71,6 +82,20 @@ export async function askQuestion(prompt: string, options: QuestionOption[]): Pr
71
82
  const answer = await new Promise<QuestionAnswer>((resolve, reject) => {
72
83
  pendingResolve = resolve;
73
84
  pendingReject = reject;
85
+
86
+ if (timeout !== undefined && timeout > 0) {
87
+ pendingTimeoutId = setTimeout(() => {
88
+ pendingTimeoutId = null;
89
+ if (pendingReject) {
90
+ const rej = pendingReject;
91
+ pendingResolve = null;
92
+ pendingReject = null;
93
+ currentRequest = null;
94
+ notify();
95
+ rej(new Error(`Question timed out after ${timeout}s`));
96
+ }
97
+ }, timeout * 1000);
98
+ }
74
99
  });
75
100
 
76
101
  return answer;
@@ -101,6 +126,11 @@ export function answerQuestion(index: number, customText?: string): void {
101
126
 
102
127
  if (!answer) return;
103
128
 
129
+ if (pendingTimeoutId !== null) {
130
+ clearTimeout(pendingTimeoutId);
131
+ pendingTimeoutId = null;
132
+ }
133
+
104
134
  const resolve = pendingResolve;
105
135
  pendingResolve = null;
106
136
  pendingReject = null;
@@ -112,6 +142,11 @@ export function answerQuestion(index: number, customText?: string): void {
112
142
  export function cancelQuestion(): void {
113
143
  if (!currentRequest || !pendingReject) return;
114
144
 
145
+ if (pendingTimeoutId !== null) {
146
+ clearTimeout(pendingTimeoutId);
147
+ pendingTimeoutId = null;
148
+ }
149
+
115
150
  const reject = pendingReject;
116
151
  pendingResolve = null;
117
152
  pendingReject = null;
@@ -0,0 +1,32 @@
1
+ const CODE_CHARS = /[{}()\[\]=<>:;]/g;
2
+ const CODE_DENSITY_THRESHOLD = 0.04;
3
+
4
+ export function estimateTokensFromText(text: string): number {
5
+ if (!text) return 0;
6
+ const matches = text.match(CODE_CHARS);
7
+ const density = matches ? matches.length / text.length : 0;
8
+ const ratio = density >= CODE_DENSITY_THRESHOLD ? 2.8 : 3.3;
9
+ return Math.ceil(text.length / ratio);
10
+ }
11
+
12
+ export function estimateTokensForContent(content: string, thinkingContent?: string): number {
13
+ const contentTokens = estimateTokensFromText(content);
14
+ const thinkingTokens = thinkingContent ? estimateTokensFromText(thinkingContent) : 0;
15
+ return contentTokens + thinkingTokens + 4;
16
+ }
17
+
18
+ const CONTEXT_BUDGETS: Record<string, number> = {
19
+ anthropic: 180000,
20
+ openai: 115000,
21
+ google: 900000,
22
+ mistral: 28000,
23
+ xai: 117000,
24
+ ollama: 7000,
25
+ };
26
+
27
+ const DEFAULT_BUDGET = 12000;
28
+
29
+ export function getDefaultContextBudget(provider?: string): number {
30
+ if (!provider) return DEFAULT_BUDGET;
31
+ return CONTEXT_BUDGETS[provider] ?? DEFAULT_BUDGET;
32
+ }