the-citadel 0.4.3 → 0.4.5

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.

@@ -25,6 +25,7 @@ export declare const ConfigSchema: z.ZodObject<{
25
25
  }>;
26
26
  model: z.ZodString;
27
27
  mcpTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
28
+ mcpResources: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
28
29
  }, z.core.$strip>;
29
30
  worker: z.ZodObject<{
30
31
  provider: z.ZodEnum<{
@@ -34,15 +35,7 @@ export declare const ConfigSchema: z.ZodObject<{
34
35
  }>;
35
36
  model: z.ZodString;
36
37
  mcpTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
37
- }, z.core.$strip>;
38
- supervisor: z.ZodObject<{
39
- provider: z.ZodEnum<{
40
- openai: "openai";
41
- anthropic: "anthropic";
42
- ollama: "ollama";
43
- }>;
44
- model: z.ZodString;
45
- mcpTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
38
+ mcpResources: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
46
39
  }, z.core.$strip>;
47
40
  gatekeeper: z.ZodObject<{
48
41
  provider: z.ZodEnum<{
@@ -52,6 +45,7 @@ export declare const ConfigSchema: z.ZodObject<{
52
45
  }>;
53
46
  model: z.ZodString;
54
47
  mcpTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
48
+ mcpResources: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
55
49
  }, z.core.$strip>;
56
50
  }, z.core.$strip>;
57
51
  mcpServers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -1,6 +1,7 @@
1
1
  import { generateText, type LanguageModel, type ModelMessage, type Tool } from "ai";
2
2
  import { z } from "zod";
3
3
  import type { AgentRole } from "../config/schema";
4
+ import { type BeadsClient } from "./beads";
4
5
  export interface AgentContext {
5
6
  beadId?: string;
6
7
  [key: string]: unknown;
@@ -16,7 +17,8 @@ export declare abstract class CoreAgent {
16
17
  protected dynamicTools: Record<string, Tool>;
17
18
  protected schemas: Record<string, z.ZodTypeAny>;
18
19
  protected requiresExplicitCompletion: boolean;
19
- constructor(role: AgentRole, model?: LanguageModel);
20
+ protected beadsClient?: BeadsClient;
21
+ constructor(role: AgentRole, model?: LanguageModel, beadsClient?: BeadsClient);
20
22
  /**
21
23
  * Override this to provide tools dynamically based on context.
22
24
  * These will be merged with registered static tools (like MCP tools).
@@ -27,6 +27,7 @@ export declare const FormulaSchema: z.ZodObject<{
27
27
  default: z.ZodOptional<z.ZodString>;
28
28
  }, z.core.$strip>>>;
29
29
  prompts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
30
+ mcp_resources: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
30
31
  steps: z.ZodArray<z.ZodObject<{
31
32
  id: z.ZodString;
32
33
  title: z.ZodString;
@@ -1,4 +1,4 @@
1
1
  import type { LanguageModel } from "ai";
2
- type AgentRole = "router" | "worker" | "supervisor" | "gatekeeper";
2
+ type AgentRole = "router" | "worker" | "gatekeeper";
3
3
  export declare function getAgentModel(role: AgentRole): LanguageModel;
4
4
  export {};
@@ -0,0 +1,7 @@
1
+ import type { InstructionContext, InstructionProvider } from "./instruction";
2
+ export declare class MCPResourceProvider implements InstructionProvider {
3
+ name: string;
4
+ priority: number;
5
+ getInstructions(ctx: InstructionContext): Promise<string | null>;
6
+ private mergeResources;
7
+ }
@@ -19,7 +19,6 @@ export declare const TicketSchema: z.ZodObject<{
19
19
  target_role: z.ZodEnum<{
20
20
  router: "router";
21
21
  worker: "worker";
22
- supervisor: "supervisor";
23
22
  gatekeeper: "gatekeeper";
24
23
  }>;
25
24
  assignee_id: z.ZodNullable<z.ZodString>;
package/dist/index.js CHANGED
@@ -64994,22 +64994,20 @@ var ConfigSchema = exports_external.object({
64994
64994
  router: exports_external.object({
64995
64995
  provider: exports_external.enum(["openai", "anthropic", "ollama"]),
64996
64996
  model: exports_external.string(),
64997
- mcpTools: exports_external.array(exports_external.string()).optional()
64997
+ mcpTools: exports_external.array(exports_external.string()).optional(),
64998
+ mcpResources: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).optional()
64998
64999
  }),
64999
65000
  worker: exports_external.object({
65000
65001
  provider: exports_external.enum(["openai", "anthropic", "ollama"]),
65001
65002
  model: exports_external.string(),
65002
- mcpTools: exports_external.array(exports_external.string()).optional()
65003
- }),
65004
- supervisor: exports_external.object({
65005
- provider: exports_external.enum(["openai", "anthropic", "ollama"]),
65006
- model: exports_external.string(),
65007
- mcpTools: exports_external.array(exports_external.string()).optional()
65003
+ mcpTools: exports_external.array(exports_external.string()).optional(),
65004
+ mcpResources: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).optional()
65008
65005
  }),
65009
65006
  gatekeeper: exports_external.object({
65010
65007
  provider: exports_external.enum(["openai", "anthropic", "ollama"]),
65011
65008
  model: exports_external.string(),
65012
- mcpTools: exports_external.array(exports_external.string()).optional()
65009
+ mcpTools: exports_external.array(exports_external.string()).optional(),
65010
+ mcpResources: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).optional()
65013
65011
  })
65014
65012
  }),
65015
65013
  mcpServers: exports_external.record(exports_external.string(), exports_external.object({
@@ -81469,6 +81467,48 @@ class MCPService {
81469
81467
  arguments: args
81470
81468
  });
81471
81469
  }
81470
+ async readResource(serverName, uri) {
81471
+ const client = this.clients.get(serverName);
81472
+ if (!client) {
81473
+ logger.warn(`[MCP] Server ${serverName} not connected for resource ${uri}`);
81474
+ return [];
81475
+ }
81476
+ try {
81477
+ logger.info(`[MCP] Reading resource ${serverName}:${uri}`);
81478
+ const result = await client.request({
81479
+ method: "resources/read",
81480
+ params: { uri }
81481
+ }, ReadResourceRequestSchema);
81482
+ return result.contents.map((content) => {
81483
+ if ("text" in content && content.text) {
81484
+ return content.text;
81485
+ }
81486
+ if ("blob" in content) {
81487
+ logger.warn(`[MCP] Skipping binary resource content for ${uri}`);
81488
+ }
81489
+ return null;
81490
+ }).filter((text2) => text2 !== null);
81491
+ } catch (error48) {
81492
+ logger.error(`[MCP] Failed to read resource ${serverName}:${uri}:`, error48);
81493
+ return [];
81494
+ }
81495
+ }
81496
+ async listResources(serverName) {
81497
+ const client = this.clients.get(serverName);
81498
+ if (!client) {
81499
+ logger.warn(`[MCP] Server ${serverName} not connected for listResources`);
81500
+ return [];
81501
+ }
81502
+ try {
81503
+ const result = await client.request({
81504
+ method: "resources/list"
81505
+ }, ListResourcesRequestSchema);
81506
+ return result.resources;
81507
+ } catch (error48) {
81508
+ logger.error(`[MCP] Failed to list resources for ${serverName}:`, error48);
81509
+ return [];
81510
+ }
81511
+ }
81472
81512
  async shutdown() {
81473
81513
  for (const [name18, client] of this.clients) {
81474
81514
  try {
@@ -84768,6 +84808,7 @@ var FormulaSchema = exports_external.object({
84768
84808
  description: exports_external.string(),
84769
84809
  vars: exports_external.record(exports_external.string(), FormulaVariableSchema).optional(),
84770
84810
  prompts: exports_external.record(exports_external.string(), exports_external.string()).optional(),
84811
+ mcp_resources: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).optional(),
84771
84812
  steps: exports_external.array(FormulaStepSchema)
84772
84813
  });
84773
84814
 
@@ -84814,6 +84855,81 @@ function getFormulaRegistry(basePath) {
84814
84855
  return _registry;
84815
84856
  }
84816
84857
 
84858
+ // src/core/mcp-resource-provider.ts
84859
+ class MCPResourceProvider {
84860
+ name = "mcp-resources";
84861
+ priority = 25;
84862
+ async getInstructions(ctx) {
84863
+ const resourcesToFetch = {};
84864
+ const config2 = getConfig();
84865
+ const roleConfig = config2.agents[ctx.role];
84866
+ if (roleConfig && "mcpResources" in roleConfig && roleConfig.mcpResources) {
84867
+ this.mergeResources(resourcesToFetch, roleConfig.mcpResources);
84868
+ }
84869
+ if (ctx.beadId) {
84870
+ try {
84871
+ const bead = await getBeads().get(ctx.beadId);
84872
+ const formulaLabel = bead.labels?.find((l) => l.startsWith("formula:"));
84873
+ if (formulaLabel) {
84874
+ const formulaName = formulaLabel.split(":")[1];
84875
+ if (formulaName) {
84876
+ const formula = getFormulaRegistry().get(formulaName);
84877
+ if (formula?.mcp_resources) {
84878
+ this.mergeResources(resourcesToFetch, formula.mcp_resources);
84879
+ }
84880
+ }
84881
+ }
84882
+ if (bead.context?.mcp_resources) {
84883
+ this.mergeResources(resourcesToFetch, bead.context.mcp_resources);
84884
+ }
84885
+ } catch (err) {
84886
+ logger.debug(`[MCPResourceProvider] Error fetching resources from bead/formula: ${err}`);
84887
+ }
84888
+ }
84889
+ if (Object.keys(resourcesToFetch).length === 0)
84890
+ return null;
84891
+ const mcpService = getMCPService();
84892
+ const results = [];
84893
+ for (const [serverName, uris] of Object.entries(resourcesToFetch)) {
84894
+ for (const uri of uris) {
84895
+ try {
84896
+ const contents = await mcpService.readResource(serverName, uri);
84897
+ if (contents.length > 0) {
84898
+ results.push(`## RESOURCE: ${serverName}:${uri}
84899
+ ${contents.join(`
84900
+
84901
+ `)}`);
84902
+ }
84903
+ } catch (err) {
84904
+ logger.warn(`[MCPResourceProvider] Failed to fetch resource ${serverName}:${uri}: ${err}`);
84905
+ }
84906
+ }
84907
+ }
84908
+ if (results.length === 0)
84909
+ return null;
84910
+ return `
84911
+ # CONTEXT RESOURCES
84912
+ The following resources have been injected into your context for this task:
84913
+
84914
+ ${results.join(`
84915
+
84916
+ ---
84917
+
84918
+ `)}
84919
+ `;
84920
+ }
84921
+ mergeResources(target, source) {
84922
+ for (const [server, uris] of Object.entries(source)) {
84923
+ if (!target[server]) {
84924
+ target[server] = new Set;
84925
+ }
84926
+ for (const uri of uris) {
84927
+ target[server].add(uri);
84928
+ }
84929
+ }
84930
+ }
84931
+ }
84932
+
84817
84933
  // src/core/instruction.ts
84818
84934
  class GlobalProvider {
84819
84935
  name = "global";
@@ -84966,6 +85082,7 @@ class InstructionService {
84966
85082
  new GlobalProvider,
84967
85083
  new BuiltinProvider,
84968
85084
  new RoleProvider,
85085
+ new MCPResourceProvider,
84969
85086
  new FormulaProvider,
84970
85087
  new TagProvider,
84971
85088
  new ContextProvider
@@ -93792,9 +93909,11 @@ class CoreAgent {
93792
93909
  dynamicTools = {};
93793
93910
  schemas = {};
93794
93911
  requiresExplicitCompletion = false;
93795
- constructor(role, model) {
93912
+ beadsClient;
93913
+ constructor(role, model, beadsClient) {
93796
93914
  this.role = role;
93797
93915
  this.model = model || getAgentModel(role);
93916
+ this.beadsClient = beadsClient;
93798
93917
  }
93799
93918
  async getDynamicTools(_context) {
93800
93919
  return {};
@@ -94195,7 +94314,8 @@ If you are still working, continue with your next step.`
94195
94314
  - **Input Tokens**: ${totalUsage.inputTokens}
94196
94315
  - **Output Tokens**: ${totalUsage.outputTokens}
94197
94316
  - **Total Tokens**: ${totalUsage.totalTokens}`;
94198
- getBeads().addComment(context2.beadId, summary).catch((err) => {
94317
+ const client = this.beadsClient || getBeads();
94318
+ client.addComment(context2.beadId, summary).catch((err) => {
94199
94319
  logger.warn(`[${this.role}] Failed to report token usage to bead ${context2.beadId}`, { error: err });
94200
94320
  });
94201
94321
  } catch (err) {
@@ -94388,7 +94508,7 @@ var TicketSchema = exports_external.object({
94388
94508
  bead_id: exports_external.string(),
94389
94509
  status: TicketStatusSchema,
94390
94510
  priority: exports_external.number().min(0).max(3),
94391
- target_role: exports_external.enum(["router", "worker", "supervisor", "gatekeeper"]),
94511
+ target_role: exports_external.enum(["router", "worker", "gatekeeper"]),
94392
94512
  assignee_id: exports_external.string().nullable(),
94393
94513
  created_at: exports_external.number(),
94394
94514
  started_at: exports_external.number().nullable(),
@@ -96411,7 +96531,7 @@ var TicketSchema2 = exports_external.object({
96411
96531
  bead_id: exports_external.string(),
96412
96532
  status: TicketStatusSchema2,
96413
96533
  priority: exports_external.number().min(0).max(3),
96414
- target_role: exports_external.enum(["router", "worker", "supervisor", "gatekeeper"]),
96534
+ target_role: exports_external.enum(["router", "worker", "gatekeeper"]),
96415
96535
  assignee_id: exports_external.string().nullable(),
96416
96536
  created_at: exports_external.number(),
96417
96537
  started_at: exports_external.number().nullable(),
@@ -97086,7 +97206,7 @@ export default {
97086
97206
  model: 'llama3:8b',
97087
97207
  mcpTools: ['filesystem:read_text_file', 'filesystem:list_directory']
97088
97208
  },
97089
- supervisor: { provider: 'ollama', model: 'llama3:8b' },
97209
+
97090
97210
  },
97091
97211
  mcpServers: {
97092
97212
  filesystem: {
@@ -13,6 +13,8 @@ export declare class MCPService {
13
13
  initialize(): Promise<void>;
14
14
  getToolsForAgent(assignedTools?: string[]): Promise<MCPTool[]>;
15
15
  callTool(serverName: string, toolName: string, args: Record<string, unknown>): Promise<unknown>;
16
+ readResource(serverName: string, uri: string): Promise<string[]>;
17
+ listResources(serverName: string): Promise<unknown[]>;
16
18
  shutdown(): Promise<void>;
17
19
  }
18
20
  export declare function getMCPService(): MCPService;
@@ -20,7 +20,7 @@ export declare const createReportProgressTool: (_context: AgentContext) => impor
20
20
  }>;
21
21
  export declare const createDelegateTaskTool: (_context: AgentContext) => import("ai").Tool<{
22
22
  title: string;
23
- priority: "low" | "normal" | "high" | "critical";
23
+ priority: "critical" | "low" | "normal" | "high";
24
24
  parentBeadId?: string | undefined;
25
25
  tags?: string[] | undefined;
26
26
  description?: string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "the-citadel",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "A deterministic agent orchestration system for Knowledge Work",
5
5
  "module": "src/index.ts",
6
6
  "type": "module",