dexto 1.0.1 → 1.1.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 +14 -12
- package/agents/agent-registry.json +53 -0
- package/agents/database-agent/README.md +35 -0
- package/agents/database-agent/data/example.db +0 -0
- package/agents/database-agent/database-agent-example.sql +98 -0
- package/agents/database-agent/database-agent.yml +116 -0
- package/agents/database-agent/setup-database.sh +64 -0
- package/agents/{agent.yml → default-agent.yml} +1 -1
- package/agents/image-editor-agent/Lenna.webp +0 -0
- package/agents/image-editor-agent/README.md +435 -0
- package/agents/image-editor-agent/image-editor-agent.yml +45 -0
- package/agents/music-agent/README.md +294 -0
- package/agents/music-agent/music-agent.yml +43 -0
- package/agents/product-name-researcher/README.md +98 -0
- package/agents/product-name-researcher/product-name-researcher.yml +161 -0
- package/agents/talk2pdf-agent/README.md +166 -0
- package/agents/talk2pdf-agent/talk2pdf-agent.yml +42 -0
- package/agents/triage-demo/README.md +337 -0
- package/agents/triage-demo/billing-agent.yml +76 -0
- package/agents/triage-demo/docs/billing-policies.md +246 -0
- package/agents/triage-demo/docs/company-overview.md +94 -0
- package/agents/triage-demo/docs/escalation-policies.md +301 -0
- package/agents/triage-demo/docs/product-features.md +253 -0
- package/agents/triage-demo/docs/technical-documentation.md +226 -0
- package/agents/triage-demo/escalation-agent.yml +82 -0
- package/agents/triage-demo/product-info-agent.yml +86 -0
- package/agents/triage-demo/technical-support-agent.yml +71 -0
- package/agents/triage-demo/test-scenarios.md +209 -0
- package/agents/triage-demo/triage-agent.yml +172 -0
- package/dist/src/app/{chunk-M4OZIDPC.js → chunk-CLDYRNV6.js} +7241 -5753
- package/dist/src/app/chunk-DYNVXGAH.js +137 -0
- package/dist/src/app/chunk-PW2PHCHR.js +83 -0
- package/dist/src/app/chunk-R4Q522DR.js +205 -0
- package/dist/src/app/chunk-UXCBS3TR.js +281 -0
- package/dist/src/app/chunk-X6LEX724.js +108 -0
- package/dist/src/app/chunk-Y33BS5SA.js +39 -0
- package/dist/src/app/{cli-confirmation-handler-2APQRKHG.js → cli-confirmation-handler-GJHPLGOL.js} +4 -1
- package/dist/src/app/errors-5MNETGOV.js +8 -0
- package/dist/src/app/index.js +2184 -612
- package/dist/src/app/loader-EFMKWNNQ.js +20 -0
- package/dist/src/app/path-7FT4SZMO.js +23 -0
- package/dist/src/app/{postgres-backend-7HVVW3RL.js → postgres-backend-U5MIIMUY.js} +12 -1
- package/dist/src/app/{redis-backend-2YBZSSSV.js → redis-backend-NGI67ILT.js} +38 -9
- package/dist/src/app/registry-RALMVM3P.js +14 -0
- package/dist/src/app/sqlite-backend-752UUBD4.js +245 -0
- package/dist/src/app/webui/.next/standalone/.next/BUILD_ID +1 -1
- package/dist/src/app/webui/.next/standalone/.next/app-build-manifest.json +20 -21
- package/dist/src/app/webui/.next/standalone/.next/app-path-routes-manifest.json +0 -1
- package/dist/src/app/webui/.next/standalone/.next/build-manifest.json +4 -4
- package/dist/src/app/webui/.next/standalone/.next/prerender-manifest.json +4 -82
- package/dist/src/app/webui/.next/standalone/.next/required-server-files.json +2 -3
- package/dist/src/app/webui/.next/standalone/.next/routes-manifest.json +0 -6
- package/dist/src/app/webui/.next/standalone/.next/server/app/_not-found/page.js +1 -1
- package/dist/src/app/webui/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/src/app/webui/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/src/app/webui/.next/standalone/.next/server/app/page.js +7 -3
- package/dist/src/app/webui/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/dist/src/app/webui/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/src/app/webui/.next/standalone/.next/server/app/playground/page.js +8 -8
- package/dist/src/app/webui/.next/standalone/.next/server/app/playground/page.js.nft.json +1 -1
- package/dist/src/app/webui/.next/standalone/.next/server/app/playground/page_client-reference-manifest.js +1 -1
- package/dist/src/app/webui/.next/standalone/.next/server/app-paths-manifest.json +0 -1
- package/dist/src/app/webui/.next/standalone/.next/server/chunks/176.js +1 -0
- package/dist/src/app/webui/.next/standalone/.next/server/chunks/195.js +24 -0
- package/dist/src/app/webui/.next/standalone/.next/server/chunks/620.js +1 -0
- package/dist/src/app/webui/.next/standalone/.next/server/chunks/80.js +5 -0
- package/dist/src/app/webui/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/src/app/webui/.next/standalone/.next/server/pages/500.html +1 -1
- package/dist/src/app/webui/.next/standalone/.next/server/pages-manifest.json +1 -2
- package/dist/src/app/webui/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/src/app/webui/.next/standalone/.next/server/webpack-runtime.js +1 -1
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/190-b897ef36fde616bf.js +1 -0
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/487-a77054bd2c64c79c.js +1 -0
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/588-dbe47a44489742dd.js +1 -0
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/62-35030b5cb176bd7b.js +1 -0
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/app/layout-91c0cb9eb1ee327a.js +1 -0
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/app/page-3279aaf14db87f45.js +1 -0
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/app/playground/page-200aad53af9ca53f.js +1 -0
- package/dist/src/app/webui/.next/standalone/.next/static/css/af71306827be150e.css +3 -0
- package/dist/src/app/webui/.next/standalone/.next/static/tpCURR82LyyGfdALJ4Qvl/_buildManifest.js +1 -0
- package/dist/src/app/webui/.next/standalone/package.json +4 -3
- package/dist/src/app/webui/.next/standalone/public/favicon2.ico +0 -0
- package/dist/src/app/webui/.next/standalone/public/logo.svg +1 -0
- package/dist/src/app/webui/.next/standalone/public/logo_no_text.png +0 -0
- package/dist/src/app/webui/.next/standalone/server.js +1 -1
- package/dist/src/app/webui/.next/static/chunks/190-b897ef36fde616bf.js +1 -0
- package/dist/src/app/webui/.next/static/chunks/487-a77054bd2c64c79c.js +1 -0
- package/dist/src/app/webui/.next/static/chunks/588-dbe47a44489742dd.js +1 -0
- package/dist/src/app/webui/.next/static/chunks/62-35030b5cb176bd7b.js +1 -0
- package/dist/src/app/webui/.next/static/chunks/app/layout-91c0cb9eb1ee327a.js +1 -0
- package/dist/src/app/webui/.next/static/chunks/app/page-3279aaf14db87f45.js +1 -0
- package/dist/src/app/webui/.next/static/chunks/app/playground/page-200aad53af9ca53f.js +1 -0
- package/dist/src/app/webui/.next/static/css/af71306827be150e.css +3 -0
- package/dist/src/app/webui/.next/static/tpCURR82LyyGfdALJ4Qvl/_buildManifest.js +1 -0
- package/dist/src/app/webui/package.json +4 -3
- package/dist/src/app/webui/public/favicon2.ico +0 -0
- package/dist/src/app/webui/public/logo.svg +1 -0
- package/dist/src/app/webui/public/logo_no_text.png +0 -0
- package/dist/src/core/chunk-7A6NQKQ3.js +193 -0
- package/dist/src/core/chunk-CZIXQNMZ.js +12191 -0
- package/dist/src/core/index.cjs +10601 -8012
- package/dist/src/core/index.d.cts +4356 -3907
- package/dist/src/core/index.d.ts +4356 -3907
- package/dist/src/core/index.js +117 -8396
- package/dist/src/core/{postgres-backend-ERZ6DP76.js → postgres-backend-LOLKTD2T.js} +9 -2
- package/dist/src/core/{redis-backend-46O7Y44C.js → redis-backend-APZ576PJ.js} +35 -10
- package/dist/src/core/sqlite-backend-KQ75DPR7.js +245 -0
- package/package.json +20 -12
- package/dist/src/app/chunk-O5YHNFMH.js +0 -435
- package/dist/src/app/interactive-api-key-setup-V3GAACLN.js +0 -269
- package/dist/src/app/sqlite-backend-KIJZ5IP3.js +0 -180
- package/dist/src/app/webui/.next/standalone/.next/server/app/_not-found.html +0 -1
- package/dist/src/app/webui/.next/standalone/.next/server/app/_not-found.meta +0 -8
- package/dist/src/app/webui/.next/standalone/.next/server/app/_not-found.rsc +0 -21
- package/dist/src/app/webui/.next/standalone/.next/server/app/favicon.ico/route.js +0 -1
- package/dist/src/app/webui/.next/standalone/.next/server/app/favicon.ico/route.js.nft.json +0 -1
- package/dist/src/app/webui/.next/standalone/.next/server/app/favicon.ico.body +0 -0
- package/dist/src/app/webui/.next/standalone/.next/server/app/favicon.ico.meta +0 -1
- package/dist/src/app/webui/.next/standalone/.next/server/app/index.html +0 -1
- package/dist/src/app/webui/.next/standalone/.next/server/app/index.meta +0 -7
- package/dist/src/app/webui/.next/standalone/.next/server/app/index.rsc +0 -22
- package/dist/src/app/webui/.next/standalone/.next/server/app/playground.html +0 -1
- package/dist/src/app/webui/.next/standalone/.next/server/app/playground.meta +0 -7
- package/dist/src/app/webui/.next/standalone/.next/server/app/playground.rsc +0 -25
- package/dist/src/app/webui/.next/standalone/.next/server/chunks/447.js +0 -20
- package/dist/src/app/webui/.next/standalone/.next/server/chunks/504.js +0 -1
- package/dist/src/app/webui/.next/standalone/.next/server/chunks/54.js +0 -5
- package/dist/src/app/webui/.next/standalone/.next/server/chunks/624.js +0 -1
- package/dist/src/app/webui/.next/standalone/.next/server/chunks/985.js +0 -5
- package/dist/src/app/webui/.next/standalone/.next/server/pages/404.html +0 -1
- package/dist/src/app/webui/.next/standalone/.next/static/H-71qcBOOk528tDEa_ldn/_buildManifest.js +0 -1
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/125-9b34ec01f112cdb2.js +0 -1
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/487-c6ea8b63ca68db1c.js +0 -1
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/588-20dc7f3a8664c387.js +0 -1
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/687-3e614f30982093f6.js +0 -1
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/879-cf875984faa0b72f.js +0 -1
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/app/layout-ed56660b7ecaf47b.js +0 -1
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/app/page-b05580de36ce0e36.js +0 -1
- package/dist/src/app/webui/.next/standalone/.next/static/chunks/app/playground/page-ac5443cddbe824aa.js +0 -1
- package/dist/src/app/webui/.next/standalone/.next/static/css/d44f09bc2605dc76.css +0 -3
- package/dist/src/app/webui/.next/standalone/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js +0 -19
- package/dist/src/app/webui/.next/standalone/public/favicon.svg +0 -26
- package/dist/src/app/webui/.next/standalone/public/logo.png +0 -0
- package/dist/src/app/webui/.next/static/H-71qcBOOk528tDEa_ldn/_buildManifest.js +0 -1
- package/dist/src/app/webui/.next/static/chunks/125-9b34ec01f112cdb2.js +0 -1
- package/dist/src/app/webui/.next/static/chunks/487-c6ea8b63ca68db1c.js +0 -1
- package/dist/src/app/webui/.next/static/chunks/588-20dc7f3a8664c387.js +0 -1
- package/dist/src/app/webui/.next/static/chunks/687-3e614f30982093f6.js +0 -1
- package/dist/src/app/webui/.next/static/chunks/879-cf875984faa0b72f.js +0 -1
- package/dist/src/app/webui/.next/static/chunks/app/layout-ed56660b7ecaf47b.js +0 -1
- package/dist/src/app/webui/.next/static/chunks/app/page-b05580de36ce0e36.js +0 -1
- package/dist/src/app/webui/.next/static/chunks/app/playground/page-ac5443cddbe824aa.js +0 -1
- package/dist/src/app/webui/.next/static/css/d44f09bc2605dc76.css +0 -3
- package/dist/src/app/webui/public/favicon.svg +0 -26
- package/dist/src/app/webui/public/logo.png +0 -0
- package/dist/src/core/chunk-BGO5B3L4.js +0 -2124
- package/dist/src/core/chunk-BYHW25EA.js +0 -41
- package/dist/src/core/sqlite-backend-RKK4WBHE.js +0 -184
- /package/dist/src/app/webui/.next/standalone/.next/static/chunks/{4bd1b696-2df85d4b3b58aed5.js → 4bd1b696-c95fa02060335229.js} +0 -0
- /package/dist/src/app/webui/.next/standalone/.next/static/chunks/{684-058c08971e023037.js → 684-2e7175657246b549.js} +0 -0
- /package/dist/src/app/webui/.next/standalone/.next/static/chunks/app/_not-found/{page-7b137d85f9de4771.js → page-b63df5a8d3225455.js} +0 -0
- /package/dist/src/app/webui/.next/standalone/.next/static/{H-71qcBOOk528tDEa_ldn → tpCURR82LyyGfdALJ4Qvl}/_ssgManifest.js +0 -0
- /package/dist/src/app/webui/.next/static/chunks/{4bd1b696-2df85d4b3b58aed5.js → 4bd1b696-c95fa02060335229.js} +0 -0
- /package/dist/src/app/webui/.next/static/chunks/{684-058c08971e023037.js → 684-2e7175657246b549.js} +0 -0
- /package/dist/src/app/webui/.next/static/chunks/app/_not-found/{page-7b137d85f9de4771.js → page-b63df5a8d3225455.js} +0 -0
- /package/dist/src/app/webui/.next/static/{H-71qcBOOk528tDEa_ldn → tpCURR82LyyGfdALJ4Qvl}/_ssgManifest.js +0 -0
|
@@ -1,435 +0,0 @@
|
|
|
1
|
-
// src/core/utils/path.ts
|
|
2
|
-
import * as path from "path";
|
|
3
|
-
import { existsSync, readFileSync } from "fs";
|
|
4
|
-
import { homedir } from "os";
|
|
5
|
-
import { createRequire } from "module";
|
|
6
|
-
|
|
7
|
-
// src/core/error/index.ts
|
|
8
|
-
var ConfigurationError = class extends Error {
|
|
9
|
-
/**
|
|
10
|
-
* Creates an instance of ConfigurationError.
|
|
11
|
-
* @param message - A human-readable description of the error.
|
|
12
|
-
* @param configPath - Optional. The path to the configuration file related to the error.
|
|
13
|
-
*/
|
|
14
|
-
constructor(message, configPath) {
|
|
15
|
-
super(message);
|
|
16
|
-
this.configPath = configPath;
|
|
17
|
-
this.name = this.constructor.name;
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
var ConfigFileNotFoundError = class extends ConfigurationError {
|
|
21
|
-
/**
|
|
22
|
-
* Creates an instance of ConfigFileNotFoundError.
|
|
23
|
-
* @param configPath - The path to the configuration file that was not found.
|
|
24
|
-
*/
|
|
25
|
-
constructor(configPath) {
|
|
26
|
-
super(`Configuration file not found: ${configPath}`, configPath);
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
var ConfigFileReadError = class extends ConfigurationError {
|
|
30
|
-
/**
|
|
31
|
-
* Creates an instance of ConfigFileReadError.
|
|
32
|
-
* @param configPath - The path to the configuration file that could not be read.
|
|
33
|
-
* @param cause - A string describing the underlying reason for the read failure (e.g., "Permission denied").
|
|
34
|
-
*/
|
|
35
|
-
constructor(configPath, cause) {
|
|
36
|
-
super(`Failed to read configuration file: ${cause}`, configPath);
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
var ConfigParseError = class extends ConfigurationError {
|
|
40
|
-
/**
|
|
41
|
-
* Creates an instance of ConfigParseError.
|
|
42
|
-
* @param configPath - The path to the configuration file that failed to parse.
|
|
43
|
-
* @param cause - A string detailing the parsing error (e.g., "YAMLException: bad indentation").
|
|
44
|
-
*/
|
|
45
|
-
constructor(configPath, cause) {
|
|
46
|
-
super(`Failed to parse YAML configuration: ${cause}`, configPath);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
var ConfigEnvVarError = class extends ConfigurationError {
|
|
50
|
-
/**
|
|
51
|
-
* Creates an instance of ConfigEnvVarError.
|
|
52
|
-
* @param configPath - The path to the configuration file where the environment variable issue occurred.
|
|
53
|
-
* @param envVar - The name of the environment variable that caused the error.
|
|
54
|
-
* @param cause - Optional. A string describing the specific reason for the expansion failure (e.g., "not defined").
|
|
55
|
-
*/
|
|
56
|
-
constructor(configPath, envVar, cause) {
|
|
57
|
-
const message = cause ? `Failed to expand environment variable '${envVar}': ${cause}` : `Environment variable '${envVar}' is required but not set`;
|
|
58
|
-
super(message, configPath);
|
|
59
|
-
this.envVar = envVar;
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
// src/core/utils/path.ts
|
|
64
|
-
var DEFAULT_CONFIG_PATH = "agents/agent.yml";
|
|
65
|
-
function walkUpDirectories(startPath, predicate) {
|
|
66
|
-
let currentPath = path.resolve(startPath);
|
|
67
|
-
const rootPath = path.parse(currentPath).root;
|
|
68
|
-
while (currentPath !== rootPath) {
|
|
69
|
-
if (predicate(currentPath)) {
|
|
70
|
-
return currentPath;
|
|
71
|
-
}
|
|
72
|
-
currentPath = path.dirname(currentPath);
|
|
73
|
-
}
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
function hasDextoDependency(dirPath) {
|
|
77
|
-
const packageJsonPath = path.join(dirPath, "package.json");
|
|
78
|
-
try {
|
|
79
|
-
const pkg = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
80
|
-
if (pkg.name === "dexto") {
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
const allDeps = {
|
|
84
|
-
...pkg.dependencies,
|
|
85
|
-
...pkg.devDependencies,
|
|
86
|
-
...pkg.peerDependencies
|
|
87
|
-
};
|
|
88
|
-
return "dexto" in allDeps;
|
|
89
|
-
} catch {
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
function getDextoProjectRoot(startPath = process.cwd()) {
|
|
94
|
-
return walkUpDirectories(startPath, hasDextoDependency);
|
|
95
|
-
}
|
|
96
|
-
function getDextoPath(type, filename, startPath) {
|
|
97
|
-
const projectRoot = getDextoProjectRoot(startPath);
|
|
98
|
-
let basePath;
|
|
99
|
-
if (projectRoot) {
|
|
100
|
-
basePath = path.join(projectRoot, ".dexto", type);
|
|
101
|
-
} else {
|
|
102
|
-
basePath = path.join(homedir(), ".dexto", type);
|
|
103
|
-
}
|
|
104
|
-
return filename ? path.join(basePath, filename) : basePath;
|
|
105
|
-
}
|
|
106
|
-
function resolveConfigPath(configPath, startPath) {
|
|
107
|
-
if (configPath) {
|
|
108
|
-
return path.resolve(configPath);
|
|
109
|
-
}
|
|
110
|
-
const projectRoot = getDextoProjectRoot(startPath);
|
|
111
|
-
if (projectRoot) {
|
|
112
|
-
const configPaths = [
|
|
113
|
-
path.join(projectRoot, "agents", "agent.yml"),
|
|
114
|
-
// Standard
|
|
115
|
-
path.join(projectRoot, "src", "agents", "agent.yml"),
|
|
116
|
-
// Common
|
|
117
|
-
path.join(projectRoot, "src", "dexto", "agents", "agent.yml"),
|
|
118
|
-
// Test app structure
|
|
119
|
-
path.join(projectRoot, ".dexto", "agent.yml"),
|
|
120
|
-
// Hidden
|
|
121
|
-
path.join(projectRoot, "agent.yml")
|
|
122
|
-
// Root
|
|
123
|
-
];
|
|
124
|
-
for (const configPath2 of configPaths) {
|
|
125
|
-
if (existsSync(configPath2)) {
|
|
126
|
-
return configPath2;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
throw new ConfigFileNotFoundError(
|
|
130
|
-
`No agent.yml found in project. Searched: ${configPaths.join(", ")}`
|
|
131
|
-
);
|
|
132
|
-
} else {
|
|
133
|
-
try {
|
|
134
|
-
const bundledConfigPath = resolveBundledScript("agents/agent.yml");
|
|
135
|
-
if (existsSync(bundledConfigPath)) {
|
|
136
|
-
return bundledConfigPath;
|
|
137
|
-
}
|
|
138
|
-
} catch {
|
|
139
|
-
}
|
|
140
|
-
throw new ConfigFileNotFoundError(
|
|
141
|
-
"Global CLI: No bundled config found and no explicit config provided"
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
function findPackageRoot(startPath = process.cwd()) {
|
|
146
|
-
return walkUpDirectories(startPath, (dirPath) => {
|
|
147
|
-
const pkgPath = path.join(dirPath, "package.json");
|
|
148
|
-
return existsSync(pkgPath);
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
function resolveBundledScript(scriptPath) {
|
|
152
|
-
try {
|
|
153
|
-
const require2 = createRequire(import.meta.url);
|
|
154
|
-
const packageJsonPath = require2.resolve("dexto/package.json");
|
|
155
|
-
const packageRoot = path.dirname(packageJsonPath);
|
|
156
|
-
return path.resolve(packageRoot, scriptPath);
|
|
157
|
-
} catch {
|
|
158
|
-
const packageRoot = findPackageRoot();
|
|
159
|
-
if (!packageRoot) {
|
|
160
|
-
throw new Error(`Cannot resolve bundled script: ${scriptPath}`);
|
|
161
|
-
}
|
|
162
|
-
return path.resolve(packageRoot, scriptPath);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// src/core/logger/logger.ts
|
|
167
|
-
import * as winston from "winston";
|
|
168
|
-
import chalk from "chalk";
|
|
169
|
-
import boxen from "boxen";
|
|
170
|
-
import * as fs from "fs";
|
|
171
|
-
import * as path2 from "path";
|
|
172
|
-
var logLevels = {
|
|
173
|
-
error: 0,
|
|
174
|
-
warn: 1,
|
|
175
|
-
info: 2,
|
|
176
|
-
http: 3,
|
|
177
|
-
verbose: 4,
|
|
178
|
-
debug: 5,
|
|
179
|
-
silly: 6
|
|
180
|
-
};
|
|
181
|
-
var consoleFormat = winston.format.printf(({ level, message, timestamp, color }) => {
|
|
182
|
-
const levelColorMap = {
|
|
183
|
-
error: chalk.red,
|
|
184
|
-
warn: chalk.yellow,
|
|
185
|
-
info: chalk.blue,
|
|
186
|
-
http: chalk.cyan,
|
|
187
|
-
verbose: chalk.magenta,
|
|
188
|
-
debug: chalk.gray,
|
|
189
|
-
silly: chalk.gray.dim
|
|
190
|
-
};
|
|
191
|
-
const colorize = levelColorMap[level] || chalk.white;
|
|
192
|
-
const formattedMessage = color && typeof color === "string" && chalk[color] ? chalk[color](message) : message;
|
|
193
|
-
return `${chalk.dim(timestamp)} ${colorize(level.toUpperCase())}: ${formattedMessage}`;
|
|
194
|
-
});
|
|
195
|
-
var SHOULD_REDACT = process.env.REDACT_SECRETS !== "false";
|
|
196
|
-
var SENSITIVE_KEYS = ["apiKey", "password", "secret", "token"];
|
|
197
|
-
var MASK_REGEX = new RegExp(
|
|
198
|
-
`(${SENSITIVE_KEYS.join("|")})(["']?\\s*[:=]\\s*)(["'])?.*?\\3`,
|
|
199
|
-
"gi"
|
|
200
|
-
);
|
|
201
|
-
var maskFormat = winston.format((info) => {
|
|
202
|
-
if (SHOULD_REDACT && typeof info.message === "string") {
|
|
203
|
-
info.message = info.message.replace(MASK_REGEX, "$1$2$3[REDACTED]$3");
|
|
204
|
-
}
|
|
205
|
-
return info;
|
|
206
|
-
});
|
|
207
|
-
var getDefaultLogLevel = () => {
|
|
208
|
-
const envLevel = process.env.DEXTO_LOG_LEVEL;
|
|
209
|
-
if (envLevel && Object.keys(logLevels).includes(envLevel.toLowerCase())) {
|
|
210
|
-
return envLevel.toLowerCase();
|
|
211
|
-
}
|
|
212
|
-
return "info";
|
|
213
|
-
};
|
|
214
|
-
var Logger = class {
|
|
215
|
-
logger;
|
|
216
|
-
isSilent = false;
|
|
217
|
-
logFilePath = null;
|
|
218
|
-
logToConsole = false;
|
|
219
|
-
constructor(options = {}) {
|
|
220
|
-
this.isSilent = options.silent || false;
|
|
221
|
-
this.initializeTransports(options);
|
|
222
|
-
this.logger = winston.createLogger({
|
|
223
|
-
levels: logLevels,
|
|
224
|
-
level: options.level || getDefaultLogLevel(),
|
|
225
|
-
silent: options.silent || false,
|
|
226
|
-
format: winston.format.combine(
|
|
227
|
-
winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
|
|
228
|
-
maskFormat(),
|
|
229
|
-
winston.format.errors({ stack: true }),
|
|
230
|
-
winston.format.splat(),
|
|
231
|
-
winston.format.json()
|
|
232
|
-
),
|
|
233
|
-
transports: this.createTransports(options)
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
initializeTransports(options) {
|
|
237
|
-
const logToConsole = options.logToConsole ?? process.env.DEXTO_LOG_TO_CONSOLE === "true";
|
|
238
|
-
this.logToConsole = logToConsole;
|
|
239
|
-
if (options.customLogPath) {
|
|
240
|
-
this.logFilePath = options.customLogPath;
|
|
241
|
-
} else {
|
|
242
|
-
this.logFilePath = getDextoPath("logs", "dexto.log");
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
createTransports(_options) {
|
|
246
|
-
const transports2 = [];
|
|
247
|
-
if (this.logToConsole) {
|
|
248
|
-
transports2.push(
|
|
249
|
-
new winston.transports.Console({
|
|
250
|
-
format: winston.format.combine(
|
|
251
|
-
winston.format.timestamp({ format: "HH:mm:ss" }),
|
|
252
|
-
maskFormat(),
|
|
253
|
-
consoleFormat
|
|
254
|
-
)
|
|
255
|
-
})
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
try {
|
|
259
|
-
if (this.logFilePath) {
|
|
260
|
-
const logDir = path2.dirname(this.logFilePath);
|
|
261
|
-
fs.mkdirSync(logDir, { recursive: true });
|
|
262
|
-
transports2.push(
|
|
263
|
-
new winston.transports.File({
|
|
264
|
-
filename: this.logFilePath,
|
|
265
|
-
format: winston.format.combine(
|
|
266
|
-
winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
|
|
267
|
-
maskFormat(),
|
|
268
|
-
winston.format.errors({ stack: true }),
|
|
269
|
-
winston.format.json()
|
|
270
|
-
),
|
|
271
|
-
// Add daily rotation
|
|
272
|
-
maxsize: 10 * 1024 * 1024,
|
|
273
|
-
// 10MB
|
|
274
|
-
maxFiles: 7,
|
|
275
|
-
// Keep 7 files
|
|
276
|
-
tailable: true
|
|
277
|
-
})
|
|
278
|
-
);
|
|
279
|
-
}
|
|
280
|
-
} catch (error) {
|
|
281
|
-
console.error(`Failed to initialize file logging: ${error}. Falling back to console.`);
|
|
282
|
-
if (!this.logToConsole) {
|
|
283
|
-
this.logToConsole = true;
|
|
284
|
-
transports2.push(
|
|
285
|
-
new winston.transports.Console({
|
|
286
|
-
format: winston.format.combine(
|
|
287
|
-
winston.format.timestamp({ format: "HH:mm:ss" }),
|
|
288
|
-
maskFormat(),
|
|
289
|
-
consoleFormat
|
|
290
|
-
)
|
|
291
|
-
})
|
|
292
|
-
);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
return transports2;
|
|
296
|
-
}
|
|
297
|
-
// General logging methods with optional color parameter
|
|
298
|
-
error(message, meta, color) {
|
|
299
|
-
this.logger.error(message, { ...meta, color });
|
|
300
|
-
}
|
|
301
|
-
warn(message, meta, color) {
|
|
302
|
-
this.logger.warn(message, { ...meta, color });
|
|
303
|
-
}
|
|
304
|
-
info(message, meta, color) {
|
|
305
|
-
this.logger.info(message, { ...meta, color });
|
|
306
|
-
}
|
|
307
|
-
http(message, meta, color) {
|
|
308
|
-
this.logger.http(message, { ...meta, color });
|
|
309
|
-
}
|
|
310
|
-
verbose(message, meta, color) {
|
|
311
|
-
this.logger.verbose(message, { ...meta, color });
|
|
312
|
-
}
|
|
313
|
-
debug(message, meta, color) {
|
|
314
|
-
const formattedMessage = typeof message === "string" ? message : JSON.stringify(message, null, 2);
|
|
315
|
-
this.logger.debug(formattedMessage, { ...meta, color });
|
|
316
|
-
}
|
|
317
|
-
silly(message, meta, color) {
|
|
318
|
-
this.logger.silly(message, { ...meta, color });
|
|
319
|
-
}
|
|
320
|
-
// Display AI response in a box
|
|
321
|
-
displayAIResponse(response) {
|
|
322
|
-
if (this.isSilent) return;
|
|
323
|
-
if (response.content) {
|
|
324
|
-
console.log(
|
|
325
|
-
boxen(chalk.white(response.content), {
|
|
326
|
-
padding: 1,
|
|
327
|
-
borderColor: "yellow",
|
|
328
|
-
title: "\u{1F916} AI Response",
|
|
329
|
-
titleAlignment: "center"
|
|
330
|
-
})
|
|
331
|
-
);
|
|
332
|
-
} else {
|
|
333
|
-
console.log(chalk.yellow("AI is thinking..."));
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
// Tool-related logging
|
|
337
|
-
toolCall(toolName, args) {
|
|
338
|
-
if (this.isSilent) return;
|
|
339
|
-
console.log(
|
|
340
|
-
boxen(
|
|
341
|
-
`${chalk.cyan("Tool Call")}: ${chalk.yellow(toolName)}
|
|
342
|
-
${chalk.dim("Arguments")}:
|
|
343
|
-
${chalk.white(JSON.stringify(args, null, 2))}`,
|
|
344
|
-
{ padding: 1, borderColor: "blue", title: "\u{1F527} Tool Call", titleAlignment: "center" }
|
|
345
|
-
)
|
|
346
|
-
);
|
|
347
|
-
}
|
|
348
|
-
toolResult(result) {
|
|
349
|
-
if (this.isSilent) return;
|
|
350
|
-
let displayText = "";
|
|
351
|
-
let isError = false;
|
|
352
|
-
let borderColor = "green";
|
|
353
|
-
let title = "\u2705 Tool Result";
|
|
354
|
-
if (result?.error || result?.isError) {
|
|
355
|
-
isError = true;
|
|
356
|
-
borderColor = "yellow";
|
|
357
|
-
title = "\u26A0\uFE0F Tool Result (Error)";
|
|
358
|
-
}
|
|
359
|
-
if (result?.content && Array.isArray(result.content)) {
|
|
360
|
-
result.content.forEach((item) => {
|
|
361
|
-
if (item.type === "text") {
|
|
362
|
-
displayText += item.text;
|
|
363
|
-
} else if (item.type === "image" && item.url) {
|
|
364
|
-
displayText += `[Image URL: ${item.url}]`;
|
|
365
|
-
} else if (item.type === "image") {
|
|
366
|
-
displayText += `[Image Data: ${item.mimeType || "unknown type"}]`;
|
|
367
|
-
} else if (item.type === "markdown") {
|
|
368
|
-
displayText += item.markdown;
|
|
369
|
-
} else {
|
|
370
|
-
displayText += `[Unsupported content type: ${item.type}]`;
|
|
371
|
-
}
|
|
372
|
-
displayText += "\n";
|
|
373
|
-
});
|
|
374
|
-
} else if (result?.message) {
|
|
375
|
-
displayText = result.message;
|
|
376
|
-
isError = true;
|
|
377
|
-
borderColor = "red";
|
|
378
|
-
title = "\u274C Tool Error";
|
|
379
|
-
} else if (typeof result === "string") {
|
|
380
|
-
displayText = result;
|
|
381
|
-
} else {
|
|
382
|
-
try {
|
|
383
|
-
displayText = JSON.stringify(result, null, 2);
|
|
384
|
-
} catch {
|
|
385
|
-
displayText = `[Unparseable result: ${typeof result}]`;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
if (!displayText || displayText.trim() === "") {
|
|
389
|
-
displayText = "[Empty result]";
|
|
390
|
-
}
|
|
391
|
-
const textColor = isError ? chalk.yellow : chalk.green;
|
|
392
|
-
console.log(
|
|
393
|
-
boxen(textColor(displayText), {
|
|
394
|
-
padding: 1,
|
|
395
|
-
borderColor,
|
|
396
|
-
title,
|
|
397
|
-
titleAlignment: "center"
|
|
398
|
-
})
|
|
399
|
-
);
|
|
400
|
-
}
|
|
401
|
-
// Configuration
|
|
402
|
-
setLevel(level) {
|
|
403
|
-
if (Object.keys(logLevels).includes(level.toLowerCase())) {
|
|
404
|
-
this.logger.level = level.toLowerCase();
|
|
405
|
-
if (!this.isSilent) {
|
|
406
|
-
console.log(`Log level set to: ${level}`);
|
|
407
|
-
}
|
|
408
|
-
} else {
|
|
409
|
-
this.error(`Invalid log level: ${level}. Using current level: ${this.logger.level}`);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
// Get the current log file path
|
|
413
|
-
getLogFilePath() {
|
|
414
|
-
return this.logFilePath;
|
|
415
|
-
}
|
|
416
|
-
// Get current log level
|
|
417
|
-
getLevel() {
|
|
418
|
-
return this.logger.level;
|
|
419
|
-
}
|
|
420
|
-
};
|
|
421
|
-
var logger = new Logger();
|
|
422
|
-
|
|
423
|
-
export {
|
|
424
|
-
ConfigurationError,
|
|
425
|
-
ConfigFileNotFoundError,
|
|
426
|
-
ConfigFileReadError,
|
|
427
|
-
ConfigParseError,
|
|
428
|
-
ConfigEnvVarError,
|
|
429
|
-
DEFAULT_CONFIG_PATH,
|
|
430
|
-
getDextoPath,
|
|
431
|
-
resolveConfigPath,
|
|
432
|
-
findPackageRoot,
|
|
433
|
-
resolveBundledScript,
|
|
434
|
-
logger
|
|
435
|
-
};
|
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getPrimaryApiKeyEnvVar,
|
|
3
|
-
updateDextoConfigFile,
|
|
4
|
-
updateEnvFile
|
|
5
|
-
} from "./chunk-M4OZIDPC.js";
|
|
6
|
-
import {
|
|
7
|
-
DEFAULT_CONFIG_PATH,
|
|
8
|
-
logger,
|
|
9
|
-
resolveConfigPath
|
|
10
|
-
} from "./chunk-O5YHNFMH.js";
|
|
11
|
-
|
|
12
|
-
// src/app/cli/utils/interactive-api-key-setup.ts
|
|
13
|
-
import * as p from "@clack/prompts";
|
|
14
|
-
import chalk from "chalk";
|
|
15
|
-
async function interactiveApiKeySetup() {
|
|
16
|
-
try {
|
|
17
|
-
p.intro(chalk.cyan("\u{1F511} API Key Setup"));
|
|
18
|
-
p.note(
|
|
19
|
-
`Dexto needs an API key to work with AI models. You can:
|
|
20
|
-
|
|
21
|
-
\u2022 ${chalk.green("Google Gemini")} - Free tier available (15 requests/minute)
|
|
22
|
-
\u2022 ${chalk.blue("OpenAI")} - Most popular, requires payment
|
|
23
|
-
\u2022 ${chalk.magenta("Anthropic")} - High quality models, requires payment
|
|
24
|
-
\u2022 ${chalk.yellow("Groq")} - Fast inference, free tier available
|
|
25
|
-
|
|
26
|
-
Don't have an API key? Get a free one from Google AI Studio!`,
|
|
27
|
-
chalk.bold("Choose your AI provider")
|
|
28
|
-
);
|
|
29
|
-
const action = await p.select({
|
|
30
|
-
message: "What would you like to do?",
|
|
31
|
-
options: [
|
|
32
|
-
{
|
|
33
|
-
value: "setup",
|
|
34
|
-
label: "Set up an API key now",
|
|
35
|
-
hint: "Interactive setup (recommended)"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
value: "manual",
|
|
39
|
-
label: "Set up manually later",
|
|
40
|
-
hint: "Get instructions for manual setup"
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
value: "exit",
|
|
44
|
-
label: "Exit",
|
|
45
|
-
hint: "Quit Dexto for now"
|
|
46
|
-
}
|
|
47
|
-
]
|
|
48
|
-
});
|
|
49
|
-
if (action === "exit") {
|
|
50
|
-
p.cancel("Setup cancelled. Run dexto again when you have an API key!");
|
|
51
|
-
return { success: false, skipSetup: true };
|
|
52
|
-
}
|
|
53
|
-
if (action === "manual") {
|
|
54
|
-
showManualSetupInstructions();
|
|
55
|
-
return { success: false, skipSetup: true };
|
|
56
|
-
}
|
|
57
|
-
const provider = await p.select({
|
|
58
|
-
message: "Select your AI provider",
|
|
59
|
-
options: [
|
|
60
|
-
{
|
|
61
|
-
value: "google",
|
|
62
|
-
label: "Google Gemini",
|
|
63
|
-
hint: "\u{1F193} Free tier available - get key from aistudio.google.com"
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
value: "openai",
|
|
67
|
-
label: "OpenAI",
|
|
68
|
-
hint: "\u{1F4B0} Requires payment - get key from platform.openai.com"
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
value: "anthropic",
|
|
72
|
-
label: "Anthropic Claude",
|
|
73
|
-
hint: "\u{1F4B0} Requires payment - get key from console.anthropic.com"
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
value: "groq",
|
|
77
|
-
label: "Groq",
|
|
78
|
-
hint: "\u{1F193} Free tier available - get key from console.groq.com"
|
|
79
|
-
}
|
|
80
|
-
]
|
|
81
|
-
});
|
|
82
|
-
showProviderInstructions(provider);
|
|
83
|
-
const apiKey = await p.text({
|
|
84
|
-
message: `Enter your ${getProviderDisplayName(provider)} API key`,
|
|
85
|
-
placeholder: getApiKeyPlaceholder(provider),
|
|
86
|
-
validate: (value) => {
|
|
87
|
-
if (!value || value.trim().length === 0) {
|
|
88
|
-
return "API key is required";
|
|
89
|
-
}
|
|
90
|
-
if (!isValidApiKeyFormat(value.trim(), provider)) {
|
|
91
|
-
return `Invalid ${getProviderDisplayName(provider)} API key format`;
|
|
92
|
-
}
|
|
93
|
-
return void 0;
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
if (p.isCancel(apiKey)) {
|
|
97
|
-
p.cancel("Setup cancelled");
|
|
98
|
-
return { success: false };
|
|
99
|
-
}
|
|
100
|
-
const spinner2 = p.spinner();
|
|
101
|
-
spinner2.start("Saving API key and updating configuration...");
|
|
102
|
-
try {
|
|
103
|
-
await updateEnvFile(process.cwd(), provider, apiKey.trim());
|
|
104
|
-
try {
|
|
105
|
-
const configPath = resolveConfigPath(DEFAULT_CONFIG_PATH);
|
|
106
|
-
await updateDextoConfigFile(configPath, provider);
|
|
107
|
-
spinner2.stop("Configuration updated successfully! \u2728");
|
|
108
|
-
} catch (configError) {
|
|
109
|
-
spinner2.stop("API key saved, but config update failed");
|
|
110
|
-
logger.debug(`Failed to update agent config: ${configError}`);
|
|
111
|
-
p.note(
|
|
112
|
-
`API key saved successfully, but automatic config update failed.
|
|
113
|
-
|
|
114
|
-
To use ${getProviderDisplayName(provider)}, you may need to:
|
|
115
|
-
1. Edit your agent.yml file
|
|
116
|
-
2. Update the llm.provider to "${provider}"
|
|
117
|
-
3. Update the llm.apiKey to "$${getPrimaryApiKeyEnvVar(provider)}"`,
|
|
118
|
-
chalk.yellow("Manual config update needed")
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
p.outro(
|
|
122
|
-
chalk.green("\u{1F389} Setup complete!") + `
|
|
123
|
-
|
|
124
|
-
Your ${getProviderDisplayName(provider)} API key has been saved to .env
|
|
125
|
-
Dexto is now configured to use ${getProviderDisplayName(provider)}.`
|
|
126
|
-
);
|
|
127
|
-
return { success: true, provider };
|
|
128
|
-
} catch (error) {
|
|
129
|
-
spinner2.stop("Failed to save API key");
|
|
130
|
-
logger.error(`Failed to update .env file: ${error}`);
|
|
131
|
-
p.note(
|
|
132
|
-
`Manual setup required:
|
|
133
|
-
|
|
134
|
-
1. Create a .env file in your project root
|
|
135
|
-
2. Add this line: ${getPrimaryApiKeyEnvVar(provider)}=${apiKey}
|
|
136
|
-
3. Update your agent.yml llm.provider to "${provider}"
|
|
137
|
-
4. Update your agent.yml llm.apiKey to "$${getPrimaryApiKeyEnvVar(provider)}"
|
|
138
|
-
5. Run dexto again`,
|
|
139
|
-
chalk.yellow("Save this API key manually")
|
|
140
|
-
);
|
|
141
|
-
return { success: false, provider };
|
|
142
|
-
}
|
|
143
|
-
} catch (error) {
|
|
144
|
-
if (p.isCancel(error)) {
|
|
145
|
-
p.cancel("Setup cancelled");
|
|
146
|
-
return { success: false };
|
|
147
|
-
}
|
|
148
|
-
throw error;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
function showManualSetupInstructions() {
|
|
152
|
-
const instructions = [
|
|
153
|
-
`${chalk.bold("1. Get an API key:")}`,
|
|
154
|
-
` \u2022 ${chalk.green("Google Gemini (Free)")}: https://aistudio.google.com/apikey`,
|
|
155
|
-
` \u2022 ${chalk.blue("OpenAI")}: https://platform.openai.com/api-keys`,
|
|
156
|
-
` \u2022 ${chalk.magenta("Anthropic")}: https://console.anthropic.com/keys`,
|
|
157
|
-
` \u2022 ${chalk.yellow("Groq (Free)")}: https://console.groq.com/keys`,
|
|
158
|
-
``,
|
|
159
|
-
`${chalk.bold("2. Create a .env file in your project:")}`,
|
|
160
|
-
` echo "GOOGLE_GENERATIVE_AI_API_KEY=your_key_here" > .env`,
|
|
161
|
-
` # OR for other providers:`,
|
|
162
|
-
` # OPENAI_API_KEY=your_key_here`,
|
|
163
|
-
` # ANTHROPIC_API_KEY=your_key_here`,
|
|
164
|
-
` # GROQ_API_KEY=your_key_here`,
|
|
165
|
-
``,
|
|
166
|
-
`${chalk.bold("3. Run dexto again:")}`,
|
|
167
|
-
` npx dexto`,
|
|
168
|
-
``,
|
|
169
|
-
`${chalk.dim("\u{1F4A1} Tip: Start with Google Gemini for a free experience!")}`
|
|
170
|
-
].join("\n");
|
|
171
|
-
p.note(instructions, chalk.bold("Manual Setup Instructions"));
|
|
172
|
-
}
|
|
173
|
-
function showProviderInstructions(provider) {
|
|
174
|
-
const instructions = getProviderInstructions(provider);
|
|
175
|
-
if (instructions) {
|
|
176
|
-
p.note(instructions.content, instructions.title);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
function getProviderInstructions(provider) {
|
|
180
|
-
switch (provider) {
|
|
181
|
-
case "google":
|
|
182
|
-
return {
|
|
183
|
-
title: chalk.green("Google Gemini - Free API Key"),
|
|
184
|
-
content: `1. Visit: ${chalk.cyan("https://aistudio.google.com/apikey")}
|
|
185
|
-
2. Sign in with your Google account
|
|
186
|
-
3. Click "Create API Key"
|
|
187
|
-
4. Copy the key (starts with "AIza...")
|
|
188
|
-
|
|
189
|
-
${chalk.dim("\u2728 Free tier: 15 requests/minute, 1500 requests/day")}`
|
|
190
|
-
};
|
|
191
|
-
case "openai":
|
|
192
|
-
return {
|
|
193
|
-
title: chalk.blue("OpenAI API Key"),
|
|
194
|
-
content: `1. Visit: ${chalk.cyan("https://platform.openai.com/api-keys")}
|
|
195
|
-
2. Sign in to your OpenAI account
|
|
196
|
-
3. Click "Create new secret key"
|
|
197
|
-
4. Copy the key (starts with "sk-...")
|
|
198
|
-
|
|
199
|
-
${chalk.dim("\u{1F4B0} Requires payment - $5 minimum credit")}`
|
|
200
|
-
};
|
|
201
|
-
case "anthropic":
|
|
202
|
-
return {
|
|
203
|
-
title: chalk.magenta("Anthropic API Key"),
|
|
204
|
-
content: `1. Visit: ${chalk.cyan("https://console.anthropic.com/keys")}
|
|
205
|
-
2. Sign in to your Anthropic account
|
|
206
|
-
3. Click "Create Key"
|
|
207
|
-
4. Copy the key (starts with "sk-ant-...")
|
|
208
|
-
|
|
209
|
-
${chalk.dim("\u{1F4B0} Requires payment - $5 minimum credit")}`
|
|
210
|
-
};
|
|
211
|
-
case "groq":
|
|
212
|
-
return {
|
|
213
|
-
title: chalk.yellow("Groq API Key"),
|
|
214
|
-
content: `1. Visit: ${chalk.cyan("https://console.groq.com/keys")}
|
|
215
|
-
2. Sign in with your account
|
|
216
|
-
3. Click "Create API Key"
|
|
217
|
-
4. Copy the key (starts with "gsk_...")
|
|
218
|
-
|
|
219
|
-
${chalk.dim("\u{1F193} Free tier: 30 requests/minute")}`
|
|
220
|
-
};
|
|
221
|
-
default:
|
|
222
|
-
return null;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
function getProviderDisplayName(provider) {
|
|
226
|
-
switch (provider) {
|
|
227
|
-
case "google":
|
|
228
|
-
return "Google Gemini";
|
|
229
|
-
case "openai":
|
|
230
|
-
return "OpenAI";
|
|
231
|
-
case "anthropic":
|
|
232
|
-
return "Anthropic";
|
|
233
|
-
case "groq":
|
|
234
|
-
return "Groq";
|
|
235
|
-
default:
|
|
236
|
-
return provider;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
function getApiKeyPlaceholder(provider) {
|
|
240
|
-
switch (provider) {
|
|
241
|
-
case "google":
|
|
242
|
-
return "AIza...";
|
|
243
|
-
case "openai":
|
|
244
|
-
return "sk-...";
|
|
245
|
-
case "anthropic":
|
|
246
|
-
return "sk-ant-...";
|
|
247
|
-
case "groq":
|
|
248
|
-
return "gsk_...";
|
|
249
|
-
default:
|
|
250
|
-
return "your-api-key";
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
function isValidApiKeyFormat(apiKey, provider) {
|
|
254
|
-
switch (provider) {
|
|
255
|
-
case "google":
|
|
256
|
-
return apiKey.startsWith("AIza") && apiKey.length > 20;
|
|
257
|
-
case "openai":
|
|
258
|
-
return apiKey.startsWith("sk-") && apiKey.length > 40;
|
|
259
|
-
case "anthropic":
|
|
260
|
-
return apiKey.startsWith("sk-ant-") && apiKey.length > 40;
|
|
261
|
-
case "groq":
|
|
262
|
-
return apiKey.startsWith("gsk_") && apiKey.length > 40;
|
|
263
|
-
default:
|
|
264
|
-
return apiKey.length > 10;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
export {
|
|
268
|
-
interactiveApiKeySetup
|
|
269
|
-
};
|