orynacode-ai 1.16.2 → 1.16.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/cli/cmd/models.ts +1 -1
- package/src/cli/cmd/providers.ts +3 -3
- package/src/cli/cmd/tui/component/dialog-provider.tsx +16 -16
- package/src/cli/cmd/tui/routes/home.tsx +5 -5
- package/src/cli/cmd/tui/routes/session/index.tsx +5 -5
- package/src/oryna/agent.ts +2 -2
- package/src/plugin/index.ts +2 -2
- package/src/plugin/oryna.ts +4 -4
- package/src/server/routes/instance/httpapi/handlers/config.ts +11 -11
- package/src/server/routes/instance/httpapi/handlers/control.ts +2 -2
- package/src/server/routes/instance/httpapi/handlers/provider.ts +5 -5
package/package.json
CHANGED
package/src/cli/cmd/models.ts
CHANGED
|
@@ -54,7 +54,7 @@ export const ModelsCommand = effectCmd({
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
const ids = Object.keys(providers)
|
|
57
|
-
.filter((id) => id === "oryna" || id === "
|
|
57
|
+
.filter((id) => id === "oryna" || id === "orynagate")
|
|
58
58
|
.sort((a, b) => {
|
|
59
59
|
if (a === "oryna") return -1
|
|
60
60
|
if (b === "oryna") return 1
|
package/src/cli/cmd/providers.ts
CHANGED
|
@@ -361,14 +361,14 @@ export const ProvidersLoginCommand = effectCmd({
|
|
|
361
361
|
const allProviders = yield* modelsDev.get()
|
|
362
362
|
const providers: Record<string, (typeof allProviders)[string]> = {}
|
|
363
363
|
for (const [key, value] of Object.entries(allProviders)) {
|
|
364
|
-
if (key !== "oryna" && key !== "
|
|
364
|
+
if (key !== "oryna" && key !== "orynagate") continue
|
|
365
365
|
if ((enabled ? enabled.has(key) : true) && !disabled.has(key)) providers[key] = value
|
|
366
366
|
}
|
|
367
367
|
const hooks = yield* pluginSvc.list()
|
|
368
368
|
|
|
369
369
|
const priority: Record<string, number> = {
|
|
370
370
|
oryna: 0,
|
|
371
|
-
"
|
|
371
|
+
"orynagate": 1,
|
|
372
372
|
}
|
|
373
373
|
const pluginProviders = resolvePluginProviders({
|
|
374
374
|
hooks,
|
|
@@ -393,7 +393,7 @@ export const ProvidersLoginCommand = effectCmd({
|
|
|
393
393
|
}[x.id],
|
|
394
394
|
})),
|
|
395
395
|
),
|
|
396
|
-
...pluginProviders.filter((x) => x.id === "oryna" || x.id === "
|
|
396
|
+
...pluginProviders.filter((x) => x.id === "oryna" || x.id === "orynagate").map((x) => ({
|
|
397
397
|
label: x.name,
|
|
398
398
|
value: x.id,
|
|
399
399
|
hint: "plugin",
|
|
@@ -24,7 +24,7 @@ import os from "os"
|
|
|
24
24
|
|
|
25
25
|
const PROVIDER_PRIORITY: Record<string, number> = {
|
|
26
26
|
oryna: 0,
|
|
27
|
-
"
|
|
27
|
+
"orynagate": 1,
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
const CUSTOM_PROVIDER_OPTION_VALUE = "__opencode_custom_provider__"
|
|
@@ -58,7 +58,7 @@ export function providerOptions(list: { id: string; name: string }[]): ProviderO
|
|
|
58
58
|
providerID: provider.id,
|
|
59
59
|
description: {
|
|
60
60
|
oryna: "Cloud API — China's Best LLMs, Now Global.",
|
|
61
|
-
"
|
|
61
|
+
"orynagate": "Deploy on your own network",
|
|
62
62
|
}[provider.id],
|
|
63
63
|
category: "Oryna",
|
|
64
64
|
})),
|
|
@@ -134,7 +134,7 @@ export function createDialogProviderOptions() {
|
|
|
134
134
|
async onSelect() {
|
|
135
135
|
if (consoleManaged) return
|
|
136
136
|
|
|
137
|
-
if (providerID === "
|
|
137
|
+
if (providerID === "orynagate") {
|
|
138
138
|
dialog.replace(() => <ConnectLocal onClose={() => dialog.clear()} />)
|
|
139
139
|
return
|
|
140
140
|
}
|
|
@@ -547,14 +547,14 @@ function ConnectLocal(props: { onClose: () => void }) {
|
|
|
547
547
|
onCleanup(() => clearInterval(scanTimer))
|
|
548
548
|
|
|
549
549
|
async function connect(url: string) {
|
|
550
|
-
process.env.
|
|
550
|
+
process.env.ORYNA_GATE_URL = url
|
|
551
551
|
await sdk.client.auth.set({
|
|
552
|
-
providerID: "
|
|
552
|
+
providerID: "orynagate",
|
|
553
553
|
auth: { type: "api", key: `sk-local-${os.userInfo().username || "user"}-${path.basename(process.cwd())}`, metadata: { url } },
|
|
554
554
|
})
|
|
555
555
|
await sdk.client.instance.dispose()
|
|
556
556
|
await sync.bootstrap()
|
|
557
|
-
dialog.replace(() => <DialogModel providerID="
|
|
557
|
+
dialog.replace(() => <DialogModel providerID="orynagate" />)
|
|
558
558
|
startAgent()
|
|
559
559
|
}
|
|
560
560
|
|
|
@@ -579,7 +579,7 @@ function ConnectLocal(props: { onClose: () => void }) {
|
|
|
579
579
|
<box paddingLeft={2} paddingRight={2} gap={1} paddingBottom={1}>
|
|
580
580
|
<box flexDirection="row" justifyContent="space-between">
|
|
581
581
|
<text attributes={TextAttributes.BOLD} fg={theme.text}>
|
|
582
|
-
|
|
582
|
+
OrynaGate
|
|
583
583
|
</text>
|
|
584
584
|
<text fg={theme.textMuted} onMouseUp={props.onClose}>
|
|
585
585
|
esc
|
|
@@ -591,14 +591,14 @@ function ConnectLocal(props: { onClose: () => void }) {
|
|
|
591
591
|
<Show when={status() === "scanning"}>
|
|
592
592
|
<box flexGrow={1} alignItems="center" justifyContent="center" gap={1} paddingTop={2} paddingBottom={2}>
|
|
593
593
|
<Spinner color={theme.primary} />
|
|
594
|
-
<text fg={theme.textMuted}>Scanning local network for
|
|
594
|
+
<text fg={theme.textMuted}>Scanning local network for OrynaGate ({scanSeconds()}s)</text>
|
|
595
595
|
<text fg={theme.textMuted}>Checking port 9527 in nearby subnets</text>
|
|
596
596
|
</box>
|
|
597
597
|
</Show>
|
|
598
598
|
|
|
599
599
|
<Show when={status() === "found"}>
|
|
600
600
|
<box gap={1} paddingTop={2}>
|
|
601
|
-
<text fg={theme.success}>✓ Found
|
|
601
|
+
<text fg={theme.success}>✓ Found OrynaGate</text>
|
|
602
602
|
<text fg={theme.textMuted}>{proxyUrls()[0]}</text>
|
|
603
603
|
<text fg={theme.textMuted}>Connecting...</text>
|
|
604
604
|
</box>
|
|
@@ -607,12 +607,12 @@ function ConnectLocal(props: { onClose: () => void }) {
|
|
|
607
607
|
<Show when={status() === "multiple"}>
|
|
608
608
|
<box gap={1} paddingTop={1}>
|
|
609
609
|
<box flexDirection="row" justifyContent="space-between">
|
|
610
|
-
<text fg={theme.success}>✓ Found {proxyUrls().length}
|
|
610
|
+
<text fg={theme.success}>✓ Found {proxyUrls().length} OrynaGate servers</text>
|
|
611
611
|
<text fg={theme.textMuted} onMouseUp={() => setStatus("not-found")}>← Back</text>
|
|
612
612
|
</box>
|
|
613
613
|
<For each={proxyUrls()}>
|
|
614
614
|
{(url, index) => {
|
|
615
|
-
const name = `
|
|
615
|
+
const name = `OrynaGate (${new URL(url).hostname})`
|
|
616
616
|
return (
|
|
617
617
|
<box flexDirection="row" gap={1}>
|
|
618
618
|
<text fg={selectedIndex() === index() ? theme.primary : theme.textMuted}>
|
|
@@ -637,8 +637,8 @@ function ConnectLocal(props: { onClose: () => void }) {
|
|
|
637
637
|
<Show when={status() === "not-found" || status() === "validating" || status() === "invalid"}>
|
|
638
638
|
<box gap={1} paddingTop={1}>
|
|
639
639
|
<Show when={status() === "not-found"}>
|
|
640
|
-
<text fg={theme.warning}>No
|
|
641
|
-
<text fg={theme.textMuted}>
|
|
640
|
+
<text fg={theme.warning}>No OrynaGate found on your network</text>
|
|
641
|
+
<text fg={theme.textMuted}>OrynaGate lets you run models on your own infrastructure.</text>
|
|
642
642
|
</Show>
|
|
643
643
|
<Show when={status() === "validating"}>
|
|
644
644
|
<box flexDirection="row" gap={1}>
|
|
@@ -647,7 +647,7 @@ function ConnectLocal(props: { onClose: () => void }) {
|
|
|
647
647
|
</box>
|
|
648
648
|
</Show>
|
|
649
649
|
<Show when={status() === "invalid"}>
|
|
650
|
-
<text fg={theme.error}>Could not reach
|
|
650
|
+
<text fg={theme.error}>Could not reach OrynaGate at this address</text>
|
|
651
651
|
</Show>
|
|
652
652
|
<box gap={2} paddingTop={1}>
|
|
653
653
|
<text fg={theme.primary} onMouseUp={() => setManual(true)}>
|
|
@@ -655,7 +655,7 @@ function ConnectLocal(props: { onClose: () => void }) {
|
|
|
655
655
|
</text>
|
|
656
656
|
</box>
|
|
657
657
|
<box gap={1} paddingTop={1} flexDirection="row">
|
|
658
|
-
<text fg={theme.textMuted}>Don't have
|
|
658
|
+
<text fg={theme.textMuted}>Don't have OrynaGate? Download at</text>
|
|
659
659
|
<text fg={theme.primary} onMouseUp={() => open("https://oryna.ai").catch(() => {})}>oryna.ai</text>
|
|
660
660
|
</box>
|
|
661
661
|
</box>
|
|
@@ -663,7 +663,7 @@ function ConnectLocal(props: { onClose: () => void }) {
|
|
|
663
663
|
</>
|
|
664
664
|
}>
|
|
665
665
|
<box gap={1} paddingTop={1}>
|
|
666
|
-
<text fg={theme.textMuted}>Enter
|
|
666
|
+
<text fg={theme.textMuted}>Enter OrynaGate address:</text>
|
|
667
667
|
<textarea
|
|
668
668
|
height={3}
|
|
669
669
|
ref={(val: any) => {
|
|
@@ -69,16 +69,16 @@ export function Home() {
|
|
|
69
69
|
})
|
|
70
70
|
|
|
71
71
|
// connect/disconnect WS based on selected model
|
|
72
|
-
let
|
|
72
|
+
let lastWasOrynaGate = false
|
|
73
73
|
createEffect(() => {
|
|
74
74
|
const model = local.model.current()
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
75
|
+
const isOrynaGate = model?.providerID === "orynagate"
|
|
76
|
+
if (isOrynaGate && !lastWasOrynaGate) {
|
|
77
77
|
startAgent()
|
|
78
|
-
} else if (!
|
|
78
|
+
} else if (!isOrynaGate && lastWasOrynaGate) {
|
|
79
79
|
stopAgent()
|
|
80
80
|
}
|
|
81
|
-
|
|
81
|
+
lastWasOrynaGate = isOrynaGate
|
|
82
82
|
})
|
|
83
83
|
|
|
84
84
|
const bind = (r: PromptRef | undefined) => {
|
|
@@ -1184,16 +1184,16 @@ export function Session() {
|
|
|
1184
1184
|
})
|
|
1185
1185
|
|
|
1186
1186
|
// connect/disconnect WS based on selected model
|
|
1187
|
-
let
|
|
1187
|
+
let lastWasOrynaGate = false
|
|
1188
1188
|
createEffect(() => {
|
|
1189
1189
|
const model = local.model.current()
|
|
1190
|
-
const
|
|
1191
|
-
if (
|
|
1190
|
+
const isOrynaGate = model?.providerID === "orynagate"
|
|
1191
|
+
if (isOrynaGate && !lastWasOrynaGate) {
|
|
1192
1192
|
startAgent()
|
|
1193
|
-
} else if (!
|
|
1193
|
+
} else if (!isOrynaGate && lastWasOrynaGate) {
|
|
1194
1194
|
stopAgent()
|
|
1195
1195
|
}
|
|
1196
|
-
|
|
1196
|
+
lastWasOrynaGate = isOrynaGate
|
|
1197
1197
|
})
|
|
1198
1198
|
|
|
1199
1199
|
return (
|
package/src/oryna/agent.ts
CHANGED
|
@@ -21,7 +21,7 @@ function readAuthUrl(): string | undefined {
|
|
|
21
21
|
const dataDir = process.env.XDG_DATA_HOME || path.join(os.homedir(), ".local", "share")
|
|
22
22
|
const authPath = path.join(dataDir, "orynacode", "auth.json")
|
|
23
23
|
const auth = JSON.parse(readFileSync(authPath, "utf-8"))
|
|
24
|
-
const local = auth?.["
|
|
24
|
+
const local = auth?.["orynagate"]
|
|
25
25
|
if (local?.metadata?.url) return local.metadata.url
|
|
26
26
|
} catch {}
|
|
27
27
|
return undefined
|
|
@@ -46,7 +46,7 @@ function startReplyWatch() {
|
|
|
46
46
|
|
|
47
47
|
export function start() {
|
|
48
48
|
stopped = false
|
|
49
|
-
const url = process.env.
|
|
49
|
+
const url = process.env.ORYNA_GATE_URL || readAuthUrl()
|
|
50
50
|
if (!url) return
|
|
51
51
|
if (connecting) return
|
|
52
52
|
connecting = true
|
package/src/plugin/index.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { CloudflareAIGatewayAuthPlugin, CloudflareWorkersAuthPlugin } from "./cl
|
|
|
19
19
|
import { AzureAuthPlugin } from "./azure"
|
|
20
20
|
import { DigitalOceanAuthPlugin } from "./digitalocean"
|
|
21
21
|
import { XaiAuthPlugin } from "./xai"
|
|
22
|
-
import { OrynaAuthPlugin,
|
|
22
|
+
import { OrynaAuthPlugin, OrynaGateProvider } from "./oryna"
|
|
23
23
|
import { Effect, Layer, Context } from "effect"
|
|
24
24
|
import { EffectBridge } from "@/effect/bridge"
|
|
25
25
|
import { InstanceState } from "@/effect/instance-state"
|
|
@@ -80,7 +80,7 @@ function internalPlugins(flags: RuntimeFlags.Info): PluginInstance[] {
|
|
|
80
80
|
DigitalOceanAuthPlugin,
|
|
81
81
|
XaiAuthPlugin,
|
|
82
82
|
OrynaAuthPlugin,
|
|
83
|
-
|
|
83
|
+
OrynaGateProvider,
|
|
84
84
|
]
|
|
85
85
|
}
|
|
86
86
|
|
package/src/plugin/oryna.ts
CHANGED
|
@@ -325,13 +325,13 @@ export async function OrynaAuthPlugin(input: PluginInput): Promise<Hooks> {
|
|
|
325
325
|
}
|
|
326
326
|
}
|
|
327
327
|
|
|
328
|
-
export async function
|
|
328
|
+
export async function OrynaGateProvider(_input: PluginInput): Promise<Hooks> {
|
|
329
329
|
return {
|
|
330
330
|
provider: {
|
|
331
|
-
id: "
|
|
332
|
-
name: "
|
|
331
|
+
id: "orynagate",
|
|
332
|
+
name: "OrynaGate",
|
|
333
333
|
async models(_provider, _ctx) {
|
|
334
|
-
const url = process.env.
|
|
334
|
+
const url = process.env.ORYNA_GATE_URL
|
|
335
335
|
if (!url) return {}
|
|
336
336
|
try {
|
|
337
337
|
const base = url.endsWith("/") ? url.slice(0, -1) : url
|
|
@@ -17,14 +17,14 @@ async function tryRecoverLocalUrl(): Promise<{ url: string; key?: string } | und
|
|
|
17
17
|
try {
|
|
18
18
|
const authFile = path.join(Global.Path.data, "auth.json")
|
|
19
19
|
const data = await Bun.file(authFile).json()
|
|
20
|
-
const localAuth = data?.["
|
|
20
|
+
const localAuth = data?.["orynagate"]
|
|
21
21
|
if (!localAuth || localAuth.type !== "api" || !localAuth.metadata?.url) return
|
|
22
22
|
const url = localAuth.metadata.url
|
|
23
23
|
const key = localAuth.key
|
|
24
24
|
const base = url.endsWith("/") ? url.slice(0, -1) : url
|
|
25
25
|
const res = await fetch(`${base}/api.json`, { signal: AbortSignal.timeout(3000) })
|
|
26
26
|
if (res.ok) {
|
|
27
|
-
process.env.
|
|
27
|
+
process.env.ORYNA_GATE_URL = url
|
|
28
28
|
_localAuthKey = key
|
|
29
29
|
return { url, key }
|
|
30
30
|
}
|
|
@@ -40,7 +40,7 @@ function mapOrynaModels(data: Record<string, any>): Record<string, any> {
|
|
|
40
40
|
result[id] = {
|
|
41
41
|
id,
|
|
42
42
|
name: m.name,
|
|
43
|
-
providerID: "
|
|
43
|
+
providerID: "orynagate",
|
|
44
44
|
family: m.family,
|
|
45
45
|
api: { id, url: oryna.api ?? "", npm: oryna.npm ?? "@ai-sdk/openai-compatible" },
|
|
46
46
|
capabilities: {
|
|
@@ -102,14 +102,14 @@ export const configHandlers = HttpApiBuilder.group(InstanceHttpApi, "config", (h
|
|
|
102
102
|
|
|
103
103
|
const providers = Effect.fn("ConfigHttpApi.providers")(function* () {
|
|
104
104
|
const allProviders = yield* providerSvc.list()
|
|
105
|
-
const orynaIDs = new Set(["oryna", "
|
|
105
|
+
const orynaIDs = new Set(["oryna", "orynagate"])
|
|
106
106
|
const filtered: Record<string, any> = {}
|
|
107
107
|
for (const [id, info] of Object.entries(allProviders)) {
|
|
108
108
|
if (orynaIDs.has(id)) filtered[id] = info
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
const localUrlRecover = process.env.
|
|
112
|
-
? { url: process.env.
|
|
111
|
+
const localUrlRecover = process.env.ORYNA_GATE_URL
|
|
112
|
+
? { url: process.env.ORYNA_GATE_URL }
|
|
113
113
|
: (yield* Effect.tryPromise(() => tryRecoverLocalUrl()).pipe(
|
|
114
114
|
Effect.catchCause(() => Effect.succeed(undefined)),
|
|
115
115
|
))
|
|
@@ -121,11 +121,11 @@ export const configHandlers = HttpApiBuilder.group(InstanceHttpApi, "config", (h
|
|
|
121
121
|
)
|
|
122
122
|
const models = (raw as any).models ?? {}
|
|
123
123
|
const localApi = (raw as any).api
|
|
124
|
-
const existing = allProviders["
|
|
124
|
+
const existing = allProviders["orynagate" as any] as Record<string, any> | undefined
|
|
125
125
|
const existingKey = existing?.key || recoveredKey
|
|
126
126
|
const entry = {
|
|
127
|
-
id: "
|
|
128
|
-
name: "
|
|
127
|
+
id: "orynagate",
|
|
128
|
+
name: "OrynaGate",
|
|
129
129
|
env: [],
|
|
130
130
|
source: existing?.source ?? "api",
|
|
131
131
|
key: existingKey,
|
|
@@ -133,8 +133,8 @@ export const configHandlers = HttpApiBuilder.group(InstanceHttpApi, "config", (h
|
|
|
133
133
|
models,
|
|
134
134
|
options: existing?.options ?? {},
|
|
135
135
|
}
|
|
136
|
-
filtered["
|
|
137
|
-
allProviders["
|
|
136
|
+
filtered["orynagate"] = entry
|
|
137
|
+
allProviders["orynagate" as any] = Provider.toPublicInfo(entry as any)
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
const withModels = Object.fromEntries(
|
|
@@ -16,8 +16,8 @@ export const controlHandlers = HttpApiBuilder.group(RootHttpApi, "control", (han
|
|
|
16
16
|
payload: Auth.Info
|
|
17
17
|
}) {
|
|
18
18
|
yield* auth.set(ctx.params.providerID, ctx.payload).pipe(Effect.orDie)
|
|
19
|
-
if (ctx.payload.type === "api" && ctx.payload.metadata?.url && String(ctx.params.providerID) === "
|
|
20
|
-
process.env.
|
|
19
|
+
if (ctx.payload.type === "api" && ctx.payload.metadata?.url && String(ctx.params.providerID) === "orynagate") {
|
|
20
|
+
process.env.ORYNA_GATE_URL = ctx.payload.metadata.url
|
|
21
21
|
}
|
|
22
22
|
return true
|
|
23
23
|
})
|
|
@@ -74,17 +74,17 @@ export const providerHandlers = HttpApiBuilder.group(InstanceHttpApi, "provider"
|
|
|
74
74
|
models: orynaRemote?.models ?? {},
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
const localUrl = process.env.
|
|
78
|
-
filtered["
|
|
79
|
-
id: "
|
|
80
|
-
name: "
|
|
77
|
+
const localUrl = process.env.ORYNA_GATE_URL
|
|
78
|
+
filtered["orynagate"] = {
|
|
79
|
+
id: "orynagate",
|
|
80
|
+
name: "OrynaGate",
|
|
81
81
|
env: [],
|
|
82
82
|
api: localUrl ? `${localUrl.endsWith("/") ? localUrl.slice(0, -1) : localUrl}/v1` : "",
|
|
83
83
|
models: {},
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
const connected = yield* provider.list()
|
|
87
|
-
const orynaIDs = new Set(["oryna", "
|
|
87
|
+
const orynaIDs = new Set(["oryna", "orynagate"])
|
|
88
88
|
const filteredConnected: Record<string, any> = {}
|
|
89
89
|
for (const [id, info] of Object.entries(connected)) {
|
|
90
90
|
if (orynaIDs.has(id)) filteredConnected[id] = info
|