type error fix

This commit is contained in:
Dax Raad 2025-05-29 11:58:40 -04:00
parent 48f81fe4d3
commit 80597cd3fd
28 changed files with 76 additions and 230 deletions

View file

@ -1 +0,0 @@
export const x: number = "asd";

View file

@ -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);
});

View file

@ -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 />);

View file

@ -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 {

View file

@ -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();

View file

@ -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";

View file

@ -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 ?? {});

View file

@ -1 +0,0 @@
export * as anthropic from "./anthropic";

View file

@ -1,11 +0,0 @@
export interface ModelInfo {
cost: {
input: number;
inputCached: number;
output: number;
outputCached: number;
};
contextWindow: number;
maxTokens: number;
attachment: boolean;
}

View file

@ -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;

View file

@ -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 {

View 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>;
}

View file

@ -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;
}

View file

@ -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";

View file

@ -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";

View file

@ -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";

View file

@ -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:

View file

@ -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).

View file

@ -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";

View file

@ -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";

View file

@ -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",

View file

@ -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",

View file

@ -1,4 +1,4 @@
import { App } from "../../app";
import { App } from "../../app/app";
export namespace FileTimes {
export const state = App.state("tool.filetimes", () => ({

View file

@ -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";

View file

@ -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": {

View file

@ -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
}