This commit is contained in:
geoffsee
2025-07-11 16:18:34 -04:00
parent 8956579eff
commit 8545aa8699
32 changed files with 4448 additions and 0 deletions

11
.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
/target
.idea
Cargo.lock
*.iml
node_modules
bun.lockb
.junie
project
.env

6
Cargo.toml Normal file
View File

@@ -0,0 +1,6 @@
[package]
name = "sumpin"
version = "0.1.0"
edition = "2024"
[dependencies]

240
bun.lock Normal file
View File

@@ -0,0 +1,240 @@
{
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "sumpin",
"dependencies": {
"@openai/agents": "^0.0.11",
"mobx": "^6.13.7",
"mobx-state-tree": "^7.0.2",
"openai": "^5.9.0",
"uuid": "^11.1.0",
"zod": "<=3.25.67",
},
"devDependencies": {
"@types/bun": "latest",
"@types/uuid": "^10.0.0",
},
"peerDependencies": {
"typescript": "^5.0.0",
},
},
},
"packages": {
"@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.15.1", "", { "dependencies": { "ajv": "^6.12.6", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.23.8", "zod-to-json-schema": "^3.24.1" } }, "sha512-W/XlN9c528yYn+9MQkVjxiTPgPxoxt+oczfjHBDsJx0+59+O7B75Zhsp0B16Xbwbz8ANISDajh6+V7nIcPMc5w=="],
"@openai/agents": ["@openai/agents@0.0.11", "", { "dependencies": { "@openai/agents-core": "0.0.11", "@openai/agents-openai": "0.0.11", "@openai/agents-realtime": "0.0.11", "debug": "^4.4.0", "openai": "^5.0.1" } }, "sha512-MYSuQ0PptjryTb/BzrqoZB+cajv/p31uF42uXeqkI3s9PihqRttnQBJ1YCTJS/xQCl4f5R9cIradh/o5PpbDkA=="],
"@openai/agents-core": ["@openai/agents-core@0.0.11", "", { "dependencies": { "@openai/zod": "npm:zod@3.25.40 - 3.25.67", "debug": "^4.4.0", "openai": "^5.0.1" }, "optionalDependencies": { "@modelcontextprotocol/sdk": "^1.12.0" }, "peerDependencies": { "zod": "3.25.40 - 3.25.67" }, "optionalPeers": ["zod"] }, "sha512-kMG/B620fsFAwUe/ounmXty4FuAmWbMWgql4z/gCoER3S6h5tBqNTxffN0MAOFHV3EuPLiqTxA0kGiSdTpDwyA=="],
"@openai/agents-openai": ["@openai/agents-openai@0.0.11", "", { "dependencies": { "@openai/agents-core": "0.0.11", "@openai/zod": "npm:zod@3.25.40 - 3.25.67", "debug": "^4.4.0", "openai": "^5.0.1" } }, "sha512-gqVVDfyD0UYYBkc4kPJgbWzFzayKCKQBHMKHnbMsReZ8/nqHKGEd/hjBiqAZGqDW0BTKNaGfzGB8XAiLWWipnw=="],
"@openai/agents-realtime": ["@openai/agents-realtime@0.0.11", "", { "dependencies": { "@openai/agents-core": "0.0.11", "@openai/zod": "npm:zod@3.25.40 - 3.25.67", "@types/ws": "^8.18.1", "debug": "^4.4.0", "ws": "^8.18.1" } }, "sha512-gVdrKri0dPBOJfsQR6m9rdpBscRZK/efc1zLKqOA2mfmaL0RxI2/LvnyXbwrDGHQ6GEbovULkbWWQ9D4nUafow=="],
"@openai/zod": ["zod@3.25.67", "", {}, "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw=="],
"@types/bun": ["@types/bun@1.2.18", "", { "dependencies": { "bun-types": "1.2.18" } }, "sha512-Xf6RaWVheyemaThV0kUfaAUvCNokFr+bH8Jxp+tTZfx7dAPA8z9ePnP9S9+Vspzuxxx9JRAXhnyccRj3GyCMdQ=="],
"@types/node": ["@types/node@24.0.13", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-Qm9OYVOFHFYg3wJoTSrz80hoec5Lia/dPp84do3X7dZvLikQvM1YpmvTBEdIr/e+U8HTkFjLHLnl78K/qjf+jQ=="],
"@types/react": ["@types/react@19.1.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="],
"@types/uuid": ["@types/uuid@10.0.0", "", {}, "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ=="],
"@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
"accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
"body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="],
"bun-types": ["bun-types@1.2.18", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-04+Eha5NP7Z0A9YgDAzMk5PHR16ZuLVa83b26kH5+cp1qZW4F6FmAURngE7INf4tKOvCE69vYvDEwoNl1tGiWw=="],
"bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
"call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
"content-disposition": ["content-disposition@1.0.0", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg=="],
"content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
"cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
"cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="],
"cors": ["cors@2.8.5", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g=="],
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
"ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
"encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
"escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="],
"etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
"eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="],
"eventsource-parser": ["eventsource-parser@3.0.3", "", {}, "sha512-nVpZkTMM9rF6AQ9gPJpFsNAMt48wIzB5TQgiTLdHiuO8XEDhUgZEhqKlZWXbIzo9VmJ/HvysHqEaVeD5v9TPvA=="],
"express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="],
"express-rate-limit": ["express-rate-limit@7.5.1", "", { "peerDependencies": { "express": ">= 4.11" } }, "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw=="],
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
"finalhandler": ["finalhandler@2.1.0", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q=="],
"forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
"fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="],
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
"ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
"is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="],
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
"media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
"merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="],
"mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
"mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="],
"mobx": ["mobx@6.13.7", "", {}, "sha512-aChaVU/DO5aRPmk1GX8L+whocagUUpBQqoPtJk+cm7UOXUk87J4PeWCh6nNmTTIfEhiR9DI/+FnA8dln/hTK7g=="],
"mobx-state-tree": ["mobx-state-tree@7.0.2", "", { "dependencies": { "ts-essentials": "^9.4.1" }, "peerDependencies": { "mobx": "^6.3.0" } }, "sha512-Qmqgo2Ho1/JRTquo0EWw0ZA/k4wTUNPMIBg98ALGN1V/0Gupic7dg4GDYUhNbiLsYHpp48VgpaCDpDIKV+jNkQ=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
"object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
"on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
"openai": ["openai@5.9.0", "", { "peerDependencies": { "ws": "^8.18.0", "zod": "^3.23.8" }, "optionalPeers": ["ws", "zod"], "bin": { "openai": "bin/cli" } }, "sha512-cmLC0pfqLLhBGxE4aZPyRPjydgYCncppV2ClQkKmW79hNjCvmzkfhz8rN5/YVDmjVQlFV+UsF1JIuNjNgeagyQ=="],
"parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
"path-to-regexp": ["path-to-regexp@8.2.0", "", {}, "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ=="],
"pkce-challenge": ["pkce-challenge@5.0.0", "", {}, "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ=="],
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
"qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="],
"range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
"raw-body": ["raw-body@3.0.0", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.6.3", "unpipe": "1.0.0" } }, "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g=="],
"router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="],
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
"send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="],
"serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="],
"setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
"side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
"side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
"side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
"statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
"ts-essentials": ["ts-essentials@9.4.2", "", { "peerDependencies": { "typescript": ">=4.1.0" }, "optionalPeers": ["typescript"] }, "sha512-mB/cDhOvD7pg3YCLk2rOtejHjjdSi9in/IBYE13S+8WA5FBSraYf4V/ws55uvs0IvQ/l0wBOlXy5yBNZ9Bl8ZQ=="],
"type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
"undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="],
"unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
"uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="],
"vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
"zod": ["zod@3.25.67", "", {}, "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw=="],
"zod-to-json-schema": ["zod-to-json-schema@3.24.6", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg=="],
"http-errors/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
}
}

332
cli.ts Normal file
View File

@@ -0,0 +1,332 @@
#!/usr/bin/env bun
/**
* Sumpin CLI - Professional Hierarchy Generator
*
* A command-line interface for generating professional hierarchies from natural language specifications.
* Leverages the existing hierarchy generation infrastructure to provide a clean, professional CLI experience.
*/
import { parseArgs } from 'util';
import { writeFileSync, mkdirSync, existsSync } from 'fs';
import { join, resolve } from 'path';
import { generateHierarchy } from './generate-template';
import HierarchyAgent from './lib/agent-wrapper';
const CLI_VERSION = '1.0.0';
const DEFAULT_OUTPUT_DIR = './output';
interface CLIOptions {
help?: boolean;
version?: boolean;
output?: string;
format?: 'json' | 'typescript' | 'both';
complexity?: 'simple' | 'medium' | 'complex';
hierarchyVersion?: 'v1' | 'v2';
stream?: boolean;
quiet?: boolean;
skills?: boolean;
tools?: boolean;
examples?: boolean;
}
const HELP_TEXT = `
Sumpin CLI v${CLI_VERSION} - Professional Hierarchy Generator
USAGE:
bun cli.ts [OPTIONS] "<natural language specification>"
DESCRIPTION:
Generate professional hierarchies from natural language descriptions.
Supports both simple JSON output and full TypeScript code generation.
ARGUMENTS:
specification Natural language description of the hierarchy to generate
Example: "Create a healthcare hierarchy for mental health services"
OPTIONS:
-h, --help Show this help message
-v, --version Show version information
-o, --output DIR Output directory (default: ./output)
-f, --format FORMAT Output format: json, typescript, both (default: json)
-c, --complexity LEVEL Complexity level: simple, medium, complex (default: medium)
--hierarchy-version VER Hierarchy version: v1, v2 (default: v2)
--stream Enable streaming output for real-time feedback
--quiet Suppress progress messages
--skills Include skills and competencies (default: true)
--tools Include tools and technologies (default: true)
--examples Include practical examples (default: true)
EXAMPLES:
# Basic usage - generate JSON hierarchy
bun cli.ts "Create a technology hierarchy for AI development"
# Generate TypeScript code with streaming
bun cli.ts --format typescript --stream "Healthcare hierarchy for emergency medicine"
# Complex v1 hierarchy with custom output directory
bun cli.ts -o ./my-hierarchies -c complex --hierarchy-version v1 "Finance hierarchy for investment banking"
# Generate both formats quietly
bun cli.ts --format both --quiet "Education hierarchy for online learning platforms"
OUTPUT:
Generated files will be saved to the specified output directory with descriptive names.
JSON format: Creates .json files with the hierarchy data
TypeScript format: Creates .ts files with executable TypeScript code
`;
// Parse command line arguments
function parseCliArgs(): { options: CLIOptions; specification: string } {
const { values, positionals } = parseArgs({
args: process.argv.slice(2),
options: {
help: { type: 'boolean', short: 'h' },
version: { type: 'boolean', short: 'v' },
output: { type: 'string', short: 'o' },
format: { type: 'string', short: 'f' },
complexity: { type: 'string', short: 'c' },
'hierarchy-version': { type: 'string' },
stream: { type: 'boolean' },
quiet: { type: 'boolean' },
skills: { type: 'boolean' },
tools: { type: 'boolean' },
examples: { type: 'boolean' },
},
allowPositionals: true,
});
const options: CLIOptions = {
help: values.help,
version: values.version,
output: values.output || DEFAULT_OUTPUT_DIR,
format: (values.format as any) || 'json',
complexity: (values.complexity as any) || 'medium',
hierarchyVersion: (values['hierarchy-version'] as any) || 'v2',
stream: values.stream || false,
quiet: values.quiet || false,
skills: values.skills !== false,
tools: values.tools !== false,
examples: values.examples !== false,
};
const specification = positionals.join(' ');
return { options, specification };
}
// Validate CLI options
function validateOptions(options: CLIOptions, specification: string): void {
if (!['json', 'typescript', 'both'].includes(options.format!)) {
console.error('❌ Error: Invalid format. Must be one of: json, typescript, both');
process.exit(1);
}
if (!['simple', 'medium', 'complex'].includes(options.complexity!)) {
console.error('❌ Error: Invalid complexity. Must be one of: simple, medium, complex');
process.exit(1);
}
if (!['v1', 'v2'].includes(options.hierarchyVersion!)) {
console.error('❌ Error: Invalid hierarchy version. Must be one of: v1, v2');
process.exit(1);
}
if (!specification.trim()) {
console.error('❌ Error: Natural language specification is required');
console.error('Use --help for usage information');
process.exit(1);
}
}
// Generate filename from specification
function generateFilename(specification: string, format: string): string {
const cleanSpec = specification
.toLowerCase()
.replace(/[^a-z0-9\s]/g, '')
.replace(/\s+/g, '-')
.substring(0, 50);
const timestamp = new Date().toISOString().slice(0, 19).replace(/[:-]/g, '');
return `hierarchy-${cleanSpec}-${timestamp}`;
}
// Generate hierarchy using the simple JSON approach
async function generateJsonHierarchy(specification: string, options: CLIOptions): Promise<any> {
if (!options.quiet) {
console.log('🔄 Generating hierarchy using JSON approach...');
}
const hierarchy = await generateHierarchy(specification);
return hierarchy.toJSON();
}
// Generate hierarchy using the agent-based TypeScript approach
async function generateTypescriptHierarchy(specification: string, options: CLIOptions): Promise<string> {
if (!options.quiet) {
console.log('🔄 Generating hierarchy using TypeScript agent approach...');
}
const hierarchyAgent = new HierarchyAgent({
name: 'CLI Hierarchy Generator',
instructions: `Generate professional hierarchy TypeScript code based on user specifications.
Focus on creating clean, implementable code that demonstrates real-world organizational structures.`,
});
const generationOptions = {
domain: extractDomain(specification),
version: options.hierarchyVersion!,
complexity: options.complexity!,
includeSkills: options.skills!,
includeTools: options.tools!,
includeExamples: options.examples!,
};
if (options.stream) {
return await hierarchyAgent.generateHierarchyWithStreaming(
generationOptions,
options.quiet ? undefined : (event) => {
if (event.type === 'raw_model_stream_event' && event.delta?.content) {
process.stdout.write('.');
}
}
).then(result => result.content);
} else {
const result = await hierarchyAgent.generateHierarchy(generationOptions);
return result.content;
}
}
// Extract domain from specification (simple heuristic)
function extractDomain(specification: string): string {
const words = specification.toLowerCase().split(/\s+/);
// Look for domain keywords
const domainKeywords = [
'healthcare', 'technology', 'finance', 'education', 'manufacturing',
'retail', 'consulting', 'media', 'logistics', 'legal', 'construction',
'hospitality', 'automotive', 'aerospace', 'energy', 'agriculture'
];
for (const keyword of domainKeywords) {
if (words.some(word => word.includes(keyword))) {
return keyword;
}
}
// Fallback: use first meaningful word
const meaningfulWords = words.filter(word =>
word.length > 3 &&
!['create', 'generate', 'build', 'make', 'hierarchy', 'for', 'the', 'and', 'with'].includes(word)
);
return meaningfulWords[0] || 'general';
}
// Save output to files
async function saveOutput(
content: any,
filename: string,
format: string,
outputDir: string,
quiet: boolean
): Promise<void> {
// Ensure output directory exists
if (!existsSync(outputDir)) {
mkdirSync(outputDir, { recursive: true });
}
const outputPath = resolve(outputDir);
if (format === 'json' || format === 'both') {
const jsonFile = join(outputPath, `${filename}.json`);
const jsonContent = typeof content === 'string' ? content : JSON.stringify(content, null, 2);
writeFileSync(jsonFile, jsonContent);
if (!quiet) {
console.log(`✅ JSON hierarchy saved: ${jsonFile}`);
}
}
if (format === 'typescript' || format === 'both') {
const tsFile = join(outputPath, `${filename}.ts`);
const tsContent = typeof content === 'string' ? content : `// Generated hierarchy\nexport const hierarchy = ${JSON.stringify(content, null, 2)};`;
writeFileSync(tsFile, tsContent);
if (!quiet) {
console.log(`✅ TypeScript hierarchy saved: ${tsFile}`);
}
}
}
// Main CLI function
async function main(): Promise<void> {
try {
const { options, specification } = parseCliArgs();
// Handle help and version
if (options.help) {
console.log(HELP_TEXT);
process.exit(0);
}
if (options.version) {
console.log(`Sumpin CLI v${CLI_VERSION}`);
process.exit(0);
}
// Validate options
validateOptions(options, specification);
if (!options.quiet) {
console.log(`🚀 Sumpin CLI v${CLI_VERSION} - Professional Hierarchy Generator`);
console.log(`📝 Specification: "${specification}"`);
console.log(`⚙️ Configuration:`);
console.log(` Format: ${options.format}`);
console.log(` Complexity: ${options.complexity}`);
console.log(` Version: ${options.hierarchyVersion}`);
console.log(` Output: ${options.output}`);
console.log();
}
const filename = generateFilename(specification, options.format!);
let content: any;
// Generate based on format preference
if (options.format === 'json') {
content = await generateJsonHierarchy(specification, options);
} else if (options.format === 'typescript') {
content = await generateTypescriptHierarchy(specification, options);
} else if (options.format === 'both') {
// Generate both formats
const jsonContent = await generateJsonHierarchy(specification, options);
const tsContent = await generateTypescriptHierarchy(specification, options);
await saveOutput(jsonContent, filename, 'json', options.output!, options.quiet!);
await saveOutput(tsContent, filename, 'typescript', options.output!, options.quiet!);
if (!options.quiet) {
console.log('\n🎉 Hierarchy generation complete!');
console.log(`📁 Files saved to: ${resolve(options.output!)}`);
}
return;
}
// Save single format output
await saveOutput(content, filename, options.format!, options.output!, options.quiet!);
if (!options.quiet) {
console.log('\n🎉 Hierarchy generation complete!');
console.log(`📁 Files saved to: ${resolve(options.output!)}`);
}
} catch (error) {
console.error('❌ Error:', error instanceof Error ? error.message : String(error));
process.exit(1);
}
}
// Run CLI if this file is executed directly
if (import.meta.main) {
main();
}
export { main as runCLI };

