mirror of
https://github.com/sst/opencode.git
synced 2025-08-31 10:17:26 +00:00
type error fix
This commit is contained in:
parent
48f81fe4d3
commit
80597cd3fd
28 changed files with 76 additions and 230 deletions
|
@ -1 +0,0 @@
|
|||
export const x: number = "asd";
|
|
@ -1,21 +0,0 @@
|
|||
import { App } from "../src/app";
|
||||
import path from "path";
|
||||
import { edit } from "../src/tool";
|
||||
import { FileTimes } from "../src/tool/util/file-times";
|
||||
|
||||
await App.provide({ directory: process.cwd() }, async () => {
|
||||
const file = path.join(process.cwd(), "example/broken.ts");
|
||||
FileTimes.read(file);
|
||||
const tool = await edit.execute(
|
||||
{
|
||||
file_path: file,
|
||||
old_string: "x:",
|
||||
new_string: "x:",
|
||||
},
|
||||
{
|
||||
toolCallId: "test",
|
||||
messages: [],
|
||||
},
|
||||
);
|
||||
console.log(tool.output);
|
||||
});
|
|
@ -1,122 +0,0 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import type { Server } from "../src/server/server";
|
||||
import type { Session } from "../src/session/session";
|
||||
import { hc } from "hono/client";
|
||||
import { createInterface, Interface } from "readline";
|
||||
|
||||
const client = hc<Server.App>(`http://localhost:16713`);
|
||||
|
||||
|
||||
const session = await client.session_create.$post().then((res) => res.json());
|
||||
|
||||
const initial: {
|
||||
session: {
|
||||
info: {
|
||||
[sessionID: string]: Session.Info;
|
||||
};
|
||||
message: {
|
||||
[sessionID: string]: {
|
||||
[messageID: string]: Session.Message;
|
||||
};
|
||||
};
|
||||
};
|
||||
} = {
|
||||
session: {
|
||||
info: {
|
||||
[session.id]: session
|
||||
},
|
||||
message: {
|
||||
[session.id]: {}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
import { render, Text, Newline, useStdout, Box } from "ink";
|
||||
import TextInput from "ink-text-input"
|
||||
|
||||
function App() {
|
||||
const [state, setState] = useState(initial)
|
||||
const [input, setInput] = useState("")
|
||||
|
||||
useEffect(() => {
|
||||
fetch("http://localhost:16713/event")
|
||||
.then(stream => {
|
||||
const decoder = new TextDecoder();
|
||||
stream.body!.pipeTo(
|
||||
new WritableStream({
|
||||
write(chunk) {
|
||||
const data = decoder.decode(chunk);
|
||||
if (data.startsWith("data: ")) {
|
||||
try {
|
||||
const event = JSON.parse(data.substring(6));
|
||||
switch (event.type) {
|
||||
case "storage.write":
|
||||
const splits: string[] = event.properties.key.split("/");
|
||||
let item = state as any;
|
||||
for (let i = 0; i < splits.length; i++) {
|
||||
const part = splits[i];
|
||||
if (i === splits.length - 1) {
|
||||
item[part] = event.properties.body;
|
||||
continue;
|
||||
}
|
||||
if (!item[part]) item[part] = {};
|
||||
item = item[part];
|
||||
}
|
||||
}
|
||||
setState({ ...state })
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
},
|
||||
}),
|
||||
)
|
||||
});
|
||||
}, [])
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Text>{session.title}</Text>
|
||||
{
|
||||
Object.values(state.session.message[session.id])
|
||||
.filter(message => message.role !== "system")
|
||||
.map(message => {
|
||||
return Object.values(message.parts)
|
||||
.map((part, index) => {
|
||||
if (part.type === "text") {
|
||||
return <Text key={`${message.id}-${index}`}>{message.role}: {part.text}</Text>
|
||||
}
|
||||
if (part.type === "tool-invocation") {
|
||||
return <Text key={`${message.id}-${index}`}>{message.role}: {part.toolInvocation.toolName} {JSON.stringify(part.toolInvocation.args)}</Text>
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
<Box gap={1} >
|
||||
<Text>Input:</Text>
|
||||
<TextInput
|
||||
value={input}
|
||||
onChange={setInput}
|
||||
onSubmit={() => {
|
||||
setInput("")
|
||||
client.session_chat.$post({
|
||||
json: {
|
||||
sessionID: session.id,
|
||||
parts: [
|
||||
{
|
||||
type: "text",
|
||||
text: input,
|
||||
},
|
||||
],
|
||||
}
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
console.clear();
|
||||
render(<App />);
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { z, type ZodType } from "zod";
|
||||
import { App } from "../app";
|
||||
import { App } from "../app/app";
|
||||
import { Log } from "../util/log";
|
||||
|
||||
export namespace Bus {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import path from "path";
|
||||
import { Log } from "../util/log";
|
||||
import { z } from "zod";
|
||||
import { App } from ".";
|
||||
import { App } from "../app/app";
|
||||
import { Provider } from "../provider/provider";
|
||||
|
||||
export namespace Config {
|
||||
const log = Log.create({ service: "config" });
|
||||
|
@ -11,38 +12,9 @@ export namespace Config {
|
|||
return result;
|
||||
});
|
||||
|
||||
export const Model = z
|
||||
.object({
|
||||
name: z.string().optional(),
|
||||
cost: z.object({
|
||||
input: z.number(),
|
||||
inputCached: z.number(),
|
||||
output: z.number(),
|
||||
outputCached: z.number(),
|
||||
}),
|
||||
contextWindow: z.number(),
|
||||
maxTokens: z.number().optional(),
|
||||
attachment: z.boolean(),
|
||||
reasoning: z.boolean().optional(),
|
||||
})
|
||||
.openapi({
|
||||
ref: "model",
|
||||
});
|
||||
export type Model = z.output<typeof Model>;
|
||||
|
||||
export const Provider = z
|
||||
.object({
|
||||
options: z.record(z.string(), z.any()).optional(),
|
||||
models: z.record(z.string(), Model),
|
||||
})
|
||||
.openapi({
|
||||
ref: "provider",
|
||||
});
|
||||
export type Provider = z.output<typeof Provider>;
|
||||
|
||||
export const Info = z
|
||||
.object({
|
||||
providers: z.record(z.string(), Provider).optional(),
|
||||
providers: z.record(z.string(), Provider.Info).optional(),
|
||||
})
|
||||
.strict();
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import "zod-openapi/extend";
|
||||
import { App } from "./app";
|
||||
import { App } from "./app/app";
|
||||
import { Server } from "./server/server";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { App } from "../app";
|
||||
import { App } from "../app/app";
|
||||
import { Log } from "../util/log";
|
||||
import { mergeDeep } from "remeda";
|
||||
import path from "path";
|
||||
import { Provider } from "../provider/provider";
|
||||
|
||||
import type { LanguageModel, Provider } from "ai";
|
||||
import type { LanguageModel, Provider as ProviderInstance } from "ai";
|
||||
import { NoSuchModelError } from "ai";
|
||||
import { Config } from "../app/config";
|
||||
import { Config } from "../config/config";
|
||||
import { BunProc } from "../bun";
|
||||
import { Global } from "../global";
|
||||
|
||||
|
@ -18,7 +19,7 @@ export namespace LLM {
|
|||
}
|
||||
}
|
||||
|
||||
const NATIVE_PROVIDERS: Record<string, Config.Provider> = {
|
||||
const NATIVE_PROVIDERS: Record<string, Provider.Info> = {
|
||||
anthropic: {
|
||||
models: {
|
||||
"claude-sonnet-4-20250514": {
|
||||
|
@ -76,18 +77,18 @@ export namespace LLM {
|
|||
google: ["GOOGLE_GENERATIVE_AI_API_KEY"],
|
||||
};
|
||||
|
||||
const state = App.state("llm", async (app) => {
|
||||
const state = App.state("llm", async () => {
|
||||
const config = await Config.get();
|
||||
const providers: Record<
|
||||
string,
|
||||
{
|
||||
info: Config.Provider;
|
||||
instance: Provider;
|
||||
info: Provider.Info;
|
||||
instance: ProviderInstance;
|
||||
}
|
||||
> = {};
|
||||
const models = new Map<
|
||||
string,
|
||||
{ info: Config.Model; instance: LanguageModel }
|
||||
{ info: Provider.Model; instance: LanguageModel }
|
||||
>();
|
||||
|
||||
const list = mergeDeep(NATIVE_PROVIDERS, config.providers ?? {});
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export * as anthropic from "./anthropic";
|
|
@ -1,11 +0,0 @@
|
|||
export interface ModelInfo {
|
||||
cost: {
|
||||
input: number;
|
||||
inputCached: number;
|
||||
output: number;
|
||||
outputCached: number;
|
||||
};
|
||||
contextWindow: number;
|
||||
maxTokens: number;
|
||||
attachment: boolean;
|
||||
}
|
|
@ -6,7 +6,7 @@ import {
|
|||
StreamMessageWriter,
|
||||
} from "vscode-jsonrpc/node";
|
||||
import type { Diagnostic as VSCodeDiagnostic } from "vscode-languageserver-types";
|
||||
import { App } from "../app";
|
||||
import { App } from "../app/app";
|
||||
import { Log } from "../util/log";
|
||||
import { LANGUAGE_EXTENSIONS } from "./language";
|
||||
import { Bus } from "../bus";
|
||||
|
@ -31,7 +31,6 @@ export namespace LSPClient {
|
|||
|
||||
export async function create(input: { cmd: string[]; serverID: string }) {
|
||||
log.info("starting client", input);
|
||||
let version = 0;
|
||||
|
||||
const app = await App.use();
|
||||
const [command, ...args] = input.cmd;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { App } from "../app";
|
||||
import { App } from "../app/app";
|
||||
import { Log } from "../util/log";
|
||||
import { LSPClient } from "./client";
|
||||
import path from "path";
|
||||
|
@ -9,6 +9,7 @@ export namespace LSP {
|
|||
const state = App.state(
|
||||
"lsp",
|
||||
async () => {
|
||||
log.info("initializing");
|
||||
const clients = new Map<string, LSPClient.Info>();
|
||||
|
||||
return {
|
||||
|
|
32
js/src/provider/provider.ts
Normal file
32
js/src/provider/provider.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
import z from "zod";
|
||||
|
||||
export namespace Provider {
|
||||
export const Model = z
|
||||
.object({
|
||||
name: z.string().optional(),
|
||||
cost: z.object({
|
||||
input: z.number(),
|
||||
inputCached: z.number(),
|
||||
output: z.number(),
|
||||
outputCached: z.number(),
|
||||
}),
|
||||
contextWindow: z.number(),
|
||||
maxTokens: z.number().optional(),
|
||||
attachment: z.boolean(),
|
||||
reasoning: z.boolean().optional(),
|
||||
})
|
||||
.openapi({
|
||||
ref: "Provider.Model",
|
||||
});
|
||||
export type Model = z.output<typeof Model>;
|
||||
|
||||
export const Info = z
|
||||
.object({
|
||||
options: z.record(z.string(), z.any()).optional(),
|
||||
models: z.record(z.string(), Model),
|
||||
})
|
||||
.openapi({
|
||||
ref: "Provider.Info",
|
||||
});
|
||||
export type Info = z.output<typeof Info>;
|
||||
}
|
|
@ -6,9 +6,9 @@ import { streamSSE } from "hono/streaming";
|
|||
import { Session } from "../session/session";
|
||||
import { resolver, validator as zValidator } from "hono-openapi/zod";
|
||||
import { z } from "zod";
|
||||
import { Config } from "../app/config";
|
||||
import { LLM } from "../llm/llm";
|
||||
import { Message } from "../session/message";
|
||||
import { Provider } from "../provider/provider";
|
||||
|
||||
export namespace Server {
|
||||
const log = Log.create({ service: "server" });
|
||||
|
@ -234,7 +234,7 @@ export namespace Server {
|
|||
description: "List of providers",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(z.record(z.string(), Config.Provider)),
|
||||
schema: resolver(z.record(z.string(), Provider.Info)),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -242,7 +242,7 @@ export namespace Server {
|
|||
}),
|
||||
async (c) => {
|
||||
const providers = await LLM.providers();
|
||||
const result: Record<string, Config.Provider> = {};
|
||||
const result: Record<string, Provider.Info> = {};
|
||||
for (const [providerID, provider] of Object.entries(providers)) {
|
||||
result[providerID] = provider.info;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import path from "path";
|
||||
import { App } from "../app/";
|
||||
import { App } from "../app/app";
|
||||
import { Identifier } from "../id/id";
|
||||
import { LLM } from "../llm/llm";
|
||||
import { Storage } from "../storage/storage";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { App } from "../app";
|
||||
import { App } from "../app/app";
|
||||
import { Bus } from "../bus";
|
||||
import { Session } from "../session/session";
|
||||
import { Storage } from "../storage/storage";
|
||||
|
|
|
@ -2,7 +2,7 @@ import { FileStorage } from "@flystorage/file-storage";
|
|||
import { LocalStorageAdapter } from "@flystorage/local-fs";
|
||||
import fs from "fs/promises";
|
||||
import { Log } from "../util/log";
|
||||
import { App } from "../app";
|
||||
import { App } from "../app/app";
|
||||
import { AppPath } from "../app/path";
|
||||
import { Bus } from "../bus";
|
||||
import z from "zod";
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
import { z } from "zod";
|
||||
import * as path from "path";
|
||||
import { Log } from "../util/log";
|
||||
import { Tool } from "./tool";
|
||||
import { FileTimes } from "./util/file-times";
|
||||
import { LSP } from "../lsp";
|
||||
|
||||
const log = Log.create({ service: "tool.edit" });
|
||||
|
||||
const DESCRIPTION = `Edits files by replacing text, creating new files, or deleting content. For moving or renaming files, use the Bash tool with the 'mv' command instead. For larger file edits, use the FileWrite tool to overwrite files.
|
||||
|
||||
Before using this tool:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { z } from "zod";
|
||||
import { Tool } from "./tool";
|
||||
import { App } from "../app";
|
||||
import { App } from "../app/app";
|
||||
|
||||
const DESCRIPTION = `Fast file pattern matching tool that finds files by name and pattern, returning matching paths sorted by modification time (newest first).
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { z } from "zod";
|
||||
import { Tool } from "./tool";
|
||||
import { App } from "../app";
|
||||
import { App } from "../app/app";
|
||||
import { spawn } from "child_process";
|
||||
import { promises as fs } from "fs";
|
||||
import path from "path";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { z } from "zod";
|
||||
import { Tool } from "./tool";
|
||||
import { App } from "../app";
|
||||
import { App } from "../app/app";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import { z } from "zod";
|
|||
import { Tool } from "./tool";
|
||||
import path from "path";
|
||||
import { LSP } from "../lsp";
|
||||
import { App } from "../app";
|
||||
import { App } from "../app/app";
|
||||
|
||||
export const LspDiagnosticTool = Tool.define({
|
||||
name: "diagnostics",
|
||||
|
|
|
@ -2,7 +2,7 @@ import { z } from "zod";
|
|||
import { Tool } from "./tool";
|
||||
import path from "path";
|
||||
import { LSP } from "../lsp";
|
||||
import { App } from "../app";
|
||||
import { App } from "../app/app";
|
||||
|
||||
export const LspHoverTool = Tool.define({
|
||||
name: "lsp.hover",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { App } from "../../app";
|
||||
import { App } from "../../app/app";
|
||||
|
||||
export namespace FileTimes {
|
||||
export const state = App.state("tool.filetimes", () => ({
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { describe, expect, test } from "bun:test";
|
||||
import { App } from "../../src/app";
|
||||
import { App } from "../../src/app/app";
|
||||
import { glob } from "../../src/tool/glob";
|
||||
import { ls } from "../../src/tool/ls";
|
||||
|
||||
|
|
|
@ -238,7 +238,7 @@
|
|||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/components/schemas/provider"
|
||||
"$ref": "#/components/schemas/Provider.Info"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -740,7 +740,7 @@
|
|||
"title"
|
||||
]
|
||||
},
|
||||
"provider": {
|
||||
"Provider.Info": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"options": {
|
||||
|
@ -750,7 +750,7 @@
|
|||
"models": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/components/schemas/model"
|
||||
"$ref": "#/components/schemas/Provider.Model"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -758,7 +758,7 @@
|
|||
"models"
|
||||
]
|
||||
},
|
||||
"model": {
|
||||
"Provider.Model": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
|
|
|
@ -170,8 +170,14 @@ type MessageToolInvocationToolResult struct {
|
|||
ToolName string `json:"toolName"`
|
||||
}
|
||||
|
||||
// Model defines model for model.
|
||||
type Model struct {
|
||||
// ProviderInfo defines model for Provider.Info.
|
||||
type ProviderInfo struct {
|
||||
Models map[string]ProviderModel `json:"models"`
|
||||
Options *map[string]interface{} `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
// ProviderModel defines model for Provider.Model.
|
||||
type ProviderModel struct {
|
||||
Attachment bool `json:"attachment"`
|
||||
ContextWindow float32 `json:"contextWindow"`
|
||||
Cost struct {
|
||||
|
@ -185,12 +191,6 @@ type Model struct {
|
|||
Reasoning *bool `json:"reasoning,omitempty"`
|
||||
}
|
||||
|
||||
// Provider defines model for provider.
|
||||
type Provider struct {
|
||||
Models map[string]Model `json:"models"`
|
||||
Options *map[string]interface{} `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
// SessionInfo defines model for session.info.
|
||||
type SessionInfo struct {
|
||||
Id string `json:"id"`
|
||||
|
@ -1329,7 +1329,7 @@ func (r GetEventResponse) StatusCode() int {
|
|||
type PostProviderListResponse struct {
|
||||
Body []byte
|
||||
HTTPResponse *http.Response
|
||||
JSON200 *map[string]Provider
|
||||
JSON200 *map[string]ProviderInfo
|
||||
}
|
||||
|
||||
// Status returns HTTPResponse.Status
|
||||
|
@ -1625,7 +1625,7 @@ func ParsePostProviderListResponse(rsp *http.Response) (*PostProviderListRespons
|
|||
|
||||
switch {
|
||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
|
||||
var dest map[string]Provider
|
||||
var dest map[string]ProviderInfo
|
||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue