mirror of
https://github.com/seemueller-io/sumpin.git
synced 2025-09-08 22:56:46 +00:00
add code
This commit is contained in:
115
lib/components/hierarchy-generator.ts
Normal file
115
lib/components/hierarchy-generator.ts
Normal 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;
|
278
lib/components/output-formatter.ts
Normal file
278
lib/components/output-formatter.ts
Normal 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;
|
81
lib/components/template-manager.ts
Normal file
81
lib/components/template-manager.ts
Normal 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;
|
9
lib/components/templates/v1-finance.ts
Normal file
9
lib/components/templates/v1-finance.ts
Normal 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']
|
||||
}
|
9
lib/components/templates/v1-tech.ts
Normal file
9
lib/components/templates/v1-tech.ts
Normal 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']
|
||||
}
|
9
lib/components/templates/v2-edu.ts
Normal file
9
lib/components/templates/v2-edu.ts
Normal 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']
|
||||
}
|
9
lib/components/templates/v2-healthcare.ts
Normal file
9
lib/components/templates/v2-healthcare.ts
Normal 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']
|
||||
}
|
9
lib/components/templates/v2-tech.ts
Normal file
9
lib/components/templates/v2-tech.ts
Normal 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']
|
||||
}
|
Reference in New Issue
Block a user