tractatus/docs/api/examples-javascript.md
TheFlow 8cb075bce1 feat: add comprehensive JavaScript and Python code examples
- Created examples-javascript.md (20KB, 638 lines)
  - Authentication, Documents, Governance, Audit examples
  - Node.js and browser implementations
  - Complete TractatusClient class
  - Error handling and retry logic
  - Rate limiting documentation

- Created examples-python.md (30KB, 983 lines)
  - Authentication, Documents, Governance, Audit examples
  - Type hints and data classes
  - Complete TractatusClient class
  - Error handling decorators and retry logic
  - Rate limiting documentation

- Updated api-reference.html with code examples links
- All examples deployed to production

Task 12 (API Documentation) - Code examples complete
2025-10-12 11:13:55 +13:00

20 KiB
Raw Permalink Blame History

JavaScript API Examples

Complete examples for integrating with the Tractatus Framework API using JavaScript (Node.js and Browser).

Table of Contents


Authentication

Login and Store Token (Node.js)

const axios = require('axios');

const API_BASE = 'https://agenticgovernance.digital/api';
// For local development: const API_BASE = 'http://localhost:9000/api';

async function login(email, password) {
  try {
    const response = await axios.post(`${API_BASE}/auth/login`, {
      email,
      password
    });

    const { token, user } = response.data;

    // Store token for subsequent requests
    process.env.TRACTATUS_TOKEN = token;

    console.log('Login successful:', user);
    return { token, user };
  } catch (error) {
    if (error.response?.status === 429) {
      console.error('Too many login attempts. Please wait 15 minutes.');
    } else if (error.response?.status === 401) {
      console.error('Invalid credentials');
    } else {
      console.error('Login failed:', error.message);
    }
    throw error;
  }
}

// Usage
login('admin@tractatus.local', 'your_password')
  .then(({ token }) => {
    console.log('Token:', token);
  });

Login and Store Token (Browser)

async function login(email, password) {
  try {
    const response = await fetch('https://agenticgovernance.digital/api/auth/login', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ email, password })
    });

    if (!response.ok) {
      if (response.status === 429) {
        throw new Error('Too many login attempts. Please wait 15 minutes.');
      }
      throw new Error('Login failed');
    }

    const { token, user } = await response.json();

    // Store token in localStorage
    localStorage.setItem('tractatus_token', token);
    localStorage.setItem('tractatus_user', JSON.stringify(user));

    console.log('Login successful:', user);
    return { token, user };
  } catch (error) {
    console.error('Login error:', error);
    throw error;
  }
}

// Usage
login('admin@tractatus.local', 'your_password')
  .then(({ user }) => {
    console.log('Logged in as:', user.email);
  });

Making Authenticated Requests (Node.js)

const axios = require('axios');

// Create axios instance with authentication
function createAuthClient(token) {
  return axios.create({
    baseURL: 'https://agenticgovernance.digital/api',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    }
  });
}

// Usage
const token = process.env.TRACTATUS_TOKEN;
const client = createAuthClient(token);

// Now all requests include authentication
client.get('/governance/status')
  .then(response => console.log(response.data));

Making Authenticated Requests (Browser)

async function authenticatedFetch(endpoint, options = {}) {
  const token = localStorage.getItem('tractatus_token');

  if (!token) {
    throw new Error('Not authenticated. Please login first.');
  }

  const defaultOptions = {
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
      ...options.headers
    }
  };

  const response = await fetch(`https://agenticgovernance.digital/api${endpoint}`, {
    ...options,
    ...defaultOptions
  });

  if (response.status === 401) {
    // Token expired or invalid
    localStorage.removeItem('tractatus_token');
    localStorage.removeItem('tractatus_user');
    throw new Error('Session expired. Please login again.');
  }

  if (!response.ok) {
    throw new Error(`API error: ${response.statusText}`);
  }

  return response.json();
}

// Usage
authenticatedFetch('/governance/status')
  .then(data => console.log(data));

Documents

List All Documents

async function listDocuments(options = {}) {
  const { page = 1, limit = 50, quadrant } = options;

  const params = new URLSearchParams({
    page: page.toString(),
    limit: limit.toString()
  });

  if (quadrant) {
    params.append('quadrant', quadrant);
  }

  const response = await fetch(
    `https://agenticgovernance.digital/api/documents?${params}`
  );

  if (!response.ok) {
    throw new Error('Failed to fetch documents');
  }

  return response.json();
}

// Usage
listDocuments({ page: 1, limit: 10, quadrant: 'STRATEGIC' })
  .then(data => {
    console.log(`Found ${data.pagination.total} documents`);
    data.documents.forEach(doc => {
      console.log(`- ${doc.title} (${doc.quadrant})`);
    });
  });