65
examples/README.md Normal file
View File

@@ -0,0 +1,65 @@
# Examples Directory
This directory contains comprehensive examples demonstrating how to use both versions of the professional hierarchy models.
## Structure
- `v1/` - Examples for the simpler 4-layer hierarchy model (Domain → Specialization → Role → Responsibility)
- `v2/` - Examples for the advanced 6-layer hierarchy model (Domain → Industry → Profession → Field → Role → Task)
## Prerequisites
Make sure you have the required dependencies installed:
```bash
bun install
```
For v1 and v2 examples, you'll also need:
```bash
bun add mobx-state-tree mobx uuid
bun add -d @types/uuid
```
## Running Examples
Each example can be run independently using Bun:
```bash
# Run v1 examples
bun run examples/v1/healthcare-example.ts
bun run examples/v1/technology-example.ts
# Run v2 examples
bun run examples/v2/software-company-example.ts
bun run examples/v2/healthcare-system-example.ts
```
## Testing Examples
You can also run the test files to see the examples in action:
```bash
# Test v1 examples
bun test examples/v1/
# Test v2 examples
bun test examples/v2/
```
## Example Scenarios
### V1 Examples (4-layer hierarchy)
- **Healthcare Example**: Models medical professionals with specializations, roles, and responsibilities
- **Technology Example**: Models software engineering domain with various specializations
### V2 Examples (6-layer hierarchy)
- **Software Company Example**: Complete modeling of a tech company's professional structure
- **Healthcare System Example**: Comprehensive healthcare organization modeling
Each example demonstrates:
- Creating and structuring hierarchies
- Adding attributes/skills/tools
- CRUD operations
- Querying and traversing the hierarchy
- Real-world use cases and best practices

View File

@@ -0,0 +1,349 @@
import { ProfessionModel, Domain, Specialization, Role, Responsibility, Attribute } from "../../lib/v1";
console.log("=== Healthcare Professional Hierarchy Example (V1) ===\n");
const professionModel = ProfessionModel.create({
domains: []
});
// Create the Healthcare domain
const healthcareDomain = Domain.create({
name: "Healthcare",
description: "Medical and health services domain",
specializations: [],
coreAttributes: [
{
name: "Medical Ethics",
type: "Trait",
description: "Understanding of medical ethics and patient care principles"
},
{
name: "Communication",
type: "Skill",
description: "Effective communication with patients and colleagues"
},
{
name: "Electronic Health Records",
type: "Tool",
description: "Proficiency with EHR systems"
}
]
});
// Add specializations to Healthcare domain
const cardiology = Specialization.create({
name: "Cardiology",
focus: "Heart and cardiovascular system disorders",
coreAttributes: [
{
name: "Cardiac Catheterization",
type: "Skill",
description: "Performing cardiac catheterization procedures"
},
{
name: "ECG Interpretation",
type: "Skill",
description: "Reading and interpreting electrocardiograms"
},
{
name: "Echocardiogram Machine",
type: "Tool",
description: "Operating echocardiogram equipment"
}
],
roles: []
});
const pediatrics = Specialization.create({
name: "Pediatrics",
focus: "Medical care of infants, children, and adolescents",
coreAttributes: [
{
name: "Child Psychology",
type: "Skill",
description: "Understanding child development and psychology"
},
{
name: "Vaccination Protocols",
type: "Skill",
description: "Knowledge of pediatric vaccination schedules"
},
{
name: "Pediatric Stethoscope",
type: "Tool",
description: "Specialized stethoscope for children"
}
],
roles: []
});
// Create roles for Cardiology
const cardiologist = Role.create({
title: "Cardiologist",
seniority: "Senior",
responsibilities: [],
requiredAttributes: [
{
name: "Board Certification",
type: "Trait",
description: "Board certified in cardiology"
},
{
name: "Surgical Skills",
type: "Skill",
description: "Advanced surgical techniques for cardiac procedures"
}
]
});
const cardiacNurse = Role.create({
title: "Cardiac Nurse",
seniority: "Mid",
responsibilities: [],
requiredAttributes: [
{
name: "Critical Care Experience",
type: "Trait",
description: "Experience in critical care environments"
},
{
name: "Medication Administration",
type: "Skill",
description: "Safe administration of cardiac medications"
}
]
});
// Create responsibilities for Cardiologist
const diagnosisResponsibility = Responsibility.create({
title: "Cardiac Diagnosis",
outcome: "Accurate diagnosis of cardiovascular conditions",
requiredAttributes: [
{
name: "Diagnostic Imaging",
type: "Skill",
description: "Interpreting cardiac imaging studies"
},
{
name: "Clinical Assessment",
type: "Skill",
description: "Comprehensive cardiovascular examination"
}
]
});
const treatmentPlanningResponsibility = Responsibility.create({
title: "Treatment Planning",
outcome: "Comprehensive treatment plans for cardiac patients",
requiredAttributes: [
{
name: "Evidence-Based Medicine",
type: "Skill",
description: "Applying current research to treatment decisions"
},
{
name: "Risk Assessment",
type: "Skill",
description: "Evaluating patient risk factors"
}
]
});
// Create responsibilities for Cardiac Nurse
const patientMonitoringResponsibility = Responsibility.create({
title: "Patient Monitoring",
outcome: "Continuous monitoring of cardiac patients' vital signs and condition",
requiredAttributes: [
{
name: "Telemetry Monitoring",
type: "Skill",
description: "Monitoring cardiac rhythms via telemetry"
},
{
name: "Cardiac Monitor",
type: "Tool",
description: "Operating cardiac monitoring equipment"
}
]
});
// Create roles for Pediatrics
const pediatrician = Role.create({
title: "Pediatrician",
seniority: "Senior",
responsibilities: [],
requiredAttributes: [
{
name: "Pediatric Board Certification",
type: "Trait",
description: "Board certified in pediatrics"
},
{
name: "Developmental Assessment",
type: "Skill",
description: "Assessing child development milestones"
}
]
});
const pediatricNurse = Role.create({
title: "Pediatric Nurse",
seniority: "Mid",
responsibilities: [],
requiredAttributes: [
{
name: "Pediatric Nursing Certification",
type: "Trait",
description: "Certified in pediatric nursing"
},
{
name: "Family Communication",
type: "Skill",
description: "Communicating effectively with children and families"
}
]
});
// Create responsibilities for Pediatrician
const wellChildExamResponsibility = Responsibility.create({
title: "Well-Child Examinations",
outcome: "Regular health assessments and preventive care for children",
requiredAttributes: [
{
name: "Growth Assessment",
type: "Skill",
description: "Evaluating child growth patterns"
},
{
name: "Immunization Knowledge",
type: "Skill",
description: "Current knowledge of vaccination schedules"
}
]
});
const developmentalScreeningResponsibility = Responsibility.create({
title: "Developmental Screening",
outcome: "Early identification of developmental delays or disorders",
requiredAttributes: [
{
name: "Screening Tools",
type: "Tool",
description: "Standardized developmental screening instruments"
},
{
name: "Behavioral Assessment",
type: "Skill",
description: "Assessing child behavior and development"
}
]
});
// Assemble the hierarchy
cardiologist.responsibilities.push(diagnosisResponsibility, treatmentPlanningResponsibility);
cardiacNurse.responsibilities.push(patientMonitoringResponsibility);
pediatrician.responsibilities.push(wellChildExamResponsibility, developmentalScreeningResponsibility);
cardiology.roles.push(cardiologist, cardiacNurse);
pediatrics.roles.push(pediatrician, pediatricNurse);
healthcareDomain.specializations.push(cardiology, pediatrics);
professionModel.domains.push(healthcareDomain);
// Demonstrate the hierarchy
console.log("🏥 Healthcare Domain Structure:");
console.log(`Domain: ${healthcareDomain.name}`);
console.log(`Description: ${healthcareDomain.description}`);
console.log(`Core Attributes: ${healthcareDomain.coreAttributes.length}`);
healthcareDomain.coreAttributes.forEach(attr => {
console.log(` - ${attr.name} (${attr.type}): ${attr.description}`);
});
console.log(`\nSpecializations: ${healthcareDomain.specializations.length}`);
healthcareDomain.specializations.forEach(spec => {
console.log(`\n📋 ${spec.name}`);
console.log(` Focus: ${spec.focus}`);
console.log(` Core Attributes: ${spec.coreAttributes.length}`);
spec.coreAttributes.forEach(attr => {
console.log(` - ${attr.name} (${attr.type}): ${attr.description}`);
});
console.log(` Roles: ${spec.roles.length}`);
spec.roles.forEach(role => {
console.log(`\n 👨‍⚕️ ${role.title} (${role.seniority} Level)`);
console.log(` Required Attributes: ${role.requiredAttributes.length}`);
role.requiredAttributes.forEach(attr => {
console.log(` - ${attr.name} (${attr.type}): ${attr.description}`);
});
console.log(` Responsibilities: ${role.responsibilities.length}`);
role.responsibilities.forEach(resp => {
console.log(`\n 📝 ${resp.title}`);
console.log(` Outcome: ${resp.outcome}`);
console.log(` Required Attributes: ${resp.requiredAttributes.length}`);
resp.requiredAttributes.forEach(attr => {
console.log(` - ${attr.name} (${attr.type}): ${attr.description}`);
});
});
});
});
// Demonstrate querying capabilities
console.log("\n" + "=".repeat(60));
console.log("🔍 QUERYING EXAMPLES");
console.log("=".repeat(60));
// Find all skills across the domain
const allSkills = healthcareDomain.specializations
.flatMap(spec => [
...spec.coreAttributes.filter(attr => attr.type === "Skill"),
...spec.roles.flatMap(role => [
...role.requiredAttributes.filter(attr => attr.type === "Skill"),
...role.responsibilities.flatMap(resp =>
resp.requiredAttributes.filter(attr => attr.type === "Skill")
)
])
]);
console.log(`\n💪 All Skills in Healthcare Domain (${allSkills.length}):`);
allSkills.forEach(skill => {
console.log(` - ${skill.name}: ${skill.description}`);
});
// Find all tools
const allTools = healthcareDomain.specializations
.flatMap(spec => [
...spec.coreAttributes.filter(attr => attr.type === "Tool"),
...spec.roles.flatMap(role => [
...role.requiredAttributes.filter(attr => attr.type === "Tool"),
...role.responsibilities.flatMap(resp =>
resp.requiredAttributes.filter(attr => attr.type === "Tool")
)
])
]);
console.log(`\n🛠 All Tools in Healthcare Domain (${allTools.length}):`);
allTools.forEach(tool => {
console.log(` - ${tool.name}: ${tool.description}`);
});
// Find all senior-level roles
const seniorRoles = healthcareDomain.specializations
.flatMap(spec => spec.roles)
.filter(role => role.seniority === "Senior");
console.log(`\n🎖 Senior-Level Roles (${seniorRoles.length}):`);
seniorRoles.forEach(role => {
console.log(` - ${role.title}`);
});
console.log("\n" + "=".repeat(60));
console.log("✅ Healthcare example completed successfully!");
console.log("=".repeat(60));

View File

