@forwardimpact/model 0.3.0 → 0.5.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/lib/agent.js CHANGED
@@ -19,7 +19,7 @@
19
19
  */
20
20
 
21
21
  import { deriveSkillMatrix, deriveBehaviourProfile } from "./derivation.js";
22
- import { deriveChecklist, formatChecklistMarkdown } from "./checklist.js";
22
+ import { deriveChecklist } from "./checklist.js";
23
23
  import {
24
24
  filterSkillsForAgent,
25
25
  sortByLevelDescending,
@@ -308,7 +308,6 @@ function estimateBodyDataLength(bodyData) {
308
308
  "priority",
309
309
  "roleContext",
310
310
  "workingStyle",
311
- "beforeHandoff",
312
311
  ];
313
312
  for (const field of stringFields) {
314
313
  if (bodyData[field]) {
@@ -487,7 +486,7 @@ function getChecklistStage(stageId) {
487
486
  * @param {Array} params.derivedBehaviours - Behaviours sorted by maturity
488
487
  * @param {Array} params.agentBehaviours - Agent behaviour definitions
489
488
  * @param {Array} params.skills - All skill definitions (for agent section lookup)
490
- * @param {string} params.checklistMarkdown - Pre-formatted checklist markdown
489
+ * @param {Array<{skill: Object, capability: Object, items: string[]}>} params.checklist - Raw checklist from deriveChecklist
491
490
  * @param {Array<{id: string, name: string, description: string}>} [params.agentIndex] - List of all available agents
492
491
  * @returns {Object} Structured profile body data
493
492
  */
@@ -501,7 +500,7 @@ function buildStageProfileBodyData({
501
500
  derivedBehaviours,
502
501
  agentBehaviours,
503
502
  skills,
504
- checklistMarkdown,
503
+ checklist,
505
504
  agentIndex,
506
505
  }) {
507
506
  const name = `${humanDiscipline.specialization || humanDiscipline.name} - ${humanTrack.name}`;
@@ -563,7 +562,7 @@ function buildStageProfileBodyData({
563
562
  skillIndex,
564
563
  roleContext,
565
564
  workingStyles,
566
- beforeHandoff: checklistMarkdown || null,
565
+ beforeHandoff: checklist || [],
567
566
  constraints,
568
567
  agentIndex: filteredAgentIndex,
569
568
  hasAgentIndex: filteredAgentIndex.length > 0,
@@ -706,15 +705,10 @@ export function generateStageAgentProfile({
706
705
  const fullName = `${abbrev}-${toKebabCase(track.id)}-${stage.id}`;
707
706
  const filename = `${fullName}.agent.md`;
708
707
 
709
- // Build description
710
- const disciplineDesc = discipline.description.trim().split("\n")[0];
711
- const stageDesc = stage.description.split(" - ")[0]; // Just the short part
712
- const description = `${stageDesc} agent for ${discipline.specialization || discipline.name} on ${track.name} track. ${disciplineDesc}`;
713
-
714
- // Format checklist as markdown
715
- const checklistMarkdown = formatChecklistMarkdown(agent.checklist);
708
+ // Build description using shared helper
709
+ const description = buildAgentDescription(discipline, track, stage);
716
710
 
717
- // Build structured profile body data
711
+ // Build structured profile body data (pass raw checklist for template iteration)
718
712
  const bodyData = buildStageProfileBodyData({
719
713
  stage,
720
714
  humanDiscipline: discipline,
@@ -725,7 +719,7 @@ export function generateStageAgentProfile({
725
719
  derivedBehaviours: agent.derivedBehaviours,
726
720
  agentBehaviours,
727
721
  skills,
728
- checklistMarkdown,
722
+ checklist: agent.checklist,
729
723
  agentIndex,
730
724
  });
731
725
 
@@ -746,16 +740,16 @@ export function generateStageAgentProfile({
746
740
 
747
741
  /**
748
742
  * Build an agent description from discipline, track, and stage
749
- * Uses the same format as generateStageAgentProfile for consistency
743
+ * Uses stage.summary for third-person metadata description
750
744
  * @param {Object} discipline - Human discipline definition
751
745
  * @param {Object} track - Human track definition
752
- * @param {Object} stage - Stage definition
746
+ * @param {Object} stage - Stage definition with summary field
753
747
  * @returns {string} Agent description
754
748
  */
755
749
  function buildAgentDescription(discipline, track, stage) {
756
750
  const disciplineDesc = discipline.description.trim().split("\n")[0];
757
- const stageDesc = stage.description.split(" - ")[0];
758
- return `${stageDesc} agent for ${discipline.specialization || discipline.name} on ${track.name} track. ${disciplineDesc}`;
751
+ const stageSummary = stage.summary || stage.name;
752
+ return `${stageSummary} agent for ${discipline.specialization || discipline.name} on ${track.name} track. ${disciplineDesc}`;
759
753
  }
760
754
 
761
755
  /**
package/lib/toolkit.js CHANGED
@@ -2,9 +2,12 @@
2
2
  * Toolkit Derivation Functions
3
3
  *
4
4
  * Derives a de-duplicated list of tools from a skill matrix by looking up
5
- * toolReferences from skill definitions.
5
+ * toolReferences from skill definitions. Only skills at the highest derived
6
+ * level contribute tools, ensuring focused toolkits for both jobs and agents.
6
7
  */
7
8
 
9
+ import { filterByHighestLevel } from "./profile.js";
10
+
8
11
  /**
9
12
  * @typedef {Object} ToolkitEntry
10
13
  * @property {string} name - Tool name
@@ -17,22 +20,26 @@
17
20
  /**
18
21
  * Derive a de-duplicated toolkit from a skill matrix
19
22
  *
20
- * Extracts all tools referenced by skills in the matrix, de-duplicates by name,
21
- * and collects which skills reference each tool.
23
+ * Extracts tools from skills at the highest derived level, de-duplicates by name,
24
+ * and collects which skills reference each tool. This keeps toolkits focused on
25
+ * the engineer's core competencies for both jobs and agents.
22
26
  *
23
27
  * @param {Object} params
24
- * @param {Array<{skillId: string}>} params.skillMatrix - Skill matrix with skill IDs
28
+ * @param {Array<{skillId: string, level: string}>} params.skillMatrix - Skill matrix with skill IDs and levels
25
29
  * @param {Array} params.skills - All skill definitions with toolReferences
26
30
  * @returns {ToolkitEntry[]} De-duplicated toolkit sorted by name
27
31
  */
28
32
  export function deriveToolkit({ skillMatrix, skills }) {
33
+ // Filter to highest level skills only
34
+ const sourceMatrix = filterByHighestLevel(skillMatrix);
35
+
29
36
  // Build skill lookup map for O(1) access
30
37
  const skillMap = new Map(skills.map((s) => [s.id, s]));
31
38
 
32
39
  // Tool map for de-duplication: name -> ToolkitEntry
33
40
  const toolMap = new Map();
34
41
 
35
- for (const entry of skillMatrix) {
42
+ for (const entry of sourceMatrix) {
36
43
  const skill = skillMap.get(entry.skillId);
37
44
  if (!skill?.toolReferences) continue;
38
45
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forwardimpact/model",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Derivation engine for roles, skills, and AI agent profiles",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -28,7 +28,7 @@
28
28
  "./progression": "./lib/progression.js"
29
29
  },
30
30
  "dependencies": {
31
- "@forwardimpact/schema": "^0.3.0"
31
+ "@forwardimpact/schema": "^0.4.0"
32
32
  },
33
33
  "engines": {
34
34
  "node": ">=18.0.0"