(program: Program, onCall: (func: string, args: unknown[]) => Promise<unknown>)
| 145 | * @returns A `Promise` with the value of the last expression in the program. |
| 146 | */ |
| 147 | export async function evaluateJsonProgram(program: Program, onCall: (func: string, args: unknown[]) => Promise<unknown>) { |
| 148 | const results: unknown[] = []; |
| 149 | for (const expr of program["@steps"]) { |
| 150 | results.push(await evaluate(expr)); |
| 151 | } |
| 152 | return results.length > 0 ? results[results.length - 1] : undefined; |
| 153 | |
| 154 | async function evaluate(expr: unknown): Promise<unknown> { |
| 155 | return typeof expr === "object" && expr !== null ? |
| 156 | await evaluateObject(expr as Record<string, unknown>) : |
| 157 | expr; |
| 158 | } |
| 159 | |
| 160 | async function evaluateObject(obj: Record<string, unknown>) { |
| 161 | if (obj.hasOwnProperty("@ref")) { |
| 162 | const index = obj["@ref"]; |
| 163 | if (typeof index === "number" && index < results.length) { |
| 164 | return results[index]; |
| 165 | } |
| 166 | } |
| 167 | else if (obj.hasOwnProperty("@func")) { |
| 168 | const func = obj["@func"]; |
| 169 | const args = obj.hasOwnProperty("@args") ? obj["@args"] : []; |
| 170 | if (typeof func === "string" && Array.isArray(args)) { |
| 171 | return await onCall(func, await evaluateArray(args)); |
| 172 | } |
| 173 | } |
| 174 | else if (Array.isArray(obj)) { |
| 175 | return evaluateArray(obj); |
| 176 | } |
| 177 | else { |
| 178 | const values = await Promise.all(Object.values(obj).map(evaluate)); |
| 179 | return Object.fromEntries(Object.keys(obj).map((k, i) => [k, values[i]])); |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | function evaluateArray(array: unknown[]) { |
| 184 | return Promise.all(array.map(evaluate)); |
| 185 | } |
| 186 | } |
| 187 | |
| 188 | /** |
| 189 | * Creates an object that can translate natural language requests into simple programs, represented as JSON, that compose |
no test coverage detected
searching dependent graphs…