@@ -0,0 +1,531 @@
import { ProfessionModel, Domain, Specialization, Role, Responsibility, Attribute } from "../../lib/v1";
console.log("=== Technology Professional Hierarchy Example (V1) ===\n");
const professionModel = ProfessionModel.create({
domains: []
});
// Create the Technology domain
const technologyDomain = Domain.create({
name: "Technology",
description: "Software development and technology services domain",
specializations: [],
coreAttributes: [
{
name: "Problem Solving",
type: "Skill",
description: "Analytical thinking and systematic problem-solving approach"
},
{
name: "Version Control",
type: "Tool",
description: "Proficiency with Git and version control systems"
},
{
name: "Continuous Learning",
type: "Trait",
description: "Commitment to staying current with technology trends"
},
{
name: "Agile Methodology",
type: "Skill",
description: "Understanding of Agile/Scrum development processes"
}
]
});
// Create Web Development specialization
const webDevelopment = Specialization.create({
name: "Web Development",
focus: "Building web applications and websites",
coreAttributes: [
{
name: "HTML/CSS",
type: "Skill",
description: "Markup and styling for web interfaces"
},
{
name: "JavaScript",
type: "Skill",
description: "Client-side and server-side JavaScript programming"
},
{
name: "Web Browser DevTools",
type: "Tool",
description: "Browser developer tools for debugging and optimization"
},
{
name: "Responsive Design",
type: "Skill",
description: "Creating mobile-friendly and adaptive layouts"
}
],
roles: []
});
// Create Data Science specialization
const dataScience = Specialization.create({
name: "Data Science",
focus: "Extracting insights from data using statistical and machine learning methods",
coreAttributes: [
{
name: "Statistical Analysis",
type: "Skill",
description: "Statistical methods and hypothesis testing"
},
{
name: "Python/R",
type: "Skill",
description: "Programming languages for data analysis"
},
{
name: "Jupyter Notebooks",
type: "Tool",
description: "Interactive development environment for data science"
},
{
name: "Data Visualization",
type: "Skill",
description: "Creating meaningful visual representations of data"
}
],
roles: []
});
// Create Mobile Development specialization
const mobileDevelopment = Specialization.create({
name: "Mobile Development",
focus: "Building native and cross-platform mobile applications",
coreAttributes: [
{
name: "Mobile UI/UX",
type: "Skill",
description: "Designing user interfaces for mobile devices"
},
{
name: "App Store Guidelines",
type: "Skill",
description: "Understanding platform-specific app store requirements"
},
{
name: "Mobile Testing Frameworks",
type: "Tool",
description: "Tools for testing mobile applications"
}
],
roles: []
});
// Create roles for Web Development
const frontendDeveloper = Role.create({
title: "Frontend Developer",
seniority: "Mid",
responsibilities: [],
requiredAttributes: [
{
name: "React/Vue/Angular",
type: "Skill",
description: "Modern frontend frameworks"
},
{
name: "Cross-browser Compatibility",
type: "Skill",
description: "Ensuring consistent behavior across different browsers"
},
{
name: "Performance Optimization",
type: "Skill",
description: "Optimizing web application performance"
}
]
});
const fullStackDeveloper = Role.create({
title: "Full Stack Developer",
seniority: "Senior",
responsibilities: [],
requiredAttributes: [
{
name: "Backend Development",
type: "Skill",
description: "Server-side programming and API development"
},
{
name: "Database Design",
type: "Skill",
description: "Designing and optimizing database schemas"
},
{
name: "Cloud Platforms",
type: "Tool",
description: "AWS, Azure, or Google Cloud Platform"
}
]
});
// Create roles for Data Science
const dataAnalyst = Role.create({
title: "Data Analyst",
seniority: "Junior",
responsibilities: [],
requiredAttributes: [
{
name: "SQL",
type: "Skill",
description: "Database querying and data manipulation"
},
{
name: "Excel/Spreadsheets",
type: "Tool",
description: "Advanced spreadsheet analysis"
},
{
name: "Business Intelligence Tools",
type: "Tool",
description: "Tableau, Power BI, or similar BI tools"
}
]
});
const machineLearningEngineer = Role.create({
title: "Machine Learning Engineer",
seniority: "Senior",
responsibilities: [],
requiredAttributes: [
{
name: "Machine Learning Algorithms",
type: "Skill",
description: "Understanding of ML algorithms and their applications"
},
{
name: "Model Deployment",
type: "Skill",
description: "Deploying ML models to production environments"
},
{
name: "TensorFlow/PyTorch",
type: "Tool",
description: "Deep learning frameworks"
}
]
});
// Create roles for Mobile Development
const iosDeveloper = Role.create({
title: "iOS Developer",
seniority: "Mid",
responsibilities: [],
requiredAttributes: [
{
name: "Swift/Objective-C",
type: "Skill",
description: "iOS native programming languages"
},
{
name: "Xcode",
type: "Tool",
description: "Apple's integrated development environment"
},
{
name: "iOS SDK",
type: "Skill",
description: "iOS Software Development Kit and frameworks"
}
]
});
// Create responsibilities for Frontend Developer
const uiImplementationResponsibility = Responsibility.create({
title: "User Interface Implementation",
outcome: "Pixel-perfect, responsive user interfaces that match design specifications",
requiredAttributes: [
{
name: "CSS Frameworks",
type: "Tool",
description: "Bootstrap, Tailwind CSS, or similar frameworks"
},
{
name: "Design Systems",
type: "Skill",
description: "Implementing and maintaining design system components"
}
]
});
const frontendTestingResponsibility = Responsibility.create({
title: "Frontend Testing",
outcome: "Comprehensive test coverage for user interface components",
requiredAttributes: [
{
name: "Jest/Cypress",
type: "Tool",
description: "Frontend testing frameworks"
},
{
name: "Test-Driven Development",
type: "Skill",
description: "Writing tests before implementation"
}
]
});
// Create responsibilities for Full Stack Developer
const apiDevelopmentResponsibility = Responsibility.create({
title: "API Development",
outcome: "Robust, scalable APIs that serve frontend applications",
requiredAttributes: [
{
name: "RESTful Services",
type: "Skill",
description: "Designing and implementing REST APIs"
},
{
name: "API Documentation",
type: "Skill",
description: "Creating comprehensive API documentation"
},
{
name: "Postman/Insomnia",
type: "Tool",
description: "API testing and documentation tools"
}
]
});
const systemArchitectureResponsibility = Responsibility.create({
title: "System Architecture",
outcome: "Scalable, maintainable system architecture decisions",
requiredAttributes: [
{
name: "Microservices",
type: "Skill",
description: "Designing microservice architectures"
},
{
name: "Load Balancing",
type: "Skill",
description: "Implementing load balancing strategies"
},
{
name: "Docker/Kubernetes",
type: "Tool",
description: "Containerization and orchestration tools"
}
]
});
// Create responsibilities for Data Analyst
const dataExplorationResponsibility = Responsibility.create({
title: "Data Exploration",
outcome: "Comprehensive understanding of data patterns and anomalies",
requiredAttributes: [
{
name: "Exploratory Data Analysis",
type: "Skill",
description: "Systematic approach to exploring datasets"
},
{
name: "Data Cleaning",
type: "Skill",
description: "Identifying and correcting data quality issues"
}
]
});
// Create responsibilities for Machine Learning Engineer
const modelDevelopmentResponsibility = Responsibility.create({
title: "Model Development",
outcome: "Accurate, efficient machine learning models for production use",
requiredAttributes: [
{
name: "Feature Engineering",
type: "Skill",
description: "Creating and selecting relevant features for ML models"
},
{
name: "Model Validation",
type: "Skill",
description: "Cross-validation and performance evaluation techniques"
},
{
name: "MLflow/Kubeflow",
type: "Tool",
description: "ML pipeline and experiment tracking tools"
}
]
});
// Create responsibilities for iOS Developer
const iosAppDevelopmentResponsibility = Responsibility.create({
title: "iOS App Development",
outcome: "High-quality iOS applications that meet App Store standards",
requiredAttributes: [
{
name: "UIKit/SwiftUI",
type: "Skill",
description: "iOS user interface frameworks"
},
{
name: "Core Data",
type: "Skill",
description: "iOS data persistence framework"
},
{
name: "App Store Connect",
type: "Tool",
description: "Apple's app distribution platform"
}
]
});
// Assemble the hierarchy
frontendDeveloper.responsibilities.push(uiImplementationResponsibility, frontendTestingResponsibility);
fullStackDeveloper.responsibilities.push(apiDevelopmentResponsibility, systemArchitectureResponsibility);
dataAnalyst.responsibilities.push(dataExplorationResponsibility);
machineLearningEngineer.responsibilities.push(modelDevelopmentResponsibility);
iosDeveloper.responsibilities.push(iosAppDevelopmentResponsibility);
webDevelopment.roles.push(frontendDeveloper, fullStackDeveloper);
dataScience.roles.push(dataAnalyst, machineLearningEngineer);
mobileDevelopment.roles.push(iosDeveloper);
technologyDomain.specializations.push(webDevelopment, dataScience, mobileDevelopment);
professionModel.domains.push(technologyDomain);
// Demonstrate the hierarchy
console.log("💻 Technology Domain Structure:");
console.log(`Domain: ${technologyDomain.name}`);
console.log(`Description: ${technologyDomain.description}`);
console.log(`Core Attributes: ${technologyDomain.coreAttributes.length}`);
technologyDomain.coreAttributes.forEach(attr => {
console.log(` - ${attr.name} (${attr.type}): ${attr.description}`);
});
console.log(`\nSpecializations: ${technologyDomain.specializations.length}`);
technologyDomain.specializations.forEach(spec => {
console.log(`\n🔧 ${spec.name}`);
console.log(` Focus: ${spec.focus}`);
console.log(` Core Attributes: ${spec.coreAttributes.length}`);
spec.coreAttributes.forEach(attr => {
console.log(` - ${attr.name} (${attr.type}): ${attr.description}`);
});
console.log(` Roles: ${spec.roles.length}`);
spec.roles.forEach(role => {
console.log(`\n 👨‍💻 ${role.title} (${role.seniority} Level)`);
console.log(` Required Attributes: ${role.requiredAttributes.length}`);
role.requiredAttributes.forEach(attr => {
console.log(` - ${attr.name} (${attr.type}): ${attr.description}`);
});
console.log(` Responsibilities: ${role.responsibilities.length}`);
role.responsibilities.forEach(resp => {
console.log(`\n 📋 ${resp.title}`);
console.log(` Outcome: ${resp.outcome}`);
console.log(` Required Attributes: ${resp.requiredAttributes.length}`);
resp.requiredAttributes.forEach(attr => {
console.log(` - ${attr.name} (${attr.type}): ${attr.description}`);
});
});
});
});
// Demonstrate advanced querying capabilities
console.log("\n" + "=".repeat(60));
console.log("🔍 ADVANCED QUERYING EXAMPLES");
console.log("=".repeat(60));
// Find all programming languages/frameworks (skills containing common tech terms)
const programmingSkills = technologyDomain.specializations
.flatMap(spec => [
...spec.coreAttributes.filter(attr => attr.type === "Skill"),
...spec.roles.flatMap(role => [
...role.requiredAttributes.filter(attr => attr.type === "Skill"),
...role.responsibilities.flatMap(resp =>
resp.requiredAttributes.filter(attr => attr.type === "Skill")
)
])
])
.filter(skill =>
skill.name.includes("/") ||
skill.name.includes("JavaScript") ||
skill.name.includes("Python") ||
skill.name.includes("Swift") ||
skill.name.includes("SQL")
);
console.log(`\n🚀 Programming Languages & Frameworks (${programmingSkills.length}):`);
programmingSkills.forEach(skill => {
console.log(` - ${skill.name}: ${skill.description}`);
});
// Find all development tools
const developmentTools = technologyDomain.specializations
.flatMap(spec => [
...spec.coreAttributes.filter(attr => attr.type === "Tool"),
...spec.roles.flatMap(role => [
...role.requiredAttributes.filter(attr => attr.type === "Tool"),
...role.responsibilities.flatMap(resp =>
resp.requiredAttributes.filter(attr => attr.type === "Tool")
)
])
]);
console.log(`\n🛠 Development Tools (${developmentTools.length}):`);
developmentTools.forEach(tool => {
console.log(` - ${tool.name}: ${tool.description}`);
});
// Find roles by seniority level
const seniorityLevels = ["Junior", "Mid", "Senior"];
seniorityLevels.forEach(level => {
const rolesAtLevel = technologyDomain.specializations
.flatMap(spec => spec.roles)
.filter(role => role.seniority === level);
if (rolesAtLevel.length > 0) {
console.log(`\n🎯 ${level} Level Roles (${rolesAtLevel.length}):`);
rolesAtLevel.forEach(role => {
console.log(` - ${role.title}`);
});
}
});
// Find specializations with the most roles
const specializationsByRoleCount = technologyDomain.specializations
.map(spec => ({ name: spec.name, roleCount: spec.roles.length }))
.sort((a, b) => b.roleCount - a.roleCount);
console.log(`\n📊 Specializations by Role Count:`);
specializationsByRoleCount.forEach(spec => {
console.log(` - ${spec.name}: ${spec.roleCount} roles`);
});
// Calculate total responsibilities across the domain
const totalResponsibilities = technologyDomain.specializations
.flatMap(spec => spec.roles)
.reduce((total, role) => total + role.responsibilities.length, 0);
console.log(`\n📈 Domain Statistics:`);
console.log(` - Total Specializations: ${technologyDomain.specializations.length}`);
console.log(` - Total Roles: ${technologyDomain.specializations.flatMap(spec => spec.roles).length}`);
console.log(` - Total Responsibilities: ${totalResponsibilities}`);
console.log(` - Total Attributes: ${technologyDomain.coreAttributes.length +
technologyDomain.specializations.reduce((total, spec) =>
total + spec.coreAttributes.length +
spec.roles.reduce((roleTotal, role) =>
roleTotal + role.requiredAttributes.length +
role.responsibilities.reduce((respTotal, resp) =>
respTotal + resp.requiredAttributes.length, 0), 0), 0)}`);
console.log("\n" + "=".repeat(60));
console.log("✅ Technology example completed successfully!");
console.log("=".repeat(60));

View File