Get Single Document

async function getDocument(identifier) {
  const response = await fetch(
    `https://agenticgovernance.digital/api/documents/${identifier}`
  );

  if (response.status === 404) {
    throw new Error('Document not found');
  }

  if (!response.ok) {
    throw new Error('Failed to fetch document');
  }

  return response.json();
}

// Usage (by slug)
getDocument('introduction-to-tractatus')
  .then(data => {
    console.log('Title:', data.document.title);
    console.log('Quadrant:', data.document.quadrant);
    console.log('Content:', data.document.content_html.substring(0, 100) + '...');
  });

// Usage (by ID)
getDocument('672f821b6e820c0c7a0e0d55')
  .then(data => console.log(data.document));

Search Documents

async function searchDocuments(query) {
  const params = new URLSearchParams({ q: query });

  const response = await fetch(
    `https://agenticgovernance.digital/api/documents/search?${params}`
  );

  if (!response.ok) {
    throw new Error('Search failed');
  }

  return response.json();
}

// Usage
searchDocuments('boundary enforcement')
  .then(data => {
    console.log(`Found ${data.count} results`);
    data.results.forEach(result => {
      console.log(`- ${result.title} (score: ${result.score})`);
    });
  });

Create Document (Admin Only)

async function createDocument(token, documentData) {
  const client = createAuthClient(token);

  try {
    const response = await client.post('/documents', {
      title: documentData.title,
      slug: documentData.slug,
      quadrant: documentData.quadrant,
      content_markdown: documentData.content,
      status: documentData.status || 'published'
    });

    console.log('Document created:', response.data.document._id);
    return response.data.document;
  } catch (error) {
    if (error.response?.status === 403) {
      console.error('Admin role required');
    } else if (error.response?.status === 409) {
      console.error('Slug already exists');
    }
    throw error;
  }
}

// Usage
const newDocument = {
  title: 'Advanced Boundary Enforcement Patterns',
  slug: 'advanced-boundary-enforcement',
  quadrant: 'OPERATIONAL',
  content: '# Advanced Patterns\n\nThis document explores...',
  status: 'published'
};

createDocument(process.env.TRACTATUS_TOKEN, newDocument);

Governance Services

InstructionPersistenceClassifier

async function classifyInstruction(token, text, context = {}) {
  const client = createAuthClient(token);

  const response = await client.post('/governance/classify', {
    text,
    context: {
      source: context.source || 'user',
      session_id: context.session_id || 'default',
      ...context
    }
  });

  return response.data.classification;
}

// Usage
classifyInstruction(
  process.env.TRACTATUS_TOKEN,
  'Always use MongoDB on port 27027',
  { source: 'user', session_id: 'sess_123' }
).then(classification => {
  console.log('Quadrant:', classification.quadrant);
  console.log('Persistence:', classification.persistence);
  console.log('Temporal Scope:', classification.temporal_scope);
  console.log('Confidence:', classification.confidence);
  console.log('Reasoning:', classification.reasoning);
});

CrossReferenceValidator

async function validateAction(token, action, context = {}) {
  const client = createAuthClient(token);

  const response = await client.post('/governance/validate', {
    action,
    context: {
      messages: context.messages || [],
      session_id: context.session_id || 'default',
      ...context
    }
  });

  return response.data.validation;
}

// Usage
const action = {
  type: 'database_config',
  target: 'MongoDB',
  parameters: { port: 27017 }
};

validateAction(process.env.TRACTATUS_TOKEN, action)
  .then(validation => {
    if (validation.status === 'REJECTED') {
      console.error('❌ Action rejected');
      console.error('Reason:', validation.reason);
      validation.conflicts.forEach(conflict => {
        console.error(`  Conflicts with: ${conflict.text} (${conflict.instruction_id})`);
      });
      console.log('Recommendation:', validation.recommendation);
    } else if (validation.status === 'APPROVED') {
      console.log('✅ Action approved');
    }
  });

BoundaryEnforcer

async function enforceBounda ry(token, action, context = {}) {
  const client = createAuthClient(token);

  const response = await client.post('/governance/enforce', {
    action,
    context
  });

  return response.data.enforcement;
}

// Usage
const action = {
  type: 'policy_change',
  description: 'Update privacy policy to enable more tracking',
  impact: 'user_privacy'
};

