Skip to content

Auto-detect folder path in do_ingest() CLI handler #9

Description

@verkligheten

Parent Epic

Part of #5 — Integrate Graphify for zero-cost code entity extraction

Task

Modify do_ingest() in agent_notes/commands/memory.py to auto-detect when the title argument is a filesystem folder path and route to wiki_ingest_folder() instead of wiki_ingest().

File

agent_notes/commands/memory.py — function do_ingest() (lines 515-543)

Current Behavior

agent-notes memory ingest "My Title" "My body" "concept1,concept2" "entity1,entity2"

Always calls wiki_ingest() with text-based ingestion.

New Behavior

# Folder path → routes to wiki_ingest_folder (with Graphify auto-extraction)
agent-notes memory ingest /path/to/project "Optional summary"
agent-notes memory ingest ./src "Analyzing source directory"
agent-notes memory ingest ~/code/my-app

# Text title → existing behavior unchanged
agent-notes memory ingest "My Title" "My body text" "concepts" "entities"

Implementation

Modify do_ingest() (line 515-543)

def do_ingest(title: str, body: str, concepts: Optional[list] = None,
              entities: Optional[list] = None, tags: Optional[list] = None) -> None:
    """Ingest a source into the wiki backend."""
    backend, path = _load_memory_config()
    if backend != "wiki":
        print("The `ingest` subcommand is only available for wiki storage.")
        return
    if path is None:
        print("Memory path not configured.")
        return

    # Auto-detect folder path
    candidate = Path(title).expanduser().resolve()
    if candidate.is_dir():
        from ..services.wiki_backend import wiki_ingest_folder
        result = wiki_ingest_folder(
            path,
            folder_path=candidate,
            body=body or "",
            concepts=concepts,
            entities=entities,
            tags=tags,
        )
        source_paths = result.get("source", [])
        concept_paths = result.get("concepts", [])
        entity_paths = result.get("entities", [])
        print(f"{Color.GREEN}Ingested folder: {candidate}{Color.NC}")
        for p in source_paths:
            print(f"  source:  {p}")
        for p in concept_paths:
            print(f"  concept: {p}")
        for p in entity_paths:
            print(f"  entity:  {p}")
        return

    # Existing text-based ingest (unchanged)
    from ..services.wiki_backend import wiki_ingest
    result = wiki_ingest(
        path,
        title=title,
        body=body,
        concepts=concepts or [],
        entities=entities or [],
        tags=tags or [],
    )
    source_paths = result.get("source", [])
    concept_paths = result.get("concepts", [])
    entity_paths = result.get("entities", [])
    print(f"{Color.GREEN}Ingested: {title}{Color.NC}")
    for p in source_paths:
        print(f"  source:  {p}")
    for p in concept_paths:
        print(f"  concept: {p}")
    for p in entity_paths:
        print(f"  entity:  {p}")

Edge Cases

  1. Title looks like a path but isn't a directory (e.g., "/tmp/nonexistent"): candidate.is_dir() returns False, falls through to text-based ingest. Title becomes "/tmp/nonexistent".
  2. Title is "." or "./": Resolves to CWD, which is a directory → triggers folder ingest.
  3. Title with spaces that's also a valid dir (e.g., "My Project"): If ./My Project/ exists as a directory, it triggers folder ingest. This is the desired behavior — directory detection takes priority.
  4. Title is a file path (not directory): is_dir() returns False. For file ingest, users should use the existing wiki_ingest_file() path (or we could add is_file() detection too as a follow-up).
  5. Symlinks: resolve() follows symlinks. A symlink to a directory is detected as a directory.

CLI Argument Routing (context)

The CLI routing in memory() (line 821-832) passes name as title and extra[0] as body:

elif action == "ingest":
    if not name:
        do_scan_raw()
        exit(0)
    body = extra[0] if extra else ""
    concepts_csv = extra[1] if extra and len(extra) > 1 else ""
    # ...
    do_ingest(name, body, concepts=concepts, entities=entities, tags=tags)

So agent-notes memory ingest /path/to/dir "summary" maps to do_ingest("/path/to/dir", "summary"). No changes needed to the CLI routing.

Dependencies

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions