@pantheon.ai/agents 0.0.9 → 0.0.10

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.
Files changed (2) hide show
  1. package/dist/index.js +172 -7
  2. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -420,7 +420,7 @@ var require_cli_options = /* @__PURE__ */ __commonJSMin(((exports, module) => {
420
420
 
421
421
  //#endregion
422
422
  //#region package.json
423
- var version$1 = "0.0.9";
423
+ var version$1 = "0.0.10";
424
424
 
425
425
  //#endregion
426
426
  //#region src/schemas/task-list.ts
@@ -611,6 +611,13 @@ var TaskListTidbProvider = class extends TaskListProvider {
611
611
  ...config
612
612
  }).execute();
613
613
  }
614
+ async updateAgentConfig({ skills, ...config }) {
615
+ const result = await this.db.updateTable("agent_project_config").set({
616
+ skills: JSON.stringify(skills),
617
+ ...config
618
+ }).where("agent", "=", this.agentName).where("project_id", "=", config.project_id).executeTakeFirst();
619
+ if (Number(result.numUpdatedRows ?? 0) === 0) throw new Error(`No config found to update for agent ${this.agentName} and project ${config.project_id}.`);
620
+ }
614
621
  async getTask(taskId) {
615
622
  const taskItem = await this.selectTask().where("id", "=", taskId).executeTakeFirst();
616
623
  if (taskItem == null) return null;
@@ -9701,6 +9708,69 @@ async function startPendingTask(provider, task, logger) {
9701
9708
 
9702
9709
  //#endregion
9703
9710
  //#region src/core/index.ts
9711
+ function normalizeSkills(value) {
9712
+ if (Array.isArray(value)) return value.filter((item) => typeof item === "string");
9713
+ if (typeof value === "string") {
9714
+ try {
9715
+ const parsed = JSON.parse(value);
9716
+ if (Array.isArray(parsed)) return parsed.filter((item) => typeof item === "string");
9717
+ } catch {}
9718
+ return value.split(",").map((item) => item.trim()).filter((item) => item !== "");
9719
+ }
9720
+ return [];
9721
+ }
9722
+ function buildRebootstrapDiffPrompt(options) {
9723
+ return `You must follow these instructions":
9724
+ 1. Clone the main branch from ${options.prototypeUrl} to a temporary directory (<pantheon-agents> in follow instructions references to this directory).
9725
+ 2. Copy the <pantheon-agents>/agents/${options.role}/AGENTS.md to \`<workspace>/AGENTS.md\`.
9726
+ 3. Copy the <pantheon-agents>/agents/${options.role}/skills directory to \`<workspace>/.codex/skills\` if the source directory exists.
9727
+ ${options.skills.length > 0 ? `4. Copy the pantheon-agents/skills/\{${options.skills.join(",")}} directory to \`<workspace>/.codex/skills/\`` : ""}
9728
+
9729
+ Validate <workspace>: check if files and directorys exists:
9730
+ - AGENTS.md
9731
+ - .codex/skills
9732
+
9733
+ **You MUST NOT generate AGENTS.md and skills by yourself if clone failed.**
9734
+
9735
+ Finally, output a DIFF-oriented summary (not raw file contents) between:
9736
+ - BEFORE: the workspace state before applying the steps above (previous base branch id: ${options.previousBaseBranchId})
9737
+ - AFTER: the workspace state after applying the steps above
9738
+
9739
+ The summary MUST include:
9740
+ - \`AGENTS.md\` changes (diff/stat only; do NOT print full file content)
9741
+ - \`.codex/skills\` added/removed/modified entries (filenames only; do NOT print file contents)
9742
+ - A concise summary with: changed files list + add/remove/modify counts
9743
+ `;
9744
+ }
9745
+ async function defaultSleep(ms) {
9746
+ await new Promise((resolve) => {
9747
+ setTimeout(resolve, ms);
9748
+ });
9749
+ }
9750
+ async function waitForPantheonBranchOutput(options) {
9751
+ let retried = 0;
9752
+ let i = 0;
9753
+ while (true) {
9754
+ await options.sleep(options.pollIntervalMs);
9755
+ const result = await options.getPantheonBranchFn({
9756
+ branchId: options.branchId,
9757
+ projectId: options.projectId,
9758
+ getOutputIfFinished: true
9759
+ }).then((result) => {
9760
+ retried = 0;
9761
+ return result;
9762
+ }).catch((reason) => {
9763
+ if (retried < options.maxRetries) {
9764
+ retried++;
9765
+ return { state: "others" };
9766
+ }
9767
+ throw new Error(`Failed to get bootstrap branch status. Retry ${retried} times. Last error: ${getErrorMessage(reason)}`);
9768
+ });
9769
+ if (result.state === "failed") throw new Error(`Bootstrap failed: ${result.error}`);
9770
+ if (result.state === "succeed") return result.output ?? "";
9771
+ console.log(`Bootstrap in progress... [${++i}]`);
9772
+ }
9773
+ }
9704
9774
  async function runAgent(name, options, logger) {
9705
9775
  const agentDir = path.join(options.dataDir, "agents", name);
9706
9776
  const pidFile = path.join(agentDir, "pid");
@@ -9808,6 +9878,65 @@ Finally, outputs the first 5 lines of <workspace>/AGENTS.md and the skills list
9808
9878
  console.log(`Agent ${name} configured successfully.`);
9809
9879
  await provider.close();
9810
9880
  }
9881
+ async function reconfigAgentWithDeps(name, options, deps) {
9882
+ const previousConfig = await deps.provider.getAgentConfig(options.projectId);
9883
+ if (!previousConfig) throw new Error(`No config found for agent ${name} and project ${options.projectId}.`);
9884
+ const resolvedRole = options.role?.trim() || previousConfig.role;
9885
+ if (options.role != null && !options.role.trim()) throw new Error("--role must be non-empty.");
9886
+ const resolvedSkills = options.skills ?? normalizeSkills(previousConfig.skills);
9887
+ const nextBaseBranchId = await deps.executeOnPantheonFn({
9888
+ projectId: options.projectId,
9889
+ branchId: previousConfig.base_branch_id,
9890
+ agent: "codex",
9891
+ prompt: buildRebootstrapDiffPrompt({
9892
+ prototypeUrl: previousConfig.prototype_url,
9893
+ role: resolvedRole,
9894
+ skills: resolvedSkills,
9895
+ previousBaseBranchId: previousConfig.base_branch_id
9896
+ })
9897
+ });
9898
+ console.log(`Bootstrap branch created: ${nextBaseBranchId}. Waiting for ready... [poll interval = ${Math.floor((deps.pollIntervalMs ?? 1e4) / 1e3)}s]`);
9899
+ const bootstrapOutput = await waitForPantheonBranchOutput({
9900
+ projectId: options.projectId,
9901
+ branchId: nextBaseBranchId,
9902
+ pollIntervalMs: deps.pollIntervalMs ?? 1e4,
9903
+ maxRetries: deps.maxRetries ?? 3,
9904
+ getPantheonBranchFn: deps.getPantheonBranchFn,
9905
+ sleep: deps.sleep ?? defaultSleep
9906
+ });
9907
+ await deps.provider.updateAgentConfig({
9908
+ project_id: options.projectId,
9909
+ base_branch_id: nextBaseBranchId,
9910
+ execute_agent: previousConfig.execute_agent,
9911
+ role: resolvedRole,
9912
+ skills: resolvedSkills,
9913
+ prototype_url: previousConfig.prototype_url
9914
+ });
9915
+ return {
9916
+ previousConfig,
9917
+ resolvedRole,
9918
+ resolvedSkills,
9919
+ nextBaseBranchId,
9920
+ bootstrapOutput
9921
+ };
9922
+ }
9923
+ async function reconfigAgent(name, options) {
9924
+ const provider = new TaskListTidbProvider(name, pino());
9925
+ try {
9926
+ console.log(`Reconfiguring agent ${name} for project ${options.projectId}.`);
9927
+ const result = await reconfigAgentWithDeps(name, options, {
9928
+ provider,
9929
+ executeOnPantheonFn: executeOnPantheon,
9930
+ getPantheonBranchFn: getPantheonBranch
9931
+ });
9932
+ console.log("Re-bootstrap succeeded. Output is:");
9933
+ console.log(result.bootstrapOutput);
9934
+ console.log(`New base branch id: ${result.nextBaseBranchId}`);
9935
+ console.log(`Agent ${name} reconfigured successfully.`);
9936
+ } finally {
9937
+ await provider.close();
9938
+ }
9939
+ }
9811
9940
  async function addTask(name, options) {
9812
9941
  const provider = new TaskListTidbProvider(name, pino());
9813
9942
  const config = await provider.getAgentConfig(options.projectId);
@@ -10028,6 +10157,47 @@ function createDeleteTaskCommand(version) {
10028
10157
  });
10029
10158
  }
10030
10159
 
10160
+ //#endregion
10161
+ //#region src/cli/utils/parse.ts
10162
+ function parseCommaList(value) {
10163
+ return value.split(",").map((item) => item.trim()).filter((item) => item !== "");
10164
+ }
10165
+ function parseUniqueCommaList(value) {
10166
+ const items = parseCommaList(value);
10167
+ const seen = /* @__PURE__ */ new Set();
10168
+ const result = [];
10169
+ for (const item of items) {
10170
+ if (seen.has(item)) continue;
10171
+ seen.add(item);
10172
+ result.push(item);
10173
+ }
10174
+ return result;
10175
+ }
10176
+
10177
+ //#endregion
10178
+ //#region src/cli/commands/reconfig.ts
10179
+ function createReconfigAgentCommand(version) {
10180
+ return createCommand("pantheon-agents reconfig").version(version).description("Re-bootstrap an existing agent configuration for a project").argument("<name>", "The name of the agent.").argument("<project-id>", "The project id of the agent.").option("--role <role>", "Override role for the agent.").option("--skills <skills>", "Override skills for the agent (comma-separated, replaces existing list).", parseUniqueCommaList).action(async function() {
10181
+ const [name, projectId] = this.args;
10182
+ const options = this.opts();
10183
+ const resolvedRole = options.role?.trim();
10184
+ if (options.role != null && !resolvedRole) {
10185
+ console.error("--role must be non-empty.");
10186
+ process$1.exit(1);
10187
+ }
10188
+ try {
10189
+ await reconfigAgent(name, {
10190
+ projectId,
10191
+ role: resolvedRole,
10192
+ skills: options.skills
10193
+ });
10194
+ } catch (error) {
10195
+ console.error(getErrorMessage(error));
10196
+ process$1.exit(1);
10197
+ }
10198
+ });
10199
+ }
10200
+
10031
10201
  //#endregion
10032
10202
  //#region src/cli/commands/run.ts
10033
10203
  function createRunAgentCommand(version) {
@@ -31749,12 +31919,6 @@ const orderByFields = [
31749
31919
  ];
31750
31920
  const orderDirections = ["asc", "desc"];
31751
31921
 
31752
- //#endregion
31753
- //#region src/cli/utils/parse.ts
31754
- function parseCommaList(value) {
31755
- return value.split(",").map((item) => item.trim()).filter((item) => item !== "");
31756
- }
31757
-
31758
31922
  //#endregion
31759
31923
  //#region src/cli/commands/show-tasks.ts
31760
31924
  function createShowTasksCommand(version) {
@@ -31846,6 +32010,7 @@ const commands = {
31846
32010
  "add-task": createAddTaskCommand(version$1),
31847
32011
  config: createConfigAgentCommand(version$1),
31848
32012
  "delete-task": createDeleteTaskCommand(version$1),
32013
+ reconfig: createReconfigAgentCommand(version$1),
31849
32014
  run: createRunAgentCommand(version$1),
31850
32015
  server: createServerCommand(version$1),
31851
32016
  "show-config": createShowConfigCommand(version$1),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pantheon.ai/agents",
3
3
  "type": "module",
4
- "version": "0.0.9",
4
+ "version": "0.0.10",
5
5
  "bin": {
6
6
  "pantheon-agents": "dist/index.js"
7
7
  },
@@ -13,6 +13,7 @@
13
13
  },
14
14
  "scripts": {
15
15
  "build": "rolldown -c rolldown.config.ts && chmod +x dist/index.js",
16
+ "test": "bun test",
16
17
  "dev:db:start": "tiup playground --without-monitor --tag pantheon-agents",
17
18
  "dev:db:gen": "kysely-codegen "
18
19
  },