Increase security and reformat
This commit is contained in:
@@ -45,14 +45,15 @@ class BPParsedCommand(dict):
|
||||
return str(self.get("remainder_text") or "")
|
||||
|
||||
|
||||
|
||||
def parse_bp_subcommand(text: str) -> BPParsedCommand:
|
||||
body = str(text or "")
|
||||
if _BP_SET_RANGE_RE.match(body):
|
||||
return BPParsedCommand(command="set_range", remainder_text="")
|
||||
match = _BP_SET_RE.match(body)
|
||||
if match:
|
||||
return BPParsedCommand(command="set", remainder_text=str(match.group("rest") or "").strip())
|
||||
return BPParsedCommand(
|
||||
command="set", remainder_text=str(match.group("rest") or "").strip()
|
||||
)
|
||||
return BPParsedCommand(command=None, remainder_text="")
|
||||
|
||||
|
||||
@@ -63,7 +64,9 @@ def bp_subcommands_enabled() -> bool:
|
||||
return bool(raw)
|
||||
|
||||
|
||||
def bp_trigger_matches(message_text: str, trigger_token: str, exact_match_only: bool) -> bool:
|
||||
def bp_trigger_matches(
|
||||
message_text: str, trigger_token: str, exact_match_only: bool
|
||||
) -> bool:
|
||||
body = str(message_text or "").strip()
|
||||
trigger = str(trigger_token or "").strip()
|
||||
parsed = parse_bp_subcommand(body)
|
||||
@@ -144,7 +147,8 @@ class BPCommandHandler(CommandHandler):
|
||||
"enabled": True,
|
||||
"generation_mode": "ai" if variant_key == "bp" else "verbatim",
|
||||
"send_plan_to_egress": "post_result" in action_types,
|
||||
"send_status_to_source": str(profile.visibility_mode or "") == "status_in_source",
|
||||
"send_status_to_source": str(profile.visibility_mode or "")
|
||||
== "status_in_source",
|
||||
"send_status_to_egress": False,
|
||||
"store_document": True,
|
||||
}
|
||||
@@ -224,10 +228,14 @@ class BPCommandHandler(CommandHandler):
|
||||
ts__lte=int(trigger.ts or 0),
|
||||
)
|
||||
.order_by("ts")
|
||||
.select_related("session", "session__identifier", "session__identifier__person")
|
||||
.select_related(
|
||||
"session", "session__identifier", "session__identifier__person"
|
||||
)
|
||||
)
|
||||
|
||||
def _annotation(self, mode: str, message_count: int, has_addendum: bool = False) -> str:
|
||||
def _annotation(
|
||||
self, mode: str, message_count: int, has_addendum: bool = False
|
||||
) -> str:
|
||||
if mode == "set" and has_addendum:
|
||||
return "Generated from 1 message + 1 addendum."
|
||||
if message_count == 1:
|
||||
@@ -291,21 +299,29 @@ class BPCommandHandler(CommandHandler):
|
||||
if anchor is None:
|
||||
run.status = "failed"
|
||||
run.error = "bp_set_range_requires_reply_target"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="failed", error=run.error)
|
||||
rows = await self._load_window(trigger, anchor)
|
||||
deterministic_content = plain_text_blob(rows)
|
||||
if not deterministic_content.strip():
|
||||
run.status = "failed"
|
||||
run.error = "bp_set_range_empty_content"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="failed", error=run.error)
|
||||
if str(policy.get("generation_mode") or "verbatim") == "ai":
|
||||
ai_obj = await sync_to_async(lambda: AI.objects.filter(user=trigger.user).first())()
|
||||
ai_obj = await sync_to_async(
|
||||
lambda: AI.objects.filter(user=trigger.user).first()
|
||||
)()
|
||||
if ai_obj is None:
|
||||
run.status = "failed"
|
||||
run.error = "ai_not_configured"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="failed", error=run.error)
|
||||
prompt = [
|
||||
{
|
||||
@@ -329,12 +345,16 @@ class BPCommandHandler(CommandHandler):
|
||||
except Exception as exc:
|
||||
run.status = "failed"
|
||||
run.error = f"bp_ai_failed:{exc}"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="failed", error=run.error)
|
||||
if not content:
|
||||
run.status = "failed"
|
||||
run.error = "empty_ai_response"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="failed", error=run.error)
|
||||
else:
|
||||
content = deterministic_content
|
||||
@@ -360,9 +380,7 @@ class BPCommandHandler(CommandHandler):
|
||||
elif anchor is not None and remainder:
|
||||
base = str(anchor.text or "").strip() or "(no text)"
|
||||
content = (
|
||||
f"{base}\n"
|
||||
"--- Addendum (newer message text) ---\n"
|
||||
f"{remainder}"
|
||||
f"{base}\n" "--- Addendum (newer message text) ---\n" f"{remainder}"
|
||||
)
|
||||
source_ids.extend([str(anchor.id), str(trigger.id)])
|
||||
has_addendum = True
|
||||
@@ -373,15 +391,21 @@ class BPCommandHandler(CommandHandler):
|
||||
else:
|
||||
run.status = "failed"
|
||||
run.error = "bp_set_empty_content"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="failed", error=run.error)
|
||||
|
||||
if str(policy.get("generation_mode") or "verbatim") == "ai":
|
||||
ai_obj = await sync_to_async(lambda: AI.objects.filter(user=trigger.user).first())()
|
||||
ai_obj = await sync_to_async(
|
||||
lambda: AI.objects.filter(user=trigger.user).first()
|
||||
)()
|
||||
if ai_obj is None:
|
||||
run.status = "failed"
|
||||
run.error = "ai_not_configured"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="failed", error=run.error)
|
||||
prompt = [
|
||||
{
|
||||
@@ -405,16 +429,22 @@ class BPCommandHandler(CommandHandler):
|
||||
except Exception as exc:
|
||||
run.status = "failed"
|
||||
run.error = f"bp_ai_failed:{exc}"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="failed", error=run.error)
|
||||
if not ai_content:
|
||||
run.status = "failed"
|
||||
run.error = "empty_ai_response"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="failed", error=run.error)
|
||||
content = ai_content
|
||||
|
||||
annotation = self._annotation("set", 1 if not has_addendum else 2, has_addendum)
|
||||
annotation = self._annotation(
|
||||
"set", 1 if not has_addendum else 2, has_addendum
|
||||
)
|
||||
doc = None
|
||||
if bool(policy.get("store_document", True)):
|
||||
doc = await self._persist_document(
|
||||
@@ -430,7 +460,9 @@ class BPCommandHandler(CommandHandler):
|
||||
else:
|
||||
run.status = "failed"
|
||||
run.error = "bp_unknown_subcommand"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="failed", error=run.error)
|
||||
|
||||
fanout_stats = {"sent_bindings": 0, "failed_bindings": 0}
|
||||
@@ -479,7 +511,9 @@ class BPCommandHandler(CommandHandler):
|
||||
if trigger.reply_to_id is None:
|
||||
run.status = "failed"
|
||||
run.error = "bp_requires_reply_target"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="failed", error=run.error)
|
||||
|
||||
anchor = trigger.reply_to
|
||||
@@ -488,7 +522,9 @@ class BPCommandHandler(CommandHandler):
|
||||
rows,
|
||||
author_rewrites={"USER": "Operator", "BOT": "Assistant"},
|
||||
)
|
||||
max_transcript_chars = int(getattr(settings, "BP_MAX_TRANSCRIPT_CHARS", 12000) or 12000)
|
||||
max_transcript_chars = int(
|
||||
getattr(settings, "BP_MAX_TRANSCRIPT_CHARS", 12000) or 12000
|
||||
)
|
||||
transcript = _clamp_transcript(transcript, max_transcript_chars)
|
||||
default_template = (
|
||||
"Business Plan:\n"
|
||||
@@ -499,7 +535,9 @@ class BPCommandHandler(CommandHandler):
|
||||
"- Risks"
|
||||
)
|
||||
template_text = profile.template_text or default_template
|
||||
max_template_chars = int(getattr(settings, "BP_MAX_TEMPLATE_CHARS", 5000) or 5000)
|
||||
max_template_chars = int(
|
||||
getattr(settings, "BP_MAX_TEMPLATE_CHARS", 5000) or 5000
|
||||
)
|
||||
template_text = str(template_text or "")[:max_template_chars]
|
||||
generation_mode = str(policy.get("generation_mode") or "ai")
|
||||
if generation_mode == "verbatim":
|
||||
@@ -507,14 +545,20 @@ class BPCommandHandler(CommandHandler):
|
||||
if not summary.strip():
|
||||
run.status = "failed"
|
||||
run.error = "bp_verbatim_empty_content"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="failed", error=run.error)
|
||||
else:
|
||||
ai_obj = await sync_to_async(lambda: AI.objects.filter(user=trigger.user).first())()
|
||||
ai_obj = await sync_to_async(
|
||||
lambda: AI.objects.filter(user=trigger.user).first()
|
||||
)()
|
||||
if ai_obj is None:
|
||||
run.status = "failed"
|
||||
run.error = "ai_not_configured"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="failed", error=run.error)
|
||||
|
||||
prompt = [
|
||||
@@ -530,13 +574,20 @@ class BPCommandHandler(CommandHandler):
|
||||
},
|
||||
]
|
||||
try:
|
||||
summary = str(await ai_runner.run_prompt(prompt, ai_obj, operation="command_bp_extract") or "").strip()
|
||||
summary = str(
|
||||
await ai_runner.run_prompt(
|
||||
prompt, ai_obj, operation="command_bp_extract"
|
||||
)
|
||||
or ""
|
||||
).strip()
|
||||
if not summary:
|
||||
raise RuntimeError("empty_ai_response")
|
||||
except Exception as exc:
|
||||
run.status = "failed"
|
||||
run.error = f"bp_ai_failed:{exc}"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="failed", error=run.error)
|
||||
|
||||
annotation = self._annotation("legacy", len(rows))
|
||||
@@ -588,23 +639,31 @@ class BPCommandHandler(CommandHandler):
|
||||
|
||||
async def execute(self, ctx: CommandContext) -> CommandResult:
|
||||
trigger = await sync_to_async(
|
||||
lambda: Message.objects.select_related("user", "session").filter(id=ctx.message_id).first()
|
||||
lambda: Message.objects.select_related("user", "session")
|
||||
.filter(id=ctx.message_id)
|
||||
.first()
|
||||
)()
|
||||
if trigger is None:
|
||||
return CommandResult(ok=False, status="failed", error="trigger_not_found")
|
||||
|
||||
profile = await sync_to_async(
|
||||
lambda: trigger.user.commandprofile_set.filter(slug=self.slug, enabled=True).first()
|
||||
lambda: trigger.user.commandprofile_set.filter(
|
||||
slug=self.slug, enabled=True
|
||||
).first()
|
||||
)()
|
||||
if profile is None:
|
||||
return CommandResult(ok=False, status="skipped", error="profile_missing")
|
||||
|
||||
actions = await sync_to_async(list)(
|
||||
CommandAction.objects.filter(profile=profile, enabled=True).order_by("position", "id")
|
||||
CommandAction.objects.filter(profile=profile, enabled=True).order_by(
|
||||
"position", "id"
|
||||
)
|
||||
)
|
||||
action_types = {row.action_type for row in actions}
|
||||
if "extract_bp" not in action_types:
|
||||
return CommandResult(ok=False, status="skipped", error="extract_bp_disabled")
|
||||
return CommandResult(
|
||||
ok=False, status="skipped", error="extract_bp_disabled"
|
||||
)
|
||||
|
||||
run, created = await sync_to_async(CommandRun.objects.get_or_create)(
|
||||
profile=profile,
|
||||
@@ -612,7 +671,11 @@ class BPCommandHandler(CommandHandler):
|
||||
defaults={"user": trigger.user, "status": "running"},
|
||||
)
|
||||
if not created and run.status in {"ok", "running"}:
|
||||
return CommandResult(ok=True, status="ok", payload={"document_id": str(run.result_ref_id or "")})
|
||||
return CommandResult(
|
||||
ok=True,
|
||||
status="ok",
|
||||
payload={"document_id": str(run.result_ref_id or "")},
|
||||
)
|
||||
|
||||
run.status = "running"
|
||||
run.error = ""
|
||||
@@ -627,7 +690,9 @@ class BPCommandHandler(CommandHandler):
|
||||
if not bool(policy.get("enabled")):
|
||||
run.status = "skipped"
|
||||
run.error = f"variant_disabled:{variant_key}"
|
||||
await sync_to_async(run.save)(update_fields=["status", "error", "updated_at"])
|
||||
await sync_to_async(run.save)(
|
||||
update_fields=["status", "error", "updated_at"]
|
||||
)
|
||||
return CommandResult(ok=False, status="skipped", error=run.error)
|
||||
|
||||
parsed = parse_bp_subcommand(ctx.message_text)
|
||||
|
||||
Reference in New Issue
Block a user