-
Notifications
You must be signed in to change notification settings - Fork 146
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* towards configure support * link to docs * more config * twekas * helper flag * configure mode * configure docs * add responseType, responseSchema to cache key
- Loading branch information
Showing
10 changed files
with
407 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,5 @@ package.json | |
package-lock.json | ||
yarn.lock | ||
**/package.lock | ||
docs/dist/ | ||
docs/distasw/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--- | ||
title: configure | ||
descript: Configure and validate the LLM connections. | ||
sidebar: | ||
order: 4 | ||
--- | ||
|
||
Interactice command to configure and validate the LLM connections. | ||
|
||
```bash | ||
npx genaiscript configure | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import { select, input, confirm, password } from "@inquirer/prompts" | ||
import { MODEL_PROVIDERS } from "../../core/src/constants" | ||
import { resolveLanguageModelConfigurations } from "../../core/src/config" | ||
import { parse } from "dotenv" | ||
import { readFile } from "fs/promises" | ||
import { writeFile } from "fs/promises" | ||
import { runtimeHost } from "../../core/src/host" | ||
import { deleteUndefinedValues } from "../../core/src/cleaners" | ||
import { logInfo, logVerbose, logWarn } from "../../core/src/util" | ||
|
||
export async function configure(options: { provider?: string }) { | ||
while (true) { | ||
const provider = options?.provider | ||
? MODEL_PROVIDERS.find(({ id }) => options.provider === id) | ||
: await select({ | ||
message: "Select a LLM provider to configure", | ||
choices: MODEL_PROVIDERS.map((provider) => ({ | ||
name: provider.id, | ||
value: provider, | ||
description: provider.detail, | ||
})), | ||
}) | ||
if (!provider) break | ||
|
||
logInfo(`configurating ${provider.id} (${provider.detail})`) | ||
logVerbose( | ||
`- docs: https://microsoft.github.io/genaiscript/getting-started/configuration#${provider.id}` | ||
) | ||
while (true) { | ||
const config = await runtimeHost.readConfig() | ||
logVerbose(`- env file: ${config.envFile}`) | ||
const envText = await readFile(config.envFile, "utf-8") | ||
const env = parse(envText) | ||
const conn = ( | ||
await resolveLanguageModelConfigurations(provider.id, { | ||
token: false, | ||
error: true, | ||
models: true, | ||
}) | ||
)?.[0] | ||
if (conn) { | ||
const { error, models, ...rest } = conn | ||
logInfo("") | ||
logInfo( | ||
YAML.stringify( | ||
deleteUndefinedValues({ | ||
configuration: deleteUndefinedValues({ | ||
...rest, | ||
models: models?.length ?? undefined, | ||
}), | ||
}) | ||
) | ||
) | ||
if (error) logWarn(`error: ${error}`) | ||
else logInfo(`configured!`) | ||
} else { | ||
logWarn(`no configuration found`) | ||
} | ||
if (!provider.env) { | ||
logInfo( | ||
`sorry, this provider is not yet configurable through the cli` | ||
) | ||
break | ||
} | ||
const envVars = Object.entries(provider.env) | ||
if (!envVars.length) { | ||
logInfo(`this provider does not have configuration flags`) | ||
break | ||
} | ||
|
||
if (!conn?.error) { | ||
const edit = await confirm({ | ||
message: `do you want to edit the configuration?`, | ||
}) | ||
if (!edit) break | ||
} | ||
for (const ev of envVars) { | ||
const [name, info] = ev | ||
const oldValue = env[name] | ||
let value = oldValue | ||
if (value) { | ||
const edit = await confirm({ | ||
message: `found a value for ${name}, do you want to edit?`, | ||
}) | ||
if (!edit) continue | ||
} | ||
if (info.secret) { | ||
value = await password({ | ||
message: `enter a value for ${name}`, | ||
mask: false, | ||
}) | ||
} else { | ||
value = await input({ | ||
message: `enter a value for ${name} (optional, leave empty to skip)`, | ||
default: value, | ||
required: info.required, | ||
theme: { | ||
validationFailureMode: "keep", | ||
}, | ||
validate: (v) => { | ||
console.log(v) | ||
if (info.format === "url") { | ||
if (v && !URL.canParse(v)) return "invalid url" | ||
} | ||
return true | ||
}, | ||
}) | ||
} | ||
if (value === "") continue | ||
if (value !== oldValue) | ||
await patchEnvFile(config.envFile, name, value) | ||
} | ||
} | ||
} | ||
} | ||
|
||
async function patchEnvFile(filePath: string, key: string, value: string) { | ||
logVerbose(`patching ${filePath}, ${key}`) | ||
|
||
const fileContent = await readFile(filePath, "utf-8") | ||
const lines = fileContent.split("\n") | ||
let found = false | ||
|
||
const updatedLines = lines.map((line) => { | ||
if (line.startsWith(`${key}=`)) { | ||
found = true | ||
return `${key}=${value}` | ||
} | ||
return line | ||
}) | ||
|
||
if (!found) { | ||
updatedLines.push(`${key}=${value}`) | ||
} | ||
|
||
await writeFile(filePath, updatedLines.join("\n"), "utf-8") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.