@perstack/runtime 0.0.70 → 0.0.71

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 CHANGED
@@ -25,7 +25,6 @@ perstack-runtime run <expertKey> <query> [options]
25
25
  | `--config <path>` | Path to perstack.toml |
26
26
  | `--provider <provider>` | LLM provider |
27
27
  | `--model <model>` | Model name |
28
- | `--temperature <temp>` | Temperature (0.0-1.0) |
29
28
  | `--max-steps <n>` | Maximum steps |
30
29
  | `--max-retries <n>` | Maximum retries |
31
30
  | `--timeout <ms>` | Timeout in milliseconds |
package/dist/bin/cli.js CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { package_default, run } from '../chunk-3RWT2GPO.js';
2
+ import { package_default, findLockfile, loadLockfile, run } from '../chunk-LDJKVMQK.js';
3
+ import '../chunk-RG4QHAGG.js';
3
4
  import { parseWithFriendlyError, runCommandInputSchema, perstackConfigSchema } from '@perstack/core';
4
5
  import { Command } from 'commander';
5
6
  import dotenv from 'dotenv';
@@ -183,7 +184,8 @@ var defaultProvider = "anthropic";
183
184
  var defaultModel = "claude-sonnet-4-5";
184
185
  async function resolveRunContext(input) {
185
186
  const perstackConfig = await getPerstackConfig(input.configPath);
186
- const env = getEnv(input.envPath ?? perstackConfig.envPath ?? [".env", ".env.local"]);
187
+ const envPath = input.envPath && input.envPath.length > 0 ? input.envPath : perstackConfig.envPath ?? [".env", ".env.local"];
188
+ const env = getEnv(envPath);
187
189
  const provider = input.provider ?? perstackConfig.provider?.providerName ?? defaultProvider;
188
190
  const model = input.model ?? perstackConfig.model ?? defaultModel;
189
191
  const providerConfig = getProviderConfig(provider, env, perstackConfig.provider);
@@ -227,7 +229,10 @@ var retrieveCheckpoint = async (_jobId, checkpointId) => {
227
229
  return checkpoint;
228
230
  };
229
231
  var program = new Command().name("perstack-runtime").description("Perstack Runtime CLI - Execute Experts directly").version(package_default.version);
230
- program.command("run").description("Run an Expert with JSON event output").argument("<expertKey>", "Expert key to run").argument("<query>", "Query to run").option("--config <configPath>", "Path to perstack.toml config file").option("--provider <provider>", "Provider to use").option("--model <model>", "Model to use").option("--temperature <temperature>", "Temperature for the model, default is 0.3").option(
232
+ program.command("run").description("Run an Expert with JSON event output").argument("<expertKey>", "Expert key to run").argument("<query>", "Query to run").option("--config <configPath>", "Path to perstack.toml config file").option("--provider <provider>", "Provider to use").option("--model <model>", "Model to use").option(
233
+ "--reasoning-budget <budget>",
234
+ "Reasoning budget for native LLM reasoning (minimal, low, medium, high, or token count)"
235
+ ).option(
231
236
  "--max-steps <maxSteps>",
232
237
  "Maximum number of steps to run, default is undefined (no limit)"
233
238
  ).option("--max-retries <maxRetries>", "Maximum number of generation retries, default is 5").option(
@@ -247,6 +252,8 @@ program.command("run").description("Run an Expert with JSON event output").argum
247
252
  model: input.options.model,
248
253
  envPath: input.options.envPath
249
254
  });
255
+ const lockfilePath = findLockfile(input.options.config);
256
+ const lockfile = lockfilePath ? loadLockfile(lockfilePath) ?? void 0 : void 0;
250
257
  await run(
251
258
  {
252
259
  setting: {
@@ -257,7 +264,7 @@ program.command("run").description("Run an Expert with JSON event output").argum
257
264
  experts,
258
265
  model,
259
266
  providerConfig,
260
- temperature: input.options.temperature ?? perstackConfig.temperature,
267
+ reasoningBudget: input.options.reasoningBudget ?? perstackConfig.reasoningBudget,
261
268
  maxSteps: input.options.maxSteps ?? perstackConfig.maxSteps,
262
269
  maxRetries: input.options.maxRetries ?? perstackConfig.maxRetries,
263
270
  timeout: input.options.timeout ?? perstackConfig.timeout,
@@ -269,7 +276,7 @@ program.command("run").description("Run an Expert with JSON event output").argum
269
276
  verbose: input.options.verbose
270
277
  }
271
278
  },
272
- { eventListener: defaultEventListener, storeCheckpoint, retrieveCheckpoint }
279
+ { eventListener: defaultEventListener, storeCheckpoint, retrieveCheckpoint, lockfile }
273
280
  );
274
281
  } catch (error) {
275
282
  if (error instanceof Error) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/get-env.ts","../../src/cli/perstack-toml.ts","../../src/cli/provider-config.ts","../../src/cli/context.ts","../../bin/cli.ts"],"names":["parseWithFriendlyError"],"mappings":"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","file":"cli.js","sourcesContent":["import dotenv from \"dotenv\"\n\nexport function getEnv(envPath: string[]): Record<string, string> {\n const env: Record<string, string> = Object.fromEntries(\n Object.entries(process.env)\n .filter(([_, value]) => !!value)\n .map(([key, value]) => [key, value as string]),\n )\n dotenv.config({ path: envPath, processEnv: env, quiet: true })\n return env\n}\n","import { readFile } from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { type PerstackConfig, parseWithFriendlyError, perstackConfigSchema } from \"@perstack/core\"\nimport TOML from \"smol-toml\"\n\nconst ALLOWED_CONFIG_HOSTS = [\"raw.githubusercontent.com\"]\n\nexport async function getPerstackConfig(configPath?: string): Promise<PerstackConfig> {\n const configString = await findPerstackConfigString(configPath)\n if (configString === null) {\n throw new Error(\"perstack.toml not found. Create one or specify --config path.\")\n }\n return await parsePerstackConfig(configString)\n}\n\nfunction isRemoteUrl(configPath: string): boolean {\n const lower = configPath.toLowerCase()\n return lower.startsWith(\"https://\") || lower.startsWith(\"http://\")\n}\n\nasync function fetchRemoteConfig(url: string): Promise<string> {\n let parsed: URL\n try {\n parsed = new URL(url)\n } catch {\n throw new Error(`Invalid remote config URL: ${url}`)\n }\n if (parsed.protocol !== \"https:\") {\n throw new Error(\"Remote config requires HTTPS\")\n }\n if (!ALLOWED_CONFIG_HOSTS.includes(parsed.hostname)) {\n throw new Error(`Remote config only allowed from: ${ALLOWED_CONFIG_HOSTS.join(\", \")}`)\n }\n try {\n const response = await fetch(url, { redirect: \"error\" })\n if (!response.ok) {\n throw new Error(`${response.status} ${response.statusText}`)\n }\n return await response.text()\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new Error(`Failed to fetch remote config: ${message}`)\n }\n}\n\nasync function findPerstackConfigString(configPath?: string): Promise<string | null> {\n if (configPath) {\n if (isRemoteUrl(configPath)) {\n return await fetchRemoteConfig(configPath)\n }\n try {\n const tomlString = await readFile(path.resolve(process.cwd(), configPath), \"utf-8\")\n return tomlString\n } catch {\n throw new Error(`Given config path \"${configPath}\" is not found`)\n }\n }\n return await findPerstackConfigStringRecursively(path.resolve(process.cwd()))\n}\n\nasync function findPerstackConfigStringRecursively(cwd: string): Promise<string | null> {\n try {\n const tomlString = await readFile(path.resolve(cwd, \"perstack.toml\"), \"utf-8\")\n return tomlString\n } catch {\n if (cwd === path.parse(cwd).root) {\n return null\n }\n return await findPerstackConfigStringRecursively(path.dirname(cwd))\n }\n}\n\nasync function parsePerstackConfig(config: string): Promise<PerstackConfig> {\n const toml = TOML.parse(config ?? \"\")\n return parseWithFriendlyError(perstackConfigSchema, toml, \"perstack.toml\")\n}\n","import type { ProviderConfig, ProviderName, ProviderTable } from \"@perstack/core\"\n\ntype SettingRecord = Record<string, unknown>\n\nexport function getProviderConfig(\n provider: ProviderName,\n env: Record<string, string>,\n providerTable?: ProviderTable,\n): ProviderConfig {\n const setting = (providerTable?.setting ?? {}) as SettingRecord\n switch (provider) {\n case \"anthropic\": {\n const apiKey = env.ANTHROPIC_API_KEY\n if (!apiKey) throw new Error(\"ANTHROPIC_API_KEY is not set\")\n return {\n providerName: \"anthropic\",\n apiKey,\n baseUrl: (setting.baseUrl as string | undefined) ?? env.ANTHROPIC_BASE_URL,\n headers: setting.headers as Record<string, string> | undefined,\n }\n }\n case \"google\": {\n const apiKey = env.GOOGLE_GENERATIVE_AI_API_KEY\n if (!apiKey) throw new Error(\"GOOGLE_GENERATIVE_AI_API_KEY is not set\")\n return {\n providerName: \"google\",\n apiKey,\n baseUrl: (setting.baseUrl as string | undefined) ?? env.GOOGLE_GENERATIVE_AI_BASE_URL,\n headers: setting.headers as Record<string, string> | undefined,\n }\n }\n case \"openai\": {\n const apiKey = env.OPENAI_API_KEY\n if (!apiKey) throw new Error(\"OPENAI_API_KEY is not set\")\n return {\n providerName: \"openai\",\n apiKey,\n baseUrl: (setting.baseUrl as string | undefined) ?? env.OPENAI_BASE_URL,\n organization: (setting.organization as string | undefined) ?? env.OPENAI_ORGANIZATION,\n project: (setting.project as string | undefined) ?? env.OPENAI_PROJECT,\n name: setting.name as string | undefined,\n headers: setting.headers as Record<string, string> | undefined,\n }\n }\n case \"ollama\": {\n return {\n providerName: \"ollama\",\n baseUrl: (setting.baseUrl as string | undefined) ?? env.OLLAMA_BASE_URL,\n headers: setting.headers as Record<string, string> | undefined,\n }\n }\n case \"azure-openai\": {\n const apiKey = env.AZURE_API_KEY\n if (!apiKey) throw new Error(\"AZURE_API_KEY is not set\")\n const resourceName = (setting.resourceName as string | undefined) ?? env.AZURE_RESOURCE_NAME\n const baseUrl = (setting.baseUrl as string | undefined) ?? env.AZURE_BASE_URL\n if (!resourceName && !baseUrl) throw new Error(\"AZURE_RESOURCE_NAME or baseUrl is not set\")\n return {\n providerName: \"azure-openai\",\n apiKey,\n resourceName,\n apiVersion: (setting.apiVersion as string | undefined) ?? env.AZURE_API_VERSION,\n baseUrl,\n headers: setting.headers as Record<string, string> | undefined,\n useDeploymentBasedUrls: setting.useDeploymentBasedUrls as boolean | undefined,\n }\n }\n case \"amazon-bedrock\": {\n const accessKeyId = env.AWS_ACCESS_KEY_ID\n const secretAccessKey = env.AWS_SECRET_ACCESS_KEY\n const sessionToken = env.AWS_SESSION_TOKEN\n if (!accessKeyId) throw new Error(\"AWS_ACCESS_KEY_ID is not set\")\n if (!secretAccessKey) throw new Error(\"AWS_SECRET_ACCESS_KEY is not set\")\n const region = (setting.region as string | undefined) ?? env.AWS_REGION\n if (!region) throw new Error(\"AWS_REGION is not set\")\n return {\n providerName: \"amazon-bedrock\",\n accessKeyId,\n secretAccessKey,\n region,\n sessionToken,\n }\n }\n case \"google-vertex\": {\n return {\n providerName: \"google-vertex\",\n project: (setting.project as string | undefined) ?? env.GOOGLE_VERTEX_PROJECT,\n location: (setting.location as string | undefined) ?? env.GOOGLE_VERTEX_LOCATION,\n baseUrl: (setting.baseUrl as string | undefined) ?? env.GOOGLE_VERTEX_BASE_URL,\n headers: setting.headers as Record<string, string> | undefined,\n }\n }\n case \"deepseek\": {\n const apiKey = env.DEEPSEEK_API_KEY\n if (!apiKey) throw new Error(\"DEEPSEEK_API_KEY is not set\")\n return {\n providerName: \"deepseek\",\n apiKey,\n baseUrl: (setting.baseUrl as string | undefined) ?? env.DEEPSEEK_BASE_URL,\n headers: setting.headers as Record<string, string> | undefined,\n }\n }\n }\n}\n","import type { PerstackConfig, ProviderConfig, ProviderName } from \"@perstack/core\"\nimport { getEnv } from \"./get-env.js\"\nimport { getPerstackConfig } from \"./perstack-toml.js\"\nimport { getProviderConfig } from \"./provider-config.js\"\n\nconst defaultProvider: ProviderName = \"anthropic\"\nconst defaultModel = \"claude-sonnet-4-5\"\n\nexport type ExpertConfig = NonNullable<PerstackConfig[\"experts\"]>[string]\n\nexport type RunContext = {\n perstackConfig: PerstackConfig\n env: Record<string, string>\n providerConfig: ProviderConfig\n model: string\n experts: Record<string, ExpertConfig & { key: string; name: string; version: string }>\n}\n\nexport type ResolveRunContextInput = {\n configPath?: string\n provider?: string\n model?: string\n envPath?: string[]\n}\n\nexport async function resolveRunContext(input: ResolveRunContextInput): Promise<RunContext> {\n const perstackConfig = await getPerstackConfig(input.configPath)\n const env = getEnv(input.envPath ?? perstackConfig.envPath ?? [\".env\", \".env.local\"])\n const provider = (input.provider ??\n perstackConfig.provider?.providerName ??\n defaultProvider) as ProviderName\n const model = input.model ?? perstackConfig.model ?? defaultModel\n const providerConfig = getProviderConfig(provider, env, perstackConfig.provider)\n const experts = Object.fromEntries(\n Object.entries(perstackConfig.experts ?? {}).map(([name, expert]) => {\n return [\n name,\n {\n key: name,\n name,\n version: expert.version ?? \"1.0.0\",\n description: expert.description,\n instruction: expert.instruction,\n skills: expert.skills ?? {},\n delegates: expert.delegates ?? [],\n tags: expert.tags ?? [],\n },\n ]\n }),\n )\n return {\n perstackConfig,\n env,\n providerConfig,\n model,\n experts: experts as Record<\n string,\n ExpertConfig & { key: string; name: string; version: string }\n >,\n }\n}\n","#!/usr/bin/env node\n\nimport type { Checkpoint, RunEvent, RuntimeEvent } from \"@perstack/core\"\nimport { parseWithFriendlyError, runCommandInputSchema } from \"@perstack/core\"\nimport { Command } from \"commander\"\nimport pkg from \"../package.json\" with { type: \"json\" }\nimport { resolveRunContext } from \"../src/cli/context.js\"\nimport { run } from \"../src/run.js\"\n\nconst defaultEventListener = (event: RunEvent | RuntimeEvent) => console.log(JSON.stringify(event))\n\nconst checkpointStore = new Map<string, Checkpoint>()\nconst storeCheckpoint = async (checkpoint: Checkpoint) => {\n checkpointStore.set(checkpoint.id, checkpoint)\n}\nconst retrieveCheckpoint = async (_jobId: string, checkpointId: string) => {\n const checkpoint = checkpointStore.get(checkpointId)\n if (!checkpoint) {\n throw new Error(`Checkpoint not found: ${checkpointId}`)\n }\n return checkpoint\n}\n\nconst program = new Command()\n .name(\"perstack-runtime\")\n .description(\"Perstack Runtime CLI - Execute Experts directly\")\n .version(pkg.version)\n\nprogram\n .command(\"run\")\n .description(\"Run an Expert with JSON event output\")\n .argument(\"<expertKey>\", \"Expert key to run\")\n .argument(\"<query>\", \"Query to run\")\n .option(\"--config <configPath>\", \"Path to perstack.toml config file\")\n .option(\"--provider <provider>\", \"Provider to use\")\n .option(\"--model <model>\", \"Model to use\")\n .option(\"--temperature <temperature>\", \"Temperature for the model, default is 0.3\")\n .option(\n \"--max-steps <maxSteps>\",\n \"Maximum number of steps to run, default is undefined (no limit)\",\n )\n .option(\"--max-retries <maxRetries>\", \"Maximum number of generation retries, default is 5\")\n .option(\n \"--timeout <timeout>\",\n \"Timeout for each generation in milliseconds, default is 60000 (1 minute)\",\n )\n .option(\"--job-id <jobId>\", \"Job ID for identifying the job\")\n .option(\"--run-id <runId>\", \"Run ID for identifying the run\")\n .option(\n \"--env-path <path>\",\n \"Path to the environment file (can be specified multiple times), default is .env and .env.local\",\n (value: string, previous: string[]) => previous.concat(value),\n [] as string[],\n )\n .option(\"--verbose\", \"Enable verbose logging\")\n .action(async (expertKey, query, options) => {\n const input = parseWithFriendlyError(runCommandInputSchema, { expertKey, query, options })\n try {\n const { perstackConfig, env, providerConfig, model, experts } = await resolveRunContext({\n configPath: input.options.config,\n provider: input.options.provider,\n model: input.options.model,\n envPath: input.options.envPath,\n })\n await run(\n {\n setting: {\n jobId: input.options.jobId,\n runId: input.options.runId,\n expertKey: input.expertKey,\n input: { text: input.query },\n experts,\n model,\n providerConfig,\n temperature: input.options.temperature ?? perstackConfig.temperature,\n maxSteps: input.options.maxSteps ?? perstackConfig.maxSteps,\n maxRetries: input.options.maxRetries ?? perstackConfig.maxRetries,\n timeout: input.options.timeout ?? perstackConfig.timeout,\n perstackApiBaseUrl: perstackConfig.perstackApiBaseUrl,\n perstackApiKey: env.PERSTACK_API_KEY,\n perstackBaseSkillCommand: perstackConfig.perstackBaseSkillCommand,\n env,\n proxyUrl: process.env.PERSTACK_PROXY_URL,\n verbose: input.options.verbose,\n },\n },\n { eventListener: defaultEventListener, storeCheckpoint, retrieveCheckpoint },\n )\n } catch (error) {\n if (error instanceof Error) {\n console.error(error.message)\n } else {\n console.error(error)\n }\n process.exit(1)\n }\n })\n\nprogram.parse()\n"]}
