@mutagent/cli 0.1.12 → 0.1.13

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/dist/bin/cli.js CHANGED
@@ -439,9 +439,9 @@ class SDKClientWrapper {
439
439
  systemPrompt: data.systemPrompt ?? undefined,
440
440
  humanPrompt: data.humanPrompt ?? undefined,
441
441
  rawPrompt: data.rawPrompt ?? undefined,
442
- inputSchema: data.inputSchema ?? {},
443
- outputSchema: data.outputSchema,
444
- metadata: data.metadata,
442
+ inputSchema: data.inputSchema ?? undefined,
443
+ outputSchema: data.outputSchema ?? undefined,
444
+ metadata: data.metadata ?? undefined,
445
445
  tags: data.tags ?? undefined
446
446
  });
447
447
  return response;
@@ -1628,11 +1628,85 @@ function providerSettingsLink() {
1628
1628
  }
1629
1629
  function promptLinks(promptId) {
1630
1630
  return {
1631
- view: promptLink(promptId),
1631
+ dashboard: promptLink(promptId),
1632
+ api: `/api/prompts/${String(promptId)}`,
1632
1633
  datasets: promptDatasetsLink(promptId),
1633
1634
  evaluations: promptEvaluationsLink(promptId)
1634
1635
  };
1635
1636
  }
1637
+ function datasetLinks(promptId, datasetId) {
1638
+ return {
1639
+ dashboard: datasetLink(promptId, datasetId),
1640
+ api: `/api/prompts/${String(promptId)}/datasets/${String(datasetId)}`
1641
+ };
1642
+ }
1643
+ function evaluationLinks(promptId, evalId) {
1644
+ return {
1645
+ dashboard: evaluationLink(promptId, evalId),
1646
+ api: `/api/prompts/${String(promptId)}/evaluations/${String(evalId)}`
1647
+ };
1648
+ }
1649
+ function formatCreationHints(hint) {
1650
+ const lines = [
1651
+ "",
1652
+ ` -> View in dashboard: ${hint.dashboardUrl}`,
1653
+ ` -> API: GET ${hint.apiPath}`,
1654
+ "",
1655
+ " Tip: Copy the link above to open in your browser or share with your team."
1656
+ ];
1657
+ return lines.join(`
1658
+ `);
1659
+ }
1660
+
1661
+ // src/lib/schema-helpers.ts
1662
+ var SUPPORTED_SCHEMA_TYPES = ["string", "number", "boolean", "array", "object"];
1663
+ function isValidJsonSchema(schema) {
1664
+ if (schema === null || schema === undefined)
1665
+ return false;
1666
+ if (typeof schema !== "object")
1667
+ return false;
1668
+ if (Array.isArray(schema))
1669
+ return false;
1670
+ const obj = schema;
1671
+ if (!("type" in obj) || typeof obj.type !== "string")
1672
+ return false;
1673
+ if (obj.type === "object") {
1674
+ if (!("properties" in obj) || typeof obj.properties !== "object" || obj.properties === null) {
1675
+ return false;
1676
+ }
1677
+ }
1678
+ return true;
1679
+ }
1680
+ function buildSchemaFromVariables(variables) {
1681
+ const properties = {};
1682
+ for (const variable of variables) {
1683
+ const prop = { type: variable.type };
1684
+ if (variable.description) {
1685
+ prop.description = variable.description;
1686
+ }
1687
+ properties[variable.name] = prop;
1688
+ }
1689
+ return {
1690
+ type: "object",
1691
+ properties
1692
+ };
1693
+ }
1694
+ function formatSchemaWarning(fieldName) {
1695
+ return [
1696
+ `${fieldName} doesn't appear to be a valid JSON Schema.`,
1697
+ "",
1698
+ " Expected format:",
1699
+ " {",
1700
+ ' "type": "object",',
1701
+ ' "properties": {',
1702
+ ' "variable_name": { "type": "string", "description": "Description here" }',
1703
+ " }",
1704
+ " }",
1705
+ "",
1706
+ " You can also provide a schema file: mutagent prompts create --file schema.json"
1707
+ ].join(`
1708
+ `);
1709
+ }
1636
1710
 
1637
1711
  // src/commands/prompts.ts
