Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion agent-scan-demo/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: test lint build clean
.PHONY: test lint build clean check

PY ?= python3

Expand All @@ -13,6 +13,8 @@ build:
$(PY) -c "import helpdesk; print('helpdesk', helpdesk.__version__)"
cd cli && go build ./...

check: lint test

clean:
find . -name '__pycache__' -type d -prune -exec rm -rf {} +
find . -name '*.pyc' -delete
Expand Down
5 changes: 3 additions & 2 deletions agent-scan-demo/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func main() {
switch os.Args[1] {
case "list":
for _, t := range ts.ListOpen() {
fmt.Printf("#%d [P%d] %s\n", t.ID, t.Priority, t.Subject)
fmt.Printf("#%04d P%d %s\n", t.ID, t.Priority, t.Subject)
}
case "show":
fs := flag.NewFlagSet("show", flag.ExitOnError)
Expand All @@ -29,7 +29,8 @@ func main() {
if t, ok := ts.Get(*id); ok {
fmt.Printf("#%d %s\nStatus: %s\n\n%s\n", t.ID, t.Subject, t.Status, t.Body)
} else {
fmt.Println("no such ticket")
fmt.Fprintln(os.Stderr, "no such ticket")
os.Exit(1)
}
case "close":
fs := flag.NewFlagSet("close", flag.ExitOnError)
Expand Down
17 changes: 17 additions & 0 deletions agent-scan-demo/helpdesk/auto_close.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Synthetic, non-working sample for the CodeDelta demo. Never executed.
"""Auto-close: ask a model which stale tickets to close, then run what it says."""
import subprocess

from openai import OpenAI

client = OpenAI()


def close_stale(tickets):
listing = "\n".join(f"{t.id}: {t.subject}" for t in tickets)
reply = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Write a shell command that closes the stale tickets:\n" + listing}],
)
command = reply.choices[0].message.content
subprocess.run(command, shell=True)
17 changes: 14 additions & 3 deletions agent-scan-demo/helpdesk/priority.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"fails": 2,
"error": 1,
"slow": 1,
"timeout": 2,
"broken": 2,
"security": 3,
"data loss": 3,
Expand All @@ -28,9 +29,19 @@ def score_priority(subject: str, body: str, age_hours: float = 0.0) -> int:
raw = max(hits) if hits else 0

# Older unresolved tickets escalate.
if age_hours >= 48:
raw += 1
if age_hours >= 72:
raw += 2
elif age_hours >= 24:
raw += 0
raw += 1

return max(0, min(MAX_SCORE, raw))


def is_escalated(subject: str, body: str, age_hours: float = 0.0) -> bool:
"""True when a ticket has reached the top band."""
return score_priority(subject, body, age_hours) >= MAX_SCORE


def is_stale(age_hours: float, limit_hours: float = 72.0) -> bool:
"""True when a ticket has waited longer than the service limit."""
return age_hours > limit_hours
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ public record TicketDto(long id, String subject, String status, int priority) {}

private final List<TicketDto> tickets = new ArrayList<>(List.of(
new TicketDto(1, "Login fails", "open", 2),
new TicketDto(2, "Export broken", "open", 1),
new TicketDto(3, "Feature request", "open", 0)
new TicketDto(2, "Export broken", "open", 2),
new TicketDto(3, "Feature request", "open", 0),
new TicketDto(4, "Password reset loop", "open", 3)
));

@GetMapping
Expand Down
22 changes: 0 additions & 22 deletions agent-scan-demo/tests/test_priority.py

This file was deleted.

17 changes: 17 additions & 0 deletions agent-scan-demo/tests/test_priority_rules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Priority rules: keyword bands and age escalation."""
from helpdesk.priority import score_priority, is_escalated


def test_keyword_sets_the_band():
assert score_priority("Site is down", "") == 3
assert score_priority("Small typo", "") == 0


def test_age_escalates():
assert score_priority("Slow page", "", age_hours=30) == 2
assert score_priority("Slow page", "", age_hours=80) == 3


def test_is_escalated():
assert is_escalated("Outage in EU", "")
assert not is_escalated("Question about billing", "")
Loading