@forgespace/siza-gen 0.3.0 → 0.4.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/README.md +13 -17
- package/dist/index.d.ts +90 -1
- package/dist/index.js +650 -169
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import pino from 'pino';
|
|
1
2
|
import path2, { join } from 'path';
|
|
2
3
|
import fs, { mkdirSync, writeFileSync, existsSync, statSync, readdirSync } from 'fs';
|
|
3
|
-
import pino6 from 'pino';
|
|
4
4
|
import { createRequire } from 'module';
|
|
5
5
|
import { homedir } from 'os';
|
|
6
6
|
import { spawn } from 'child_process';
|
|
@@ -3653,7 +3653,413 @@ var init_backend_registry = __esm({
|
|
|
3653
3653
|
initialized4 = false;
|
|
3654
3654
|
}
|
|
3655
3655
|
});
|
|
3656
|
-
|
|
3656
|
+
|
|
3657
|
+
// src/llm/types.ts
|
|
3658
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
3659
|
+
var DEFAULT_MAX_TOKENS = 1024;
|
|
3660
|
+
var DEFAULT_TEMPERATURE = 0.3;
|
|
3661
|
+
var loggerInstance = null;
|
|
3662
|
+
var consoleFallbackCache = /* @__PURE__ */ new Map();
|
|
3663
|
+
function initLogger() {
|
|
3664
|
+
if (loggerInstance) return loggerInstance;
|
|
3665
|
+
const config3 = {
|
|
3666
|
+
NODE_ENV: process.env.NODE_ENV ?? "production",
|
|
3667
|
+
FIGMA_ACCESS_TOKEN: process.env.FIGMA_ACCESS_TOKEN,
|
|
3668
|
+
LOG_LEVEL: process.env.LOG_LEVEL ?? "info"
|
|
3669
|
+
};
|
|
3670
|
+
const isDevelopment = config3.NODE_ENV !== "production";
|
|
3671
|
+
loggerInstance = pino(
|
|
3672
|
+
{
|
|
3673
|
+
level: config3.LOG_LEVEL,
|
|
3674
|
+
transport: isDevelopment ? {
|
|
3675
|
+
target: "pino-pretty",
|
|
3676
|
+
options: {
|
|
3677
|
+
colorize: true,
|
|
3678
|
+
translateTime: "HH:MM:ss",
|
|
3679
|
+
ignore: "pid,hostname",
|
|
3680
|
+
destination: 2
|
|
3681
|
+
}
|
|
3682
|
+
} : void 0
|
|
3683
|
+
},
|
|
3684
|
+
isDevelopment ? void 0 : pino.destination(2)
|
|
3685
|
+
);
|
|
3686
|
+
return loggerInstance;
|
|
3687
|
+
}
|
|
3688
|
+
function createConsoleFallback(name) {
|
|
3689
|
+
const cacheKey = name ?? "default";
|
|
3690
|
+
const cached = consoleFallbackCache.get(cacheKey);
|
|
3691
|
+
if (cached) {
|
|
3692
|
+
return cached;
|
|
3693
|
+
}
|
|
3694
|
+
const prefix = name ? `[${name}]` : "";
|
|
3695
|
+
const fallback = {
|
|
3696
|
+
// eslint-disable-next-line no-console
|
|
3697
|
+
error: (...args) => console.error(prefix, ...args),
|
|
3698
|
+
// eslint-disable-next-line no-console
|
|
3699
|
+
warn: (...args) => console.warn(prefix, ...args),
|
|
3700
|
+
// eslint-disable-next-line no-console
|
|
3701
|
+
info: (...args) => console.info(prefix, ...args),
|
|
3702
|
+
// eslint-disable-next-line no-console
|
|
3703
|
+
debug: (...args) => console.debug(prefix, ...args),
|
|
3704
|
+
// eslint-disable-next-line no-console
|
|
3705
|
+
fatal: (...args) => console.error(`${prefix} FATAL:`, ...args),
|
|
3706
|
+
// eslint-disable-next-line no-console
|
|
3707
|
+
trace: (...args) => console.debug(`${prefix} TRACE:`, ...args),
|
|
3708
|
+
silent: () => void 0,
|
|
3709
|
+
child: (bindings) => {
|
|
3710
|
+
const moduleName = typeof bindings.module === "string" ? bindings.module : name;
|
|
3711
|
+
return createConsoleFallback(moduleName);
|
|
3712
|
+
},
|
|
3713
|
+
level: "error"
|
|
3714
|
+
};
|
|
3715
|
+
consoleFallbackCache.set(cacheKey, fallback);
|
|
3716
|
+
return fallback;
|
|
3717
|
+
}
|
|
3718
|
+
var logger = new Proxy({}, {
|
|
3719
|
+
get(target, prop) {
|
|
3720
|
+
try {
|
|
3721
|
+
const instance = initLogger();
|
|
3722
|
+
return instance[prop];
|
|
3723
|
+
} catch {
|
|
3724
|
+
const fallback = createConsoleFallback();
|
|
3725
|
+
return fallback[prop];
|
|
3726
|
+
}
|
|
3727
|
+
}
|
|
3728
|
+
});
|
|
3729
|
+
function createLogger(name) {
|
|
3730
|
+
try {
|
|
3731
|
+
return initLogger().child({ module: name });
|
|
3732
|
+
} catch (err) {
|
|
3733
|
+
console.debug(`Failed to create logger for module '${name}', using console fallback:`, err);
|
|
3734
|
+
return createConsoleFallback(name);
|
|
3735
|
+
}
|
|
3736
|
+
}
|
|
3737
|
+
|
|
3738
|
+
// src/llm/providers/ollama.ts
|
|
3739
|
+
var logger2 = createLogger("llm:ollama");
|
|
3740
|
+
var DEFAULT_BASE_URL = "http://localhost:11434";
|
|
3741
|
+
var DEFAULT_MODEL = "llama3.2:3b";
|
|
3742
|
+
var OllamaProvider = class {
|
|
3743
|
+
type = "ollama";
|
|
3744
|
+
model;
|
|
3745
|
+
baseUrl;
|
|
3746
|
+
defaultTimeout;
|
|
3747
|
+
constructor(opts) {
|
|
3748
|
+
this.model = opts?.model ?? DEFAULT_MODEL;
|
|
3749
|
+
this.baseUrl = (opts?.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
3750
|
+
this.defaultTimeout = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
3751
|
+
}
|
|
3752
|
+
async generate(prompt, options) {
|
|
3753
|
+
const start = Date.now();
|
|
3754
|
+
const timeout = options?.timeoutMs ?? this.defaultTimeout;
|
|
3755
|
+
const body = {
|
|
3756
|
+
model: this.model,
|
|
3757
|
+
prompt: options?.systemPrompt ? `${options.systemPrompt}
|
|
3758
|
+
|
|
3759
|
+
${prompt}` : prompt,
|
|
3760
|
+
stream: false,
|
|
3761
|
+
options: {
|
|
3762
|
+
num_predict: options?.maxTokens ?? DEFAULT_MAX_TOKENS,
|
|
3763
|
+
temperature: options?.temperature ?? DEFAULT_TEMPERATURE
|
|
3764
|
+
}
|
|
3765
|
+
};
|
|
3766
|
+
const controller = new AbortController();
|
|
3767
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
3768
|
+
try {
|
|
3769
|
+
const res = await fetch(`${this.baseUrl}/api/generate`, {
|
|
3770
|
+
method: "POST",
|
|
3771
|
+
headers: { "Content-Type": "application/json" },
|
|
3772
|
+
body: JSON.stringify(body),
|
|
3773
|
+
signal: controller.signal
|
|
3774
|
+
});
|
|
3775
|
+
if (!res.ok) {
|
|
3776
|
+
const errText = await res.text().catch(() => "");
|
|
3777
|
+
throw new Error(`Ollama ${res.status}: ${errText.slice(0, 200)}`);
|
|
3778
|
+
}
|
|
3779
|
+
const data = await res.json();
|
|
3780
|
+
return {
|
|
3781
|
+
text: data.response?.trim() ?? "",
|
|
3782
|
+
model: this.model,
|
|
3783
|
+
provider: "ollama",
|
|
3784
|
+
tokensUsed: data.eval_count,
|
|
3785
|
+
latencyMs: Date.now() - start
|
|
3786
|
+
};
|
|
3787
|
+
} catch (err) {
|
|
3788
|
+
if (err.name === "AbortError") {
|
|
3789
|
+
throw new Error(`Ollama request timed out after ${timeout}ms`);
|
|
3790
|
+
}
|
|
3791
|
+
throw err;
|
|
3792
|
+
} finally {
|
|
3793
|
+
clearTimeout(timer);
|
|
3794
|
+
}
|
|
3795
|
+
}
|
|
3796
|
+
async isAvailable() {
|
|
3797
|
+
try {
|
|
3798
|
+
const controller = new AbortController();
|
|
3799
|
+
const timer = setTimeout(() => controller.abort(), 3e3);
|
|
3800
|
+
const res = await fetch(`${this.baseUrl}/api/tags`, {
|
|
3801
|
+
signal: controller.signal
|
|
3802
|
+
});
|
|
3803
|
+
clearTimeout(timer);
|
|
3804
|
+
return res.ok;
|
|
3805
|
+
} catch {
|
|
3806
|
+
logger2.debug("Ollama not available");
|
|
3807
|
+
return false;
|
|
3808
|
+
}
|
|
3809
|
+
}
|
|
3810
|
+
};
|
|
3811
|
+
|
|
3812
|
+
// src/llm/providers/openai.ts
|
|
3813
|
+
var logger3 = createLogger("llm:openai");
|
|
3814
|
+
var DEFAULT_BASE_URL2 = "https://api.openai.com/v1";
|
|
3815
|
+
var DEFAULT_MODEL2 = "gpt-4o-mini";
|
|
3816
|
+
var OpenAIProvider = class {
|
|
3817
|
+
type = "openai";
|
|
3818
|
+
model;
|
|
3819
|
+
baseUrl;
|
|
3820
|
+
apiKey;
|
|
3821
|
+
defaultTimeout;
|
|
3822
|
+
constructor(opts) {
|
|
3823
|
+
if (!opts.apiKey) {
|
|
3824
|
+
throw new Error("OpenAI provider requires an API key");
|
|
3825
|
+
}
|
|
3826
|
+
this.apiKey = opts.apiKey;
|
|
3827
|
+
this.model = opts.model ?? DEFAULT_MODEL2;
|
|
3828
|
+
this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE_URL2).replace(/\/$/, "");
|
|
3829
|
+
this.defaultTimeout = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
3830
|
+
}
|
|
3831
|
+
async generate(prompt, options) {
|
|
3832
|
+
const start = Date.now();
|
|
3833
|
+
const timeout = options?.timeoutMs ?? this.defaultTimeout;
|
|
3834
|
+
const messages = [];
|
|
3835
|
+
if (options?.systemPrompt) {
|
|
3836
|
+
messages.push({
|
|
3837
|
+
role: "system",
|
|
3838
|
+
content: options.systemPrompt
|
|
3839
|
+
});
|
|
3840
|
+
}
|
|
3841
|
+
messages.push({ role: "user", content: prompt });
|
|
3842
|
+
const body = {
|
|
3843
|
+
model: this.model,
|
|
3844
|
+
messages,
|
|
3845
|
+
max_tokens: options?.maxTokens ?? DEFAULT_MAX_TOKENS,
|
|
3846
|
+
temperature: options?.temperature ?? DEFAULT_TEMPERATURE
|
|
3847
|
+
};
|
|
3848
|
+
const controller = new AbortController();
|
|
3849
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
3850
|
+
try {
|
|
3851
|
+
const res = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
3852
|
+
method: "POST",
|
|
3853
|
+
headers: {
|
|
3854
|
+
"Content-Type": "application/json",
|
|
3855
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
3856
|
+
},
|
|
3857
|
+
body: JSON.stringify(body),
|
|
3858
|
+
signal: controller.signal
|
|
3859
|
+
});
|
|
3860
|
+
if (!res.ok) {
|
|
3861
|
+
const errText = await res.text().catch(() => "");
|
|
3862
|
+
throw new Error(`OpenAI ${res.status}: ${errText.slice(0, 200)}`);
|
|
3863
|
+
}
|
|
3864
|
+
const data = await res.json();
|
|
3865
|
+
const text = data.choices?.[0]?.message?.content?.trim() ?? "";
|
|
3866
|
+
return {
|
|
3867
|
+
text,
|
|
3868
|
+
model: this.model,
|
|
3869
|
+
provider: "openai",
|
|
3870
|
+
tokensUsed: data.usage?.total_tokens,
|
|
3871
|
+
latencyMs: Date.now() - start
|
|
3872
|
+
};
|
|
3873
|
+
} catch (err) {
|
|
3874
|
+
if (err.name === "AbortError") {
|
|
3875
|
+
throw new Error(`OpenAI request timed out after ${timeout}ms`);
|
|
3876
|
+
}
|
|
3877
|
+
throw err;
|
|
3878
|
+
} finally {
|
|
3879
|
+
clearTimeout(timer);
|
|
3880
|
+
}
|
|
3881
|
+
}
|
|
3882
|
+
async isAvailable() {
|
|
3883
|
+
try {
|
|
3884
|
+
const controller = new AbortController();
|
|
3885
|
+
const timer = setTimeout(() => controller.abort(), 5e3);
|
|
3886
|
+
const res = await fetch(`${this.baseUrl}/models`, {
|
|
3887
|
+
headers: {
|
|
3888
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
3889
|
+
},
|
|
3890
|
+
signal: controller.signal
|
|
3891
|
+
});
|
|
3892
|
+
clearTimeout(timer);
|
|
3893
|
+
return res.ok;
|
|
3894
|
+
} catch {
|
|
3895
|
+
logger3.debug("OpenAI API not reachable");
|
|
3896
|
+
return false;
|
|
3897
|
+
}
|
|
3898
|
+
}
|
|
3899
|
+
};
|
|
3900
|
+
|
|
3901
|
+
// src/llm/providers/anthropic.ts
|
|
3902
|
+
var logger4 = createLogger("llm:anthropic");
|
|
3903
|
+
var DEFAULT_BASE_URL3 = "https://api.anthropic.com";
|
|
3904
|
+
var DEFAULT_MODEL3 = "claude-sonnet-4-20250514";
|
|
3905
|
+
var API_VERSION = "2023-06-01";
|
|
3906
|
+
var AnthropicProvider = class {
|
|
3907
|
+
type = "anthropic";
|
|
3908
|
+
model;
|
|
3909
|
+
baseUrl;
|
|
3910
|
+
apiKey;
|
|
3911
|
+
defaultTimeout;
|
|
3912
|
+
constructor(opts) {
|
|
3913
|
+
if (!opts.apiKey) {
|
|
3914
|
+
throw new Error("Anthropic provider requires an API key");
|
|
3915
|
+
}
|
|
3916
|
+
this.apiKey = opts.apiKey;
|
|
3917
|
+
this.model = opts.model ?? DEFAULT_MODEL3;
|
|
3918
|
+
this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE_URL3).replace(/\/$/, "");
|
|
3919
|
+
this.defaultTimeout = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
3920
|
+
}
|
|
3921
|
+
async generate(prompt, options) {
|
|
3922
|
+
const start = Date.now();
|
|
3923
|
+
const timeout = options?.timeoutMs ?? this.defaultTimeout;
|
|
3924
|
+
const body = {
|
|
3925
|
+
model: this.model,
|
|
3926
|
+
max_tokens: options?.maxTokens ?? DEFAULT_MAX_TOKENS,
|
|
3927
|
+
messages: [{ role: "user", content: prompt }]
|
|
3928
|
+
};
|
|
3929
|
+
if (options?.systemPrompt) {
|
|
3930
|
+
body.system = options.systemPrompt;
|
|
3931
|
+
}
|
|
3932
|
+
if (options?.temperature !== void 0) {
|
|
3933
|
+
body.temperature = options.temperature;
|
|
3934
|
+
} else {
|
|
3935
|
+
body.temperature = DEFAULT_TEMPERATURE;
|
|
3936
|
+
}
|
|
3937
|
+
const controller = new AbortController();
|
|
3938
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
3939
|
+
try {
|
|
3940
|
+
const res = await fetch(`${this.baseUrl}/v1/messages`, {
|
|
3941
|
+
method: "POST",
|
|
3942
|
+
headers: {
|
|
3943
|
+
"Content-Type": "application/json",
|
|
3944
|
+
"x-api-key": this.apiKey,
|
|
3945
|
+
"anthropic-version": API_VERSION
|
|
3946
|
+
},
|
|
3947
|
+
body: JSON.stringify(body),
|
|
3948
|
+
signal: controller.signal
|
|
3949
|
+
});
|
|
3950
|
+
if (!res.ok) {
|
|
3951
|
+
const errText = await res.text().catch(() => "");
|
|
3952
|
+
throw new Error(`Anthropic ${res.status}: ${errText.slice(0, 200)}`);
|
|
3953
|
+
}
|
|
3954
|
+
const data = await res.json();
|
|
3955
|
+
const textBlock = data.content?.find((b) => b.type === "text");
|
|
3956
|
+
const text = textBlock?.text?.trim() ?? "";
|
|
3957
|
+
const tokensUsed = (data.usage?.input_tokens ?? 0) + (data.usage?.output_tokens ?? 0);
|
|
3958
|
+
return {
|
|
3959
|
+
text,
|
|
3960
|
+
model: this.model,
|
|
3961
|
+
provider: "anthropic",
|
|
3962
|
+
tokensUsed: tokensUsed || void 0,
|
|
3963
|
+
latencyMs: Date.now() - start
|
|
3964
|
+
};
|
|
3965
|
+
} catch (err) {
|
|
3966
|
+
if (err.name === "AbortError") {
|
|
3967
|
+
throw new Error(`Anthropic request timed out after ${timeout}ms`);
|
|
3968
|
+
}
|
|
3969
|
+
throw err;
|
|
3970
|
+
} finally {
|
|
3971
|
+
clearTimeout(timer);
|
|
3972
|
+
}
|
|
3973
|
+
}
|
|
3974
|
+
async isAvailable() {
|
|
3975
|
+
try {
|
|
3976
|
+
const controller = new AbortController();
|
|
3977
|
+
const timer = setTimeout(() => controller.abort(), 5e3);
|
|
3978
|
+
const res = await fetch(`${this.baseUrl}/v1/messages`, {
|
|
3979
|
+
method: "POST",
|
|
3980
|
+
headers: {
|
|
3981
|
+
"Content-Type": "application/json",
|
|
3982
|
+
"x-api-key": this.apiKey,
|
|
3983
|
+
"anthropic-version": API_VERSION
|
|
3984
|
+
},
|
|
3985
|
+
body: JSON.stringify({
|
|
3986
|
+
model: this.model,
|
|
3987
|
+
max_tokens: 1,
|
|
3988
|
+
messages: [{ role: "user", content: "ping" }]
|
|
3989
|
+
}),
|
|
3990
|
+
signal: controller.signal
|
|
3991
|
+
});
|
|
3992
|
+
clearTimeout(timer);
|
|
3993
|
+
return res.ok || res.status === 429;
|
|
3994
|
+
} catch {
|
|
3995
|
+
logger4.debug("Anthropic API not reachable");
|
|
3996
|
+
return false;
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3999
|
+
};
|
|
4000
|
+
|
|
4001
|
+
// src/llm/provider-factory.ts
|
|
4002
|
+
var logger5 = createLogger("llm:factory");
|
|
4003
|
+
function createProvider(config3) {
|
|
4004
|
+
switch (config3.provider) {
|
|
4005
|
+
case "ollama":
|
|
4006
|
+
return new OllamaProvider({
|
|
4007
|
+
model: config3.model,
|
|
4008
|
+
baseUrl: config3.baseUrl,
|
|
4009
|
+
timeoutMs: config3.timeoutMs
|
|
4010
|
+
});
|
|
4011
|
+
case "openai":
|
|
4012
|
+
return new OpenAIProvider({
|
|
4013
|
+
apiKey: config3.apiKey ?? "",
|
|
4014
|
+
model: config3.model,
|
|
4015
|
+
baseUrl: config3.baseUrl,
|
|
4016
|
+
timeoutMs: config3.timeoutMs
|
|
4017
|
+
});
|
|
4018
|
+
case "anthropic":
|
|
4019
|
+
return new AnthropicProvider({
|
|
4020
|
+
apiKey: config3.apiKey ?? "",
|
|
4021
|
+
model: config3.model,
|
|
4022
|
+
baseUrl: config3.baseUrl,
|
|
4023
|
+
timeoutMs: config3.timeoutMs
|
|
4024
|
+
});
|
|
4025
|
+
case "gemini":
|
|
4026
|
+
return new OpenAIProvider({
|
|
4027
|
+
apiKey: config3.apiKey ?? "",
|
|
4028
|
+
model: config3.model || "gemini-2.0-flash",
|
|
4029
|
+
baseUrl: config3.baseUrl ?? "https://generativelanguage.googleapis.com/v1beta/openai",
|
|
4030
|
+
timeoutMs: config3.timeoutMs
|
|
4031
|
+
});
|
|
4032
|
+
default:
|
|
4033
|
+
throw new Error(`Unknown LLM provider: ${config3.provider}`);
|
|
4034
|
+
}
|
|
4035
|
+
}
|
|
4036
|
+
async function detectOllama(baseUrl) {
|
|
4037
|
+
const provider = new OllamaProvider({ baseUrl });
|
|
4038
|
+
return provider.isAvailable();
|
|
4039
|
+
}
|
|
4040
|
+
async function createProviderWithFallback(config3) {
|
|
4041
|
+
if (config3) {
|
|
4042
|
+
try {
|
|
4043
|
+
const provider = createProvider(config3);
|
|
4044
|
+
const available = await provider.isAvailable();
|
|
4045
|
+
if (available) {
|
|
4046
|
+
logger5.info({ provider: config3.provider, model: config3.model }, "LLM provider ready");
|
|
4047
|
+
return provider;
|
|
4048
|
+
}
|
|
4049
|
+
logger5.warn({ provider: config3.provider }, "Configured provider unavailable, trying Ollama");
|
|
4050
|
+
} catch (err) {
|
|
4051
|
+
logger5.warn({ error: err.message }, "Provider creation failed, trying Ollama");
|
|
4052
|
+
}
|
|
4053
|
+
}
|
|
4054
|
+
const ollamaAvailable = await detectOllama();
|
|
4055
|
+
if (ollamaAvailable) {
|
|
4056
|
+
logger5.info("Ollama detected as fallback LLM provider");
|
|
4057
|
+
return new OllamaProvider();
|
|
4058
|
+
}
|
|
4059
|
+
logger5.debug("No LLM provider available");
|
|
4060
|
+
return null;
|
|
4061
|
+
}
|
|
4062
|
+
var logger6 = pino({ name: "ml-embeddings" });
|
|
3657
4063
|
var extractor = null;
|
|
3658
4064
|
var pipelineFn = null;
|
|
3659
4065
|
var DEFAULT_CONFIG = {
|
|
@@ -3681,16 +4087,16 @@ async function getExtractor() {
|
|
|
3681
4087
|
transformers.env.cacheDir = config.cacheDir;
|
|
3682
4088
|
}
|
|
3683
4089
|
}
|
|
3684
|
-
|
|
4090
|
+
logger6.info({ model: config.modelId, cache: config.cacheDir }, "Loading embedding model");
|
|
3685
4091
|
try {
|
|
3686
4092
|
extractor = await pipelineFn("feature-extraction", config.modelId, {
|
|
3687
4093
|
quantized: true
|
|
3688
4094
|
// Use quantized model for smaller size & faster CPU inference
|
|
3689
4095
|
});
|
|
3690
|
-
|
|
4096
|
+
logger6.info("Embedding model loaded");
|
|
3691
4097
|
return extractor;
|
|
3692
4098
|
} catch (err) {
|
|
3693
|
-
|
|
4099
|
+
logger6.error({ err, model: config.modelId }, "Failed to load embedding model");
|
|
3694
4100
|
throw new Error(`Failed to load embedding model: ${err}`);
|
|
3695
4101
|
}
|
|
3696
4102
|
}
|
|
@@ -3754,9 +4160,9 @@ function isModelLoaded() {
|
|
|
3754
4160
|
}
|
|
3755
4161
|
function unloadModel() {
|
|
3756
4162
|
extractor = null;
|
|
3757
|
-
|
|
4163
|
+
logger6.info("Embedding model unloaded");
|
|
3758
4164
|
}
|
|
3759
|
-
var
|
|
4165
|
+
var logger7 = pino({ name: "vector-index" });
|
|
3760
4166
|
var DIMENSIONS = 384;
|
|
3761
4167
|
var VSS_TABLE = "vss_embeddings";
|
|
3762
4168
|
var vssAvailable = false;
|
|
@@ -3771,11 +4177,11 @@ function initVectorIndex(db2) {
|
|
|
3771
4177
|
loadVss(db2);
|
|
3772
4178
|
db2.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS ${VSS_TABLE} USING vss0(vector(${DIMENSIONS}))`);
|
|
3773
4179
|
vssAvailable = true;
|
|
3774
|
-
|
|
4180
|
+
logger7.info("sqlite-vss loaded, vector index ready");
|
|
3775
4181
|
return true;
|
|
3776
4182
|
} catch (err) {
|
|
3777
4183
|
vssAvailable = false;
|
|
3778
|
-
|
|
4184
|
+
logger7.warn({ err }, "sqlite-vss unavailable, falling back to brute-force search");
|
|
3779
4185
|
return false;
|
|
3780
4186
|
}
|
|
3781
4187
|
}
|
|
@@ -3911,7 +4317,7 @@ function deleteEmbeddings(sourceType, db2) {
|
|
|
3911
4317
|
const result = db2.prepare("DELETE FROM embeddings WHERE source_type = ?").run(sourceType);
|
|
3912
4318
|
return result.changes;
|
|
3913
4319
|
}
|
|
3914
|
-
var
|
|
4320
|
+
var logger8 = pino({ name: "training-data-exporter" });
|
|
3915
4321
|
function exportRawExamples(db2, opts = {}) {
|
|
3916
4322
|
const minAbs = opts.minAbsScore ?? 0.3;
|
|
3917
4323
|
const limit = opts.limit ?? 1e4;
|
|
@@ -3980,7 +4386,7 @@ function writeJsonl(rows, filePath) {
|
|
|
3980
4386
|
const lines = rows.map((r) => JSON.stringify(r)).join("\n");
|
|
3981
4387
|
writeFileSync(filePath, `${lines}
|
|
3982
4388
|
`, "utf-8");
|
|
3983
|
-
|
|
4389
|
+
logger8.info({ path: filePath, rows: rows.length }, "Training data written");
|
|
3984
4390
|
return rows.length;
|
|
3985
4391
|
}
|
|
3986
4392
|
function exportForAdapter(adapter, db2, outputDir) {
|
|
@@ -4020,7 +4426,7 @@ function hasEnoughData(adapter, db2, includeSynthetic = false) {
|
|
|
4020
4426
|
const required = includeSynthetic ? syntheticThresholds[adapter] : feedbackThresholds[adapter];
|
|
4021
4427
|
return { ready: count >= required, count, required };
|
|
4022
4428
|
}
|
|
4023
|
-
var
|
|
4429
|
+
var logger9 = pino({ name: "model-manager" });
|
|
4024
4430
|
var DEFAULT_BASE_DIR = join(homedir(), ".uiforge");
|
|
4025
4431
|
var MODEL_REGISTRY = {
|
|
4026
4432
|
"qwen2.5-0.5b": {
|
|
@@ -4032,7 +4438,7 @@ var MODEL_REGISTRY = {
|
|
|
4032
4438
|
var _baseDir = DEFAULT_BASE_DIR;
|
|
4033
4439
|
function configureModelDir(baseDir) {
|
|
4034
4440
|
_baseDir = baseDir;
|
|
4035
|
-
|
|
4441
|
+
logger9.debug({ baseDir }, "Model directory configured");
|
|
4036
4442
|
}
|
|
4037
4443
|
function getBaseDir() {
|
|
4038
4444
|
return _baseDir;
|
|
@@ -4051,7 +4457,7 @@ function ensureDirectories() {
|
|
|
4051
4457
|
for (const dir of Object.values(paths)) {
|
|
4052
4458
|
if (!existsSync(dir)) {
|
|
4053
4459
|
mkdirSync(dir, { recursive: true });
|
|
4054
|
-
|
|
4460
|
+
logger9.debug({ dir }, "Created directory");
|
|
4055
4461
|
}
|
|
4056
4462
|
}
|
|
4057
4463
|
return paths;
|
|
@@ -4121,7 +4527,7 @@ function getDirectorySize(dir) {
|
|
|
4121
4527
|
}
|
|
4122
4528
|
return total;
|
|
4123
4529
|
}
|
|
4124
|
-
var
|
|
4530
|
+
var logger10 = pino({ name: "training-pipeline" });
|
|
4125
4531
|
var DEFAULT_LORA_CONFIG = {
|
|
4126
4532
|
rank: 8,
|
|
4127
4533
|
epochs: 3,
|
|
@@ -4216,7 +4622,7 @@ function startTrainingJob(adapter, modelId, db2, config3 = DEFAULT_LORA_CONFIG,
|
|
|
4216
4622
|
const modelPath = getModelPath(modelId);
|
|
4217
4623
|
const adapterPath = getAdapterPath(adapter);
|
|
4218
4624
|
const cmd = trainingCommand ?? buildDefaultTrainingCommand(modelPath, dataPath, adapterPath, config3);
|
|
4219
|
-
|
|
4625
|
+
logger10.info({ adapter, jobId, count, modelId }, "Starting LoRA training job");
|
|
4220
4626
|
try {
|
|
4221
4627
|
const cmdParts = cmd.split(/\s+/);
|
|
4222
4628
|
const child = spawn(cmdParts[0], cmdParts.slice(1), {
|
|
@@ -4231,10 +4637,10 @@ function startTrainingJob(adapter, modelId, db2, config3 = DEFAULT_LORA_CONFIG,
|
|
|
4231
4637
|
if (progress !== null) {
|
|
4232
4638
|
updateJobStatus(jobId, "training", progress, db2);
|
|
4233
4639
|
}
|
|
4234
|
-
|
|
4640
|
+
logger10.debug({ adapter, line }, "Training output");
|
|
4235
4641
|
});
|
|
4236
4642
|
child.stderr?.on("data", (data) => {
|
|
4237
|
-
|
|
4643
|
+
logger10.warn({ adapter, stderr: data.toString().trim() }, "Training stderr");
|
|
4238
4644
|
});
|
|
4239
4645
|
child.on("close", (code) => {
|
|
4240
4646
|
activeJobs.delete(adapter);
|
|
@@ -4242,21 +4648,21 @@ function startTrainingJob(adapter, modelId, db2, config3 = DEFAULT_LORA_CONFIG,
|
|
|
4242
4648
|
try {
|
|
4243
4649
|
process.kill(-child.pid, "SIGTERM");
|
|
4244
4650
|
} catch (err) {
|
|
4245
|
-
|
|
4651
|
+
logger10.debug({ err }, "Process group already terminated");
|
|
4246
4652
|
}
|
|
4247
4653
|
}
|
|
4248
4654
|
if (code === 0 && existsSync(adapterPath)) {
|
|
4249
4655
|
updateJobStatus(jobId, "complete", 100, db2);
|
|
4250
|
-
|
|
4656
|
+
logger10.info({ adapter, jobId }, "Training completed successfully");
|
|
4251
4657
|
} else {
|
|
4252
4658
|
updateJobStatus(jobId, "failed", 0, db2, `Process exited with code ${code}`);
|
|
4253
|
-
|
|
4659
|
+
logger10.error({ adapter, jobId, code }, "Training failed");
|
|
4254
4660
|
}
|
|
4255
4661
|
});
|
|
4256
4662
|
child.on("error", (err) => {
|
|
4257
4663
|
activeJobs.delete(adapter);
|
|
4258
4664
|
updateJobStatus(jobId, "failed", 0, db2, err.message);
|
|
4259
|
-
|
|
4665
|
+
logger10.error({ adapter, jobId, error: err.message }, "Training process error");
|
|
4260
4666
|
});
|
|
4261
4667
|
child.unref();
|
|
4262
4668
|
} catch (err) {
|
|
@@ -4285,7 +4691,7 @@ function cancelTrainingJob(adapter, db2) {
|
|
|
4285
4691
|
updateJobStatus(row.id, "failed", 0, db2, "Cancelled by user");
|
|
4286
4692
|
}
|
|
4287
4693
|
}
|
|
4288
|
-
|
|
4694
|
+
logger10.info({ adapter }, "Training job cancelled");
|
|
4289
4695
|
return true;
|
|
4290
4696
|
} catch {
|
|
4291
4697
|
return false;
|
|
@@ -4476,82 +4882,6 @@ var ConfigNotInitializedError = class _ConfigNotInitializedError extends Error {
|
|
|
4476
4882
|
}
|
|
4477
4883
|
}
|
|
4478
4884
|
};
|
|
4479
|
-
var loggerInstance = null;
|
|
4480
|
-
var consoleFallbackCache = /* @__PURE__ */ new Map();
|
|
4481
|
-
function initLogger() {
|
|
4482
|
-
if (loggerInstance) return loggerInstance;
|
|
4483
|
-
const config3 = {
|
|
4484
|
-
NODE_ENV: process.env.NODE_ENV ?? "production",
|
|
4485
|
-
FIGMA_ACCESS_TOKEN: process.env.FIGMA_ACCESS_TOKEN,
|
|
4486
|
-
LOG_LEVEL: process.env.LOG_LEVEL ?? "info"
|
|
4487
|
-
};
|
|
4488
|
-
const isDevelopment = config3.NODE_ENV !== "production";
|
|
4489
|
-
loggerInstance = pino6(
|
|
4490
|
-
{
|
|
4491
|
-
level: config3.LOG_LEVEL,
|
|
4492
|
-
transport: isDevelopment ? {
|
|
4493
|
-
target: "pino-pretty",
|
|
4494
|
-
options: {
|
|
4495
|
-
colorize: true,
|
|
4496
|
-
translateTime: "HH:MM:ss",
|
|
4497
|
-
ignore: "pid,hostname",
|
|
4498
|
-
destination: 2
|
|
4499
|
-
}
|
|
4500
|
-
} : void 0
|
|
4501
|
-
},
|
|
4502
|
-
isDevelopment ? void 0 : pino6.destination(2)
|
|
4503
|
-
);
|
|
4504
|
-
return loggerInstance;
|
|
4505
|
-
}
|
|
4506
|
-
function createConsoleFallback(name) {
|
|
4507
|
-
const cacheKey = name ?? "default";
|
|
4508
|
-
const cached = consoleFallbackCache.get(cacheKey);
|
|
4509
|
-
if (cached) {
|
|
4510
|
-
return cached;
|
|
4511
|
-
}
|
|
4512
|
-
const prefix = name ? `[${name}]` : "";
|
|
4513
|
-
const fallback = {
|
|
4514
|
-
// eslint-disable-next-line no-console
|
|
4515
|
-
error: (...args) => console.error(prefix, ...args),
|
|
4516
|
-
// eslint-disable-next-line no-console
|
|
4517
|
-
warn: (...args) => console.warn(prefix, ...args),
|
|
4518
|
-
// eslint-disable-next-line no-console
|
|
4519
|
-
info: (...args) => console.info(prefix, ...args),
|
|
4520
|
-
// eslint-disable-next-line no-console
|
|
4521
|
-
debug: (...args) => console.debug(prefix, ...args),
|
|
4522
|
-
// eslint-disable-next-line no-console
|
|
4523
|
-
fatal: (...args) => console.error(`${prefix} FATAL:`, ...args),
|
|
4524
|
-
// eslint-disable-next-line no-console
|
|
4525
|
-
trace: (...args) => console.debug(`${prefix} TRACE:`, ...args),
|
|
4526
|
-
silent: () => void 0,
|
|
4527
|
-
child: (bindings) => {
|
|
4528
|
-
const moduleName = typeof bindings.module === "string" ? bindings.module : name;
|
|
4529
|
-
return createConsoleFallback(moduleName);
|
|
4530
|
-
},
|
|
4531
|
-
level: "error"
|
|
4532
|
-
};
|
|
4533
|
-
consoleFallbackCache.set(cacheKey, fallback);
|
|
4534
|
-
return fallback;
|
|
4535
|
-
}
|
|
4536
|
-
var logger6 = new Proxy({}, {
|
|
4537
|
-
get(target, prop) {
|
|
4538
|
-
try {
|
|
4539
|
-
const instance = initLogger();
|
|
4540
|
-
return instance[prop];
|
|
4541
|
-
} catch {
|
|
4542
|
-
const fallback = createConsoleFallback();
|
|
4543
|
-
return fallback[prop];
|
|
4544
|
-
}
|
|
4545
|
-
}
|
|
4546
|
-
});
|
|
4547
|
-
function createLogger(name) {
|
|
4548
|
-
try {
|
|
4549
|
-
return initLogger().child({ module: name });
|
|
4550
|
-
} catch (err) {
|
|
4551
|
-
console.debug(`Failed to create logger for module '${name}', using console fallback:`, err);
|
|
4552
|
-
return createConsoleFallback(name);
|
|
4553
|
-
}
|
|
4554
|
-
}
|
|
4555
4885
|
|
|
4556
4886
|
// src/config.ts
|
|
4557
4887
|
var configSchema = z.object({
|
|
@@ -4582,13 +4912,13 @@ function safeJSONParse(jsonString, defaultValue) {
|
|
|
4582
4912
|
try {
|
|
4583
4913
|
return JSON.parse(jsonString);
|
|
4584
4914
|
} catch (err) {
|
|
4585
|
-
|
|
4915
|
+
logger.error({ err, jsonString: jsonString.substring(0, 100) }, "Failed to parse JSON, returning fallback");
|
|
4586
4916
|
return fallback;
|
|
4587
4917
|
}
|
|
4588
4918
|
}
|
|
4589
4919
|
|
|
4590
4920
|
// src/registry/database/store.ts
|
|
4591
|
-
var
|
|
4921
|
+
var logger11 = pino({ name: "design-references-db" });
|
|
4592
4922
|
var db = null;
|
|
4593
4923
|
function getDatabase(customPath) {
|
|
4594
4924
|
if (db) return db;
|
|
@@ -4604,7 +4934,7 @@ function getDatabase(customPath) {
|
|
|
4604
4934
|
db.pragma("synchronous = NORMAL");
|
|
4605
4935
|
db.prepare("INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)").run("schema_version", String(SCHEMA_VERSION));
|
|
4606
4936
|
initVectorIndex(db);
|
|
4607
|
-
|
|
4937
|
+
logger11.info({ dbPath: resolvedPath }, "Database opened/created");
|
|
4608
4938
|
return db;
|
|
4609
4939
|
}
|
|
4610
4940
|
function closeDatabase() {
|
|
@@ -4680,7 +5010,7 @@ function seedComponents(snippets2, database) {
|
|
|
4680
5010
|
d.prepare("INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)").run("seed_count", String(snippets2.length));
|
|
4681
5011
|
});
|
|
4682
5012
|
seedAll();
|
|
4683
|
-
|
|
5013
|
+
logger11.info({ count: snippets2.length }, "Components seeded to database");
|
|
4684
5014
|
}
|
|
4685
5015
|
function hydrateSnippetsBatch(ids, d) {
|
|
4686
5016
|
if (ids.length === 0) return [];
|
|
@@ -4785,10 +5115,94 @@ function getAllComponents(database) {
|
|
|
4785
5115
|
function getDefaultDbPath() {
|
|
4786
5116
|
return path2.resolve(process.cwd(), ".uiforge", "rag.sqlite");
|
|
4787
5117
|
}
|
|
4788
|
-
|
|
4789
|
-
|
|
5118
|
+
|
|
5119
|
+
// src/ml/quality-scorer.ts
|
|
5120
|
+
var logger12 = createLogger("quality-scorer");
|
|
5121
|
+
var llmProvider = null;
|
|
5122
|
+
function setQualityScorerLLM(provider) {
|
|
5123
|
+
llmProvider = provider;
|
|
5124
|
+
}
|
|
5125
|
+
function getQualityScorerLLM() {
|
|
5126
|
+
return llmProvider;
|
|
5127
|
+
}
|
|
5128
|
+
async function scoreQuality(prompt, generatedCode, params) {
|
|
4790
5129
|
const start = Date.now();
|
|
4791
|
-
|
|
5130
|
+
const heuristic = scoreWithHeuristics(prompt, generatedCode, params, start);
|
|
5131
|
+
if (!llmProvider) return heuristic;
|
|
5132
|
+
try {
|
|
5133
|
+
const llmScore = await scoreWithLLM(prompt, generatedCode, params, start);
|
|
5134
|
+
return blendScores(heuristic, llmScore, start);
|
|
5135
|
+
} catch (err) {
|
|
5136
|
+
logger12.debug({ error: err.message }, "LLM scoring failed, using heuristic");
|
|
5137
|
+
return heuristic;
|
|
5138
|
+
}
|
|
5139
|
+
}
|
|
5140
|
+
var LLM_SCORE_TIMEOUT_MS = 1e4;
|
|
5141
|
+
var LLM_WEIGHT = 0.6;
|
|
5142
|
+
var HEURISTIC_WEIGHT = 0.4;
|
|
5143
|
+
async function scoreWithLLM(prompt, generatedCode, params, start) {
|
|
5144
|
+
const codeSnippet = generatedCode.slice(0, 2e3);
|
|
5145
|
+
const evalPrompt = [
|
|
5146
|
+
"Rate this generated UI code on a scale of 0-10.",
|
|
5147
|
+
"Evaluate: security, accessibility, semantic HTML,",
|
|
5148
|
+
"responsiveness, code structure, and prompt alignment.",
|
|
5149
|
+
"Respond with ONLY a JSON object:",
|
|
5150
|
+
'{"score":N,"reasoning":"brief"}',
|
|
5151
|
+
"",
|
|
5152
|
+
`User prompt: ${prompt.slice(0, 200)}`,
|
|
5153
|
+
`Component: ${params?.componentType ?? "unknown"}`,
|
|
5154
|
+
`Framework: ${params?.framework ?? "unknown"}`,
|
|
5155
|
+
"",
|
|
5156
|
+
"```",
|
|
5157
|
+
codeSnippet,
|
|
5158
|
+
"```"
|
|
5159
|
+
].join("\n");
|
|
5160
|
+
const result = await llmProvider.generate(evalPrompt, {
|
|
5161
|
+
maxTokens: 64,
|
|
5162
|
+
temperature: 0.1,
|
|
5163
|
+
timeoutMs: LLM_SCORE_TIMEOUT_MS
|
|
5164
|
+
});
|
|
5165
|
+
const parsed = parseLLMScore(result.text);
|
|
5166
|
+
if (parsed === null) {
|
|
5167
|
+
throw new Error("LLM score unparseable");
|
|
5168
|
+
}
|
|
5169
|
+
return {
|
|
5170
|
+
score: parsed,
|
|
5171
|
+
confidence: 0.8,
|
|
5172
|
+
source: "model",
|
|
5173
|
+
latencyMs: Date.now() - start
|
|
5174
|
+
};
|
|
5175
|
+
}
|
|
5176
|
+
function parseLLMScore(text) {
|
|
5177
|
+
const jsonMatch = text.match(/\{[^}]*"score"\s*:\s*([\d.]+)/);
|
|
5178
|
+
if (jsonMatch) {
|
|
5179
|
+
const val = parseFloat(jsonMatch[1]);
|
|
5180
|
+
if (!isNaN(val) && val >= 0 && val <= 10) {
|
|
5181
|
+
return Math.round(val * 10) / 10;
|
|
5182
|
+
}
|
|
5183
|
+
}
|
|
5184
|
+
const numMatch = text.trim().match(/^(\d+\.?\d*)$/);
|
|
5185
|
+
if (numMatch) {
|
|
5186
|
+
const val = parseFloat(numMatch[1]);
|
|
5187
|
+
if (!isNaN(val) && val >= 0 && val <= 10) {
|
|
5188
|
+
return Math.round(val * 10) / 10;
|
|
5189
|
+
}
|
|
5190
|
+
}
|
|
5191
|
+
return null;
|
|
5192
|
+
}
|
|
5193
|
+
function blendScores(heuristic, llm, start) {
|
|
5194
|
+
const blended = LLM_WEIGHT * llm.score + HEURISTIC_WEIGHT * heuristic.score;
|
|
5195
|
+
return {
|
|
5196
|
+
score: Math.round(blended * 10) / 10,
|
|
5197
|
+
confidence: Math.min(0.9, LLM_WEIGHT * llm.confidence + HEURISTIC_WEIGHT * heuristic.confidence),
|
|
5198
|
+
source: "model",
|
|
5199
|
+
factors: {
|
|
5200
|
+
...heuristic.factors,
|
|
5201
|
+
llmScore: llm.score,
|
|
5202
|
+
heuristicScore: heuristic.score
|
|
5203
|
+
},
|
|
5204
|
+
latencyMs: Date.now() - start
|
|
5205
|
+
};
|
|
4792
5206
|
}
|
|
4793
5207
|
function scoreWithHeuristics(prompt, generatedCode, params, start) {
|
|
4794
5208
|
const factors = {};
|
|
@@ -4921,7 +5335,7 @@ async function scoreQualityWithRAG(prompt, generatedCode, params) {
|
|
|
4921
5335
|
latencyMs: Date.now() - start
|
|
4922
5336
|
};
|
|
4923
5337
|
} catch (err) {
|
|
4924
|
-
|
|
5338
|
+
logger12.warn({ error: err.message }, "RAG quality scoring failed");
|
|
4925
5339
|
return baseScore;
|
|
4926
5340
|
}
|
|
4927
5341
|
}
|
|
@@ -4929,10 +5343,77 @@ async function isLikelyAccepted(prompt, generatedCode, params) {
|
|
|
4929
5343
|
const result = await scoreQuality(prompt, generatedCode, params);
|
|
4930
5344
|
return result.score >= 6;
|
|
4931
5345
|
}
|
|
4932
|
-
|
|
4933
|
-
|
|
5346
|
+
|
|
5347
|
+
// src/ml/prompt-enhancer.ts
|
|
5348
|
+
var logger13 = createLogger("prompt-enhancer");
|
|
5349
|
+
var llmProvider2 = null;
|
|
5350
|
+
function setPromptEnhancerLLM(provider) {
|
|
5351
|
+
llmProvider2 = provider;
|
|
5352
|
+
}
|
|
5353
|
+
function getPromptEnhancerLLM() {
|
|
5354
|
+
return llmProvider2;
|
|
5355
|
+
}
|
|
5356
|
+
async function enhancePrompt(prompt, context) {
|
|
4934
5357
|
const start = Date.now();
|
|
4935
|
-
|
|
5358
|
+
if (!llmProvider2) {
|
|
5359
|
+
return enhanceWithRules(prompt, context, start);
|
|
5360
|
+
}
|
|
5361
|
+
try {
|
|
5362
|
+
return await enhanceWithModel(prompt, context, start);
|
|
5363
|
+
} catch (err) {
|
|
5364
|
+
logger13.debug({ error: err.message }, "LLM enhancement failed, using rules");
|
|
5365
|
+
return enhanceWithRules(prompt, context, start);
|
|
5366
|
+
}
|
|
5367
|
+
}
|
|
5368
|
+
var LLM_ENHANCE_TIMEOUT_MS = 1e4;
|
|
5369
|
+
async function enhanceWithModel(prompt, context, start) {
|
|
5370
|
+
const ruleResult = enhanceWithRules(prompt, context, start);
|
|
5371
|
+
const llmPrompt = [
|
|
5372
|
+
"Improve this UI generation prompt. Keep the intent but",
|
|
5373
|
+
"add specificity about layout, styling, accessibility.",
|
|
5374
|
+
"Respond with ONLY the improved prompt text.",
|
|
5375
|
+
"",
|
|
5376
|
+
`Original: ${prompt}`,
|
|
5377
|
+
context?.componentType ? `Component: ${context.componentType}` : "",
|
|
5378
|
+
context?.framework ? `Framework: ${context.framework}` : "",
|
|
5379
|
+
context?.style ? `Style: ${context.style}` : "",
|
|
5380
|
+
context?.mood ? `Mood: ${context.mood}` : "",
|
|
5381
|
+
context?.industry ? `Industry: ${context.industry}` : ""
|
|
5382
|
+
].filter(Boolean).join("\n");
|
|
5383
|
+
const result = await llmProvider2.generate(llmPrompt, {
|
|
5384
|
+
maxTokens: 256,
|
|
5385
|
+
temperature: 0.5,
|
|
5386
|
+
timeoutMs: LLM_ENHANCE_TIMEOUT_MS
|
|
5387
|
+
});
|
|
5388
|
+
const enhanced = result.text.trim();
|
|
5389
|
+
if (enhanced.length < prompt.length * 0.5) {
|
|
5390
|
+
return ruleResult;
|
|
5391
|
+
}
|
|
5392
|
+
const combined = mergeEnhancements(enhanced, ruleResult);
|
|
5393
|
+
return {
|
|
5394
|
+
enhanced: combined,
|
|
5395
|
+
original: prompt,
|
|
5396
|
+
source: "model",
|
|
5397
|
+
additions: ["llm-enhanced", ...ruleResult.additions.filter((a) => !combined.includes(a))],
|
|
5398
|
+
latencyMs: Date.now() - start
|
|
5399
|
+
};
|
|
5400
|
+
}
|
|
5401
|
+
function mergeEnhancements(llmResult, ruleResult, original) {
|
|
5402
|
+
let merged = llmResult;
|
|
5403
|
+
const llmLower = llmResult.toLowerCase();
|
|
5404
|
+
for (const addition of ruleResult.additions) {
|
|
5405
|
+
if (addition === "accessibility") {
|
|
5406
|
+
if (!llmLower.includes("aria") && !llmLower.includes("accessible") && !llmLower.includes("keyboard")) {
|
|
5407
|
+
merged += ". Include ARIA labels and keyboard navigation";
|
|
5408
|
+
}
|
|
5409
|
+
}
|
|
5410
|
+
if (addition === "responsive") {
|
|
5411
|
+
if (!llmLower.includes("responsive") && !llmLower.includes("mobile")) {
|
|
5412
|
+
merged += ". Make it responsive";
|
|
5413
|
+
}
|
|
5414
|
+
}
|
|
5415
|
+
}
|
|
5416
|
+
return merged;
|
|
4936
5417
|
}
|
|
4937
5418
|
function enhanceWithRules(prompt, context, start = Date.now()) {
|
|
4938
5419
|
const additions = [];
|
|
@@ -4971,7 +5452,7 @@ function enhanceWithRules(prompt, context, start = Date.now()) {
|
|
|
4971
5452
|
additions.push(...ragAdditions.additions);
|
|
4972
5453
|
}
|
|
4973
5454
|
} catch (err) {
|
|
4974
|
-
|
|
5455
|
+
logger13.debug({ error: err.message }, "RAG enhancement skipped");
|
|
4975
5456
|
}
|
|
4976
5457
|
return {
|
|
4977
5458
|
enhanced,
|
|
@@ -5032,7 +5513,7 @@ async function enhancePromptWithRAG(prompt, context) {
|
|
|
5032
5513
|
}
|
|
5033
5514
|
}
|
|
5034
5515
|
} catch (err) {
|
|
5035
|
-
|
|
5516
|
+
logger13.warn({ error: err.message }, "RAG enhancement failed");
|
|
5036
5517
|
}
|
|
5037
5518
|
return {
|
|
5038
5519
|
enhanced,
|
|
@@ -5093,7 +5574,7 @@ function addComponentHints(prompt, componentType, additions) {
|
|
|
5093
5574
|
}
|
|
5094
5575
|
return prompt;
|
|
5095
5576
|
}
|
|
5096
|
-
var
|
|
5577
|
+
var logger14 = pino({ name: "style-recommender" });
|
|
5097
5578
|
var INDUSTRY_STYLES = {
|
|
5098
5579
|
fintech: {
|
|
5099
5580
|
primaryColor: "#0F172A",
|
|
@@ -5197,7 +5678,7 @@ async function recommendStyle(prompt, context) {
|
|
|
5197
5678
|
try {
|
|
5198
5679
|
return await recommendWithRAG(prompt, context, db2);
|
|
5199
5680
|
} catch (err) {
|
|
5200
|
-
|
|
5681
|
+
logger14.warn({ error: err.message }, "RAG style recommendation failed, using heuristic");
|
|
5201
5682
|
}
|
|
5202
5683
|
}
|
|
5203
5684
|
return recommendWithHeuristic(prompt, context);
|
|
@@ -5444,7 +5925,7 @@ function extractMetadata(description, code) {
|
|
|
5444
5925
|
accessibilityNotes
|
|
5445
5926
|
};
|
|
5446
5927
|
}
|
|
5447
|
-
var
|
|
5928
|
+
var logger15 = pino({ name: "visual-styles" });
|
|
5448
5929
|
var styles = [];
|
|
5449
5930
|
var initialized = false;
|
|
5450
5931
|
function registerVisualStyle(style) {
|
|
@@ -5476,7 +5957,7 @@ function applyVisualStyle(snippet, style) {
|
|
|
5476
5957
|
}
|
|
5477
5958
|
}
|
|
5478
5959
|
if (droppedModifiers.length > 0) {
|
|
5479
|
-
|
|
5960
|
+
logger15.warn(
|
|
5480
5961
|
{ styleId: style.id, snippetId: snippet.id, droppedModifiers },
|
|
5481
5962
|
"Some style modifiers could not be applied - no matching role in snippet"
|
|
5482
5963
|
);
|
|
@@ -5662,7 +6143,7 @@ function initializeStyles() {
|
|
|
5662
6143
|
registerVisualStyle(style);
|
|
5663
6144
|
}
|
|
5664
6145
|
initialized = true;
|
|
5665
|
-
|
|
6146
|
+
logger15.debug("Visual styles initialized");
|
|
5666
6147
|
}
|
|
5667
6148
|
|
|
5668
6149
|
// src/registry/micro-interactions/entrance-fade.ts
|
|
@@ -6979,7 +7460,7 @@ function initializeInteractions() {
|
|
|
6979
7460
|
]);
|
|
6980
7461
|
initialized2 = true;
|
|
6981
7462
|
}
|
|
6982
|
-
|
|
7463
|
+
pino({ name: "prompt-classifier" });
|
|
6983
7464
|
var NEW_TASK_CONFIDENCE = 0.8;
|
|
6984
7465
|
var PRAISE_SCORE = 2;
|
|
6985
7466
|
var PRAISE_CONFIDENCE = 0.9;
|
|
@@ -7277,7 +7758,7 @@ function fingerprint(code) {
|
|
|
7277
7758
|
function isPromotable(pattern) {
|
|
7278
7759
|
return pattern.frequency >= 3 && pattern.avgScore > 0.5 && !pattern.promoted;
|
|
7279
7760
|
}
|
|
7280
|
-
var
|
|
7761
|
+
var logger16 = pino({ name: "feedback-tracker" });
|
|
7281
7762
|
var lastGeneration = /* @__PURE__ */ new Map();
|
|
7282
7763
|
function recordGeneration(gen, generatedCode, db2, promptContext) {
|
|
7283
7764
|
const codeHash = createHash("sha256").update(generatedCode).digest("hex").slice(0, 16);
|
|
@@ -7297,7 +7778,7 @@ function recordGeneration(gen, generatedCode, db2, promptContext) {
|
|
|
7297
7778
|
timestamp: Date.now()
|
|
7298
7779
|
};
|
|
7299
7780
|
storeFeedback(implicitFeedback, db2);
|
|
7300
|
-
|
|
7781
|
+
logger16.debug(
|
|
7301
7782
|
{ generationId: prev.id, score: implicitFeedback.score, signals: classification.signals.length },
|
|
7302
7783
|
"Implicit feedback recorded"
|
|
7303
7784
|
);
|
|
@@ -7322,7 +7803,7 @@ function recordExplicitFeedback(generationId, rating, db2, comment) {
|
|
|
7322
7803
|
timestamp: Date.now()
|
|
7323
7804
|
};
|
|
7324
7805
|
storeFeedback(feedback, db2);
|
|
7325
|
-
|
|
7806
|
+
logger16.info({ generationId, rating }, "Explicit feedback recorded");
|
|
7326
7807
|
return feedback;
|
|
7327
7808
|
}
|
|
7328
7809
|
function getAggregateScore(componentType, db2) {
|
|
@@ -7390,7 +7871,7 @@ function storeFeedback(feedback, db2) {
|
|
|
7390
7871
|
function upsertPattern(hash, skeleton, code, db2) {
|
|
7391
7872
|
const existing = db2.prepare("SELECT source_id FROM embeddings WHERE source_id = ? AND source_type = ?").get(hash, "description");
|
|
7392
7873
|
if (!existing) {
|
|
7393
|
-
|
|
7874
|
+
logger16.debug({ hash, skeleton }, "New code pattern detected");
|
|
7394
7875
|
}
|
|
7395
7876
|
}
|
|
7396
7877
|
function clearSessionCache() {
|
|
@@ -7471,7 +7952,7 @@ function getFeedbackBoost(componentType, db2) {
|
|
|
7471
7952
|
const boost = normalizedScore * FEEDBACK_BOOST_FACTOR;
|
|
7472
7953
|
return Math.max(0.7, Math.min(1.3, 1 + boost));
|
|
7473
7954
|
}
|
|
7474
|
-
var
|
|
7955
|
+
var logger17 = pino({ name: "pattern-promotion" });
|
|
7475
7956
|
var PATTERNS_TABLE = `
|
|
7476
7957
|
CREATE TABLE IF NOT EXISTS code_patterns (
|
|
7477
7958
|
id TEXT PRIMARY KEY,
|
|
@@ -7547,7 +8028,7 @@ function getPromotablePatternsFromDb(db2) {
|
|
|
7547
8028
|
}
|
|
7548
8029
|
function promotePattern(pattern, componentType, category, db2) {
|
|
7549
8030
|
if (!isPromotable(pattern)) {
|
|
7550
|
-
|
|
8031
|
+
logger17.debug({ patternId: pattern.id }, "Pattern not eligible for promotion");
|
|
7551
8032
|
return null;
|
|
7552
8033
|
}
|
|
7553
8034
|
const snippet = {
|
|
@@ -7586,13 +8067,13 @@ function promotePattern(pattern, componentType, category, db2) {
|
|
|
7586
8067
|
Math.floor(Date.now() / 1e3),
|
|
7587
8068
|
pattern.id
|
|
7588
8069
|
);
|
|
7589
|
-
|
|
8070
|
+
logger17.info(
|
|
7590
8071
|
{ patternId: pattern.id, snippetId: snippet.id, freq: pattern.frequency, score: pattern.avgScore },
|
|
7591
8072
|
"Pattern promoted to registry snippet"
|
|
7592
8073
|
);
|
|
7593
8074
|
return snippet;
|
|
7594
8075
|
} catch (err) {
|
|
7595
|
-
|
|
8076
|
+
logger17.error({ err, patternId: pattern.id }, "Failed to promote pattern");
|
|
7596
8077
|
return null;
|
|
7597
8078
|
}
|
|
7598
8079
|
}
|
|
@@ -7607,7 +8088,7 @@ function runPromotionCycle(db2) {
|
|
|
7607
8088
|
if (result) promoted++;
|
|
7608
8089
|
}
|
|
7609
8090
|
if (promoted > 0) {
|
|
7610
|
-
|
|
8091
|
+
logger17.info({ promoted, candidates: candidates.length }, "Promotion cycle complete");
|
|
7611
8092
|
}
|
|
7612
8093
|
return promoted;
|
|
7613
8094
|
}
|
|
@@ -7709,7 +8190,7 @@ function validateSnippetStrict(snippet) {
|
|
|
7709
8190
|
}
|
|
7710
8191
|
|
|
7711
8192
|
// src/registry/component-registry/index.ts
|
|
7712
|
-
var
|
|
8193
|
+
var logger18 = pino({ name: "component-registry" });
|
|
7713
8194
|
var registry = [];
|
|
7714
8195
|
var moodAffinities = {
|
|
7715
8196
|
bold: ["energetic", "premium"],
|
|
@@ -7727,27 +8208,27 @@ var moodAffinities = {
|
|
|
7727
8208
|
};
|
|
7728
8209
|
function registerSnippet(snippet) {
|
|
7729
8210
|
if (!snippet?.id || typeof snippet.id !== "string") {
|
|
7730
|
-
|
|
8211
|
+
logger18.warn({ snippet }, "Invalid snippet: missing or invalid id");
|
|
7731
8212
|
return;
|
|
7732
8213
|
}
|
|
7733
8214
|
if (!snippet.type || typeof snippet.type !== "string" || !snippet.type.trim()) {
|
|
7734
|
-
|
|
8215
|
+
logger18.warn({ snippet }, "Invalid snippet: missing or invalid type");
|
|
7735
8216
|
return;
|
|
7736
8217
|
}
|
|
7737
8218
|
if (!snippet.variant || typeof snippet.variant !== "string" || !snippet.variant.trim()) {
|
|
7738
|
-
|
|
8219
|
+
logger18.warn({ snippet }, "Invalid snippet: missing or invalid variant");
|
|
7739
8220
|
return;
|
|
7740
8221
|
}
|
|
7741
8222
|
if (!Array.isArray(snippet.tags)) {
|
|
7742
|
-
|
|
8223
|
+
logger18.warn({ snippet }, "Invalid snippet: tags must be an array");
|
|
7743
8224
|
return;
|
|
7744
8225
|
}
|
|
7745
8226
|
const validation = validateSnippet(snippet);
|
|
7746
8227
|
if (!validation.valid) {
|
|
7747
|
-
|
|
8228
|
+
logger18.warn({ id: snippet.id, errors: validation.errors }, "Snippet failed quality validation");
|
|
7748
8229
|
}
|
|
7749
8230
|
if (validation.warnings.length > 0) {
|
|
7750
|
-
|
|
8231
|
+
logger18.debug({ id: snippet.id, warnings: validation.warnings }, "Snippet quality warnings");
|
|
7751
8232
|
}
|
|
7752
8233
|
const normalized = {
|
|
7753
8234
|
...snippet,
|
|
@@ -7757,19 +8238,19 @@ function registerSnippet(snippet) {
|
|
|
7757
8238
|
};
|
|
7758
8239
|
const exists = registry.findIndex((s) => s.id === normalized.id);
|
|
7759
8240
|
if (exists >= 0) {
|
|
7760
|
-
|
|
8241
|
+
logger18.warn(
|
|
7761
8242
|
{ id: normalized.id, existingSource: registry[exists].name, newSource: normalized.name },
|
|
7762
8243
|
"Overwriting existing snippet with duplicate id"
|
|
7763
8244
|
);
|
|
7764
8245
|
registry[exists] = normalized;
|
|
7765
8246
|
} else {
|
|
7766
8247
|
registry.push(normalized);
|
|
7767
|
-
|
|
8248
|
+
logger18.debug({ id: normalized.id, name: normalized.name }, "Registered new snippet");
|
|
7768
8249
|
}
|
|
7769
8250
|
}
|
|
7770
8251
|
function clearRegistry() {
|
|
7771
8252
|
registry.length = 0;
|
|
7772
|
-
|
|
8253
|
+
logger18.debug("Registry cleared");
|
|
7773
8254
|
}
|
|
7774
8255
|
function registerSnippets(snippets2) {
|
|
7775
8256
|
for (const snippet of snippets2) {
|
|
@@ -7871,7 +8352,7 @@ function getByIndustry(industry) {
|
|
|
7871
8352
|
function applyVisualStyle2(snippet, styleId) {
|
|
7872
8353
|
const style = getVisualStyle(styleId);
|
|
7873
8354
|
if (!style) {
|
|
7874
|
-
|
|
8355
|
+
logger18.warn(
|
|
7875
8356
|
{ styleId, snippetId: snippet.id, snippetType: snippet.type },
|
|
7876
8357
|
"Visual style not found in applyVisualStyle, returning original snippet"
|
|
7877
8358
|
);
|
|
@@ -7900,7 +8381,7 @@ ${anim.keyframes}`;
|
|
|
7900
8381
|
} else {
|
|
7901
8382
|
const rootKey = "root" in newTailwindClasses ? "root" : "container" in newTailwindClasses ? "container" : keys[0];
|
|
7902
8383
|
if (rootKey !== "root" && rootKey !== "container") {
|
|
7903
|
-
|
|
8384
|
+
logger18.warn({ snippetId: snippet.id, animationIds, rootKey }, "No root/container key found, using first key");
|
|
7904
8385
|
}
|
|
7905
8386
|
newTailwindClasses[rootKey] = `${newTailwindClasses[rootKey]} ${additionalClasses.join(" ")}`.trim();
|
|
7906
8387
|
}
|
|
@@ -7957,7 +8438,7 @@ function getBestMatchWithFeedback(type, options, db2) {
|
|
|
7957
8438
|
return boosted[0].snippet;
|
|
7958
8439
|
}
|
|
7959
8440
|
} catch (err) {
|
|
7960
|
-
|
|
8441
|
+
logger18.error({ err, type }, "Failed to apply feedback boost, falling back to base search");
|
|
7961
8442
|
}
|
|
7962
8443
|
}
|
|
7963
8444
|
const results = searchComponents({
|
|
@@ -7976,13 +8457,13 @@ function triggerPatternPromotion(db2) {
|
|
|
7976
8457
|
const promoted = runPromotionCycle(db2);
|
|
7977
8458
|
return promoted;
|
|
7978
8459
|
} catch (err) {
|
|
7979
|
-
|
|
8460
|
+
logger18.warn({ error: err }, "Pattern promotion failed");
|
|
7980
8461
|
return 0;
|
|
7981
8462
|
}
|
|
7982
8463
|
}
|
|
7983
8464
|
|
|
7984
8465
|
// src/ml/design-to-training-data.ts
|
|
7985
|
-
var
|
|
8466
|
+
var logger19 = pino({ name: "design-to-training-data" });
|
|
7986
8467
|
function storeDesignLearning(analysis, generatedCode, componentName, framework, db2) {
|
|
7987
8468
|
const result = {
|
|
7988
8469
|
snippetsCreated: 0,
|
|
@@ -7997,12 +8478,12 @@ function storeDesignLearning(analysis, generatedCode, componentName, framework,
|
|
|
7997
8478
|
registerSnippet(snippet);
|
|
7998
8479
|
result.snippetsCreated++;
|
|
7999
8480
|
}
|
|
8000
|
-
|
|
8481
|
+
logger19.info(
|
|
8001
8482
|
{ count: snippets2.length, qualityScore: analysis.qualityScore },
|
|
8002
8483
|
"Component snippets created from design analysis"
|
|
8003
8484
|
);
|
|
8004
8485
|
} catch (err) {
|
|
8005
|
-
|
|
8486
|
+
logger19.error({ err }, "Failed to convert design to component snippets");
|
|
8006
8487
|
}
|
|
8007
8488
|
}
|
|
8008
8489
|
const feedbackEntries = generateFeedbackEntries(analysis, componentName, db2);
|
|
@@ -8010,7 +8491,7 @@ function storeDesignLearning(analysis, generatedCode, componentName, framework,
|
|
|
8010
8491
|
const patterns = detectAndStorePatterns(analysis, generatedCode, db2);
|
|
8011
8492
|
result.patternsDetected = patterns;
|
|
8012
8493
|
result.summary = generateSummary(analysis, result);
|
|
8013
|
-
|
|
8494
|
+
logger19.info(result, "Design learning stored successfully");
|
|
8014
8495
|
return result;
|
|
8015
8496
|
}
|
|
8016
8497
|
function convertToComponentSnippets(analysis, generatedCode, componentName, _framework) {
|
|
@@ -8085,7 +8566,7 @@ function generateFeedbackEntries(analysis, componentName, db2) {
|
|
|
8085
8566
|
);
|
|
8086
8567
|
count++;
|
|
8087
8568
|
}
|
|
8088
|
-
|
|
8569
|
+
logger19.info({ count, score }, "Feedback entries created from design analysis");
|
|
8089
8570
|
return count;
|
|
8090
8571
|
}
|
|
8091
8572
|
function detectAndStorePatterns(analysis, generatedCode, db2) {
|
|
@@ -8122,7 +8603,7 @@ function detectAndStorePatterns(analysis, generatedCode, db2) {
|
|
|
8122
8603
|
);
|
|
8123
8604
|
count++;
|
|
8124
8605
|
}
|
|
8125
|
-
|
|
8606
|
+
logger19.info({ count }, "Code patterns stored from design analysis");
|
|
8126
8607
|
return count;
|
|
8127
8608
|
}
|
|
8128
8609
|
function generateSummary(analysis, result) {
|
|
@@ -10423,7 +10904,7 @@ TODO: Implement HTML project generation.`
|
|
|
10423
10904
|
};
|
|
10424
10905
|
|
|
10425
10906
|
// src/generators/generator-factory.ts
|
|
10426
|
-
var
|
|
10907
|
+
var logger20 = createLogger("generator-factory");
|
|
10427
10908
|
var GeneratorFactory = class _GeneratorFactory {
|
|
10428
10909
|
static instance;
|
|
10429
10910
|
generators = /* @__PURE__ */ new Map();
|
|
@@ -10449,7 +10930,7 @@ var GeneratorFactory = class _GeneratorFactory {
|
|
|
10449
10930
|
registerGenerator(framework, generatorClass) {
|
|
10450
10931
|
this.generators.set(framework, generatorClass);
|
|
10451
10932
|
this.instances.delete(framework);
|
|
10452
|
-
|
|
10933
|
+
logger20.info(`Registered generator for framework: ${framework}`);
|
|
10453
10934
|
}
|
|
10454
10935
|
/**
|
|
10455
10936
|
* Create a generator instance for the specified framework
|
|
@@ -10466,7 +10947,7 @@ var GeneratorFactory = class _GeneratorFactory {
|
|
|
10466
10947
|
}
|
|
10467
10948
|
const instance = new GeneratorClass(framework);
|
|
10468
10949
|
this.instances.set(framework, instance);
|
|
10469
|
-
|
|
10950
|
+
logger20.info(`Created generator instance for framework: ${framework}`);
|
|
10470
10951
|
return instance;
|
|
10471
10952
|
}
|
|
10472
10953
|
/**
|
|
@@ -10536,7 +11017,7 @@ var GeneratorFactory = class _GeneratorFactory {
|
|
|
10536
11017
|
*/
|
|
10537
11018
|
clearInstances() {
|
|
10538
11019
|
this.instances.clear();
|
|
10539
|
-
|
|
11020
|
+
logger20.info("Cleared all generator instances");
|
|
10540
11021
|
}
|
|
10541
11022
|
/**
|
|
10542
11023
|
* Clear instance for a specific framework
|
|
@@ -10544,7 +11025,7 @@ var GeneratorFactory = class _GeneratorFactory {
|
|
|
10544
11025
|
*/
|
|
10545
11026
|
clearInstance(framework) {
|
|
10546
11027
|
this.instances.delete(framework);
|
|
10547
|
-
|
|
11028
|
+
logger20.info(`Cleared generator instance for framework: ${framework}`);
|
|
10548
11029
|
}
|
|
10549
11030
|
/**
|
|
10550
11031
|
* Unregister a generator
|
|
@@ -10553,7 +11034,7 @@ var GeneratorFactory = class _GeneratorFactory {
|
|
|
10553
11034
|
unregisterGenerator(framework) {
|
|
10554
11035
|
this.generators.delete(framework);
|
|
10555
11036
|
this.instances.delete(framework);
|
|
10556
|
-
|
|
11037
|
+
logger20.info(`Unregistered generator for framework: ${framework}`);
|
|
10557
11038
|
}
|
|
10558
11039
|
/**
|
|
10559
11040
|
* Get default design context
|
|
@@ -10621,14 +11102,14 @@ var GeneratorFactory = class _GeneratorFactory {
|
|
|
10621
11102
|
* Register default generators for all supported frameworks
|
|
10622
11103
|
*/
|
|
10623
11104
|
registerDefaultGenerators() {
|
|
10624
|
-
|
|
11105
|
+
logger20.info("Registering default generators");
|
|
10625
11106
|
this.registerGenerator("react", ReactGenerator);
|
|
10626
11107
|
this.registerGenerator("vue", VueGenerator);
|
|
10627
11108
|
this.registerGenerator("svelte", SvelteGenerator);
|
|
10628
11109
|
this.registerGenerator("angular", AngularGenerator);
|
|
10629
11110
|
this.registerGenerator("html", HtmlGenerator);
|
|
10630
11111
|
this.registerGenerator("nextjs", ReactGenerator);
|
|
10631
|
-
|
|
11112
|
+
logger20.info(`Registered ${this.getSupportedFrameworks().length} framework generators`);
|
|
10632
11113
|
}
|
|
10633
11114
|
};
|
|
10634
11115
|
function generateComponent(framework, componentType, props, designContext, componentLibrary) {
|
|
@@ -34560,7 +35041,7 @@ function initializePacks() {
|
|
|
34560
35041
|
registerPack(startupLandingPack);
|
|
34561
35042
|
registerPack(aiChatAppPack);
|
|
34562
35043
|
}
|
|
34563
|
-
var
|
|
35044
|
+
var logger21 = pino({ name: "registry-init" });
|
|
34564
35045
|
var initialized3 = false;
|
|
34565
35046
|
function initializeRegistry() {
|
|
34566
35047
|
if (initialized3) return;
|
|
@@ -34575,14 +35056,14 @@ function initializeRegistry() {
|
|
|
34575
35056
|
registerOrganisms();
|
|
34576
35057
|
const staticSnippets = getAllSnippets();
|
|
34577
35058
|
seedComponents(staticSnippets, db2);
|
|
34578
|
-
|
|
35059
|
+
logger21.info({ count: staticSnippets.length }, "Seeded DB from static files");
|
|
34579
35060
|
}
|
|
34580
35061
|
clearRegistry();
|
|
34581
35062
|
const dbSnippets = getAllComponents(db2);
|
|
34582
35063
|
registerSnippets(dbSnippets);
|
|
34583
|
-
|
|
35064
|
+
logger21.info({ count: dbSnippets.length }, "Loaded in-memory registry from DB");
|
|
34584
35065
|
} catch (err) {
|
|
34585
|
-
|
|
35066
|
+
logger21.warn({ err }, "DB unavailable, falling back to static files");
|
|
34586
35067
|
clearRegistry();
|
|
34587
35068
|
registerAtoms();
|
|
34588
35069
|
registerMolecules();
|
|
@@ -34591,12 +35072,12 @@ function initializeRegistry() {
|
|
|
34591
35072
|
try {
|
|
34592
35073
|
initializeCompositions();
|
|
34593
35074
|
} catch (err) {
|
|
34594
|
-
|
|
35075
|
+
logger21.warn({ err }, "Compositions init failed; page templates still work");
|
|
34595
35076
|
}
|
|
34596
35077
|
try {
|
|
34597
35078
|
initializePacks();
|
|
34598
35079
|
} catch (err) {
|
|
34599
|
-
|
|
35080
|
+
logger21.warn({ err }, "Packs init failed; template packs still available");
|
|
34600
35081
|
}
|
|
34601
35082
|
initialized3 = true;
|
|
34602
35083
|
}
|
|
@@ -38495,7 +38976,7 @@ var ARTIFACTS_SCHEMA = `
|
|
|
38495
38976
|
`;
|
|
38496
38977
|
|
|
38497
38978
|
// src/artifacts/artifact-store.ts
|
|
38498
|
-
var
|
|
38979
|
+
var logger22 = pino({ name: "artifact-store" });
|
|
38499
38980
|
var schemaInitialized = false;
|
|
38500
38981
|
function ensureSchema(db2) {
|
|
38501
38982
|
if (schemaInitialized) return;
|
|
@@ -38529,7 +39010,7 @@ function storeArtifact(artifact, db2) {
|
|
|
38529
39010
|
artifact.inspirationSources ? JSON.stringify(artifact.inspirationSources) : null,
|
|
38530
39011
|
artifact.createdAt
|
|
38531
39012
|
);
|
|
38532
|
-
|
|
39013
|
+
logger22.debug({ id: artifact.id, type: artifact.type }, "Artifact stored");
|
|
38533
39014
|
}
|
|
38534
39015
|
function getArtifact(id, db2) {
|
|
38535
39016
|
ensureSchema(db2);
|
|
@@ -38617,7 +39098,7 @@ function hydrateArtifact(row) {
|
|
|
38617
39098
|
createdAt: row.created_at
|
|
38618
39099
|
};
|
|
38619
39100
|
}
|
|
38620
|
-
var
|
|
39101
|
+
var logger23 = pino({ name: "learning-loop" });
|
|
38621
39102
|
var PROMOTION_QUALITY_THRESHOLD = 7;
|
|
38622
39103
|
var PROMOTION_FEEDBACK_THRESHOLD = 1;
|
|
38623
39104
|
var MIN_ARTIFACTS_FOR_STATS = 5;
|
|
@@ -38635,7 +39116,7 @@ function recordGeneratedArtifact(prompt, code, type, db2, options) {
|
|
|
38635
39116
|
createdAt: Date.now()
|
|
38636
39117
|
};
|
|
38637
39118
|
storeArtifact(artifact, db2);
|
|
38638
|
-
|
|
39119
|
+
logger23.info({ id: artifact.id, type }, "Generation recorded");
|
|
38639
39120
|
return artifact;
|
|
38640
39121
|
}
|
|
38641
39122
|
function getPromotionCandidates(db2) {
|
|
@@ -40356,7 +40837,7 @@ function applyDesignContextToPattern(content, designContext, customizations) {
|
|
|
40356
40837
|
}
|
|
40357
40838
|
|
|
40358
40839
|
// src/component-libraries/shadcn/index.ts
|
|
40359
|
-
var
|
|
40840
|
+
var logger24 = createLogger("shadcn");
|
|
40360
40841
|
function setupShadcnProject(options) {
|
|
40361
40842
|
const files = [];
|
|
40362
40843
|
const setupFiles = generateShadcnSetup(options.framework, options.projectName, void 0, []);
|
|
@@ -40371,7 +40852,7 @@ function setupShadcnProject(options) {
|
|
|
40371
40852
|
);
|
|
40372
40853
|
files.push(...componentFiles);
|
|
40373
40854
|
} catch (error) {
|
|
40374
|
-
|
|
40855
|
+
logger24.warn({ error }, `Failed to generate component ${componentName}:`);
|
|
40375
40856
|
}
|
|
40376
40857
|
});
|
|
40377
40858
|
}
|
|
@@ -40385,7 +40866,7 @@ function setupShadcnProject(options) {
|
|
|
40385
40866
|
);
|
|
40386
40867
|
files.push(...patternFiles);
|
|
40387
40868
|
} catch (error) {
|
|
40388
|
-
|
|
40869
|
+
logger24.warn({ error }, `Failed to generate pattern ${patternName}:`);
|
|
40389
40870
|
}
|
|
40390
40871
|
});
|
|
40391
40872
|
}
|
|
@@ -41934,6 +42415,6 @@ async function retry(fn, maxAttempts = 3, delay = 1e3) {
|
|
|
41934
42415
|
throw lastError;
|
|
41935
42416
|
}
|
|
41936
42417
|
|
|
41937
|
-
export { ANIMATION_PRESETS, AngularGenerator, BaseGenerator, COLOR_SYSTEMS, COMPONENT_LIBRARIES, DEFAULT_COLOR_SYSTEM, DEFAULT_CONTEXT, DEFAULT_DESIGN_CONTEXT, DEFAULT_FONT_PAIRING, DEFAULT_LORA_CONFIG, DEFAULT_PRESET, FONT_PAIRINGS, GeneratorFactory, HtmlGenerator, ICON_LIBRARIES, INSPIRATION_SOURCES, LAYOUT_PATTERNS, PRESETS, ReactGenerator, SPACING_SYSTEM, SvelteGenerator, TYPE_SCALE, VueGenerator, applyVisualStyle2 as applyVisualStyle, brandToDesignContext, buildPromptEnhancerData, buildQualityScorerData, buildStyleRecommenderData, cancelTrainingJob, capitalize, checkTrainingReadiness, classifyPromptPair, classifyPromptText, cleanJsxSyntax, clearAllMicroInteractions, clearCompositions, clearHistory as clearDiversityHistory, clearRegistry, clearSessionCache, closeDatabase, composePageFromTemplate, composeSection, configureEmbeddings, configureModelDir, convertPathForFramework, convertStyleObjectToString, cosineSimilarity, createEmbedding, createError, createLogger, createTrainingJob, customizeTemplate, deleteArtifact, deleteEmbeddings, designContextStore, embed, embedBatch, enhancePrompt, enhancePromptWithRAG, enhanceWithRules, ensureDirectories, ensurePatternsTable, escapeHtml, exportForAdapter, exportRawExamples, exportTrainingData, expressApiTemplate, extractDesignPatterns, extractSkeleton, feedbackBoostedSearch, findBestComposition, findSimilar, fingerprint, fullstackMonoTemplate, generateArtifactId, generateComponent, generateComponentFromLibrary, generateRandomId, getAdapterPath, getAggregateScore, getAllCompositions, getAllInteractions, getAllJobStatuses, getAllPacks, getAllSnippets, getAllTemplates, getAnimationsByCategory, getArtifact, getArtifactCount, getAvailableComponentLibraries, getAvailableComponentsForLibrary, getAvailablePatternsForLibrary, getAvailableTypes, getBaseDir, getBestMatch, getBestMatchWithFeedback, getByCategory, getByIndustry, getByMood, getColorSystem, getColorSystemsByMood, getComponentLibrariesForFramework, getComponentLibrary, getComposition, getConfig, getDatabase, getDefaultIconLibrary, getDiskUsage, getEmbedding, getEmbeddingConfig, getEmbeddingCount, getFallbackDesignReference, getFeedbackBoost, getFeedbackCount, getFeedbackStats, getFileExtension, getFileName, getFontPairing, getFontPairingsByMood, getInspirationByCategory, getInspirationByPriority, getInteractionsByCategory, getLatestJobStatus, getLayoutPattern, getLayoutPatternsByUseCase, getLearningStats, getMicroInteraction, getModelDownloadUrl, getModelPath, getModelPaths, getPack, getPatternStats, getPreset, getPrimaryDesignReference, getPromotablePatternsFromDb, getPromotionCandidates, getRecentArtifacts, getRecommendations, getRecommendedLibrary, getRegistrySize, getSimilarArtifacts, getSnippetById, getTemplate, getTopArtifacts, getTrainingDataPath, getTrainingSummary, getVariants, groupBy, hasEnoughData, hashSkeleton, htmlToJsxAttributes, includesCaseInsensitive, initializeBackendRegistry, initializeInteractions, initializeRegistry, injectAnimations, isAdapterAvailable, isArray, isDuplicateConsecutive, isFunction, isLikelyAccepted, isModelAvailable, isModelLoaded, isNetworkError, isNumber, isObject, isPromotable, isString, isTraining, isValidComponentName, isValidEmail, isValidHexColor, isValidProjectName, isValidUrl, jsxToHtml, jsxToHtmlAttributes, jsxToSvelte, listAdapters, listModels, listPresets, loadConfig, loadEmbeddings,
|
|
42418
|
+
export { ANIMATION_PRESETS, AngularGenerator, AnthropicProvider, BaseGenerator, COLOR_SYSTEMS, COMPONENT_LIBRARIES, DEFAULT_COLOR_SYSTEM, DEFAULT_CONTEXT, DEFAULT_DESIGN_CONTEXT, DEFAULT_FONT_PAIRING, DEFAULT_LORA_CONFIG, DEFAULT_MAX_TOKENS, DEFAULT_PRESET, DEFAULT_TEMPERATURE, DEFAULT_TIMEOUT_MS, FONT_PAIRINGS, GeneratorFactory, HtmlGenerator, ICON_LIBRARIES, INSPIRATION_SOURCES, LAYOUT_PATTERNS, OllamaProvider, OpenAIProvider, PRESETS, ReactGenerator, SPACING_SYSTEM, SvelteGenerator, TYPE_SCALE, VueGenerator, applyVisualStyle2 as applyVisualStyle, brandToDesignContext, buildPromptEnhancerData, buildQualityScorerData, buildStyleRecommenderData, cancelTrainingJob, capitalize, checkTrainingReadiness, classifyPromptPair, classifyPromptText, cleanJsxSyntax, clearAllMicroInteractions, clearCompositions, clearHistory as clearDiversityHistory, clearRegistry, clearSessionCache, closeDatabase, composePageFromTemplate, composeSection, configureEmbeddings, configureModelDir, convertPathForFramework, convertStyleObjectToString, cosineSimilarity, createEmbedding, createError, createLogger, createProvider, createProviderWithFallback, createTrainingJob, customizeTemplate, deleteArtifact, deleteEmbeddings, designContextStore, detectOllama, embed, embedBatch, enhancePrompt, enhancePromptWithRAG, enhanceWithRules, ensureDirectories, ensurePatternsTable, escapeHtml, exportForAdapter, exportRawExamples, exportTrainingData, expressApiTemplate, extractDesignPatterns, extractSkeleton, feedbackBoostedSearch, findBestComposition, findSimilar, fingerprint, fullstackMonoTemplate, generateArtifactId, generateComponent, generateComponentFromLibrary, generateRandomId, getAdapterPath, getAggregateScore, getAllCompositions, getAllInteractions, getAllJobStatuses, getAllPacks, getAllSnippets, getAllTemplates, getAnimationsByCategory, getArtifact, getArtifactCount, getAvailableComponentLibraries, getAvailableComponentsForLibrary, getAvailablePatternsForLibrary, getAvailableTypes, getBaseDir, getBestMatch, getBestMatchWithFeedback, getByCategory, getByIndustry, getByMood, getColorSystem, getColorSystemsByMood, getComponentLibrariesForFramework, getComponentLibrary, getComposition, getConfig, getDatabase, getDefaultIconLibrary, getDiskUsage, getEmbedding, getEmbeddingConfig, getEmbeddingCount, getFallbackDesignReference, getFeedbackBoost, getFeedbackCount, getFeedbackStats, getFileExtension, getFileName, getFontPairing, getFontPairingsByMood, getInspirationByCategory, getInspirationByPriority, getInteractionsByCategory, getLatestJobStatus, getLayoutPattern, getLayoutPatternsByUseCase, getLearningStats, getMicroInteraction, getModelDownloadUrl, getModelPath, getModelPaths, getPack, getPatternStats, getPreset, getPrimaryDesignReference, getPromotablePatternsFromDb, getPromotionCandidates, getPromptEnhancerLLM, getQualityScorerLLM, getRecentArtifacts, getRecommendations, getRecommendedLibrary, getRegistrySize, getSimilarArtifacts, getSnippetById, getTemplate, getTopArtifacts, getTrainingDataPath, getTrainingSummary, getVariants, groupBy, hasEnoughData, hashSkeleton, htmlToJsxAttributes, includesCaseInsensitive, initializeBackendRegistry, initializeInteractions, initializeRegistry, injectAnimations, isAdapterAvailable, isArray, isDuplicateConsecutive, isFunction, isLikelyAccepted, isModelAvailable, isModelLoaded, isNetworkError, isNumber, isObject, isPromotable, isString, isTraining, isValidComponentName, isValidEmail, isValidHexColor, isValidProjectName, isValidUrl, jsxToHtml, jsxToHtmlAttributes, jsxToSvelte, listAdapters, listModels, listPresets, loadConfig, loadEmbeddings, logger, mergeStyles, needsEnhancement, nextAppTemplate, nextSaasTemplate, parseStyleString, pluralize, promotePattern, queryArtifacts, reactEventsToHtml, reactEventsToSvelte, reactSpaTemplate, recommendStyle, recordGeneration2 as recordDiversityGeneration, recordExplicitFeedback, recordGeneratedArtifact, recordGeneration, recordPattern, reduxToolkitPattern as reduxToolkitPatterns, registerComposition, registerInteraction, registerInteractions, registerPack, registerSnippet, registerSnippets, resetSchemaInit, retry, runPromotionCycle, safeJSONParse, sanitizeClassName, scoreQuality, scoreQualityWithRAG, searchBackendSnippets, searchComponents, searchPacks, selectTemplate, semanticSearch, setPromptEnhancerLLM, setQualityScorerLLM, setupComponentLibraryProject, sortBy, startTrainingJob, stateManagementPatterns, storeArtifact, storeDesignLearning, storeEmbedding, storeEmbeddings, suggestDiverseVariant, tanstackQueryPattern as tanstackQueryPatterns, templateList, templates2 as templates, toCamelCase, toKebabCase, toPascalCase, toSnakeCase, triggerPatternPromotion, truncate, unique, unloadModel, updateFeedbackScore, updateJobStatus, updateQualityScore, validateSnippet, validateSnippetStrict, writeJsonl, zustandPatterns };
|
|
41938
42419
|
//# sourceMappingURL=index.js.map
|
|
41939
42420
|
//# sourceMappingURL=index.js.map
|