added agent defs

This commit is contained in:
2026-05-18 14:17:33 +00:00
parent e22598f4d1
commit 497a01c544
9 changed files with 1699 additions and 0 deletions

View File

@@ -0,0 +1,150 @@
# Gategory theory as a graph
Some time ago I had a conversation with Gemini 2.5 pro, I believe, since they have backend access to youtube. The subject was regarding a specific series of videos that described category theory in basic terms that just about any dev familiar basic types and type theory could probably understand. I noticed that the relationships form a graph so after some back and forth about that I asked them to provide a sketch using graphology
```typescript
import { MultiGraph, type Attributes } from "npm:graphology"
// --- Setup and Types ---
interface ObjectAttributes extends Attributes {
name: string;
description?: string;
}
interface MorphismAttributes extends Attributes {
label: string;
implementation: (input: any) => any;
composedOf?: [string, string]; // Stores the history of the composition
}
const categoryGraph = new MultiGraph<ObjectAttributes, MorphismAttributes>();
// --- The Compose Function ---
/**
* Composes two morphisms (g after f) and adds the resulting morphism to the graph.
* @param fKey The key of the first morphism (A -> B).
* @param gKey The key of the second morphism (B -> C).
* @returns The key of the new composite morphism (A -> C).
*/
function compose(fKey: string, gKey: string): string {
// 1. & 2. Find edges and their attributes
if (!categoryGraph.hasEdge(fKey) || !categoryGraph.hasEdge(gKey)) {
throw new Error('One or both morphism keys do not exist in the graph.');
}
const f_attributes = categoryGraph.getEdgeAttributes(fKey);
const g_attributes = categoryGraph.getEdgeAttributes(gKey);
const f_source = categoryGraph.source(fKey);
const f_target = categoryGraph.target(fKey);
const g_source = categoryGraph.source(gKey);
const g_target = categoryGraph.target(gKey);
// 3. Validate the path
if (f_target !== g_source) {
throw new Error(
`Cannot compose: Target of '${fKey}' (${f_target}) does not match source of '${gKey}' (${g_source}).`
);
}
// 4. Create the composite morphism attributes
const compositeAttributes: MorphismAttributes = {
label: `${g_attributes.label}${f_attributes.label}`,
implementation: (x) => g_attributes.implementation(f_attributes.implementation(x)),
composedOf: [fKey, gKey],
};
// 5. Add the new edge to the graph
const compositeKey = `${gKey}_o_${fKey}`;
categoryGraph.addEdgeWithKey(compositeKey, f_source, g_target, compositeAttributes);
// 6. Return the new key
console.log(`Successfully composed morphisms. New morphism created with key: '${compositeKey}'`);
return compositeKey;
}
// --- Example Usage ---
// Add Objects (Nodes)
categoryGraph.addNode('Person', { name: 'Person' });
categoryGraph.addNode('Integer', { name: 'Integer' });
categoryGraph.addNode('Boolean', { name: 'Boolean' });
// Add Base Morphisms (Edges)
categoryGraph.addEdgeWithKey('age', 'Person', 'Integer', {
label: 'Age',
implementation: (person: { name: string; age: number }) => person.age,
});
categoryGraph.addEdgeWithKey('isVoter', 'Integer', 'Boolean', {
label: 'isVoter?',
implementation: (age: number) => age >= 18,
});
console.log('Graph before composition:', categoryGraph.edges());
// Expected: ['age', 'isVoter']
// Perform composition: isVoter ∘ age
const canVoteKey = compose('age', 'isVoter');
console.log('---');
console.log('Graph after composition:', categoryGraph.edges());
// Expected: ['age', 'isVoter', 'isVoter_o_age']
console.log('---');
// Let's test our new composite morphism!
const canVoteMorphism = categoryGraph.getEdgeAttributes(canVoteKey);
const alice = { name: 'Alice', age: 30 };
const bob = { name: 'Bob', age: 16 };
console.log(`Does Alice have voting rights? ${canVoteMorphism.implementation(alice)}`); // Expected: true
console.log(`Does Bob have voting rights? ${canVoteMorphism.implementation(bob)}`); // Expected: false
// Let's test the validation by trying an invalid composition
try {
compose('isVoter', 'age');
} catch (e) {
console.error('---');
console.error(`Caught expected error: ${e.message}`);
}
```
exporting the graph via `categoryGraph.export()` shows
```typescript
{
options: { type: "mixed", multi: true, allowSelfLoops: true },
attributes: {},
nodes: [
{ key: "Person", attributes: { name: "Person" } },
{ key: "Integer", attributes: { name: "Integer" } },
{ key: "Boolean", attributes: { name: "Boolean" } }
],
edges: [
{
key: "age",
source: "Person",
target: "Integer",
attributes: { label: "Age", implementation: [Function: implementation] }
},
{
key: "isVoter",
source: "Integer",
target: "Boolean",
attributes: { label: "isVoter?", implementation: [Function: implementation] }
},
{
key: "isVoter_o_age",
source: "Person",
target: "Boolean",
attributes: {
label: "isVoter? ∘ Age",
implementation: [Function: implementation],
composedOf: [ "age", "isVoter" ]
}
}
]
}
```
Having the implementations actually inside the graph makes it non-serializable but that shows the basic idea.