# graph


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

## GraphService

This service wraps the SQLite graph plugin to provide storage for the
decomposed document structure. It converts `TextSegment` objects into
graph nodes and edges, then commits them to the context graph.

------------------------------------------------------------------------

### GraphService

``` python

def GraphService(
    plugin_manager:PluginManager, # Plugin manager for accessing graph plugin
    plugin_name:str='cjm-graph-plugin-sqlite', # Name of the graph plugin
):

```

*Service for committing structure to context graph.*

## Tests

The following cells demonstrate the GraphService with the SQLite Graph
plugin.

``` python
# Test GraphService with SQLite Graph plugin
from pathlib import Path
from cjm_plugin_system.core.manager import PluginManager

# Calculate project root from notebook location (nbs/services/ -> project root)
project_root = Path.cwd().parent.parent
manifests_dir = project_root / ".cjm" / "manifests"

# Create plugin manager with explicit search path
manager = PluginManager(search_paths=[manifests_dir])
manager.discover_manifests()

print(f"Discovered {len(manager.discovered)} plugins from {manifests_dir}")

# Check if Graph plugin is available
graph_meta = manager.get_discovered_meta("cjm-graph-plugin-sqlite")
if graph_meta:
    print(f"Found plugin: {graph_meta.name} v{graph_meta.version}")
else:
    print("SQLite Graph plugin not found - install via plugins.yaml")
```

    [PluginManager] Discovered manifest: cjm-graph-plugin-sqlite from /mnt/SN850X_8TB_EXT4/Projects/GitHub/cj-mills/cjm-transcript-review/.cjm/manifests/cjm-graph-plugin-sqlite.json

    Discovered 1 plugins from /mnt/SN850X_8TB_EXT4/Projects/GitHub/cj-mills/cjm-transcript-review/.cjm/manifests
    Found plugin: cjm-graph-plugin-sqlite v0.0.3

``` python
# Initialize and test GraphService
if graph_meta:
    # Load the plugin
    # manager.load_plugin(graph_meta)
    manager.load_plugin(graph_meta, {
        "db_path": graph_meta.manifest.get("db_path")
    })
    
    graph_service = GraphService(manager)
    print(f"Plugin available: {graph_service.is_available()}")
```

    [PluginManager] Launching worker for cjm-graph-plugin-sqlite...

    [cjm-graph-plugin-sqlite] Starting worker on port 57931...
    [cjm-graph-plugin-sqlite] Logs: /home/innom-dt/.cjm/logs/cjm-graph-plugin-sqlite.log

    [PluginManager] HTTP Request: GET http://127.0.0.1:57931/health "HTTP/1.1 200 OK"
    [PluginManager] HTTP Request: POST http://127.0.0.1:57931/initialize "HTTP/1.1 200 OK"
    [PluginManager] Loaded plugin: cjm-graph-plugin-sqlite

    [cjm-graph-plugin-sqlite] Worker ready.
    Plugin available: True

``` python
# Test committing a document to the graph with separate text segments and VAD chunks
from cjm_transcript_segmentation.models import TextSegment
from cjm_transcript_vad_align.models import VADChunk

if graph_meta and graph_service.is_available():
    # Create text segments (no time fields)
    text_segments = [
        TextSegment(
            index=0,
            text="Laying Plans",
            source_id="job_123",
            source_provider_id="test-plugin",
            start_char=0,
            end_char=12,
        ),
        TextSegment(
            index=1,
            text="Sun Tzu said: The art of war is of vital importance to the state.",
            source_id="job_123",
            source_provider_id="test-plugin",
            start_char=13,
            end_char=79,
        ),
        TextSegment(
            index=2,
            text="It is a matter of life and death, a road either to safety or to ruin.",
            source_id="job_123",
            source_provider_id="test-plugin",
            start_char=80,
            end_char=150,
        )
    ]
    
    # Create VAD chunks with timing (1:1 with segments)
    vad_chunks = [
        VADChunk(index=0, start_time=0.0, end_time=1.5),
        VADChunk(index=1, start_time=1.5, end_time=5.0),
        VADChunk(index=2, start_time=5.0, end_time=9.0),
    ]
    
    print(f"Committing document with {len(text_segments)} segments and {len(vad_chunks)} VAD chunks...")
    
    # Use await directly (Jupyter supports top-level await)
    result = await graph_service.commit_document_async(
        title="The Art of War - Chapter 1",
        text_segments=text_segments,
        vad_chunks=vad_chunks,
        media_type="audio",
    )
    
    print(f"\nCommit result:")
    print(f"  Document ID: {result['document_id']}")
    print(f"  Segment IDs: {result['segment_ids']}")
    print(f"  Edge count: {result['edge_count']}")
```

    [PluginManager] HTTP Request: POST http://127.0.0.1:57931/execute "HTTP/1.1 200 OK"
    [PluginManager] HTTP Request: POST http://127.0.0.1:57931/execute "HTTP/1.1 200 OK"

    Committing document with 3 segments and 3 VAD chunks...

    Commit result:
      Document ID: 6eeda707-4438-4094-8d44-6272ff5da8a3
      Segment IDs: ['70567737-0663-4f74-8e9b-18e507249e3c', '82e8b884-a3c2-4411-9c5e-d606277e6e83', '8d773f77-9c54-40d6-8a60-3c6e7c45509d']
      Edge count: 6

``` python
# Verify the graph structure (use await directly - Jupyter supports top-level await)
if graph_meta and graph_service.is_available():
    # Get graph schema
    schema = await manager.execute_plugin_async(
        "cjm-graph-plugin-sqlite", 
        action="get_schema"
    )
    print(f"Graph schema:")
    print(f"  Node labels: {schema.get('node_labels', [])}")
    print(f"  Relation types: {schema.get('relation_types', [])}")
```

    [PluginManager] HTTP Request: POST http://127.0.0.1:57931/execute "HTTP/1.1 200 OK"

    Graph schema:
      Node labels: ['Document', 'Segment']
      Relation types: []

``` python
# Cleanup
if graph_meta:
    manager.unload_all()
    print("Plugins unloaded")
```

    [PluginManager] HTTP Request: POST http://127.0.0.1:57931/cleanup "HTTP/1.1 200 OK"
    [PluginManager] Unloaded plugin: cjm-graph-plugin-sqlite

    Plugins unloaded
