skema-core 2.1.1 → 2.1.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.
- package/README.md +5 -11
- package/dist/cli.js +89 -73
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +414 -62
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +414 -62
- package/dist/index.mjs.map +1 -1
- package/dist/server.d.mts +9 -4
- package/dist/server.d.ts +9 -4
- package/dist/server.js +90 -72
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +90 -73
- package/dist/server.mjs.map +1 -1
- package/package.json +5 -3
package/dist/server.d.mts
CHANGED
|
@@ -451,14 +451,19 @@ declare function isProviderAvailable(provider: AIProvider): boolean;
|
|
|
451
451
|
*/
|
|
452
452
|
declare function getAvailableProviders(): AIProvider[];
|
|
453
453
|
|
|
454
|
+
type VisionProvider = 'gemini' | 'claude' | 'openai';
|
|
455
|
+
declare const VISION_MODELS: Record<VisionProvider, {
|
|
456
|
+
models: string[];
|
|
457
|
+
default: string;
|
|
458
|
+
}>;
|
|
454
459
|
interface VisionAnalysisResult {
|
|
455
460
|
success: boolean;
|
|
456
461
|
description: string;
|
|
457
|
-
provider:
|
|
462
|
+
provider: VisionProvider;
|
|
458
463
|
error?: string;
|
|
459
464
|
}
|
|
460
465
|
interface VisionConfig {
|
|
461
|
-
provider:
|
|
466
|
+
provider: VisionProvider;
|
|
462
467
|
/** API key for vision API (falls back to env vars) */
|
|
463
468
|
apiKey?: string;
|
|
464
469
|
/** Model to use for vision */
|
|
@@ -471,7 +476,7 @@ declare function analyzeImage(base64Image: string, config: VisionConfig): Promis
|
|
|
471
476
|
/**
|
|
472
477
|
* Check if vision analysis is available for a provider
|
|
473
478
|
*/
|
|
474
|
-
declare function isVisionAvailable(provider:
|
|
479
|
+
declare function isVisionAvailable(provider: VisionProvider): boolean;
|
|
475
480
|
|
|
476
481
|
type AnnotationStatus = 'pending' | 'acknowledged' | 'resolved' | 'dismissed';
|
|
477
482
|
interface StoredAnnotation {
|
|
@@ -538,4 +543,4 @@ declare function onStoreEvent(listener: StoreListener): () => void;
|
|
|
538
543
|
*/
|
|
539
544
|
declare function getPendingCount(): number;
|
|
540
545
|
|
|
541
|
-
export { type AIProviderConfig, type AIRunResult, type AIStreamEvent, type AnnotationStatus, type AIProvider as CLIProvider, DELETE, type DaemonConfig, type DaemonInstance, type DetailedDomSelectionInput, type DomSelectionInput, type DrawingInput, type ExecutionMode, type GeminiCLIEvent, type GeminiCLIOptions, type GestureInput, IMAGE_ANALYSIS_PROMPT, type IncomingMessage, type OutgoingMessage, POST, type ProjectContext, type ProviderName, type StoredAnnotation, type VisionAnalysisResult, type VisionConfig, acknowledgeAnnotation, analyzeImage, buildDetailedDomSelectionPrompt, buildDrawingToCodePrompt, buildFastDomSelectionPrompt, buildGesturePrompt, buildPromptFromAnnotation, clearAnnotations, createGeminiCLIStream, createGeminiRouteHandler, createRevertRouteHandler, dismissAnnotation, getAllAnnotations, getAnnotation, getAvailableProviders as getCLIProviders, getPendingAnnotations, getPendingCount, getTrackedAnnotations, isProviderAvailable, isVisionAvailable, onStoreEvent, queueAnnotation, removeAnnotation, resolveAnnotation, revertAnnotation, runAICLI, runGeminiCLI, spawnAICLI, spawnGeminiCLI, startDaemon };
|
|
546
|
+
export { type AIProviderConfig, type AIRunResult, type AIStreamEvent, type AnnotationStatus, type AIProvider as CLIProvider, DELETE, type DaemonConfig, type DaemonInstance, type DetailedDomSelectionInput, type DomSelectionInput, type DrawingInput, type ExecutionMode, type GeminiCLIEvent, type GeminiCLIOptions, type GestureInput, IMAGE_ANALYSIS_PROMPT, type IncomingMessage, type OutgoingMessage, POST, type ProjectContext, type ProviderName, type StoredAnnotation, VISION_MODELS, type VisionAnalysisResult, type VisionConfig, type VisionProvider, acknowledgeAnnotation, analyzeImage, buildDetailedDomSelectionPrompt, buildDrawingToCodePrompt, buildFastDomSelectionPrompt, buildGesturePrompt, buildPromptFromAnnotation, clearAnnotations, createGeminiCLIStream, createGeminiRouteHandler, createRevertRouteHandler, dismissAnnotation, getAllAnnotations, getAnnotation, getAvailableProviders as getCLIProviders, getPendingAnnotations, getPendingCount, getTrackedAnnotations, isProviderAvailable, isVisionAvailable, onStoreEvent, queueAnnotation, removeAnnotation, resolveAnnotation, revertAnnotation, runAICLI, runGeminiCLI, spawnAICLI, spawnGeminiCLI, startDaemon };
|
package/dist/server.d.ts
CHANGED
|
@@ -451,14 +451,19 @@ declare function isProviderAvailable(provider: AIProvider): boolean;
|
|
|
451
451
|
*/
|
|
452
452
|
declare function getAvailableProviders(): AIProvider[];
|
|
453
453
|
|
|
454
|
+
type VisionProvider = 'gemini' | 'claude' | 'openai';
|
|
455
|
+
declare const VISION_MODELS: Record<VisionProvider, {
|
|
456
|
+
models: string[];
|
|
457
|
+
default: string;
|
|
458
|
+
}>;
|
|
454
459
|
interface VisionAnalysisResult {
|
|
455
460
|
success: boolean;
|
|
456
461
|
description: string;
|
|
457
|
-
provider:
|
|
462
|
+
provider: VisionProvider;
|
|
458
463
|
error?: string;
|
|
459
464
|
}
|
|
460
465
|
interface VisionConfig {
|
|
461
|
-
provider:
|
|
466
|
+
provider: VisionProvider;
|
|
462
467
|
/** API key for vision API (falls back to env vars) */
|
|
463
468
|
apiKey?: string;
|
|
464
469
|
/** Model to use for vision */
|
|
@@ -471,7 +476,7 @@ declare function analyzeImage(base64Image: string, config: VisionConfig): Promis
|
|
|
471
476
|
/**
|
|
472
477
|
* Check if vision analysis is available for a provider
|
|
473
478
|
*/
|
|
474
|
-
declare function isVisionAvailable(provider:
|
|
479
|
+
declare function isVisionAvailable(provider: VisionProvider): boolean;
|
|
475
480
|
|
|
476
481
|
type AnnotationStatus = 'pending' | 'acknowledged' | 'resolved' | 'dismissed';
|
|
477
482
|
interface StoredAnnotation {
|
|
@@ -538,4 +543,4 @@ declare function onStoreEvent(listener: StoreListener): () => void;
|
|
|
538
543
|
*/
|
|
539
544
|
declare function getPendingCount(): number;
|
|
540
545
|
|
|
541
|
-
export { type AIProviderConfig, type AIRunResult, type AIStreamEvent, type AnnotationStatus, type AIProvider as CLIProvider, DELETE, type DaemonConfig, type DaemonInstance, type DetailedDomSelectionInput, type DomSelectionInput, type DrawingInput, type ExecutionMode, type GeminiCLIEvent, type GeminiCLIOptions, type GestureInput, IMAGE_ANALYSIS_PROMPT, type IncomingMessage, type OutgoingMessage, POST, type ProjectContext, type ProviderName, type StoredAnnotation, type VisionAnalysisResult, type VisionConfig, acknowledgeAnnotation, analyzeImage, buildDetailedDomSelectionPrompt, buildDrawingToCodePrompt, buildFastDomSelectionPrompt, buildGesturePrompt, buildPromptFromAnnotation, clearAnnotations, createGeminiCLIStream, createGeminiRouteHandler, createRevertRouteHandler, dismissAnnotation, getAllAnnotations, getAnnotation, getAvailableProviders as getCLIProviders, getPendingAnnotations, getPendingCount, getTrackedAnnotations, isProviderAvailable, isVisionAvailable, onStoreEvent, queueAnnotation, removeAnnotation, resolveAnnotation, revertAnnotation, runAICLI, runGeminiCLI, spawnAICLI, spawnGeminiCLI, startDaemon };
|
|
546
|
+
export { type AIProviderConfig, type AIRunResult, type AIStreamEvent, type AnnotationStatus, type AIProvider as CLIProvider, DELETE, type DaemonConfig, type DaemonInstance, type DetailedDomSelectionInput, type DomSelectionInput, type DrawingInput, type ExecutionMode, type GeminiCLIEvent, type GeminiCLIOptions, type GestureInput, IMAGE_ANALYSIS_PROMPT, type IncomingMessage, type OutgoingMessage, POST, type ProjectContext, type ProviderName, type StoredAnnotation, VISION_MODELS, type VisionAnalysisResult, type VisionConfig, type VisionProvider, acknowledgeAnnotation, analyzeImage, buildDetailedDomSelectionPrompt, buildDrawingToCodePrompt, buildFastDomSelectionPrompt, buildGesturePrompt, buildPromptFromAnnotation, clearAnnotations, createGeminiCLIStream, createGeminiRouteHandler, createRevertRouteHandler, dismissAnnotation, getAllAnnotations, getAnnotation, getAvailableProviders as getCLIProviders, getPendingAnnotations, getPendingCount, getTrackedAnnotations, isProviderAvailable, isVisionAvailable, onStoreEvent, queueAnnotation, removeAnnotation, resolveAnnotation, revertAnnotation, runAICLI, runGeminiCLI, spawnAICLI, spawnGeminiCLI, startDaemon };
|
package/dist/server.js
CHANGED
|
@@ -5,6 +5,10 @@ var generativeAi = require('@google/generative-ai');
|
|
|
5
5
|
var ws = require('ws');
|
|
6
6
|
var fs = require('fs');
|
|
7
7
|
var path = require('path');
|
|
8
|
+
var ai = require('ai');
|
|
9
|
+
var google = require('@ai-sdk/google');
|
|
10
|
+
var anthropic = require('@ai-sdk/anthropic');
|
|
11
|
+
var openai = require('@ai-sdk/openai');
|
|
8
12
|
|
|
9
13
|
function _interopNamespace(e) {
|
|
10
14
|
if (e && e.__esModule) return e;
|
|
@@ -903,57 +907,83 @@ function getAllProviderStatuses() {
|
|
|
903
907
|
claude: getProviderStatus("claude")
|
|
904
908
|
};
|
|
905
909
|
}
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
910
|
+
var VISION_MODELS = {
|
|
911
|
+
gemini: {
|
|
912
|
+
models: ["gemini-2.5-flash", "gemini-2.5-pro", "gemini-3-flash-preview", "gemini-3-pro-preview"],
|
|
913
|
+
default: "gemini-2.5-flash"
|
|
914
|
+
},
|
|
915
|
+
claude: {
|
|
916
|
+
models: ["claude-haiku-4-5-20251001", "claude-sonnet-4-5-20250929", "claude-opus-4-6"],
|
|
917
|
+
default: "claude-haiku-4-5-20251001"
|
|
918
|
+
},
|
|
919
|
+
openai: {
|
|
920
|
+
models: ["gpt-4o-mini", "gpt-4o", "gpt-4.1", "gpt-5.2"],
|
|
921
|
+
default: "gpt-4o-mini"
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
function getProviderModel(provider, apiKey, model) {
|
|
925
|
+
const modelId = model || VISION_MODELS[provider].default;
|
|
926
|
+
switch (provider) {
|
|
927
|
+
case "gemini": {
|
|
928
|
+
const google$1 = google.createGoogleGenerativeAI({ apiKey });
|
|
929
|
+
return google$1(modelId);
|
|
930
|
+
}
|
|
931
|
+
case "claude": {
|
|
932
|
+
const anthropic$1 = anthropic.createAnthropic({ apiKey });
|
|
933
|
+
return anthropic$1(modelId);
|
|
934
|
+
}
|
|
935
|
+
case "openai": {
|
|
936
|
+
const openai$1 = openai.createOpenAI({ apiKey });
|
|
937
|
+
return openai$1(modelId);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
function getEnvVarForProvider(provider) {
|
|
942
|
+
switch (provider) {
|
|
943
|
+
case "gemini":
|
|
944
|
+
return process.env.GEMINI_API_KEY;
|
|
945
|
+
case "claude":
|
|
946
|
+
return process.env.ANTHROPIC_API_KEY;
|
|
947
|
+
case "openai":
|
|
948
|
+
return process.env.OPENAI_API_KEY;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
function getEnvVarName(provider) {
|
|
952
|
+
switch (provider) {
|
|
953
|
+
case "gemini":
|
|
954
|
+
return "GEMINI_API_KEY";
|
|
955
|
+
case "claude":
|
|
956
|
+
return "ANTHROPIC_API_KEY";
|
|
957
|
+
case "openai":
|
|
958
|
+
return "OPENAI_API_KEY";
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
async function analyzeImage(base64Image, config) {
|
|
962
|
+
const { provider } = config;
|
|
963
|
+
const apiKey = config.apiKey || getEnvVarForProvider(provider);
|
|
964
|
+
if (!apiKey) {
|
|
930
965
|
return {
|
|
931
966
|
success: false,
|
|
932
967
|
description: "",
|
|
933
|
-
provider
|
|
934
|
-
error:
|
|
968
|
+
provider,
|
|
969
|
+
error: `No API key found for ${provider} vision. Set ${getEnvVarName(provider)} environment variable.`
|
|
935
970
|
};
|
|
936
971
|
}
|
|
937
|
-
}
|
|
938
|
-
async function analyzeWithClaude(base64Image, apiKey, model = "claude-sonnet-4-20250514") {
|
|
972
|
+
console.log(`[Vision] Analyzing image with ${provider}...`);
|
|
939
973
|
try {
|
|
940
|
-
const Anthropic = (await import('@anthropic-ai/sdk')).default;
|
|
941
|
-
const client = new Anthropic({ apiKey });
|
|
942
974
|
const cleanBase64 = base64Image.replace(/^data:image\/\w+;base64,/, "");
|
|
943
|
-
const
|
|
975
|
+
const model = getProviderModel(provider, apiKey, config.model);
|
|
976
|
+
const result = await ai.generateText({
|
|
944
977
|
model,
|
|
945
|
-
|
|
978
|
+
maxTokens: 1024,
|
|
946
979
|
messages: [
|
|
947
980
|
{
|
|
948
981
|
role: "user",
|
|
949
982
|
content: [
|
|
950
983
|
{
|
|
951
984
|
type: "image",
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
media_type: "image/png",
|
|
955
|
-
data: cleanBase64
|
|
956
|
-
}
|
|
985
|
+
image: Buffer.from(cleanBase64, "base64"),
|
|
986
|
+
mimeType: "image/png"
|
|
957
987
|
},
|
|
958
988
|
{
|
|
959
989
|
type: "text",
|
|
@@ -963,51 +993,24 @@ async function analyzeWithClaude(base64Image, apiKey, model = "claude-sonnet-4-2
|
|
|
963
993
|
}
|
|
964
994
|
]
|
|
965
995
|
});
|
|
966
|
-
const textContent = response.content.find((c) => c.type === "text");
|
|
967
|
-
const description = textContent && "text" in textContent ? textContent.text : "";
|
|
968
996
|
return {
|
|
969
997
|
success: true,
|
|
970
|
-
description,
|
|
971
|
-
provider
|
|
998
|
+
description: result.text,
|
|
999
|
+
provider
|
|
972
1000
|
};
|
|
973
1001
|
} catch (error) {
|
|
974
1002
|
const message = error instanceof Error ? error.message : String(error);
|
|
975
|
-
console.error(
|
|
976
|
-
return {
|
|
977
|
-
success: false,
|
|
978
|
-
description: "",
|
|
979
|
-
provider: "claude",
|
|
980
|
-
error: message
|
|
981
|
-
};
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
async function analyzeImage(base64Image, config) {
|
|
985
|
-
const { provider } = config;
|
|
986
|
-
let apiKey = config.apiKey;
|
|
987
|
-
if (!apiKey) {
|
|
988
|
-
apiKey = provider === "gemini" ? process.env.GEMINI_API_KEY : process.env.ANTHROPIC_API_KEY;
|
|
989
|
-
}
|
|
990
|
-
if (!apiKey) {
|
|
1003
|
+
console.error(`[Vision] ${provider} analysis failed:`, message);
|
|
991
1004
|
return {
|
|
992
1005
|
success: false,
|
|
993
1006
|
description: "",
|
|
994
1007
|
provider,
|
|
995
|
-
error:
|
|
1008
|
+
error: message
|
|
996
1009
|
};
|
|
997
1010
|
}
|
|
998
|
-
console.log(`[Vision] Analyzing image with ${provider}...`);
|
|
999
|
-
if (provider === "gemini") {
|
|
1000
|
-
return analyzeWithGemini(base64Image, apiKey, config.model);
|
|
1001
|
-
} else {
|
|
1002
|
-
return analyzeWithClaude(base64Image, apiKey, config.model);
|
|
1003
|
-
}
|
|
1004
1011
|
}
|
|
1005
1012
|
function isVisionAvailable(provider) {
|
|
1006
|
-
|
|
1007
|
-
return !!process.env.GEMINI_API_KEY;
|
|
1008
|
-
} else {
|
|
1009
|
-
return !!process.env.ANTHROPIC_API_KEY;
|
|
1010
|
-
}
|
|
1013
|
+
return !!getEnvVarForProvider(provider);
|
|
1011
1014
|
}
|
|
1012
1015
|
|
|
1013
1016
|
// src/server/annotation-store.ts
|
|
@@ -1251,9 +1254,14 @@ var handlers = {
|
|
|
1251
1254
|
provider: requestProvider
|
|
1252
1255
|
}
|
|
1253
1256
|
});
|
|
1254
|
-
|
|
1257
|
+
const visionProvider = msg.visionProvider || "gemini";
|
|
1258
|
+
const visionModel = msg.visionModel;
|
|
1259
|
+
const visionApiKey = msg.visionApiKey || (visionProvider === "gemini" ? process.env.GEMINI_API_KEY : visionProvider === "claude" ? process.env.ANTHROPIC_API_KEY : process.env.OPENAI_API_KEY);
|
|
1260
|
+
if (visionApiKey) {
|
|
1255
1261
|
const visionResult = await analyzeImage(drawingAnnotation.drawingImage, {
|
|
1256
|
-
provider:
|
|
1262
|
+
provider: visionProvider,
|
|
1263
|
+
apiKey: visionApiKey,
|
|
1264
|
+
model: visionModel
|
|
1257
1265
|
});
|
|
1258
1266
|
if (visionResult.success) {
|
|
1259
1267
|
visionDescription = visionResult.description;
|
|
@@ -1286,7 +1294,7 @@ ${visionDescription}`,
|
|
|
1286
1294
|
type: "ai-event",
|
|
1287
1295
|
event: {
|
|
1288
1296
|
type: "text",
|
|
1289
|
-
content: `[Vision not available -
|
|
1297
|
+
content: `[Vision not available - add your API key in Settings (gear icon)]`,
|
|
1290
1298
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1291
1299
|
provider: requestProvider
|
|
1292
1300
|
}
|
|
@@ -1297,6 +1305,8 @@ ${visionDescription}`,
|
|
|
1297
1305
|
fastMode: msg.fastMode === true,
|
|
1298
1306
|
visionDescription
|
|
1299
1307
|
});
|
|
1308
|
+
console.log(`[Skema] Prompt:
|
|
1309
|
+
${prompt}`);
|
|
1300
1310
|
sendMessage(ws, {
|
|
1301
1311
|
id: msg.id,
|
|
1302
1312
|
type: "ai-event",
|
|
@@ -1327,7 +1337,14 @@ ${visionDescription}`,
|
|
|
1327
1337
|
model: msg.model
|
|
1328
1338
|
};
|
|
1329
1339
|
const { process: aiProcess, events } = spawnAICLI(prompt, config);
|
|
1340
|
+
const prefixGreen = "\x1B[32m";
|
|
1341
|
+
const reset = "\x1B[0m";
|
|
1330
1342
|
for await (const event of events) {
|
|
1343
|
+
if (event.type === "text" && event.content) {
|
|
1344
|
+
console.log(`${prefixGreen}[Skema ${requestProvider}]${reset} ${event.content}`);
|
|
1345
|
+
} else if (event.type === "error" && event.content) {
|
|
1346
|
+
console.error(`${prefixGreen}[Skema ${requestProvider}]${reset} ${event.content}`);
|
|
1347
|
+
}
|
|
1331
1348
|
sendMessage(ws, {
|
|
1332
1349
|
id: msg.id,
|
|
1333
1350
|
type: "ai-event",
|
|
@@ -1720,6 +1737,7 @@ function startDaemon(config = {}) {
|
|
|
1720
1737
|
exports.DELETE = DELETE;
|
|
1721
1738
|
exports.IMAGE_ANALYSIS_PROMPT = IMAGE_ANALYSIS_PROMPT;
|
|
1722
1739
|
exports.POST = POST;
|
|
1740
|
+
exports.VISION_MODELS = VISION_MODELS;
|
|
1723
1741
|
exports.acknowledgeAnnotation = acknowledgeAnnotation;
|
|
1724
1742
|
exports.analyzeImage = analyzeImage;
|
|
1725
1743
|
exports.buildDetailedDomSelectionPrompt = buildDetailedDomSelectionPrompt;
|