the-citadel 0.5.2 → 0.5.4

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.

Potentially problematic release.


This version of the-citadel might be problematic. Click here for more details.

@@ -26,7 +26,7 @@ export declare abstract class CoreAgent {
26
26
  protected getDynamicTools(_context?: AgentContext): Promise<Record<string, Tool>>;
27
27
  private mcpLoaded;
28
28
  protected executeGenerateText(messages: ModelMessage[]): Promise<Awaited<ReturnType<typeof generateText>>>;
29
- private registerBuiltinTools;
29
+ protected registerBuiltinTools(): Promise<void>;
30
30
  protected registerTool<T extends z.ZodTypeAny, R>(name: string, description: string, schema: T, execute: (args: z.infer<T>) => Promise<R>): void;
31
31
  /**
32
32
  * Registers an AI SDK Tool directly, ensuring its schema is discoverable.
package/dist/index.js CHANGED
@@ -94148,7 +94148,7 @@ class CoreAgent {
94148
94148
  return { allowed: true };
94149
94149
  }
94150
94150
  async run(prompt, context2) {
94151
- logger.info(`[${this.role}] Running...`, { role: this.role });
94151
+ logger.info(`[${this.role}] Running...`, { role: this.role, prompt: prompt.length > 400 ? prompt.slice(0, 400) + "..." : prompt });
94152
94152
  await this.registerBuiltinTools();
94153
94153
  this.dynamicTools = await this.getDynamicTools(context2);
94154
94154
  const instructionService = getInstructionService();
@@ -94185,22 +94185,25 @@ Request: ${prompt}`
94185
94185
  const { maxHistoryMessages = 20, maxToolResponseSize = 50000, maxMessageSize = 1e5 } = config2.context || {};
94186
94186
  if (messages.length > maxHistoryMessages) {
94187
94187
  const systemMessage = messages[0];
94188
- const lastN = messages.slice(-maxHistoryMessages);
94188
+ const userRequest = messages[1];
94189
+ const lastNCount = Math.max(0, maxHistoryMessages - 2);
94190
+ const lastN = messages.slice(-lastNCount);
94189
94191
  if (lastN.length > 0 && lastN[0] && lastN[0].role === "tool") {
94190
94192
  const toolResult = lastN[0];
94191
94193
  const originalIndex = messages.indexOf(toolResult);
94192
94194
  if (originalIndex > 0) {
94193
94195
  const preceding = messages[originalIndex - 1];
94194
- if (preceding && preceding !== toolResult) {
94196
+ if (preceding && preceding !== userRequest && preceding !== systemMessage) {
94195
94197
  lastN.unshift(preceding);
94196
94198
  }
94197
94199
  }
94198
94200
  }
94199
94201
  messages.length = 0;
94202
+ if (systemMessage)
94203
+ messages.push(systemMessage);
94204
+ if (userRequest && userRequest !== systemMessage)
94205
+ messages.push(userRequest);
94200
94206
  messages.push(...lastN);
94201
- if (systemMessage) {
94202
- messages.unshift(systemMessage);
94203
- }
94204
94207
  }
94205
94208
  const result = await this.executeGenerateText(messages);
94206
94209
  console.log("DEBUG: result.usage", JSON.stringify(result.usage));
@@ -94498,15 +94501,15 @@ var createFailWorkTool = (_context) => {
94498
94501
  };
94499
94502
 
94500
94503
  // src/tools/shell.ts
94501
- import { exec as exec2 } from "node:child_process";
94502
- import { promisify } from "node:util";
94503
- var execAsync = promisify(exec2);
94504
+ import { spawn as spawn3 } from "node:child_process";
94504
94505
  var runCommandTool = {
94505
94506
  name: "run_command",
94506
- description: "Execute a shell command (e.g. to run tests)",
94507
+ description: "Execute a shell command (e.g. to run tests). Supports timeouts and background execution.",
94507
94508
  schema: exports_external.object({
94508
94509
  command: exports_external.union([exports_external.string(), exports_external.array(exports_external.string())]).optional().describe('The shell command to execute as a single string (e.g., "ls -la", "npm test")'),
94509
- cmd: exports_external.union([exports_external.string(), exports_external.array(exports_external.string())]).optional().describe("Alternative: command as string or array of arguments")
94510
+ cmd: exports_external.union([exports_external.string(), exports_external.array(exports_external.string())]).optional().describe("Alternative: command as string or array of arguments"),
94511
+ timeout: exports_external.number().optional().default(60000).describe("Timeout in milliseconds (default: 60000)"),
94512
+ background: exports_external.boolean().optional().default(false).describe("Whether to run the command in the background (default: false)")
94510
94513
  }).loose(),
94511
94514
  handler: async (args) => {
94512
94515
  let command;
@@ -94521,31 +94524,90 @@ var runCommandTool = {
94521
94524
  error: 'Either "command" or "cmd" parameter must be provided'
94522
94525
  };
94523
94526
  }
94524
- logger.debug(`[Shell] Running command: ${command}`);
94525
- try {
94526
- const { stdout, stderr } = await execAsync(command);
94527
- if (command.trim().startsWith("git ")) {
94528
- let autoSync = true;
94529
- try {
94530
- const config2 = getConfig();
94531
- autoSync = config2.pearls.autoSync !== false;
94532
- } catch {}
94533
- if (autoSync) {
94534
- logger.info(`[Shell] Git operation detected. Triggering Pearls sync.`);
94535
- await getPearls().sync();
94536
- }
94527
+ const timeout = args.timeout ?? 60000;
94528
+ const background = args.background === true;
94529
+ logger.debug(`[Shell] Running command: ${command} (timeout: ${timeout}, background: ${background})`);
94530
+ if (background) {
94531
+ try {
94532
+ const child = spawn3(command, {
94533
+ shell: true,
94534
+ detached: true,
94535
+ stdio: "ignore"
94536
+ });
94537
+ child.unref();
94538
+ return {
94539
+ success: true,
94540
+ message: `Started background process with PID ${child.pid}`,
94541
+ pid: child.pid
94542
+ };
94543
+ } catch (error48) {
94544
+ return {
94545
+ success: false,
94546
+ error: error48 instanceof Error ? error48.message : String(error48)
94547
+ };
94537
94548
  }
94538
- return { success: true, stdout: stdout.trim(), stderr: stderr.trim() };
94539
- } catch (error48) {
94540
- const errorMessage = error48 instanceof Error ? error48.message : String(error48);
94541
- const errObj = error48;
94542
- return {
94543
- success: false,
94544
- error: errorMessage,
94545
- stdout: errObj.stdout,
94546
- stderr: errObj.stderr
94547
- };
94548
94549
  }
94550
+ return new Promise((resolve8) => {
94551
+ const child = spawn3(command, { shell: true });
94552
+ let stdout = "";
94553
+ let stderr = "";
94554
+ const timer = setTimeout(() => {
94555
+ try {
94556
+ process.kill(-child.pid, "SIGTERM");
94557
+ } catch (e) {
94558
+ child.kill("SIGTERM");
94559
+ }
94560
+ resolve8({
94561
+ success: false,
94562
+ error: `Command timed out after ${timeout}ms`,
94563
+ stdout: stdout.trim(),
94564
+ stderr: stderr.trim()
94565
+ });
94566
+ }, timeout);
94567
+ child.stdout?.on("data", (data) => {
94568
+ stdout += data.toString();
94569
+ });
94570
+ child.stderr?.on("data", (data) => {
94571
+ stderr += data.toString();
94572
+ });
94573
+ child.on("close", async (code) => {
94574
+ clearTimeout(timer);
94575
+ if (command.trim().startsWith("git ")) {
94576
+ let autoSync = true;
94577
+ try {
94578
+ const config2 = getConfig();
94579
+ autoSync = config2.pearls.autoSync !== false;
94580
+ } catch {}
94581
+ if (autoSync) {
94582
+ logger.info(`[Shell] Git operation detected. Triggering Pearls sync.`);
94583
+ await getPearls().sync();
94584
+ }
94585
+ }
94586
+ if (code === 0) {
94587
+ resolve8({
94588
+ success: true,
94589
+ stdout: stdout.trim(),
94590
+ stderr: stderr.trim()
94591
+ });
94592
+ } else {
94593
+ resolve8({
94594
+ success: false,
94595
+ error: `Command exited with code ${code}`,
94596
+ stdout: stdout.trim(),
94597
+ stderr: stderr.trim()
94598
+ });
94599
+ }
94600
+ });
94601
+ child.on("error", (err) => {
94602
+ clearTimeout(timer);
94603
+ resolve8({
94604
+ success: false,
94605
+ error: err.message,
94606
+ stdout: stdout.trim(),
94607
+ stderr: stderr.trim()
94608
+ });
94609
+ });
94610
+ });
94549
94611
  }
94550
94612
  };
94551
94613
 
@@ -96255,7 +96317,7 @@ async function loadConfig2() {
96255
96317
  }
96256
96318
 
96257
96319
  // src/core/pearls.ts
96258
- import { spawn as spawn3 } from "node:child_process";
96320
+ import { spawn as spawn4 } from "node:child_process";
96259
96321
  import { resolve as resolve10 } from "node:path";
96260
96322
  var PearlStatusSchema2 = exports_external.enum([
96261
96323
  "open",
@@ -96339,7 +96401,7 @@ ${err.message}`);
96339
96401
  }
96340
96402
  async execute(command, args, cwd2) {
96341
96403
  return new Promise((resolve11, reject) => {
96342
- const child = spawn3(command, args, { cwd: cwd2 });
96404
+ const child = spawn4(command, args, { cwd: cwd2 });
96343
96405
  let stdout = "";
96344
96406
  let stderr = "";
96345
96407
  child.stdout.on("data", (data) => {
@@ -5,25 +5,14 @@ export declare const runCommandTool: {
5
5
  schema: z.ZodObject<{
6
6
  command: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
7
7
  cmd: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
8
+ timeout: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
9
+ background: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
8
10
  }, z.core.$loose>;
9
11
  handler: (args: {
10
12
  command?: string | string[];
11
13
  cmd?: string | string[];
14
+ timeout?: number;
15
+ background?: boolean;
12
16
  [key: string]: unknown;
13
- }) => Promise<{
14
- success: boolean;
15
- error: string;
16
- stdout?: undefined;
17
- stderr?: undefined;
18
- } | {
19
- success: boolean;
20
- stdout: string;
21
- stderr: string;
22
- error?: undefined;
23
- } | {
24
- success: boolean;
25
- error: string;
26
- stdout: string | undefined;
27
- stderr: string | undefined;
28
- }>;
17
+ }) => Promise<unknown>;
29
18
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "the-citadel",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "description": "A deterministic agent orchestration system for Knowledge Work",
5
5
  "module": "src/index.ts",
6
6
  "type": "module",