@yottagraph-app/aether-instructions 1.1.35 → 1.1.37
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/package.json
CHANGED
package/rules/agents.mdc
CHANGED
|
@@ -455,3 +455,29 @@ exploration but requires more tool calls and is more error-prone.
|
|
|
455
455
|
returns formatted strings. Fewer tools, more reliable, better for production
|
|
456
456
|
use cases. **Prefer this pattern** unless the agent genuinely needs to
|
|
457
457
|
explore arbitrary entity types.
|
|
458
|
+
|
|
459
|
+
### McpToolset passthrough is not a substitute for custom tools
|
|
460
|
+
|
|
461
|
+
When DESIGN.md specifies named agent tools (e.g. `entity_search`,
|
|
462
|
+
`corporate_structure`, `event_monitor`), each must be implemented as a
|
|
463
|
+
**Python function** that calls MCP, formats results, and handles errors.
|
|
464
|
+
Passing a raw `McpToolset` as the agent's only tool source and writing a
|
|
465
|
+
long system prompt does **not** satisfy the spec.
|
|
466
|
+
|
|
467
|
+
`McpToolset` passthrough means:
|
|
468
|
+
- The LLM receives raw JSON responses — no Markdown formatting, no
|
|
469
|
+
human-readable reports
|
|
470
|
+
- No session-state caching — repeated queries for the same entity make
|
|
471
|
+
redundant MCP calls every turn
|
|
472
|
+
- No property type handling — `data_nindex` values (entity references)
|
|
473
|
+
render as meaningless 19-digit numbers
|
|
474
|
+
- No error boundaries — MCP failures surface as opaque tool errors
|
|
475
|
+
- No compound cache keys or report generation — the patterns that make
|
|
476
|
+
multi-turn research conversations reliable
|
|
477
|
+
|
|
478
|
+
`McpToolset` passthrough is fine for **simple exploration agents** or
|
|
479
|
+
quick prototypes. It is **not acceptable** when the project spec
|
|
480
|
+
describes a production agent with a defined tool suite. If DESIGN.md
|
|
481
|
+
lists N custom tools, build N custom Python functions — each calling MCP
|
|
482
|
+
tools internally, formatting output as Markdown, catching exceptions,
|
|
483
|
+
and saving reports to session state where appropriate.
|
package/rules/cookbook-data.mdc
CHANGED
|
@@ -403,3 +403,148 @@ relationship PID. See the `data` rule for the two-layer architecture.
|
|
|
403
403
|
}
|
|
404
404
|
</script>
|
|
405
405
|
```
|
|
406
|
+
|
|
407
|
+
## 5. Async Entity Search with Live Suggestions
|
|
408
|
+
|
|
409
|
+
Type-ahead search that shows results in a dropdown as the user types. Uses
|
|
410
|
+
`searchEntities()` from the gateway helpers with a debounced watcher.
|
|
411
|
+
|
|
412
|
+
> **Do not use `v-autocomplete` for async search.** Vuetify's `v-autocomplete`
|
|
413
|
+
> with `hide-no-data` + `no-filter` + async item loading has a timing bug:
|
|
414
|
+
> the menu hides while items are empty (during the fetch) and does not reopen
|
|
415
|
+
> when results arrive. Use `v-text-field` with a manual dropdown instead.
|
|
416
|
+
|
|
417
|
+
```vue
|
|
418
|
+
<template>
|
|
419
|
+
<div class="entity-search" style="position: relative">
|
|
420
|
+
<v-text-field
|
|
421
|
+
v-model="searchQuery"
|
|
422
|
+
:label="label"
|
|
423
|
+
:prepend-inner-icon="icon"
|
|
424
|
+
variant="solo-filled"
|
|
425
|
+
rounded="lg"
|
|
426
|
+
clearable
|
|
427
|
+
density="comfortable"
|
|
428
|
+
:loading="searching"
|
|
429
|
+
@focus="showMenu = suggestions.length > 0"
|
|
430
|
+
@click:clear="onClear"
|
|
431
|
+
/>
|
|
432
|
+
|
|
433
|
+
<v-card
|
|
434
|
+
v-if="showMenu && suggestions.length > 0"
|
|
435
|
+
class="search-dropdown"
|
|
436
|
+
elevation="8"
|
|
437
|
+
>
|
|
438
|
+
<v-list density="compact">
|
|
439
|
+
<v-list-item
|
|
440
|
+
v-for="item in suggestions"
|
|
441
|
+
:key="item.neid"
|
|
442
|
+
:title="item.name"
|
|
443
|
+
:subtitle="item.neid"
|
|
444
|
+
@click="onSelect(item)"
|
|
445
|
+
/>
|
|
446
|
+
</v-list>
|
|
447
|
+
</v-card>
|
|
448
|
+
</div>
|
|
449
|
+
</template>
|
|
450
|
+
|
|
451
|
+
<script setup lang="ts">
|
|
452
|
+
import { searchEntities } from '~/utils/elementalHelpers';
|
|
453
|
+
|
|
454
|
+
const props = withDefaults(
|
|
455
|
+
defineProps<{
|
|
456
|
+
label?: string;
|
|
457
|
+
icon?: string;
|
|
458
|
+
flavors?: string[];
|
|
459
|
+
}>(),
|
|
460
|
+
{ label: 'Search', icon: 'mdi-magnify', flavors: undefined },
|
|
461
|
+
);
|
|
462
|
+
|
|
463
|
+
const emit = defineEmits<{
|
|
464
|
+
selected: [entity: { neid: string; name: string }];
|
|
465
|
+
}>();
|
|
466
|
+
|
|
467
|
+
const searchQuery = ref('');
|
|
468
|
+
const suggestions = ref<{ neid: string; name: string }[]>([]);
|
|
469
|
+
const searching = ref(false);
|
|
470
|
+
const showMenu = ref(false);
|
|
471
|
+
let selectedName = '';
|
|
472
|
+
let debounceTimer: ReturnType<typeof setTimeout> | null = null;
|
|
473
|
+
|
|
474
|
+
watch(searchQuery, (val) => {
|
|
475
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
476
|
+
if (val === selectedName) return;
|
|
477
|
+
if (!val || val.length < 2) {
|
|
478
|
+
suggestions.value = [];
|
|
479
|
+
showMenu.value = false;
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
debounceTimer = setTimeout(() => doSearch(val), 300);
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
async function doSearch(query: string) {
|
|
486
|
+
searching.value = true;
|
|
487
|
+
try {
|
|
488
|
+
suggestions.value = await searchEntities(query, {
|
|
489
|
+
maxResults: 8,
|
|
490
|
+
flavors: props.flavors,
|
|
491
|
+
});
|
|
492
|
+
showMenu.value = suggestions.value.length > 0;
|
|
493
|
+
} catch {
|
|
494
|
+
suggestions.value = [];
|
|
495
|
+
showMenu.value = false;
|
|
496
|
+
} finally {
|
|
497
|
+
searching.value = false;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
function onSelect(item: { neid: string; name: string }) {
|
|
502
|
+
selectedName = item.name;
|
|
503
|
+
searchQuery.value = item.name;
|
|
504
|
+
suggestions.value = [];
|
|
505
|
+
showMenu.value = false;
|
|
506
|
+
emit('selected', item);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
function onClear() {
|
|
510
|
+
selectedName = '';
|
|
511
|
+
suggestions.value = [];
|
|
512
|
+
showMenu.value = false;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
onMounted(() => {
|
|
516
|
+
document.addEventListener('click', (e) => {
|
|
517
|
+
const el = (e.target as HTMLElement)?.closest('.entity-search');
|
|
518
|
+
if (!el) showMenu.value = false;
|
|
519
|
+
});
|
|
520
|
+
});
|
|
521
|
+
</script>
|
|
522
|
+
|
|
523
|
+
<style scoped>
|
|
524
|
+
.entity-search {
|
|
525
|
+
max-width: 600px;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
.search-dropdown {
|
|
529
|
+
position: absolute;
|
|
530
|
+
top: 100%;
|
|
531
|
+
left: 0;
|
|
532
|
+
right: 0;
|
|
533
|
+
z-index: 100;
|
|
534
|
+
max-height: 300px;
|
|
535
|
+
overflow-y: auto;
|
|
536
|
+
margin-top: -8px;
|
|
537
|
+
}
|
|
538
|
+
</style>
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
Usage:
|
|
542
|
+
|
|
543
|
+
```vue
|
|
544
|
+
<EntitySearch
|
|
545
|
+
label="Search for a company"
|
|
546
|
+
icon="mdi-domain"
|
|
547
|
+
:flavors="['organization']"
|
|
548
|
+
@selected="onCompanySelected"
|
|
549
|
+
/>
|
|
550
|
+
```
|
|
@@ -604,6 +604,17 @@ These are mistakes previous agents have made. Do not repeat them.
|
|
|
604
604
|
when the `ref` field is actually present in the tool response data.
|
|
605
605
|
The client renders these as numbered citations with source links.
|
|
606
606
|
|
|
607
|
+
6. **Do not pass raw `McpToolset` when the spec calls for custom tools.**
|
|
608
|
+
If DESIGN.md describes named tools (e.g. `entity_search`,
|
|
609
|
+
`corporate_structure`, `event_monitor`), each must be a Python
|
|
610
|
+
function that calls MCP internally. Passing `McpToolset` as the
|
|
611
|
+
agent's only tool source means: no Markdown report formatting, no
|
|
612
|
+
session-state caching, no property type resolution (`data_nindex`
|
|
613
|
+
values render as raw NEIDs), no compound cache keys, and no error
|
|
614
|
+
boundaries. The LLM gets raw JSON and hallucinates when responses
|
|
615
|
+
are large. `McpToolset` passthrough is acceptable for quick
|
|
616
|
+
prototypes but not for production agents with a defined tool suite.
|
|
617
|
+
|
|
607
618
|
---
|
|
608
619
|
|
|
609
620
|
## Citation Handling
|
|
@@ -114,6 +114,18 @@ Match the brief: dashboards from `/api/...`, **chat** as primary, or both. No El
|
|
|
114
114
|
|
|
115
115
|
## Step 6: Build
|
|
116
116
|
|
|
117
|
+
**If the brief is agent-heavy** (the agent IS the product — chatbot,
|
|
118
|
+
research assistant, investigation tool, etc.), build the agent FIRST:
|
|
119
|
+
|
|
120
|
+
1. **`agents/`** — Build the full agent with all tools specified in DESIGN.md.
|
|
121
|
+
Each named tool must be a Python function — do NOT just pass `McpToolset`
|
|
122
|
+
through and write a system prompt. Read the `agents` rule ("McpToolset
|
|
123
|
+
passthrough" section) for why this matters.
|
|
124
|
+
2. Test the agent locally with `adk web` before building the UI.
|
|
125
|
+
3. Then build the UI around the working agent.
|
|
126
|
+
|
|
127
|
+
**For all projects:**
|
|
128
|
+
|
|
117
129
|
1. **`agents/`** — one or more agents per `agents-data` (sync, research, channeling, or mixed).
|
|
118
130
|
2. **`server/api/` + composables + `pages/`** — when the brief needs materialized lists or detail.
|
|
119
131
|
3. **`pages/chat` or custom** — when the brief is agent-forward.
|
|
@@ -121,6 +133,26 @@ Match the brief: dashboards from `/api/...`, **chat** as primary, or both. No El
|
|
|
121
133
|
|
|
122
134
|
---
|
|
123
135
|
|
|
136
|
+
## Step 6b: Audit Against the Spec
|
|
137
|
+
|
|
138
|
+
Before committing, re-read DESIGN.md and compare what you built against
|
|
139
|
+
what it specifies. This is a mechanical check — no judgment needed.
|
|
140
|
+
|
|
141
|
+
1. **List every agent tool** DESIGN.md describes (by name, with purpose).
|
|
142
|
+
2. For each, confirm it exists in your code with the described behavior.
|
|
143
|
+
3. If the spec describes N custom tools and you built fewer, **go back
|
|
144
|
+
and build the missing ones** before proceeding.
|
|
145
|
+
4. If you used `McpToolset` passthrough where the spec calls for custom
|
|
146
|
+
Python tool functions, **replace it** — passthrough does not satisfy a
|
|
147
|
+
spec that describes named tools with specific behaviors.
|
|
148
|
+
5. Check that tools format output as Markdown, handle errors, and cache
|
|
149
|
+
results in session state where the spec requires it.
|
|
150
|
+
|
|
151
|
+
Do not skip this step. The most common failure mode is building a polished
|
|
152
|
+
UI connected to a stub agent that passes raw MCP tools through to the LLM.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
124
156
|
## Step 7: Verify and Commit
|
|
125
157
|
|
|
126
158
|
After building, ensure dependencies are installed and run a production build:
|