propelix-cli 0.1.1 → 0.2.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/dist/index.cjs +260 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -19614,6 +19614,13 @@ function outputTable(columns, rows) {
|
|
|
19614
19614
|
function output(data, format, tableConfig) {
|
|
19615
19615
|
if (format === "table" && tableConfig) {
|
|
19616
19616
|
outputTable(tableConfig.columns, tableConfig.rows);
|
|
19617
|
+
if (data && typeof data === "object" && "total" in data && typeof data.total === "number") {
|
|
19618
|
+
const shown = tableConfig.rows.length;
|
|
19619
|
+
if (data.total > shown) {
|
|
19620
|
+
console.log(import_chalk2.default.dim(`
|
|
19621
|
+
Showing ${shown} of ${data.total} results. Use --limit and --offset to paginate.`));
|
|
19622
|
+
}
|
|
19623
|
+
}
|
|
19617
19624
|
} else {
|
|
19618
19625
|
outputJSON(data);
|
|
19619
19626
|
}
|
|
@@ -19976,6 +19983,136 @@ var CREATE_CHAT_MESSAGE_MUTATION = `
|
|
|
19976
19983
|
}
|
|
19977
19984
|
}
|
|
19978
19985
|
`;
|
|
19986
|
+
var EXPERIMENTS_QUERY = `
|
|
19987
|
+
query Experiments($pagination: PaginationInput, $filter: ExperimentFilter!) {
|
|
19988
|
+
experiments(pagination: $pagination, filter: $filter) {
|
|
19989
|
+
items {
|
|
19990
|
+
id
|
|
19991
|
+
title
|
|
19992
|
+
description
|
|
19993
|
+
project { id }
|
|
19994
|
+
creator { id firstName }
|
|
19995
|
+
startTime
|
|
19996
|
+
endTime
|
|
19997
|
+
variations
|
|
19998
|
+
result
|
|
19999
|
+
createdAt
|
|
20000
|
+
updatedAt
|
|
20001
|
+
cancelledAt
|
|
20002
|
+
}
|
|
20003
|
+
total
|
|
20004
|
+
}
|
|
20005
|
+
}
|
|
20006
|
+
`;
|
|
20007
|
+
var EXPERIMENT_QUERY = `
|
|
20008
|
+
query Experiment($id: ID!) {
|
|
20009
|
+
experiment(id: $id) {
|
|
20010
|
+
id
|
|
20011
|
+
title
|
|
20012
|
+
description
|
|
20013
|
+
project { id }
|
|
20014
|
+
creator { id firstName }
|
|
20015
|
+
startTime
|
|
20016
|
+
endTime
|
|
20017
|
+
variations
|
|
20018
|
+
result
|
|
20019
|
+
createdAt
|
|
20020
|
+
updatedAt
|
|
20021
|
+
cancelledAt
|
|
20022
|
+
controlVariationAgentVersions {
|
|
20023
|
+
agentName
|
|
20024
|
+
promptVersionName
|
|
20025
|
+
}
|
|
20026
|
+
testVariationAgentVersions {
|
|
20027
|
+
agentName
|
|
20028
|
+
promptVersionName
|
|
20029
|
+
}
|
|
20030
|
+
}
|
|
20031
|
+
}
|
|
20032
|
+
`;
|
|
20033
|
+
var EXPERIMENT_MESSAGE_RESPONSE_COMPARISONS_QUERY = `
|
|
20034
|
+
query GetExperimentMessageResponseComparisons(
|
|
20035
|
+
$experimentID: ID!
|
|
20036
|
+
$pagination: PaginationInput
|
|
20037
|
+
$filter: ExperimentMessageResponseComparisonFilter
|
|
20038
|
+
) {
|
|
20039
|
+
experimentMessageResponseComparisons(experimentID: $experimentID, pagination: $pagination, filter: $filter) {
|
|
20040
|
+
items {
|
|
20041
|
+
id
|
|
20042
|
+
experiment { id }
|
|
20043
|
+
targetMessage {
|
|
20044
|
+
id
|
|
20045
|
+
conversationID
|
|
20046
|
+
body
|
|
20047
|
+
authorType
|
|
20048
|
+
authorInfo { name }
|
|
20049
|
+
createdAt
|
|
20050
|
+
}
|
|
20051
|
+
testResponse {
|
|
20052
|
+
id
|
|
20053
|
+
variation
|
|
20054
|
+
runProjectResult
|
|
20055
|
+
finalAgentName
|
|
20056
|
+
metricsData
|
|
20057
|
+
logID
|
|
20058
|
+
createdAt
|
|
20059
|
+
}
|
|
20060
|
+
controlResponse {
|
|
20061
|
+
id
|
|
20062
|
+
variation
|
|
20063
|
+
runProjectResult
|
|
20064
|
+
finalAgentName
|
|
20065
|
+
metricsData
|
|
20066
|
+
logID
|
|
20067
|
+
createdAt
|
|
20068
|
+
}
|
|
20069
|
+
comparisonResult
|
|
20070
|
+
createdAt
|
|
20071
|
+
updatedAt
|
|
20072
|
+
}
|
|
20073
|
+
total
|
|
20074
|
+
}
|
|
20075
|
+
}
|
|
20076
|
+
`;
|
|
20077
|
+
var EXPERIMENT_MESSAGE_RESPONSE_COMPARISON_QUERY = `
|
|
20078
|
+
query GetExperimentMessageResponseComparison($experimentMessageResponseComparisonID: ID!) {
|
|
20079
|
+
experimentMessageResponseComparison(experimentMessageResponseComparisonID: $experimentMessageResponseComparisonID) {
|
|
20080
|
+
id
|
|
20081
|
+
experiment { id title }
|
|
20082
|
+
targetMessage {
|
|
20083
|
+
id
|
|
20084
|
+
conversationID
|
|
20085
|
+
body
|
|
20086
|
+
authorType
|
|
20087
|
+
authorInfo { name }
|
|
20088
|
+
imageURLs
|
|
20089
|
+
fileAttachments { url name mimeType }
|
|
20090
|
+
createdAt
|
|
20091
|
+
}
|
|
20092
|
+
testResponse {
|
|
20093
|
+
id
|
|
20094
|
+
variation
|
|
20095
|
+
runProjectResult
|
|
20096
|
+
finalAgentName
|
|
20097
|
+
metricsData
|
|
20098
|
+
logID
|
|
20099
|
+
createdAt
|
|
20100
|
+
}
|
|
20101
|
+
controlResponse {
|
|
20102
|
+
id
|
|
20103
|
+
variation
|
|
20104
|
+
runProjectResult
|
|
20105
|
+
finalAgentName
|
|
20106
|
+
metricsData
|
|
20107
|
+
logID
|
|
20108
|
+
createdAt
|
|
20109
|
+
}
|
|
20110
|
+
comparisonResult
|
|
20111
|
+
createdAt
|
|
20112
|
+
updatedAt
|
|
20113
|
+
}
|
|
20114
|
+
}
|
|
20115
|
+
`;
|
|
19979
20116
|
var CLEAR_CHAT_MESSAGES_MUTATION = `
|
|
19980
20117
|
mutation ClearChatMessages {
|
|
19981
20118
|
clearChatMessages
|
|
@@ -20468,6 +20605,126 @@ function registerConversationCommand(program3) {
|
|
|
20468
20605
|
});
|
|
20469
20606
|
}
|
|
20470
20607
|
|
|
20608
|
+
// src/commands/experiment.ts
|
|
20609
|
+
var EVALUATION_CATEGORIES = [
|
|
20610
|
+
"SubsetAndConsistent",
|
|
20611
|
+
"SupersetAndConsistent",
|
|
20612
|
+
"SameDetailsAsExpert",
|
|
20613
|
+
"DisagreementBetweenAnswers",
|
|
20614
|
+
"DifferencesDontMatter"
|
|
20615
|
+
];
|
|
20616
|
+
function experimentStatus(exp) {
|
|
20617
|
+
if (exp.cancelledAt) return "cancelled";
|
|
20618
|
+
if (exp.endTime) return "completed";
|
|
20619
|
+
if (exp.startTime) return "running";
|
|
20620
|
+
return "pending";
|
|
20621
|
+
}
|
|
20622
|
+
function registerExperimentCommand(program3) {
|
|
20623
|
+
const experiment = program3.command("experiment").description("Experiment (shadow test) operations");
|
|
20624
|
+
experiment.command("list").description("List experiments for the current project").option("--limit <n>", "Max results").option("--offset <n>", "Skip results").option("--date-from <ISO>", "Filter from date (ISO 8601)").option("--date-to <ISO>", "Filter to date (ISO 8601)").option("--from-file <path>", "Load params from JSON file").action(async (cmdOpts) => {
|
|
20625
|
+
try {
|
|
20626
|
+
const parentOpts = program3.opts();
|
|
20627
|
+
const opts = mergeFromFile(cmdOpts, cmdOpts.fromFile);
|
|
20628
|
+
const config = requireConfig(parentOpts);
|
|
20629
|
+
const projectID = requireProjectID(config);
|
|
20630
|
+
const client = createGraphQLClient(config);
|
|
20631
|
+
const filter = { projectID };
|
|
20632
|
+
if (opts.dateFrom && opts.dateTo) {
|
|
20633
|
+
filter.createdAtRange = [opts.dateFrom, opts.dateTo];
|
|
20634
|
+
} else if (opts.dateFrom) {
|
|
20635
|
+
filter.createdAtRange = [opts.dateFrom, (/* @__PURE__ */ new Date()).toISOString()];
|
|
20636
|
+
} else if (opts.dateTo) {
|
|
20637
|
+
filter.createdAtRange = [(/* @__PURE__ */ new Date(0)).toISOString(), opts.dateTo];
|
|
20638
|
+
}
|
|
20639
|
+
const data = await client.request(EXPERIMENTS_QUERY, {
|
|
20640
|
+
pagination: toPagination(opts),
|
|
20641
|
+
filter
|
|
20642
|
+
});
|
|
20643
|
+
output(data.experiments, parentOpts.format, {
|
|
20644
|
+
columns: ["id", "title", "status", "createdAt"],
|
|
20645
|
+
rows: data.experiments.items.map((e) => ({
|
|
20646
|
+
id: e.id,
|
|
20647
|
+
title: e.title,
|
|
20648
|
+
status: experimentStatus(e),
|
|
20649
|
+
createdAt: e.createdAt
|
|
20650
|
+
}))
|
|
20651
|
+
});
|
|
20652
|
+
} catch (error) {
|
|
20653
|
+
handleError(error);
|
|
20654
|
+
}
|
|
20655
|
+
});
|
|
20656
|
+
experiment.command("get").description("Get experiment detail").argument("<id>", "Experiment ID").action(async (id) => {
|
|
20657
|
+
try {
|
|
20658
|
+
const parentOpts = program3.opts();
|
|
20659
|
+
const config = requireConfig(parentOpts);
|
|
20660
|
+
const client = createGraphQLClient(config);
|
|
20661
|
+
const data = await client.request(EXPERIMENT_QUERY, { id });
|
|
20662
|
+
output(data.experiment, parentOpts.format);
|
|
20663
|
+
} catch (error) {
|
|
20664
|
+
handleError(error);
|
|
20665
|
+
}
|
|
20666
|
+
});
|
|
20667
|
+
const comparison = experiment.command("comparison").description("Message response comparison operations");
|
|
20668
|
+
comparison.command("list").description("List message response comparisons for an experiment").argument("<experiment-id>", "Experiment ID").option("--limit <n>", "Max results").option("--offset <n>", "Skip results").option("--evaluation-category <cat>", "Filter by evaluation category").addHelpText("after", `
|
|
20669
|
+
Valid evaluation categories: ${EVALUATION_CATEGORIES.join(", ")}`).option("--has-images <bool>", "Filter comparisons with/without images (true|false)").option("--has-file-attachments <bool>", "Filter comparisons with/without file attachments (true|false)").option("--has-failed-tool-calls <bool>", "Filter comparisons with/without failed tool calls (true|false)").option("--from-file <path>", "Load params from JSON file").action(async (experimentID, cmdOpts) => {
|
|
20670
|
+
try {
|
|
20671
|
+
const parentOpts = program3.opts();
|
|
20672
|
+
const opts = mergeFromFile(cmdOpts, cmdOpts.fromFile);
|
|
20673
|
+
const config = requireConfig(parentOpts);
|
|
20674
|
+
const client = createGraphQLClient(config);
|
|
20675
|
+
const filter = {};
|
|
20676
|
+
if (opts.evaluationCategory) {
|
|
20677
|
+
const cat = opts.evaluationCategory;
|
|
20678
|
+
if (!EVALUATION_CATEGORIES.includes(cat)) {
|
|
20679
|
+
throw new Error(
|
|
20680
|
+
`Invalid evaluation category: "${cat}". Must be one of: ${EVALUATION_CATEGORIES.join(", ")}`
|
|
20681
|
+
);
|
|
20682
|
+
}
|
|
20683
|
+
filter.evaluationCategory = cat;
|
|
20684
|
+
}
|
|
20685
|
+
if (opts.hasImages !== void 0) filter.hasImages = opts.hasImages === "true";
|
|
20686
|
+
if (opts.hasFileAttachments !== void 0) filter.hasFileAttachments = opts.hasFileAttachments === "true";
|
|
20687
|
+
if (opts.hasFailedToolCalls !== void 0) filter.hasFailedToolCalls = opts.hasFailedToolCalls === "true";
|
|
20688
|
+
const data = await client.request(EXPERIMENT_MESSAGE_RESPONSE_COMPARISONS_QUERY, {
|
|
20689
|
+
experimentID,
|
|
20690
|
+
pagination: toPagination(opts),
|
|
20691
|
+
filter: Object.keys(filter).length > 0 ? filter : void 0
|
|
20692
|
+
});
|
|
20693
|
+
const comparisons = data.experimentMessageResponseComparisons;
|
|
20694
|
+
output(comparisons, parentOpts.format, {
|
|
20695
|
+
columns: ["id", "category", "controlAgent", "testAgent", "messagePreview", "createdAt"],
|
|
20696
|
+
rows: comparisons.items.map((c) => ({
|
|
20697
|
+
id: c.id,
|
|
20698
|
+
category: c.comparisonResult?.category ?? "",
|
|
20699
|
+
controlAgent: c.controlResponse?.finalAgentName ?? "",
|
|
20700
|
+
testAgent: c.testResponse?.finalAgentName ?? "",
|
|
20701
|
+
messagePreview: truncate(c.targetMessage?.body ?? "", 60),
|
|
20702
|
+
createdAt: c.createdAt
|
|
20703
|
+
}))
|
|
20704
|
+
});
|
|
20705
|
+
} catch (error) {
|
|
20706
|
+
handleError(error);
|
|
20707
|
+
}
|
|
20708
|
+
});
|
|
20709
|
+
comparison.command("get").description("Get a single message response comparison detail").argument("<comparison-id>", "Comparison ID").action(async (comparisonID) => {
|
|
20710
|
+
try {
|
|
20711
|
+
const parentOpts = program3.opts();
|
|
20712
|
+
const config = requireConfig(parentOpts);
|
|
20713
|
+
const client = createGraphQLClient(config);
|
|
20714
|
+
const data = await client.request(EXPERIMENT_MESSAGE_RESPONSE_COMPARISON_QUERY, {
|
|
20715
|
+
experimentMessageResponseComparisonID: comparisonID
|
|
20716
|
+
});
|
|
20717
|
+
output(data.experimentMessageResponseComparison, parentOpts.format);
|
|
20718
|
+
} catch (error) {
|
|
20719
|
+
handleError(error);
|
|
20720
|
+
}
|
|
20721
|
+
});
|
|
20722
|
+
}
|
|
20723
|
+
function truncate(text, max) {
|
|
20724
|
+
if (text.length <= max) return text;
|
|
20725
|
+
return text.slice(0, max - 3) + "...";
|
|
20726
|
+
}
|
|
20727
|
+
|
|
20471
20728
|
// src/commands/guardrail.ts
|
|
20472
20729
|
function registerGuardrailCommand(program3) {
|
|
20473
20730
|
const guard = program3.command("guardrail").description("Guard rail operations");
|
|
@@ -21083,7 +21340,7 @@ function registerTestCommand(program3) {
|
|
|
21083
21340
|
|
|
21084
21341
|
// src/index.ts
|
|
21085
21342
|
var program2 = new Command();
|
|
21086
|
-
program2.name("propelix").description("Propelix CLI").version("0.
|
|
21343
|
+
program2.name("propelix").description("Propelix CLI").version("0.2.0").option("--base-url <url>", "API base URL (default: https://propelix.ai)").option("--token <token>", "Auth token (overrides stored config)").option("--project-id <id>", "Project ID (overrides stored config)").option("--insecure", "Disable TLS certificate verification (for local dev)").option("--json", "Output as JSON (deprecated, use --format json)").option("--format <fmt>", "Output format: json (default) | table");
|
|
21087
21344
|
program2.hook("preAction", () => {
|
|
21088
21345
|
if (program2.opts().insecure) {
|
|
21089
21346
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
@@ -21096,13 +21353,14 @@ registerAgentCommand(program2);
|
|
|
21096
21353
|
registerChannelCommand(program2);
|
|
21097
21354
|
registerPromptCommand(program2);
|
|
21098
21355
|
registerConversationCommand(program2);
|
|
21356
|
+
registerExperimentCommand(program2);
|
|
21099
21357
|
registerLogCommand(program2);
|
|
21100
21358
|
registerGuardrailCommand(program2);
|
|
21101
21359
|
registerImageCommand(program2);
|
|
21102
21360
|
registerChatCommand(program2);
|
|
21103
21361
|
registerTestCommand(program2);
|
|
21104
21362
|
program2.command("version").description("Print version number").action(() => {
|
|
21105
|
-
console.log("0.
|
|
21363
|
+
console.log("0.2.0");
|
|
21106
21364
|
});
|
|
21107
21365
|
program2.command("whoami").description("Show the currently authenticated user").action(async () => {
|
|
21108
21366
|
try {
|