Function bodies 227 total
BranchConfig.__post_init__ method · python · L77-L82 (6 LOC)src/agent_session_linker/branching/branch_manager.py
def __post_init__(self) -> None:
if self.max_segments is not None and self.max_segments < 0:
raise ValueError(
f"max_segments must be non-negative or None, "
f"got {self.max_segments!r}."
)SessionBranch.summary_line method · python · L131-L137 (7 LOC)src/agent_session_linker/branching/branch_manager.py
def summary_line(self) -> str:
"""Return a one-line human-readable description."""
return (
f"Branch[{self.branch_name}] id={self.branch_id[:8]} "
f"parent={self.parent_session_id[:8]} "
f"segments={self.segment_count} tasks={self.task_count}"
)SessionBranch.add_divergent_segment method · python · L139-L151 (13 LOC)src/agent_session_linker/branching/branch_manager.py
def add_divergent_segment(self, role: str, content: str, **kwargs: object) -> None:
"""Add a segment specific to this branch (does not affect parent).
Parameters
----------
role:
Message role.
content:
Segment text content.
**kwargs:
Additional kwargs forwarded to :meth:`SessionState.add_segment`.
"""
self.session.add_segment(role, content, **kwargs)BranchManager.__init__ method · python · L182-L187 (6 LOC)src/agent_session_linker/branching/branch_manager.py
def __init__(self, parent_session_id: str) -> None:
if not parent_session_id.strip():
raise ValueError("parent_session_id must not be empty.")
self._parent_session_id = parent_session_id
self._branches: dict[str, SessionBranch] = {}
self._lock = threading.Lock()BranchManager.create_branch method · python · L204-L281 (78 LOC)src/agent_session_linker/branching/branch_manager.py
def create_branch(
self,
source_session: SessionState,
branch_name: str,
config: BranchConfig | None = None,
metadata: dict[str, object] | None = None,
) -> SessionBranch:
"""Fork *source_session* into a new named branch.
Parameters
----------
source_session:
The session to fork. A deep copy is made.
branch_name:
Unique name for this branch within this manager.
config:
Optional :class:`BranchConfig`. Defaults to copying everything.
metadata:
Optional annotations for the branch.
Returns
-------
SessionBranch
Raises
------
ValueError
If *branch_name* already exists or is empty.
"""
if not branch_name.strip():
raise ValueError("branch_name must not be empty.")
cfg = config or BranchConfig()
with self._lock:
if branch_nBranchManager.get_branch method · python · L287-L301 (15 LOC)src/agent_session_linker/branching/branch_manager.py
def get_branch(self, branch_name: str) -> SessionBranch:
"""Return the branch with *branch_name*.
Raises
------
KeyError
If the branch does not exist.
"""
with self._lock:
if branch_name not in self._branches:
raise KeyError(
f"Branch {branch_name!r} not found for session "
f"{self._parent_session_id!r}."
)
return self._branches[branch_name]BranchManager.delete_branch method · python · L313-L325 (13 LOC)src/agent_session_linker/branching/branch_manager.py
def delete_branch(self, branch_name: str) -> bool:
"""Delete a branch by name.
Returns
-------
bool
True if the branch existed and was deleted.
"""
with self._lock:
if branch_name not in self._branches:
return False
del self._branches[branch_name]
return TrueCitation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
_make_backend function · python · L44-L78 (35 LOC)src/agent_session_linker/cli/main.py
def _make_backend(
storage: str,
db_path: str | None,
storage_dir: str | None,
) -> object:
"""Instantiate the requested storage backend.
Parameters
----------
storage:
Backend name: ``"memory"``, ``"filesystem"``, or ``"sqlite"``.
db_path:
Path to the SQLite database (used when ``storage="sqlite"``).
storage_dir:
Directory for the filesystem backend (used when ``storage="filesystem"``).
Returns
-------
StorageBackend
A configured storage backend instance.
"""
from agent_session_linker.storage.memory import InMemoryBackend
from agent_session_linker.storage.filesystem import FilesystemBackend
from agent_session_linker.storage.sqlite import SQLiteBackend
if storage == "memory":
return InMemoryBackend()
if storage == "filesystem":
directory = Path(storage_dir) if storage_dir else Path.home() / ".agent-sessions"
return FilesystemBackend(storage_dir=directory)
session_group function · python · L137-L145 (9 LOC)src/agent_session_linker/cli/main.py
def session_group(
ctx: click.Context,
storage: str,
db_path: str | None,
storage_dir: str | None,
) -> None:
"""Session management commands."""
ctx.ensure_object(dict)
ctx.obj["backend"] = _make_backend(storage, db_path, storage_dir)session_save function · python · L166-L186 (21 LOC)src/agent_session_linker/cli/main.py
def session_save(
ctx: click.Context,
agent_id: str,
parent: str | None,
content: str | None,
) -> None:
"""Create and persist a new session.
Prints the new session ID on success.
"""
from agent_session_linker.session.manager import SessionManager
backend = ctx.obj["backend"]
manager = SessionManager(backend=backend, default_agent_id=agent_id)
session = manager.create_session(agent_id=agent_id, parent_session_id=parent)
if content:
session.add_segment(role="user", content=content)
session_id = manager.save_session(session)
console.print(f"[green]Session saved:[/green] {session_id}")session_load function · python · L198-L249 (52 LOC)src/agent_session_linker/cli/main.py
def session_load(
ctx: click.Context,
session_id: str,
json_output: bool,
) -> None:
"""Load and display a session by SESSION_ID."""
from agent_session_linker.session.manager import SessionManager, SessionNotFoundError
backend = ctx.obj["backend"]
manager = SessionManager(backend=backend)
try:
session = manager.load_session(session_id)
except SessionNotFoundError:
console.print(f"[red]Session not found:[/red] {session_id}")
sys.exit(1)
if json_output:
console.print_json(session.model_dump_json(indent=2))
return
table = Table(title=f"Session {session.session_id[:8]}", show_lines=True)
table.add_column("Field", style="bold cyan")
table.add_column("Value")
table.add_row("session_id", session.session_id)
table.add_row("agent_id", session.agent_id)
table.add_row("schema_version", session.schema_version)
table.add_row("segments", str(len(session.segments)))
table.add_row("tasksession_list function · python · L261-L304 (44 LOC)src/agent_session_linker/cli/main.py
def session_list(
ctx: click.Context,
agent_id: str | None,
limit: int,
) -> None:
"""List all sessions in the storage backend."""
from agent_session_linker.session.manager import SessionManager
backend = ctx.obj["backend"]
manager = SessionManager(backend=backend)
if agent_id:
session_ids = manager.list_sessions_for_agent(agent_id)
else:
session_ids = manager.list_sessions()
if not session_ids:
console.print("[yellow]No sessions found.[/yellow]")
return
session_ids = session_ids[:limit]
table = Table(title="Sessions", show_lines=False)
table.add_column("Session ID", style="cyan")
table.add_column("Agent", style="green")
table.add_column("Segments", justify="right")
table.add_column("Tokens", justify="right")
table.add_column("Updated")
for sid in session_ids:
try:
session = manager.load_session(sid)
table.add_row(
session.sessionsession_link function · python · L327-L364 (38 LOC)src/agent_session_linker/cli/main.py
def session_link(
ctx: click.Context,
source_session_id: str,
target_session_id: str,
relationship: str,
links_file: str | None,
) -> None:
"""Create a directed relationship between two sessions.
SOURCE_SESSION_ID is the originating session.
TARGET_SESSION_ID is the related session.
"""
from agent_session_linker.linking.session_linker import SessionLinker
links_path = Path(links_file) if links_file else Path.home() / ".agent-sessions" / "links.json"
linker = SessionLinker()
if links_path.exists():
try:
existing_data: list[dict[str, object]] = json.loads(links_path.read_text())
linker.import_links(existing_data)
except Exception as exc: # noqa: BLE001
console.print(f"[yellow]Warning: could not load existing links: {exc}[/yellow]")
try:
linked = linker.link(source_session_id, target_session_id, relationship)
except ValueError as exc:
console.print(f"[red]Esession_context function · python · L387-L434 (48 LOC)src/agent_session_linker/cli/main.py
def session_context(
ctx: click.Context,
session_id: str,
query: str,
token_budget: int,
include_linked: bool,
links_file: str | None,
) -> None:
"""Show the injected context block for a session."""
from agent_session_linker.session.manager import SessionManager, SessionNotFoundError
from agent_session_linker.context.injector import ContextInjector, InjectionConfig
from agent_session_linker.linking.session_linker import SessionLinker
backend = ctx.obj["backend"]
manager = SessionManager(backend=backend)
try:
session = manager.load_session(session_id)
except SessionNotFoundError:
console.print(f"[red]Session not found:[/red] {session_id}")
sys.exit(1)
sessions_to_inject = [session]
if include_linked:
links_path = (
Path(links_file) if links_file else Path.home() / ".agent-sessions" / "links.json"
)
linker = SessionLinker()
if links_path.exists():
session_checkpoint function · python · L452-L528 (77 LOC)src/agent_session_linker/cli/main.py
def session_checkpoint(
ctx: click.Context,
action: str,
session_id: str,
label: str,
checkpoint_id: str | None,
) -> None:
"""Create, restore, or list checkpoints for a session.
ACTION is one of: create, restore, list.
SESSION_ID is the target session.
Examples::
agent-session-linker session checkpoint create <session_id> --label before-refactor
agent-session-linker session checkpoint list <session_id>
agent-session-linker session checkpoint restore <session_id> --checkpoint-id __checkpoint__<...>
"""
from agent_session_linker.session.manager import SessionManager, SessionNotFoundError
from agent_session_linker.middleware.checkpoint import CheckpointManager
backend = ctx.obj["backend"]
manager = SessionManager(backend=backend)
checkpoint_manager = CheckpointManager(backend=backend, manager=manager)
if action == "create":
try:
session = manager.load_session(session_id)
eIf a scraper extracted this row, it came from Repobility (https://repobility.com)
portable_group function · python · L537-L542 (6 LOC)src/agent_session_linker/cli/main.py
def portable_group() -> None:
"""Cross-framework session portability commands (USF).
Export, import, or convert sessions between LangChain, CrewAI, and OpenAI
formats using the Universal Session Format as the interchange layer.
"""portable_export function · python · L567-L608 (42 LOC)src/agent_session_linker/cli/main.py
def portable_export(fmt: str, input_file: str, output_file: str) -> None:
"""Export a USF session file to a framework-native JSON format.
Reads a UniversalSession from INPUT and writes the framework-specific
representation to OUTPUT.
Examples::
agent-session-linker portable export --format langchain \\
--input session.usf.json --output lc_session.json
agent-session-linker portable export --format openai \\
--input session.usf.json --output openai_thread.json
"""
import json
from pathlib import Path
from agent_session_linker.portable.usf import UniversalSession
from agent_session_linker.portable.exporters import (
LangChainExporter,
CrewAIExporter,
OpenAIExporter,
)
try:
json_str = Path(input_file).read_text(encoding="utf-8")
session = UniversalSession.from_json(json_str)
except (ValueError, OSError) as exc:
console.print(f"[red]Failed to load sessportable_import function · python · L633-L678 (46 LOC)src/agent_session_linker/cli/main.py
def portable_import(fmt: str, input_file: str, output_file: str) -> None:
"""Import a framework-native JSON file as a USF session.
Reads the framework-specific representation from INPUT and writes a
UniversalSession to OUTPUT.
Examples::
agent-session-linker portable import --format langchain \\
--input lc_memory.json --output session.usf.json
agent-session-linker portable import --format crewai \\
--input crewai_ctx.json --output session.usf.json
"""
import json as _json
from pathlib import Path
from agent_session_linker.portable.importers import (
LangChainImporter,
CrewAIImporter,
OpenAIImporter,
)
try:
raw_text = Path(input_file).read_text(encoding="utf-8")
data: dict[str, object] = _json.loads(raw_text)
except (ValueError, OSError) as exc:
console.print(f"[red]Failed to read input:[/red] {exc}")
sys.exit(1)
importer_map = {
"portable_convert function · python · L710-L768 (59 LOC)src/agent_session_linker/cli/main.py
def portable_convert(from_fmt: str, to_fmt: str, input_file: str, output_file: str) -> None:
"""Convert a session between two framework-native formats via USF.
The conversion pipeline is: source -> USF -> target.
Examples::
agent-session-linker portable convert --from langchain --to openai \\
--input lc_memory.json --output openai_thread.json
agent-session-linker portable convert --from crewai --to langchain \\
--input crewai_ctx.json --output lc_memory.json
"""
import json as _json
from pathlib import Path
from agent_session_linker.portable.importers import (
LangChainImporter,
CrewAIImporter,
OpenAIImporter,
)
from agent_session_linker.portable.exporters import (
LangChainExporter,
CrewAIExporter,
OpenAIExporter,
)
importer_map = {
"langchain": LangChainImporter(),
"crewai": CrewAIImporter(),
"openai": OpenAIImporter(),
}FreshnessDecay.__init__ method · python · L54-L64 (11 LOC)src/agent_session_linker/context/freshness.py
def __init__(
self,
curve: DecayCurve = DecayCurve.EXPONENTIAL,
max_age_hours: float = 168.0,
decay_rate: float = 0.01,
step_thresholds: tuple[float, float] = (24.0, 168.0),
) -> None:
self.curve = curve
self.max_age_hours = max_age_hours
self.decay_rate = decay_rate
self.step_thresholds = step_thresholdsFreshnessDecay.score method · python · L70-L94 (25 LOC)src/agent_session_linker/context/freshness.py
def score(self, age_hours: float) -> float:
"""Return the freshness score for a segment of age ``age_hours``.
Parameters
----------
age_hours:
The age of the segment in hours (must be >= 0).
Returns
-------
float
Freshness score in [0.0, 1.0]. A score of 1.0 means fully
fresh; 0.0 means completely stale.
"""
age = max(0.0, age_hours)
if self.curve is DecayCurve.LINEAR:
return self._linear(age)
if self.curve is DecayCurve.EXPONENTIAL:
return self._exponential(age)
if self.curve is DecayCurve.STEP:
return self._step(age)
# Fallback — should not be reachable with a valid DecayCurve.
return 1.0FreshnessDecay._step method · python · L110-L117 (8 LOC)src/agent_session_linker/context/freshness.py
def _step(self, age: float) -> float:
"""Step decay: 1.0 / 0.5 / 0.1 based on threshold bands."""
t1, t2 = self.step_thresholds
if age < t1:
return 1.0
if age < t2:
return 0.5
return 0.1FreshnessDecay.score_many method · python · L123-L136 (14 LOC)src/agent_session_linker/context/freshness.py
def score_many(self, ages_hours: list[float]) -> list[float]:
"""Return freshness scores for a list of ages.
Parameters
----------
ages_hours:
List of segment ages in hours.
Returns
-------
list[float]
Corresponding freshness scores.
"""
return [self.score(age) for age in ages_hours]Repobility · code-quality intelligence · https://repobility.com
FreshnessDecay.__repr__ method · python · L138-L143 (6 LOC)src/agent_session_linker/context/freshness.py
def __repr__(self) -> str:
return (
f"FreshnessDecay(curve={self.curve.value!r}, "
f"max_age_hours={self.max_age_hours}, "
f"decay_rate={self.decay_rate})"
)_term_frequency function · python · L108-L114 (7 LOC)src/agent_session_linker/context/injector.py
def _term_frequency(tokens: list[str]) -> dict[str, float]:
"""Compute raw TF for a token list (normalised by document length)."""
if not tokens:
return {}
counts = Counter(tokens)
total = len(tokens)
return {term: count / total for term, count in counts.items()}_compute_idf function · python · L117-L128 (12 LOC)src/agent_session_linker/context/injector.py
def _compute_idf(documents: list[list[str]]) -> dict[str, float]:
"""Compute IDF scores across a corpus of tokenised documents."""
num_docs = len(documents)
if num_docs == 0:
return {}
document_freq: Counter[str] = Counter()
for doc_tokens in documents:
document_freq.update(set(doc_tokens))
return {
term: math.log((1 + num_docs) / (1 + df)) + 1
for term, df in document_freq.items()
}_tfidf_score function · python · L131-L140 (10 LOC)src/agent_session_linker/context/injector.py
def _tfidf_score(query_tokens: list[str], doc_tokens: list[str], idf: dict[str, float]) -> float:
"""Score a document against a query using TF-IDF overlap."""
if not query_tokens or not doc_tokens:
return 0.0
tf = _term_frequency(doc_tokens)
score = sum(
tf.get(token, 0.0) * idf.get(token, 0.0)
for token in set(query_tokens)
)
return scoreContextInjector.__init__ method · python · L156-L163 (8 LOC)src/agent_session_linker/context/injector.py
def __init__(self, config: InjectionConfig | None = None) -> None:
self.config = config or InjectionConfig()
self._freshness = FreshnessDecay(
curve=self.config.freshness_curve,
max_age_hours=self.config.max_age_hours,
decay_rate=self.config.decay_rate,
step_thresholds=self.config.step_thresholds,
)ContextInjector.inject method · python · L169-L238 (70 LOC)src/agent_session_linker/context/injector.py
def inject(self, sessions: list[SessionState], query: str) -> str:
"""Select relevant context and return a formatted injection block.
Parameters
----------
sessions:
One or more prior sessions to draw context from. Sessions are
processed together; segments from all sessions compete for
the token budget.
query:
The current user query or task description. Used to compute
TF-IDF relevance scores.
Returns
-------
str
A formatted string ready for inclusion in a system prompt.
Empty string if no relevant content was found.
"""
if not sessions:
return ""
query_tokens = _tokenize(query)
now = datetime.now(timezone.utc)
# Collect all segments and filter by max_age.
eligible: list[tuple[ContextSegment, SessionState]] = []
for session in sessions:
for segment in ContextInjector.score_segment method · python · L240-L272 (33 LOC)src/agent_session_linker/context/injector.py
def score_segment(
self, segment: ContextSegment, query: str, reference_segments: list[ContextSegment]
) -> float:
"""Return the combined relevance+freshness+type score for one segment.
Parameters
----------
segment:
The segment to score.
query:
Current query text.
reference_segments:
All segments in the context corpus (for IDF computation).
Returns
-------
float
Combined score.
"""
now = datetime.now(timezone.utc)
query_tokens = _tokenize(query)
doc_tokens = _tokenize(segment.content)
all_doc_tokens = [_tokenize(s.content) for s in reference_segments]
idf = _compute_idf(all_doc_tokens)
age_hours = (now - segment.timestamp).total_seconds() / 3600.0
freshness = self._freshness.score(age_hours)
relevance = _tfidf_score(query_tokens, doc_tokens, idf)
type_score = self.configContextInjector._build_header method · python · L278-L322 (45 LOC)src/agent_session_linker/context/injector.py
def _build_header(self, sessions: list[SessionState], query_tokens: list[str]) -> str:
"""Build the header block (summary + tasks + entities) even when
no segments pass the age filter."""
parts: list[str] = []
parts.append("--- PRIOR SESSION CONTEXT ---")
if self.config.include_summary:
for session in sessions:
if session.summary:
parts.append(f"\n[Summary from session {session.session_id[:8]}]")
parts.append(session.summary)
if self.config.include_active_tasks:
active_tasks = [
task
for session in sessions
for task in session.tasks
if task.status in (TaskStatus.PENDING, TaskStatus.IN_PROGRESS)
]
if active_tasks:
parts.append("\n[Active Tasks]")
for task in active_tasks:
status_label = task.status.value.replace("_", Repobility (the analyzer behind this table) · https://repobility.com
ContextInjector._format method · python · L324-L342 (19 LOC)src/agent_session_linker/context/injector.py
def _format(
self,
sessions: list[SessionState],
selected: list[tuple[ContextSegment, SessionState]],
query_tokens: list[str],
) -> str:
"""Format selected segments and metadata into the injection block."""
parts: list[str] = [self._build_header(sessions, query_tokens)]
if selected:
parts.append("\n[Relevant Context Segments]")
for segment, session in selected:
role_label = segment.role.upper()
turn_info = f"turn={segment.turn_index}"
session_info = f"session={session.session_id[:8]}"
parts.append(f"\n[{role_label} | {segment.segment_type} | {turn_info} | {session_info}]")
parts.append(segment.content)
return "\n".join(parts)ContextInjector._filter_entities method · python · L345-L358 (14 LOC)src/agent_session_linker/context/injector.py
def _filter_entities(
entities: list[EntityReference], query_tokens: list[str]
) -> list[EntityReference]:
"""Filter entities whose name or aliases overlap with ``query_tokens``."""
query_set = set(query_tokens)
relevant: list[EntityReference] = []
for entity in entities:
name_tokens = set(_tokenize(entity.canonical_name))
alias_tokens: set[str] = set()
for alias in entity.aliases:
alias_tokens.update(_tokenize(alias))
if name_tokens & query_set or alias_tokens & query_set:
relevant.append(entity)
return relevant_term_frequency function · python · L39-L45 (7 LOC)src/agent_session_linker/context/relevance.py
def _term_frequency(tokens: list[str]) -> dict[str, float]:
"""Return length-normalised TF for a token list."""
if not tokens:
return {}
counts = Counter(tokens)
total = len(tokens)
return {term: count / total for term, count in counts.items()}_compute_idf function · python · L48-L73 (26 LOC)src/agent_session_linker/context/relevance.py
def _compute_idf(documents: list[list[str]]) -> dict[str, float]:
"""Compute smoothed IDF over a corpus of tokenised documents.
Uses the formula: ``log((1 + N) / (1 + df)) + 1`` so that terms
appearing in every document still receive a small positive weight.
Parameters
----------
documents:
Each element is the token list for one document.
Returns
-------
dict[str, float]
IDF value per unique term.
"""
num_docs = len(documents)
if num_docs == 0:
return {}
document_freq: Counter[str] = Counter()
for doc_tokens in documents:
document_freq.update(set(doc_tokens))
return {
term: math.log((1 + num_docs) / (1 + df)) + 1
for term, df in document_freq.items()
}RelevanceScorer.__init__ method · python · L99-L105 (7 LOC)src/agent_session_linker/context/relevance.py
def __init__(
self,
smooth_idf: bool = True,
sublinear_tf: bool = False,
) -> None:
self.smooth_idf = smooth_idf
self.sublinear_tf = sublinear_tfRelevanceScorer.score method · python · L111-L137 (27 LOC)src/agent_session_linker/context/relevance.py
def score(self, segment_text: str, query: str) -> float:
"""Compute TF-IDF similarity between ``segment_text`` and ``query``.
The document corpus for IDF purposes consists of only the segment
and the query — this is a lightweight two-document IDF. For
corpus-aware scoring across many segments prefer ``rank``.
Parameters
----------
segment_text:
The candidate segment content to score.
query:
The reference query string.
Returns
-------
float
Similarity score >= 0.0. Higher means more relevant.
"""
query_tokens = _tokenize(query)
doc_tokens = _tokenize(segment_text)
if not query_tokens or not doc_tokens:
return 0.0
idf = self._build_idf([doc_tokens, query_tokens])
return self._tfidf_similarity(query_tokens, doc_tokens, idf)RelevanceScorer.rank method · python · L139-L189 (51 LOC)src/agent_session_linker/context/relevance.py
def rank(
self,
segments: list[object],
query: str,
) -> list[tuple[float, object]]:
"""Rank segments by TF-IDF similarity to ``query``.
IDF is computed across all provided segments at once for accuracy.
Parameters
----------
segments:
Sequence of segments to rank. Each element may be a
``ContextSegment``-like object with a ``.content`` attribute or
a plain string.
query:
The reference query string.
Returns
-------
list[tuple[float, object]]
List of ``(score, segment)`` pairs sorted by score descending.
The original segment objects (not copies) are returned.
"""
if not segments:
return []
query_tokens = _tokenize(query)
# Extract text from each segment.
texts: list[str] = []
for segment in segments:
if isinstance(segment, str):
RelevanceScorer.score_many method · python · L191-L223 (33 LOC)src/agent_session_linker/context/relevance.py
def score_many(
self,
segment_texts: list[str],
query: str,
) -> list[float]:
"""Return per-segment TF-IDF scores for a list of plain text strings.
Uses a shared IDF built from the full corpus, giving more accurate
scores than calling ``score`` individually for each segment.
Parameters
----------
segment_texts:
Raw text strings to score.
query:
The reference query string.
Returns
-------
list[float]
Scores in the same order as ``segment_texts``.
"""
if not segment_texts:
return []
query_tokens = _tokenize(query)
all_token_lists = [_tokenize(text) for text in segment_texts]
idf = self._build_idf(all_token_lists + [query_tokens])
return [
self._tfidf_similarity(query_tokens, doc_tokens, idf)
for doc_tokens in all_token_lists
]Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
RelevanceScorer._build_idf method · python · L229-L256 (28 LOC)src/agent_session_linker/context/relevance.py
def _build_idf(self, documents: list[list[str]]) -> dict[str, float]:
"""Build an IDF mapping from a list of tokenised documents.
Parameters
----------
documents:
Tokenised corpus.
Returns
-------
dict[str, float]
IDF score per term.
"""
num_docs = len(documents)
if num_docs == 0:
return {}
document_freq: Counter[str] = Counter()
for doc_tokens in documents:
document_freq.update(set(doc_tokens))
result: dict[str, float] = {}
for term, df in document_freq.items():
if self.smooth_idf:
result[term] = math.log((1 + num_docs) / (1 + df)) + 1
else:
result[term] = math.log(num_docs / max(1, df))
return resultRelevanceScorer._apply_tf method · python · L258-L277 (20 LOC)src/agent_session_linker/context/relevance.py
def _apply_tf(self, tokens: list[str]) -> dict[str, float]:
"""Compute TF, optionally with sublinear scaling.
Parameters
----------
tokens:
Token list for a single document.
Returns
-------
dict[str, float]
TF per term.
"""
if not tokens:
return {}
counts = Counter(tokens)
total = len(tokens)
if self.sublinear_tf:
return {term: 1.0 + math.log(count) for term, count in counts.items()}
return {term: count / total for term, count in counts.items()}RelevanceScorer._tfidf_similarity method · python · L279-L309 (31 LOC)src/agent_session_linker/context/relevance.py
def _tfidf_similarity(
self,
query_tokens: list[str],
doc_tokens: list[str],
idf: dict[str, float],
) -> float:
"""Compute TF-IDF dot-product similarity.
Parameters
----------
query_tokens:
Tokenised query.
doc_tokens:
Tokenised document.
idf:
Pre-computed IDF map.
Returns
-------
float
Similarity score >= 0.0.
"""
if not query_tokens or not doc_tokens:
return 0.0
doc_tf = self._apply_tf(doc_tokens)
return sum(
doc_tf.get(token, 0.0) * idf.get(token, 0.0)
for token in set(query_tokens)
)_term_frequency function · python · L52-L58 (7 LOC)src/agent_session_linker/context/summarizer.py
def _term_frequency(tokens: list[str]) -> dict[str, float]:
"""Compute normalised TF for a token list."""
if not tokens:
return {}
counts = Counter(tokens)
total = len(tokens)
return {term: count / total for term, count in counts.items()}_compute_idf function · python · L61-L72 (12 LOC)src/agent_session_linker/context/summarizer.py
def _compute_idf(documents: list[list[str]]) -> dict[str, float]:
"""Compute IDF across a corpus of tokenised documents."""
num_docs = len(documents)
if num_docs == 0:
return {}
document_freq: Counter[str] = Counter()
for doc_tokens in documents:
document_freq.update(set(doc_tokens))
return {
term: math.log((1 + num_docs) / (1 + df)) + 1
for term, df in document_freq.items()
}_score_sentence function · python · L75-L115 (41 LOC)src/agent_session_linker/context/summarizer.py
def _score_sentence(
sentence_tokens: list[str],
idf: dict[str, float],
position_index: int,
total_sentences: int,
) -> float:
"""Score one sentence by TF-IDF sum weighted by position.
Sentences appearing earlier receive a higher positional boost because
the first sentences of a segment tend to carry higher information density
(topic introduction, conclusions, decisions).
Parameters
----------
sentence_tokens:
Tokenised words in the sentence.
idf:
IDF scores for all terms in the corpus.
position_index:
Zero-based position of this sentence within its segment.
total_sentences:
Total sentence count in the segment (used for normalisation).
Returns
-------
float
Composite score for this sentence.
"""
if not sentence_tokens:
return 0.0
tf = _term_frequency(sentence_tokens)
tfidf_sum = sum(tf.get(term, 0.0) * idf.get(term, 0.0) for term in tf)
# PositionContextSummarizer.__init__ method · python · L141-L147 (7 LOC)src/agent_session_linker/context/summarizer.py
def __init__(
self,
max_sentences_per_segment: int = 5,
position_bias: bool = True,
) -> None:
self.max_sentences_per_segment = max_sentences_per_segment
self.position_bias = position_biasContextSummarizer.summarize method · python · L153-L246 (94 LOC)src/agent_session_linker/context/summarizer.py
def summarize(self, segments: list[object], max_tokens: int) -> str:
"""Produce an extractive summary within ``max_tokens``.
Each element of ``segments`` may be either a
``ContextSegment``-like object (with a ``.content`` attribute) or
a plain string. Both forms are accepted so the summarizer can be
used independently of the session model.
Parameters
----------
segments:
Ordered sequence of context segments or plain text strings.
max_tokens:
Target token budget for the returned summary. The summarizer
selects sentences greedily until this budget is exhausted.
Returns
-------
str
The extractive summary. An empty string is returned when
``segments`` is empty or contains no usable text.
"""
if not segments:
return ""
# Extract text content from segments (support both str and objects).
If a scraper extracted this row, it came from Repobility (https://repobility.com)
ContextSummarizer.summarize_text method · python · L248-L263 (16 LOC)src/agent_session_linker/context/summarizer.py
def summarize_text(self, text: str, max_tokens: int) -> str:
"""Convenience wrapper: summarize a single plain-text string.
Parameters
----------
text:
Raw text to summarize.
max_tokens:
Target token budget.
Returns
-------
str
Extractive summary.
"""
return self.summarize([text], max_tokens)Session.__init__ method · python · L40-L50 (11 LOC)src/agent_session_linker/convenience.py
def __init__(self, agent_id: str = "default-agent") -> None:
from agent_session_linker.storage.memory import InMemoryBackend
from agent_session_linker.session.manager import SessionManager
self._backend = InMemoryBackend()
self._manager = SessionManager(
backend=self._backend,
default_agent_id=agent_id,
)
self._state = self._manager.create_session(agent_id=agent_id)
self.agent_id = agent_idSession.save method · python · L62-L71 (10 LOC)src/agent_session_linker/convenience.py
def save(self) -> str:
"""Persist the current session state.
Returns
-------
str
The session ID of the saved session.
"""
self._manager.save_session(self._state)
return self._state.session_idpage 1 / 5next ›