crow-central-agency 0.26.14 → 0.27.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.
Files changed (101) hide show
  1. package/dist/_shared/constants/system-agent.js +1 -0
  2. package/dist/_shared/index.js +5 -3
  3. package/dist/_shared/schemas/agent-circle.schema.js +12 -3
  4. package/dist/_shared/schemas/agent-runtime-state.schema.js +1 -1
  5. package/dist/_shared/schemas/artifact.schema.js +4 -2
  6. package/dist/_shared/schemas/fragment-reflection.schema.js +62 -0
  7. package/dist/_shared/schemas/fragment.schema.js +47 -0
  8. package/dist/_shared/schemas/graph.schema.js +3 -1
  9. package/dist/_shared/schemas/websocket.schema.js +38 -12
  10. package/dist/agents/crow-fragment-reflection-agent.js +98 -0
  11. package/dist/bootstrap.js +22 -5
  12. package/dist/core/error/app-error.types.js +1 -0
  13. package/dist/mcp/agents/agents-mcp-server.js +4 -4
  14. package/dist/mcp/agents/search-workspace.js +25 -8
  15. package/dist/mcp/artifacts/artifacts-mcp-server.js +7 -2
  16. package/dist/mcp/audio/audio-mcp-server.js +7 -2
  17. package/dist/mcp/fragments/active-domain-signal.js +8 -0
  18. package/dist/mcp/fragments/fragment-tool-utils.js +12 -0
  19. package/dist/mcp/fragments/fragments-mcp-server.js +28 -0
  20. package/dist/mcp/fragments/fragments-reflection-mcp-server.js +21 -0
  21. package/dist/mcp/fragments/link-fragment.js +82 -0
  22. package/dist/mcp/fragments/read-fragment.js +43 -0
  23. package/dist/mcp/fragments/search-fragment.js +51 -0
  24. package/dist/mcp/fragments/unlink-fragment.js +53 -0
  25. package/dist/mcp/fragments/update-fragment.js +52 -0
  26. package/dist/mcp/fragments/write-fragment.js +45 -0
  27. package/dist/mcp/reminders/reminders-mcp-server.js +7 -2
  28. package/dist/mcp/tasks/tasks-mcp-server.js +2 -2
  29. package/dist/public/assets/{architectureDiagram-3BPJPVTR-9PO2Zi5j.js → architectureDiagram-3BPJPVTR-B81-2nJq.js} +1 -1
  30. package/dist/public/assets/{blockDiagram-GPEHLZMM-B8TiZHkt.js → blockDiagram-GPEHLZMM-DXGYsvdc.js} +1 -1
  31. package/dist/public/assets/{c4Diagram-AAUBKEIU-C7EL8BgS.js → c4Diagram-AAUBKEIU-ztTqSRMY.js} +1 -1
  32. package/dist/public/assets/{chunk-3OPIFGDE-MQSAwWWp.js → chunk-3OPIFGDE-Bxujc1Rt.js} +1 -1
  33. package/dist/public/assets/chunk-5ZQYHXKU-BjSbc4aL.js +2 -0
  34. package/dist/public/assets/{chunk-727SXJPM-BmaCn-6B.js → chunk-727SXJPM-CA5zpRF4.js} +1 -1
  35. package/dist/public/assets/{chunk-AQP2D5EJ-Cca-zKhj.js → chunk-AQP2D5EJ-BfWilfr3.js} +1 -1
  36. package/dist/public/assets/{chunk-L5ZTLDWV-qldrlPBQ.js → chunk-L5ZTLDWV-DB34dWa1.js} +1 -1
  37. package/dist/public/assets/{chunk-O5CBEL6O-IrQhDPxX.js → chunk-O5CBEL6O-DX0VXF6r.js} +1 -1
  38. package/dist/public/assets/classDiagram-4FO5ZUOK-hSZP-zK7.js +1 -0
  39. package/dist/public/assets/classDiagram-v2-Q7XG4LA2-hSZP-zK7.js +1 -0
  40. package/dist/public/assets/{dagre-BM42HDAG-CRiqaSzz.js → dagre-BM42HDAG-Du7tE18Y.js} +1 -1
  41. package/dist/public/assets/{diagram-2AECGRRQ-BRpLjqbq.js → diagram-2AECGRRQ-BtisML-9.js} +1 -1
  42. package/dist/public/assets/{diagram-5GNKFQAL-Bc9v-jIT.js → diagram-5GNKFQAL-4XFQLBWU.js} +1 -1
  43. package/dist/public/assets/{diagram-KO2AKTUF-l-G_fXJx.js → diagram-KO2AKTUF-Bw_mRWA5.js} +1 -1
  44. package/dist/public/assets/{diagram-LMA3HP47-BML6fr2x.js → diagram-LMA3HP47-CADs130y.js} +1 -1
  45. package/dist/public/assets/{diagram-OG6HWLK6-Czbcayu-.js → diagram-OG6HWLK6-B0wqIPgk.js} +1 -1
  46. package/dist/public/assets/{erDiagram-TEJ5UH35-DWxHYHOI.js → erDiagram-TEJ5UH35-yQjnWqYr.js} +1 -1
  47. package/dist/public/assets/{flowDiagram-I6XJVG4X-ZS40gCP9.js → flowDiagram-I6XJVG4X-DQyaPhc_.js} +1 -1
  48. package/dist/public/assets/{ganttDiagram-6RSMTGT7-DcrRy6MU.js → ganttDiagram-6RSMTGT7-CQRvJhaK.js} +1 -1
  49. package/dist/public/assets/{gitGraphDiagram-PVQCEYII-C2wZyHYx.js → gitGraphDiagram-PVQCEYII-DWInzrI1.js} +1 -1
  50. package/dist/public/assets/index-BX-BOG4C.js +506 -0
  51. package/dist/public/assets/index-TfuJyPCv.css +1 -0
  52. package/dist/public/assets/{infoDiagram-5YYISTIA-cREQjSEN.js → infoDiagram-5YYISTIA-BDbevxAp.js} +1 -1
  53. package/dist/public/assets/{ishikawaDiagram-YF4QCWOH-BGHPisrV.js → ishikawaDiagram-YF4QCWOH-Bsu77_Yo.js} +1 -1
  54. package/dist/public/assets/{kanban-definition-UN3LZRKU-C-2qMHn6.js → kanban-definition-UN3LZRKU-f64whSnz.js} +1 -1
  55. package/dist/public/assets/{line-kwTiCfuG.js → line-TBAqc70M.js} +1 -1
  56. package/dist/public/assets/{mindmap-definition-RKZ34NQL-gLns4iF7.js → mindmap-definition-RKZ34NQL-DfWnXOfI.js} +1 -1
  57. package/dist/public/assets/{pieDiagram-4H26LBE5-Da06yraI.js → pieDiagram-4H26LBE5-Bqg7-q_N.js} +1 -1
  58. package/dist/public/assets/{requirementDiagram-4Y6WPE33-BsSvQc8s.js → requirementDiagram-4Y6WPE33-cip1_k9k.js} +1 -1
  59. package/dist/public/assets/{sequenceDiagram-3UESZ5HK-CxdEFAWz.js → sequenceDiagram-3UESZ5HK-CheQJr2g.js} +1 -1
  60. package/dist/public/assets/{stateDiagram-AJRCARHV-itM-qY8o.js → stateDiagram-AJRCARHV-an7e6llz.js} +1 -1
  61. package/dist/public/assets/stateDiagram-v2-BHNVJYJU-BNydHOrt.js +1 -0
  62. package/dist/public/assets/{timeline-definition-PNZ67QCA-BUxAMoDy.js → timeline-definition-PNZ67QCA-DoYJE76o.js} +1 -1
  63. package/dist/public/assets/{vennDiagram-CIIHVFJN-CtO4Fn4j.js → vennDiagram-CIIHVFJN-CtoH0FT3.js} +1 -1
  64. package/dist/public/assets/{wardleyDiagram-YWT4CUSO-BewTtRo4.js → wardleyDiagram-YWT4CUSO-BgAGL7w8.js} +1 -1
  65. package/dist/public/assets/{xychartDiagram-2RQKCTM6-DjHvRmZM.js → xychartDiagram-2RQKCTM6-B8gJqy0A.js} +1 -1
  66. package/dist/public/index.html +7 -7
  67. package/dist/routes/agent.routes.js +1 -0
  68. package/dist/routes/circle.routes.js +9 -1
  69. package/dist/routes/fragment.routes.js +40 -0
  70. package/dist/routes/graph.routes.js +10 -3
  71. package/dist/routines/fragment-reflection-routine.js +109 -0
  72. package/dist/runner/agent-runner-factory.js +3 -3
  73. package/dist/runner/agent-runner.js +58 -6
  74. package/dist/runner/claude-code-agent-runner.js +2 -2
  75. package/dist/runner/github-copilot-agent-runner.js +2 -2
  76. package/dist/server/error-handler.js +1 -0
  77. package/dist/services/agent-circle-manager.js +30 -93
  78. package/dist/services/agent-registry.js +3 -1
  79. package/dist/services/fragment/fragment-cue-renderer.js +49 -0
  80. package/dist/services/fragment/fragment-manager.js +536 -0
  81. package/dist/services/fragment/fragment-manager.types.js +2 -0
  82. package/dist/services/fragment/fragment-reflection-applier.js +102 -0
  83. package/dist/services/fragment/fragment-reflection-prompts.js +77 -0
  84. package/dist/services/fragment/fragment-reflection-state-store.js +21 -0
  85. package/dist/services/fragment/fragment-reflection.constants.js +8 -0
  86. package/dist/services/relationship-manager.js +140 -0
  87. package/dist/services/relationship-manager.types.js +2 -0
  88. package/dist/services/runtime/agent-runtime-manager.js +38 -3
  89. package/dist/services/search/document-search-service.js +28 -5
  90. package/dist/services/search/document-search-service.types.js +1 -0
  91. package/dist/services/world-builder/world-builder-service.js +4 -3
  92. package/dist/utils/extract-marked.js +31 -0
  93. package/dist/utils/id-utils.js +2 -1
  94. package/package.json +4 -4
  95. package/dist/public/assets/chunk-5ZQYHXKU-DjjMoQy4.js +0 -2
  96. package/dist/public/assets/classDiagram-4FO5ZUOK-B_zdrMg0.js +0 -1
  97. package/dist/public/assets/classDiagram-v2-Q7XG4LA2-B_zdrMg0.js +0 -1
  98. package/dist/public/assets/index-Bf-eiYs6.js +0 -506
  99. package/dist/public/assets/index-DOeMoLVc.css +0 -1
  100. package/dist/public/assets/stateDiagram-v2-BHNVJYJU-CSRZkocn.js +0 -1
  101. package/dist/services/world-builder/extract-marked.js +0 -31
