@forwardimpact/model 0.3.0 → 0.4.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
@@ -706,10 +706,8 @@ export function generateStageAgentProfile({
706
706
  const fullName = `${abbrev}-${toKebabCase(track.id)}-${stage.id}`;
707
707
  const filename = `${fullName}.agent.md`;
708
708
 
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}`;
709
+ // Build description using shared helper
710
+ const description = buildAgentDescription(discipline, track, stage);
713
711
 
714
712
  // Format checklist as markdown
715
713
  const checklistMarkdown = formatChecklistMarkdown(agent.checklist);
@@ -746,16 +744,16 @@ export function generateStageAgentProfile({
746
744
 
747
745
  /**
748
746
  * Build an agent description from discipline, track, and stage
749
- * Uses the same format as generateStageAgentProfile for consistency
747
+ * Uses stage.summary for third-person metadata description
750
748
  * @param {Object} discipline - Human discipline definition
751
749
  * @param {Object} track - Human track definition
752
- * @param {Object} stage - Stage definition
750
+ * @param {Object} stage - Stage definition with summary field
753
751
  * @returns {string} Agent description
754
752
  */
755
753
  function buildAgentDescription(discipline, track, stage) {
756
754
  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}`;
755
+ const stageSummary = stage.summary || stage.name;
756
+ return `${stageSummary} agent for ${discipline.specialization || discipline.name} on ${track.name} track. ${disciplineDesc}`;
759
757
  }
760
758
 
761
759
  /**
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.4.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"