Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 17 additions & 21 deletions dipstick/services/agent-swarm/src/swarm.affine
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
// SPDX-License-Identifier: MPL-2.0
// Ported via Harvard Engine mechanical processor
// Ported via Harvard Engine (Semantic pass)

module swarm;

// TODO: Complete semantic implementation

/* === ORIGINAL TYPESCRIPT CONTEXT ===
// NUJ AI Agent Swarm Coordination Service
// Multi-agent system for policy analysis, guidance generation, and PESTLE monitoring
// Uses LangChain for agent orchestration with best practices

import { ChatOpenAI } from "@langchain/openai";

// Agent role definitions following AI agent best practices
export enum AgentRole {
enum AgentRole {
POLICY_ANALYST = "policy_analyst",
SEVERITY_ASSESSOR = "severity_assessor",
GUIDANCE_WRITER = "guidance_writer",
Expand All @@ -24,7 +21,7 @@ export enum AgentRole {
}

// Agent state machine following swarm coordination patterns
export interface AgentState {
struct AgentState {
id: string;
role: AgentRole;
status: "idle" | "working" | "blocked" | "completed" | "failed";
Expand All @@ -35,7 +32,7 @@ export interface AgentState {
}

// Task coordination following distributed consensus patterns
export interface SwarmTask {
struct SwarmTask {
id: string;
type: "policy_analysis" | "guidance_generation" | "pestle_monitoring";
context: {
Expand All @@ -50,7 +47,7 @@ export interface SwarmTask {
}

// Swarm coordination using actor model pattern
export class AgentSwarm {
struct AgentSwarm {
private tasks: Map<string, SwarmTask> = new Map();
private agents: Map<string, AgentState> = new Map();
private llm: ChatOpenAI;
Expand All @@ -66,7 +63,7 @@ export class AgentSwarm {
}

private initializeAgents(): void {
const roles = [
let roles = [
AgentRole.POLICY_ANALYST,
AgentRole.SEVERITY_ASSESSOR,
AgentRole.GUIDANCE_WRITER,
Expand All @@ -76,7 +73,7 @@ export class AgentSwarm {
];

roles.forEach((role) => {
const agentId = `${role}-${crypto.randomUUID()}`;
let agentId = `${role}-${crypto.randomUUID()}`;
this.agents.set(agentId, {
id: agentId,
role,
Expand All @@ -93,11 +90,11 @@ export class AgentSwarm {
async coordinatePolicyAnalysis(
policyChangeId: string,
context: SwarmTask["context"],
): Promise<string> {
const taskId = crypto.randomUUID();
): string {
let taskId = crypto.randomUUID();

// Define agent workflow DAG (Directed Acyclic Graph)
const workflow = [
let workflow = [
{
// Phase 1: Parallel analysis
parallel: [
Expand Down Expand Up @@ -143,8 +140,8 @@ export class AgentSwarm {
private async executePolicyAnalysis(
agent: AgentState,
context: SwarmTask["context"],
): Promise<Record<string, unknown>> {
const prompt = `You are a policy analyst for a journalism union. Analyze this policy change:
): Record<string, unknown> {
let prompt = `You are a policy analyst for a journalism union. Analyze this policy change:

Platform: ${context.platform}
Policy Change ID: ${context.policyChangeId}
Expand All @@ -171,7 +168,7 @@ Be precise, factual, and focused on journalistic implications.`;
private async executePestleAnalysis(
agent: AgentState,
context: SwarmTask["context"],
): Promise<Record<string, unknown>> {
): Record<string, unknown> {
// PESTLE framework analysis
return {
political: ["Regulatory change impact"],
Expand All @@ -188,7 +185,7 @@ Be precise, factual, and focused on journalistic implications.`;
agent: AgentState,
context: SwarmTask["context"],
priorResults: Record<string, unknown>,
): Promise<Record<string, unknown>> {
): Record<string, unknown> {
// Synthesize all prior agent results into member guidance
return {
guidanceDraft: "Draft guidance content...",
Expand All @@ -212,9 +209,9 @@ Be precise, factual, and focused on journalistic implications.`;
}

// HTTP server for swarm coordination API
async function startSwarmService(port: number): Promise<void> {
const apiKey = Deno.env.get("OPENAI_API_KEY") || "";
const swarm = new AgentSwarm(apiKey);
async fn startSwarmService(port: number): void {
let apiKey = Deno.env.get("OPENAI_API_KEY") || "";
let swarm = new AgentSwarm(apiKey);

console.log(`[Agent Swarm] Starting coordination service on port ${port}`);
console.log(`[Agent Swarm] Initialized ${swarm.getActiveAgents().length} agents`);
Expand All @@ -230,4 +227,3 @@ if (import.meta.main) {
await startSwarmService(3004);
}

==================================== */
56 changes: 26 additions & 30 deletions dipstick/services/pestle-observatory/src/observatory.affine
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
// SPDX-License-Identifier: MPL-2.0
// Ported via Harvard Engine mechanical processor
// Ported via Harvard Engine (Semantic pass)