@@ -0,0 +1,521 @@
import {
Enterprise,
DomainModel,
IndustryModel,
ProfessionModel,
FieldModel,
RoleModel,
TaskModel
} from "../../lib/v2";
console.log("=== Software Company Professional Hierarchy Example (V2) ===\n");
const enterprise = Enterprise.create({});
enterprise.addDomain({
name: "STEM",
description: "Science, Technology, Engineering, and Mathematics domain"
});
const stemDomain = enterprise.domains[0];
stemDomain.addIndustry({
name: "Software",
description: "Software development and technology services industry"
});
const softwareIndustry = stemDomain.industries[0];
softwareIndustry.addProfession({
name: "Software Engineering",
description: "Design, development, and maintenance of software systems"
});
const softwareEngineering = softwareIndustry.professions[0];
const fieldData = [
{
name: "Backend Development",
description: "Server-side application development, APIs, and database management"
},
{
name: "Frontend Development",
description: "User interface and user experience development"
},
{
name: "DevOps Engineering",
description: "Development operations, CI/CD, and infrastructure management"
},
{
name: "Mobile Development",
description: "Native and cross-platform mobile application development"
},
{
name: "Data Engineering",
description: "Data pipeline development and big data processing"
}
];
fieldData.forEach(field => {
softwareEngineering.addField(field);
});
const [backendField, frontendField, devopsField, mobileField, dataField] = softwareEngineering.fields;
const backendRoles = [
{
title: "Senior Backend Engineer",
summary: "Lead backend development initiatives and mentor junior developers"
},
{
title: "API Developer",
summary: "Design and implement RESTful and GraphQL APIs"
},
{
title: "Database Engineer",
summary: "Design, optimize, and maintain database systems"
}
];
backendRoles.forEach(role => {
backendField.addRole(role);
});
const frontendRoles = [
{
title: "React Developer",
summary: "Build modern web applications using React ecosystem"
},
{
title: "UI/UX Engineer",
summary: "Bridge design and development with focus on user experience"
}
];
frontendRoles.forEach(role => {
frontendField.addRole(role);
});
devopsField.addRole({
title: "DevOps Engineer",
summary: "Manage CI/CD pipelines and cloud infrastructure"
});
devopsField.addRole({
title: "Site Reliability Engineer",
summary: "Ensure system reliability, monitoring, and incident response"
});
mobileField.addRole({
title: "iOS Developer",
summary: "Develop native iOS applications using Swift and iOS SDK"
});
mobileField.addRole({
title: "React Native Developer",
summary: "Build cross-platform mobile apps using React Native"
});
dataField.addRole({
title: "Data Pipeline Engineer",
summary: "Build and maintain data processing pipelines"
});
const seniorBackendEngineer = backendField.roles[0];
const apiDeveloper = backendField.roles[1];
const databaseEngineer = backendField.roles[2];
const seniorBackendTasks = [
{
name: "Design system architecture",
description: "Create scalable and maintainable system architecture designs"
},
{
name: "Code review and mentoring",
description: "Review code submissions and mentor junior team members"
},
{
name: "Performance optimization",
description: "Identify and resolve performance bottlenecks in backend systems"
},
{
name: "Technical documentation",
description: "Create and maintain comprehensive technical documentation"
}
];
seniorBackendTasks.forEach(task => {
seniorBackendEngineer.addTask(task);
});
const apiDeveloperTasks = [
{
name: "Design REST endpoints",
description: "Create RESTful API endpoints following best practices"
},
{
name: "Implement GraphQL resolvers",
description: "Build GraphQL schema and resolver functions"
},
{
name: "API documentation",
description: "Document API endpoints using OpenAPI/Swagger specifications"
},
{
name: "API testing",
description: "Write comprehensive tests for API endpoints"
}
];
apiDeveloperTasks.forEach(task => {
apiDeveloper.addTask(task);
});
const databaseEngineerTasks = [
{
name: "Database schema design",
description: "Design efficient and normalized database schemas"
},
{
name: "Query optimization",
description: "Optimize database queries for better performance"
},
{
name: "Database migration scripts",
description: "Create and manage database migration scripts"
},
{
name: "Backup and recovery procedures",
description: "Implement and maintain database backup and recovery strategies"
}
];
databaseEngineerTasks.forEach(task => {
databaseEngineer.addTask(task);
});
const reactDeveloper = frontendField.roles[0];
const uiuxEngineer = frontendField.roles[1];
const reactDeveloperTasks = [
{
name: "Build React components",
description: "Create reusable and performant React components"
},
{
name: "State management implementation",
description: "Implement state management using Redux, Zustand, or Context API"
},
{
name: "Frontend testing",
description: "Write unit and integration tests for React components"
},
{
name: "Bundle optimization",
description: "Optimize webpack bundles for better performance"
}
];
reactDeveloperTasks.forEach(task => {
reactDeveloper.addTask(task);
});
const uiuxEngineerTasks = [
{
name: "Design system implementation",
description: "Implement and maintain design system components"
},
{
name: "Accessibility compliance",
description: "Ensure applications meet WCAG accessibility standards"
},
{
name: "User experience optimization",
description: "Analyze and improve user interaction patterns"
}
];
uiuxEngineerTasks.forEach(task => {
uiuxEngineer.addTask(task);
});
const devopsEngineer = devopsField.roles[0];
const sreEngineer = devopsField.roles[1];
const devopsEngineerTasks = [
{
name: "CI/CD pipeline setup",
description: "Configure continuous integration and deployment pipelines"
},
{
name: "Infrastructure as Code",
description: "Manage infrastructure using Terraform, CloudFormation, or similar tools"
},
{
name: "Container orchestration",
description: "Deploy and manage applications using Docker and Kubernetes"
},
{
name: "Cloud resource management",
description: "Optimize cloud resource usage and costs"
}
];
devopsEngineerTasks.forEach(task => {
devopsEngineer.addTask(task);
});
const sreEngineerTasks = [
{
name: "Monitoring and alerting",
description: "Set up comprehensive monitoring and alerting systems"
},
{
name: "Incident response",
description: "Respond to and resolve production incidents"
},
{
name: "Capacity planning",
description: "Plan and manage system capacity and scaling"
},
{
name: "Post-mortem analysis",
description: "Conduct post-incident analysis and implement improvements"
}
];
sreEngineerTasks.forEach(task => {
sreEngineer.addTask(task);
});
const iosDeveloper = mobileField.roles[0];
const reactNativeDeveloper = mobileField.roles[1];
const iosDeveloperTasks = [
{
name: "iOS app development",
description: "Build native iOS applications using Swift and UIKit/SwiftUI"
},
{
name: "App Store submission",
description: "Prepare and submit apps to the Apple App Store"
},
{
name: "iOS performance optimization",
description: "Optimize app performance and memory usage"
}
];
iosDeveloperTasks.forEach(task => {
iosDeveloper.addTask(task);
});
const reactNativeDeveloperTasks = [
{
name: "Cross-platform development",
description: "Build apps that work on both iOS and Android platforms"
},
{
name: "Native module integration",
description: "Integrate native iOS and Android modules when needed"
},
{
name: "App performance tuning",
description: "Optimize React Native app performance and bundle size"
}
];
reactNativeDeveloperTasks.forEach(task => {
reactNativeDeveloper.addTask(task);
});
const dataPipelineEngineer = dataField.roles[0];
const dataPipelineEngineerTasks = [
{
name: "ETL pipeline development",
description: "Build Extract, Transform, Load pipelines for data processing"
},
{
name: "Data quality monitoring",
description: "Implement data quality checks and monitoring systems"
},
{
name: "Big data processing",
description: "Process large datasets using Spark, Hadoop, or similar technologies"
},
{
name: "Data warehouse management",
description: "Design and maintain data warehouse schemas and processes"
}
];
dataPipelineEngineerTasks.forEach(task => {
dataPipelineEngineer.addTask(task);
});
console.log("🏢 Software Company Hierarchy Structure:");
console.log("=".repeat(60));
console.log(`\n🌐 Domain: ${stemDomain.name}`);
console.log(` Description: ${stemDomain.description}`);
console.log(` Industries: ${stemDomain.industries.length}`);
stemDomain.industries.forEach(industry => {
console.log(`\n 🏭 Industry: ${industry.name}`);
console.log(` Description: ${industry.description}`);
console.log(` Professions: ${industry.professions.length}`);
industry.professions.forEach(profession => {
console.log(`\n 👨‍💼 Profession: ${profession.name}`);
console.log(` Description: ${profession.description}`);
console.log(` Fields: ${profession.fields.length}`);
profession.fields.forEach(field => {
console.log(`\n 🔧 Field: ${field.name}`);
console.log(` Description: ${field.description}`);
console.log(` Roles: ${field.roles.length}`);
field.roles.forEach(role => {
console.log(`\n 👤 Role: ${role.title}`);
console.log(` Summary: ${role.summary}`);
console.log(` Tasks: ${role.tasks.length}`);
role.tasks.forEach((task, index) => {
console.log(` ${index + 1}. ${task.name}`);
if (task.description) {
console.log(`${task.description}`);
}
});
});
});
});
});
console.log("\n" + "=".repeat(60));
console.log("🔍 V2 ADVANCED FEATURES DEMONSTRATION");
console.log("=".repeat(60));
console.log("\n🆔 UUID Identifiers:");
console.log(`Domain ID: ${stemDomain.id}`);
console.log(`Industry ID: ${softwareIndustry.id}`);
console.log(`Profession ID: ${softwareEngineering.id}`);
console.log(`First Field ID: ${backendField.id}`);
console.log(`First Role ID: ${seniorBackendEngineer.id}`);
console.log(`First Task ID: ${seniorBackendEngineer.tasks[0].id}`);
console.log(`\n📊 All Tasks in Software Industry (${softwareIndustry.allTasks.length}):`);
softwareIndustry.allTasks.forEach((task, index) => {
console.log(`${index + 1}. ${task.name}`);
});
console.log(`\n🔧 Tasks by Field:`);
softwareEngineering.fields.forEach(field => {
console.log(`${field.name}: ${field.allTasks.length} tasks`);
});
console.log("\n⚡ CRUD Operations Demonstration:");
console.log("\n Adding new field: 'Quality Assurance'");
softwareEngineering.addField({
name: "Quality Assurance",
description: "Software testing and quality assurance"
});
const qaField = softwareEngineering.fields[softwareEngineering.fields.length - 1];
console.log(`✅ Added field: ${qaField.name} (ID: ${qaField.id})`);
qaField.addRole({
title: "QA Engineer",
summary: "Ensure software quality through comprehensive testing"
});
const qaEngineer = qaField.roles[0];
console.log(`✅ Added role: ${qaEngineer.title} (ID: ${qaEngineer.id})`);
const qaTasks = [
{
name: "Test case development",
description: "Create comprehensive test cases for software features"
},
{
name: "Automated testing",
description: "Develop and maintain automated test suites"
},
{
name: "Bug reporting and tracking",
description: "Identify, document, and track software defects"
}
];
qaTasks.forEach(task => {
qaEngineer.addTask(task);
});
console.log(`✅ Added ${qaTasks.length} tasks to QA Engineer`);
const firstQATask = qaEngineer.tasks[0];
console.log(`\n✏ Updating task: "${firstQATask.name}"`);
firstQATask.update({
name: "Comprehensive Test Case Development",
description: "Create detailed test cases covering functional, integration, and edge cases"
});
console.log(`✅ Updated to: "${firstQATask.name}"`);
console.log(`\n🗑 Removing last task from QA Engineer`);
const taskToRemove = qaEngineer.tasks[qaEngineer.tasks.length - 1];
console.log(`Removing: "${taskToRemove.name}"`);
qaEngineer.removeTask(taskToRemove);
console.log(`✅ Task removed. QA Engineer now has ${qaEngineer.tasks.length} tasks`);
console.log("\n🔍 Advanced Querying:");
const engineerRoles = softwareEngineering.fields
.flatMap(field => field.roles)
.filter(role => role.title.includes("Engineer"));
console.log(`\n👷 Roles with "Engineer" in title (${engineerRoles.length}):`);
engineerRoles.forEach(role => {
console.log(` - ${role.title}`);
});
const fieldTaskCounts = softwareEngineering.fields
.map(field => ({
name: field.name,
taskCount: field.allTasks.length
}))
.sort((a, b) => b.taskCount - a.taskCount);
console.log(`\n📈 Fields by Task Count:`);
fieldTaskCounts.forEach(field => {
console.log(` - ${field.name}: ${field.taskCount} tasks`);
});
const developmentTasks = enterprise.allTasks
.filter(task =>
task.name.toLowerCase().includes("develop") ||
task.description?.toLowerCase().includes("develop")
);
console.log(`\n💻 Development-related Tasks (${developmentTasks.length}):`);
developmentTasks.forEach(task => {
console.log(` - ${task.name}`);
});
console.log("\n📊 Complete Hierarchy Statistics:");
console.log(` - Domains: ${enterprise.domains.length}`);
console.log(` - Industries: ${enterprise.domains.reduce((sum, d) => sum + d.industries.length, 0)}`);
console.log(` - Professions: ${enterprise.domains.reduce((sum, d) => sum + d.industries.reduce((sum2, i) => sum2 + i.professions.length, 0), 0)}`);
console.log(` - Fields: ${enterprise.domains.reduce((sum, d) => sum + d.industries.reduce((sum2, i) => sum2 + i.professions.reduce((sum3, p) => sum3 + p.fields.length, 0), 0), 0)}`);
console.log(` - Roles: ${enterprise.domains.reduce((sum, d) => sum + d.industries.reduce((sum2, i) => sum2 + i.professions.reduce((sum3, p) => sum3 + p.fields.reduce((sum4, f) => sum4 + f.roles.length, 0), 0), 0), 0)}`);
console.log(` - Tasks: ${enterprise.allTasks.length}`);
console.log("\n" + "=".repeat(60));
console.log("✅ Software Company example completed successfully!");
console.log("This example demonstrates the full 6-layer hierarchy with:");
console.log(" • UUID-based identifiers for distributed systems");
console.log(" • Comprehensive CRUD operations");
console.log(" • Compositional queries and views");
console.log(" • Real-world software company structure");
console.log(" • Advanced querying capabilities");
console.log("=".repeat(60));

125
generate-template.ts Executable file
View File

@@ -0,0 +1,125 @@
#!/usr/bin/env bun
/*
* hierarchyGenerator.ts
* ------------------------------------------------------------
* A tiny OpenAIpowered helper that turns naturallanguage prompts
* into domain hierarchies matching `HierarchyModel` (mobxstatetree).
* ------------------------------------------------------------
* Usage example:
* import { generateHierarchy } from "./hierarchyGenerator";
* const hierarchy = await generateHierarchy("Create a v2 Healthcare hierarchy for mental health services");
*
* The function returns a live MST instance of `HierarchyModel` so it
* can be plugged straight into your state tree or persisted as JSON.
*/
import OpenAI from "openai";
import { HierarchyModel } from "./lib/hierarchy-model.ts";
import type { Instance } from "mobx-state-tree";
// ---------------------------------------------------------------------------
// Type Definitions
// ---------------------------------------------------------------------------
/**
* Shape produced by the LLM and accepted by `HierarchyModel`.
*/
export interface Hierarchy {
version: "v1" | "v2";
domain: string; // e.g. "Finance", "Technology"
structure: string[]; // ordered list of hierarchy labels
description: string; // plaintext description
commonSkills: string[];
commonTools: string[];
examples: string[];
}
// ---------------------------------------------------------------------------
// OpenAI client configuration
// ---------------------------------------------------------------------------
const openai = new OpenAI({
// Rely on OPENAI_API_KEY env var or pass explicit key here
apiKey: process.env.OPENAI_API_KEY,
});
// System prompt used for every request. Keeps the model focused on
// emitting strict JSON with NO extra text.
const SYS_PROMPT = `
You are an API that converts naturallanguage descriptions into JSON
objects that conform **exactly** to the following TypeScript interface.
Return the JSON only no markdown, comments, or additional keys.
If a field is missing in the user's request, make a sensible inference.
interface Hierarchy {
version: "v1" | "v2"; // one of the two schema versions
domain: string; // highlevel sector name
structure: string[]; // ordered labels, 4 elements for v1, 6 for v2
description: string; // concise explanation of the hierarchy
commonSkills: string[]; // 37 bullet items
commonTools: string[]; // 37 bullet items
examples: string[]; // 37 representative examples
}
`;
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
/**
* Convert a naturallanguage prompt into a fullytyped `HierarchyModel`.
*
* @param nlPrompt Human description, e.g. "Define a v1 hierarchy for legal services"
* @param model (optional) Which OpenAI model to use. Defaults to GPT4omini.
*/
export async function generateHierarchy(
nlPrompt: string,
model: string = "gpt-4o-mini"
): Promise<Instance<typeof HierarchyModel>> {
const chat = await openai.chat.completions.create({
model,
response_format: { type: "json_object" }, // guarantees pure JSON
messages: [
{ role: "system", content: SYS_PROMPT },
{ role: "user", content: nlPrompt },
],
});
// Defensive parsing — in rare cases the assistant may wrap JSON in text.
const raw = chat.choices[0]?.message?.content ?? "{}";
let data: Hierarchy;
try {
data = JSON.parse(raw) as Hierarchy;
} catch {
// Attempt to salvage JSON embedded in text
const match = raw.match(/\{[\s\S]*\}/);
if (!match) throw new Error("Failed to parse JSON from LLM response");
data = JSON.parse(match[0]) as Hierarchy;
}
// Validate minimal shape before creating MST instance.
if (!data.version || !data.domain || !data.structure) {
throw new Error("Incomplete hierarchy returned by LLM");
}
return HierarchyModel.create(data);
}
// ---------------------------------------------------------------------------
// Helper: quick commandline demo when run with tsnode
// ---------------------------------------------------------------------------
if (require.main === module) {
(async () => {
const prompt = process.argv.slice(2).join(" ") ||
"Create a v2 Technology hierarchy focused on AI safety";
try {
const hierarchy = await generateHierarchy(prompt);
console.log(JSON.stringify(hierarchy.toJSON(), null, 2));
} catch (err) {
console.error("Error generating hierarchy:", err);
process.exitCode = 1;
}
})();
}

199
index.ts Normal file
View File

