Skip to content

Commit e2107bd

Browse files
northdpoleclaude
andcommitted
feat(comprehension): L4 reads up to three named projects whole (OWASP_CX_LONGCTX_PROJECTS)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 parent 69235cc commit e2107bd

2 files changed

Lines changed: 28 additions & 18 deletions

File tree

‎.env.example‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ OWASP_PGVECTOR_HALFVEC=0
146146
OWASP_CX_LONGCTX=1
147147
# Max characters of one project to read whole.
148148
OWASP_CX_LONGCTX_CHARS=700000
149+
# How many named projects to read whole at once (questions naming more fall back to retrieval).
150+
OWASP_CX_LONGCTX_PROJECTS=3
149151
# Off: hybrid keyword search (-2.5 points, +5 s), rerank (-2), query rewrite (-3), verify
150152
# (+/-3, hurts with LONGCTX), per-project (0), expand (+1, noise), count (+1, slower),
151153
# merged single call (-13, loses citations), in-process answer cache (real traffic only).

‎application/utils/comprehension/retrieve.py‎

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -331,31 +331,39 @@ def assemble_project_sources(
331331
return [("\n".join(by_file[c]), [c]) for c in order]
332332

333333

334+
def longctx_max_projects() -> int:
335+
try:
336+
return max(1, int(os.environ.get("OWASP_CX_LONGCTX_PROJECTS", "3")))
337+
except ValueError:
338+
return 3
339+
340+
334341
def project_sources(question: str) -> List[tuple]:
335-
"""The whole text of the single project the question names ([] if none/several/too big)."""
342+
"""Whole text of the projects the question names (1..N); [] if none, too many or too big."""
336343
try:
337344
from sqlalchemy import text as sql_text
338345

339346
from application import sqla
340347

348+
limit = longctx_max_projects()
341349
with sqla.session.get_bind().connect() as conn:
342-
slugs = matched_slugs(question, _known_slugs(conn))
343-
if len(slugs) != 1:
350+
slugs = matched_slugs(question, _known_slugs(conn), limit=limit + 1)
351+
if not slugs or len(slugs) > limit:
344352
return []
345-
rows = conn.execute(
346-
sql_text(
347-
"SELECT embeddings_url, embeddings_content FROM embeddings "
348-
"WHERE source_channel = :channel AND embeddings_url LIKE :pat "
349-
"ORDER BY embeddings_url"
350-
),
351-
{
352-
"channel": CHANNEL_AGENT,
353-
"pat": f"owasp-agent://evidence/comprehension-{slugs[0]}-raw-%",
354-
},
355-
).fetchall()
356-
return assemble_project_sources(
357-
[(r.embeddings_url, r.embeddings_content) for r in rows],
358-
max_chars=longctx_max_chars(),
359-
)
353+
rows: List[tuple] = []
354+
for slug in slugs:
355+
found = conn.execute(
356+
sql_text(
357+
"SELECT embeddings_url, embeddings_content FROM embeddings "
358+
"WHERE source_channel = :channel AND embeddings_url LIKE :pat "
359+
"ORDER BY embeddings_url"
360+
),
361+
{
362+
"channel": CHANNEL_AGENT,
363+
"pat": f"owasp-agent://evidence/comprehension-{slug}-raw-%",
364+
},
365+
).fetchall()
366+
rows += [(r.embeddings_url, r.embeddings_content) for r in found]
367+
return assemble_project_sources(rows, max_chars=longctx_max_chars())
360368
except Exception:
361369
return []

0 commit comments

Comments
 (0)