enforceBoundary(process.env.TRACTATUS_TOKEN, action)
  .then(enforcement => {
    if (enforcement.decision === 'BLOCK') {
      console.error('🚫 Action blocked - crosses values boundary');
      console.error('Boundary:', enforcement.boundary_crossed);
      console.error('Reason:', enforcement.reason);
      console.log('\nAlternatives:');
      enforcement.alternatives.forEach((alt, i) => {
        console.log(`${i + 1}. ${alt}`);
      });
    } else {
      console.log('✅ Action allowed');
    }
  });

ContextPressureMonitor

async function analyzePressure(token, context) {
  const client = createAuthClient(token);

  const response = await client.post('/governance/pressure', {
    context: {
      tokenUsage: context.tokenUsage || 50000,
      tokenBudget: context.tokenBudget || 200000,
      messageCount: context.messageCount || 20,
      errorCount: context.errorCount || 0,
      complexOperations: context.complexOperations || 0,
      sessionDuration: context.sessionDuration || 1800
    }
  });

  return response.data.pressure;
}

// Usage
analyzePressure(process.env.TRACTATUS_TOKEN, {
  tokenUsage: 120000,
  tokenBudget: 200000,
  messageCount: 45,
  errorCount: 3,
  complexOperations: 8,
  sessionDuration: 3600
}).then(pressure => {
  console.log('Pressure Level:', pressure.level);
  console.log('Score:', pressure.score + '%');
  console.log('\nFactors:');
  Object.entries(pressure.factors).forEach(([factor, data]) => {
    console.log(`  ${factor}: ${data.value} (${data.status})`);
  });
  console.log('\nRecommendation:', pressure.recommendation);

  if (pressure.triggerHandoff) {
    console.warn('⚠️ Session handoff recommended');
  }
});

MetacognitiveVerifier

async function verifyAction(token, action, reasoning, context = {}) {
  const client = createAuthClient(token);

  const response = await client.post('/governance/verify', {
    action,
    reasoning,
    context
  });

  return response.data.verification;
}

// Usage
const action = {
  type: 'refactor',
  scope: 'Refactor 47 files across 5 system areas',
  complexity: 'high'
};

const reasoning = {
  intent: 'Improve code organization',
  approach: 'Extract shared utilities, consolidate duplicates',
  risks: 'Potential breaking changes'
};

const context = {
  requested: 'Refactor authentication module',
  original_scope: 'single module'
};

verifyAction(process.env.TRACTATUS_TOKEN, action, reasoning, context)
  .then(verification => {
    console.log('Decision:', verification.decision);
    console.log('Confidence:', verification.confidence);

    if (verification.concerns.length > 0) {
      console.log('\n⚠  Concerns:');
      verification.concerns.forEach(concern => {
        console.log(`  [${concern.severity}] ${concern.type}: ${concern.detail}`);
      });
    }

    if (verification.scopeCreep) {
      console.warn('\n🔴 Scope creep detected');
    }

    console.log('\nCriteria Scores:');
    Object.entries(verification.criteria).forEach(([criterion, score]) => {
      console.log(`  ${criterion}: ${(score * 100).toFixed(0)}%`);
    });

    if (verification.alternatives.length > 0) {
      console.log('\nAlternatives:');
      verification.alternatives.forEach((alt, i) => {
        console.log(`${i + 1}. ${alt}`);
      });
    }
  });

Audit Logs

Get Audit Logs with Filtering

async function getAuditLogs(token, options = {}) {
  const client = createAuthClient(token);

  const params = {
    page: options.page || 1,
    limit: options.limit || 50
  };

  if (options.action) params.action = options.action;
  if (options.userId) params.userId = options.userId;
  if (options.startDate) params.startDate = options.startDate;
  if (options.endDate) params.endDate = options.endDate;

  const response = await client.get('/audit/audit-logs', { params });
  return response.data;
}

// Usage
getAuditLogs(process.env.TRACTATUS_TOKEN, {
  page: 1,
  limit: 20,
  action: 'validate_action',
  startDate: '2025-10-01T00:00:00Z'
}).then(data => {
  console.log(`Total logs: ${data.total}`);
  data.logs.forEach(log => {
    console.log(`[${log.timestamp}] ${log.service}: ${log.action} - ${log.status}`);
    if (log.details) {
      console.log('  Details:', JSON.stringify(log.details, null, 2));
    }
  });
});

Get Audit Analytics

async function getAuditAnalytics(token, startDate, endDate) {
  const client = createAuthClient(token);

  const params = {};
  if (startDate) params.startDate = startDate;
  if (endDate) params.endDate = endDate;

  const response = await client.get('/audit/audit-analytics', { params });
  return response.data.analytics;
}