1638
1712
  var PREREQUISITES_TEXT = `
@@ -1659,6 +1733,117 @@ function parseValidationErrors(error) {
1659
1733
  }
1660
1734
  return ["An unknown error occurred"];
1661
1735
  }
1736
+ function isSchemaEmpty(schema) {
1737
+ if (schema === undefined || schema === null)
1738
+ return true;
1739
+ if (typeof schema !== "object")
1740
+ return false;
1741
+ const obj = schema;
1742
+ if (Object.keys(obj).length === 0)
1743
+ return true;
1744
+ return false;
1745
+ }
1746
+ function warnMissingSchemas(data, output) {
1747
+ if (isSchemaEmpty(data.inputSchema)) {
1748
+ output.warn("No inputSchema provided. Optimization requires inputSchema with defined variables.");
1749
+ } else if (!isValidJsonSchema(data.inputSchema)) {
1750
+ output.warn(formatSchemaWarning("inputSchema"));
1751
+ }
1752
+ if (isSchemaEmpty(data.outputSchema)) {
1753
+ output.warn("No outputSchema provided. This may limit optimization effectiveness.");
1754
+ } else if (!isValidJsonSchema(data.outputSchema)) {
1755
+ output.warn(formatSchemaWarning("outputSchema"));
1756
+ }
1757
+ }
1758
+ async function collectSchemaInteractively() {
1759
+ const inquirer3 = (await import("inquirer")).default;
1760
+ const variables = [];
1761
+ let addMore = true;
1762
+ while (addMore) {
1763
+ const answers = await inquirer3.prompt([
1764
+ {
1765
+ type: "input",
1766
+ name: "name",
1767
+ message: "Variable name:",
1768
+ validate: (input) => {
1769
+ if (!input.trim())
1770
+ return "Variable name is required";
1771
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(input.trim())) {
1772
+ return "Variable name must start with a letter/underscore and contain only alphanumeric/underscore";
1773
+ }
1774
+ return true;
1775
+ }
1776
+ },
1777
+ {
1778
+ type: "list",
1779
+ name: "type",
1780
+ message: "Variable type:",
1781
+ choices: [...SUPPORTED_SCHEMA_TYPES]
1782
+ },
1783
+ {
1784
+ type: "input",
1785
+ name: "description",
1786
+ message: "Description (optional):"
1787
+ }
1788
+ ]);
1789
+ variables.push({
1790
+ name: answers.name.trim(),
1791
+ type: answers.type,
1792
+ description: answers.description.trim() || undefined
1793
+ });
1794
+ const continueAnswer = await inquirer3.prompt([{
1795
+ type: "confirm",
1796
+ name: "addAnother",
1797
+ message: "Add another variable?",
1798
+ default: false
1799
+ }]);
1800
+ addMore = continueAnswer.addAnother;
1801
+ }
1802
+ return buildSchemaFromVariables(variables);
1803
+ }
1804
+ async function promptForInputSchema() {
1805
+ const inquirer3 = (await import("inquirer")).default;
1806
+ const answer = await inquirer3.prompt([{
1807
+ type: "list",
1808
+ name: "choice",
1809
+ message: "Would you like to define input variables for this prompt?",
1810
+ choices: [
1811
+ { name: "Yes, define variables interactively", value: "interactive" },
1812
+ { name: "Provide a JSON Schema file path", value: "file" },
1813
+ { name: "Skip (not recommended for optimization)", value: "skip" }
1814
+ ]
1815
+ }]);
1816
+ if (answer.choice === "interactive") {
1817
+ return collectSchemaInteractively();
1818
+ }
1819
+ if (answer.choice === "file") {
1820
+ const fileAnswer = await inquirer3.prompt([{
1821
+ type: "input",
1822
+ name: "path",
1823
+ message: "JSON Schema file path:",
1824
+ validate: (input) => {
1825
+ if (!input.trim())
1826
+ return "File path is required";
1827
+ if (!existsSync2(input.trim()))
1828
+ return `File not found: ${input.trim()}`;
1829
+ return true;
1830
+ }
1831
+ }]);
1832
+ const content = readFileSync2(fileAnswer.path.trim(), "utf-8");
1833
+ try {
1834
+ const parsed = JSON.parse(content);
1835
+ if (!isValidJsonSchema(parsed)) {
1836
+ console.log(chalk4.yellow(`
1837
+ Warning: ${formatSchemaWarning("inputSchema")}
1838
+ `));
1839
+ }
1840
+ return parsed;
1841
+ } catch {
1842
+ throw new MutagentError("INVALID_JSON", `Failed to parse JSON Schema from ${fileAnswer.path.trim()}`, "Ensure the file contains valid JSON");
1843
+ }
1844
+ }
1845
+ return;
1846
+ }
1662
1847
  function warnSingleBraceVariables(content, output) {
1663
1848
  const singleBracePattern = /(?<!\{)\{([a-zA-Z_][a-zA-Z0-9_]*)\}(?!\})/g;
1664
1849
  const matches = [...content.matchAll(singleBracePattern)];
@@ -1850,14 +2035,31 @@ ${chalk4.dim("Hint: Use --file with JSON or --raw-file for plain text. Get promp
1850
2035
  if (promptContent && !isJson) {
1851
2036
  warnSingleBraceVariables(promptContent, output);
1852
2037
  }
2038
+ if (!isJson && isSchemaEmpty(data.inputSchema)) {
2039
+ if (process.stdin.isTTY) {
2040
+ const schema = await promptForInputSchema();
2041
+ if (schema) {
2042
+ data.inputSchema = schema;
2043
+ }
2044
+ } else {
2045
+ output.warn("No inputSchema provided. Optimization requires inputSchema with defined variables.");
2046
+ }
2047
+ }
2048
+ warnMissingSchemas(data, output);
1853
2049
  const client = getSDKClient();
1854
2050
  const prompt = await client.createPrompt(data);
1855
2051
  if (isJson) {
1856
2052
  output.output({ ...prompt, _links: promptLinks(prompt.id) });
1857
2053
  } else {
1858
- output.success(`Created prompt: ${prompt.name}`);
1859
- output.output(prompt);
1860
- output.info(`View: ${promptLink(prompt.id)}`);
2054
+ output.success(`Created prompt: ${prompt.name} (id: ${String(prompt.id)})`);
2055
+ const hints = formatCreationHints({
2056
+ resourceType: "Prompt",
2057
+ id: prompt.id,
2058
+ name: prompt.name,
2059
+ dashboardUrl: promptLink(prompt.id),
2060
+ apiPath: `/api/prompts/${String(prompt.id)}`
2061
+ });
2062
+ console.log(hints);
1861
2063
  }
1862
2064
  } catch (error) {
1863
2065
  handleError(error, isJson);
@@ -1924,8 +2126,15 @@ Examples:
1924
2126
  if (isJson) {
1925
2127
  output.output({ ...prompt, _links: promptLinks(prompt.id) });
1926
2128
  } else {
1927
- output.success(`Updated prompt: ${prompt.name}`);
1928
- output.output(prompt);
2129
+ output.success(`Updated prompt: ${prompt.name} (id: ${String(prompt.id)})`);
2130
+ const hints = formatCreationHints({
2131
+ resourceType: "Prompt",
2132
+ id: prompt.id,
2133
+ name: prompt.name,
2134
+ dashboardUrl: promptLink(prompt.id),
2135
+ apiPath: `/api/prompts/${String(prompt.id)}`
2136
+ });
2137
+ console.log(hints);
1929
2138
  }
1930
2139
  } catch (error) {
1931
2140
  handleError(error, isJson);
@@ -1981,7 +2190,7 @@ Examples:
1981
2190
  if (isJson) {
1982
2191
  const withLinks = datasets.map((d) => ({
1983
2192
  ...d,
1984
- _links: { view: datasetLink(promptId, d.id) }
2193
+ _links: datasetLinks(promptId, d.id)
1985
2194
  }));
1986
2195
  output.output(withLinks);
1987
2196
  } else {
@@ -2042,13 +2251,25 @@ ${chalk4.dim("Note: --file and -d are mutually exclusive. Provide one or the oth
2042
2251
  }
2043
2252
  const client = getSDKClient();
2044
2253
  const datasetResult = await client.addDataset(promptId, content, options.name);
2045
- if (!isJson) {
2046
- output.success(`Added dataset "${datasetResult.name}" to prompt: ${promptId}`);
2254
+ if (isJson) {
2255
+ output.output({
2256
+ ...datasetResult,
2257
+ _links: datasetLinks(promptId, datasetResult.id)
2258
+ });
2259
+ } else {
2260
+ output.success(`Added dataset "${datasetResult.name}" to prompt: ${promptId} (id: ${String(datasetResult.id)})`);
2047
2261
  if (datasetResult.itemCount !== undefined && datasetResult.itemCount > 0) {
2048
2262
  output.info(`Items uploaded: ${String(datasetResult.itemCount)}`);
2049
2263
  }
2264
+ const hints = formatCreationHints({
2265
+ resourceType: "Dataset",
2266
+ id: datasetResult.id,
2267
+ name: datasetResult.name,
2268
+ dashboardUrl: datasetLink(promptId, datasetResult.id),
2269
+ apiPath: `/api/prompts/${promptId}/datasets/${String(datasetResult.id)}`
2270
+ });
2271
+ console.log(hints);
2050
2272
  }
2051
- output.output(datasetResult);
2052
2273
  } catch (error) {
2053
2274
  handleError(error, isJson);
2054
2275
  }
@@ -2087,7 +2308,7 @@ Examples:
2087
2308
  if (isJson) {
2088
2309
  const withLinks = evals.map((e) => ({
2089
2310
  ...e,
2090
- _links: { view: evaluationLink(promptId, e.id) }
2311
+ _links: evaluationLinks(promptId, e.id)
2091
2312
  }));
2092
2313
  output.output(withLinks);
2093
2314
  } else {
@@ -2150,12 +2371,18 @@ ${chalk4.dim("Get prompt IDs: mutagent prompts list | Get dataset IDs: mutagent
2150
2371
  if (isJson) {
2151
2372
  output.output({
2152
2373
  ...evalResult,
2153
- _links: { view: evaluationLink(promptId, evalResult.id) }
2374
+ _links: evaluationLinks(promptId, evalResult.id)
2154
2375
  });
2155
2376
  } else {
2156
- output.success(`Created evaluation: ${evalResult.name}`);
2157
- output.output(evalResult);
2158
- output.info(`View: ${evaluationLink(promptId, evalResult.id)}`);
2377
+ output.success(`Created evaluation: ${evalResult.name} (id: ${String(evalResult.id)})`);
2378
+ const hints = formatCreationHints({
2379
+ resourceType: "Evaluation",
2380
+ id: evalResult.id,
2381
+ name: evalResult.name,
2382
+ dashboardUrl: evaluationLink(promptId, evalResult.id),
2383
+ apiPath: `/api/prompts/${promptId}/evaluations/${String(evalResult.id)}`
2384
+ });
2385
+ console.log(hints);
2159
2386
  }
2160
2387
  } catch (error) {
2161
2388
  handleError(error, isJson);
@@ -2206,11 +2433,22 @@ ${chalk4.dim("Monitor progress with: mutagent prompts optimize status <job-id>")
2206
2433
  evalModel: options.evalModel
2207
2434
  });
2208
2435
  if (isJson) {
2209
- output.output({ ...job, _links: { optimizer: optimizerLink(job.jobId) } });
2436
+ output.output({
2437
+ ...job,
2438
+ _links: {
2439
+ dashboard: optimizerLink(job.jobId),
2440
+ api: `/api/prompts/${promptId}/optimizations/${job.jobId}`
2441
+ }
2442
+ });
2210
2443
  } else {
2211
2444
  output.success(`Started optimization job: ${job.jobId}`);
2212
- output.output(job);
2213
- output.info(`Monitor: ${optimizerLink(job.jobId)}`);
2445
+ const hints = formatCreationHints({
2446
+ resourceType: "Optimization",
2447
+ id: job.jobId,
2448
+ dashboardUrl: optimizerLink(job.jobId),
2449
+ apiPath: `/api/prompts/${promptId}/optimizations/${job.jobId}`
2450
+ });
2451
+ console.log(hints);
2214
2452
  }
2215
2453
  } catch (error) {
2216
2454
  if (error instanceof ApiError) {
@@ -4945,5 +5183,5 @@ program.addCommand(createWorkspacesCommand());
4945
5183
  program.addCommand(createProvidersCommand());
4946
5184
  program.parse();
4947
5185
 
4948
- //# debugId=BAA438F82E7B39A164756E2164756E21
5186
+ //# debugId=EDFE2E68EFA4B20A64756E2164756E21
4949
5187
  //# sourceMappingURL=cli.js.map