Files
SnapGo/frontend/wailsjs/go/models.ts
T
mamamiyear 87874e64cf feat: prefer base64 inline image for summary, fall back to S3
Send the screenshot to the multimodal model inline as a base64 data URL
so summarisation no longer requires S3 to be configured or publicly
reachable. Only when the PNG exceeds the provider MaxInlineBytes limit
do we upload to S3, verify the public URL is reachable, and delete the
temporary object once done. Oversized images without S3 now surface a
clear hint instead of a hard S3 requirement.
2026-07-07 13:39:23 +08:00

283 lines
7.6 KiB
TypeScript
Executable File

export namespace application {
export class Point {
x: number;
y: number;
static createFrom(source: any = {}) {
return new Point(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.x = source["x"];
this.y = source["y"];
}
}
export class Annotation {
tool: string;
color: string;
points: Point[];
static createFrom(source: any = {}) {
return new Annotation(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.tool = source["tool"];
this.color = source["color"];
this.points = this.convertValues(source["points"], Point);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
}
export namespace domain {
export class LLMProviderConfig {
label: string;
baseUrl: string;
apiKey: string;
model: string;
maxTokens: number;
temperature: number;
timeoutSecs: number;
maxInlineBytes: number;
static createFrom(source: any = {}) {
return new LLMProviderConfig(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.label = source["label"];
this.baseUrl = source["baseUrl"];
this.apiKey = source["apiKey"];
this.model = source["model"];
this.maxTokens = source["maxTokens"];
this.temperature = source["temperature"];
this.timeoutSecs = source["timeoutSecs"];
this.maxInlineBytes = source["maxInlineBytes"];
}
}
export class LLMConfig {
activeProvider: string;
prompt: string;
providers: Record<string, LLMProviderConfig>;
static createFrom(source: any = {}) {
return new LLMConfig(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.activeProvider = source["activeProvider"];
this.prompt = source["prompt"];
this.providers = this.convertValues(source["providers"], LLMProviderConfig, true);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class SSHConfig {
host: string;
port: number;
user: string;
authMethod: string;
password: string;
pathPrefix: string;
strictHostKey: boolean;
knownHostsPath: string;
connectTimeoutSecs: number;
static createFrom(source: any = {}) {
return new SSHConfig(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.host = source["host"];
this.port = source["port"];
this.user = source["user"];
this.authMethod = source["authMethod"];
this.password = source["password"];
this.pathPrefix = source["pathPrefix"];
this.strictHostKey = source["strictHostKey"];
this.knownHostsPath = source["knownHostsPath"];
this.connectTimeoutSecs = source["connectTimeoutSecs"];
}
}
export class S3Config {
endpoint: string;
region: string;
bucket: string;
accessKeyId: string;
secretAccessKey: string;
pathPrefix: string;
publicUrlBase: string;
usePathStyle: boolean;
static createFrom(source: any = {}) {
return new S3Config(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.endpoint = source["endpoint"];
this.region = source["region"];
this.bucket = source["bucket"];
this.accessKeyId = source["accessKeyId"];
this.secretAccessKey = source["secretAccessKey"];
this.pathPrefix = source["pathPrefix"];
this.publicUrlBase = source["publicUrlBase"];
this.usePathStyle = source["usePathStyle"];
}
}
export class AppConfig {
hotkey: string;
theme: string;
s3: S3Config;
ssh: SSHConfig;
llm: LLMConfig;
static createFrom(source: any = {}) {
return new AppConfig(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.hotkey = source["hotkey"];
this.theme = source["theme"];
this.s3 = this.convertValues(source["s3"], S3Config);
this.ssh = this.convertValues(source["ssh"], SSHConfig);
this.llm = this.convertValues(source["llm"], LLMConfig);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
}
export namespace main {
export class CaptureActionResult {
completed: boolean;
path?: string;
static createFrom(source: any = {}) {
return new CaptureActionResult(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.completed = source["completed"];
this.path = source["path"];
}
}
export class RegionRect {
x: number;
y: number;
w: number;
h: number;
static createFrom(source: any = {}) {
return new RegionRect(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.x = source["x"];
this.y = source["y"];
this.w = source["w"];
this.h = source["h"];
}
}
export class CaptureResult {
rect: RegionRect;
annotations: application.Annotation[];
static createFrom(source: any = {}) {
return new CaptureResult(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.rect = this.convertValues(source["rect"], RegionRect);
this.annotations = this.convertValues(source["annotations"], application.Annotation);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
}