Skip to content

Commit e81f6ed

Browse files
committed
Handle env variables in tiny-agents
1 parent b7af869 commit e81f6ed

File tree

3 files changed

+90
-2
lines changed

3 files changed

+90
-2
lines changed

packages/tiny-agents/src/cli.ts

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#!/usr/bin/env node
22
import { parseArgs } from "node:util";
3+
import * as readline from "node:readline/promises";
4+
import { stdin, stdout } from "node:process";
35
import { z } from "zod";
46
import { PROVIDERS_OR_POLICIES } from "@huggingface/inference";
57
import { Agent } from "@huggingface/mcp-client";
68
import { version as packageVersion } from "../package.json";
7-
import { ServerConfigSchema } from "./lib/types";
8-
import { debug, error } from "./lib/utils";
9+
import { InputConfigSchema, ServerConfigSchema } from "./lib/types";
10+
import { debug, error, ANSI } from "./lib/utils";
911
import { mainCliLoop } from "./lib/mainCliLoop";
1012
import { loadConfigFrom } from "./lib/loadConfigFrom";
1113

@@ -70,6 +72,7 @@ async function main() {
7072
provider: z.enum(PROVIDERS_OR_POLICIES).optional(),
7173
endpointUrl: z.string().optional(),
7274
apiKey: z.string().optional(),
75+
inputs: z.array(InputConfigSchema).optional(),
7376
servers: z.array(ServerConfigSchema),
7477
})
7578
.refine((data) => data.provider !== undefined || data.endpointUrl !== undefined, {
@@ -85,6 +88,81 @@ async function main() {
8588
process.exit(1);
8689
}
8790

91+
// Handle inputs (i.e. env variables injection)
92+
if (config.inputs && config.inputs.length > 0) {
93+
const rl = readline.createInterface({ input: stdin, output: stdout });
94+
95+
stdout.write(ANSI.BLUE);
96+
stdout.write("Some initial inputs are required by the agent. ");
97+
stdout.write("Please provide a value or leave empty to load from env.");
98+
stdout.write(ANSI.RESET);
99+
stdout.write("\n");
100+
101+
for (const inputItem of config.inputs) {
102+
const inputId = inputItem.id;
103+
const description = inputItem.description;
104+
const envSpecialValue = `\${input:${inputId}}`; // Special value to indicate env variable injection
105+
106+
// Check env variables that will use this input
107+
const inputVars = new Set<string>();
108+
for (const server of config.servers) {
109+
if (server.type === "stdio" && server.config.env) {
110+
for (const [key, value] of Object.entries(server.config.env)) {
111+
if (value === envSpecialValue) {
112+
inputVars.add(key);
113+
}
114+
}
115+
}
116+
}
117+
118+
if (inputVars.size === 0) {
119+
stdout.write(ANSI.YELLOW);
120+
stdout.write(`Input ${inputId} defined in config but not used by any server.`);
121+
stdout.write(ANSI.RESET);
122+
stdout.write("\n");
123+
continue;
124+
}
125+
126+
// Prompt user for input
127+
stdout.write(ANSI.BLUE);
128+
stdout.write(` • ${inputId}`);
129+
stdout.write(ANSI.RESET);
130+
stdout.write(`: ${description}. (default: load from ${Array.from(inputVars).join(", ")}) `);
131+
132+
const userInput = (await rl.question("")).trim();
133+
134+
// Inject user input (or env variable) into servers' env
135+
for (const server of config.servers) {
136+
if (server.type === "stdio" && server.config.env) {
137+
for (const [key, value] of Object.entries(server.config.env)) {
138+
if (value === envSpecialValue) {
139+
if (userInput) {
140+
server.config.env[key] = userInput;
141+
} else {
142+
const valueFromEnv = process.env[key] || "";
143+
server.config.env[key] = valueFromEnv;
144+
if (valueFromEnv) {
145+
stdout.write(ANSI.GREEN);
146+
stdout.write(`Value successfully loaded from '${key}'`);
147+
stdout.write(ANSI.RESET);
148+
stdout.write("\n");
149+
} else {
150+
stdout.write(ANSI.YELLOW);
151+
stdout.write(`No value found for '${key}' in environment variables. Continuing.`);
152+
stdout.write(ANSI.RESET);
153+
stdout.write("\n");
154+
}
155+
}
156+
}
157+
}
158+
}
159+
}
160+
}
161+
162+
stdout.write("\n");
163+
rl.close();
164+
}
165+
88166
const agent = new Agent(
89167
config.endpointUrl
90168
? {

packages/tiny-agents/src/lib/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,12 @@ export const ServerConfigSchema = z.discriminatedUnion("type", [
4040
]);
4141

4242
export type ServerConfig = z.infer<typeof ServerConfigSchema>;
43+
44+
export const InputConfigSchema = z.object({
45+
id: z.string(),
46+
description: z.string(),
47+
type: z.string().optional(),
48+
password: z.boolean().optional(),
49+
});
50+
51+
export type InputConfig = z.infer<typeof InputConfigSchema>;

packages/tiny-agents/src/lib/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ export const ANSI = {
1616
GREEN: "\x1b[32m",
1717
RED: "\x1b[31m",
1818
RESET: "\x1b[0m",
19+
YELLOW: "\x1b[33m",
1920
};

0 commit comments

Comments
 (0)