@forwardimpact/model 0.4.0 → 0.7.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/README.md +2 -2
- package/package.json +17 -15
- package/{lib → src}/agent.js +20 -22
- package/{lib → src}/derivation.js +6 -9
- package/{lib → src}/index.js +59 -17
- package/{lib → src}/interview.js +450 -21
- package/{lib → src}/job-cache.js +7 -7
- package/{lib → src}/matching.js +38 -28
- package/{lib → src}/modifiers.js +4 -4
- package/src/policies/composed.js +111 -0
- package/src/policies/filters.js +104 -0
- package/src/policies/index.js +128 -0
- package/src/policies/orderings.js +300 -0
- package/src/policies/predicates.js +177 -0
- package/src/policies/thresholds.js +160 -0
- package/src/profile.js +182 -0
- package/{lib → src}/progression.js +8 -13
- package/{lib → src}/toolkit.js +3 -3
- package/lib/profile.js +0 -262
- /package/{lib → src}/checklist.js +0 -0
- /package/{lib → src}/job.js +0 -0
package/README.md
CHANGED
|
@@ -29,8 +29,8 @@ import {
|
|
|
29
29
|
deriveSkillMatrix,
|
|
30
30
|
deriveBehaviourProfile,
|
|
31
31
|
} from "@forwardimpact/model/derivation";
|
|
32
|
-
import { prepareAgentProfile } from "@forwardimpact/model/
|
|
33
|
-
import {
|
|
32
|
+
import { prepareAgentProfile } from "@forwardimpact/model/profile";
|
|
33
|
+
import { deriveInterviewQuestions } from "@forwardimpact/model/interview";
|
|
34
34
|
import { analyzeProgression } from "@forwardimpact/model/progression";
|
|
35
35
|
```
|
|
36
36
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forwardimpact/model",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Derivation engine for roles, skills, and AI agent profiles",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -10,25 +10,27 @@
|
|
|
10
10
|
},
|
|
11
11
|
"homepage": "https://www.forwardimpact.team/model",
|
|
12
12
|
"type": "module",
|
|
13
|
-
"main": "
|
|
13
|
+
"main": "src/index.js",
|
|
14
14
|
"files": [
|
|
15
|
-
"
|
|
15
|
+
"src/"
|
|
16
16
|
],
|
|
17
17
|
"exports": {
|
|
18
|
-
".": "./
|
|
19
|
-
"./derivation": "./
|
|
20
|
-
"./modifiers": "./
|
|
21
|
-
"./agent": "./
|
|
22
|
-
"./interview": "./
|
|
23
|
-
"./job": "./
|
|
24
|
-
"./job-cache": "./
|
|
25
|
-
"./checklist": "./
|
|
26
|
-
"./matching": "./
|
|
27
|
-
"./profile": "./
|
|
28
|
-
"./progression": "./
|
|
18
|
+
".": "./src/index.js",
|
|
19
|
+
"./derivation": "./src/derivation.js",
|
|
20
|
+
"./modifiers": "./src/modifiers.js",
|
|
21
|
+
"./agent": "./src/agent.js",
|
|
22
|
+
"./interview": "./src/interview.js",
|
|
23
|
+
"./job": "./src/job.js",
|
|
24
|
+
"./job-cache": "./src/job-cache.js",
|
|
25
|
+
"./checklist": "./src/checklist.js",
|
|
26
|
+
"./matching": "./src/matching.js",
|
|
27
|
+
"./profile": "./src/profile.js",
|
|
28
|
+
"./progression": "./src/progression.js",
|
|
29
|
+
"./policies": "./src/policies/index.js",
|
|
30
|
+
"./toolkit": "./src/toolkit.js"
|
|
29
31
|
},
|
|
30
32
|
"dependencies": {
|
|
31
|
-
"@forwardimpact/schema": "^0.
|
|
33
|
+
"@forwardimpact/schema": "^0.6.0"
|
|
32
34
|
},
|
|
33
35
|
"engines": {
|
|
34
36
|
"node": ">=18.0.0"
|
package/{lib → src}/agent.js
RENAMED
|
@@ -19,12 +19,13 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import { deriveSkillMatrix, deriveBehaviourProfile } from "./derivation.js";
|
|
22
|
-
import { deriveChecklist
|
|
22
|
+
import { deriveChecklist } from "./checklist.js";
|
|
23
23
|
import {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
} from "./
|
|
24
|
+
filterAgentSkills,
|
|
25
|
+
sortAgentSkills,
|
|
26
|
+
sortAgentBehaviours,
|
|
27
|
+
} from "./policies/composed.js";
|
|
28
|
+
import { ORDER_AGENT_STAGE } from "./policies/orderings.js";
|
|
28
29
|
import { SkillLevel } from "@forwardimpact/schema/levels";
|
|
29
30
|
|
|
30
31
|
/**
|
|
@@ -123,9 +124,9 @@ export function deriveAgentSkills({ discipline, track, grade, skills }) {
|
|
|
123
124
|
skills,
|
|
124
125
|
});
|
|
125
126
|
|
|
126
|
-
// Apply agent-specific filtering and sorting
|
|
127
|
-
const filtered =
|
|
128
|
-
return
|
|
127
|
+
// Apply agent-specific filtering and sorting using policies
|
|
128
|
+
const filtered = filterAgentSkills(skillMatrix);
|
|
129
|
+
return sortAgentSkills(filtered);
|
|
129
130
|
}
|
|
130
131
|
|
|
131
132
|
/**
|
|
@@ -151,7 +152,7 @@ export function deriveAgentBehaviours({
|
|
|
151
152
|
behaviours,
|
|
152
153
|
});
|
|
153
154
|
|
|
154
|
-
return
|
|
155
|
+
return sortAgentBehaviours(profile);
|
|
155
156
|
}
|
|
156
157
|
|
|
157
158
|
/**
|
|
@@ -229,7 +230,7 @@ function buildWorkingStyleFromBehaviours(
|
|
|
229
230
|
* @param {Array} stages - All stage entities
|
|
230
231
|
* @returns {Object} Skill with frontmatter, title, stages array, reference, dirname
|
|
231
232
|
*/
|
|
232
|
-
export function
|
|
233
|
+
export function generateSkillMarkdown(skillData, stages) {
|
|
233
234
|
const { agent, name } = skillData;
|
|
234
235
|
|
|
235
236
|
if (!agent) {
|
|
@@ -272,10 +273,11 @@ export function generateSkillMd(skillData, stages) {
|
|
|
272
273
|
},
|
|
273
274
|
);
|
|
274
275
|
|
|
275
|
-
// Sort stages
|
|
276
|
-
const stageOrder = ["plan", "code", "review"];
|
|
276
|
+
// Sort stages using canonical ordering from policies
|
|
277
277
|
stagesArray.sort(
|
|
278
|
-
(a, b) =>
|
|
278
|
+
(a, b) =>
|
|
279
|
+
ORDER_AGENT_STAGE.indexOf(a.stageId) -
|
|
280
|
+
ORDER_AGENT_STAGE.indexOf(b.stageId),
|
|
279
281
|
);
|
|
280
282
|
|
|
281
283
|
return {
|
|
@@ -308,7 +310,6 @@ function estimateBodyDataLength(bodyData) {
|
|
|
308
310
|
"priority",
|
|
309
311
|
"roleContext",
|
|
310
312
|
"workingStyle",
|
|
311
|
-
"beforeHandoff",
|
|
312
313
|
];
|
|
313
314
|
for (const field of stringFields) {
|
|
314
315
|
if (bodyData[field]) {
|
|
@@ -487,7 +488,7 @@ function getChecklistStage(stageId) {
|
|
|
487
488
|
* @param {Array} params.derivedBehaviours - Behaviours sorted by maturity
|
|
488
489
|
* @param {Array} params.agentBehaviours - Agent behaviour definitions
|
|
489
490
|
* @param {Array} params.skills - All skill definitions (for agent section lookup)
|
|
490
|
-
* @param {string} params.
|
|
491
|
+
* @param {Array<{skill: Object, capability: Object, items: string[]}>} params.checklist - Raw checklist from deriveChecklist
|
|
491
492
|
* @param {Array<{id: string, name: string, description: string}>} [params.agentIndex] - List of all available agents
|
|
492
493
|
* @returns {Object} Structured profile body data
|
|
493
494
|
*/
|
|
@@ -501,7 +502,7 @@ function buildStageProfileBodyData({
|
|
|
501
502
|
derivedBehaviours,
|
|
502
503
|
agentBehaviours,
|
|
503
504
|
skills,
|
|
504
|
-
|
|
505
|
+
checklist,
|
|
505
506
|
agentIndex,
|
|
506
507
|
}) {
|
|
507
508
|
const name = `${humanDiscipline.specialization || humanDiscipline.name} - ${humanTrack.name}`;
|
|
@@ -563,7 +564,7 @@ function buildStageProfileBodyData({
|
|
|
563
564
|
skillIndex,
|
|
564
565
|
roleContext,
|
|
565
566
|
workingStyles,
|
|
566
|
-
beforeHandoff:
|
|
567
|
+
beforeHandoff: checklist || [],
|
|
567
568
|
constraints,
|
|
568
569
|
agentIndex: filteredAgentIndex,
|
|
569
570
|
hasAgentIndex: filteredAgentIndex.length > 0,
|
|
@@ -709,10 +710,7 @@ export function generateStageAgentProfile({
|
|
|
709
710
|
// Build description using shared helper
|
|
710
711
|
const description = buildAgentDescription(discipline, track, stage);
|
|
711
712
|
|
|
712
|
-
//
|
|
713
|
-
const checklistMarkdown = formatChecklistMarkdown(agent.checklist);
|
|
714
|
-
|
|
715
|
-
// Build structured profile body data
|
|
713
|
+
// Build structured profile body data (pass raw checklist for template iteration)
|
|
716
714
|
const bodyData = buildStageProfileBodyData({
|
|
717
715
|
stage,
|
|
718
716
|
humanDiscipline: discipline,
|
|
@@ -723,7 +721,7 @@ export function generateStageAgentProfile({
|
|
|
723
721
|
derivedBehaviours: agent.derivedBehaviours,
|
|
724
722
|
agentBehaviours,
|
|
725
723
|
skills,
|
|
726
|
-
|
|
724
|
+
checklist: agent.checklist,
|
|
727
725
|
agentIndex,
|
|
728
726
|
});
|
|
729
727
|
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
} from "@forwardimpact/schema/levels";
|
|
19
19
|
|
|
20
20
|
import { resolveSkillModifier } from "./modifiers.js";
|
|
21
|
+
import { ORDER_SKILL_TYPE } from "./policies/orderings.js";
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Build a Map of skillId → skillType for a discipline
|
|
@@ -226,14 +227,10 @@ export function deriveSkillMatrix({ discipline, grade, track = null, skills }) {
|
|
|
226
227
|
}
|
|
227
228
|
|
|
228
229
|
// Sort by type (primary first, then secondary, then broad, then track) and then by name
|
|
229
|
-
|
|
230
|
-
[SkillType.PRIMARY]: 0,
|
|
231
|
-
[SkillType.SECONDARY]: 1,
|
|
232
|
-
[SkillType.BROAD]: 2,
|
|
233
|
-
[SkillType.TRACK]: 3,
|
|
234
|
-
};
|
|
230
|
+
// Use ORDER_SKILL_TYPE from policies for canonical ordering
|
|
235
231
|
matrix.sort((a, b) => {
|
|
236
|
-
const typeCompare =
|
|
232
|
+
const typeCompare =
|
|
233
|
+
ORDER_SKILL_TYPE.indexOf(a.type) - ORDER_SKILL_TYPE.indexOf(b.type);
|
|
237
234
|
if (typeCompare !== 0) return typeCompare;
|
|
238
235
|
return a.skillName.localeCompare(b.skillName);
|
|
239
236
|
});
|
|
@@ -485,7 +482,7 @@ export function deriveResponsibilities({
|
|
|
485
482
|
capability: capabilityId,
|
|
486
483
|
capabilityName: capability.name,
|
|
487
484
|
emojiIcon: capability.emojiIcon || "💡",
|
|
488
|
-
|
|
485
|
+
ordinalRank: capability.ordinalRank ?? 999,
|
|
489
486
|
responsibility: responsibilityText,
|
|
490
487
|
level,
|
|
491
488
|
levelIndex: SKILL_LEVEL_ORDER.indexOf(level),
|
|
@@ -498,7 +495,7 @@ export function deriveResponsibilities({
|
|
|
498
495
|
if (b.levelIndex !== a.levelIndex) {
|
|
499
496
|
return b.levelIndex - a.levelIndex;
|
|
500
497
|
}
|
|
501
|
-
return a.
|
|
498
|
+
return a.ordinalRank - b.ordinalRank;
|
|
502
499
|
});
|
|
503
500
|
|
|
504
501
|
// Remove levelIndex from output (internal use only)
|
package/{lib → src}/index.js
RENAMED
|
@@ -33,11 +33,11 @@ export {
|
|
|
33
33
|
|
|
34
34
|
// Job caching
|
|
35
35
|
export {
|
|
36
|
-
|
|
36
|
+
buildJobKey,
|
|
37
37
|
getOrCreateJob,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
clearCache,
|
|
39
|
+
invalidateCachedJob,
|
|
40
|
+
getCachedJobCount,
|
|
41
41
|
} from "./job-cache.js";
|
|
42
42
|
|
|
43
43
|
// Modifiers
|
|
@@ -45,17 +45,17 @@ export {
|
|
|
45
45
|
isCapability,
|
|
46
46
|
getSkillsByCapability,
|
|
47
47
|
buildCapabilityToSkillsMap,
|
|
48
|
-
|
|
48
|
+
expandModifiersToSkills,
|
|
49
49
|
extractCapabilityModifiers,
|
|
50
|
-
|
|
50
|
+
extractSkillModifiers,
|
|
51
51
|
resolveSkillModifier,
|
|
52
52
|
} from "./modifiers.js";
|
|
53
53
|
|
|
54
54
|
// Matching
|
|
55
55
|
export {
|
|
56
56
|
MatchTier,
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
CONFIG_MATCH_TIER,
|
|
58
|
+
classifyMatch,
|
|
59
59
|
GAP_SCORES,
|
|
60
60
|
calculateGapScore,
|
|
61
61
|
calculateJobMatch,
|
|
@@ -87,16 +87,18 @@ export {
|
|
|
87
87
|
deriveShortInterview,
|
|
88
88
|
deriveBehaviourQuestions,
|
|
89
89
|
deriveFocusedInterview,
|
|
90
|
+
deriveMissionFitInterview,
|
|
91
|
+
deriveDecompositionInterview,
|
|
92
|
+
deriveStakeholderInterview,
|
|
90
93
|
} from "./interview.js";
|
|
91
94
|
|
|
92
95
|
// Agent generation
|
|
93
96
|
export {
|
|
94
97
|
deriveReferenceGrade,
|
|
95
98
|
getDisciplineAbbreviation,
|
|
96
|
-
toKebabCase,
|
|
97
99
|
deriveAgentSkills,
|
|
98
100
|
deriveAgentBehaviours,
|
|
99
|
-
|
|
101
|
+
generateSkillMarkdown,
|
|
100
102
|
validateAgentProfile,
|
|
101
103
|
validateAgentSkill,
|
|
102
104
|
deriveHandoffs,
|
|
@@ -111,15 +113,55 @@ export { deriveChecklist, formatChecklistMarkdown } from "./checklist.js";
|
|
|
111
113
|
// Toolkit
|
|
112
114
|
export { deriveToolkit } from "./toolkit.js";
|
|
113
115
|
|
|
114
|
-
// Profile
|
|
116
|
+
// Profile derivation
|
|
115
117
|
export {
|
|
116
118
|
getPositiveTrackCapabilities,
|
|
117
|
-
filterHumanOnlySkills,
|
|
118
|
-
filterByHighestLevel,
|
|
119
|
-
filterSkillsForAgent,
|
|
120
|
-
sortByLevelDescending,
|
|
121
|
-
sortByMaturityDescending,
|
|
122
119
|
prepareBaseProfile,
|
|
123
|
-
AGENT_PROFILE_OPTIONS,
|
|
124
120
|
prepareAgentProfile,
|
|
125
121
|
} from "./profile.js";
|
|
122
|
+
|
|
123
|
+
// Policies - re-export key items for convenience
|
|
124
|
+
export {
|
|
125
|
+
// Thresholds
|
|
126
|
+
THRESHOLD_MATCH_STRONG,
|
|
127
|
+
THRESHOLD_MATCH_GOOD,
|
|
128
|
+
THRESHOLD_MATCH_STRETCH,
|
|
129
|
+
THRESHOLD_MATCH_ASPIRATIONAL,
|
|
130
|
+
SCORE_GAP,
|
|
131
|
+
WEIGHT_SKILL_TYPE,
|
|
132
|
+
WEIGHT_CAPABILITY_BOOST,
|
|
133
|
+
// Predicates
|
|
134
|
+
isHumanOnly,
|
|
135
|
+
isAgentEligible,
|
|
136
|
+
isPrimary,
|
|
137
|
+
isSecondary,
|
|
138
|
+
isBroad,
|
|
139
|
+
isTrack,
|
|
140
|
+
isCore,
|
|
141
|
+
isSupporting,
|
|
142
|
+
hasMinLevel,
|
|
143
|
+
allOf,
|
|
144
|
+
anyOf,
|
|
145
|
+
not,
|
|
146
|
+
// Filters
|
|
147
|
+
filterHighestLevel,
|
|
148
|
+
filterAboveAwareness,
|
|
149
|
+
applyFilters,
|
|
150
|
+
composeFilters,
|
|
151
|
+
// Orderings
|
|
152
|
+
ORDER_SKILL_TYPE,
|
|
153
|
+
ORDER_STAGE,
|
|
154
|
+
ORDER_AGENT_STAGE,
|
|
155
|
+
compareByLevelDesc,
|
|
156
|
+
compareByType,
|
|
157
|
+
compareBySkillPriority,
|
|
158
|
+
compareByMaturityDesc,
|
|
159
|
+
compareByBehaviourPriority,
|
|
160
|
+
// Composed policies
|
|
161
|
+
filterAgentSkills,
|
|
162
|
+
filterToolkitSkills,
|
|
163
|
+
sortAgentSkills,
|
|
164
|
+
sortAgentBehaviours,
|
|
165
|
+
prepareAgentSkillMatrix,
|
|
166
|
+
prepareAgentBehaviourProfile,
|
|
167
|
+
} from "./policies/index.js";
|