@@ -0,0 +1,199 @@
import HierarchyAgent from './lib/agent-wrapper';
import { writeFileSync, mkdirSync } from 'fs';
import { join } from 'path';
// Create the hierarchy agent with enhanced instructions
const hierarchyAgent = new HierarchyAgent({
name: 'Professional Hierarchy Generator',
instructions: `You are an expert at creating professional hierarchy models.
You understand organizational structures, job roles, skills, and professional development paths.
Generate comprehensive, realistic examples that demonstrate best practices in professional modeling.
Focus on creating practical, implementable hierarchies that reflect real-world organizational structures.
Include relevant skills, tools, and technologies for each role.
Provide clear examples of how the hierarchy can be used in practice.`,
});
// Demonstrate the modular agent capabilities
async function demonstrateAgentCapabilities() {
console.log('🚀 Demonstrating Professional Hierarchy Agent Capabilities...\n');
// Show available templates
console.log('📋 Available Templates:');
const templates = hierarchyAgent.getAvailableTemplates();
templates.forEach(template => {
console.log(` - ${template.domain} (${template.version}): ${template.description}`);
});
console.log();
// Generate examples using different approaches
const examples = [
{
name: 'Education Domain (using template)',
options: {
domain: 'education',
templateKey: 'education-v2',
complexity: 'complex' as const,
includeSkills: true,
includeTools: true,
includeExamples: true
}
},
{
name: 'Manufacturing Domain (custom generation)',
options: {
domain: 'manufacturing',
version: 'v2' as const,
complexity: 'medium' as const,
includeSkills: true,
includeTools: true,
includeExamples: true
}
},
{
name: 'Retail Domain (simple v1)',
options: {
domain: 'retail',
version: 'v1' as const,
complexity: 'simple' as const,
includeSkills: false,
includeTools: false,
includeExamples: true
}
}
];
// Create examples directory
const examplesDir = join(process.cwd(), 'examples', 'generated');
mkdirSync(examplesDir, { recursive: true });
// Generate each example with streaming for visibility
for (const example of examples) {
try {
console.log(`📊 Generating: ${example.name}...`);
console.log('🔍 Watch the agent work in real-time:\n');
// Use streaming to show what the agent is doing
const result = await hierarchyAgent.generateHierarchyWithStreaming(
example.options,
(event) => {
// Enhanced trace information for agent activities
if (event.type === 'agent_updated_stream_event') {
console.log(`[TRACE] 🤖 Agent: ${event.agent?.name || 'Unknown'} - Status updated`);
} else if (event.type === 'run_item_stream_event') {
if (event.item?.type === 'tool_call_item') {
console.log(`[TRACE] 🔧 Tool Call: ${event.item.tool_call?.function?.name || 'Unknown tool'}`);
if (event.item.tool_call?.function?.arguments) {
try {
const args = JSON.parse(event.item.tool_call.function.arguments);
console.log(`[TRACE] 📋 Tool Arguments: ${JSON.stringify(args, null, 2)}`);
} catch (e) {
console.log(`[TRACE] 📋 Tool Arguments: ${event.item.tool_call.function.arguments}`);
}
}
} else if (event.item?.type === 'tool_call_output_item') {
console.log(`[TRACE] ✅ Tool Output: Received response`);
} else if (event.item?.type === 'message_output_item') {
console.log(`[TRACE] 💬 Message: Generating response content`);
}
} else if (event.type === 'raw_model_stream_event' && event.delta?.content) {
// Show partial content being generated (throttled)
process.stdout.write('.');
} else if (event.type === 'run_started_stream_event') {
console.log(`[TRACE] 🚀 Run Started: Beginning agent execution`);
} else if (event.type === 'run_completed_stream_event') {
console.log(`[TRACE] 🏁 Run Completed: Agent execution finished`);
}
}
);
console.log(); // New line after dots
// Write the generated example to a file
const filepath = join(examplesDir, `${result.filename}.${result.extension}`);
writeFileSync(filepath, result.content);
console.log(`✅ Generated: ${filepath}`);
console.log(` Format: typescript (default)`);
console.log(` Complexity: ${example.options.complexity}`);
console.log();
} catch (error) {
console.error(`❌ Error generating ${example.name}:`, error);
}
}
// Demonstrate batch generation with streaming
console.log('🔄 Demonstrating batch generation with streaming...');
const batchDomains = ['logistics', 'consulting', 'media'];
const batchResults = [];
for (const domain of batchDomains) {
try {
console.log(`📊 Batch generating: ${domain} domain...`);
console.log('🔍 Streaming agent progress:\n');
const result = await hierarchyAgent.generateHierarchyWithStreaming({
domain,
version: 'v2',
complexity: 'medium',
includeSkills: true,
includeTools: true,
includeExamples: true
}, (event) => {
// Enhanced trace information for batch generation
if (event.type === 'agent_updated_stream_event') {
console.log(`[BATCH TRACE] 🤖 Agent: ${event.agent?.name || 'Unknown'} - Status updated`);
} else if (event.type === 'run_item_stream_event') {
if (event.item?.type === 'tool_call_item') {
console.log(`[BATCH TRACE] 🔧 Tool Call: ${event.item.tool_call?.function?.name || 'Unknown tool'}`);
if (event.item.tool_call?.function?.arguments) {
try {
const args = JSON.parse(event.item.tool_call.function.arguments);
console.log(`[BATCH TRACE] 📋 Tool Arguments: ${JSON.stringify(args, null, 2)}`);
} catch (e) {
console.log(`[BATCH TRACE] 📋 Tool Arguments: ${event.item.tool_call.function.arguments}`);
}
}
} else if (event.item?.type === 'tool_call_output_item') {
console.log(`[BATCH TRACE] ✅ Tool Output: Received response`);
} else if (event.item?.type === 'message_output_item') {
console.log(`[BATCH TRACE] 💬 Message: Generating response content`);
}
} else if (event.type === 'raw_model_stream_event' && event.delta?.content) {
// Show partial content being generated (throttled)
process.stdout.write('.');
} else if (event.type === 'run_started_stream_event') {
console.log(`[BATCH TRACE] 🚀 Run Started: Beginning agent execution for ${domain}`);
} else if (event.type === 'run_completed_stream_event') {
console.log(`[BATCH TRACE] 🏁 Run Completed: Agent execution finished for ${domain}`);
}
});
console.log(); // New line after dots
batchResults.push(result);
// Save batch result immediately
const filepath = join(examplesDir, `batch-${result.filename}.${result.extension}`);
writeFileSync(filepath, result.content);
console.log(`✅ Batch generated: ${filepath}`);
console.log();
} catch (error) {
console.error(`❌ Error in batch generation for ${domain}:`, error);
}
}
console.log('\n🎉 Agent capability demonstration complete!');
console.log(`📁 All examples saved to: ${examplesDir}`);
// Show summary
console.log('\n📊 Generation Summary:');
console.log(` Individual examples: ${examples.length}`);
console.log(` Batch examples: ${batchResults.length}`);
console.log(` Total files generated: ${examples.length + batchResults.length}`);
console.log(` Available templates: ${templates.length}`);
}
// Run the demonstration
demonstrateAgentCapabilities().catch(console.error);

252
lib/__tests__/v1.test.ts Normal file
View File

@@ -0,0 +1,252 @@
import { expect, test, describe } from "bun:test";
import { ProfessionModel, Domain, Specialization, Role, Responsibility, Attribute } from "../v1.ts";
describe("V1 Professional Hierarchy Model", () => {
describe("Attribute Model", () => {
test("should create an attribute with required fields", () => {
const attribute = Attribute.create({
name: "JavaScript",
type: "Skill"
});
expect(attribute.name).toBe("JavaScript");
expect(attribute.type).toBe("Skill");
expect(attribute.description).toBe("");
});
test("should create an attribute with description", () => {
const attribute = Attribute.create({
name: "React",
type: "Tool",
description: "Frontend library for building user interfaces"
});
expect(attribute.name).toBe("React");
expect(attribute.type).toBe("Tool");
expect(attribute.description).toBe("Frontend library for building user interfaces");
});
test("should accept all valid attribute types", () => {
const skill = Attribute.create({ name: "Problem Solving", type: "Skill" });
const tool = Attribute.create({ name: "VS Code", type: "Tool" });
const trait = Attribute.create({ name: "Leadership", type: "Trait" });
expect(skill.type).toBe("Skill");
expect(tool.type).toBe("Tool");
expect(trait.type).toBe("Trait");
});
});
describe("Responsibility Model", () => {
test("should create a responsibility with required attributes", () => {
const jsAttribute = Attribute.create({ name: "JavaScript", type: "Skill" });
const reactAttribute = Attribute.create({ name: "React", type: "Tool" });
const responsibility = Responsibility.create({
title: "Build User Interfaces",
outcome: "Functional and responsive web applications",
requiredAttributes: [jsAttribute, reactAttribute]
});
expect(responsibility.title).toBe("Build User Interfaces");
expect(responsibility.outcome).toBe("Functional and responsive web applications");
expect(responsibility.requiredAttributes).toHaveLength(2);
expect(responsibility.requiredAttributes[0].name).toBe("JavaScript");
expect(responsibility.requiredAttributes[1].name).toBe("React");
});
test("should create a responsibility with empty attributes array", () => {
const responsibility = Responsibility.create({
title: "Code Review",
outcome: "High quality code",
requiredAttributes: []
});
expect(responsibility.requiredAttributes).toHaveLength(0);
});
});
describe("Role Model", () => {
test("should create a role with all seniority levels", () => {
const seniorityLevels = ["Intern", "Junior", "Mid", "Senior", "Lead", "Principal"];
seniorityLevels.forEach(level => {
const role = Role.create({
title: `${level} Developer`,
responsibilities: [],
requiredAttributes: [],
seniority: level as any
});
expect(role.seniority).toBe(level);
});
});
test("should create a role with responsibilities and attributes", () => {
const attributeForResponsibility = Attribute.create({ name: "TypeScript", type: "Skill" });
const attributeForRole = Attribute.create({ name: "TypeScript", type: "Skill" });
const responsibility = Responsibility.create({
title: "Develop Features",
outcome: "Working software features",
requiredAttributes: [attributeForResponsibility]
});
const role = Role.create({
title: "Frontend Developer",
responsibilities: [responsibility],
requiredAttributes: [attributeForRole],
seniority: "Mid"
});
expect(role.title).toBe("Frontend Developer");
expect(role.responsibilities).toHaveLength(1);
expect(role.requiredAttributes).toHaveLength(1);
expect(role.seniority).toBe("Mid");
});
});
describe("Specialization Model", () => {
test("should create a specialization with roles and attributes", () => {
const coreAttribute = Attribute.create({ name: "Web Development", type: "Skill" });
const role = Role.create({
title: "Web Developer",
responsibilities: [],
requiredAttributes: [],
seniority: "Mid"
});
const specialization = Specialization.create({
name: "Frontend Development",
focus: "User interface and experience",
coreAttributes: [coreAttribute],
roles: [role]
});
expect(specialization.name).toBe("Frontend Development");
expect(specialization.focus).toBe("User interface and experience");
expect(specialization.coreAttributes).toHaveLength(1);
expect(specialization.roles).toHaveLength(1);
});
});
describe("Domain Model", () => {
test("should create a domain with specializations", () => {
const attribute = Attribute.create({ name: "Programming", type: "Skill" });
const specialization = Specialization.create({
name: "Software Engineering",
focus: "Building software systems",
coreAttributes: [],
roles: []
});
const domain = Domain.create({
name: "Technology",
description: "Technology and software development",
specializations: [specialization],
coreAttributes: [attribute]
});
expect(domain.name).toBe("Technology");
expect(domain.description).toBe("Technology and software development");
expect(domain.specializations).toHaveLength(1);
expect(domain.coreAttributes).toHaveLength(1);
});
test("should create a domain with empty description", () => {
const domain = Domain.create({
name: "Engineering",
specializations: [],
coreAttributes: []
});
expect(domain.description).toBe("");
});
});
describe("ProfessionModel", () => {
test("should create a profession model with domains", () => {
const domain = Domain.create({
name: "Healthcare",
specializations: [],
coreAttributes: []
});
const professionModel = ProfessionModel.create({
domains: [domain]
});
expect(professionModel.domains).toHaveLength(1);
expect(professionModel.domains[0].name).toBe("Healthcare");
});
test("should create an empty profession model", () => {
const professionModel = ProfessionModel.create({
domains: []
});
expect(professionModel.domains).toHaveLength(0);
});
});
describe("Complete Hierarchy Integration", () => {
test("should create a complete professional hierarchy", () => {
const jsSkillForResponsibility = Attribute.create({ name: "JavaScript", type: "Skill" });
const reactToolForResponsibility = Attribute.create({ name: "React", type: "Tool" });
// Create attributes for role
const jsSkillForRole = Attribute.create({ name: "JavaScript", type: "Skill" });
const reactToolForRole = Attribute.create({ name: "React", type: "Tool" });
const leadershipTrait = Attribute.create({ name: "Leadership", type: "Trait" });
const jsSkillForSpecialization = Attribute.create({ name: "JavaScript", type: "Skill" });
const reactToolForSpecialization = Attribute.create({ name: "React", type: "Tool" });
const jsSkillForDomain = Attribute.create({ name: "JavaScript", type: "Skill" });
const responsibility = Responsibility.create({
title: "Build React Applications",
outcome: "Scalable web applications",
requiredAttributes: [jsSkillForResponsibility, reactToolForResponsibility]
});
// Create role
const role = Role.create({
title: "Senior Frontend Developer",
responsibilities: [responsibility],
requiredAttributes: [jsSkillForRole, reactToolForRole, leadershipTrait],
seniority: "Senior"
});
const specialization = Specialization.create({
name: "Frontend Development",
focus: "User interfaces and client-side applications",
coreAttributes: [jsSkillForSpecialization, reactToolForSpecialization],
roles: [role]
});
// Create domain
const domain = Domain.create({
name: "Software Engineering",
description: "Building software systems and applications",
specializations: [specialization],
coreAttributes: [jsSkillForDomain]
});
const professionModel = ProfessionModel.create({
domains: [domain]
});
// Verify the complete hierarchy
expect(professionModel.domains).toHaveLength(1);
expect(professionModel.domains[0].specializations).toHaveLength(1);
expect(professionModel.domains[0].specializations[0].roles).toHaveLength(1);
expect(professionModel.domains[0].specializations[0].roles[0].responsibilities).toHaveLength(1);
const retrievedRole = professionModel.domains[0].specializations[0].roles[0];
expect(retrievedRole.title).toBe("Senior Frontend Developer");
expect(retrievedRole.seniority).toBe("Senior");
expect(retrievedRole.responsibilities[0].title).toBe("Build React Applications");
expect(retrievedRole.requiredAttributes).toHaveLength(3);
});
});
});

476
lib/__tests__/v2.test.ts Normal file
View File

