Add projects

This commit is contained in:
Alois 2026-08-24 00:10:41 +02:00
commit 8b607dd700
Signed by: alois
SSH key fingerprint: SHA256:GBzT2DXvAuGV9XIV5W3WrzVpjU54FThmxHXdbz95J24
1802 changed files with 503346 additions and 2 deletions

View file

@ -0,0 +1,99 @@
package pluginabi
import "encoding/json"
const (
// ABIVersion tracks the native C ABI shape (native plugin exports).
ABIVersion uint32 = 1
// SchemaVersion tracks the RPC JSON contract exchanged at plugin.register.
// Version 2 adds request lifecycle completion and active request termination.
// Version 3 omits OriginalRequest/RequestBody on payload stream chunks
// (ChunkIndex >= 0); those fields remain on StreamChunkHeaderInitIndex only.
// Plugins that still need per-chunk request bodies should keep schema_version < 3.
SchemaVersion uint32 = 3
// SchemaVersionStreamChunkOmitRequestBody is the first schema version that omits
// request bodies on payload stream-chunk interceptor calls.
SchemaVersionStreamChunkOmitRequestBody uint32 = 3
)
const (
MethodPluginRegister = "plugin.register"
MethodPluginReconfigure = "plugin.reconfigure"
MethodPluginShutdown = "plugin.shutdown"
MethodModelRegister = "model.register"
MethodModelStatic = "model.static"
MethodModelForAuth = "model.for_auth"
MethodAuthIdentifier = "auth.identifier"
MethodAuthParse = "auth.parse"
MethodAuthLoginStart = "auth.login.start"
MethodAuthLoginPoll = "auth.login.poll"
MethodAuthRefresh = "auth.refresh"
MethodFrontendAuthIdentifier = "frontend_auth.identifier"
MethodFrontendAuthAuthenticate = "frontend_auth.authenticate"
// MethodSchedulerPick asks a scheduler plugin to select an auth candidate.
MethodSchedulerPick = "scheduler.pick"
// MethodModelRoute asks a router plugin to select a plugin executor for a matching request.
MethodModelRoute = "model.route"
MethodExecutorIdentifier = "executor.identifier"
MethodExecutorExecute = "executor.execute"
MethodExecutorExecuteStream = "executor.execute_stream"
MethodExecutorCountTokens = "executor.count_tokens"
MethodExecutorHTTPRequest = "executor.http_request"
MethodRequestTranslate = "request.translate"
MethodRequestNormalize = "request.normalize"
MethodRequestInterceptBefore = "request.intercept_before"
MethodRequestInterceptAfter = "request.intercept_after"
MethodRequestComplete = "request.complete"
MethodResponseTranslate = "response.translate"
MethodResponseNormalizeBefore = "response.normalize_before"
MethodResponseNormalizeAfter = "response.normalize_after"
MethodResponseInterceptAfter = "response.intercept_after"
MethodResponseInterceptStreamChunk = "response.intercept_stream_chunk"
MethodThinkingIdentifier = "thinking.identifier"
MethodThinkingApply = "thinking.apply"
MethodUsageHandle = "usage.handle"
MethodCommandLineRegister = "command_line.register"
MethodCommandLineExecute = "command_line.execute"
MethodManagementRegister = "management.register"
MethodManagementHandle = "management.handle"
MethodHostHTTPDo = "host.http.do"
MethodHostHTTPDoStream = "host.http.do_stream"
MethodHostHTTPStreamRead = "host.http.stream_read"
MethodHostHTTPStreamClose = "host.http.stream_close"
MethodHostModelExecute = "host.model.execute"
MethodHostModelExecuteStream = "host.model.execute_stream"
MethodHostModelStreamRead = "host.model.stream_read"
MethodHostModelStreamClose = "host.model.stream_close"
MethodHostStreamEmit = "host.stream.emit"
MethodHostStreamClose = "host.stream.close"
MethodHostLog = "host.log"
MethodHostAuthList = "host.auth.list"
MethodHostAuthGet = "host.auth.get"
MethodHostAuthGetRuntime = "host.auth.get_runtime"
MethodHostAuthSave = "host.auth.save"
)
type Envelope struct {
OK bool `json:"ok"`
Result json.RawMessage `json:"result,omitempty"`
Error *Error `json:"error,omitempty"`
}
type Error struct {
Code string `json:"code"`
Message string `json:"message"`
Retryable bool `json:"retryable,omitempty"`
HTTPStatus int `json:"http_status,omitempty"`
}

