arkaos 3.17.0 → 3.18.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.17.0
1
+ 3.18.0
@@ -61,6 +61,10 @@ class Persona(BaseModel):
61
61
  # Communication
62
62
  communication: PersonaCommunication = Field(default_factory=PersonaCommunication)
63
63
 
64
+ # PR86d v3.18.0 — long-form Markdown bio. Free-text field, never
65
+ # parsed; rendered in the dashboard with `marked` for preview.
66
+ bio_md: str = ""
67
+
64
68
  # Metadata
65
69
  created_at: str = ""
66
70
  updated_at: str = ""
@@ -58,6 +58,7 @@ interface AgentDraft {
58
58
  avoid: string[]
59
59
  }
60
60
  linked_personas: string[]
61
+ bio_md: string
61
62
  }
62
63
 
63
64
  const draft = ref<AgentDraft | null>(null)
@@ -88,6 +89,7 @@ watch(
88
89
  avoid: agent.communication?.avoid ?? [],
89
90
  },
90
91
  linked_personas: agent.linked_personas ?? [],
92
+ bio_md: agent.bio_md ?? '',
91
93
  }
92
94
  dirty.value = false
93
95
  } else if (!open) {
@@ -323,6 +325,7 @@ async function save() {
323
325
  },
324
326
  communication: draft.value.communication,
325
327
  linked_personas: draft.value.linked_personas,
328
+ bio_md: draft.value.bio_md,
326
329
  }