// Usage
getAuditAnalytics(
  process.env.TRACTATUS_TOKEN,
  '2025-10-01T00:00:00Z',
  '2025-10-12T23:59:59Z'
).then(analytics => {
  console.log('Total Events:', analytics.total_events);
  console.log('\nBreakdown by Service:');
  Object.entries(analytics.by_service).forEach(([service, count]) => {
    console.log(`  ${service}: ${count}`);
  });
  console.log('\nBreakdown by Status:');
  Object.entries(analytics.by_status).forEach(([status, count]) => {
    console.log(`  ${status}: ${count}`);
  });
  console.log('\nRejection Rate:', analytics.rejection_rate + '%');
});

Error Handling

Comprehensive Error Handler

async function handleApiRequest(requestFn) {
  try {
    return await requestFn();
  } catch (error) {
    // Axios error structure
    if (error.response) {
      const { status, data } = error.response;

      switch (status) {
        case 400:
          console.error('Bad Request:', data.message);
          console.error('Details:', data.details);
          break;
        case 401:
          console.error('Unauthorized: Please login');
          // Clear stored token
          localStorage.removeItem('tractatus_token');
          break;
        case 403:
          console.error('Forbidden: Insufficient permissions');
          console.error('Required role:', data.required_role || 'admin');
          break;
        case 404:
          console.error('Not Found:', data.message);
          break;
        case 409:
          console.error('Conflict:', data.message);
          console.error('Conflicting resource:', data.conflict);
          break;
        case 429:
          console.error('Rate Limit Exceeded:', data.message);
          console.error('Retry after:', error.response.headers['retry-after']);
          break;
        case 500:
          console.error('Internal Server Error');
          console.error('Error ID:', data.errorId);
          break;
        default:
          console.error('API Error:', status, data.message);
      }
    } else if (error.request) {
      console.error('Network Error: No response received');
      console.error('Check your internet connection');
    } else {
      console.error('Error:', error.message);
    }

    throw error;
  }
}

// Usage
handleApiRequest(async () => {
  return await classifyInstruction(token, 'Test instruction');
})
  .then(result => console.log('Success:', result))
  .catch(error => console.log('Handled error'));

Retry Logic with Exponential Backoff

async function retryWithBackoff(fn, maxRetries = 3, baseDelay = 1000) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      if (attempt === maxRetries) {
        throw error;
      }

      // Don't retry on client errors (4xx except 429)
      if (error.response?.status >= 400 &&
          error.response?.status < 500 &&
          error.response?.status !== 429) {
        throw error;
      }

      const delay = baseDelay * Math.pow(2, attempt - 1);
      console.log(`Attempt ${attempt} failed. Retrying in ${delay}ms...`);
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}

// Usage
retryWithBackoff(async () => {
  return await getDocument('some-slug');
}, 3, 1000)
  .then(doc => console.log('Document:', doc))
  .catch(error => console.error('All retries failed:', error));

Complete Example: Full Integration

const axios = require('axios');

class TractatusClient {
  constructor(baseURL = 'https://agenticgovernance.digital/api') {
    this.baseURL = baseURL;
    this.token = null;
    this.client = axios.create({ baseURL });
  }

  async login(email, password) {
    const response = await this.client.post('/auth/login', { email, password });
    this.token = response.data.token;
    this.client.defaults.headers.common['Authorization'] = `Bearer ${this.token}`;
    return response.data;
  }

  async classifyInstruction(text, context = {}) {
    const response = await this.client.post('/governance/classify', { text, context });
    return response.data.classification;
  }

  async validateAction(action, context = {}) {
    const response = await this.client.post('/governance/validate', { action, context });
    return response.data.validation;
  }

  async getDocuments(options = {}) {
    const response = await this.client.get('/documents', { params: options });
    return response.data;
  }
}

// Usage
const tractatus = new TractatusClient();

async function main() {
  await tractatus.login('admin@tractatus.local', 'password');

  const classification = await tractatus.classifyInstruction(
    'Always use MongoDB on port 27027'
  );
  console.log('Classification:', classification);

  const docs = await tractatus.getDocuments({ limit: 5 });
  console.log(`Found ${docs.total} documents`);
}

main().catch(console.error);

Rate Limiting

The Tractatus API implements rate limiting:

  • Login endpoint: 5 attempts per 15 minutes per IP
  • General API: 100 requests per 15 minutes per IP

Handle rate limiting:

async function apiCallWithRateLimit(fn) {
  try {
    return await fn();
  } catch (error) {
    if (error.response?.status === 429) {
      const retryAfter = error.response.headers['retry-after'];
      console.warn(`Rate limited. Retry after ${retryAfter} seconds`);

      // Wait and retry
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      return await fn();
    }
    throw error;
  }
}

For more information, see the API Reference and OpenAPI Specification.