module observatory;

// TODO: Complete semantic implementation

/* === ORIGINAL TYPESCRIPT CONTEXT ===
// NUJ PESTLE Observatory Service
// Connects to reliable external GraphQL APIs for PESTLE intelligence
// Monitors developing guidance, best practices, and regulatory changes

import { GraphQLClient } from "graphql-request";

// PESTLE framework domains
export enum PESTLEDomain {
enum PESTLEDomain {
POLITICAL = "political",
ECONOMIC = "economic",
SOCIAL = "social",
Expand All @@ -23,7 +20,7 @@ export enum PESTLEDomain {
}

// External observatory connections (reliable public GraphQL APIs)
export interface ObservatorySource {
struct ObservatorySource {
name: string;
endpoint: string;
domains: PESTLEDomain[];
Expand All @@ -32,7 +29,7 @@ export interface ObservatorySource {
}

// Observatory configuration for trusted data sources
export const OBSERVATORY_SOURCES: ObservatorySource[] = [
const OBSERVATORY_SOURCES: ObservatorySource[] = [
{
name: "GDPR Observatory",
endpoint: "https://api.gdpr.eu/graphql", // Placeholder - would use actual GDPR API
Expand Down Expand Up @@ -82,7 +79,7 @@ export const OBSERVATORY_SOURCES: ObservatorySource[] = [
];

// PESTLE intelligence data structure
export interface PESTLEIntelligence {
struct PESTLEIntelligence {
domain: PESTLEDomain;
source: string;
title: string;
Expand All @@ -94,7 +91,7 @@ export interface PESTLEIntelligence {
}

// Aggregated PESTLE analysis
export interface PESTLEAnalysis {
struct PESTLEAnalysis {
policyChangeId: string;
political: PESTLEIntelligence[];
economic: PESTLEIntelligence[];
Expand All @@ -107,7 +104,7 @@ export interface PESTLEAnalysis {
}

// Best practices tracker
export interface BestPractice {
struct BestPractice {
id: string;
title: string;
domain: PESTLEDomain;
Expand All @@ -119,7 +116,7 @@ export interface BestPractice {
}

// Observatory client for GraphQL federation
export class PESTLEObservatory {
struct PESTLEObservatory {
private clients: Map<string, GraphQLClient> = new Map();
private cache: Map<string, { data: unknown; timestamp: number }> = new Map();
private cacheTTL = 3600000; // 1 hour
Expand All @@ -130,7 +127,7 @@ export class PESTLEObservatory {

private initializeClients(): void {
OBSERVATORY_SOURCES.forEach((source) => {
const client = new GraphQLClient(source.endpoint, {
let client = new GraphQLClient(source.endpoint, {
headers: {
"User-Agent": "NUJ-Social-Media-Monitor/1.0",
},
Expand All @@ -147,7 +144,7 @@ export class PESTLEObservatory {
async queryPESTLEIntelligence(
platform: string,
policyKeywords: string[],
): Promise<PESTLEAnalysis> {
): PESTLEAnalysis {
const results: PESTLEAnalysis = {
policyChangeId: crypto.randomUUID(),
political: [],
Expand All @@ -161,9 +158,9 @@ export class PESTLEObservatory {
};

// Query each observatory source in parallel
const queries = OBSERVATORY_SOURCES.map(async (source) => {
let queries = OBSERVATORY_SOURCES.map(async (source) => {
try {
const intelligence = await this.querySource(
let intelligence = await this.querySource(
source,
platform,
policyKeywords,
Expand All @@ -177,7 +174,7 @@ export class PESTLEObservatory {
}
});

const responses = await Promise.all(queries);
let responses = await Promise.all(queries);

// Aggregate results by domain
responses.forEach(({ source, intelligence }) => {
Expand Down Expand Up @@ -206,7 +203,7 @@ export class PESTLEObservatory {
});

// Calculate overall confidence based on source reliability
const totalIntelligence =
let totalIntelligence =
results.political.length +
results.economic.length +
results.social.length +
Expand All @@ -215,7 +212,7 @@ export class PESTLEObservatory {
results.environmental.length;

if (totalIntelligence > 0) {
const avgReliability =
let avgReliability =
responses.reduce(
(sum, { source }) => sum + source.reliability,
0,
Expand All @@ -231,17 +228,17 @@ export class PESTLEObservatory {
source: ObservatorySource,
platform: string,
keywords: string[],
): Promise<PESTLEIntelligence[]> {
): PESTLEIntelligence[] {
// Cache key
const cacheKey = `${source.name}:${platform}:${keywords.join(",")}`;
const cached = this.cache.get(cacheKey);
let cacheKey = `${source.name}:${platform}:${keywords.join(",")}`;
let cached = this.cache.get(cacheKey);

if (cached && Date.now() - cached.timestamp < this.cacheTTL) {
return cached.data as PESTLEIntelligence[];
}

// GraphQL query (simplified - would be specific to each API)
const query = `
let query = `
query GetRelevantIntelligence($platform: String!, $keywords: [String!]!) {
intelligence(platform: $platform, keywords: $keywords) {
title
Expand Down Expand Up @@ -284,7 +281,7 @@ export class PESTLEObservatory {
}

// Monitor best practices updates
async getBestPractices(domain?: PESTLEDomain): Promise<BestPractice[]> {
async getBestPractices(domain?: PESTLEDomain): BestPractice[] {
const practices: BestPractice[] = [
{
id: "bp-001",
Expand Down Expand Up @@ -331,7 +328,7 @@ export class PESTLEObservatory {
// Real-time observatory feed subscription
async subscribeToUpdates(
callback: (update: PESTLEIntelligence) => void,
): Promise<void> {
): void {
console.log(
"[Observatory] Starting real-time subscription to observatory feeds",
);
Expand All @@ -340,12 +337,12 @@ export class PESTLEObservatory {
// For now, mock periodic polling
setInterval(async () => {
// Poll for updates
const updates = await this.checkForUpdates();
let updates = await this.checkForUpdates();
updates.forEach(callback);
}, 60000); // Check every minute
}

private async checkForUpdates(): Promise<PESTLEIntelligence[]> {
private async checkForUpdates(): PESTLEIntelligence[] {
// Check all sources for new intelligence
return [];
}
Expand Down Expand Up @@ -373,8 +370,8 @@ export class PESTLEObservatory {
}

// HTTP server for PESTLE observatory API
async function startObservatoryService(port: number): Promise<void> {
const observatory = new PESTLEObservatory();
async fn startObservatoryService(port: number): void {
let observatory = new PESTLEObservatory();

console.log(`[PESTLE Observatory] Starting service on port ${port}`);
console.log(
Expand All @@ -388,7 +385,7 @@ async function startObservatoryService(port: number): Promise<void> {
console.log(" - Legal: Terms of service, compliance requirements");
console.log(" - Environmental: Sustainability, digital footprint");

const healthStatus = observatory.getHealthStatus();
let healthStatus = observatory.getHealthStatus();
console.log("\n[PESTLE Observatory] Source health:");
Object.entries(healthStatus).forEach(([name, status]) => {
console.log(
Expand All @@ -406,4 +403,3 @@ if (import.meta.main) {
await startObservatoryService(3005);
}

==================================== */
Loading
Loading