feat: add tier and session_log MCP tools

Adds two new MCP skill packages:
- internal/skills/org: exposes the tier tool, calling an injected TierFn
  for testability; returns current operating tier as structured JSON
- internal/skills/sessionlog: exposes the session_log tool, appending
  structured JSONL entries to brain/sessions/{session_id}.jsonl; requires
  session_id, wraps internal/session.Append

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Mathias Bergqvist
2026-04-17 20:40:50 +02:00
parent e610e253ef
commit 9cfce8f700
6 changed files with 237 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
// internal/skills/org/handlers.go
package org
import (
"context"
"encoding/json"
"fmt"
)
// Handle dispatches the tier tool call.
func (s *Skill) Handle(ctx context.Context, tool string, args json.RawMessage) (json.RawMessage, error) {
if tool != "tier" {
return nil, fmt.Errorf("unknown org tool: %s", tool)
}
info := s.cfg.TierFn(ctx)
b, err := json.Marshal(info)
if err != nil {
return nil, fmt.Errorf("marshal tier info: %w", err)
}
return b, nil
}

View File

@@ -0,0 +1,29 @@
// internal/skills/org/handlers_test.go
package org_test
import (
"context"
"encoding/json"
"testing"
"github.com/mathiasbq/supervisor/internal/skills/org"
"github.com/mathiasbq/supervisor/internal/tier"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestHandle_Tier_ReturnsTierInfo(t *testing.T) {
s := org.New(org.Config{
TierFn: func(ctx context.Context) tier.Info {
return tier.Info{Tier: tier.LANOnly, Label: "lan-only", ManagedAgents: false}
},
})
out, err := s.Handle(context.Background(), "tier", nil)
require.NoError(t, err)
var info tier.Info
require.NoError(t, json.Unmarshal(out, &info))
assert.Equal(t, tier.LANOnly, info.Tier)
assert.Equal(t, "lan-only", info.Label)
assert.False(t, info.ManagedAgents)
}

View File

@@ -0,0 +1,40 @@
// internal/skills/org/skill.go
package org
import (
"context"
"encoding/json"
"github.com/mathiasbq/supervisor/internal/registry"
"github.com/mathiasbq/supervisor/internal/tier"
)
// TierFn returns the current tier. Injected for testability.
type TierFn func(ctx context.Context) tier.Info
// Config holds org skill configuration.
type Config struct {
TierFn TierFn
}
// Skill implements registry.Skill for the tier tool.
type Skill struct {
cfg Config
}
// New constructs an org Skill.
func New(cfg Config) *Skill { return &Skill{cfg: cfg} }
// Name returns the skill name.
func (s *Skill) Name() string { return "org" }
// Tools returns the MCP tool definitions.
func (s *Skill) Tools() []registry.ToolDef {
return []registry.ToolDef{
{
Name: "tier",
Description: "Returns the current operating tier: 1=full-online (Claude+Ollama+Managed Agents), 2=lan-only (Ollama only), 3=airplane (minimal). Call at session start to know which models and capabilities are available.",
InputSchema: json.RawMessage(`{"type":"object","properties":{}}`),
},
}
}