@@ -0,0 +1,476 @@
import { expect, test, describe, beforeEach } from "bun:test";
import {
TaskModel,
RoleModel,
FieldModel,
ProfessionModel,
IndustryModel,
DomainModel,
Enterprise,
Task,
Role,
Field,
Profession,
Industry,
Domain,
IRootStore
} from "../v2.ts";
describe("V2 Professional Hierarchy Model", () => {
describe("TaskModel", () => {
test("should create a task with UUID identifier", () => {
const task = TaskModel.create({
name: "Design REST endpoints"
});
expect(task.name).toBe("Design REST endpoints");
expect(task.id).toBeDefined();
expect(typeof task.id).toBe("string");
expect(task.id.length).toBeGreaterThan(0);
expect(task.description).toBeUndefined();
});
test("should create a task with description", () => {
const task = TaskModel.create({
name: "Write unit tests",
description: "Create comprehensive test coverage for new features"
});
expect(task.name).toBe("Write unit tests");
expect(task.description).toBe("Create comprehensive test coverage for new features");
});
test("should update task properties", () => {
const task = TaskModel.create({
name: "Initial task"
});
task.update({
name: "Updated task",
description: "Updated description"
});
expect(task.name).toBe("Updated task");
expect(task.description).toBe("Updated description");
});
test("should have unique IDs for different tasks", () => {
const task1 = TaskModel.create({ name: "Task 1" });
const task2 = TaskModel.create({ name: "Task 2" });
expect(task1.id).not.toBe(task2.id);
});
});
describe("RoleModel", () => {
test("should create a role with tasks", () => {
const role = RoleModel.create({
title: "API Engineer",
summary: "Designs and implements REST APIs"
});
expect(role.title).toBe("API Engineer");
expect(role.summary).toBe("Designs and implements REST APIs");
expect(role.tasks).toHaveLength(0);
expect(role.id).toBeDefined();
});
test("should add and remove tasks", () => {
const role = RoleModel.create({
title: "Backend Developer"
});
role.addTask({ name: "Design database schema" });
role.addTask({ name: "Implement API endpoints" });
expect(role.tasks).toHaveLength(2);
expect((role.tasks[0] as any).name).toBe("Design database schema");
expect((role.tasks[1] as any).name ).toBe("Implement API endpoints");
// Remove a task
const taskToRemove = role.tasks[0];
role.removeTask(taskToRemove);
expect(role.tasks).toHaveLength(1);
expect((role.tasks[0] as any).name).toBe("Implement API endpoints");
});
test("should return all tasks through view", () => {
const role = RoleModel.create({
title: "Frontend Developer"
});
role.addTask({ name: "Build components" });
role.addTask({ name: "Write tests" });
const allTasks = role.allTasks;
expect(allTasks).toHaveLength(2);
expect(allTasks[0].name).toBe("Build components");
expect(allTasks[1].name).toBe("Write tests");
});
});
describe("FieldModel", () => {
test("should create a field with roles", () => {
const field = FieldModel.create({
name: "Backend Development",
description: "Server-side application development"
});
expect(field.name).toBe("Backend Development");
expect(field.description).toBe("Server-side application development");
expect(field.roles).toHaveLength(0);
});
test("should add and remove roles", () => {
const field = FieldModel.create({
name: "Frontend Development"
});
field.addRole({ title: "React Developer" });
field.addRole({ title: "Vue Developer" });
expect(field.roles).toHaveLength(2);
expect(field.roles[0].title).toBe("React Developer");
expect(field.roles[1].title).toBe("Vue Developer");
const roleToRemove = field.roles[0];
field.removeRole(roleToRemove);
expect(field.roles).toHaveLength(1);
expect(field.roles[0].title).toBe("Vue Developer");
});
test("should return all tasks from nested roles", () => {
const field = FieldModel.create({
name: "Full Stack Development"
});
field.addRole({ title: "Frontend Developer" });
field.addRole({ title: "Backend Developer" });
// Add tasks to roles
field.roles[0].addTask({ name: "Build UI components" });
field.roles[0].addTask({ name: "Handle user interactions" });
field.roles[1].addTask({ name: "Design APIs" });
const allTasks = field.allTasks;
expect(allTasks).toHaveLength(3);
expect(allTasks.map(t => t.name)).toContain("Build UI components");
expect(allTasks.map(t => t.name)).toContain("Handle user interactions");
expect(allTasks.map(t => t.name)).toContain("Design APIs");
});
});
describe("ProfessionModel", () => {
test("should create a profession with fields", () => {
const profession = ProfessionModel.create({
name: "Software Engineering",
description: "Building software systems and applications"
});
expect(profession.name).toBe("Software Engineering");
expect(profession.description).toBe("Building software systems and applications");
expect(profession.fields).toHaveLength(0);
});
test("should add and remove fields", () => {
const profession = ProfessionModel.create({
name: "Web Development"
});
profession.addField({ name: "Frontend" });
profession.addField({ name: "Backend" });
expect(profession.fields).toHaveLength(2);
expect(profession.fields[0].name).toBe("Frontend");
expect(profession.fields[1].name).toBe("Backend");
const fieldToRemove = profession.fields[0];
profession.removeField(fieldToRemove);
expect(profession.fields).toHaveLength(1);
expect(profession.fields[0].name).toBe("Backend");
});
test("should return all tasks from nested hierarchy", () => {
const profession = ProfessionModel.create({
name: "Software Engineering"
});
profession.addField({ name: "Backend" });
profession.fields[0].addRole({ title: "API Developer" });
profession.fields[0].roles[0].addTask({ name: "Design REST endpoints" });
profession.fields[0].roles[0].addTask({ name: "Implement authentication" });
const allTasks = profession.allTasks;
expect(allTasks).toHaveLength(2);
expect(allTasks.map(t => t.name)).toContain("Design REST endpoints");
expect(allTasks.map(t => t.name)).toContain("Implement authentication");
});
});
describe("IndustryModel", () => {
test("should create an industry with professions", () => {
const industry = IndustryModel.create({
name: "Software",
description: "Software development and technology"
});
expect(industry.name).toBe("Software");
expect(industry.description).toBe("Software development and technology");
expect(industry.professions).toHaveLength(0);
});
test("should add and remove professions", () => {
const industry = IndustryModel.create({
name: "Technology"
});
industry.addProfession({ name: "Software Engineering" });
industry.addProfession({ name: "Data Science" });
expect(industry.professions).toHaveLength(2);
expect(industry.professions[0].name).toBe("Software Engineering");
expect(industry.professions[1].name).toBe("Data Science");
// Remove a profession
const professionToRemove = industry.professions[0];
industry.removeProfession(professionToRemove);
expect(industry.professions).toHaveLength(1);
expect(industry.professions[0].name).toBe("Data Science");
});
test("should return all tasks from nested hierarchy", () => {
const industry = IndustryModel.create({
name: "Software"
});
industry.addProfession({ name: "Web Development" });
industry.professions[0].addField({ name: "Frontend" });
industry.professions[0].fields[0].addRole({ title: "React Developer" });
industry.professions[0].fields[0].roles[0].addTask({ name: "Build components" });
industry.professions[0].fields[0].roles[0].addTask({ name: "Manage state" });
const allTasks = industry.allTasks;
expect(allTasks).toHaveLength(2);
expect(allTasks.map(t => t.name)).toContain("Build components");
expect(allTasks.map(t => t.name)).toContain("Manage state");
});
});
describe("DomainModel", () => {
test("should create a domain with industries", () => {
const domain = DomainModel.create({
name: "STEM",
description: "Science, Technology, Engineering, and Mathematics"
});
expect(domain.name).toBe("STEM");
expect(domain.description).toBe("Science, Technology, Engineering, and Mathematics");
expect(domain.industries).toHaveLength(0);
});
test("should add and remove industries", () => {
const domain = DomainModel.create({
name: "Technology"
});
domain.addIndustry({ name: "Software" });
domain.addIndustry({ name: "Hardware" });
expect(domain.industries).toHaveLength(2);
expect(domain.industries[0].name).toBe("Software");
expect(domain.industries[1].name).toBe("Hardware");
const industryToRemove = domain.industries[0];
domain.removeIndustry(industryToRemove);
expect(domain.industries).toHaveLength(1);
expect(domain.industries[0].name).toBe("Hardware");
});
test("should return all tasks from nested hierarchy", () => {
const domain = DomainModel.create({
name: "STEM"
});
domain.addIndustry({ name: "Software" });
domain.industries[0].addProfession({ name: "Software Engineering" });
domain.industries[0].professions[0].addField({ name: "Backend" });
domain.industries[0].professions[0].fields[0].addRole({ title: "API Engineer" });
domain.industries[0].professions[0].fields[0].roles[0].addTask({ name: "Design REST endpoints" });
const allTasks = domain.allTasks;
expect(allTasks).toHaveLength(1);
expect(allTasks[0].name).toBe("Design REST endpoints");
});
});
describe("Enterprise", () => {
let store: IRootStore;
beforeEach(() => {
store = Enterprise.create({});
});
test("should create an empty root store", () => {
expect(store.domains).toHaveLength(0);
});
test("should add domains", () => {
store.addDomain({ name: "STEM" });
store.addDomain({ name: "Arts" });
expect(store.domains).toHaveLength(2);
expect(store.domains[0].name).toBe("STEM");
expect(store.domains[1].name).toBe("Arts");
});
test("should return all tasks from entire hierarchy", () => {
store.addDomain({ name: "STEM" });
store.domains[0].addIndustry({ name: "Software" });
store.domains[0].industries[0].addProfession({ name: "Software Engineering" });
store.domains[0].industries[0].professions[0].addField({ name: "Backend" });
store.domains[0].industries[0].professions[0].fields[0].addRole({ title: "API Engineer" });
store.domains[0].industries[0].professions[0].fields[0].roles[0].addTask({ name: "Design REST endpoints" });
store.domains[0].industries[0].professions[0].fields[0].roles[0].addTask({ name: "Implement authentication" });
const allTasks = store.allTasks;
expect(allTasks).toHaveLength(2);
expect(allTasks.map(t => t.name)).toContain("Design REST endpoints");
expect(allTasks.map(t => t.name)).toContain("Implement authentication");
});
});
describe("Complete Hierarchy Integration", () => {
test("should create and manipulate a complete 6-layer hierarchy", () => {
const store = Enterprise.create({});
// Build the complete hierarchy as shown in the example
store.addDomain({ name: "STEM" });
store.domains[0].addIndustry({ name: "Software" });
store.domains[0].industries[0].addProfession({ name: "Software Engineering" });
store.domains[0].industries[0].professions[0].addField({ name: "Backend" });
store.domains[0].industries[0].professions[0].fields[0].addRole({ title: "API Engineer" });
store.domains[0].industries[0].professions[0].fields[0].roles[0].addTask({ name: "Design REST endpoints" });
expect(store.domains).toHaveLength(1);
expect(store.domains[0].industries).toHaveLength(1);
expect(store.domains[0].industries[0].professions).toHaveLength(1);
expect(store.domains[0].industries[0].professions[0].fields).toHaveLength(1);
expect(store.domains[0].industries[0].professions[0].fields[0].roles).toHaveLength(1);
expect(store.domains[0].industries[0].professions[0].fields[0].roles[0].tasks).toHaveLength(1);
// Verify data integrity through the hierarchy
const task = store.domains[0].industries[0].professions[0].fields[0].roles[0].tasks[0];
expect(task.name).toBe("Design REST endpoints");
expect(store.allTasks).toHaveLength(1);
expect(store.domains[0].allTasks).toHaveLength(1);
expect(store.domains[0].industries[0].allTasks).toHaveLength(1);
expect(store.domains[0].industries[0].professions[0].allTasks).toHaveLength(1);
expect(store.domains[0].industries[0].professions[0].fields[0].allTasks).toHaveLength(1);
// Add more tasks and verify aggregation
store.domains[0].industries[0].professions[0].fields[0].roles[0].addTask({ name: "Implement authentication" });
store.domains[0].industries[0].professions[0].fields[0].addRole({ title: "Database Engineer" });
store.domains[0].industries[0].professions[0].fields[0].roles[1].addTask({ name: "Design database schema" });
expect(store.allTasks).toHaveLength(3);
expect(store.domains[0].industries[0].professions[0].fields[0].allTasks).toHaveLength(3);
});
test("should handle multiple parallel hierarchies", () => {
const store = Enterprise.create({});
store.addDomain({ name: "STEM" });
store.domains[0].addIndustry({ name: "Software" });
store.domains[0].industries[0].addProfession({ name: "Web Development" });
store.domains[0].industries[0].professions[0].addField({ name: "Frontend" });
store.domains[0].industries[0].professions[0].fields[0].addRole({ title: "React Developer" });
store.domains[0].industries[0].professions[0].fields[0].roles[0].addTask({ name: "Build components" });
// Create second hierarchy branch
store.addDomain({ name: "Arts" });
store.domains[1].addIndustry({ name: "Digital Media" });
store.domains[1].industries[0].addProfession({ name: "Graphic Design" });
store.domains[1].industries[0].professions[0].addField({ name: "Web Design" });
store.domains[1].industries[0].professions[0].fields[0].addRole({ title: "UI Designer" });
store.domains[1].industries[0].professions[0].fields[0].roles[0].addTask({ name: "Create mockups" });
expect(store.domains).toHaveLength(2);
expect(store.allTasks).toHaveLength(2);
expect(store.allTasks.map(t => t.name)).toContain("Build components");
expect(store.allTasks.map(t => t.name)).toContain("Create mockups");
// Verify each domain has its own tasks
expect(store.domains[0].allTasks).toHaveLength(1);
expect(store.domains[1].allTasks).toHaveLength(1);
expect(store.domains[0].allTasks[0].name).toBe("Build components");
expect(store.domains[1].allTasks[0].name).toBe("Create mockups");
});
});
describe("CRUD Operations", () => {
test("should support task updates and removal", () => {
const role = RoleModel.create({ title: "Developer" });
role.addTask({ name: "Initial task", description: "Initial description" });
const task = role.tasks[0];
const originalId = task.id;
task.update({ name: "Updated task", description: "Updated description" });
expect(task.name).toBe("Updated task");
expect(task.description).toBe("Updated description");
expect(task.id).toBe(originalId); // ID should remain the same
// Remove task through parent
expect(role.tasks).toHaveLength(1);
role.removeTask(task);
expect(role.tasks).toHaveLength(0);
});
test("should support role removal", () => {
const field = FieldModel.create({ name: "Development" });
field.addRole({ title: "Developer" });
expect(field.roles).toHaveLength(1);
const role = field.roles[0];
field.removeRole(role);
expect(field.roles).toHaveLength(0);
});
test("should support field removal", () => {
const profession = ProfessionModel.create({ name: "Engineering" });
profession.addField({ name: "Software" });
expect(profession.fields).toHaveLength(1);
const field = profession.fields[0];
profession.removeField(field);
expect(profession.fields).toHaveLength(0);
});
test("should support profession removal", () => {
const industry = IndustryModel.create({ name: "Tech" });
industry.addProfession({ name: "Software Engineering" });
expect(industry.professions).toHaveLength(1);
const profession = industry.professions[0];
industry.removeProfession(profession);
expect(industry.professions).toHaveLength(0);
});
test("should support industry removal", () => {
const domain = DomainModel.create({ name: "STEM" });
domain.addIndustry({ name: "Software" });
expect(domain.industries).toHaveLength(1);
const industry = domain.industries[0];
domain.removeIndustry(industry);
expect(domain.industries).toHaveLength(0);
});
});
});

203
lib/agent-wrapper.ts Normal file
View File

@@ -0,0 +1,203 @@
import { Agent, StreamedRunResult } from '@openai/agents';
import HierarchyGenerator, { GenerationParams } from './components/hierarchy-generator';
import TemplateManager, { DomainTemplate } from './components/template-manager';
import OutputFormatter, { OutputOptions, FormattedOutput } from './components/output-formatter';
export interface AgentConfig {
name: string;
instructions: string;
model?: string;
}
export interface HierarchyGenerationOptions extends GenerationParams {
outputFormat?: OutputOptions;
templateKey?: string;
stream?: boolean;
}
export class HierarchyAgent {
private agent: Agent;
private generator: HierarchyGenerator;
private templateManager: TemplateManager;
private outputFormatter: OutputFormatter;
constructor(config: AgentConfig) {
this.agent = new Agent({
name: config.name,
instructions: config.instructions,
model: config.model || 'gpt-4o-mini'
});
this.generator = new HierarchyGenerator(this.agent);
this.templateManager = new TemplateManager();
this.outputFormatter = new OutputFormatter();
}
async generateHierarchy(options: HierarchyGenerationOptions): Promise<FormattedOutput | StreamedRunResult> {
let template: DomainTemplate;
if (options.templateKey) {
template = this.templateManager.getTemplate(options.templateKey);
if (!template) {
throw new Error(`Template not found: ${options.templateKey}`);
}
} else {
// Create a default template for the domain
const version = options.version || 'v2';
template = this.templateManager.createCustomTemplate(
`${options.domain}-${version}`,
options.domain,
version
);
}
const generationParams: GenerationParams = {
domain: options.domain,
complexity: options.complexity || 'medium',
includeSkills: options.includeSkills ?? true,
includeTools: options.includeTools ?? true,
includeExamples: options.includeExamples ?? true,
stream: options.stream
};
const content = await this.generator.generateFromTemplate(template, generationParams);
// If streaming, return the stream directly
if (options.stream && content instanceof Object && 'toStream' in content) {
return content as StreamedRunResult;
}
const outputOptions = options.outputFormat || this.outputFormatter.getDefaultOptions();
const formattedOutput = this.outputFormatter.formatOutput(
content as string,
options.domain,
template.version,
outputOptions
);
return formattedOutput;
}
// New method for streaming with enhanced visibility
async generateHierarchyWithStreaming(
options: HierarchyGenerationOptions,
onStreamEvent?: (event: any) => void
): Promise<FormattedOutput> {
let template: DomainTemplate;
if (options.templateKey) {
template = this.templateManager.getTemplate(options.templateKey);
if (!template) {
throw new Error(`Template not found: ${options.templateKey}`);
}
} else {
// Create a default template for the domain
const version = options.version || 'v2';
template = this.templateManager.createCustomTemplate(
`${options.domain}-${version}`,
options.domain,
version
);
}
const generationParams: GenerationParams = {
domain: options.domain,
complexity: options.complexity || 'medium',
includeSkills: options.includeSkills ?? true,
includeTools: options.includeTools ?? true,
includeExamples: options.includeExamples ?? true
};
const content = await this.generator.generateFromTemplateWithStreaming(
template,
generationParams,
onStreamEvent
);
// Format the output
const outputOptions = options.outputFormat || this.outputFormatter.getDefaultOptions();
const formattedOutput = this.outputFormatter.formatOutput(
content,
options.domain,
template.version,
outputOptions
);
return formattedOutput;
}
async generateExample(
domain: string,
version: 'v1' | 'v2' = 'v2',
complexity: 'simple' | 'medium' | 'complex' = 'medium'
): Promise<FormattedOutput> {
return this.generateHierarchy({
domain,
version,
complexity,
includeSkills: true,
includeTools: true,
includeExamples: true
});
}
// Template management methods
getAvailableTemplates(): DomainTemplate[] {
return this.templateManager.getAllTemplates();
}
getTemplatesByDomain(domain: string): DomainTemplate[] {
return this.templateManager.getTemplatesByDomain(domain);
}
getTemplatesByVersion(version: 'v1' | 'v2'): DomainTemplate[] {
return this.templateManager.getTemplatesByVersion(version);
}
addCustomTemplate(key: string, template: DomainTemplate): void {
this.templateManager.addTemplate(key, template);
}
// Validation and optimization methods
async validateHierarchy(hierarchyData: any): Promise<boolean> {
// TODO: Implement validation logic using the agent
// Could validate structure, naming conventions, completeness, etc.
return true;
}
async optimizeHierarchy(hierarchyData: any): Promise<any> {
// TODO: Implement optimization logic using the agent
// Could suggest improvements, fill gaps, optimize structure, etc.
return hierarchyData;
}
// Batch generation methods
async generateMultipleExamples(
domains: string[],
version: 'v1' | 'v2' = 'v2',
outputFormat?: OutputOptions
): Promise<FormattedOutput[]> {
const results: FormattedOutput[] = [];
for (const domain of domains) {
try {
const result = await this.generateHierarchy({
domain,
version,
complexity: 'medium',
includeSkills: true,
includeTools: true,
includeExamples: true,
outputFormat
});
results.push(result);
} catch (error) {
console.error(`Error generating example for ${domain}:`, error);
}
}
return results;
}
}
export default HierarchyAgent;

View File

