-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathauthz.go
More file actions
65 lines (58 loc) · 2.45 KB
/
Copy pathauthz.go
File metadata and controls
65 lines (58 loc) · 2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package cortex
import (
"context"
"errors"
"github.com/xraph/cortex/id"
"github.com/xraph/cortex/llm"
)
// ErrRequiresApproval is the authorizer's third answer. Returning it from
// Authorize suspends the run and opens a checkpoint rather than denying
// the call, so a human can decide and the run can carry on afterwards.
//
// It was held back in v1.10.0 on purpose: with nowhere to suspend into,
// returning it would have read as an ordinary denial and quietly turned
// "ask someone" into "no".
var ErrRequiresApproval = errors.New("cortex: tool call requires approval")
// Subject is who is asking. Principal is host-defined and cortex never
// interprets it: a host puts whatever its own authorization layer needs
// there, and gets it back unchanged.
type Subject struct {
Scope Scope
Principal any
AgentID id.AgentID
RunID id.AgentRunID
}
// Invocation is one tool call about to be dispatched. It embeds Subject
// so a handler receives scope and principal explicitly.
//
// The alternative is leaving handlers to pull those off the context. That
// works and is idiomatic Go, and it is also the exact pattern that let a
// tenant identifier sit available and unread until every tenant shared
// one conversation bucket. An explicit Invocation means a handler that
// ignores scope has visibly ignored it.
type Invocation struct {
Subject
Call llm.ToolCall
}
// ToolAuthorizer decides what the model may see and what it may call.
// It is consulted at two points because they are different questions: a
// model can name a tool it was never shown, so filtering the list is not
// a substitute for gating the call.
//
// A nil authorizer allows everything, so a host that sets none sees no
// change.
type ToolAuthorizer interface {
// Visible filters the tool list before it reaches the model. Called
// once per step.
Visible(ctx context.Context, s Subject, tools []llm.Tool) []llm.Tool
// Authorize gates one dispatch. Returning nil allows the call; any
// error denies it, and the error's text is fed back to the model as
// the tool result so it can react rather than silently retrying.
//
// The one exception is ErrRequiresApproval, which is not a denial:
// nothing goes back to the model, the run pauses, and a checkpoint
// carries the call to whoever decides. Wrap it if you want to say
// why (fmt.Errorf("...: %w", cortex.ErrRequiresApproval)); it is
// matched with errors.Is.
Authorize(ctx context.Context, s Subject, call llm.ToolCall) error
}