@@ -3,4 +3,5 @@ export const CROW_SYSTEM_AGENT_ID = "__super_crow__";
3
3
  export const CROW_TASK_DISPATCHER_AGENT_ID = "__crow_task_dp__";
4
4
  export const CROW_NARRATIVE_ARCHITECT_AGENT_ID = "__crow_narrative_architect__";
5
5
  export const CROW_WORLD_BUILDER_AGENT_ID = "__crow_world_builder__";
6
+ export const FRAGMENT_REFLECTION_AGENT_ID = "__crow_fragment_reflection__";
6
7
  //# sourceMappingURL=system-agent.js.map
@@ -2,10 +2,10 @@ export { CLAUDE_MODELS, GITHUB_COPILOT_MODELS, CLAUDE_CODE_MODEL_OPTIONS, ModelO
2
2
  export { SchedulerTimeSchema, DAY_OF_WEEK, DayOfWeekSchema, TimeModeSchema, TIME_MODE, } from "./schemas/scheduler.schema.js";
3
3
  export { createApiSuccessSchema, ApiErrorSchema, } from "./schemas/api-response.schema.js";
4
4
  export { SessionUsageSchema, PendingPermissionInfoSchema, PendingInstructionReminderSchema, AgentRuntimeStateSchema, AgentActivitySchema, AGENT_ACTIVITY_TYPE, AGENT_STATUS, MAX_INPUT_HISTORY, } from "./schemas/agent-runtime-state.schema.js";
5
- export { ClientMessageSchema, ServerMessageSchema, SendMessageSchema, InjectMessageSchema, PermissionResponseWsSchema, CommandMessageSchema, AgentTextWsMessageSchema, AgentActivityWsMessageSchema, AgentResultWsMessageSchema, AgentStatusWsMessageSchema, AgentCreatedWsMessageSchema, AgentUpdatedWsMessageSchema, AgentDeletedWsMessageSchema, AgentUsageWsMessageSchema, PermissionRequestWsMessageSchema, PermissionCancelledWsMessageSchema, ErrorWsMessageSchema, AgentMessageWsMessageSchema, AgentToolProgressWsMessageSchema, TaskAddedWsMessageSchema, TaskUpdatedWsMessageSchema, TaskAssignedWsMessageSchema, TaskStateChangedWsMessageSchema, TaskDeletedWsMessageSchema, CircleCreatedWsMessageSchema, CircleUpdatedWsMessageSchema, CircleDeletedWsMessageSchema, RelationshipCreatedWsMessageSchema, RelationshipDeletedWsMessageSchema, AgentBuilderDraftUpdatedWsMessageSchema, isAgentServerMessage, CLIENT_MESSAGE_TYPE, SERVER_MESSAGE_TYPE, } from "./schemas/websocket.schema.js";
5
+ export { ClientMessageSchema, ServerMessageSchema, SendMessageSchema, InjectMessageSchema, PermissionResponseWsSchema, CommandMessageSchema, AgentTextWsMessageSchema, AgentActivityWsMessageSchema, AgentResultWsMessageSchema, AgentStatusWsMessageSchema, AgentCreatedWsMessageSchema, AgentUpdatedWsMessageSchema, AgentDeletedWsMessageSchema, AgentUsageWsMessageSchema, PermissionRequestWsMessageSchema, PermissionCancelledWsMessageSchema, ErrorWsMessageSchema, AgentMessageWsMessageSchema, AgentToolProgressWsMessageSchema, TaskAddedWsMessageSchema, TaskUpdatedWsMessageSchema, TaskAssignedWsMessageSchema, TaskStateChangedWsMessageSchema, TaskDeletedWsMessageSchema, CircleCreatedWsMessageSchema, CircleUpdatedWsMessageSchema, CircleDeletedWsMessageSchema, RelationshipCreatedWsMessageSchema, RelationshipDeletedWsMessageSchema, FragmentCreatedWsMessageSchema, FragmentUpdatedWsMessageSchema, FragmentDeletedWsMessageSchema, AgentBuilderDraftUpdatedWsMessageSchema, isAgentServerMessage, isAgentLifecycleServerMessage, CLIENT_MESSAGE_TYPE, SERVER_MESSAGE_TYPE, } from "./schemas/websocket.schema.js";
6
6
  export { PERMISSION_DECISION, PermissionRequestSchema, PermissionResponseSchema, } from "./schemas/permission.schema.js";
7
7
  export { AgentMessageSchema, MessageAnnotationSchema, AGENT_MESSAGE_ROLE, AGENT_MESSAGE_TYPE, } from "./schemas/agent-message.schema.js";
8
- export { ARTIFACT_TYPE, ARTIFACT_CONTENT_TYPE, ArtifactTypeSchema, ArtifactContentTypeSchema, ArtifactMetadataSchema, ArtifactUpdateSchema, } from "./schemas/artifact.schema.js";
8
+ export { ARTIFACT_TYPE, ARTIFACT_CONTENT_TYPE, ArtifactTypeSchema, ArtifactContentTypeSchema, ArtifactEntityTypeSchema, ArtifactMetadataSchema, ArtifactUpdateSchema, } from "./schemas/artifact.schema.js";
9
9
  export { AGENT_TASK_STATE, AGENT_TASK_SOURCE_TYPE, AgentTaskStateSchema, AgentTaskSourceSchema, AgentTaskItemSchema, AgentTaskDatabaseSchema, CreateTaskInputSchema, UpdateTaskInputSchema, UpdateTaskStateInputSchema, AssignTaskInputSchema, } from "./schemas/agent-task.schema.js";
10
10
  export { MCP_CONFIG_TYPE, InternalMcpConfigSchema, McpServerConfigSchema, CreateMcpConfigInputSchema, UpdateMcpConfigInputSchema, } from "./schemas/mcp-config.schema.js";
11
11
  export { SensorInfoSchema } from "./schemas/sensor.schema.js";
@@ -19,7 +19,9 @@ export { applyAgentOrder } from "./utils/apply-agent-order.js";
19
19
  export { MODEL_ALIASES, resolveModel, modelSupportsAdaptiveThinking } from "./utils/resolve-model.js";
20
20
  export { BASE_CIRCLE_ID, BASE_CIRCLE_NAME } from "./constants/system-circle.js";
21
21
  export { ENTITY_TYPE, RELATIONSHIP_TYPE, AgentCircleSchema, CreateAgentCircleInputSchema, UpdateAgentCircleInputSchema, EntityTypeSchema, RelationshipTypeSchema, RelationshipSchema, CreateRelationshipInputSchema, CircleMemberSchema, } from "./schemas/agent-circle.schema.js";
22
- export { CROW_SYSTEM_AGENT_ID, CROW_TASK_DISPATCHER_AGENT_ID, CROW_NARRATIVE_ARCHITECT_AGENT_ID, CROW_WORLD_BUILDER_AGENT_ID, } from "./constants/system-agent.js";
22
+ export { CROW_SYSTEM_AGENT_ID, CROW_TASK_DISPATCHER_AGENT_ID, CROW_NARRATIVE_ARCHITECT_AGENT_ID, CROW_WORLD_BUILDER_AGENT_ID, FRAGMENT_REFLECTION_AGENT_ID, } from "./constants/system-agent.js";
23
+ export { CreateFragmentAssociationInputSchema, FRAGMENT_KIND, FRAGMENT_FIRST_LEVEL_TARGET, FRAGMENT_MAX_WORDS, FragmentKindSchema, FragmentSchema, } from "./schemas/fragment.schema.js";
24
+ export { REFLECTION_AGENT_REF, REFLECTION_TEMP_PREFIX, REFLECTION_OP, ReflectionOpSchema, ReflectionPlanSchema, } from "./schemas/fragment-reflection.schema.js";
23
25
  export { MESSAGE_SOURCE_TYPE, MessageSourceSchema, } from "./schemas/message-source.schema.js";
24
26
  export { AGENT_COMMAND, AgentCommandSchema } from "./schemas/agent-command.schema.js";
25
27
  export { GraphNodeSchema, GraphEdgeSchema, GraphDataSchema, } from "./schemas/graph.schema.js";
@@ -5,13 +5,18 @@ import { z } from "zod";
5
5
  export const ENTITY_TYPE = {
6
6
  AGENT: "AGENT",
7
7
  AGENT_CIRCLE: "AGENT_CIRCLE",
8
+ FRAGMENT: "FRAGMENT",
8
9
  };
9
10
  /**
10
11
  * Relationship types between entities.
11
- * MEMBERSHIP means "source contains target as a member".
12
+ * MEMBERSHIP means "source contains target as a member" (agent ↔ circle only).
13
+ * ASSOCIATION anchors an agent to a fragment (agent → fragment).
14
+ * LINK connects fragments (fragment → fragment).
12
15
  */
13
16
  export const RELATIONSHIP_TYPE = {
14
17
  MEMBERSHIP: "MEMBERSHIP",
18
+ ASSOCIATION: "ASSOCIATION",
19
+ LINK: "LINK",
15
20
  };
16
21
  export const AgentCircleSchema = z.object({
17
22
  /** Unique identifier - UUID for user-created circles, well-known string for system circles */
@@ -37,8 +42,12 @@ export const UpdateAgentCircleInputSchema = z.object({
37
42
  convention: z.string().optional(),
38
43
  displayOrder: z.number().optional(),
39
44
  });
40
- export const EntityTypeSchema = z.enum([ENTITY_TYPE.AGENT, ENTITY_TYPE.AGENT_CIRCLE]);
41
- export const RelationshipTypeSchema = z.enum([RELATIONSHIP_TYPE.MEMBERSHIP]);
45
+ export const EntityTypeSchema = z.enum([ENTITY_TYPE.AGENT, ENTITY_TYPE.AGENT_CIRCLE, ENTITY_TYPE.FRAGMENT]);
46
+ export const RelationshipTypeSchema = z.enum([
47
+ RELATIONSHIP_TYPE.MEMBERSHIP,
48
+ RELATIONSHIP_TYPE.ASSOCIATION,
49
+ RELATIONSHIP_TYPE.LINK,
50
+ ]);
42
51
  export const RelationshipSchema = z.object({
43
52
  /** Unique identifier - UUID except for virtual relationship with system agents */
44
53
  id: z.string().min(1),
@@ -77,13 +77,13 @@ export const AgentRuntimeStateSchema = z.object({
77
77
  messageSource: MessageSourceSchema.optional(),
78
78
  discordDmChannelId: z.string().optional(),
79
79
  sessionId: z.string().optional(),
80
+ activeDomainFragmentIds: z.array(z.string()).default([]),
80
81
  sessionUsage: SessionUsageSchema,
81
82
  prevLoopMessageTimestamp: z.number().optional(),
82
83
  lastGmailCheckTimestamp: z.number().optional(),
83
84
  lastError: z.string().optional(),
84
85
  pendingPermissions: z.array(PendingPermissionInfoSchema).optional(),
85
86
  pendingInstructionReminder: PendingInstructionReminderSchema.optional(),
86
- /** Recent user message inputs (oldest first) for compose-box Up/Down recall; survives new sessions. */
87
87
  inputHistory: z.array(z.string()).optional(),
88
88
  });
89
89
  //# sourceMappingURL=agent-runtime-state.schema.js.map
@@ -1,6 +1,8 @@
1
1
  import { z } from "zod";
2
- import { EntityTypeSchema } from "./agent-circle.schema.js";
2
+ import { ENTITY_TYPE } from "./agent-circle.schema.js";
3
3
  import { AgentTaskSourceSchema } from "./agent-task.schema.js";
4
+ /** Entity types that can own artifacts — fragments are never artifact-bearing */
5
+ export const ArtifactEntityTypeSchema = z.enum([ENTITY_TYPE.AGENT, ENTITY_TYPE.AGENT_CIRCLE]);
4
6
  /**
5
7
  * TODO: layered memory system via artifacts.
6
8
  */
@@ -41,7 +43,7 @@ export const ArtifactMetadataSchema = z.object({
41
43
  type: ArtifactTypeSchema,
42
44
  contentType: ArtifactContentTypeSchema,
43
45
  entityId: z.string(),
44
- entityType: EntityTypeSchema,
46
+ entityType: ArtifactEntityTypeSchema,
45
47
  size: z.number(),
46
48
  tags: z.array(z.string()).optional(),
47
49
  createdTimestamp: z.number(),
@@ -0,0 +1,62 @@
1
+ import { z } from "zod";
2
+ import { FragmentKindSchema } from "./fragment.schema.js";
3
+ /**
4
+ * A plan node reference is a single string.
5
+ * `REFLECTION_AGENT_REF` names the target agent (top-level anchor).
6
+ * A string starting with `REFLECTION_TEMP_PREFIX` names a node created earlier in the same plan by its tempId.
7
+ * Anything else is an existing fragment id.
8
+ */
9
+ export const REFLECTION_AGENT_REF = "agent";
10
+ export const REFLECTION_TEMP_PREFIX = "$";
11
+ const NodeRefSchema = z.string().min(1);
12
+ /**
13
+ * Reflection plan operations, applied in order against the target agent's memory fragments.
14
+ * CREATE - a new node (theme/sub-domain) hanging under `parent`.
15
+ * LINK - add an edge, or move when `from` names the edge to drop.
16
+ * UNLINK - remove one named edge (last-edge removal cascade-deletes).
17
+ * UPDATE - content only (cue/body).
18
+ */
19
+ export const REFLECTION_OP = {
20
+ CREATE: "create",
21
+ LINK: "link",
22
+ UNLINK: "unlink",
23
+ UPDATE: "update",
24
+ };
25
+ const CreateReflectionOpSchema = z.object({
26
+ op: z.literal(REFLECTION_OP.CREATE),
27
+ /** Handle later operations in the same plan use to reference this node — must start with `$` */
28
+ tempId: z.string().regex(/^\$/),
29
+ kind: FragmentKindSchema,
30
+ cue: z.string().min(1),
31
+ body: z.string().min(1),
32
+ parent: NodeRefSchema,
33
+ });
34
+ const LinkReflectionOpSchema = z.object({
35
+ op: z.literal(REFLECTION_OP.LINK),
36
+ fragment: NodeRefSchema,
37
+ parent: NodeRefSchema,
38
+ /** When given, the move drops this original parent edge after the new one is added */
39
+ from: NodeRefSchema.optional(),
40
+ });
41
+ const UnlinkReflectionOpSchema = z.object({
42
+ op: z.literal(REFLECTION_OP.UNLINK),
43
+ fragment: NodeRefSchema,
44
+ parent: NodeRefSchema,
45
+ });
46
+ const UpdateReflectionOpSchema = z.object({
47
+ op: z.literal(REFLECTION_OP.UPDATE),
48
+ fragment: NodeRefSchema,
49
+ cue: z.string().min(1).optional(),
50
+ body: z.string().min(1).optional(),
51
+ });
52
+ export const ReflectionOpSchema = z.discriminatedUnion("op", [
53
+ CreateReflectionOpSchema,
54
+ LinkReflectionOpSchema,
55
+ UnlinkReflectionOpSchema,
56
+ UpdateReflectionOpSchema,
57
+ ]);
58
+ /** The single-pass reorganization plan the reflection agent returns between its output markers */
59
+ export const ReflectionPlanSchema = z.object({
60
+ operations: z.array(ReflectionOpSchema),
61
+ });
62
+ //# sourceMappingURL=fragment-reflection.schema.js.map
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Fragment kinds.
4
+ * DOMAIN - an organizing topic others nest under.
5
+ * KNOWLEDGE - a fact (even one a user tells you); leaf under a DOMAIN.
6
+ * LESSON - a how-to-act rule from the agent's own reflection.
7
+ * FEEDBACK - a correction or preference from the user.
8
+ */
9
+ export const FRAGMENT_KIND = {
10
+ FEEDBACK: "FEEDBACK",
11
+ LESSON: "LESSON",
12
+ DOMAIN: "DOMAIN",
13
+ KNOWLEDGE: "KNOWLEDGE",
14
+ };
15
+ export const FragmentKindSchema = z.enum([
16
+ FRAGMENT_KIND.FEEDBACK,
17
+ FRAGMENT_KIND.LESSON,
18
+ FRAGMENT_KIND.DOMAIN,
19
+ FRAGMENT_KIND.KNOWLEDGE,
20
+ ]);
21
+ /** Maximum number of words in a fragment body, kind-agnostic, enforced on write */
22
+ export const FRAGMENT_MAX_WORDS = 100;
23
+ /** Target ceiling for a first-level bucket or any parent's direct children before reflection consolidates */
24
+ export const FRAGMENT_FIRST_LEVEL_TARGET = 20;
25
+ /**
26
+ * An atomic unit of agent experience.
27
+ * Pure: no agent reference and no link fields — agent↔fragment and
28
+ * fragment↔fragment relations are relationship-graph edges only.
29
+ */
30
+ export const FragmentSchema = z.object({
31
+ id: z.string().min(1),
32
+ kind: FragmentKindSchema,
33
+ /** Level-1: short one-line relevance descriptor, always cheap to surface */
34
+ cue: z.string().min(1),
35
+ /** Level-2: the lesson itself, pulled on demand */
36
+ body: z.string().min(1),
37
+ /** Times the fragment has been recalled */
38
+ usageCount: z.number(),
39
+ lastRecalledTimestamp: z.number().optional(),
40
+ createdTimestamp: z.number(),
41
+ updatedTimestamp: z.number(),
42
+ });
43
+ /** Input for the user-facing sharing route: associate an agent to a fragment */
44
+ export const CreateFragmentAssociationInputSchema = z.object({
45
+ agentId: z.string().min(1),
46
+ });
47
+ //# sourceMappingURL=fragment.schema.js.map
@@ -1,7 +1,8 @@
1
1
  import { z } from "zod";
2
2
  import { EntityTypeSchema, RelationshipTypeSchema } from "./agent-circle.schema.js";
3
3
  import { AGENT_STATUS } from "./agent-runtime-state.schema.js";
4
- /** A node in the relationship graph — represents either an agent or a circle */
4
+ import { FragmentKindSchema } from "./fragment.schema.js";
5
+ /** A node in the relationship graph — represents an agent, a circle, or a fragment */
5
6
  export const GraphNodeSchema = z.object({
6
7
  id: z.string(),
7
8
  name: z.string(),
@@ -9,6 +10,7 @@ export const GraphNodeSchema = z.object({
9
10
  isSystemAgent: z.boolean().optional(),
10
11
  isPinned: z.boolean().optional(),
11
12
  isSystemCircle: z.boolean().optional(),
13
+ kind: FragmentKindSchema.optional(),
12
14
  status: z
13
15
  .enum([AGENT_STATUS.IDLE, AGENT_STATUS.ACTIVATING, AGENT_STATUS.STREAMING, AGENT_STATUS.COMPACTING])
14
16
  .optional(),
@@ -44,10 +44,13 @@ export const SERVER_MESSAGE_TYPE = {
44
44
  CIRCLE_DELETED: "circle_deleted",
45
45
  RELATIONSHIP_CREATED: "relationship_created",
46
46
  RELATIONSHIP_DELETED: "relationship_deleted",
47
+ FRAGMENT_CREATED: "fragment_created",
48
+ FRAGMENT_UPDATED: "fragment_updated",
49
+ FRAGMENT_DELETED: "fragment_deleted",
47
50
  AGENT_BUILDER_DRAFT_UPDATED: "agent_builder_draft_updated",
48
51
  };
49
52
  export const SendMessageSchema = z.object({
50
- type: z.literal("send_message"),
53
+ type: z.literal(CLIENT_MESSAGE_TYPE.SEND_MESSAGE),
51
54
  agentId: z.string(),
52
55
  message: z.string(),
53
56
  });
@@ -57,7 +60,7 @@ export const InjectMessageSchema = z.object({
57
60
  message: z.string(),
58
61
  });
59
62
  export const PermissionResponseWsSchema = z.object({
60
- type: z.literal("permission_response"),
63
+ type: z.literal(CLIENT_MESSAGE_TYPE.PERMISSION_RESPONSE),
61
64
  agentId: z.string(),
62
65
  toolUseId: z.string(),
63
66
  decision: z.enum([PERMISSION_DECISION.ALLOW, PERMISSION_DECISION.DENY, PERMISSION_DECISION.ALLOW_ALWAYS]),
@@ -76,24 +79,24 @@ export const ClientMessageSchema = z.discriminatedUnion("type", [
76
79
  CommandMessageSchema,
77
80
  ]);
78
81
  export const AgentTextWsMessageSchema = z.object({
79
- type: z.literal("agent_text"),
82
+ type: z.literal(SERVER_MESSAGE_TYPE.AGENT_TEXT),
80
83
  agentId: z.string(),
81
84
  text: z.string(),
82
85
  });
83
86
  export const AgentActivityWsMessageSchema = z.object({
84
- type: z.literal("agent_activity"),
87
+ type: z.literal(SERVER_MESSAGE_TYPE.AGENT_ACTIVITY),
85
88
  agentId: z.string(),
86
89
  agentActivity: AgentActivitySchema,
87
90
  });
88
91
  export const AgentResultWsMessageSchema = z.object({
89
- type: z.literal("agent_result"),
92
+ type: z.literal(SERVER_MESSAGE_TYPE.AGENT_RESULT),
90
93
  agentId: z.string(),
91
94
  subtype: z.string(),
92
95
  totalCostUsd: z.number().optional(),
93
96
  durationMs: z.number().optional(),
94
97
  });
95
98
  export const AgentStatusWsMessageSchema = z.object({
96
- type: z.literal("agent_status"),
99
+ type: z.literal(SERVER_MESSAGE_TYPE.AGENT_STATUS),
97
100
  agentId: z.string(),
98
101
  status: z.enum([AGENT_STATUS.IDLE, AGENT_STATUS.ACTIVATING, AGENT_STATUS.STREAMING, AGENT_STATUS.COMPACTING]),
99
102
  messageSource: MessageSourceSchema.optional(),
@@ -113,7 +116,7 @@ export const AgentDeletedWsMessageSchema = z.object({
113
116
  agentId: z.string(),
114
117
  });
115
118
  export const AgentUsageWsMessageSchema = z.object({
116
- type: z.literal("agent_usage"),
119
+ type: z.literal(SERVER_MESSAGE_TYPE.AGENT_USAGE),
117
120
  agentId: z.string(),
118
121
  inputTokens: z.number(),
119
122
  outputTokens: z.number(),
@@ -122,7 +125,7 @@ export const AgentUsageWsMessageSchema = z.object({
122
125
  contextTotal: z.number(),
123
126
  });
124
127
  export const PermissionRequestWsMessageSchema = z.object({
125
- type: z.literal("permission_request"),
128
+ type: z.literal(SERVER_MESSAGE_TYPE.PERMISSION_REQUEST),
126
129
  agentId: z.string(),
127
130
  toolUseId: z.string(),
128
131
  toolName: z.string(),
@@ -130,23 +133,23 @@ export const PermissionRequestWsMessageSchema = z.object({
130
133
  decisionReason: z.string().optional(),
131
134
  });
132
135
  export const PermissionCancelledWsMessageSchema = z.object({
133
- type: z.literal("permission_cancelled"),
136
+ type: z.literal(SERVER_MESSAGE_TYPE.PERMISSION_CANCELLED),
134
137
  agentId: z.string(),
135
138
  toolUseId: z.string(),
136
139
  });
137
140
  export const ErrorWsMessageSchema = z.object({
138
- type: z.literal("error"),
141
+ type: z.literal(SERVER_MESSAGE_TYPE.ERROR),
139
142
  agentId: z.string().optional(),
140
143
  code: z.string(),
141
144
  message: z.string(),
142
145
  });
143
146
  export const AgentMessageWsMessageSchema = z.object({
144
- type: z.literal("agent_message"),
147
+ type: z.literal(SERVER_MESSAGE_TYPE.AGENT_MESSAGE),
145
148
  agentId: z.string(),
146
149
  message: AgentMessageSchema,
147
150
  });
148
151
  export const AgentToolProgressWsMessageSchema = z.object({
149
- type: z.literal("agent_tool_progress"),
152
+ type: z.literal(SERVER_MESSAGE_TYPE.AGENT_TOOL_PROGRESS),
150
153
  agentId: z.string(),
151
154
  toolName: z.string(),
152
155
  elapsedTimeSeconds: z.number(),
@@ -192,6 +195,18 @@ export const RelationshipDeletedWsMessageSchema = z.object({
192
195
  type: z.literal(SERVER_MESSAGE_TYPE.RELATIONSHIP_DELETED),
193
196
  relationshipId: z.string(),
194
197
  });
198
+ export const FragmentCreatedWsMessageSchema = z.object({
199
+ type: z.literal(SERVER_MESSAGE_TYPE.FRAGMENT_CREATED),
200
+ fragmentId: z.string(),
201
+ });
202
+ export const FragmentUpdatedWsMessageSchema = z.object({
203
+ type: z.literal(SERVER_MESSAGE_TYPE.FRAGMENT_UPDATED),
204
+ fragmentId: z.string(),
205
+ });
206
+ export const FragmentDeletedWsMessageSchema = z.object({
207
+ type: z.literal(SERVER_MESSAGE_TYPE.FRAGMENT_DELETED),
208
+ fragmentId: z.string(),
209
+ });
195
210
  /** The single agent-builder draft changed; carries the resolved view, or null when it was cleared. */
196
211
  export const AgentBuilderDraftUpdatedWsMessageSchema = z.object({
197
212
  type: z.literal(SERVER_MESSAGE_TYPE.AGENT_BUILDER_DRAFT_UPDATED),
@@ -222,9 +237,20 @@ export const ServerMessageSchema = z.discriminatedUnion("type", [
222
237
  CircleDeletedWsMessageSchema,
223
238
  RelationshipCreatedWsMessageSchema,
224
239
  RelationshipDeletedWsMessageSchema,
240
+ FragmentCreatedWsMessageSchema,
241
+ FragmentUpdatedWsMessageSchema,
242
+ FragmentDeletedWsMessageSchema,
225
243
  AgentBuilderDraftUpdatedWsMessageSchema,
226
244
  ]);
227
245
  export function isAgentServerMessage(message) {
228
246
  return "agentId" in message && typeof message.agentId === "string";
229
247
  }
248
+ const AGENT_LIFECYCLE_MESSAGE_TYPES = new Set([
249
+ SERVER_MESSAGE_TYPE.AGENT_CREATED,
250
+ SERVER_MESSAGE_TYPE.AGENT_UPDATED,
251
+ SERVER_MESSAGE_TYPE.AGENT_DELETED,
252
+ ]);
253
+ export function isAgentLifecycleServerMessage(message) {
254
+ return AGENT_LIFECYCLE_MESSAGE_TYPES.has(message.type);
255
+ }
230
256
  //# sourceMappingURL=websocket.schema.js.map
@@ -0,0 +1,98 @@
1
+ import { PERMISSION_MODE, TOOL_MODE, CLAUDE_MODELS, FRAGMENT_REFLECTION_AGENT_ID, FRAGMENT_FIRST_LEVEL_TARGET, FRAGMENT_MAX_WORDS, REFLECTION_AGENT_REF, REFLECTION_TEMP_PREFIX, } from "../_shared/index.js";
2
+ import path from "node:path";
3
+ import { env } from "../config/env.js";
4
+ import { SYSTEM_AGENT_TYPE, resolveSystemAgentModel } from "./system-agent-provider.js";
5
+ import { createMessageContentFromTemplate, getDefaultPromptContext } from "../utils/message-template.js";
6
+ import { SYSTEM_AGENTS_PROJECT_DIR_NAME } from "../config/constants.js";
7
+ import { FRAGMENT_REFLECTION_BEGIN, FRAGMENT_REFLECTION_END, } from "../services/fragment/fragment-reflection.constants.js";
8
+ const CROW_FRAGMENT_REFLECTION_AGENT_NAME = "Crow Fragment Reflection";
9
+ /**
10
+ * Planner charter for the fragment reflection agent. Substituted with
11
+ * {maxWords}/{firstLevelTarget} from the shared fragment constants at agent build time.
12
+ */
13
+ export const CROW_FRAGMENT_REFLECTION_AGENT_PERSONA = {
14
+ role: "system",
15
+ content: [
16
+ {
17
+ content: [
18
+ "You are the reflective memory steward for crow central agency — an invisible background role that reviews another agent's long-term memory. Each run you step back and study ONE target agent's fragments: what it has newly learned, and how that sits against everything it already holds. From that reflection you return a plan that settles each fragment where it truly belongs. You never talk to a user, never mutate the memory yourself, and never emit anything but the plan.",
19
+ "",
20
+ "A fragment is one atomic memory: a short `cue` plus a `body` of at most {maxWords} words, typed DOMAIN, KNOWLEDGE, FEEDBACK, or LESSON. Fragments form a DAG — a fragment can hang under multiple parents by LINK, and top-level fragments are anchored to the agent. KNOWLEDGE is a leaf that only hangs under a DOMAIN.",
21
+ "",
22
+ "Your job: examine every fragment and settle each under the parents where it truly belongs, whether a DOMAIN it concerns or a broader FEEDBACK or LESSON it refines. When any parent's direct children grow past about {firstLevelTarget}, introduce an intermediate parent of the fitting kind and move the related members under it. Merge duplicates by folding unique content into the survivor before removing the loser, and prune stale or superseded fragments. Make minimal, high-confidence changes — under-organizing is far safer than scrambling sound structure.",
23
+ "",
24
+ "Use `read_fragment(id)` to pull any body the context did not front-load, and `search_fragment(targetAgentId, query)` to find near-duplicates elsewhere in the target's memory before you decide.",
25
+ "",
26
+ "## OUTPUT",
27
+ "",
28
+ "Emit exactly one JSON object between the markers below and nothing else — no preamble, no commentary, no code fences.",
29
+ "",
30
+ "Every node reference in the plan is a single string:",
31
+ `- \`"${REFLECTION_AGENT_REF}"\` — the target agent (top-level anchor).`,
32
+ `- \`"${REFLECTION_TEMP_PREFIX}…"\` (starts with \`${REFLECTION_TEMP_PREFIX}\`, e.g. \`"${REFLECTION_TEMP_PREFIX}1"\`) — a node created earlier in this same plan, by the tempId that create gave it.`,
33
+ "- anything else — an existing fragment id.",
34
+ "",
35
+ "Operand names are the same across ops: `fragment` = the node being operated on, `parent` = the node it hangs under, `from` = the old parent in a move.",
36
+ "",
37
+ "The plan:",
38
+ "```",
39
+ '{ "operations": [',
40
+ ` { "op": "create", "tempId": "${REFLECTION_TEMP_PREFIX}1", "kind": "DOMAIN|KNOWLEDGE|FEEDBACK|LESSON", "cue": "...", "body": "...", "parent": <ref> },`,
41
+ ' { "op": "link", "fragment": <ref>, "parent": <ref>, "from": <ref> }, // "from" optional — include to MOVE off that parent',
42
+ ' { "op": "unlink", "fragment": <ref>, "parent": <ref> }, // removing the last parent cascade-deletes the fragment + orphaned children',
43
+ ' { "op": "update", "fragment": <ref>, "cue": "...", "body": "..." } // cue/body optional — include only what changes',
44
+ "] }",
45
+ "```",
46
+ "",
47
+ "Rules:",
48
+ `- \`tempId\` must start with \`${REFLECTION_TEMP_PREFIX}\` and be unique within the plan; reference it in later ops as that same \`"${REFLECTION_TEMP_PREFIX}…"\` string.`,
49
+ "- Respect the structure rules — KNOWLEDGE only under a DOMAIN, bodies within {maxWords} words, no cycles. Invalid ops are rejected on apply, so plan only valid moves.",
50
+ '- If you have no confident changes to make, return `{ "operations": [] }`.',
51
+ "",
52
+ "Shape of every response:",
53
+ FRAGMENT_REFLECTION_BEGIN,
54
+ "<the plan JSON object>",
55
+ FRAGMENT_REFLECTION_END,
56
+ ],
57
+ },
58
+ ],
59
+ keys: ["maxWords", "firstLevelTarget"],
60
+ };
61
+ const CROW_FRAGMENT_REFLECTION_BIRTHDAY = "1970-01-01T00:00:00Z";
62
+ const CROW_FRAGMENT_REFLECTION_TOOLS = [];
63
+ /**
64
+ * Build the fragment reflection agent config - an invisible background agent that performs
65
+ * retrospection on one target agent's long-term memory per run and returns a single
66
+ * marker-wrapped reorganization plan.
67
+ */
68
+ export function getFragmentReflectionAgent() {
69
+ const persona = createMessageContentFromTemplate(CROW_FRAGMENT_REFLECTION_AGENT_PERSONA, getDefaultPromptContext({
70
+ maxWords: String(FRAGMENT_MAX_WORDS),
71
+ firstLevelTarget: String(FRAGMENT_FIRST_LEVEL_TARGET),
72
+ }));
73
+ return {
74
+ id: FRAGMENT_REFLECTION_AGENT_ID,
75
+ type: SYSTEM_AGENT_TYPE,
76
+ name: CROW_FRAGMENT_REFLECTION_AGENT_NAME,
77
+ description: "Reflection agent that reviews a target agent's long-term memory and plans its reorganization. Not user-facing.",
78
+ workspace: path.join(env.CROW_SYSTEM_PATH, SYSTEM_AGENTS_PROJECT_DIR_NAME),
79
+ persona,
80
+ model: resolveSystemAgentModel(CLAUDE_MODELS.SONNET),
81
+ permissionMode: PERMISSION_MODE.DEFAULT,
82
+ settingSources: [],
83
+ availableTools: [],
84
+ toolConfig: {
85
+ mode: TOOL_MODE.RESTRICTED,
86
+ tools: CROW_FRAGMENT_REFLECTION_TOOLS,
87
+ autoApprovedTools: CROW_FRAGMENT_REFLECTION_TOOLS,
88
+ },
89
+ mcpServerIds: [],
90
+ persistSession: false,
91
+ excludeClaudeCodeSystemPrompt: true,
92
+ isSystemAgent: true,
93
+ isBackgroundAgent: true,
94
+ createdAt: CROW_FRAGMENT_REFLECTION_BIRTHDAY,
95
+ updatedAt: CROW_FRAGMENT_REFLECTION_BIRTHDAY,
96
+ };
97
+ }
98
+ //# sourceMappingURL=crow-fragment-reflection-agent.js.map
package/dist/bootstrap.js CHANGED
@@ -16,6 +16,8 @@ import { PlacesManager } from "./services/places/places-manager.js";
16
16
  import { setupWebSocket } from "./server/setup-websocket.js";
17
17
  import { registerArtifactRoutes } from "./routes/artifact.routes.js";
18
18
  import { getArtifactsMcpServerDefinition } from "./mcp/artifacts/artifacts-mcp-server.js";
19
+ import { getFragmentsMcpServerDefinition } from "./mcp/fragments/fragments-mcp-server.js";
20
+ import { getFragmentsReflectionMcpServerDefinition } from "./mcp/fragments/fragments-reflection-mcp-server.js";
19
21
  import { getAgentsMcpServerDefinition } from "./mcp/agents/agents-mcp-server.js";
20
22
  import { getSuperAgentMcpServerDefinition } from "./mcp/agents/super-agent-mcp-server.js";
21
23
  import { getBuilderAgentMcpServerDefinition } from "./mcp/agents/builder-agent-mcp-server.js";
@@ -50,7 +52,12 @@ import { SensorManager } from "./sensors/sensor-manager.js";
50
52
  import { GeoLocationSensor } from "./sensors/geolocation-sensor.js";
51
53
  import { WeatherSensor } from "./sensors/weather-sensor.js";
52
54
  import { AgentCircleManager } from "./services/agent-circle-manager.js";
55
+ import { RelationshipManager } from "./services/relationship-manager.js";
56
+ import { FragmentManager } from "./services/fragment/fragment-manager.js";
57
+ import { FragmentReflectionStateStore } from "./services/fragment/fragment-reflection-state-store.js";
58
+ import { createFragmentReflectionRoutine } from "./routines/fragment-reflection-routine.js";
53
59
  import { registerCircleRoutes } from "./routes/circle.routes.js";
60
+ import { registerFragmentRoutes } from "./routes/fragment.routes.js";
54
61
  import { registerGraphRoutes } from "./routes/graph.routes.js";
55
62
  import { DiscordBotManager } from "./bot-connectors/discord/discord-bot-manager.js";
56
63
  import { createDiscordRoutine } from "./routines/discord-routine.js";
@@ -82,7 +89,9 @@ export async function bootstrap(options) {
82
89
  const folderFileProvider = new FolderFileStoreProvider(env.CROW_SYSTEM_PATH);
83
90
  const storeProvider = new FileObjectStoreProvider(env.CROW_SYSTEM_PATH);
84
91
  const systemSettingsManager = new SystemSettingsManager(storeProvider);
85
- const circleManager = new AgentCircleManager(storeProvider, broadcaster);
92
+ const relationshipManager = new RelationshipManager(storeProvider);
93
+ await relationshipManager.initialize();
94
+ const circleManager = new AgentCircleManager(storeProvider, relationshipManager, broadcaster);
86
95
  await circleManager.initialize();
87
96
  const registry = new AgentRegistry(storeProvider, folderFileProvider, broadcaster, circleManager);
88
97
  await registry.initialize();
@@ -94,7 +103,9 @@ export async function bootstrap(options) {
94
103
  await feedManager.initialize();
95
104
  const artifactManager = new ArtifactManager(storeProvider, registry, circleManager);
96
105
  await artifactManager.initialize();
97
- const documentSearchService = new DocumentSearchService(artifactManager, taskManager, registry, circleManager);
106
+ const fragmentManager = new FragmentManager(folderFileProvider, storeProvider, relationshipManager, broadcaster);
107
+ await fragmentManager.initialize();
108
+ const documentSearchService = new DocumentSearchService(artifactManager, taskManager, registry, circleManager, fragmentManager);
98
109
  await documentSearchService.initialize();
99
110
  const placesManager = new PlacesManager();
100
111
  const connectorManager = new ConnectorManager(storeProvider, registry, crowScheduler);
@@ -108,7 +119,7 @@ export async function bootstrap(options) {
108
119
  const sensorManager = new SensorManager(storeProvider);
109
120
  sensorManager.registerSensor(new GeoLocationSensor(placesManager));
110
121
  sensorManager.registerSensor(new WeatherSensor());
111
- const runtimeManager = new AgentRuntimeManager(storeProvider, broadcaster, registry, mcpManager, sessionManager, messageQueue, taskManager, sensorManager, circleManager);
122
+ const runtimeManager = new AgentRuntimeManager(storeProvider, broadcaster, registry, mcpManager, sessionManager, messageQueue, taskManager, sensorManager, circleManager, fragmentManager);
112
123
  await runtimeManager.initialize();
113
124
  const worldBuilderDraftStore = new WorldBuilderDraftStore(storeProvider);
114
125
  const worldBuilderService = new WorldBuilderService(runtimeManager, worldBuilderDraftStore, registry, circleManager, mcpManager, broadcaster);
@@ -127,6 +138,9 @@ export async function bootstrap(options) {
127
138
  routineManager.addRoutine(feedNewItemsRoutine);
128
139
  const gmailNotificationRoutine = createGmailNotificationRoutine(registry, taskManager, runtimeManager, connectorManager, sensorManager);
129
140
  routineManager.addRoutine(gmailNotificationRoutine);
141
+ const fragmentReflectionStateStore = new FragmentReflectionStateStore(storeProvider);
142
+ const fragmentReflectionRoutine = createFragmentReflectionRoutine(registry, runtimeManager, fragmentManager, fragmentReflectionStateStore);
143
+ routineManager.addRoutine(fragmentReflectionRoutine);
130
144
  // Discord bot manager — creates per-agent bots for agents with discordConfig
131
145
  const discordBotManager = new DiscordBotManager(registry, runtimeManager);
132
146
  await discordBotManager.initialize();
@@ -134,7 +148,9 @@ export async function bootstrap(options) {
134
148
  routineManager.addRoutine(discordRoutine);
135
149
  // Register built-in MCP servers
136
150
  mcpManager.registerMcpServer(getArtifactsMcpServerDefinition(artifactManager, registry, circleManager, sensorManager));
137
- mcpManager.registerMcpServer(getAgentsMcpServerDefinition(registry, runtimeManager, taskManager, documentSearchService, circleManager));
151
+ mcpManager.registerMcpServer(getFragmentsMcpServerDefinition(fragmentManager, runtimeManager));
152
+ mcpManager.registerMcpServer(getFragmentsReflectionMcpServerDefinition(fragmentManager, runtimeManager, documentSearchService));
153
+ mcpManager.registerMcpServer(getAgentsMcpServerDefinition(registry, runtimeManager, taskManager, documentSearchService, circleManager, fragmentManager));
138
154
  mcpManager.registerMcpServer(getTasksMcpServerDefinition(taskManager, circleManager, sensorManager));
139
155
  mcpManager.registerMcpServer(getFeedMcpServerDefinition(registry, feedManager, sensorManager, systemSettingsManager));
140
156
  mcpManager.registerMcpServer(getAudioMcpServerDefinition(registry, artifactManager));
@@ -164,7 +180,8 @@ export async function bootstrap(options) {
164
180
  await registerMcpRoutes(server, mcpManager);
165
181
  await registerSensorRoutes(server, sensorManager);
166
182
  await registerCircleRoutes(server, circleManager, registry);
167
- await registerGraphRoutes(server, circleManager, registry, runtimeManager);
183
+ await registerFragmentRoutes(server, fragmentManager, registry);
184
+ await registerGraphRoutes(server, circleManager, registry, runtimeManager, fragmentManager);
168
185
  await registerFeedRoutes(server, feedManager);
169
186
  await registerSystemSettingsRoutes(server, systemSettingsManager);
170
187
  await registerConnectorsRoutes(server, connectorManager);
@@ -24,6 +24,7 @@ export const APP_ERROR_CODES = {
24
24
  SDK_ERROR: "sdk_error",
25
25
  WS_ERROR: "ws_error",
26
26
  CIRCLE_NOT_FOUND: "circle_not_found",
27
+ FRAGMENT_NOT_FOUND: "fragment_not_found",
27
28
  RELATIONSHIP_NOT_FOUND: "relationship_not_found",
28
29
  DUPLICATE_RELATIONSHIP: "duplicate_relationship",
29
30
  CIRCLE_IMMUTABLE: "circle_immutable",
@@ -2,16 +2,16 @@ import { defineMcpTool } from "../crow-mcp-manager-utils.js";
2
2
  import { getListAgentsToolConfig } from "./list-agents.js";
3
3
  import { getInvokeAgentToolConfig } from "./invoke-agent.js";
4
4
  import { getSearchWorkspaceToolConfig } from "./search-workspace.js";
5
- import { CROW_NARRATIVE_ARCHITECT_AGENT_ID, CROW_WORLD_BUILDER_AGENT_ID } from "../../_shared/index.js";
5
+ import { CROW_NARRATIVE_ARCHITECT_AGENT_ID, CROW_WORLD_BUILDER_AGENT_ID, FRAGMENT_REFLECTION_AGENT_ID, } from "../../_shared/index.js";
6
6
  export const CROW_AGENTS_MCP_SERVER_NAME = "crow-agents";
7
- export function getAgentsMcpServerDefinition(registry, runtimeManager, taskManager, documentSearchService, circleManager) {
7
+ export function getAgentsMcpServerDefinition(registry, runtimeManager, taskManager, documentSearchService, circleManager, fragmentManager) {
8
8
  return {
9
9
  name: CROW_AGENTS_MCP_SERVER_NAME,
10
- disallowedAgentIds: [CROW_NARRATIVE_ARCHITECT_AGENT_ID, CROW_WORLD_BUILDER_AGENT_ID],
10
+ disallowedAgentIds: [CROW_NARRATIVE_ARCHITECT_AGENT_ID, CROW_WORLD_BUILDER_AGENT_ID, FRAGMENT_REFLECTION_AGENT_ID],
11
11
  getTools: (agentId) => [
12
12
  defineMcpTool(getListAgentsToolConfig(agentId, registry)),
13
13
  defineMcpTool(getInvokeAgentToolConfig(agentId, registry, runtimeManager, taskManager)),
14
- defineMcpTool(getSearchWorkspaceToolConfig(agentId, documentSearchService, taskManager, circleManager)),
14
+ defineMcpTool(getSearchWorkspaceToolConfig(agentId, documentSearchService, taskManager, circleManager, fragmentManager)),
15
15
  ],
16
16
  };
17
17
  }