Class: LittleGhost::Subagents::AgentPath

Inherits:
Object
  • Object
show all
Defined in:
lib/little_ghost/subagents/agent_path.rb

Overview

AgentPath gives every delegated conversation a stable place beneath its parent. Paths begin at /root, keeping nested delegation visible in logs and metadata.

Child task names contain only lowercase letters, digits, and underscores, are limited to 40 characters, and must be unique among siblings when reserved by a manager.

AgentPath.join("/root", "review_api") # => "/root/review_api"

Constant Summary collapse

ROOT =

:nodoc:

"/root"
MAX_NAME_LENGTH =

:nodoc:

40
MAX_PATH_LENGTH =

:nodoc:

1024
NAME_PATTERN =

:nodoc:

/\A[a-z0-9_]+\z/

Class Method Summary collapse

Class Method Details

.immediate_child?(path, parent) ⇒ Boolean

Checks whether path is exactly one level beneath parent.

Returns:

  • (Boolean)


54
55
56
57
58
59
# File 'lib/little_ghost/subagents/agent_path.rb', line 54

def immediate_child?(path, parent)
  value = validate!(path)
  ancestor = validate!(parent)
  value.start_with?("#{ancestor}/") &&
    !value.delete_prefix("#{ancestor}/").include?("/")
end

.join(parent, name) ⇒ Object

Validates both parts and returns a direct child path.



36
37
38
# File 'lib/little_ghost/subagents/agent_path.rb', line 36

def join(parent, name)
  validate!("#{validate!(parent)}/#{validate_name!(name)}")
end

.validate!(path) ⇒ Object

Validates an absolute agent path and returns it unchanged.

Raises:

  • (ArgumentError)


22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/little_ghost/subagents/agent_path.rb', line 22

def validate!(path)
  value = String(path)
  raise ArgumentError, "agent path must start with /root" unless value == ROOT || value.start_with?("#{ROOT}/")
  raise ArgumentError, "agent path must not end with /" if value.end_with?("/")
  raise ArgumentError, "agent path is too long" if value.length > MAX_PATH_LENGTH

  segments = value.split("/").drop(2)
  raise ArgumentError, "agent path must not contain empty segments" if segments.any?(&:empty?)

  segments.each { |segment| validate_name!(segment) }
  value
end

.validate_name!(name) ⇒ Object

Validates and returns one model-chosen task name.



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/little_ghost/subagents/agent_path.rb', line 41

def validate_name!(name)
  value = String(name)
  if value.length > MAX_NAME_LENGTH
    raise ArgumentError, "task_name must be at most #{MAX_NAME_LENGTH} characters"
  end
  if value == "root" || !value.match?(NAME_PATTERN)
    raise ArgumentError, "task_name must use lowercase letters, digits, and underscores"
  end

  value
end