Spaces:
Running
Running
/** | |
* Copyright (c) 2023 MERCENARIES.AI PTE. LTD. | |
* All rights reserved. | |
*/ | |
import Rete from 'rete'; | |
import { type OmniControl, type OmniIO } from './types.js'; | |
import { WorkflowClientControlManager } from '../WorkflowClientControlManager.js'; | |
class OAIControl31 extends Rete.Control { | |
data: OmniControl; | |
props: { ikey: string }; | |
emitter?: any; | |
constructor(config: OmniControl, control: any, emitter: any) { | |
super(config.name); | |
this.data = JSON.parse(JSON.stringify(config)); | |
this.emitter = emitter; | |
this.props = { ikey: config.name }; | |
// @ts-expect-error | |
this.component = control; | |
if (!control) { | |
console.error('Could not find component for ' + config.controlType); | |
} | |
// handle various types of choices array | |
} | |
async initChoices(): Promise<void> { | |
if (this.data.choices) { | |
const choices = this.data.choices; | |
if (Array.isArray(choices)) { | |
this.data.choices = choices.map(function (v: any) { | |
if (typeof v === 'object') { | |
return v; | |
} else { | |
return { value: v, title: v }; | |
} | |
}); | |
} | |
if (typeof this.data.choices === 'object') { | |
const choices = this.data.choices as { block: any; args: any; map: any; cache?: 'global' | 'user' | 'none' }; | |
if (choices.block) { | |
let list: any = ['Internal Error Fetching choices']; | |
try { | |
list = await (globalThis as any).client.runBlock({ | |
block: choices.block, | |
args: choices.args || {}, | |
cache: choices.cache ?? choices.map.cache ?? 'none' | |
}); | |
} catch (ex: any) { | |
console.error('Could not load choices for ' + this.data.name + ': ' + ex.message); | |
list = ['ERROR: ' + ex.message, this.data.default]; | |
} | |
if (list.error) { | |
console.error('Could not load choices for ' + this.data.name + ': ' + list.error.message); | |
list = ['ERROR: ' + list.error, this.data.default]; | |
} | |
const root = choices.map?.root; | |
if (root && list[root] != null && Array.isArray(list[root])) { | |
list = list[root]; | |
} | |
if (!Array.isArray(list)) { | |
list = Array.from(Object.values(list)); | |
} | |
interface Choice { | |
value: any; | |
title: string; | |
description: string; | |
} | |
const filterRegex = new RegExp(choices.map?.filter?.value); | |
this.data.choices = list | |
.map((v: any) => { | |
let e: Choice = { value: v, title: v, description: '' }; | |
if (choices.map?.value && choices.map?.title) { | |
e = { | |
value: v[choices.map.value], | |
title: v[choices.map.title], | |
description: v[choices.map.description] || '' | |
}; | |
} | |
return e; | |
}) | |
.filter((e: Choice) => e.value && filterRegex.test(e.title)) | |
.sort((a: Choice, b: Choice) => b.title.localeCompare(a.title)); | |
} | |
} | |
} | |
} | |
get dataType() { | |
return this.data.dataType ?? 'string'; | |
} | |
get controlType() { | |
console.log('Access to field controlType on control'); | |
return this.data.controlType; | |
} | |
get type() { | |
console.trace(); | |
console.log('Access to deprecated field type on control'); | |
return this.data.dataType; | |
} | |
get opts() { | |
return this.data; | |
} | |
get displays() { | |
return this.data.displays ?? null; | |
} | |
get minimum() { | |
return this.data.minimum; | |
} | |
get description() { | |
return this.data.description; | |
} | |
get title() { | |
return this.data.title ?? this.data.name; | |
} | |
get maximum() { | |
return this.data.maximum; | |
} | |
get customData() { | |
return this.data.customData ?? {}; | |
} | |
custom(key: string) { | |
return this.data.customData?.[key] ?? null; | |
} | |
get choices() { | |
return this.data.choices ?? ['(default)']; | |
} | |
get readonly() { | |
return this.data.readonly ?? false; | |
} | |
_formatValue(val: any) { | |
if (val) { | |
if ((this.dataType === 'number' || this.dataType == 'float') && typeof val === 'string') { | |
val = parseFloat(val); | |
} else if (this.dataType === 'integer' && typeof val === 'string') { | |
val = parseFloat(val); | |
} else if (this.dataType === 'boolean' && typeof val === 'number') { | |
val = val != 0; | |
} else if (this.dataType === 'boolean' && typeof val === 'string') { | |
val = [true, 'true', '1', 'on', 'active'].includes(val.toLowerCase()); | |
} | |
} | |
return val; | |
} | |
setValue(val: any) { | |
// Readonly or 'displays' properties are not settable | |
if (this.displays || this.readonly) { | |
return; | |
} | |
val = this._formatValue(val); | |
this.putData(this.props.ikey, val); | |
// @ts-ignore | |
this.update(); | |
} | |
static async fromControl(ctl: OmniControl, emitter: any): Promise<OAIControl31> { | |
const control = WorkflowClientControlManager.getInstance().get(ctl.controlType); | |
const ret = new OAIControl31(ctl, control, emitter); | |
await ret.initChoices(); | |
return ret; | |
} | |
static async fromIO(ctlType: string, io: OmniIO, emitter: any): Promise<OAIControl31> { | |
const control = { | |
dataType: io.type, | |
controlType: ctlType, | |
name: io.name, | |
title: io.title, | |
choices: io.choices, | |
description: io.description, | |
step: io.step, | |
default: io.default, | |
minimum: io.minimum, | |
maximum: io.maximum, | |
required: io.required, | |
...(io.control || {}) | |
}; | |
const ctl = WorkflowClientControlManager.getInstance().get(ctlType); | |
const ret = new OAIControl31(control, ctl, emitter); | |
await ret.initChoices(); | |
return ret; | |
} | |
} | |
export default OAIControl31; | |