@@ -0,0 +1,115 @@
import { Agent, run, StreamedRunResult } from '@openai/agents';
export interface HierarchyTemplate {
version: 'v1' | 'v2';
structure: string[];
description: string;
}
export interface GenerationParams {
domain: string;
complexity: 'simple' | 'medium' | 'complex';
includeSkills: boolean;
includeTools: boolean;
includeExamples: boolean;
stream?: boolean;
}
export class HierarchyGenerator {
private agent: Agent;
constructor(agent: Agent) {
this.agent = agent;
}
async generateFromTemplate(template: HierarchyTemplate, params: GenerationParams): Promise<string | StreamedRunResult> {
const prompt = this.buildPrompt(template, params);
if (params.stream) {
return await run(this.agent, prompt, { stream: true });
} else {
const result = await run(this.agent, prompt);
return result.finalOutput;
}
}
// Helper method to stream and collect final output
async generateFromTemplateWithStreaming(
template: HierarchyTemplate,
params: GenerationParams,
onStreamEvent?: (event: any) => void
): Promise<string> {
const prompt = this.buildPrompt(template, params);
console.log('🔄 Starting hierarchy generation...');
const stream = await run(this.agent, prompt, { stream: true });
let content = '';
for await (const event of stream) {
if (event.type === 'raw_model_stream_event' && event.data.delta) {
// console.log(event.data.delta)
content += event.delta;
process.stdout.write(event.data.delta);
}
if (event.type === 'agent_updated_stream_event') {
console.log(`\n📝 Agent: ${event.agent.name} is processing...`);
} else if (event.type === 'run_item_stream_event') {
if (event.item.type === 'tool_call_item') {
console.log('\n🔧 Tool being called...');
} else if (event.item.type === 'message_output_item') {
console.log('\n💬 Generating response...');
}
}
// Allow custom event handling
if (onStreamEvent) {
onStreamEvent(event);
}
}
console.log('\n✅ Hierarchy generation complete!');
return stream.finalOutput;
}
private buildPrompt(template: HierarchyTemplate, params: GenerationParams): string {
const structureDescription = template.version === 'v1'
? 'Domain → Specialization → Role → Responsibility'
: 'Domain → Industry → Profession → Field → Role → Task';
const importStatement = template.version === 'v1'
? 'import { Enterprise, DomainModel, SpecializationModel, RoleModel, ResponsibilityModel } from "../../lib/v1";'
: 'import { Enterprise, DomainModel, IndustryModel, ProfessionModel, FieldModel, RoleModel, TaskModel } from "../../lib/v2";';
return `
Generate ONLY TypeScript code for a professional hierarchy in the ${params.domain} domain using the ${template.version} structure.
Structure: ${structureDescription}
Complexity Level: ${params.complexity}
${params.includeSkills ? '✓ Include relevant skills and competencies' : ''}
${params.includeTools ? '✓ Include tools and technologies' : ''}
${params.includeExamples ? '✓ Include practical examples and use cases' : ''}
IMPORTANT: Output ONLY valid TypeScript code. Do not include any markdown, explanations, or comments outside of TypeScript comments.
Requirements:
1. Start with the import statement: ${importStatement}
2. Create a realistic, comprehensive hierarchy using MobX State Tree models
3. Use appropriate professional terminology
4. Ensure logical relationships between levels
5. ${params.complexity === 'complex' ? 'Include multiple branches and detailed attributes' :
params.complexity === 'medium' ? 'Include moderate detail with key attributes' :
'Keep it simple with essential elements only'}
The code should demonstrate:
- Creating the hierarchy structure using the imported models
- Adding relevant attributes (skills, tools, examples)
- Basic operations (create, read, update)
- Real-world application examples as TypeScript code
Output format: Pure TypeScript code only, no markdown or explanations.
`;
}
}
export default HierarchyGenerator;

View File

