VectorDiff
 
package.json
{   "name": "@vectordiff/core",   "version": "1.0.0",   "description": "Lightweight format",   "main": "dist/index.js",   "types": "dist/index.d.ts",   "license": "AGPL-3.0",   "author": "Sławomir Wiśniewski",   "repository": {     "type": "git",     "url": "https://github.com/SlawomirWisniewski73/VectorDiff.git"   },   "scripts": {     "build": "tsc",     "test": "jest",     "dev": "tsc --watch",     "prepublishOnly": "npm run build"   },   "files": ["dist"],   "keywords": ["animation", "svg", "vector", "differential", "ai"],   "devDependencies": {     "typescript": "^5.2.2",     "jest": "^29.7.0",     "@types/jest": "^29.5.5",     "ts-jest": "^29.1.1"   } }  
tsconfig.json
{   "compilerOptions": {     "target": "ES2020",     "module": "commonjs",     "lib": ["ES2020"],     "outDir": "./dist",     "rootDir": "./src",     "strict": true,     "esModuleInterop": true,     "skipLibCheck": true,     "forceConsistentCasingInFileNames": true,     "declaration": true,     "declarationMap": true,     "sourceMap": true   },   "include": ["src/**/*"],   "exclude": ["node_modules", "dist", "tests"] }  
src/types.ts - Podstawowe Typy
/**  * Podstawowe typy dla formatu VectorDiff  */  export interface VectorDiffAnimation {   version: string;   metadata: AnimationMetadata;   canvas: Canvas;   objects: VectorObject[];   timeline: Keyframe[]; }  export interface AnimationMetadata {   title?: string;   author?: string;   description?: string;   duration: number; // ms   createdAt: string;   fps?: number; }  export interface Canvas {   width: number;   height: number;   backgroundColor?: string; }  export interface VectorObject {   id: string;   type: ObjectType;   properties: ObjectProperties;   style: ObjectStyle; }  export type ObjectType = 'rect' | 'circle' | 'ellipse' | 'path' | 'text' | 'group';  export interface ObjectProperties {   [key: string]: any; }  export interface ObjectStyle {   fill?: string;   stroke?: string;   strokeWidth?: number;   opacity?: number;   [key: string]: any; }  export interface Keyframe {   time: number; // ms   changes: ObjectChange[]; }  export interface ObjectChange {   objectId: string;   transform: Transform; }  export interface Transform {   type: TransformType;   [key: string]: any; }  export type TransformType = 'translate' | 'rotate' | 'scale' | 'opacity';  export interface TranslateTransform extends Transform {   type: 'translate';   x: number;   y: number; }  export interface RotateTransform extends Transform {   type: 'rotate';   angle: number; // degrees   centerX?: number;   centerY?: number; }  export interface ScaleTransform extends Transform {   type: 'scale';   scaleX: number;   scaleY: number;   centerX?: number;   centerY?: number; }  export interface OpacityTransform extends Transform {   type: 'opacity';   opacity: number; // 0-1 }  
src/animation.ts - Główna Klasa Animacji
import { VectorDiffAnimation, AnimationMetadata, Canvas } from './types'; import { generateId } from './utils';  export class Animation {   private data: VectorDiffAnimation;    constructor(width: number, height: number, metadata?: Partial<AnimationMetadata>) {     this.data = {       version: '1.0.0',       metadata: {         duration: 0,         createdAt: new Date().toISOString(),         fps: 60,         ...metadata       },       canvas: {         width,         height       },       objects: [],       timeline: []     };   }    // Gettery   get width(): number { return this.data.canvas.width; }   get height(): number { return this.data.canvas.height; }   get duration(): number { return this.data.metadata.duration; }   get objects() { return this.data.objects; }   get timeline() { return this.data.timeline; }    // Settery     setCanvas(width: number, height: number, backgroundColor?: string): void {     this.data.canvas = { width, height, backgroundColor };   }    setDuration(duration: number): void {     this.data.metadata.duration = duration;   }    // Eksport/Import   toJSON(): string {     return JSON.stringify(this.data, null, 2);   }    static fromJSON(json: string): Animation {     const data = JSON.parse(json) as VectorDiffAnimation;     const animation = new Animation(data.canvas.width, data.canvas.height);     animation.data = data;     return animation;   }    // Walidacja   validate(): { valid: boolean; errors: string[] } {     const errors: string[] = [];      if (this.data.canvas.width <= 0) {       errors.push('Canvas width must be positive');     }          if (this.data.canvas.height <= 0) {       errors.push('Canvas height must be positive');     }      // Sprawdź unikalne ID obiektów     const ids = new Set<string>();     for (const obj of this.data.objects) {       if (ids.has(obj.id)) {         errors.push(`Duplicate object ID: ${obj.id}`);       }       ids.add(obj.id);     }      // Sprawdź timeline     for (const keyframe of this.data.timeline) {       if (keyframe.time < 0) {         errors.push(`Invalid keyframe time: ${keyframe.time}`);       }              for (const change of keyframe.changes) {         if (!ids.has(change.objectId)) {           errors.push(`Keyframe references non-existent object: ${change.objectId}`);         }       }     }      return {       valid: errors.length === 0,       errors     };   }    // Klonowanie   clone(): Animation {     return Animation.fromJSON(this.toJSON());   } }  
src/objects.ts - Zarządzanie Obiektami
import { VectorObject, ObjectType, ObjectProperties, ObjectStyle } from './types'; import { Animation } from './animation'; import { generateId } from './utils';  export class ObjectManager {   constructor(private animation: Animation) {}    // Prostokąt   addRectangle(x: number, y: number, width: number, height: number, style: ObjectStyle = {}): string {     const id = generateId();     const rect: VectorObject = {       id,       type: 'rect',       properties: { x, y, width, height },       style: { fill: '#000000', ...style }     };          this.animation.objects.push(rect);     return id;   }    // Koło   addCircle(cx: number, cy: number, radius: number, style: ObjectStyle = {}): string {     const id = generateId();     const circle: VectorObject = {       id,       type: 'circle',        properties: { cx, cy, radius },       style: { fill: '#000000', ...style }     };          this.animation.objects.push(circle);     return id;   }    // Elipsa   addEllipse(cx: number, cy: number, rx: number, ry: number, style: ObjectStyle = {}): string {     const id = generateId();     const ellipse: VectorObject = {       id,       type: 'ellipse',       properties: { cx, cy, rx, ry },       style: { fill: '#000000', ...style }     };          this.animation.objects.push(ellipse);     return id;   }    // Ścieżka SVG   addPath(d: string, style: ObjectStyle = {}): string {     const id = generateId();     const path: VectorObject = {       id,       type: 'path',       properties: { d },       style: { fill: 'none', stroke: '#000000', ...style }     };          this.animation.objects.push(path);     return id;   }    // Tekst   addText(text: string, x: number, y: number, style: ObjectStyle = {}): string {     const id = generateId();     const textObj: VectorObject = {       id,       type: 'text',       properties: { text, x, y },       style: {          fill: '#000000',          fontSize: '16px',         fontFamily: 'Arial, sans-serif',         ...style        }     };          this.animation.objects.push(textObj);     return id;   }    // Grupa   addGroup(objectIds: string[], style: ObjectStyle = {}): string {     const id = generateId();     const group: VectorObject = {       id,       type: 'group',       properties: { children: objectIds },       style     };          this.animation.objects.push(group);     return id;   }    // Usuń obiekt   removeObject(id: string): boolean {     const index = this.animation.objects.findIndex(obj => obj.id === id);     if (index >= 0) {       this.animation.objects.splice(index, 1);       return true;     }     return false;   }    // Znajdź obiekt   getObject(id: string): VectorObject | undefined {     return this.animation.objects.find(obj => obj.id === id);   }    // Aktualizuj właściwości   updateProperties(id: string, properties: Partial<ObjectProperties>): boolean {     const obj = this.getObject(id);     if (obj) {       Object.assign(obj.properties, properties);       return true;     }     return false;   }    // Aktualizuj style   updateStyle(id: string, style: Partial<ObjectStyle>): boolean {     const obj = this.getObject(id);     if (obj) {       Object.assign(obj.style, style);       return true;     }     return false;   } }  
src/transforms.ts - System Transformacji
import { Animation } from './animation'; import { Transform, Keyframe, ObjectChange, TransformType } from './types';  export class TransformManager {   constructor(private animation: Animation) {}    // Dodaj transformację   addTransform(objectId: string, time: number, transform: Transform): void {     // Sprawdź czy obiekt istnieje     const obj = this.animation.objects.find(o => o.id === objectId);     if (!obj) {       throw new Error(`Object with ID ${objectId} not found`);     }      // Znajdź lub utwórz keyframe     let keyframe = this.animation.timeline.find(kf => kf.time === time);     if (!keyframe) {       keyframe = { time, changes: [] };       this.animation.timeline.push(keyframe);       // Sortuj timeline według czasu       this.animation.timeline.sort((a, b) => a.time - b.time);     }      // Znajdź lub utwórz zmianę dla obiektu     let change = keyframe.changes.find(ch => ch.objectId === objectId);     if (!change) {       change = { objectId, transform };       keyframe.changes.push(change);     } else {       change.transform = transform;     }      // Aktualizuj czas trwania animacji     if (time > this.animation.duration) {       this.animation.setDuration(time);     }   }    // Przesunięcie   addTranslation(objectId: string, time: number, x: number, y: number): void {     this.addTransform(objectId, time, {       type: 'translate',       x, y     });   }    // Obrót   addRotation(objectId: string, time: number, angle: number, centerX?: number, centerY?: number): void {     this.addTransform(objectId, time, {       type: 'rotate',       angle,       centerX,       centerY     });   }    // Skalowanie   addScale(objectId: string, time: number, scaleX: number, scaleY: number, centerX?: number, centerY?: number): void {     this.addTransform(objectId, time, {       type: 'scale',       scaleX,       scaleY,       centerX,       centerY     });   }    // Przezroczystość   addOpacity(objectId: string, time: number, opacity: number): void {     this.addTransform(objectId, time, {       type: 'opacity',       opacity: Math.max(0, Math.min(1, opacity))     });   }    // Usuń transformację   removeTransform(objectId: string, time: number): boolean {     const keyframe = this.animation.timeline.find(kf => kf.time === time);     if (keyframe) {       const index = keyframe.changes.findIndex(ch => ch.objectId === objectId);       if (index >= 0) {         keyframe.changes.splice(index, 1);                  // Usuń pusty keyframe         if (keyframe.changes.length === 0) {           const kfIndex = this.animation.timeline.indexOf(keyframe);           this.animation.timeline.splice(kfIndex, 1);         }                  return true;       }     }     return false;   }    // Pobierz wszystkie transformacje dla obiektu   getTransforms(objectId: string): { time: number; transform: Transform }[] {     const transforms: { time: number; transform: Transform }[] = [];          for (const keyframe of this.animation.timeline) {       const change = keyframe.changes.find(ch => ch.objectId === objectId);       if (change) {         transforms.push({           time: keyframe.time,           transform: change.transform         });       }     }          return transforms.sort((a, b) => a.time - b.time);   }    // Wyczyść wszystkie transformacje   clear(): void {     this.animation.timeline.splice(0);     this.animation.setDuration(0);   } }  
src/utils.ts - Funkcje Pomocnicze
let idCounter = 0;  export function generateId(): string {   return `obj_${++idCounter}`; }  export function resetIdCounter(): void {   idCounter = 0; }  export function clamp(value: number, min: number, max: number): number {   return Math.min(Math.max(value, min), max); }  export function lerp(start: number, end: number, t: number): number {   return start + (end - start) * t; }  export function degToRad(degrees: number): number {   return degrees * Math.PI / 180; }  export function radToDeg(radians: number): number {   return radians * 180 / Math.PI; }  // Walidacja kolorów export function isValidColor(color: string): boolean {   const colorRegex = /^#([0-9A-Fa-f]{3}){1,2}$|^rgb\(|^rgba\(|^hsl\(|^hsla\(/;   return colorRegex.test(color); }  // Parsing prostych transformacji SVG export function parseTransform(transformString: string): Transform[] {   const transforms: Transform[] = [];   const regex = /(\w+)\s*\(([^)]*)\)/g;   let match;      while ((match = regex.exec(transformString)) !== null) {     const [, type, params] = match;     const values = params.split(/[\s,]+/).map(Number);          switch (type.toLowerCase()) {       case 'translate':         transforms.push({           type: 'translate',           x: values[^0] || 0,           y: values[^1] || 0         });         break;                case 'rotate':         transforms.push({           type: 'rotate',           angle: values[^0] || 0,           centerX: values[^1],           centerY: values[^2]         });         break;                case 'scale':         transforms.push({           type: 'scale',           scaleX: values[^0] || 1,           scaleY: values[^1] || values[^0] || 1         });         break;     }   }      return transforms; }  
src/index.ts - Główny Plik API
/**  * VectorDiff Core - Główne API  * Licencja: AGPL-3.0  */  // Główne klasy export { Animation } from './animation'; export { ObjectManager } from './objects'; export { TransformManager } from './transforms';  // Typy export * from './types';  // Utilities export * from './utils';  // Wysokopoziomowe API export function createAnimation(width: number, height: number, title?: string): Animation {   const animation = new Animation(width, height, { title });   return animation; }  export function createSimpleExample(): Animation {   const animation = createAnimation(800, 600, 'VectorDiff Example');   const objects = new ObjectManager(animation);   const transforms = new TransformManager(animation);      // Dodaj prostokąt   const rectId = objects.addRectangle(100, 100, 200, 100, {     fill: '#FF6B6B',     stroke: '#333333',     strokeWidth: 2   });      // Dodaj koło   const circleId = objects.addCircle(400, 300, 50, {     fill: '#4ECDC4'   });      // Animuj prostokąt   transforms.addTranslation(rectId, 1000, 300, 0);   transforms.addRotation(rectId, 2000, 45);      // Animuj koło   transforms.addScale(circleId, 1500, 1.5, 1.5, 400, 300);      animation.setDuration(2000);   return animation; }  // Wersja biblioteki export const VERSION = '1.0.0';  
examples/basic-usage.ts
import { createAnimation, ObjectManager, TransformManager } from '../src';  // Utwórz animację const animation = createAnimation(800, 600, 'Moja Pierwsza Animacja');  // Managery const objects = new ObjectManager(animation); const transforms = new TransformManager(animation);  // Dodaj obiekty const rectId = objects.addRectangle(100, 100, 200, 150, {   fill: '#FF0000',   stroke: '#000000',   strokeWidth: 2 });  const circleId = objects.addCircle(400, 300, 60, {   fill: '#0000FF',   opacity: 0.8 });  const textId = objects.addText('VectorDiff', 350, 450, {   fontSize: '24px',   fill: '#333333' });  // Dodaj animacje transforms.addTranslation(rectId, 1000, 200, 0); transforms.addRotation(circleId, 1500, 180, 400, 300); transforms.addOpacity(textId, 2000, 0.3);  // Ustaw czas trwania animation.setDuration(2000);  // Wyeksportuj console.log(animation.toJSON());  
tests/core.test.ts
import { Animation, ObjectManager, TransformManager } from '../src';  describe('VectorDiff Core', () => {   test('should create animation', () => {     const animation = new Animation(800, 600);     expect(animation.width).toBe(800);     expect(animation.height).toBe(600);   });    test('should add objects', () => {     const animation = new Animation(800, 600);     const objects = new ObjectManager(animation);          const rectId = objects.addRectangle(0, 0, 100, 100);     expect(animation.objects).toHaveLength(1);     expect(animation.objects[^0].id).toBe(rectId);   });    test('should add transforms', () => {     const animation = new Animation(800, 600);     const objects = new ObjectManager(animation);     const transforms = new TransformManager(animation);          const rectId = objects.addRectangle(0, 0, 100, 100);     transforms.addTranslation(rectId, 1000, 50, 50);          expect(animation.timeline).toHaveLength(1);     expect(animation.timeline[^0].time).toBe(1000);     expect(animation.duration).toBe(1000);   });    test('should validate animation', () => {     const animation = new Animation(800, 600);     const result = animation.validate();     expect(result.valid).toBe(true);     expect(result.errors).toHaveLength(0);   });    test('should export/import JSON', () => {     const animation = new Animation(800, 600);     const objects = new ObjectManager(animation);          objects.addRectangle(100, 100, 200, 100);          const json = animation.toJSON();     const imported = Animation.fromJSON(json);          expect(imported.width).toBe(800);     expect(imported.objects).toHaveLength(1);   }); });  

SentioDiff
package.json
 
{   "name": "sentio-diff",   "version": "0.1.0",   "description": "SentioDiff – biblioteka do wizualizacji ro\u017cnic danych i introspekcji",   "license": "MIT",   "type": "module",   "main": "dist/sentio-core/src/index.js",   "bin": {     "sentio-validate": "dist/scripts/sentio-validate.js",     "sentio-render": "dist/scripts/sentio-render.js",     "sentio-to-vector": "dist/scripts/sentio-to-vector.js"   },   "scripts": {     "build": "tsc",     "prepare": "npm run build",     "test": "echo \"No tests specified\" && exit 0",     "validate": "npm run build && node dist/scripts/sentio-validate.js examples/basic_example.json && node dist/scripts/sentio-validate.js examples/introspection_demo.json"   },   "dependencies": {     "ajv": "^8.12.0"   },   "devDependencies": {     "typescript": "^5.1.0",     "react": "^18.2.0",     "@types/react": "^18.0.28"   } }
 
tsconfig.json
 
{   "compilerOptions": {     "target": "ES2020",     "module": "ESNext",     "moduleResolution": "node",     "outDir": "dist",     "rootDir": ".",     "esModuleInterop": true,     "resolveJsonModule": true,     "jsx": "react",     "baseUrl": ".",     "paths": {       "sentio-core/*": ["sentio-core/src/*"],       "sentio-viz/*": ["sentio-viz/src/*"],       "sentio-introspect/*": ["sentio-introspect/src/*"],       "sentio-bridge/*": ["sentio-bridge/src/*"]     }   },   "include": [     "sentio-core/src",     "sentio-viz/src",     "sentio-introspect/src",     "sentio-bridge/src",     "scripts"   ],   "exclude": [     "node_modules",     "dist",     "examples",     "docs"   ] }

 

.github/workflows/ci.yml
 
name: CI  on:   push:     branches: [ main ]   pull_request:  jobs:   build-test-validate:     runs-on: ubuntu-latest     steps:       - uses: actions/checkout@v3       - uses: actions/setup-node@v3         with:           node-version: 18       - run: npm install       - run: npm run build       - run: npm test       - run: npm run validate
 
Skrypty CLI (folder scripts/)
 
scripts/sentio-validate.ts
 
#!/usr/bin/env node  import { Validator } from '../sentio-core/src/validator'; import * as fs from 'fs';  const [inputPath] = process.argv.slice(2); if (!inputPath) {   console.error('Usage: sentio-validate <path_to_json_file>');   process.exit(1); }  try {   const fileContent = fs.readFileSync(inputPath, 'utf-8');   const data = JSON.parse(fileContent);   const validator = new Validator();   const valid = validator.validate(data);   if (valid) {     console.log('File is valid according to schema.');   } else {     console.error('Validation failed: data does not match schema.');     process.exit(2);   } } catch (err) {   console.error('Error reading or validating file:', err);   process.exit(3); }
 
scripts/sentio-render.ts
 
#!/usr/bin/env node  import { SvgRenderer } from '../sentio-viz/src/SvgRenderer'; import { ThreeRenderer } from '../sentio-viz/src/ThreeRenderer'; import * as fs from 'fs';  const [mode, inputPath] = process.argv.slice(2); if (!mode || !inputPath) {   console.error('Usage: sentio-render <svg|three> <path_to_input.json>');   process.exit(1); }  const data = JSON.parse(fs.readFileSync(inputPath, 'utf-8'));  if (mode === 'svg') {   const renderer = new SvgRenderer();   const svgContent = renderer.render(data);   fs.writeFileSync('output.svg', svgContent);   console.log('SVG rendering saved to output.svg'); } else if (mode === 'three') {   const renderer = new ThreeRenderer();   renderer.render(data);   console.log('3D rendering completed (see console or graphical output)'); } else {   console.error('Unknown mode. Use "svg" or "three".');   process.exit(2); }
 
scripts/sentio-to-vector.ts
 
#!/usr/bin/env node  import { toVector } from '../sentio-bridge/src/vectorDiffAdapter'; import * as fs from 'fs';  const [inputPath, outputPath] = process.argv.slice(2); if (!inputPath) {   console.error('Usage: sentio-to-vector <input.json> [output.txt]');   process.exit(1); }  const data = JSON.parse(fs.readFileSync(inputPath, 'utf-8')); const vector = toVector(data);  if (outputPath) {   fs.writeFileSync(outputPath, vector.join(','));   console.log(`Vector saved to ${outputPath}`); } else {   console.log('Vector:', JSON.stringify(vector)); }
 
Moduł sentio-core
sentio-core/src/types.ts
 
export interface Track {   id: string;   data: number[]; }  export interface Difference {   from: string;   to: string;   distance: number; }  export interface TraceEvent {   step: number;   action: string; }  export interface SelfModelSummary {   score: number;   description: string; }  export interface SentioData {   name?: string;   tracks: Track[];   differences?: Difference[];   trace?: TraceEvent[];   attention?: number[][];   selfModel?: SelfModelSummary; }
 
sentio-core/src/parser.ts
 
import { SentioData } from './types';  export function parse(input: unknown): SentioData {   // W rzeczywistej implementacji nastąpiłaby transformacja/normalizacja danych.   // Tutaj zakładamy, że input odpowiada już strukturze SentioData.   return input as SentioData; }
 
sentio-core/src/validator.ts
 
import Ajv from 'ajv'; import schema from '../../sentio.schema.json'; import { SentioData } from './types';  const ajv = new Ajv(); const validateFn = ajv.compile(schema);  export class Validator {   validate(data: unknown): data is SentioData {     const valid = validateFn(data);     return !!valid;   } }
 
sentio-core/src/index.ts
 
export * from './types'; export * from './parser'; export * from './validator';
 
Moduł sentio-viz
 
sentio-viz/src/SvgRenderer.ts
 
export class SvgRenderer {   render(data: any): string {     // Tworzy prosty obraz SVG (implementacja zast\u0119pcza)     const width = 200, height = 100;     return ` <svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}">   <rect width="100%" height="100%" fill="lightgray" />   <text x="10" y="20" fill="black">Rendered SVG</text> </svg>`;   } }
 
sentio-viz/src/ThreeRenderer.ts
 
export class ThreeRenderer {   render(data: any): void {     // Placeholder: w pe\u0142nej wersji wykorzysta\u0142by Three.js do renderu 3D     console.log('ThreeRenderer: 3D rendering not implemented in this skeleton.');   } }
 
sentio-viz/src/ReactTrackView.tsx
 
import React from 'react'; import { Track } from 'sentio-core/types';  interface Props {   tracks: Track[]; }  export const ReactTrackView: React.FC<Props> = ({ tracks }) => {   return (     <div>       <h3>Track View</h3>       <ul>         {tracks.map(track => (           <li key={track.id}>             {track.id}: {track.data.join(', ')}           </li>         ))}       </ul>     </div>   ); };
 
Moduł sentio-introspect
 
sentio-introspect/src/traceVisualizer.ts
 
import { SentioData } from 'sentio-core/types';  export function visualizeTrace(data: SentioData): void {   if (data.trace && data.trace.length > 0) {     const actions = data.trace.map(ev => ev.action).join(' -> ');     console.log('Trace sequence:', actions);   } else {     console.log('No trace data available.');   } }
 
sentio-introspect/src/attentionVisualizer.ts
 
import { SentioData } from 'sentio-core/types';  export function visualizeAttention(data: SentioData): void {   if (data.attention && data.attention.length > 0) {     const rows = data.attention.length;     const cols = data.attention[0].length;     console.log('Attention matrix size:', rows + 'x' + cols);   } else {     console.log('No attention data available.');   } }
 
sentio-introspect/src/selfModelView.ts
 
import { SentioData } from 'sentio-core/types';  export function getSelfModelSummary(data: SentioData): string {   if (data.selfModel) {     return 'Self model score: ' + data.selfModel.score +            ', description: ' + data.selfModel.description;   } else {     return 'No self model data.';   } }
 
Moduł sentio-bridge
 
sentio-bridge/src/vectorDiffAdapter.ts
 
import { SentioData } from 'sentio-core/types';  export function toVector(data: SentioData): number[] {   // \u0141\u0105czy wszystkie dane ze \u015bcie\u017cek w jeden wektor (przyk\u0142adowa implementacja)   const vectors: number[] = [];   for (const track of data.tracks) {     vectors.push(...track.data);   }   return vectors; }
 
sentio-bridge/src/csvImporter.ts
 
import * as fs from 'fs'; import { parse } from 'sentio-core/parser';  export function importCsv(filePath: string): any {   const content = fs.readFileSync(filePath, 'utf-8');   const lines = content.trim().split('\n');   // Prosty parser CSV: rozdzia\u0142 na kom\u00f3rki wg przecink\u00f3w   const dataRows = lines.map(line => line.split(',').map(val => val.trim()));   // Konwersja CSV -> SentioData (podej\u015bcie uproszczone)   const tracks = dataRows.map((row, idx) => ({     id: `row${idx}`,     data: row.map(Number).filter(n => !isNaN(n))   }));   return parse({ tracks }); }
 
sentio-bridge/src/index.ts
 
export * from './vectorDiffAdapter'; export * from './csvImporter';

ActioDiff
 
/main
 
Package.json
 
{
  "name": "actiodiff-monorepo",
  "version": "0.1.0",
  "private": true,
  "description": "A meta-language for describing, simulating, and analyzing multi-agent interactions and intent.",
  "workspaces": [
    "packages/*"
  ],
  "scripts": {
    "build": "tsc -b packages/actiodiff-core packages/actiodiff-protocols packages/actiodiff-planner packages/actiodiff-viz",
    "test": "npm run test -ws --if-present"
  },
  "devDependencies": {
    "typescript": "^5.3.0"
  },
  "license": "AGPL-3.0"
}

Tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "jsx": "react-jsx",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "composite": true,
    "declaration": true,
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "@actiodiff/core": ["packages/actiodiff-core/src"],
      "@actiodiff/protocols": ["packages/actiodiff-protocols/src"],
      "@actiodiff/planner": ["packages/actiodiff-planner/src"],
      "@actiodiff/viz": ["packages/actiodiff-viz/src"]
    }
  },
  "files": [],
  "references": [
    { "path": "packages/actiodiff-core" },
    { "path": "packages/actiodiff-protocols" },
    { "path": "packages/actiodiff-planner" },
    { "path": "packages/actiodiff-viz" }
  ]
}

/examples
{
  "version": "1.0-actio",
  "interaction": {
    "type": "negotiation",
    "protocol": "offer_counteroffer_accept_reject",
    "participants": [
      "ai_buyer_7",
      "ai_seller_4"
    ]
  },
  "agents": [
    {
      "id": "ai_buyer_7",
      "goalModel": {
        "objective": "acquire_item_X_at_minimum_cost",
        "constraints": [
          "max_budget: 85",
          "time_limit: 10_steps"
        ]
      },
      "sentioState": {
        "version": "0.1",
        "tracks": [],
        "introspection": {
          "selfModel": {
            "modelName": "BuyerBot 7",
            "version": "2.1",
            "selfAssessment": {
              "confidence": "high",
              "strategy": "start_low"
            }
          },
          "traces": [
            {
              "id": "decision_trace_buyer",
              "steps": [
                {
                  "step": 1,
                  "description": "Analyzing seller's initial offer of 100."
                },
                {
                  "step": 2,
                  "description": "Calculated counter-offer of 80 based on budget constraint and 'start_low' strategy."
                }
              ]
            }
          ]
        }
      }
    },
    {
      "id": "ai_seller_4",
      "goalModel": {
        "objective": "sell_item_X_at_maximum_profit",
        "constraints": [
          "min_price: 75"
        ]
      },
      "sentioState": {
        "version": "0.1",
        "tracks": [],
        "introspection": {
          "selfModel": {
            "modelName": "SellerBot 4",
            "version": "1.8",
            "selfAssessment": {
              "patience": "medium"
            }
          }
        }
      }
    }
  ],
  "timeline": [
    {
      "time": 1,
      "actorId": "ai_seller_4",
      "action": "offer",
      "payload": {
        "item": "item_X",
        "price": 100
      }
    },
    {
      "time": 2,
      "actorId": "ai_buyer_7",
      "action": "counter_offer",
      "payload": {
        "price": 80
      }
    },
    {
      "time": 3,
      "actorId": "ai_seller_4",
      "action": "accept",
      "payload": {}
    }
  ]
}
 
/packages
/packeges/actiodiff-core
 
Package.json
 
name  "@actiodiff/core"
version           "0.1.0"
description    "Core library for the ActioDiff multi-agent interaction format"
main   "dist/index.js"
types  "dist/index.d.ts"
scripts 
build   "tsc"
test     'echo "Error: no test specified" && exit 0'
dependencies          
@sentiodiff/core      "github:SlawomirWisniewski73/SentioDiff"
devDependencies   
typescript       "^5.3.0"
license           "AGPL-3.0"
 
tsconfig.json
{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "./dist",
    "rootDir": "./src"
  },
  "include": ["src/**/*"],
  "references": [
    // W przyszłości, jeśli SentioDiff będzie w tym samym monorepo:
    // { "path": "../sentiodiff-core" } 
  ]
}

 
/packeges/actiodiff-core/src
 
Index.ts
 
// Eksportujemy wszystkie nowo zdefiniowane typy
export * from './types.js';
 
// W przyszłości będziemy tu eksportować główne klasy, np. ActioDiff
// export { ActioDiff } from './ActioDiff.js';
 
Types.ts
// Importujemy poprawny, istniejący typ 'SentioData' z biblioteki SentioDiff
import { SentioData } from '@sentiodiff/core';
 
/**
 * Definiuje cele i ograniczenia agenta.
 */
export interface GoalModel {
  objective: string;
  constraints?: string[];
  utilityFunction?: string;
}
 
/**
 * Opisuje pojedynczego agenta w ramach interakcji.
 * Używamy teraz poprawnego typu 'SentioData' dla stanu agenta.
 */
export interface Agent {
  id: string;
  sentioState: SentioData;
  goalModel: GoalModel;
}
 
/**
 * Definiuje "zasady gry" dla interakcji.
 */
export interface Interaction {
  type: string;
  protocol: string;
  participants: string[];
}
 
/**
 * Pojedyncze zdarzenie na osi czasu interakcji.
 */
export interface TimelineEvent {
  time: number;
  actorId: string;
  action: string;
  payload?: Record<string, any>;
}
 
/**
 * Główna struktura dokumentu ActioDiff.
 */
export interface ActioDiffDocument {
  version: '1.0-actio';
  interaction: Interaction;
  agents: Agent[];
  timeline: TimelineEvent[];
  hypotheticalTimelines?: any[]; 
}

 
/packeges/actiodiff-planner
Package.json
            
name  "@actiodiff/planner"
version           "0.1.0"
description    "Prediction and hypothetical timeline generation for ActioDiff"
main   "dist/index.js"
types  "dist/index.d.ts"
scripts 
build   "tsc"
test     'echo "Error: no test specified" && exit 0'
dependencies          
@actiodiff/core         "^0.1.0"
@actiodiff/protocols "^0.1.0"
devDependencies   
typescript       "^5.3.0"
license           "AGPL-3.0"
 
Tsconfig.json
extends          "../../tsconfig.json"
compilerOptions      
outDir "./dist"
rootDir            "./src"
include           
0         "src/**/*"
references     
0         
path    "../actiodiff-core"
1         
path    "../actiodiff-protocols"

/packeges/actiodiff-planner/src
Index.ts
export * from './types.js';
export * from './planner.js';
 
Planner.ts
import { ActioDiffDocument } from '@actiodiff/core';
import { validateNegotiationEvent } from '@actiodiff/protocols';
import { HypotheticalTimeline, PredictedStep } from './types.js';
 
/**
 * Prosty planer, który generuje hipotetyczne scenariusze dla negocjacji.
 */
export class Planner {
  private doc: ActioDiffDocument;
 
  constructor(document: ActioDiffDocument) {
    // Sprawdzamy, czy dokument dotyczy negocjacji
    if (document.interaction.protocol !== 'offer_counteroffer_accept') {
      throw new Error('This planner currently only supports negotiation protocols.');
    }
    this.doc = document;
  }
 
  /**
   * Generuje możliwe plany dla danego agenta.
   * @param agentId ID agenta, dla którego tworzymy plan.
   * @returns Tablica hipotetycznych linii czasu.
   */
  generatePlans(agentId: string): HypotheticalTimeline[] {
    const agent = this.doc.agents.find(a => a.id === agentId);
    if (!agent) {
      throw new Error(`Agent with ID ${agentId} not found.`);
    }
 
    // Logika symulacji - tutaj byłaby zaawansowana analityka
    // My na razie tworzymy dwa proste, "zahardkodowane" scenariusze
 
    const aggressiveOffer: PredictedStep = {
      event: { time: this.doc.timeline.length + 1, actorId: agentId, action: 'offer', payload: { price: 50 } },
      outcome: 'rejected',
      probability: 0.8
    };
    
    const conservativeOffer: PredictedStep = {
      event: { time: this.doc.timeline.length + 1, actorId: agentId, action: 'offer', payload: { price: 90 } },
      outcome: 'accepted',
      probability: 0.7
    };
 
    const planA: HypotheticalTimeline = {
      id: 'plan_aggressive',
      description: 'Strategy: Aggressive low-ball offer',
      steps: [aggressiveOffer],
      overallProbability: 0.8
    };
    
    const planB: HypotheticalTimeline = {
      id: 'plan_conservative',
      description: 'Strategy: Conservative fair offer',
      steps: [conservativeOffer],
      overallProbability: 0.7
    };
 
    return [planA, planB];
  }
}

Types.ts
import { TimelineEvent } from '@actiodiff/core';
 
/**
 * Opisuje pojedynczy, przewidywany krok w przyszłości.
 */
export interface PredictedStep {
  event: TimelineEvent;
  outcome: string; // np. "accepted", "rejected"
  probability: number; // Prawdopodobieństwo wystąpienia (0-1)
}
 
/**
 * Reprezentuje kompletną, hipotetyczną linię czasu.
 */
export interface HypotheticalTimeline {
  id: string;
  description: string; // np. "Strategy: Aggressive Opening Offer"
  steps: PredictedStep[];
  overallProbability: number;
}

/packeges/actiodiff-protocols
Package.json
{
  "name": "@actiodiff/protocols",
  "version": "0.1.0",
  "description": "Standard interaction protocols for the ActioDiff framework",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "build": "tsc",
    "test": "echo \"Error: no test specified\" && exit 0"
  },
  "dependencies": {
    "@actiodiff/core": "^0.1.0"
  },
  "devDependencies": {
    "typescript": "^5.3.0"
  },
  "license": "AGPL-3.0"
}

Tsconfig.json
{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "./dist",
    "rootDir": "./src"
  },
  "include": ["src/**/*"],
  "references": [
    { "path": "../actiodiff-core" }
  ]
}

/packeges/actiodiff-protocols/src
Index.ts
// Eksportujemy typy i funkcje walidacyjne dla protokołu negocjacji
export * from './negotiation.js';
 
// W przyszłości można tu dodać eksporty dla innych protokołów
// export * from './collaboration.js';
// export * from './auction.js';

Negotiation.ts
import { TimelineEvent } from '@actiodiff/core';
 
/**
 * Definiuje strukturę danych dla protokołu negocjacji.
 */
export interface NegotiationPayload {
  price?: number;
  item?: string;
}
 
/**
 * Definiuje dozwolone akcje w ramach tego protokołu.
 */
export type NegotiationAction = 'offer' | 'counter_offer' | 'accept' | 'reject';
 
/**
 * Sprawdza, czy dane zdarzenie na osi czasu jest zgodne z protokołem negocjacji.
 * @param event Zdarzenie z osi czasu ActioDiff.
 * @returns True, jeśli zdarzenie jest poprawne.
 */
export function validateNegotiationEvent(event: TimelineEvent): boolean {
  const validActions: NegotiationAction[] = ['offer', 'counter_offer', 'accept', 'reject'];
  
  if (!validActions.includes(event.action as NegotiationAction)) {
    throw new Error(`Invalid action '${event.action}' for negotiation protocol.`);
  }
 
  if (event.action === 'offer' || event.action === 'counter_offer') {
    if (!event.payload || typeof event.payload.price !== 'number') {
      throw new Error(`'${event.action}' must include a numeric 'price' in payload.`);
    }
  }
 
  return true;
}

/packeges/actiodiff-viz
Package.json
{
  "name": "@actiodiff/viz",
  "version": "0.1.0",
  "description": "Visualization components for the ActioDiff framework",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "build": "tsc",
    "test": "echo \"Error: no test specified\" && exit 0"
  },
  "dependencies": {
    "@actiodiff/core": "^0.1.0",
    "@actiodiff/planner": "^0.1.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.0",
    "@types/react-dom": "^18.2.0",
    "typescript": "^5.3.0"
  },
  "license": "AGPL-3.0"
}
 
Tsconfig.json
{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "./dist",
    "rootDir": "./src",
    "jsx": "react-jsx"
  },
  "include": ["src/**/*"],
  "references": [
    { "path": "../actiodiff-core" },
    { "path": "../actiodiff-planner" }
  ]
}

/packeges/actiodiff-viz/src
ActioDiffRenderer.tsx
import React from 'react';
import { ActioDiffDocument, Agent } from '@actiodiff/core';
import { HypotheticalTimeline } from '@actiodiff/planner';
 
// Definicja właściwości, jakie przyjmuje nasz komponent
interface ActioDiffRendererProps {
  document: ActioDiffDocument;
  hypotheticalTimelines?: HypotheticalTimeline[];
}
 
// Style CSS dla czytelności (można je przenieść do osobnego pliku)
const styles: { [key: string]: React.CSSProperties } = {
  container: { display: 'flex', fontFamily: 'sans-serif', border: '1px solid #ccc', padding: '10px' },
  agentColumn: { flex: 1, borderRight: '1px solid #eee', padding: '0 10px' },
  timelineColumn: { flex: 2, padding: '0 10px' },
  header: { borderBottom: '1px solid #ccc', paddingBottom: '5px', marginBottom: '10px', fontWeight: 'bold' },
  goal: { background: '#e0f7fa', padding: '5px', borderRadius: '4px', fontSize: '0.9em', marginTop: '5px' },
  event: { border: '1px solid #ddd', padding: '8px', borderRadius: '4px', marginBottom: '8px', fontSize: '0.9em' },
  hypothetical: { border: '1px dashed #f9a825', padding: '8px', borderRadius: '4px', marginTop: '15px', background: '#fffde7' }
};
 
/**
 * Komponent React do wizualizacji dokumentu ActioDiff.
 */
export const ActioDiffRenderer: React.FC<ActioDiffRendererProps> = ({ document, hypotheticalTimelines }) => {
  return (
    <div style={styles.container}>
      {/* Kolumny dla każdego agenta */}
      {document.agents.map(agent => (
        <div key={agent.id} style={styles.agentColumn}>
          <div style={styles.header}>Agent: {agent.id}</div>
          <strong>Cel:</strong>
          <div style={styles.goal}>{agent.goalModel.objective}</div>
          {/* W tym miejscu można by renderować więcej szczegółów z agent.sentioState */}
        </div>
      ))}
 
      {/* Kolumna dla osi czasu */}
      <div style={styles.timelineColumn}>
        <div style={styles.header}>Oś Czasu Interakcji: {document.interaction.type}</div>
        {document.timeline.map((event, index) => (
          <div key={index} style={styles.event}>
            <strong>Czas: {event.time}</strong> | Aktor: {event.actorId} | Akcja: {event.action}
            {event.payload && <pre style={{ margin: '5px 0 0', background: '#f5f5f5', padding: '5px' }}>
              {JSON.stringify(event.payload)}
            </pre>}
          </div>
        ))}
 
        {/* Opcjonalna sekcja dla hipotetycznych przyszłości */}
        {hypotheticalTimelines && hypotheticalTimelines.length > 0 && (
          <div style={styles.hypothetical}>
            <div style={styles.header}>Hipotetyczne Plany</div>
            {hypotheticalTimelines.map(plan => (
              <div key={plan.id} style={{ marginBottom: '10px' }}>
                <strong>Plan: {plan.description}</strong> (Prawd. {plan.overallProbability})
                {plan.steps.map((step, idx) => (
                  <div key={idx} style={{ marginLeft: '15px', fontSize: '0.85em' }}>
                    ↳ Akcja: {step.event.action}, Przewidywany wynik: {step.outcome} (Prawd. {step.probability})
                  </div>
                ))}
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
};

Index.ts
export * from './ActioDiffRenderer.js';