返回 DeepSeek-Reasonix
README.md
根目录 / sdk / go / README.md
1 # Reasonix Extension SDK for Go
2
3 Write [Reasonix](https://github.com/esengine/DeepSeek-Reasonix) extensions in
4 Go. An extension is a small sidecar process speaking **Extension Protocol
5 v1** (`reasonix.extension.v1`) over stdio: Reasonix launches it, hands it the
6 initialize handshake, and then drives intercepts, event observation,
7 extension-hosted provider streams, and structured UI surfaces.
8
9 The module is **standard library only** — zero dependencies.
10
11 ## Install
12
13 ```sh
14 go get github.com/esengine/DeepSeek-Reasonix/sdk/go@v1.0.0
15 ```
16
17 Requires Go 1.23+. SDK releases use immutable `sdk/go/vX.Y.Z` repository
18 tags; `sdk/go/v1.0.0` is published with the first product release containing
19 Extension Protocol v1. Before that tag exists, develop against a source
20 checkout instead of depending on an unversioned API.
21
22 ## Minimal example
23
24 ```go
25 package main
26
27 import (
28 "context"
29 "encoding/json"
30 "os"
31
32 extension "github.com/esengine/DeepSeek-Reasonix/sdk/go"
33 )
34
35 type ext struct{}
36
37 func (ext) Initialize(_ context.Context, p extension.InitializeParams) (*extension.InitializeResult, error) {
38 return &extension.InitializeResult{
39 Name: "my-ext",
40 Version: "0.1.0",
41 Subscriptions: []string{"tool.before"},
42 }, nil
43 }
44
45 func main() {
46 err := extension.Serve(context.Background(), ext{}, extension.Options{
47 Interceptors: map[string]extension.InterceptorFunc{
48 "tool.before": func(_ context.Context, event string, payload json.RawMessage) (*extension.InterceptResult, error) {
49 return extension.Continue(), nil // or Block / Replace / Allow / Deny
50 },
51 },
52 })
53 if err != nil {
54 os.Exit(1)
55 }
56 // Serve returned nil: the host asked for shutdown. Exit 0.
57 }
58 ```
59
60 Everything else is optional and declared through `Options`: an `Observer`
61 for fire-and-forget events, a `Provider` for extension-hosted model
62 providers, `UI` callbacks plus the `HostUI` client for structured surfaces
63 (status, cards, forms, notifications and blocking prompts — never HTML/JS),
64 `ReadContentRef`/`ResolveExternalized` for large externalized payloads, and a
65 `Shutdown` hook.
66
67 ## Concurrency contract
68
69 `Initialize` runs once and completes before any other callback. After that,
70 the SDK may run up to 32 inbound callbacks concurrently: interceptors,
71 observers, resource notifications, provider `Catalog`/`Stream`, and UI
72 callbacks can overlap, and multiple provider streams may be active at once.
73 Treat callback inputs as call-local and protect mutable state shared by
74 callbacks with a mutex, atomics, channels, or another explicit ownership
75 scheme. Cancellation and shutdown may overlap work already in flight, so
76 callbacks and stream producers must honor their contexts.
77
78 The SDK serializes protocol writes itself; extensions must not write directly
79 to stdout. stderr remains available for diagnostics.
80
81 ## Runnable example
82
83 [`examples/starterextension`](examples/starterextension/README.md) is the
84 copyable first extension: it includes a Manifest v1 file, a minimal sidecar,
85 cross-platform build commands, linked installation, `/reload`, and a visible
86 input-rewrite check.
87
88 [`examples/fullsidecar`](examples/fullsidecar/main.go) is the reference
89 extension: input rewriting (try the `/fs ` trigger), tool interception
90 (block + argument rewrite), system-prompt strategy replacement, a fake
91 streaming provider (text chunks, a tool call, usage), structured UI (status +
92 card on session start, a form prompt behind the `demo` action), and a clean
93 bounded shutdown — all in one small stdlib-only program.
94
95 ```sh
96 go build -o /tmp/fullsidecar ./examples/fullsidecar
97 ```
98
99 The binary speaks the protocol on stdin/stdout, so install it as a plugin
100 package runtime (or point the host-side conformance suite at it) rather than
101 running it interactively. It is driven end-to-end against the real host by
102 `internal/extension/conformance` in the Reasonix repository.
103
104 ## Generated wire types
105
106 `types_generated.go` is produced from the host's frozen protocol registry by
107 `go run ./cmd/extension-protocol-gen -root .` (repository root). Edit nothing
108 in that file; the handwritten half of the type layer (validators, error
109 constructors, enum helpers) lives in `types_ext.go`.
110
111 ## Protocol reference
112
113 - Method/DTO contract: [`docs/EXTENSION_PROTOCOL.generated.md`](../../docs/EXTENSION_PROTOCOL.generated.md)
114 - Canonical JSON schema: [`internal/extension/protocol/schema.generated.json`](../../internal/extension/protocol/schema.generated.json)
115 - Transport: strict JSON-RPC 2.0 over NDJSON (one object per line), integer
116 request ids, object params, 8 MiB frames.
117
118 ## Stability
119
120 Extension Protocol v1's compatibility promise applies: within major version
121 1, only optional fields, new enum values, and new methods are added; existing
122 required fields, method names, directions, limits, error reasons, and
123 semantics never change. This SDK tracks that contract — upgrading within v1
124 never breaks a compiled extension.
125
125 lines MARKDOWN