@@ -0,0 +1,278 @@
export interface OutputOptions {
format: 'typescript' | 'markdown' | 'json' | 'yaml';
includeMetadata: boolean;
includeTimestamp: boolean;
includeComments: boolean;
}
export interface FormattedOutput {
content: string;
filename: string;
extension: string;
metadata?: any;
}
export class OutputFormatter {
formatOutput(
content: string,
domain: string,
version: 'v1' | 'v2',
options: OutputOptions
): FormattedOutput {
switch (options.format) {
case 'typescript':
return this.formatTypeScript(content, domain, version, options);
case 'markdown':
return this.formatMarkdown(content, domain, version, options);
case 'json':
return this.formatJSON(content, domain, version, options);
case 'yaml':
return this.formatYAML(content, domain, version, options);
default:
throw new Error(`Unsupported format: ${options.format}`);
}
}
private formatTypeScript(
content: string,
domain: string,
version: 'v1' | 'v2',
options: OutputOptions
): FormattedOutput {
const header = options.includeComments ? `/**
* ${domain} Professional Hierarchy Example
* Generated using OpenAI Agents SDK and Sumpin Professional Hierarchy Models
* Model Version: ${version} (${version === 'v1' ? '4-layer' : '6-layer'} hierarchy)
* ${options.includeTimestamp ? `Generated on: ${new Date().toISOString()}` : ''}
*/
` : '';
const imports = `import {
Enterprise,
${version === 'v1' ? 'DomainModel, SpecializationModel, RoleModel, ResponsibilityModel' : 'DomainModel, IndustryModel, ProfessionModel, FieldModel, RoleModel, TaskModel'}
} from "../../lib/${version}";
`;
const cleanedContent = this.extractTypeScriptCode(content);
return {
content: header + imports + cleanedContent,
filename: `${domain.toLowerCase()}-hierarchy-example`,
extension: 'ts',
metadata: {
domain,
version,
generatedAt: options.includeTimestamp ? new Date().toISOString() : undefined
}
};
}
private extractTypeScriptCode(content: string): string {
let cleaned = content;
cleaned = cleaned.replace(/^#{1,6}\s+.*$/gm, '');
cleaned = cleaned.replace(/\*\*([^*]+)\*\*/g, '$1');
cleaned = cleaned.replace(/\*([^*]+)\*/g, '$1');
// Remove markdown lists that aren't TypeScript code
cleaned = cleaned.replace(/^[\s]*[-*+]\s+\*\*([^*]+)\*\*$/gm, '');
cleaned = cleaned.replace(/^[\s]*[-*+]\s+([^:]+):$/gm, '');
// Extract TypeScript code blocks
const codeBlockRegex = /```typescript\s*([\s\S]*?)```/g;
const codeBlocks = [];
let match;
while ((match = codeBlockRegex.exec(content)) !== null) {
codeBlocks.push(match[1].trim());
}
// If we found code blocks, use them
if (codeBlocks.length > 0) {
return codeBlocks.join('\n\n');
}
// Otherwise, try to extract TypeScript-like content
const lines = cleaned.split('\n');
const tsLines = [];
let inCodeSection = false;
for (const line of lines) {
const trimmed = line.trim();
// Skip empty lines and markdown-like content
if (!trimmed ||
trimmed.startsWith('#') ||
trimmed.startsWith('*') ||
trimmed.startsWith('-') ||
trimmed.includes('Below is') ||
trimmed.includes('Here\'s') ||
trimmed.includes('TypeScript Code') ||
trimmed.includes('Professional Hierarchy')) {
continue;
}
// Look for TypeScript patterns
if (trimmed.includes('interface ') ||
trimmed.includes('class ') ||
trimmed.includes('type ') ||
trimmed.includes('const ') ||
trimmed.includes('let ') ||
trimmed.includes('var ') ||
trimmed.includes('function ') ||
trimmed.includes('export ') ||
trimmed.includes('import ') ||
trimmed.includes('{') ||
trimmed.includes('}') ||
trimmed.includes(';') ||
inCodeSection) {
tsLines.push(line);
inCodeSection = true;
// End code section on certain patterns
if (trimmed === '}' && !line.includes(',')) {
inCodeSection = false;
}
}
}
return tsLines.join('\n').trim() || cleaned.trim();
}
private formatMarkdown(
content: string,
domain: string,
version: 'v1' | 'v2',
options: OutputOptions
): FormattedOutput {
const header = `# ${domain.charAt(0).toUpperCase() + domain.slice(1)} Professional Hierarchy Example
Generated using OpenAI Agents SDK and Sumpin Professional Hierarchy Models
## Overview
This example demonstrates a ${version} professional hierarchy model for the ${domain} domain.
**Model Version:** ${version} (${version === 'v1' ? '4-layer' : '6-layer'} hierarchy)
${options.includeTimestamp ? `**Generated on:** ${new Date().toISOString()}` : ''}
## Structure
${version === 'v1' ? 'Domain → Specialization → Role → Responsibility' : 'Domain → Industry → Profession → Field → Role → Task'}
## Generated Content
\`\`\`typescript
${content}
\`\`\`
## Usage
To use this example:
1. Ensure you have the required dependencies installed:
\`\`\`bash
bun add mobx-state-tree mobx uuid
bun add -d @types/uuid
\`\`\`
2. Run the example:
\`\`\`bash
bun run examples/generated/${domain.toLowerCase()}-hierarchy-example.ts
\`\`\`
---
*This example was generated automatically and demonstrates best practices for professional hierarchy modeling.*
`;
return {
content: header,
filename: `${domain.toLowerCase()}-hierarchy-example`,
extension: 'md',
metadata: {
domain,
version,
generatedAt: options.includeTimestamp ? new Date().toISOString() : undefined
}
};
}
private formatJSON(
content: string,
domain: string,
version: 'v1' | 'v2',
options: OutputOptions
): FormattedOutput {
const data = {
domain,
version,
structure: version === 'v1'
? ['Domain', 'Specialization', 'Role', 'Responsibility']
: ['Domain', 'Industry', 'Profession', 'Field', 'Role', 'Task'],
generatedContent: content,
...(options.includeMetadata && {
metadata: {
generatedAt: options.includeTimestamp ? new Date().toISOString() : undefined,
generator: 'OpenAI Agents SDK + Sumpin',
hierarchyType: `${version === 'v1' ? '4' : '6'}-layer hierarchy`
}
})
};
return {
content: JSON.stringify(data, null, 2),
filename: `${domain.toLowerCase()}-hierarchy-example`,
extension: 'json',
metadata: data.metadata
};
}
private formatYAML(
content: string,
domain: string,
version: 'v1' | 'v2',
options: OutputOptions
): FormattedOutput {
const yamlContent = `domain: ${domain}
version: ${version}
structure:
${(version === 'v1'
? ['Domain', 'Specialization', 'Role', 'Responsibility']
: ['Domain', 'Industry', 'Profession', 'Field', 'Role', 'Task']
).map(item => ` - ${item}`).join('\n')}
generated_content: |
${content.split('\n').map(line => ` ${line}`).join('\n')}
${options.includeMetadata ? `metadata:
generated_at: ${options.includeTimestamp ? new Date().toISOString() : 'null'}
generator: "OpenAI Agents SDK + Sumpin"
hierarchy_type: "${version === 'v1' ? '4' : '6'}-layer hierarchy"` : ''}`;
return {
content: yamlContent,
filename: `${domain.toLowerCase()}-hierarchy-example`,
extension: 'yaml',
metadata: {
domain,
version,
generatedAt: options.includeTimestamp ? new Date().toISOString() : undefined
}
};
}
getDefaultOptions(): OutputOptions {
return {
format: 'typescript',
includeMetadata: true,
includeTimestamp: true,
includeComments: true
};
}
}
export default OutputFormatter;

View File

@@ -0,0 +1,81 @@
import { HierarchyTemplate } from './hierarchy-generator';
import v1Finance from "./templates/v1-finance.ts";
import v1Tech from "./templates/v1-tech.ts";
import v2Edu from "./templates/v2-edu.ts";
import v2Healthcare from "./templates/v2-healthcare.ts";
import v2Tech from "./templates/v2-tech.ts";
export interface DomainTemplate extends HierarchyTemplate {
domain: string;
commonSkills: string[];
commonTools: string[];
examples: string[];
}
export class TemplateManager {
private templates: Map<string, DomainTemplate> = new Map();
constructor() {
this.initializeDefaultTemplates();
}
private initializeDefaultTemplates() {
// V2 Templates (6-layer hierarchy)
this.addTemplate('technology-v2', v2Tech);
this.addTemplate('healthcare-v2', v2Healthcare);
this.addTemplate('education-v2', v2Edu);
// V1 Templates (4-layer hierarchy)
this.addTemplate('technology-v1', v1Tech);
this.addTemplate('finance-v1', v1Finance);
}
addTemplate(key: string, template: DomainTemplate): void {
this.templates.set(key, template);
}
getTemplate(key: string): DomainTemplate | undefined {
return this.templates.get(key);
}
getTemplatesByVersion(version: 'v1' | 'v2'): DomainTemplate[] {
return Array.from(this.templates.values()).filter(t => t.version === version);
}
getTemplatesByDomain(domain: string): DomainTemplate[] {
return Array.from(this.templates.values()).filter(t =>
t.domain.toLowerCase().includes(domain.toLowerCase())
);
}
getAllTemplates(): DomainTemplate[] {
return Array.from(this.templates.values());
}
createCustomTemplate(
key: string,
domain: string,
version: 'v1' | 'v2',
options: Partial<DomainTemplate> = {}
): DomainTemplate {
const structure = version === 'v1'
? ['Domain', 'Specialization', 'Role', 'Responsibility']
: ['Domain', 'Industry', 'Profession', 'Field', 'Role', 'Task'];
const template: DomainTemplate = {
version,
domain,
structure,
description: `${domain} professional hierarchy`,
commonSkills: [],
commonTools: [],
examples: [],
...options
};
this.addTemplate(key, template);
return template;
}
}
export default TemplateManager;

View File

@@ -0,0 +1,9 @@
export default {
version: 'v1',
domain: 'Finance',
structure: ['Domain', 'Specialization', 'Role', 'Responsibility'],
description: 'Simplified finance sector hierarchy',
commonSkills: ['Financial Analysis', 'Risk Assessment', 'Compliance', 'Reporting'],
commonTools: ['Excel', 'Financial Software', 'Analytics Tools', 'Reporting Systems'],
examples: ['Investment Banking', 'Corporate Finance', 'Risk Management', 'Accounting']
}

View File

@@ -0,0 +1,9 @@
export default {
version: 'v1',
domain: 'Technology',
structure: ['Domain', 'Specialization', 'Role', 'Responsibility'],
description: 'Simplified technology sector hierarchy',
commonSkills: ['Programming', 'System Design', 'Testing', 'Documentation'],
commonTools: ['Code Editors', 'Version Control', 'Build Tools', 'Monitoring'],
examples: ['Web Development', 'Mobile Development', 'Backend Systems', 'Frontend UI']
}

View File

@@ -0,0 +1,9 @@
export default {
version: 'v2',
domain: 'Education',
structure: ['Domain', 'Industry', 'Profession', 'Field', 'Role', 'Task'],
description: 'Comprehensive education sector hierarchy',
commonSkills: ['Teaching', 'Curriculum Development', 'Assessment', 'Student Engagement'],
commonTools: ['LMS', 'Educational Software', 'Assessment Tools', 'Communication Platforms'],
examples: ['K-12 Education', 'Higher Education', 'Corporate Training', 'Online Learning']
}

View File

@@ -0,0 +1,9 @@
export default {
version: 'v2',
domain: 'Healthcare',
structure: ['Domain', 'Industry', 'Profession', 'Field', 'Role', 'Task'],
description: 'Comprehensive healthcare sector hierarchy',
commonSkills: ['Patient Care', 'Medical Knowledge', 'Communication', 'Empathy'],
commonTools: ['EMR Systems', 'Medical Devices', 'Diagnostic Tools', 'Communication Systems'],
examples: ['Clinical Care', 'Medical Research', 'Healthcare Administration', 'Public Health']
}

View File

@@ -0,0 +1,9 @@
export default {
version: 'v2',
domain: 'Technology',
structure: ['Domain', 'Industry', 'Profession', 'Field', 'Role', 'Task'],
description: 'Comprehensive technology sector hierarchy',
commonSkills: ['Problem Solving', 'Critical Thinking', 'Communication', 'Collaboration'],
commonTools: ['Git', 'IDE', 'Testing Frameworks', 'Documentation Tools'],
examples: ['Software Development', 'DevOps', 'Data Science', 'Cybersecurity']
}

35
lib/hierarchy-model.ts Normal file
View File

@@ -0,0 +1,35 @@
import { types } from "mobx-state-tree";
/**
* Reusable abstraction for a domain/sector hierarchy.
* Works for both v1 and v2
*/
export const HierarchyModel = types.model("HierarchyModel", {
version: types.string, // "v1" | "v2"
domain: types.string, // e.g. "Finance", "Technology"
structure: types.array(types.string), // ordered hierarchy labels
description: types.string, // plain-text description
commonSkills: types.array(types.string),
commonTools: types.array(types.string),
examples: types.array(types.string)
});
/* ------------------------------------------------------------------ *
* Example usage
* ------------------------------------------------------------------ */
// Create individual instances
// import { HierarchyModel } from "./hierarchy-model";
//
// const finance = HierarchyModel.create(v1Finance);
// const tech = HierarchyModel.create(v2Tech);
export const HierarchyStore = types
.model("HierarchyStore", {
items: types.map(HierarchyModel) // keyed by domain name
})
.actions(self => ({
add(h: Instance<typeof HierarchyModel>) {
self.items.set(h.domain, h);
}
}));

4
lib/index.ts Normal file
View File

@@ -0,0 +1,4 @@
import v1 from './v1';
import v2 from './v2';
export { v1, v2 };

41
lib/v1.ts Normal file
View File

@@ -0,0 +1,41 @@
import { types } from "mobx-state-tree"
const Attribute = types.model("Attribute", {
name: types.string,
type: types.enumeration("AttributeType", ["Skill", "Tool", "Trait"]),
description: types.optional(types.string, "")
})
const Responsibility = types.model("Responsibility", {
title: types.string,
outcome: types.string,
requiredAttributes: types.array(Attribute)
})
const Role = types.model("Role", {
title: types.string,
responsibilities: types.array(Responsibility),
requiredAttributes: types.array(Attribute),
seniority: types.enumeration("Seniority", ["Intern", "Junior", "Mid", "Senior", "Lead", "Principal"])
})
// Specialization within a domain (e.g., cardiologist within medicine)
const Specialization = types.model("Specialization", {
name: types.string,
focus: types.string,
coreAttributes: types.array(Attribute),
roles: types.array(Role)
})
const Domain = types.model("Domain", {
name: types.string,
description: types.optional(types.string, ""),
specializations: types.array(Specialization),
coreAttributes: types.array(Attribute)
})
const ProfessionModel = types.model("ProfessionModel", {
domains: types.array(Domain)
});
export { ProfessionModel, Domain, Specialization, Role, Responsibility, Attribute }

194
lib/v2.ts Normal file
View File

@@ -0,0 +1,194 @@
// Profession Hierarchy Model using mobx-state-tree (MST)
// -----------------------------------------------------
// This file defines a generic, extensible hierarchy that captures the essence
// of professions. It intentionally separates concerns across six conceptual
// layers, from the broad Domain level down to atomic Tasks. Each layer owns
// its children through stronglytyped arrays, enabling finegrained reactivity,
// traversal, and manipulation.
//
// Layering
// ┌ Domain e.g. "STEM", "Arts", "Public Service"
// │ └ Industry e.g. "Software", "Healthcare", "Finance"
// │ └ Profession e.g. "Software Engineering", "Nursing"
// │ └ Field e.g. "Backend", "Pediatrics"
// │ └ Role e.g. "API Engineer", "Pediatric Nurse"
// │ └ Task e.g. "Design REST endpoints", "Administer vaccine"
//
// Each model exposes actions to mutate its children as well as compositional
// views to rapidly surface nested information (e.g., all tasks under an
// Industry). Identifiers are UUIDv4 strings to guarantee uniqueness across
// distributed systems.
// -----------------------------------------------------
import { types, Instance, SnapshotIn, getParent, destroy } from "mobx-state-tree";
import { v4 as uuidv4 } from "uuid";
/* Utility --------------------------------------------------------------- */
const withId = <T extends Record<string, unknown>>(modelName: string, definition: T) =>
types.model(modelName, {
id: types.optional(types.identifier, uuidv4),
...definition
});
/* Task ------------------------------------------------------------------ */
export const TaskModel = withId("Task", {
name: types.string,
description: types.maybe(types.string)
})
.actions(self => ({
update(attrs: Partial<SnapshotIn<typeof TaskModel>>) {
Object.assign(self, attrs);
},
remove() {
destroy(self);
}
}));
export interface Task extends Instance<typeof TaskModel> {}
/* Role ------------------------------------------------------------------ */
export const RoleModel = withId("Role", {
title: types.string,
summary: types.maybe(types.string),
tasks: types.optional(types.array(TaskModel), [])
})
.actions(self => ({
addTask(task: SnapshotIn<typeof TaskModel>) {
self.tasks.push(TaskModel.create(task));
},
removeTask(task: Task) {
self.tasks.remove(task);
},
remove() {
destroy(self);
}
}))
.views(self => ({
get allTasks() {
return self.tasks.slice();
}
}));
export interface Role extends Instance<typeof RoleModel> {}
/* Field (Specialization) ------------------------------------------------- */
export const FieldModel = withId("Field", {
name: types.string,
description: types.maybe(types.string),
roles: types.optional(types.array(RoleModel), [])
})
.actions(self => ({
addRole(role: SnapshotIn<typeof RoleModel>) {
self.roles.push(RoleModel.create(role));
},
removeRole(role: Role) {
self.roles.remove(role);
},
remove() {
destroy(self);
}
}))
.views(self => ({
get allTasks() {
return self.roles.flatMap(r => r.allTasks);
}
}));
export interface Field extends Instance<typeof FieldModel> {}
/* Profession ------------------------------------------------------------ */
export const ProfessionModel = withId("Profession", {
name: types.string,
description: types.maybe(types.string),
fields: types.optional(types.array(FieldModel), [])
})
.actions(self => ({
addField(field: SnapshotIn<typeof FieldModel>) {
self.fields.push(FieldModel.create(field));
},
removeField(field: Field) {
self.fields.remove(field);
},
remove() {
destroy(self);
}
}))
.views(self => ({
get allTasks() {
return self.fields.flatMap(f => f.allTasks);
}
}));
export interface Profession extends Instance<typeof ProfessionModel> {}
/* Industry -------------------------------------------------------------- */
export const IndustryModel = withId("Industry", {
name: types.string,
description: types.maybe(types.string),
professions: types.optional(types.array(ProfessionModel), [])
})
.actions(self => ({
addProfession(prof: SnapshotIn<typeof ProfessionModel>) {
self.professions.push(ProfessionModel.create(prof));
},
removeProfession(prof: Profession) {
self.professions.remove(prof);
},
remove() {
destroy(self);
}
}))
.views(self => ({
get allTasks() {
return self.professions.flatMap(p => p.allTasks);
}
}));
export interface Industry extends Instance<typeof IndustryModel> {}
/* Domain ---------------------------------------------------------------- */
export const DomainModel = withId("Domain", {
name: types.string,
description: types.maybe(types.string),
industries: types.optional(types.array(IndustryModel), [])
})
.actions(self => ({
addIndustry(ind: SnapshotIn<typeof IndustryModel>) {
self.industries.push(IndustryModel.create(ind));
},
removeIndustry(ind: Industry) {
self.industries.remove(ind);
},
remove() {
destroy(self);
}
}))
.views(self => ({
get allTasks() {
return self.industries.flatMap(i => i.allTasks);
}
}));
export interface Domain extends Instance<typeof DomainModel> {}
/* Enterprise ------------------------------------------------------------- */
export const Enterprise = types
.model("Enterprise", {
domains: types.optional(types.array(DomainModel), [])
})
.actions(self => ({
addDomain(domain: SnapshotIn<typeof DomainModel>) {
self.domains.push(DomainModel.create(domain));
}
}))
.views(self => ({
// Convenience: get a flat list of everything
get allTasks() {
return self.domains.flatMap(d => d.allTasks);
}
}));
export interface IRootStore extends Instance<typeof Enterprise> {}
/* Example usage --------------------------------------------------------- */
// const store = Enterprise.create({});
// store.addDomain({ name: "STEM" });
// store.domains[0].addIndustry({ name: "Software" });
// store.domains[0].industries[0].addProfession({ name: "Software Engineering" });
// store.domains[0].industries[0].professions[0].addField({ name: "Backend" });
// store.domains[0].industries[0].professions[0].fields[0].addRole({ title: "API Engineer" });
// store.domains[0].industries[0].professions[0].fields[0].roles[0].addTask({ name: "Design REST endpoints" });
// console.log(store.allTasks.map(t => t.name)); // → ["Design REST endpoints"]

View File

@@ -0,0 +1,30 @@
{
"version": "v1",
"domain": "Finance",
"structure": [
"Retail Banking",
"Commercial Banking",
"Investment Banking",
"Private Banking"
],
"description": "A hierarchy of functions and services within the banking sector, focusing on various banking operations.",
"commonSkills": [
"Financial Analysis",
"Risk Management",
"Customer Relationship Management",
"Regulatory Compliance",
"Loan Processing"
],
"commonTools": [
"Financial Modeling Software",
"Customer Relationship Management (CRM) Systems",
"Investment Analysis Tools",
"Risk Assessment Software"
],
"examples": [
"Personal loans in Retail Banking",
"Small business loans in Commercial Banking",
"Mergers and Acquisitions in Investment Banking",
"Wealth management in Private Banking"
]
}

View File

@@ -0,0 +1,80 @@
/**
* finance Professional Hierarchy Example
* Generated using OpenAI Agents SDK and Sumpin Professional Hierarchy Models
* Model Version: v2 (6-layer hierarchy)
* Generated on: 2025-07-11T20:02:03.514Z
*/
import {
Enterprise,
DomainModel, IndustryModel, ProfessionModel, FieldModel, RoleModel, TaskModel
} from "../../lib/v2";
import { Enterprise, DomainModel, IndustryModel, ProfessionModel, FieldModel, RoleModel, TaskModel } from "../../lib/v2";
const financeDomain = new DomainModel({
name: "Finance",
industries: [
new IndustryModel({
name: "Investment Banking",
professions: [
new ProfessionModel({
name: "Investment Banker",
fields: [
new FieldModel({
name: "Corporate Finance",
roles: [
new RoleModel({
name: "Analyst",
tasks: [
new TaskModel({
name: "Financial Modeling",
skills: ["Excel", "Financial Analysis"],
tools: ["Excel", "Bloomberg Terminal"],
example: "Building a discounted cash flow model for a merger."
}),
new TaskModel({
name: "Market Research",
skills: ["Data Analysis", "Presentation Skills"],
tools: ["PitchBook", "Excel"],
example: "Analyzing competitor performance for a potential acquisition."
})
]
}),
new RoleModel({
name: "Associate",
tasks: [
new TaskModel({
name: "Deal Execution",
skills: ["Negotiation", "Project Management"],
tools: ["MS Project", "Deal Management Software"],
example: "Leading a team to close a multi-million dollar equity issuance."
})
]
})
]
})
]
})
]
})
]
});
// Basic operations
const readRoleTasks = (roleName: string) => {
const role = financeDomain.industries[0].professions[0].fields[0].roles.find(r => r.name === roleName);
return role ? role.tasks : [];
};
const updateTaskSkill = (roleName: string, taskName: string, newSkills: string[]) => {
const role = financeDomain.industries[0].professions[0].fields[0].roles.find(r => r.name === roleName);
const task = role?.tasks.find(t => t.name === taskName);
if (task) {
task.skills = newSkills;
}
};
// Example usages
const analystTasks = readRoleTasks("Analyst");
updateTaskSkill("Analyst", "Financial Modeling", ["Advanced Excel", "Financial Forecasting"]);

View File

@@ -0,0 +1,142 @@
/**
* healthcare Professional Hierarchy Example
* Generated using OpenAI Agents SDK and Sumpin Professional Hierarchy Models
* Model Version: v2 (6-layer hierarchy)
* Generated on: 2025-07-11T20:01:29.107Z
*/
import {
Enterprise,
DomainModel, IndustryModel, ProfessionModel, FieldModel, RoleModel, TaskModel
} from "../../lib/v2";
import { Enterprise, DomainModel, IndustryModel, ProfessionModel, FieldModel, RoleModel, TaskModel } from "../../lib/v2";
const healthcareDomain = new DomainModel({
name: "Healthcare",
industries: [
new IndustryModel({
name: "Medical Services",
professions: [
new ProfessionModel({
name: "Nursing",
fields: [
new FieldModel({
name: "Clinical Nursing",
roles: [
new RoleModel({
name: "Registered Nurse",
competencies: [
"Patient assessment",
"Medication administration",
"Care planning"
],
tools: [
"Electronic Health Records (EHR)",
"Vital signs monitors",
"Infusion pumps"
],
tasks: [
new TaskModel({
name: "Patient Monitoring",
description: "Monitoring patient vitals and documenting changes.",
examples: [
"Using EHR to log vital signs every hour.",
"Adjusting care plan based on patient observations."
]
}),
new TaskModel({
name: "Medication Management",
description: "Administering and managing patient medications.",
examples: [
"Preparing and administering IV medications.",
"Educating patients on prescribed medications."
]
})
]
})
]
}),
new FieldModel({
name: "Nurse Practitioner",
roles: [
new RoleModel({
name: "Family Nurse Practitioner",
competencies: [
"Advanced patient assessment",
"Diagnosis and treatment planning",
"Patient education"
],
tools: [
"Diagnostic tools (stethoscope, otoscope)",
"Telehealth platform",
"Prescription software"
],
tasks: [
new TaskModel({
name: "Conducting Physical Exams",
description: "Performing comprehensive assessments for patients.",
examples: [
"Utilizing telehealth for remote consultations.",
"Documenting findings and recommending treatments."
]
}),
new TaskModel({
name: "Health Promotion",
description: "Educating families about preventive care.",
examples: [
"Organizing community health seminars.",
"Providing personalized health advice to families."
]
})
]
})
]
})
]
}),
new ProfessionModel({
name: "Healthcare Administration",
fields: [
new FieldModel({
name: "Hospital Administration",
roles: [
new RoleModel({
name: "Healthcare Administrator",
competencies: [
"Operations management",
"Compliance and regulations",
"Financial planning"
],
tools: [
"Healthcare management software",
"Data analytics tools",
"Budgeting tools"
],
tasks: [
new TaskModel({
name: "Budgeting and Financial Oversight",
description: "Managing hospital budgets and financial resources.",
examples: [
"Creating annual budgets based on service demand.",
"Reviewing financial performance reports."
]
}),
new TaskModel({
name: "Quality Improvement Initiatives",
description: "Implementing strategies to improve healthcare delivery.",
examples: [
"Conducting patient satisfaction surveys.",
"Analyzing workflow for efficiency."
]
})
]
})
]
})
]
})
]
})
]
});
export default healthcareDomain;

View File

@@ -0,0 +1,31 @@
{
"version": "v1",
"domain": "Technology",
"structure": [
"Front-end",
"Back-end",
"Database",
"DevOps"
],
"description": "A hierarchy outlining the main components and roles involved in web development.",
"commonSkills": [
"HTML/CSS",
"JavaScript",
"Responsive Design",
"Backend Programming",
"Database Management"
],
"commonTools": [
"Visual Studio Code",
"Git",
"Postman",
"Node.js",
"MySQL"
],
"examples": [
"Building a static website",
"Creating a dynamic web application",
"Developing APIs",
"Implementing user authentication"
]
}

27
package.json Normal file
View File

@@ -0,0 +1,27 @@
{
"name": "sumpin",
"module": "index.ts",
"type": "module",
"devDependencies": {
"@types/bun": "latest",
"@types/uuid": "^10.0.0"
},
"scripts": {
"start": "bun ./index.ts",
"cli": "bun ./cli.ts",
"sumpin": "bun ./cli.ts",
"generate": "bun ./cli.ts",
"demo": "bun ./index.ts"
},
"peerDependencies": {
"typescript": "^5.0.0"
},
"dependencies": {
"@openai/agents": "^0.0.11",
"mobx": "^6.13.7",
"mobx-state-tree": "^7.0.2",
"openai": "^5.9.0",
"uuid": "^11.1.0",
"zod": "<=3.25.67"
}
}

3
src/main.rs Normal file
View File

@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

32
tsconfig.json Normal file
View File

@@ -0,0 +1,32 @@
{
"compilerOptions": {
// Enable latest features
"lib": ["ESNext", "DOM"],
"target": "ESNext",
"module": "ESNext",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
// Bundler mode
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false
},
"include": [
"*.ts",
"lib/**/*",
"examples/**/*"
]
}