File size: 4,303 Bytes
a20767f
5d62489
 
a20767f
666aab6
 
 
 
a20767f
 
5d62489
660d02b
a20767f
 
 
 
 
 
 
 
 
 
666aab6
a20767f
 
 
 
 
 
666aab6
a20767f
 
 
 
 
 
 
666aab6
a20767f
 
 
 
 
 
 
 
 
666aab6
a20767f
 
 
666aab6
 
a20767f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
666aab6
 
5d62489
 
 
 
 
666aab6
5d62489
 
a20767f
666aab6
a20767f
 
666aab6
a20767f
 
 
 
 
 
 
 
 
 
666aab6
 
a20767f
 
 
 
 
666aab6
a20767f
 
 
 
 
 
 
 
5d62489
a20767f
 
 
 
 
5d62489
a20767f
666aab6
a20767f
5d62489
a20767f
 
 
 
 
 
666aab6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/**
 * God Agent OS v7 — Global State Store
 * Manus + Genspark + Devin (OneHand)
 */

import { create } from 'zustand'
import { nanoid } from './nanoid'

export type Theme = 'dark' | 'light' | 'amoled' | 'neon' | 'glass'
export type Locale = 'en' | 'my'
export type AgentName = 'chat' | 'planner' | 'coding' | 'debug' | 'memory' | 'connector' | 'deploy' | 'workflow' | 'sandbox' | 'ui' | 'browser' | 'file' | 'git' | 'test' | 'vision' | 'reasoning'
export type ActivePanel = 'timeline' | 'tasks' | 'memory' | 'connectors' | 'sandbox' | 'files' | 'browser' | 'ai_router'

export interface Message {
  id: string
  role: 'user' | 'assistant' | 'system'
  content: string
  streaming?: boolean
  timestamp: number
  agent?: AgentName
  metadata?: Record<string, any>
}

export interface AgentStatus {
  name: AgentName
  status: 'idle' | 'thinking' | 'executing' | 'complete' | 'error'
  currentTask?: string
  lastActive?: number
}

export interface TaskEvent {
  id: string
  type: string
  data: Record<string, any>
  timestamp: number
  agent?: AgentName
}

export interface ConnectorInfo {
  id: string
  name: string
  connected: boolean
  icon: string
  color: string
  category: string
  description: string
}

interface GodStore {
  sessionId: string
  messages: Message[]
  isStreaming: boolean
  streamingMessageId: string | null
  mode: 'agent' | 'chat'
  setMode: (m: 'agent' | 'chat') => void
  theme: Theme
  locale: Locale
  setTheme: (t: Theme) => void
  setLocale: (l: Locale) => void
  activePanel: ActivePanel
  setActivePanel: (p: ActivePanel) => void
  sidebarOpen: boolean
  setSidebarOpen: (v: boolean) => void
  activeTaskId: string | null
  setActiveTaskId: (id: string | null) => void
  events: TaskEvent[]
  addEvent: (e: Omit<TaskEvent, 'id' | 'timestamp'>) => void
  clearEvents: () => void
  agents: Record<AgentName, AgentStatus>
  updateAgentStatus: (name: AgentName, s: Partial<AgentStatus>) => void
  connectors: ConnectorInfo[]
  setConnectors: (c: ConnectorInfo[]) => void
  addMessage: (m: Omit<Message, 'id' | 'timestamp'>) => string
  appendChunk: (id: string, chunk: string) => void
  updateMessage: (id: string, updates: Partial<Message>) => void
  setStreaming: (v: boolean, id: string | null) => void
  clearMessages: () => void
}

const ALL_AGENTS: AgentName[] = [
  'chat','planner','coding','debug','memory','connector',
  'deploy','workflow','sandbox','ui','browser','file',
  'git','test','vision','reasoning'
]

const defaultAgents = Object.fromEntries(
  ALL_AGENTS.map(n => [n, { name: n, status: 'idle' as const }])
) as Record<AgentName, AgentStatus>

export const useAgentStore = create<GodStore>((set, get) => ({
  sessionId: `sess_${nanoid(16)}`,
  messages: [],
  isStreaming: false,
  streamingMessageId: null,
  mode: 'agent',
  setMode: (mode) => set({ mode }),
  theme: 'dark',
  locale: 'en',
  setTheme: (theme) => {
    set({ theme })
    if (typeof document !== 'undefined') {
      document.documentElement.setAttribute('data-theme', theme)
    }
  },
  setLocale: (locale) => set({ locale }),
  activePanel: 'timeline',
  setActivePanel: (activePanel) => set({ activePanel }),
  sidebarOpen: true,
  setSidebarOpen: (v) => set({ sidebarOpen: v }),
  activeTaskId: null,
  setActiveTaskId: (id) => set({ activeTaskId: id }),
  events: [],
  addEvent: (e) => set(s => ({
    events: [...s.events.slice(-200), { ...e, id: nanoid(8), timestamp: Date.now() }]
  })),
  clearEvents: () => set({ events: [] }),
  agents: defaultAgents,
  updateAgentStatus: (name, updates) => set(s => ({
    agents: { ...s.agents, [name]: { ...(s.agents[name] || { name, status: 'idle' }), ...updates } }
  })),
  connectors: [],
  setConnectors: (connectors) => set({ connectors }),
  addMessage: (m) => {
    const id = nanoid(12)
    set(s => ({ messages: [...s.messages, { ...m, id, timestamp: Date.now() }] }))
    return id
  },
  appendChunk: (id, chunk) => set(s => ({
    messages: s.messages.map(m => m.id === id ? { ...m, content: m.content + chunk } : m)
  })),
  updateMessage: (id, updates) => set(s => ({
    messages: s.messages.map(m => m.id === id ? { ...m, ...updates } : m)
  })),
  setStreaming: (isStreaming, streamingMessageId) => set({ isStreaming, streamingMessageId }),
  clearMessages: () => set({ messages: [], events: [] }),
}))