327
330
  const res = await $fetch<{
328
331
  id: string
@@ -653,6 +656,18 @@ const vocabOptions = [
653
656
  </UFormField>
654
657
  </section>
655
658
 
659
+ <section class="space-y-3">
660
+ <h3 class="text-xs font-semibold uppercase tracking-wider text-muted">
661
+ Bio (Markdown)
662
+ </h3>
663
+ <MarkdownEditor
664
+ :model-value="draft.bio_md"
665
+ :rows="10"
666
+ placeholder="A free-text Markdown bio for this agent — context, voice samples, internal notes."
667
+ @update:model-value="(v: string) => { if (draft) { draft.bio_md = v; markDirty() } }"
668
+ />
669
+ </section>
670
+
656
671
  <section class="space-y-3">
657
672
  <h3 class="text-xs font-semibold uppercase tracking-wider text-muted">
658
673
  Linked personas
@@ -0,0 +1,74 @@
1
+ <script setup lang="ts">
2
+ // PR86d v3.18.0 — Markdown editor with Edit / Preview tabs.
3
+ //
4
+ // Standalone component used in agent + persona edit forms. The model
5
+ // value is the raw Markdown string. Preview is rendered via marked
6
+ // (already a deps after this PR).
7
+
8
+ import { marked } from 'marked'
9
+
10
+ const props = defineProps<{
11
+ modelValue: string
12
+ placeholder?: string
13
+ rows?: number
14
+ }>()
15
+ const emit = defineEmits<{
16
+ (e: 'update:modelValue', value: string): void
17
+ }>()
18
+
19
+ const tab = ref<'edit' | 'preview'>('edit')
20
+
21
+ const value = computed({
22
+ get: () => props.modelValue ?? '',
23
+ set: (v: string) => emit('update:modelValue', v),
24
+ })
25
+
26
+ const html = computed(() => {
27
+ if (!value.value.trim()) {
28
+ return '<p class="text-muted italic">Nothing to preview yet.</p>'
29
+ }
30
+ try {
31
+ return marked.parse(value.value, { breaks: true, gfm: true })
32
+ } catch {
33
+ return '<p class="text-error">Markdown parse failed.</p>'
34
+ }
35
+ })
36
+ </script>
37
+
38
+ <template>
39
+ <div class="space-y-2">
40
+ <div class="flex items-center gap-1 text-xs">
41
+ <button
42
+ type="button"
43
+ class="px-2 py-1 rounded-md transition-colors"
44
+ :class="tab === 'edit' ? 'bg-elevated/60 text-default font-semibold' : 'text-muted hover:text-default'"
45
+ @click="tab = 'edit'"
46
+ >
47
+ Edit
48
+ </button>
49
+ <button
50
+ type="button"
51
+ class="px-2 py-1 rounded-md transition-colors"
52
+ :class="tab === 'preview' ? 'bg-elevated/60 text-default font-semibold' : 'text-muted hover:text-default'"
53
+ @click="tab = 'preview'"
54
+ >
55
+ Preview
56
+ </button>
57
+ <span class="ml-auto text-xs text-muted">
58
+ Markdown · GFM · {{ value.length }} char{{ value.length === 1 ? '' : 's' }}
59
+ </span>
60
+ </div>
61
+ <UTextarea
62
+ v-if="tab === 'edit'"
63
+ v-model="value"
64
+ :rows="rows ?? 8"
65
+ :placeholder="placeholder ?? 'Write a Markdown bio…\n\n# Heading\n- bullets\n**bold**'"
66
+ class="w-full font-mono text-sm"
67
+ />
68
+ <div
69
+ v-else
70
+ class="rounded-lg border border-default bg-elevated/10 p-4 min-h-[12rem] prose prose-sm dark:prose-invert max-w-none"
71
+ v-html="html"
72
+ />
73
+ </div>
74
+ </template>
@@ -65,6 +65,17 @@ function formatRelative(iso: string | null): string {
65
65
  const favs = useFavorites()
66
66
  await favs.load()
67
67
 
68
+ // PR86d v3.18.0 — render Markdown bio.
69
+ import { marked } from 'marked'
70
+ function markedHtml(src: string): string {
71
+ if (!src?.trim()) return ''
72
+ try {
73
+ return marked.parse(src, { breaks: true, gfm: true }) as string
74
+ } catch {
75
+ return ''
76
+ }
77
+ }
78
+
68
79
  // PR86c v3.17.0 — export to Obsidian.
69
80
  const exporting = ref(false)
70
81
  async function exportToVault() {
@@ -418,6 +429,20 @@ function formatTokens(n: number): string {
418
429
  </div>
419
430
  </section>
420
431
 
432
+ <!-- ===== BIO (PR86d) ===== -->
433
+ <section
434
+ v-if="(agent as any).bio_md"
435
+ class="rounded-xl border border-default bg-elevated/10 p-5"
436
+ >
437
+ <h3 class="text-sm font-semibold uppercase tracking-wide text-muted mb-3">
438
+ Bio
439
+ </h3>
440
+ <div
441
+ class="prose prose-sm dark:prose-invert max-w-none"
442
+ v-html="markedHtml((agent as any).bio_md)"
443
+ />
444
+ </section>
445
+
421
446
  <AgentEditDrawer
422
447
  v-model="editOpen"
423
448
  :agent="agent"
@@ -230,6 +230,17 @@ const suggestingField = ref<SuggestField | null>(null)
230
230
  const favs = useFavorites()
231
231
  await favs.load()
232
232
 
233
+ // PR86d v3.18.0 — render Markdown bio.
234
+ import { marked } from 'marked'
235
+ function markedHtml(src: string): string {
236
+ if (!src?.trim()) return ''
237
+ try {
238
+ return marked.parse(src, { breaks: true, gfm: true }) as string
239
+ } catch {
240
+ return ''
241
+ }
242
+ }
243
+
233
244
  // PR85a v3.11.0 — Clone to Agent dialog.
234
245
  const cloneOpen = ref(false)
235
246
  function onCloned(agentId: string) {
@@ -560,6 +571,20 @@ const vocabOptions = [
560
571
  </div>
561
572
  </section>
562
573
 
574
+ <!-- BIO (PR86d) -->
575
+ <section
576
+ v-if="(detail as any).bio_md"
577
+ class="rounded-xl border border-default bg-elevated/10 p-5"
578
+ >
579
+ <h3 class="text-sm font-semibold uppercase tracking-wide text-muted mb-3">
580
+ Bio
581
+ </h3>
582
+ <div
583
+ class="prose prose-sm dark:prose-invert max-w-none"
584
+ v-html="markedHtml((detail as any).bio_md)"
585
+ />
586
+ </section>
587
+
563
588
  <!-- TABS -->
564
589
  <UTabs :items="tabs" default-value="dna" class="w-full">
565
590
  <template #content="{ item }">
@@ -937,6 +962,18 @@ const vocabOptions = [
937
962
  </UFormField>
938
963
  </section>
939
964
 
965
+ <section class="space-y-3">
966
+ <h3 class="text-xs font-semibold uppercase tracking-wider text-muted">
967
+ Bio (Markdown)
968
+ </h3>
969
+ <MarkdownEditor
970
+ :model-value="(draft as any).bio_md ?? ''"
971
+ :rows="10"
972
+ placeholder="A free-text Markdown bio for this persona — voice samples, context, references."
973
+ @update:model-value="(v: string) => { if (draft) { (draft as any).bio_md = v; markDirty() } }"
974
+ />
975
+ </section>
976
+
940
977
  <section class="space-y-3">
941
978
  <div class="flex items-center justify-between">
942
979
  <h3 class="text-xs font-semibold uppercase tracking-wider text-muted">Key quotes</h3>
@@ -21,6 +21,7 @@
21
21
  "@vueuse/core": "^14.2.1",
22
22
  "@vueuse/nuxt": "^14.2.1",
23
23
  "date-fns": "^4.1.0",
24
+ "marked": "^15.0.0",
24
25
  "nuxt": "^4.4.2",
25
26
  "scule": "^1.3.0",
26
27
  "tailwindcss": "^4.2.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkaos",
3
- "version": "3.17.0",
3
+ "version": "3.18.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.17.0"
3
+ version = "3.18.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"}
@@ -451,6 +451,9 @@ def agent_update(agent_id: str, body: dict):
451
451
  raw["communication"] = comm
452
452
  if "linked_personas" in body:
453
453
  raw["linked_personas"] = _agent_str_list(body["linked_personas"])
454
+ # PR86d v3.18.0 — Markdown bio (long-form free text).
455
+ if "bio_md" in body and isinstance(body["bio_md"], str):
456
+ raw["bio_md"] = body["bio_md"]
454
457
 
455
458
  try:
456
459
  tmp = yaml_file.with_suffix(yaml_file.suffix + ".tmp")
@@ -1101,6 +1104,7 @@ def persona_update(persona_id: str, body: dict):
1101
1104
  communication=PersonaCommunication(
1102
1105
  **(merged.get("communication", {}) or {}),
1103
1106
  ),
1107
+ bio_md=merged.get("bio_md", "") or "",
1104
1108
  created_at=merged.get("created_at", ""),
1105
1109
  )
1106
1110