@superblocksteam/vite-plugin-file-sync 2.0.72-next.8 → 2.0.73-next.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.
- package/dist/ai-service/agent/middleware.d.ts.map +1 -1
- package/dist/ai-service/agent/middleware.js +4 -1
- package/dist/ai-service/agent/middleware.js.map +1 -1
- package/dist/ai-service/agent/subagents/testing/prompt-builder.d.ts.map +1 -1
- package/dist/ai-service/agent/subagents/testing/prompt-builder.js +99 -4
- package/dist/ai-service/agent/subagents/testing/prompt-builder.js.map +1 -1
- package/dist/ai-service/agent/subagents/testing/types.d.ts +20 -0
- package/dist/ai-service/agent/subagents/testing/types.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/apis/api-source.d.ts +1 -1
- package/dist/ai-service/agent/tools/apis/api-source.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/apis/api-source.js +37 -9
- package/dist/ai-service/agent/tools/apis/api-source.js.map +1 -1
- package/dist/ai-service/agent/tools/build-reload-file.d.ts +5 -2
- package/dist/ai-service/agent/tools/build-reload-file.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-reload-file.js +4 -3
- package/dist/ai-service/agent/tools/build-reload-file.js.map +1 -1
- package/dist/ai-service/agent/tools/index.d.ts +1 -0
- package/dist/ai-service/agent/tools/index.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/index.js +1 -0
- package/dist/ai-service/agent/tools/index.js.map +1 -1
- package/dist/ai-service/agent/tools/integrations/execute-request.d.ts +1 -1
- package/dist/ai-service/agent/tools/integrations/internal.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/integrations/internal.js +8 -1
- package/dist/ai-service/agent/tools/integrations/internal.js.map +1 -1
- package/dist/ai-service/agent/tools.d.ts.map +1 -1
- package/dist/ai-service/agent/tools.js +37 -4
- package/dist/ai-service/agent/tools.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/ask-multi-choice.d.ts +0 -1
- package/dist/ai-service/agent/tools2/tools/ask-multi-choice.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/ask-multi-choice.js +1 -6
- package/dist/ai-service/agent/tools2/tools/ask-multi-choice.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/end-test-run.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/end-test-run.js +2 -0
- package/dist/ai-service/agent/tools2/tools/end-test-run.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.d.ts +2 -2
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js +58 -195
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/list-attachments.d.ts +15 -0
- package/dist/ai-service/agent/tools2/tools/list-attachments.d.ts.map +1 -0
- package/dist/ai-service/agent/tools2/tools/list-attachments.js +47 -0
- package/dist/ai-service/agent/tools2/tools/list-attachments.js.map +1 -0
- package/dist/ai-service/agent/tools2/tools/start-test-run.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/start-test-run.js +92 -10
- package/dist/ai-service/agent/tools2/tools/start-test-run.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/update-test-case-status.d.ts +2 -2
- package/dist/ai-service/agent/tools2/tools/update-test-case-status.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/update-test-case-status.js +21 -2
- package/dist/ai-service/agent/tools2/tools/update-test-case-status.js.map +1 -1
- package/dist/ai-service/agent/utils.d.ts.map +1 -1
- package/dist/ai-service/agent/utils.js +46 -2
- package/dist/ai-service/agent/utils.js.map +1 -1
- package/dist/ai-service/attachments/index.d.ts +2 -0
- package/dist/ai-service/attachments/index.d.ts.map +1 -0
- package/dist/ai-service/attachments/index.js +2 -0
- package/dist/ai-service/attachments/index.js.map +1 -0
- package/dist/ai-service/attachments/store.d.ts +65 -0
- package/dist/ai-service/attachments/store.d.ts.map +1 -0
- package/dist/ai-service/attachments/store.js +158 -0
- package/dist/ai-service/attachments/store.js.map +1 -0
- package/dist/ai-service/chat/chat-session-store.d.ts.map +1 -1
- package/dist/ai-service/chat/chat-session-store.js +11 -0
- package/dist/ai-service/chat/chat-session-store.js.map +1 -1
- package/dist/ai-service/context-download.d.ts +24 -0
- package/dist/ai-service/context-download.d.ts.map +1 -0
- package/dist/ai-service/context-download.js +127 -0
- package/dist/ai-service/context-download.js.map +1 -0
- package/dist/ai-service/context-upload.d.ts +17 -0
- package/dist/ai-service/context-upload.d.ts.map +1 -0
- package/dist/ai-service/context-upload.js +100 -0
- package/dist/ai-service/context-upload.js.map +1 -0
- package/dist/ai-service/index.d.ts +27 -3
- package/dist/ai-service/index.d.ts.map +1 -1
- package/dist/ai-service/index.js +252 -12
- package/dist/ai-service/index.js.map +1 -1
- package/dist/ai-service/llm/context/context.d.ts +4 -0
- package/dist/ai-service/llm/context/context.d.ts.map +1 -1
- package/dist/ai-service/llm/context/context.js +10 -0
- package/dist/ai-service/llm/context/context.js.map +1 -1
- package/dist/ai-service/llm/context/manager.d.ts +5 -0
- package/dist/ai-service/llm/context/manager.d.ts.map +1 -1
- package/dist/ai-service/llm/context/manager.js +8 -0
- package/dist/ai-service/llm/context/manager.js.map +1 -1
- package/dist/ai-service/llm/context/serialization.d.ts +3 -0
- package/dist/ai-service/llm/context/serialization.d.ts.map +1 -1
- package/dist/ai-service/llm/interaction/adapters/vercel.d.ts.map +1 -1
- package/dist/ai-service/llm/interaction/adapters/vercel.js +5 -4
- package/dist/ai-service/llm/interaction/adapters/vercel.js.map +1 -1
- package/dist/ai-service/llm/stream/config.d.ts +2 -0
- package/dist/ai-service/llm/stream/config.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/config.js +1 -0
- package/dist/ai-service/llm/stream/config.js.map +1 -1
- package/dist/ai-service/llm/stream/orchestrator.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/orchestrator.js +1 -1
- package/dist/ai-service/llm/stream/orchestrator.js.map +1 -1
- package/dist/ai-service/llm/stream/retry-engine.d.ts +1 -0
- package/dist/ai-service/llm/stream/retry-engine.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/retry-engine.js +20 -1
- package/dist/ai-service/llm/stream/retry-engine.js.map +1 -1
- package/dist/ai-service/llm/stream/session.d.ts +2 -0
- package/dist/ai-service/llm/stream/session.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/session.js +6 -2
- package/dist/ai-service/llm/stream/session.js.map +1 -1
- package/dist/ai-service/llmobs/otel-exporter.d.ts +58 -0
- package/dist/ai-service/llmobs/otel-exporter.d.ts.map +1 -0
- package/dist/ai-service/llmobs/otel-exporter.js +182 -0
- package/dist/ai-service/llmobs/otel-exporter.js.map +1 -0
- package/dist/ai-service/llmobs/tracer.d.ts +9 -0
- package/dist/ai-service/llmobs/tracer.d.ts.map +1 -1
- package/dist/ai-service/llmobs/tracer.js +46 -2
- package/dist/ai-service/llmobs/tracer.js.map +1 -1
- package/dist/ai-service/mcp/embedded-playwright-mcp-server.d.ts +17 -0
- package/dist/ai-service/mcp/embedded-playwright-mcp-server.d.ts.map +1 -1
- package/dist/ai-service/mcp/embedded-playwright-mcp-server.js +329 -7
- package/dist/ai-service/mcp/embedded-playwright-mcp-server.js.map +1 -1
- package/dist/ai-service/mcp/playwright-server.d.ts +29 -0
- package/dist/ai-service/mcp/playwright-server.d.ts.map +1 -1
- package/dist/ai-service/mcp/playwright-server.js +53 -0
- package/dist/ai-service/mcp/playwright-server.js.map +1 -1
- package/dist/ai-service/state-machine/clark-fsm.d.ts +3 -1
- package/dist/ai-service/state-machine/clark-fsm.d.ts.map +1 -1
- package/dist/ai-service/state-machine/clark-fsm.js +1 -0
- package/dist/ai-service/state-machine/clark-fsm.js.map +1 -1
- package/dist/ai-service/state-machine/fsm.d.ts.map +1 -1
- package/dist/ai-service/state-machine/fsm.js +1 -0
- package/dist/ai-service/state-machine/fsm.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/agent-planning.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/agent-planning.js +42 -1
- package/dist/ai-service/state-machine/handlers/agent-planning.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/awaiting-user.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/awaiting-user.js +9 -0
- package/dist/ai-service/state-machine/handlers/awaiting-user.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/llm-generating.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/llm-generating.js +43 -16
- package/dist/ai-service/state-machine/handlers/llm-generating.js.map +1 -1
- package/dist/ai-service/state-machine/helpers/peer.d.ts +1 -1
- package/dist/ai-service/state-machine/helpers/peer.d.ts.map +1 -1
- package/dist/ai-service/state-machine/helpers/peer.js +21 -4
- package/dist/ai-service/state-machine/helpers/peer.js.map +1 -1
- package/dist/ai-service/util/scoped-token-utils.d.ts +15 -0
- package/dist/ai-service/util/scoped-token-utils.d.ts.map +1 -0
- package/dist/ai-service/util/scoped-token-utils.js +131 -0
- package/dist/ai-service/util/scoped-token-utils.js.map +1 -0
- package/dist/file-sync-vite-plugin.js +3 -3
- package/dist/file-sync-vite-plugin.js.map +1 -1
- package/dist/server-rpc/index.js +1 -1
- package/dist/server-rpc/index.js.map +1 -1
- package/dist/socket-manager.d.ts.map +1 -1
- package/dist/socket-manager.js +61 -4
- package/dist/socket-manager.js.map +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-upload.js","sourceRoot":"","sources":["../../src/ai-service/context-upload.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,8 @@ import type { FileSystemManager } from "../file-system-manager.js";
|
|
|
5
5
|
import type { SourceTracker } from "../source-tracker.js";
|
|
6
6
|
import type { JudgeEvaluationOptions, JudgeEvaluationResult } from "./judge/judge-service.js";
|
|
7
7
|
import type { AiServiceConfig, AiServiceEvents, EditorClient, UserChange, ApiUpdate } from "./types.ts";
|
|
8
|
-
import type {
|
|
8
|
+
import type { ContextId } from "./llm/context/types.js";
|
|
9
|
+
import type { AiGenerateRequest, AiExplainCodeRequest, AiLabelAttachmentRequest, AiLabelAttachmentResponse, LLMProviderConfig, PromptContext, RuntimeErrorData, ConsoleLogEntry } from "@superblocksteam/library-shared/types";
|
|
9
10
|
import type { ViteDevServer } from "vite";
|
|
10
11
|
export { AiServiceFeatureFlags } from "./features.js";
|
|
11
12
|
export declare class AiService extends TracedEventEmitter<AiServiceEvents> {
|
|
@@ -18,7 +19,7 @@ export declare class AiService extends TracedEventEmitter<AiServiceEvents> {
|
|
|
18
19
|
private _appContext;
|
|
19
20
|
private llmProviderSettings;
|
|
20
21
|
private _logger;
|
|
21
|
-
private clark;
|
|
22
|
+
private readonly clark;
|
|
22
23
|
private clarkProfiler;
|
|
23
24
|
readonly chatSessionStore: ChatSessionStore;
|
|
24
25
|
private readonly contextManager;
|
|
@@ -31,6 +32,22 @@ export declare class AiService extends TracedEventEmitter<AiServiceEvents> {
|
|
|
31
32
|
private readonly mcpServerManager;
|
|
32
33
|
get appContext(): AppContextStore;
|
|
33
34
|
get clarkState(): string;
|
|
35
|
+
get appRootDirPath(): string;
|
|
36
|
+
get organizationId(): string;
|
|
37
|
+
get superblocksBaseUrl(): string;
|
|
38
|
+
/**
|
|
39
|
+
* Gets the contextId for the current conversation context.
|
|
40
|
+
* Returns null if JWT is missing or has no userId.
|
|
41
|
+
*/
|
|
42
|
+
getContextId(): ContextId | null;
|
|
43
|
+
/**
|
|
44
|
+
* Gets the JWT from Clark context
|
|
45
|
+
*/
|
|
46
|
+
getClarkJwt(): string | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Updates the JWT in Clark context
|
|
49
|
+
*/
|
|
50
|
+
updateClarkJwt(jwt: string): void;
|
|
34
51
|
constructor(config: AiServiceConfig);
|
|
35
52
|
/**
|
|
36
53
|
* Initialize the AI service. Must be called after construction.
|
|
@@ -48,10 +65,16 @@ export declare class AiService extends TracedEventEmitter<AiServiceEvents> {
|
|
|
48
65
|
private createClarkTagProviderFactory;
|
|
49
66
|
handleAiGenerate(request: AiGenerateRequest, peer: EditorClient, peerId: string): Promise<void>;
|
|
50
67
|
handleAiExplainCode(request: AiExplainCodeRequest, peer: EditorClient): Promise<void>;
|
|
68
|
+
handleAiLabelAttachment(request: AiLabelAttachmentRequest): Promise<AiLabelAttachmentResponse>;
|
|
69
|
+
/**
|
|
70
|
+
* Converts an attachment to the appropriate LLM content part.
|
|
71
|
+
*/
|
|
72
|
+
private attachmentToContentPart;
|
|
51
73
|
private submitAcceptanceEvaluation;
|
|
52
74
|
handleUserAcceptedDraft(peer: EditorClient, silently?: boolean): Promise<void>;
|
|
53
75
|
handleUserRejectedDraft(peer: EditorClient, silently?: boolean): Promise<void>;
|
|
54
76
|
handleUserCanceled(): Promise<void>;
|
|
77
|
+
handleSkipTestCase(testRunId: string, testCaseId: string): Promise<void>;
|
|
55
78
|
handleUserConnected(peer: EditorClient, peerId: string): void;
|
|
56
79
|
handleUserDisconnected(peerId: string): void;
|
|
57
80
|
private clearPeerConnection;
|
|
@@ -87,9 +110,10 @@ export declare class AiService extends TracedEventEmitter<AiServiceEvents> {
|
|
|
87
110
|
}): Promise<JudgeEvaluationResult>;
|
|
88
111
|
handleUserChange(change: UserChange): void;
|
|
89
112
|
handleNewChat(): Promise<void>;
|
|
90
|
-
|
|
113
|
+
handleRestoreToCommit(sinceTimestamp: number, commitId: string, applicationId: string, branchName: string): Promise<void>;
|
|
91
114
|
handleApiUpdate(update: ApiUpdate): Promise<void>;
|
|
92
115
|
isBusy(): boolean;
|
|
116
|
+
isAwaitingUser(): boolean;
|
|
93
117
|
/**
|
|
94
118
|
* Check if Clark is currently generating code.
|
|
95
119
|
* Used by lock-service to determine if lock should be held during generation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai-service/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai-service/index.ts"],"names":[],"mappings":"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"}
|
package/dist/ai-service/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import os from "node:os";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { isTextAttachment } from "@superblocksteam/library-shared/types";
|
|
3
4
|
import { addTracingToMethods, TracedEventEmitter, } from "@superblocksteam/shared";
|
|
4
|
-
import { hasToolCall } from "ai";
|
|
5
|
+
import { generateObject, hasToolCall } from "ai";
|
|
6
|
+
import { z } from "zod";
|
|
5
7
|
import { getErrorMeta, getLogger, setDefaultLogger } from "../util/logger.js";
|
|
6
8
|
import { OperationPassthrough } from "../util/operation-queue.js";
|
|
7
9
|
import { readFile } from "./agent/tools/build-read-file.js";
|
|
@@ -15,6 +17,7 @@ import { AppShell } from "./app-interface/shell.js";
|
|
|
15
17
|
import { BoltArtifactProcessor } from "./artifacts/bolt.js";
|
|
16
18
|
import { ChatSessionStore } from "./chat/chat-session-store.js";
|
|
17
19
|
import { AppContextStore } from "./context/app-context.js";
|
|
20
|
+
import { restoreContextFromCheckpoint } from "./context-download.js";
|
|
18
21
|
import { IntegrationStore } from "./integrations/store.js";
|
|
19
22
|
import { JudgeService } from "./judge/judge-service.js";
|
|
20
23
|
import { CsvJudgeStorage } from "./judge/storage/csv-storage.js";
|
|
@@ -100,6 +103,7 @@ const mergePlanContexts = (existing, incoming) => {
|
|
|
100
103
|
plan: incoming?.plan ?? existing?.plan,
|
|
101
104
|
approved: incoming?.approved !== undefined ? incoming.approved : existing?.approved,
|
|
102
105
|
integrations: incoming?.integrations ?? existing?.integrations,
|
|
106
|
+
entities: incoming?.entities ?? existing?.entities,
|
|
103
107
|
title: incoming?.title ?? existing?.title,
|
|
104
108
|
attachments: incoming?.attachments ?? existing?.attachments,
|
|
105
109
|
enableTesting: incoming?.enableTesting ?? existing?.enableTesting,
|
|
@@ -132,11 +136,48 @@ export class AiService extends TracedEventEmitter {
|
|
|
132
136
|
get clarkState() {
|
|
133
137
|
return this.clark.state;
|
|
134
138
|
}
|
|
139
|
+
get appRootDirPath() {
|
|
140
|
+
return this.config.appRootDirPath;
|
|
141
|
+
}
|
|
142
|
+
get organizationId() {
|
|
143
|
+
return this.config.organizationId;
|
|
144
|
+
}
|
|
145
|
+
get superblocksBaseUrl() {
|
|
146
|
+
return this.config.superblocksBaseUrl;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Gets the contextId for the current conversation context.
|
|
150
|
+
* Returns null if JWT is missing or has no userId.
|
|
151
|
+
*/
|
|
152
|
+
getContextId() {
|
|
153
|
+
try {
|
|
154
|
+
return getContextId(this.clark, this.config);
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Gets the JWT from Clark context
|
|
162
|
+
*/
|
|
163
|
+
getClarkJwt() {
|
|
164
|
+
return this.clark?.context?.jwt;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Updates the JWT in Clark context
|
|
168
|
+
*/
|
|
169
|
+
updateClarkJwt(jwt) {
|
|
170
|
+
if (jwt) {
|
|
171
|
+
this.clark.updateContext({ jwt });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
135
174
|
constructor(config) {
|
|
136
175
|
super(config.tracer);
|
|
137
176
|
this.config = config;
|
|
138
|
-
this._logger = config.logger;
|
|
139
177
|
setDefaultLogger(config.logger);
|
|
178
|
+
// Store the wrapped logger so getLogger() can return it
|
|
179
|
+
// The wrapped logger forwards logs to the browser console when Clark logs are enabled
|
|
180
|
+
this._logger = getLogger();
|
|
140
181
|
// Prevent traced functions from creating traces when called outside of a Clark context
|
|
141
182
|
llmobs.setDefaultRootPolicy("drop-if-no-parent");
|
|
142
183
|
// todo: move to state handlers
|
|
@@ -234,6 +275,7 @@ export class AiService extends TracedEventEmitter {
|
|
|
234
275
|
"handleUserAcceptedDraft",
|
|
235
276
|
"handleUserRejectedDraft",
|
|
236
277
|
"handleUserCanceled",
|
|
278
|
+
"handleSkipTestCase",
|
|
237
279
|
"handleBuildSystemError",
|
|
238
280
|
"handleRuntimeError",
|
|
239
281
|
"handleClearRuntimeError",
|
|
@@ -261,6 +303,8 @@ export class AiService extends TracedEventEmitter {
|
|
|
261
303
|
this.getLogger().info("[ai-service] Integration cache removed");
|
|
262
304
|
}
|
|
263
305
|
getLogger() {
|
|
306
|
+
// Return the wrapped logger that forwards logs to the browser console
|
|
307
|
+
// when Clark logs are enabled (via ?clark_logs=true or SUPERBLOCKS_CLI_ENV=local)
|
|
264
308
|
return this._logger;
|
|
265
309
|
}
|
|
266
310
|
createClarkTransitionHandler() {
|
|
@@ -355,6 +399,7 @@ export class AiService extends TracedEventEmitter {
|
|
|
355
399
|
};
|
|
356
400
|
}
|
|
357
401
|
async handleAiGenerate(request, peer, peerId) {
|
|
402
|
+
this.getLogger().info(`[ai-service] handleAiGenerate: peerId=${peerId}`);
|
|
358
403
|
if (this.clark.state === ClarkStateNames.Dead) {
|
|
359
404
|
throw new Error("Service is unavailable");
|
|
360
405
|
}
|
|
@@ -364,6 +409,13 @@ export class AiService extends TracedEventEmitter {
|
|
|
364
409
|
}
|
|
365
410
|
this.clarkProfiler.startSession();
|
|
366
411
|
getLogger().info("AI Service received request with llmConfig:", request.llmConfig || {});
|
|
412
|
+
getLogger().info("[ai-service] handleAiGenerate received request", {
|
|
413
|
+
requestMode: request.mode,
|
|
414
|
+
currentContextMode: this.clark.context.currentMode,
|
|
415
|
+
requestPlanContextApproved: request.planContext?.approved,
|
|
416
|
+
existingPlanContextApproved: this.clark.context.planContext?.approved,
|
|
417
|
+
responseMetadataType: request.responseMetadata?.type,
|
|
418
|
+
});
|
|
367
419
|
this.clark.updateContext((context) => {
|
|
368
420
|
return {
|
|
369
421
|
...context,
|
|
@@ -520,6 +572,110 @@ export class AiService extends TracedEventEmitter {
|
|
|
520
572
|
});
|
|
521
573
|
}
|
|
522
574
|
}
|
|
575
|
+
async handleAiLabelAttachment(request) {
|
|
576
|
+
const logger = getLogger();
|
|
577
|
+
const startTime = Date.now();
|
|
578
|
+
const timeout = 30_000;
|
|
579
|
+
const attachment = request.attachment;
|
|
580
|
+
logger.debug("[ai-service] Labeling attachment", {
|
|
581
|
+
fileName: attachment.fileName ?? "unnamed",
|
|
582
|
+
type: attachment.type,
|
|
583
|
+
});
|
|
584
|
+
const llmConfig = request.llmConfig
|
|
585
|
+
? {
|
|
586
|
+
...request.llmConfig,
|
|
587
|
+
interleavedThinking: false,
|
|
588
|
+
thinkingEnabled: false,
|
|
589
|
+
}
|
|
590
|
+
: undefined;
|
|
591
|
+
const llmProviderSettings = this.getLLMProviderSettings(false, llmConfig);
|
|
592
|
+
const llmProvider = createLLMProvider(llmProviderSettings, () => request.jwt, llmConfig);
|
|
593
|
+
const model = llmProvider.modelForTask("fast");
|
|
594
|
+
const LabelAttachmentSchema = z.object({
|
|
595
|
+
label: z
|
|
596
|
+
.string()
|
|
597
|
+
.min(1)
|
|
598
|
+
.describe('A brief 2-3 word description (e.g., "sales dashboard", "user profile", "data table", "customer data")'),
|
|
599
|
+
insight: z
|
|
600
|
+
.string()
|
|
601
|
+
.min(1)
|
|
602
|
+
.describe('A key observation about the content (e.g., "chart displays monthly revenue", "CSV contains customer records", "JSON config for API settings")'),
|
|
603
|
+
});
|
|
604
|
+
const timeoutController = new AbortController();
|
|
605
|
+
const timeoutId = setTimeout(() => timeoutController.abort(), timeout);
|
|
606
|
+
try {
|
|
607
|
+
// Build the appropriate content part based on attachment type
|
|
608
|
+
const contentPart = this.attachmentToContentPart(attachment);
|
|
609
|
+
const { object: result } = await generateObject({
|
|
610
|
+
model,
|
|
611
|
+
schema: LabelAttachmentSchema,
|
|
612
|
+
messages: [
|
|
613
|
+
{
|
|
614
|
+
role: "user",
|
|
615
|
+
content: [
|
|
616
|
+
{
|
|
617
|
+
type: "text",
|
|
618
|
+
text: "Analyze this attachment and provide a brief label and key insight about its content.",
|
|
619
|
+
},
|
|
620
|
+
contentPart,
|
|
621
|
+
],
|
|
622
|
+
},
|
|
623
|
+
],
|
|
624
|
+
abortSignal: timeoutController.signal,
|
|
625
|
+
});
|
|
626
|
+
const durationMs = Date.now() - startTime;
|
|
627
|
+
logger.debug("[ai-service] Attachment labeling complete", {
|
|
628
|
+
fileName: attachment.fileName,
|
|
629
|
+
type: attachment.type,
|
|
630
|
+
label: result.label,
|
|
631
|
+
insight: result.insight,
|
|
632
|
+
durationMs,
|
|
633
|
+
});
|
|
634
|
+
return result;
|
|
635
|
+
}
|
|
636
|
+
finally {
|
|
637
|
+
clearTimeout(timeoutId);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Converts an attachment to the appropriate LLM content part.
|
|
642
|
+
*/
|
|
643
|
+
attachmentToContentPart(attachment) {
|
|
644
|
+
if (attachment.type === "image") {
|
|
645
|
+
return {
|
|
646
|
+
type: "image",
|
|
647
|
+
image: attachment.image,
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
else if (attachment.type === "pdf") {
|
|
651
|
+
// Parse data URL to extract base64 data
|
|
652
|
+
const match = attachment.data.match(/^data:([^;]+);base64,(.+)$/);
|
|
653
|
+
const data = match?.[2] ?? attachment.data;
|
|
654
|
+
const mediaType = match?.[1] ?? "application/pdf";
|
|
655
|
+
return {
|
|
656
|
+
type: "file",
|
|
657
|
+
data,
|
|
658
|
+
mediaType,
|
|
659
|
+
filename: attachment.fileName,
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
else if (isTextAttachment(attachment)) {
|
|
663
|
+
// Wrap text content in XML tags for structured presentation
|
|
664
|
+
const sanitizedFileName = attachment.fileName
|
|
665
|
+
.replace(/&/g, "&")
|
|
666
|
+
.replace(/"/g, """)
|
|
667
|
+
.replace(/'/g, "'")
|
|
668
|
+
.replace(/</g, "<")
|
|
669
|
+
.replace(/>/g, ">");
|
|
670
|
+
return {
|
|
671
|
+
type: "text",
|
|
672
|
+
text: `<${attachment.type}_file name="${sanitizedFileName}">\n${attachment.content}\n</${attachment.type}_file>`,
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
else {
|
|
676
|
+
throw new Error(`Unsupported attachment type: ${attachment.type}`);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
523
679
|
submitAcceptanceEvaluation(wasAccepted) {
|
|
524
680
|
if (!this.clark.rootSpan) {
|
|
525
681
|
this.getLogger().warn("[ai-service] No root span available for submitting feedback");
|
|
@@ -537,12 +693,14 @@ export class AiService extends TracedEventEmitter {
|
|
|
537
693
|
}
|
|
538
694
|
}
|
|
539
695
|
async handleUserAcceptedDraft(peer, silently) {
|
|
696
|
+
this.getLogger().info(`[ai-service] handleUserAcceptedDraft`);
|
|
540
697
|
this.submitAcceptanceEvaluation(true);
|
|
541
698
|
if (this.clark.state !== ClarkStateNames.AwaitingUser) {
|
|
542
699
|
throw new Error("Service is not awaiting user input");
|
|
543
700
|
}
|
|
544
701
|
if (!this.clark.context.peer) {
|
|
545
|
-
//
|
|
702
|
+
// peer can be null if service was started with a draft
|
|
703
|
+
this.getLogger().info(`[ai-service] Setting peer from RPC caller`);
|
|
546
704
|
this.clark.updateContext({
|
|
547
705
|
peer,
|
|
548
706
|
});
|
|
@@ -551,12 +709,14 @@ export class AiService extends TracedEventEmitter {
|
|
|
551
709
|
void transitionTo({ type: USER_ACCEPTED_DRAFT, silently });
|
|
552
710
|
}
|
|
553
711
|
async handleUserRejectedDraft(peer, silently) {
|
|
712
|
+
this.getLogger().info(`[ai-service] handleUserRejectedDraft`);
|
|
554
713
|
this.submitAcceptanceEvaluation(false);
|
|
555
714
|
if (this.clark.state !== ClarkStateNames.AwaitingUser) {
|
|
556
715
|
throw new Error("Service is not awaiting user input");
|
|
557
716
|
}
|
|
558
717
|
if (!this.clark.context.peer) {
|
|
559
|
-
//
|
|
718
|
+
// peer can be null if service was started with a draft
|
|
719
|
+
this.getLogger().info(`[ai-service] Setting peer from RPC caller`);
|
|
560
720
|
this.clark.updateContext({
|
|
561
721
|
peer,
|
|
562
722
|
});
|
|
@@ -574,8 +734,42 @@ export class AiService extends TracedEventEmitter {
|
|
|
574
734
|
this.clark.context.abortController?.abort();
|
|
575
735
|
void this.clark.send({ type: USER_CANCELED });
|
|
576
736
|
}
|
|
737
|
+
async handleSkipTestCase(testRunId, testCaseId) {
|
|
738
|
+
const logger = this.getLogger();
|
|
739
|
+
logger.info(`[ai-service] Skip test case requested: testRunId=${testRunId}, testCaseId=${testCaseId}`);
|
|
740
|
+
// Verify this is the active test run
|
|
741
|
+
if (this.clark.context.currentTestRunId !== testRunId) {
|
|
742
|
+
logger.warn(`[ai-service] Skip request for testRunId=${testRunId} but current is ${this.clark.context.currentTestRunId}`);
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
// Update context with skip request
|
|
746
|
+
this.clark.updateContext({
|
|
747
|
+
skipRequestedForTestCase: testCaseId,
|
|
748
|
+
});
|
|
749
|
+
// Update the test case status to skipped
|
|
750
|
+
const testCaseStatuses = this.clark.context.testCaseStatuses ??
|
|
751
|
+
new Map();
|
|
752
|
+
testCaseStatuses.set(testCaseId, "skipped");
|
|
753
|
+
this.clark.updateContext({
|
|
754
|
+
testCaseStatuses,
|
|
755
|
+
});
|
|
756
|
+
// Send test_case_update message to UI
|
|
757
|
+
const peer = this.clark.context.peer;
|
|
758
|
+
if (peer) {
|
|
759
|
+
void peer.call.aiPushMessage({
|
|
760
|
+
type: "test_case_update",
|
|
761
|
+
testRunId,
|
|
762
|
+
testCaseId,
|
|
763
|
+
testCaseStatus: "skipped",
|
|
764
|
+
role: "assistant",
|
|
765
|
+
content: "",
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
logger.info(`[ai-service] Test case ${testCaseId} marked as skipped, flag set for subagent`);
|
|
769
|
+
}
|
|
577
770
|
handleUserConnected(peer, peerId) {
|
|
578
771
|
const existingPeerId = this.clark.context.peerId;
|
|
772
|
+
this.getLogger().info(`[ai-service] handleUserConnected: peerId=${peerId}`);
|
|
579
773
|
if (this.clark.context.peer) {
|
|
580
774
|
if (existingPeerId === peerId) {
|
|
581
775
|
this.getLogger().info(`[ai-service] Existing peer ${peerId} reconnected; refreshing reference`);
|
|
@@ -592,6 +786,7 @@ export class AiService extends TracedEventEmitter {
|
|
|
592
786
|
peer,
|
|
593
787
|
peerId,
|
|
594
788
|
}));
|
|
789
|
+
this.getLogger().info(`[ai-service] Peer set: ${peerId}`);
|
|
595
790
|
// 1. Sync generation state if generation is in progress
|
|
596
791
|
if (this.clark.context.lastGenerationState) {
|
|
597
792
|
this.getLogger().info(`[ai-service] Syncing generation state on reconnect: ${this.clark.context.lastGenerationState.state}`);
|
|
@@ -627,18 +822,19 @@ export class AiService extends TracedEventEmitter {
|
|
|
627
822
|
}
|
|
628
823
|
handleUserDisconnected(peerId) {
|
|
629
824
|
const currentPeerId = this.clark.context.peerId;
|
|
825
|
+
this.getLogger().info(`[ai-service] handleUserDisconnected: peerId=${peerId}`);
|
|
630
826
|
if (!currentPeerId) {
|
|
631
827
|
return;
|
|
632
828
|
}
|
|
633
829
|
if (currentPeerId !== peerId) {
|
|
634
|
-
this.getLogger().
|
|
635
|
-
|
|
636
|
-
else {
|
|
637
|
-
this.getLogger().info(`[ai-service] peer disconnecting: ${peerId}`);
|
|
830
|
+
this.getLogger().info(`[ai-service] Stale disconnect ignored: peer ${peerId} disconnecting but current peer is ${currentPeerId}`);
|
|
831
|
+
return; // Don't clear the current peer on stale disconnect
|
|
638
832
|
}
|
|
833
|
+
this.getLogger().info(`[ai-service] peer disconnecting: ${peerId}`);
|
|
639
834
|
this.clearPeerConnection();
|
|
640
835
|
}
|
|
641
836
|
clearPeerConnection() {
|
|
837
|
+
this.getLogger().info(`[ai-service] Clearing peer connection`);
|
|
642
838
|
this.clark.updateContext((context) => ({
|
|
643
839
|
...context,
|
|
644
840
|
peer: undefined,
|
|
@@ -877,18 +1073,59 @@ export class AiService extends TracedEventEmitter {
|
|
|
877
1073
|
this.getLogger().error("[ai-service] Failed to clear contexts on new chat", getErrorMeta(error));
|
|
878
1074
|
}
|
|
879
1075
|
}
|
|
880
|
-
async
|
|
881
|
-
//
|
|
1076
|
+
async handleRestoreToCommit(sinceTimestamp, commitId, applicationId, branchName) {
|
|
1077
|
+
// TODO: change this to truncate after commit once commit info is supported here, so we can truncate messages accurately.
|
|
1078
|
+
// 1. Truncate chat messages on server (always do this first)
|
|
882
1079
|
await this.chatSessionStore.truncateAfterTimestamp(sinceTimestamp);
|
|
883
|
-
//
|
|
1080
|
+
// Check JWT once at the beginning - needed for both restoration and truncation
|
|
1081
|
+
// Note: clark.context.jwt should be set by the socket handler (socket-manager.ts) before
|
|
1082
|
+
// this method is called. The socket handler updates it from peerAuthorization if missing.
|
|
1083
|
+
const jwt = this.clark?.context?.jwt;
|
|
1084
|
+
if (!jwt) {
|
|
1085
|
+
this.getLogger().warn(`[handleRestoreToCommit] No JWT available, cannot restore or truncate context`);
|
|
1086
|
+
return;
|
|
1087
|
+
}
|
|
1088
|
+
// 2. Try to restore context from checkpoint
|
|
1089
|
+
try {
|
|
1090
|
+
const contextId = getContextId(this.clark, this.config);
|
|
1091
|
+
const result = await restoreContextFromCheckpoint({
|
|
1092
|
+
applicationId,
|
|
1093
|
+
commitId,
|
|
1094
|
+
branchName,
|
|
1095
|
+
contextId,
|
|
1096
|
+
appRootDirPath: this.config.appRootDirPath,
|
|
1097
|
+
superblocksBaseUrl: this.config.superblocksBaseUrl,
|
|
1098
|
+
logger: this.getLogger(),
|
|
1099
|
+
jwt,
|
|
1100
|
+
contextManager: this.contextManager,
|
|
1101
|
+
});
|
|
1102
|
+
if (result.success) {
|
|
1103
|
+
this.getLogger().info(`[handleRestoreToCommit] Successfully restored main.json from checkpoint commitId=${commitId}, skipping truncation`);
|
|
1104
|
+
return; // Success - no need to truncate
|
|
1105
|
+
}
|
|
1106
|
+
else {
|
|
1107
|
+
// main.json not found or failed - fall through to truncation
|
|
1108
|
+
const reason = result.savedFiles.length > 0
|
|
1109
|
+
? "main.json not found in checkpoint"
|
|
1110
|
+
: "no file saved from checkpoint";
|
|
1111
|
+
this.getLogger().info(`[handleRestoreToCommit] Context restore failed: ${reason} for commitId=${commitId}, using truncation fallback`);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
catch (error) {
|
|
1115
|
+
// Error downloading - log and fall through to truncation
|
|
1116
|
+
this.getLogger().warn(`[handleRestoreToCommit] Error restoring context from checkpoint, using truncation fallback`, getErrorMeta(error));
|
|
1117
|
+
}
|
|
1118
|
+
// 3. Fallback: Truncate LLM context (restore failed)
|
|
884
1119
|
const contextId = getContextId(this.clark, this.config);
|
|
885
|
-
const ownerId = `
|
|
1120
|
+
const ownerId = `restore-handler-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
886
1121
|
const contextHandle = await this.contextManager.acquireContext(contextId, ownerId);
|
|
887
1122
|
try {
|
|
888
1123
|
contextHandle.context.truncateAfterTimestamp(sinceTimestamp);
|
|
1124
|
+
this.getLogger().info(`[handleRestoreToCommit] Context truncated after timestamp ${sinceTimestamp}`);
|
|
889
1125
|
}
|
|
890
1126
|
catch (error) {
|
|
891
1127
|
this.getLogger().error(`[ai-service] Failed to truncate context after timestamp ${sinceTimestamp}`, getErrorMeta(error));
|
|
1128
|
+
throw error;
|
|
892
1129
|
}
|
|
893
1130
|
finally {
|
|
894
1131
|
contextHandle.release();
|
|
@@ -914,6 +1151,9 @@ export class AiService extends TracedEventEmitter {
|
|
|
914
1151
|
this.clark.state !== ClarkStateNames.AwaitingUser &&
|
|
915
1152
|
this.clark.state !== ClarkStateNames.Dead);
|
|
916
1153
|
}
|
|
1154
|
+
isAwaitingUser() {
|
|
1155
|
+
return this.clark.state === ClarkStateNames.AwaitingUser;
|
|
1156
|
+
}
|
|
917
1157
|
/**
|
|
918
1158
|
* Check if Clark is currently generating code.
|
|
919
1159
|
* Used by lock-service to determine if lock should be held during generation.
|