View file

@ -0,0 +1,96 @@
package pluginabi
import (
"encoding/json"
"testing"
)
func TestEnvelopeRoundTrip(t *testing.T) {
payload := json.RawMessage(`{"name":"example"}`)
env := Envelope{
OK: true,
Result: payload,
}
raw, errMarshal := json.Marshal(env)
if errMarshal != nil {
t.Fatalf("marshal envelope: %v", errMarshal)
}
var decoded Envelope
if errUnmarshal := json.Unmarshal(raw, &decoded); errUnmarshal != nil {
t.Fatalf("unmarshal envelope: %v", errUnmarshal)
}
if !decoded.OK || string(decoded.Result) != string(payload) {
t.Fatalf("decoded envelope = %#v, want ok payload", decoded)
}
}
func TestMethodNamesAreStable(t *testing.T) {
if SchemaVersion != 3 {
t.Fatalf("SchemaVersion = %d, want 3", SchemaVersion)
}
if SchemaVersionStreamChunkOmitRequestBody != 3 {
t.Fatalf("SchemaVersionStreamChunkOmitRequestBody = %d, want 3", SchemaVersionStreamChunkOmitRequestBody)
}
if MethodPluginRegister != "plugin.register" {
t.Fatalf("MethodPluginRegister = %q", MethodPluginRegister)
}
if MethodRequestInterceptBefore != "request.intercept_before" {
t.Fatalf("MethodRequestInterceptBefore = %q", MethodRequestInterceptBefore)
}
if MethodRequestInterceptAfter != "request.intercept_after" {
t.Fatalf("MethodRequestInterceptAfter = %q", MethodRequestInterceptAfter)
}
if MethodRequestComplete != "request.complete" {
t.Fatalf("MethodRequestComplete = %q", MethodRequestComplete)
}
if MethodResponseInterceptAfter != "response.intercept_after" {
t.Fatalf("MethodResponseInterceptAfter = %q", MethodResponseInterceptAfter)
}
if MethodResponseInterceptStreamChunk != "response.intercept_stream_chunk" {
t.Fatalf("MethodResponseInterceptStreamChunk = %q", MethodResponseInterceptStreamChunk)
}
if MethodHostHTTPDo != "host.http.do" {
t.Fatalf("MethodHostHTTPDo = %q", MethodHostHTTPDo)
}
if MethodHostHTTPStreamRead != "host.http.stream_read" {
t.Fatalf("MethodHostHTTPStreamRead = %q", MethodHostHTTPStreamRead)
}
if MethodHostModelExecute != "host.model.execute" {
t.Fatalf("MethodHostModelExecute = %q", MethodHostModelExecute)
}
if MethodHostModelExecuteStream != "host.model.execute_stream" {
t.Fatalf("MethodHostModelExecuteStream = %q", MethodHostModelExecuteStream)
}
if MethodHostModelStreamRead != "host.model.stream_read" {
t.Fatalf("MethodHostModelStreamRead = %q", MethodHostModelStreamRead)
}
if MethodHostModelStreamClose != "host.model.stream_close" {
t.Fatalf("MethodHostModelStreamClose = %q", MethodHostModelStreamClose)
}
if MethodHostAuthList != "host.auth.list" {
t.Fatalf("MethodHostAuthList = %q", MethodHostAuthList)
}
if MethodHostAuthGet != "host.auth.get" {
t.Fatalf("MethodHostAuthGet = %q", MethodHostAuthGet)
}
if MethodHostAuthGetRuntime != "host.auth.get_runtime" {
t.Fatalf("MethodHostAuthGetRuntime = %q", MethodHostAuthGetRuntime)
}
if MethodHostAuthSave != "host.auth.save" {
t.Fatalf("MethodHostAuthSave = %q", MethodHostAuthSave)
}
if MethodExecutorExecuteStream != "executor.execute_stream" {
t.Fatalf("MethodExecutorExecuteStream = %q", MethodExecutorExecuteStream)
}
}
func TestSchedulerPickMethodName(t *testing.T) {
if MethodSchedulerPick != "scheduler.pick" {
t.Fatalf("MethodSchedulerPick = %q", MethodSchedulerPick)
}
if MethodModelRoute != "model.route" {
t.Fatalf("MethodModelRoute = %q", MethodModelRoute)
}
}