Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
Son Of Anton
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Son Of Anton
Commits
6774dcff
Commit
6774dcff
authored
Mar 30, 2026
by
Administrator
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update 3 files via Son of Anton
parent
3568bd0b
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
278 additions
and
119 deletions
+278
-119
web_search_service.py
backend/services/web_search_service.py
+209
-52
Sidebar.jsx
frontend/src/components/Sidebar.jsx
+67
-65
ChatPage.jsx
frontend/src/pages/ChatPage.jsx
+2
-2
No files found.
backend/services/web_search_service.py
View file @
6774dcff
This diff is collapsed.
Click to expand it.
frontend/src/components/Sidebar.jsx
View file @
6774dcff
...
...
@@ -7,9 +7,10 @@ import {
Edit3
,
Check
,
X
,
GitBranch
,
}
from
"lucide-react"
;
export
default
function
Sidebar
({
activeChatId
,
onSelectChat
,
isOpen
,
onClose
})
{
export
default
function
Sidebar
({
mobile
,
onClose
})
{
const
{
state
,
dispatch
}
=
useApp
();
const
nav
=
useNavigate
();
const
activeChatId
=
state
.
activeChatId
;
const
[
editId
,
setEditId
]
=
useState
(
null
);
const
[
editTitle
,
setEditTitle
]
=
useState
(
""
);
...
...
@@ -22,11 +23,15 @@ export default function Sidebar({ activeChatId, onSelectChat, isOpen, onClose })
})();
},
[
state
.
token
,
dispatch
]);
function
handleSelectChat
(
chatId
)
{
dispatch
({
type
:
"SET_ACTIVE_CHAT"
,
chatId
});
if
(
onClose
)
onClose
();
}
async
function
handleNew
()
{
try
{
const
chat
=
await
createChat
(
state
.
token
);
dispatch
({
type
:
"ADD_CHAT"
,
chat
});
onSelectChat
(
chat
.
id
);
}
catch
{
}
}
...
...
@@ -36,7 +41,6 @@ export default function Sidebar({ activeChatId, onSelectChat, isOpen, onClose })
try
{
await
deleteChat
(
state
.
token
,
chatId
);
dispatch
({
type
:
"REMOVE_CHAT"
,
chatId
});
if
(
activeChatId
===
chatId
)
onSelectChat
(
null
);
}
catch
{
}
}
...
...
@@ -52,73 +56,71 @@ export default function Sidebar({ activeChatId, onSelectChat, isOpen, onClose })
const
isSuperadmin
=
state
.
user
?.
role
===
"superadmin"
;
return
(
<>
{
isOpen
&&
<
div
className=
"fixed inset-0 bg-black/50 z-40 md:hidden"
onClick=
{
onClose
}
/>
}
<
div
className=
{
`fixed md:static z-50 inset-y-0 left-0 w-72 bg-anton-surface border-r border-anton-border flex flex-col transition-transform duration-200 ${isOpen ? "translate-x-0" : "-translate-x-full md:translate-x-0"}`
}
>
{
/* Header */
}
<
div
className=
"p-3 border-b border-anton-border"
>
<
div
className=
"flex items-center gap-2 mb-3"
>
<
div
className=
"w-8 h-8 rounded-lg bg-gradient-to-br from-anton-accent to-red-600 flex items-center justify-center"
>
<
Flame
size=
{
16
}
className=
"text-white"
/>
</
div
>
<
div
>
<
h1
className=
"text-sm font-bold text-white"
>
Son of Anton
</
h1
>
<
p
className=
"text-[10px] text-anton-muted"
>
v4.0.0 — The Architect
</
p
>
</
div
>
<
div
className=
{
`${mobile ? "h-full" : "h-dvh"} w-72 bg-anton-surface border-r border-anton-border flex flex-col`
}
>
{
/* Header */
}
<
div
className=
"p-3 border-b border-anton-border"
>
<
div
className=
"flex items-center gap-2 mb-3"
>
<
div
className=
"w-8 h-8 rounded-lg bg-gradient-to-br from-anton-accent to-red-600 flex items-center justify-center"
>
<
Flame
size=
{
16
}
className=
"text-white"
/>
</
div
>
<
div
>
<
h1
className=
"text-sm font-bold text-white"
>
Son of Anton
</
h1
>
<
p
className=
"text-[10px] text-anton-muted"
>
v4.1.0 — The Architect
</
p
>
</
div
>
<
button
onClick=
{
handleNew
}
className=
"w-full flex items-center justify-center gap-1.5 bg-anton-accent text-white rounded-lg py-2 text-sm hover:opacity-80 transition"
>
<
Plus
size=
{
16
}
/>
New Chat
</
button
>
</
div
>
<
button
onClick=
{
handleNew
}
className=
"w-full flex items-center justify-center gap-1.5 bg-anton-accent text-white rounded-lg py-2 text-sm hover:opacity-80 transition"
>
<
Plus
size=
{
16
}
/>
New Chat
</
button
>
</
div
>
{
/* Chat list */
}
<
div
className=
"flex-1 overflow-y-auto p-2 space-y-0.5"
>
{
state
.
chats
.
map
((
c
)
=>
(
<
div
key=
{
c
.
id
}
onClick=
{
()
=>
{
onSelectChat
(
c
.
id
);
onClose
?.();
}
}
className=
{
`group flex items-center gap-2 px-3 py-2 rounded-lg cursor-pointer transition text-sm ${activeChatId === c.id ? "bg-anton-accent/15 text-white" : "text-anton-muted hover:bg-anton-card hover:text-white"}`
}
>
<
MessageSquare
size=
{
14
}
className=
"shrink-0"
/>
{
editId
===
c
.
id
?
(
<
div
className=
"flex-1 flex items-center gap-1"
>
<
input
value=
{
editTitle
}
onChange=
{
(
e
)
=>
setEditTitle
(
e
.
target
.
value
)
}
onKeyDown=
{
(
e
)
=>
e
.
key
===
"Enter"
&&
handleRename
(
c
.
id
)
}
className=
"flex-1 bg-anton-bg border border-anton-border rounded px-1.5 py-0.5 text-xs text-white"
autoFocus
/>
<
button
onClick=
{
()
=>
handleRename
(
c
.
id
)
}
className=
"text-green-400"
><
Check
size=
{
12
}
/></
button
>
<
button
onClick=
{
()
=>
setEditId
(
null
)
}
className=
"text-red-400"
><
X
size=
{
12
}
/></
button
>
{
/* Chat list */
}
<
div
className=
"flex-1 overflow-y-auto p-2 space-y-0.5"
>
{
state
.
chats
.
map
((
c
)
=>
(
<
div
key=
{
c
.
id
}
onClick=
{
()
=>
handleSelectChat
(
c
.
id
)
}
className=
{
`group flex items-center gap-2 px-3 py-2 rounded-lg cursor-pointer transition text-sm ${activeChatId === c.id ? "bg-anton-accent/15 text-white" : "text-anton-muted hover:bg-anton-card hover:text-white"}`
}
>
<
MessageSquare
size=
{
14
}
className=
"shrink-0"
/>
{
editId
===
c
.
id
?
(
<
div
className=
"flex-1 flex items-center gap-1"
>
<
input
value=
{
editTitle
}
onChange=
{
(
e
)
=>
setEditTitle
(
e
.
target
.
value
)
}
onKeyDown=
{
(
e
)
=>
e
.
key
===
"Enter"
&&
handleRename
(
c
.
id
)
}
className=
"flex-1 bg-anton-bg border border-anton-border rounded px-1.5 py-0.5 text-xs text-white"
autoFocus
onClick=
{
(
e
)
=>
e
.
stopPropagation
()
}
/>
<
button
onClick=
{
(
e
)
=>
{
e
.
stopPropagation
();
handleRename
(
c
.
id
);
}
}
className=
"text-green-400"
><
Check
size=
{
12
}
/></
button
>
<
button
onClick=
{
(
e
)
=>
{
e
.
stopPropagation
();
setEditId
(
null
);
}
}
className=
"text-red-400"
><
X
size=
{
12
}
/></
button
>
</
div
>
)
:
(
<>
<
span
className=
"flex-1 truncate text-xs"
>
{
c
.
title
}
</
span
>
<
div
className=
"flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity"
>
{
c
.
linked_repo_id
&&
<
GitBranch
size=
{
11
}
className=
"text-orange-400"
/>
}
<
button
onClick=
{
(
e
)
=>
{
e
.
stopPropagation
();
setEditId
(
c
.
id
);
setEditTitle
(
c
.
title
);
}
}
className=
"p-0.5 hover:text-anton-accent"
><
Edit3
size=
{
11
}
/></
button
>
<
button
onClick=
{
(
e
)
=>
handleDelete
(
e
,
c
.
id
)
}
className=
"p-0.5 hover:text-red-400"
><
Trash2
size=
{
11
}
/></
button
>
</
div
>
)
:
(
<>
<
span
className=
"flex-1 truncate text-xs"
>
{
c
.
title
}
</
span
>
<
div
className=
"flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity"
>
{
c
.
linked_repo_id
&&
<
GitBranch
size=
{
11
}
className=
"text-orange-400"
/>
}
<
button
onClick=
{
(
e
)
=>
{
e
.
stopPropagation
();
setEditId
(
c
.
id
);
setEditTitle
(
c
.
title
);
}
}
className=
"p-0.5 hover:text-anton-accent"
><
Edit3
size=
{
11
}
/></
button
>
<
button
onClick=
{
(
e
)
=>
handleDelete
(
e
,
c
.
id
)
}
className=
"p-0.5 hover:text-red-400"
><
Trash2
size=
{
11
}
/></
button
>
</
div
>
</>
)
}
</
div
>
))
}
</
div
>
</>
)
}
</
div
>
))
}
</
div
>
{
/* Footer */
}
<
div
className=
"p-2 border-t border-anton-border space-y-0.5"
>
{
isSuperadmin
&&
(
<>
<
button
onClick=
{
()
=>
nav
(
"/gitlab"
)
}
className=
"w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-orange-400 hover:bg-anton-card transition"
>
<
GitBranch
size=
{
14
}
/>
GitLab Center
</
button
>
<
button
onClick=
{
()
=>
nav
(
"/admin"
)
}
className=
"w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-anton-muted hover:bg-anton-card hover:text-white transition"
>
<
Shield
size=
{
14
}
/>
Admin
</
button
>
</>
)
}
<
button
onClick=
{
()
=>
nav
(
"/knowledge"
)
}
className=
"w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-anton-muted hover:bg-anton-card hover:text-white transition"
>
<
BookOpen
size=
{
14
}
/>
Knowledge
</
button
>
<
button
onClick=
{
()
=>
dispatch
({
type
:
"LOGOUT"
})
}
className=
"w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-anton-muted hover:bg-anton-card hover:text-red-400 transition"
>
<
LogOut
size=
{
14
}
/>
Logout
</
button
>
<
div
className=
"px-3 py-1 text-[10px] text-anton-muted"
>
{
state
.
user
?.
username
}
•
{
state
.
user
?.
role
}
</
div
>
</
div
>
{
/* Footer */
}
<
div
className=
"p-2 border-t border-anton-border space-y-0.5"
>
{
isSuperadmin
&&
(
<>
<
button
onClick=
{
()
=>
nav
(
"/gitlab"
)
}
className=
"w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-orange-400 hover:bg-anton-card transition"
>
<
GitBranch
size=
{
14
}
/>
GitLab Center
</
button
>
<
button
onClick=
{
()
=>
nav
(
"/admin"
)
}
className=
"w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-anton-muted hover:bg-anton-card hover:text-white transition"
>
<
Shield
size=
{
14
}
/>
Admin
</
button
>
</>
)
}
<
button
onClick=
{
()
=>
nav
(
"/knowledge"
)
}
className=
"w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-anton-muted hover:bg-anton-card hover:text-white transition"
>
<
BookOpen
size=
{
14
}
/>
Knowledge
</
button
>
<
button
onClick=
{
()
=>
dispatch
({
type
:
"LOGOUT"
})
}
className=
"w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-anton-muted hover:bg-anton-card hover:text-red-400 transition"
>
<
LogOut
size=
{
14
}
/>
Logout
</
button
>
<
div
className=
"px-3 py-1 text-[10px] text-anton-muted"
>
{
state
.
user
?.
username
}
•
{
state
.
user
?.
role
}
</
div
>
</
div
>
</>
</
div
>
);
}
\ No newline at end of file
frontend/src/pages/ChatPage.jsx
View file @
6774dcff
...
...
@@ -29,7 +29,7 @@ export default function ChatPage() {
return
(
<
div
className=
"h-full h-dvh flex overflow-hidden bg-anton-bg"
>
{
/* Desktop sidebar */
}
{
/* Desktop sidebar
— always visible
*/
}
<
div
className=
"hidden sm:flex"
>
<
Sidebar
/>
</
div
>
...
...
@@ -75,7 +75,7 @@ export default function ChatPage() {
{
/* Chat or empty state */
}
{
state
.
activeChatId
?
(
<
ChatView
chatId=
{
state
.
activeChatId
}
/>
<
ChatView
key=
{
state
.
activeChatId
}
chatId=
{
state
.
activeChatId
}
/>
)
:
(
<
div
className=
"flex-1 flex items-center justify-center p-6"
>
<
div
className=
"text-center max-w-sm"
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment