arkaos 3.65.0 → 3.66.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 3.65.0
1
+ 3.66.0
@@ -0,0 +1,192 @@
1
+ <script setup lang="ts">
2
+ // PR98d v3.66.0 — Agent dependency graph.
3
+ //
4
+ // Shows the current agent in the middle, its linked personas above,
5
+ // and other agents that link to those same personas (siblings) below.
6
+ // Pure SVG, no graph lib. Frontend-only — reuses existing endpoints.
7
+
8
+ interface Props {
9
+ agentId: string
10
+ agentName: string
11
+ linkedPersonas: string[]
12
+ }
13
+ const props = defineProps<Props>()
14
+
15
+ const { fetchApi } = useApi()
16
+
17
+ // /api/personas/usage returns the reverse lookup we need.
18
+ const { data: usageData } = fetchApi<{
19
+ by_persona: Record<string, { agent_count: number, agent_ids: string[] }>
20
+ }>('/api/personas/usage')
21
+
22
+ // /api/personas for resolving persona names.
23
+ const { data: personasData } = fetchApi<{
24
+ personas: Array<{ id: string, name: string }>
25
+ }>('/api/personas')
26
+
27
+ function personaName(id: string): string {
28
+ return personasData.value?.personas?.find((p) => p.id === id)?.name ?? id
29
+ }
30
+
31
+ const siblings = computed<string[]>(() => {
32
+ const ids = new Set<string>()
33
+ const usage = usageData.value?.by_persona ?? {}
34
+ for (const pid of props.linkedPersonas) {
35
+ for (const aid of (usage[pid]?.agent_ids ?? [])) {
36
+ if (aid && aid !== props.agentId) ids.add(aid)
37
+ }
38
+ }
39
+ return Array.from(ids).slice(0, 6)
40
+ })
41
+
42
+ // Layout constants — keep tight so the graph fits the hero card.
43
+ const WIDTH = 700
44
+ const HEIGHT = 220
45
+ const CENTER_X = WIDTH / 2
46
+ const CENTER_Y = HEIGHT / 2
47
+ const NODE_W = 110
48
+ const NODE_H = 32
49
+ const NODE_RX = 8
50
+
51
+ function distributeX(count: number, idx: number): number {
52
+ if (count === 1) return CENTER_X
53
+ const span = Math.min(WIDTH - 80, count * (NODE_W + 20))
54
+ const start = (WIDTH - span) / 2 + NODE_W / 2
55
+ const step = count > 1 ? (span - NODE_W) / (count - 1) : 0
56
+ return start + idx * step
57
+ }
58
+
59
+ const personaPositions = computed(() =>
60
+ props.linkedPersonas.map((id, i) => ({
61
+ id,
62
+ x: distributeX(props.linkedPersonas.length, i),
63
+ y: 32,
64
+ })),
65
+ )
66
+ const siblingPositions = computed(() =>
67
+ siblings.value.map((id, i) => ({
68
+ id,
69
+ x: distributeX(siblings.value.length, i),
70
+ y: HEIGHT - 32,
71
+ })),
72
+ )
73
+ </script>
74
+
75
+ <template>
76
+ <div
77
+ v-if="props.linkedPersonas.length > 0 || siblings.length > 0"
78
+ class="rounded-xl border border-default bg-elevated/10 p-5"
79
+ >
80
+ <h3 class="text-sm font-semibold uppercase tracking-wide text-muted mb-3">
81
+ Dependency graph
82
+ </h3>
83
+ <svg
84
+ :viewBox="`0 0 ${WIDTH} ${HEIGHT}`"
85
+ class="w-full"
86
+ preserveAspectRatio="xMidYMid meet"
87
+ >
88
+ <!-- Connector lines (personas → center) -->
89
+ <line
90
+ v-for="p in personaPositions"
91
+ :key="`pl-${p.id}`"
92
+ :x1="p.x"
93
+ :y1="p.y + NODE_H / 2"
94
+ :x2="CENTER_X"
95
+ :y2="CENTER_Y - NODE_H / 2"
96
+ class="stroke-default"
97
+ stroke-width="1"
98
+ />
99
+ <!-- Connector lines (center → siblings) -->
100
+ <line
101
+ v-for="s in siblingPositions"
102
+ :key="`sl-${s.id}`"
103
+ :x1="CENTER_X"
104
+ :y1="CENTER_Y + NODE_H / 2"
105
+ :x2="s.x"
106
+ :y2="s.y - NODE_H / 2"
107
+ class="stroke-default"
108
+ stroke-width="1"
109
+ stroke-dasharray="3,2"
110
+ />
111
+
112
+ <!-- Persona nodes (top) -->
113
+ <g
114
+ v-for="p in personaPositions"
115
+ :key="`p-${p.id}`"
116
+ >
117
+ <a :href="`/personas/${p.id}`">
118
+ <rect
119
+ :x="p.x - NODE_W / 2"
120
+ :y="p.y - NODE_H / 2"
121
+ :width="NODE_W"
122
+ :height="NODE_H"
123
+ :rx="NODE_RX"
124
+ class="fill-emerald-500/10 stroke-emerald-500/40"
125
+ stroke-width="1"
126
+ />
127
+ <text
128
+ :x="p.x"
129
+ :y="p.y + 4"
130
+ text-anchor="middle"
131
+ class="fill-emerald-700 dark:fill-emerald-300 text-xs"
132
+ >
133
+ {{ personaName(p.id).slice(0, 14) }}
134
+ </text>
135
+ <title>{{ personaName(p.id) }}</title>
136
+ </a>
137
+ </g>
138
+
139
+ <!-- Centre node: current agent -->
140
+ <g>
141
+ <rect
142
+ :x="CENTER_X - NODE_W / 2 - 10"
143
+ :y="CENTER_Y - NODE_H / 2"
144
+ :width="NODE_W + 20"
145
+ :height="NODE_H"
146
+ :rx="NODE_RX"
147
+ class="fill-primary/15 stroke-primary"
148
+ stroke-width="1.5"
149
+ />
150
+ <text
151
+ :x="CENTER_X"
152
+ :y="CENTER_Y + 4"
153
+ text-anchor="middle"
154
+ class="fill-primary text-sm font-semibold"
155
+ >
156
+ {{ props.agentName.slice(0, 16) }}
157
+ </text>
158
+ </g>
159
+
160
+ <!-- Sibling agent nodes (bottom) -->
161
+ <g
162
+ v-for="s in siblingPositions"
163
+ :key="`s-${s.id}`"
164
+ >
165
+ <a :href="`/agents/${s.id}`">
166
+ <rect
167
+ :x="s.x - NODE_W / 2"
168
+ :y="s.y - NODE_H / 2"
169
+ :width="NODE_W"
170
+ :height="NODE_H"
171
+ :rx="NODE_RX"
172
+ class="fill-blue-500/10 stroke-blue-500/40"
173
+ stroke-width="1"
174
+ />
175
+ <text
176
+ :x="s.x"
177
+ :y="s.y + 4"
178
+ text-anchor="middle"
179
+ class="fill-blue-700 dark:fill-blue-300 text-xs"
180
+ >
181
+ {{ s.id.slice(0, 14) }}
182
+ </text>
183
+ <title>{{ s.id }}</title>
184
+ </a>
185
+ </g>
186
+ </svg>
187
+ <p class="text-xs text-muted mt-2 italic">
188
+ Top: linked personas · Centre: this agent · Bottom: siblings (other
189
+ agents linking the same personas)
190
+ </p>
191
+ </div>
192
+ </template>
@@ -658,6 +658,14 @@ function formatTokens(n: number): string {
658
658
  </div>
659
659
  </section>
660
660
 
661
+ <!-- ===== DEPENDENCY GRAPH (PR98d) ===== -->
662
+ <AgentDependencyGraph
663
+ v-if="agent.linked_personas && agent.linked_personas.length > 0"
664
+ :agent-id="agent.id"
665
+ :agent-name="agent.name"
666
+ :linked-personas="agent.linked_personas"
667
+ />
668
+
661
669
  <!-- ===== BIO (PR86d) ===== -->
662
670
  <section
663
671
  v-if="(agent as any).bio_md"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkaos",
3
- "version": "3.65.0",
3
+ "version": "3.66.0",
4
4
  "description": "The Operating System for AI Agent Teams",
5
5
  "type": "module",
6
6
  "bin": {
package/pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "arkaos-core"
3
- version = "3.65.0"
3
+ version = "3.66.0"
4
4
  description = "Core engine for ArkaOS — The Operating System for AI Agent Teams"
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}