managarten/packages/shared-ai/src/index.ts
Till JS 4be5e29bd3 feat(shared-ai): canonical proposable-tool list + drift guard on mana-ai
Makes the webapp's AI policy and the server's tool allow-list physically
impossible to drift. Adds the missing entries the guard caught on first
run: `complete_tasks_by_title`, `visit_place`, `undo_drink` now have
parameter schemas server-side too.

- `packages/shared-ai/src/policy/proposable-tools.ts`
  - `AI_PROPOSABLE_TOOL_NAMES` as `const` array + literal union type
  - `AI_PROPOSABLE_TOOL_SET` for set-membership checks
- Webapp `DEFAULT_AI_POLICY` derives its `propose` entries from the
  shared list via `Object.fromEntries(...)` — adding a tool there is now
  a one-line change in `@mana/shared-ai`
- mana-ai `AI_AVAILABLE_TOOLS`: module-load assertion compares its
  hardcoded names against `AI_PROPOSABLE_TOOL_SET` and throws with a
  pointed error on drift (extras in one direction, missing in the
  other). Service refuses to start on mismatch — better than silent
  degradation.
- Bun test (`tools.test.ts`) runs the same contract plus sanity checks
  (non-empty description, required params carry docs). Vitest policy
  test adds the symmetric check on the webapp side.

All three runtimes now green: webapp 66/66, shared-ai 2/2,
mana-ai 9/9 Bun tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 00:52:38 +02:00

37 lines
846 B
TypeScript

/**
* @mana/shared-ai
*
* AI Workbench code that both the webapp (SvelteKit/Vite) and the
* server-side mana-ai service (Bun) import. Keep this package free of
* runtime imports from storage layers (Dexie, Postgres) — the types +
* pure functions here must work in both environments.
*/
export type { Actor } from './actor';
export { USER_ACTOR, isAiActor, isSystemActor } from './actor';
export type {
Mission,
MissionCadence,
MissionInputRef,
MissionIteration,
MissionState,
PlanStep,
} from './missions';
export type {
AiPlanInput,
AiPlanOutput,
AvailableTool,
ParseResult,
PlannedStep,
PlannerMessages,
ResolvedInput,
} from './planner';
export { buildPlannerPrompt, parsePlannerResponse } from './planner';
export {
AI_PROPOSABLE_TOOL_NAMES,
AI_PROPOSABLE_TOOL_SET,
type AiProposableToolName,
} from './policy';