1
+ {"version":3,"sources":["../../src/cli/get-env.ts","../../src/cli/perstack-toml.ts","../../src/cli/provider-config.ts","../../src/cli/context.ts","../../bin/cli.ts"],"names":["parseWithFriendlyError"],"mappings":"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","file":"cli.js","sourcesContent":["import dotenv from \"dotenv\"\n\nexport function getEnv(envPath: string[]): Record<string, string> {\n const env: Record<string, string> = Object.fromEntries(\n Object.entries(process.env)\n .filter(([_, value]) => !!value)\n .map(([key, value]) => [key, value as string]),\n )\n dotenv.config({ path: envPath, processEnv: env, quiet: true })\n return env\n}\n","import { readFile } from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { type PerstackConfig, parseWithFriendlyError, perstackConfigSchema } from \"@perstack/core\"\nimport TOML from \"smol-toml\"\n\nconst ALLOWED_CONFIG_HOSTS = [\"raw.githubusercontent.com\"]\n\nexport async function getPerstackConfig(configPath?: string): Promise<PerstackConfig> {\n const configString = await findPerstackConfigString(configPath)\n if (configString === null) {\n throw new Error(\"perstack.toml not found. Create one or specify --config path.\")\n }\n return await parsePerstackConfig(configString)\n}\n\nfunction isRemoteUrl(configPath: string): boolean {\n const lower = configPath.toLowerCase()\n return lower.startsWith(\"https://\") || lower.startsWith(\"http://\")\n}\n\nasync function fetchRemoteConfig(url: string): Promise<string> {\n let parsed: URL\n try {\n parsed = new URL(url)\n } catch {\n throw new Error(`Invalid remote config URL: ${url}`)\n }\n if (parsed.protocol !== \"https:\") {\n throw new Error(\"Remote config requires HTTPS\")\n }\n if (!ALLOWED_CONFIG_HOSTS.includes(parsed.hostname)) {\n throw new Error(`Remote config only allowed from: ${ALLOWED_CONFIG_HOSTS.join(\", \")}`)\n }\n try {\n const response = await fetch(url, { redirect: \"error\" })\n if (!response.ok) {\n throw new Error(`${response.status} ${response.statusText}`)\n }\n return await response.text()\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new Error(`Failed to fetch remote config: ${message}`)\n }\n}\n\nasync function findPerstackConfigString(configPath?: string): Promise<string | null> {\n if (configPath) {\n if (isRemoteUrl(configPath)) {\n return await fetchRemoteConfig(configPath)\n }\n try {\n const tomlString = await readFile(path.resolve(process.cwd(), configPath), \"utf-8\")\n return tomlString\n } catch {\n throw new Error(`Given config path \"${configPath}\" is not found`)\n }\n }\n return await findPerstackConfigStringRecursively(path.resolve(process.cwd()))\n}\n\nasync function findPerstackConfigStringRecursively(cwd: string): Promise<string | null> {\n try {\n const tomlString = await readFile(path.resolve(cwd, \"perstack.toml\"), \"utf-8\")\n return tomlString\n } catch {\n if (cwd === path.parse(cwd).root) {\n return null\n }\n return await findPerstackConfigStringRecursively(path.dirname(cwd))\n }\n}\n\nasync function parsePerstackConfig(config: string): Promise<PerstackConfig> {\n const toml = TOML.parse(config ?? \"\")\n return parseWithFriendlyError(perstackConfigSchema, toml, \"perstack.toml\")\n}\n","import type { ProviderConfig, ProviderName, ProviderTable } from \"@perstack/core\"\n\ntype SettingRecord = Record<string, unknown>\n\nexport function getProviderConfig(\n provider: ProviderName,\n env: Record<string, string>,\n providerTable?: ProviderTable,\n): ProviderConfig {\n const setting = (providerTable?.setting ?? {}) as SettingRecord\n switch (provider) {\n case \"anthropic\": {\n const apiKey = env.ANTHROPIC_API_KEY\n if (!apiKey) throw new Error(\"ANTHROPIC_API_KEY is not set\")\n return {\n providerName: \"anthropic\",\n apiKey,\n baseUrl: (setting.baseUrl as string | undefined) ?? env.ANTHROPIC_BASE_URL,\n headers: setting.headers as Record<string, string> | undefined,\n }\n }\n case \"google\": {\n const apiKey = env.GOOGLE_GENERATIVE_AI_API_KEY\n if (!apiKey) throw new Error(\"GOOGLE_GENERATIVE_AI_API_KEY is not set\")\n return {\n providerName: \"google\",\n apiKey,\n baseUrl: (setting.baseUrl as string | undefined) ?? env.GOOGLE_GENERATIVE_AI_BASE_URL,\n headers: setting.headers as Record<string, string> | undefined,\n }\n }\n case \"openai\": {\n const apiKey = env.OPENAI_API_KEY\n if (!apiKey) throw new Error(\"OPENAI_API_KEY is not set\")\n return {\n providerName: \"openai\",\n apiKey,\n baseUrl: (setting.baseUrl as string | undefined) ?? env.OPENAI_BASE_URL,\n organization: (setting.organization as string | undefined) ?? env.OPENAI_ORGANIZATION,\n project: (setting.project as string | undefined) ?? env.OPENAI_PROJECT,\n name: setting.name as string | undefined,\n headers: setting.headers as Record<string, string> | undefined,\n }\n }\n case \"ollama\": {\n return {\n providerName: \"ollama\",\n baseUrl: (setting.baseUrl as string | undefined) ?? env.OLLAMA_BASE_URL,\n headers: setting.headers as Record<string, string> | undefined,\n }\n }\n case \"azure-openai\": {\n const apiKey = env.AZURE_API_KEY\n if (!apiKey) throw new Error(\"AZURE_API_KEY is not set\")\n const resourceName = (setting.resourceName as string | undefined) ?? env.AZURE_RESOURCE_NAME\n const baseUrl = (setting.baseUrl as string | undefined) ?? env.AZURE_BASE_URL\n if (!resourceName && !baseUrl) throw new Error(\"AZURE_RESOURCE_NAME or baseUrl is not set\")\n return {\n providerName: \"azure-openai\",\n apiKey,\n resourceName,\n apiVersion: (setting.apiVersion as string | undefined) ?? env.AZURE_API_VERSION,\n baseUrl,\n headers: setting.headers as Record<string, string> | undefined,\n useDeploymentBasedUrls: setting.useDeploymentBasedUrls as boolean | undefined,\n }\n }\n case \"amazon-bedrock\": {\n const accessKeyId = env.AWS_ACCESS_KEY_ID\n const secretAccessKey = env.AWS_SECRET_ACCESS_KEY\n const sessionToken = env.AWS_SESSION_TOKEN\n if (!accessKeyId) throw new Error(\"AWS_ACCESS_KEY_ID is not set\")\n if (!secretAccessKey) throw new Error(\"AWS_SECRET_ACCESS_KEY is not set\")\n const region = (setting.region as string | undefined) ?? env.AWS_REGION\n if (!region) throw new Error(\"AWS_REGION is not set\")\n return {\n providerName: \"amazon-bedrock\",\n accessKeyId,\n secretAccessKey,\n region,\n sessionToken,\n }\n }\n case \"google-vertex\": {\n return {\n providerName: \"google-vertex\",\n project: (setting.project as string | undefined) ?? env.GOOGLE_VERTEX_PROJECT,\n location: (setting.location as string | undefined) ?? env.GOOGLE_VERTEX_LOCATION,\n baseUrl: (setting.baseUrl as string | undefined) ?? env.GOOGLE_VERTEX_BASE_URL,\n headers: setting.headers as Record<string, string> | undefined,\n }\n }\n case \"deepseek\": {\n const apiKey = env.DEEPSEEK_API_KEY\n if (!apiKey) throw new Error(\"DEEPSEEK_API_KEY is not set\")\n return {\n providerName: \"deepseek\",\n apiKey,\n baseUrl: (setting.baseUrl as string | undefined) ?? env.DEEPSEEK_BASE_URL,\n headers: setting.headers as Record<string, string> | undefined,\n }\n }\n }\n}\n","import type { PerstackConfig, ProviderConfig, ProviderName } from \"@perstack/core\"\nimport { getEnv } from \"./get-env.js\"\nimport { getPerstackConfig } from \"./perstack-toml.js\"\nimport { getProviderConfig } from \"./provider-config.js\"\n\nconst defaultProvider: ProviderName = \"anthropic\"\nconst defaultModel = \"claude-sonnet-4-5\"\n\nexport type ExpertConfig = NonNullable<PerstackConfig[\"experts\"]>[string]\n\nexport type RunContext = {\n perstackConfig: PerstackConfig\n env: Record<string, string>\n providerConfig: ProviderConfig\n model: string\n experts: Record<string, ExpertConfig & { key: string; name: string; version: string }>\n}\n\nexport type ResolveRunContextInput = {\n configPath?: string\n provider?: string\n model?: string\n envPath?: string[]\n}\n\nexport async function resolveRunContext(input: ResolveRunContextInput): Promise<RunContext> {\n const perstackConfig = await getPerstackConfig(input.configPath)\n const envPath =\n input.envPath && input.envPath.length > 0\n ? input.envPath\n : (perstackConfig.envPath ?? [\".env\", \".env.local\"])\n const env = getEnv(envPath)\n const provider = (input.provider ??\n perstackConfig.provider?.providerName ??\n defaultProvider) as ProviderName\n const model = input.model ?? perstackConfig.model ?? defaultModel\n const providerConfig = getProviderConfig(provider, env, perstackConfig.provider)\n const experts = Object.fromEntries(\n Object.entries(perstackConfig.experts ?? {}).map(([name, expert]) => {\n return [\n name,\n {\n key: name,\n name,\n version: expert.version ?? \"1.0.0\",\n description: expert.description,\n instruction: expert.instruction,\n skills: expert.skills ?? {},\n delegates: expert.delegates ?? [],\n tags: expert.tags ?? [],\n },\n ]\n }),\n )\n return {\n perstackConfig,\n env,\n providerConfig,\n model,\n experts: experts as Record<\n string,\n ExpertConfig & { key: string; name: string; version: string }\n >,\n }\n}\n","#!/usr/bin/env node\n\nimport type { Checkpoint, RunEvent, RuntimeEvent } from \"@perstack/core\"\nimport { parseWithFriendlyError, runCommandInputSchema } from \"@perstack/core\"\nimport { Command } from \"commander\"\nimport pkg from \"../package.json\" with { type: \"json\" }\nimport { resolveRunContext } from \"../src/cli/context.js\"\nimport { findLockfile, loadLockfile } from \"../src/helpers/lockfile.js\"\nimport { run } from \"../src/run.js\"\n\nconst defaultEventListener = (event: RunEvent | RuntimeEvent) => console.log(JSON.stringify(event))\n\nconst checkpointStore = new Map<string, Checkpoint>()\nconst storeCheckpoint = async (checkpoint: Checkpoint) => {\n checkpointStore.set(checkpoint.id, checkpoint)\n}\nconst retrieveCheckpoint = async (_jobId: string, checkpointId: string) => {\n const checkpoint = checkpointStore.get(checkpointId)\n if (!checkpoint) {\n throw new Error(`Checkpoint not found: ${checkpointId}`)\n }\n return checkpoint\n}\n\nconst program = new Command()\n .name(\"perstack-runtime\")\n .description(\"Perstack Runtime CLI - Execute Experts directly\")\n .version(pkg.version)\n\nprogram\n .command(\"run\")\n .description(\"Run an Expert with JSON event output\")\n .argument(\"<expertKey>\", \"Expert key to run\")\n .argument(\"<query>\", \"Query to run\")\n .option(\"--config <configPath>\", \"Path to perstack.toml config file\")\n .option(\"--provider <provider>\", \"Provider to use\")\n .option(\"--model <model>\", \"Model to use\")\n .option(\n \"--reasoning-budget <budget>\",\n \"Reasoning budget for native LLM reasoning (minimal, low, medium, high, or token count)\",\n )\n .option(\n \"--max-steps <maxSteps>\",\n \"Maximum number of steps to run, default is undefined (no limit)\",\n )\n .option(\"--max-retries <maxRetries>\", \"Maximum number of generation retries, default is 5\")\n .option(\n \"--timeout <timeout>\",\n \"Timeout for each generation in milliseconds, default is 60000 (1 minute)\",\n )\n .option(\"--job-id <jobId>\", \"Job ID for identifying the job\")\n .option(\"--run-id <runId>\", \"Run ID for identifying the run\")\n .option(\n \"--env-path <path>\",\n \"Path to the environment file (can be specified multiple times), default is .env and .env.local\",\n (value: string, previous: string[]) => previous.concat(value),\n [] as string[],\n )\n .option(\"--verbose\", \"Enable verbose logging\")\n .action(async (expertKey, query, options) => {\n const input = parseWithFriendlyError(runCommandInputSchema, { expertKey, query, options })\n try {\n const { perstackConfig, env, providerConfig, model, experts } = await resolveRunContext({\n configPath: input.options.config,\n provider: input.options.provider,\n model: input.options.model,\n envPath: input.options.envPath,\n })\n const lockfilePath = findLockfile(input.options.config)\n const lockfile = lockfilePath ? (loadLockfile(lockfilePath) ?? undefined) : undefined\n await run(\n {\n setting: {\n jobId: input.options.jobId,\n runId: input.options.runId,\n expertKey: input.expertKey,\n input: { text: input.query },\n experts,\n model,\n providerConfig,\n reasoningBudget: input.options.reasoningBudget ?? perstackConfig.reasoningBudget,\n maxSteps: input.options.maxSteps ?? perstackConfig.maxSteps,\n maxRetries: input.options.maxRetries ?? perstackConfig.maxRetries,\n timeout: input.options.timeout ?? perstackConfig.timeout,\n perstackApiBaseUrl: perstackConfig.perstackApiBaseUrl,\n perstackApiKey: env.PERSTACK_API_KEY,\n perstackBaseSkillCommand: perstackConfig.perstackBaseSkillCommand,\n env,\n proxyUrl: process.env.PERSTACK_PROXY_URL,\n verbose: input.options.verbose,\n },\n },\n { eventListener: defaultEventListener, storeCheckpoint, retrieveCheckpoint, lockfile },\n )\n } catch (error) {\n if (error instanceof Error) {\n console.error(error.message)\n } else {\n console.error(error)\n }\n process.exit(1)\n }\n })\n\nprogram.parse()\n"]}