Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
b4cbc00
feat: implement Vulti in-app Agent Chat
enriquesouza Feb 25, 2026
f9d7e7d
fix(agent): override backend openrouter model default
enriquesouza Feb 25, 2026
365e6a8
feat(agent): implement missing client-side tool executions for price/…
enriquesouza Feb 25, 2026
327d249
style(agent): fix Vault header overlap and migrate starters to Chat S…
enriquesouza Feb 25, 2026
2c9064a
Merge branch 'main' into feat/vulti-agent-chat
enriquesouza Feb 25, 2026
00ddff9
refactor: Remove fastVaultPassword parameter from send, function call…
enriquesouza Feb 26, 2026
91b758b
feat(agent): add full tool executor coverage for all iOS-side actions
enriquesouza Feb 27, 2026
747b6cd
feat(agent): commit remaining agent chat UI and service changes
enriquesouza Feb 27, 2026
316a223
Merge branch 'main' into feat/vulti-agent-chat
enriquesouza Feb 27, 2026
5bfd425
chore(lint): run swiftlint --fix on all changed files
enriquesouza Feb 27, 2026
4602f28
refactor: Apply `Theme.fonts` and `foregroundStyle` for consistent te…
enriquesouza Feb 27, 2026
fe6d5c3
feat: Batch auto-execute agent actions and send a single aggregated r…
enriquesouza Feb 27, 2026
8895e01
fix(agent): show loading spinner during action→backend gap
enriquesouza Feb 27, 2026
43f9b61
feat(agent): stream second SSE response directly into chat in real-time
enriquesouza Feb 27, 2026
761a9db
fix(agent): wire address book into context + robust chain filter
enriquesouza Feb 28, 2026
0bbc56c
fix(agent): use isNativeToken filter for chain decimals lookup
enriquesouza Feb 28, 2026
ab20def
feat: Enable Agent to initiate and complete transaction keysigning, s…
enriquesouza Mar 1, 2026
f337cef
chore: resolve merge conflicts
enriquesouza Mar 2, 2026
70db44a
fix(macOS): fix AgentChatMessageView compilation on macOS
enriquesouza Mar 2, 2026
49e6628
fix: address CodeRabbit review comments
enriquesouza Mar 2, 2026
77529b9
fix(macOS): use separate entitlements file without Push Notifications…
enriquesouza Mar 2, 2026
8fdb383
fix(macOS): restore DEVELOPMENT_TEAM to 5BP27CHH4Y
enriquesouza Mar 2, 2026
015fe11
fix: resolve AgentPasswordPromptScreen naming compilation error in Ag…
enriquesouza Mar 2, 2026
4969064
Refactor agent auto-execute action handling to differentiate single f…
enriquesouza Mar 3, 2026
e309a87
address book
enriquesouza Mar 3, 2026
f44a4c3
Merge branch 'main' of github.com:vultisig/vultisig-ios into feat/vul…
enriquesouza Mar 3, 2026
9a85067
feat: Add fast vault password to KeysignView initializations and refi…
enriquesouza Mar 3, 2026
92d9ff7
feat: expand agent context with all vault public keys and addresses, …
enriquesouza Mar 3, 2026
2b6e5fb
Merge branch 'main' into feat/vulti-agent-chat
enriquesouza Mar 3, 2026
e8591d2
feat: implement fast vault keysign flow with password caching and aut…
enriquesouza Mar 3, 2026
dcddf3e
feat: Enable deletion of single and all agent conversations, updating…
enriquesouza Mar 4, 2026
68c1a4b
feat: Add toggle for AI Agent (Vulti) in settings and control its tab…
enriquesouza Mar 4, 2026
916ab58
fix(agent): address PR #3910 CodeRabbit review comments
enriquesouza Mar 4, 2026
bd46676
feat: add agent chat functionality with new views, view models, servi…
enriquesouza Mar 4, 2026
bcc822c
feat: Implement robust transaction broadcasting for agent, including …
enriquesouza Mar 5, 2026
4b562e5
feat: update agent backend URL from localhost to production endpoint.
enriquesouza Mar 5, 2026
9977358
feat: improve agent action success reporting, add URL encoding for co…
enriquesouza Mar 5, 2026
3391783
feat: implement token removal functionality and fix vault parameter a…
enriquesouza Mar 5, 2026
9137d2b
Fix remaining PR findings: token guards, redaction, array scopes
enriquesouza Mar 5, 2026
32c6370
Address remaining CodeRabbit comments (#3910)
enriquesouza Mar 5, 2026
d72e6eb
Fix remaining CodeRabbit nitpicks: token guard in loadStarters and si…
enriquesouza Mar 5, 2026
3cce4f7
Fix AgentConversationsView checkConnection compilation error
enriquesouza Mar 5, 2026
144a5bd
Merge branch 'main' into feat/vulti-agent-chat
enriquesouza Mar 5, 2026
08ce817
Address Johnny's PR review comments
enriquesouza Mar 6, 2026
ae01799
feat: hide the home screen header when the agent tab is active and ap…
enriquesouza Mar 6, 2026
5d25848
feat: Implement custom inline header for AgentChatView and rotate ell…
enriquesouza Mar 6, 2026
cf34bd7
feat: Improve agent conversation view performance, enhance date parsi…
enriquesouza Mar 6, 2026
eacadb5
feat: Propagate fastVaultPassword through function call routes to the…
enriquesouza Mar 6, 2026
c559e35
chore: Update commondata dependency revision.
enriquesouza Mar 6, 2026
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
100 changes: 100 additions & 0 deletions VultisigApp/VultisigApp.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions VultisigApp/VultisigApp/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ struct ContentView: View {
.navigationDestination(for: SettingsRoute.self) { router.settingsRouter.build($0) }
.navigationDestination(for: CircleRoute.self) { router.circleRouter.build($0) }
.navigationDestination(for: TronRoute.self) { router.tronRouter.build($0) }
.navigationDestination(for: AgentRoute.self) { router.agentRouter.build($0) }
}
.environment(\.router, router.navigationRouter)
.colorScheme(.dark)
Expand Down
13 changes: 13 additions & 0 deletions VultisigApp/VultisigApp/Features/Agent/Navigation/AgentRoute.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// AgentRoute.swift
// VultisigApp
//
// Created by Enrique Souza on 2026-02-25.
//

import Foundation

enum AgentRoute: Hashable {
case conversations
case chat(conversationId: String?)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// AgentRouter.swift
// VultisigApp
//
// Created by Enrique Souza on 2026-02-25.
//

import SwiftUI

struct AgentRouter {

@ViewBuilder
func build(_ route: AgentRoute) -> some View {
switch route {
case .conversations:
AgentConversationsView()
case .chat(let conversationId):
AgentChatView(conversationId: conversationId)
}
}
}
15 changes: 14 additions & 1 deletion VultisigApp/VultisigApp/Features/Home/HomeScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,16 @@ struct HomeScreen: View {
@EnvironmentObject var vultExtensionViewModel: VultExtensionViewModel
@EnvironmentObject var appViewModel: AppViewModel
@Environment(\.modelContext) private var modelContext

var tabs: [HomeTab] {
!(appViewModel.selectedVault?.availableDefiChains.isEmpty ?? true) ? [.wallet, .defi] : [.wallet]
var baseTabs: [HomeTab] = [.wallet]
if !(appViewModel.selectedVault?.availableDefiChains.isEmpty ?? true) {
baseTabs.append(.defi)
}
if SettingsViewModel.shared.agentEnabled {
baseTabs.append(.agent)
}
return baseTabs
}

init(showingVaultSelector: Bool = false) {
Expand Down Expand Up @@ -137,6 +145,8 @@ struct HomeScreen: View {
vault: selectedVault,
showBalanceInHeader: $defiShowPortfolioHeader
)
case .agent:
AgentConversationsView()
case .camera:
EmptyView()
}
Expand All @@ -149,6 +159,7 @@ struct HomeScreen: View {
}

header(vault: selectedVault)
.showIf(selectedTab != .agent)
}
}

Expand Down Expand Up @@ -318,6 +329,8 @@ extension HomeScreen {
showOpaqueHeader = defiShowPortfolioHeader
case .wallet:
showOpaqueHeader = walletShowPortfolioHeader
case .agent:
showOpaqueHeader = false
case .camera:
return
}
Expand Down
5 changes: 5 additions & 0 deletions VultisigApp/VultisigApp/Features/Home/Model/HomeTab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
enum HomeTab: TabBarItem, CaseIterable {
case wallet
case defi
case agent
// Only used to fake `camera` button for liquid glass
case camera

Expand All @@ -17,6 +18,8 @@ enum HomeTab: TabBarItem, CaseIterable {
"Wallet"
case .defi:
"DeFi"
case .agent:
"Agent"
case .camera:
""
}
Expand All @@ -28,6 +31,8 @@ enum HomeTab: TabBarItem, CaseIterable {
"wallet"
case .defi:
"coins-add"
case .agent:
"stars"
case .camera:
"camera-2"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ struct ChainDetailScreenContainer: View {
self.group = group
self.vault = vault
let supportsDefiTab = vault.availableDefiChains.contains(group.chain)
tabs = supportsDefiTab ? [.wallet, .defi] : [.wallet]
var newTabs: [HomeTab] = [.wallet]
if supportsDefiTab {
newTabs.append(.defi)
}
if SettingsViewModel.shared.agentEnabled {
newTabs.append(.agent)
}
self.tabs = newTabs
}

var body: some View {
Expand Down Expand Up @@ -58,6 +65,8 @@ struct ChainDetailScreenContainer: View {
default:
DefiChainMainScreen(vault: vault, group: group)
}
case .agent:
AgentConversationsView()
case .camera:
EmptyView()
}
Expand Down
28 changes: 28 additions & 0 deletions VultisigApp/VultisigApp/Model/Chain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,34 @@ enum Chain: String, Codable, Hashable, CaseIterable {
case hyperliquid
case sei

/// Maps removed chain raw values to their replacement chain.
/// This prevents SwiftData from crashing when decoding legacy persisted data.
private static let removedChainMigrations: [String: Chain] = [
"thorChainStagenet2": .thorChainStagenet,
"thorChainChainnet": .thorChain,
"polygon": .polygonV2
]

init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let rawValue = try container.decode(String.self)
if let chain = Chain(rawValue: rawValue) {
self = chain
} else if let migrated = Chain.removedChainMigrations[rawValue] {
self = migrated
} else {
throw DecodingError.dataCorruptedError(
in: container,
debugDescription: "Cannot initialize Chain from invalid String value \(rawValue)"
)
}
}

func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(self.rawValue)
}

enum MigrationKeys: String, CodingKey {
case ticker
}
Expand Down
2 changes: 2 additions & 0 deletions VultisigApp/VultisigApp/Navigation/VultisigRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ final class VultisigRouter: ObservableObject {
let homeRouter: HomeRouter
let circleRouter: CircleRouter
let tronRouter: TronRouter
let agentRouter: AgentRouter

init(navigationRouter: NavigationRouter) {
self.navigationRouter = navigationRouter
Expand All @@ -32,5 +33,6 @@ final class VultisigRouter: ObservableObject {
self.homeRouter = HomeRouter()
self.circleRouter = CircleRouter()
self.tronRouter = TronRouter()
self.agentRouter = AgentRouter()
}
}
Loading