Skip to content

Commit

Permalink
lint
Browse files Browse the repository at this point in the history
  • Loading branch information
EvanBoyle committed Dec 26, 2024
1 parent 3f439af commit b6b1b9a
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 41 deletions.
7 changes: 4 additions & 3 deletions src/component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { JSX } from "./jsx-runtime";
import type {
ComponentProps,
MaybePromise,
WorkflowComponent,
StreamComponent,
Streamable,
StreamComponent,
WorkflowComponent,
} from "./types";

import { JSX } from "./jsx-runtime";

export function Component<P, O>(
fn: (props: P) => MaybePromise<O | JSX.Element | JSX.Element[]>,
): WorkflowComponent<P, O> {
Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

import { Component, StreamComponent } from "./component";
import { execute } from "./resolve";
import { Element, ExecutableValue, Streamable } from "./types";
import { Stream } from "./stream";
import { Element, ExecutableValue, Streamable } from "./types";

// Collect component props
export interface CollectProps {
Expand All @@ -32,7 +32,7 @@ export const gsx = {
};

// Export Component and execute directly for use in type definitions
export { Component, StreamComponent, execute, Stream };
export { Component, execute, Stream, StreamComponent };

// Also export types
export type { Element, ExecutableValue, Streamable };
Expand Down
3 changes: 2 additions & 1 deletion src/jsx-runtime.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* eslint-disable @typescript-eslint/no-namespace */
import type { Streamable } from "./types";

import { resolveDeep } from "./resolve";
import { isInStreamingContext } from "./stream";
import type { Streamable } from "./types";

export namespace JSX {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
35 changes: 4 additions & 31 deletions src/llm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,34 +42,6 @@ export function createLLMService(config: LLMConfig) {
retryDelay = 1000,
} = config;

// Helper to create a streaming response
function createStreamingResponse(
getStream: () => AsyncIterable<string>,
getValue: () => Promise<string>,
): StreamResult<string> {
return {
stream: () => {
const stream = getStream();
return {
async next() {
try {
const { done, value } =
await stream[Symbol.asyncIterator]().next();
return { done, value: value || "" };
} catch (error) {
console.error("Stream error:", error);
return { done: true, value: undefined };
}
},
[Symbol.asyncIterator]() {
return this;
},
};
},
value: getValue(),
};
}

// Chat with streaming support
async function chatStream(
messages: ChatMessage[],
Expand All @@ -84,6 +56,7 @@ export function createLLMService(config: LLMConfig) {
});

// Split the stream into two
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const [stream1, stream2] = response.tee();

// Create a promise that will resolve with the full text
Expand All @@ -106,7 +79,7 @@ export function createLLMService(config: LLMConfig) {
(async () => {
try {
for await (const chunk of stream1) {
const content = chunk.choices[0]?.delta?.content || "";
const content = chunk.choices[0]?.delta?.content ?? "";
if (content) {
fullText += content;
}
Expand All @@ -115,13 +88,13 @@ export function createLLMService(config: LLMConfig) {
} catch (e) {
rejectValue(e instanceof Error ? e : new Error(String(e)));
}
})();
})().catch(rejectValue); // Handle floating promise

// Create a stream generator function that yields chunks immediately from stream2
const getStream = async function* () {
try {
for await (const chunk of stream2) {
const content = chunk.choices[0]?.delta?.content || "";
const content = chunk.choices[0]?.delta?.content ?? "";
if (content) {
yield content;
}
Expand Down
14 changes: 11 additions & 3 deletions src/resolve.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { JSX } from "./jsx-runtime";
import type {
ComponentProps,
ExecutableValue,
WorkflowComponent,
StreamComponent,
Streamable,
StreamComponent,
WorkflowComponent,
} from "./types";

import { JSX } from "./jsx-runtime";
import { isInStreamingContext } from "./stream";

type ComponentType<P, O> = WorkflowComponent<P, O> | StreamComponent<P, O>;
Expand All @@ -18,6 +19,7 @@ function isJSXElement<P, O>(
props: ComponentProps<P, O>;
} {
const el = element as { type: ComponentType<P, O> };
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
return (
typeof element === "object" &&
element !== null &&
Expand Down Expand Up @@ -49,11 +51,13 @@ function isStreamable<T>(value: unknown): value is Streamable<T> {
export async function resolveDeep<T>(value: unknown): Promise<T> {
// Handle promises first
if (value instanceof Promise) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const resolved = await value;
return resolveDeep(resolved);
}

// Handle streamable values
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (isStreamable(value)) {
if (isInStreamingContext()) {
return value as T;
Expand All @@ -63,6 +67,7 @@ export async function resolveDeep<T>(value: unknown): Promise<T> {
}

// Handle arrays
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (Array.isArray(value)) {
const resolvedArray = await Promise.all(
value.map(item => resolveDeep(item)),
Expand All @@ -77,6 +82,7 @@ export async function resolveDeep<T>(value: unknown): Promise<T> {
}

// Handle objects (but not null)
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (typeof value === "object" && value !== null) {
const entries = Object.entries(value);
const resolvedEntries = await Promise.all(
Expand All @@ -94,11 +100,13 @@ export async function resolveDeep<T>(value: unknown): Promise<T> {
* This is the main entry point for executing workflow components.
*/
export async function execute<T>(element: ExecutableValue): Promise<T> {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (element === null || element === undefined) {
throw new Error("Cannot execute null or undefined element");
}

// Handle JSX elements specially to support children functions
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (isJSXElement(element)) {
const componentResult = await element.type(element.props);

Expand Down
3 changes: 2 additions & 1 deletion src/stream.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Element, ExecutableValue, StreamComponent } from "./types";
import type { Element, ExecutableValue, StreamComponent } from "./types";

import { execute } from "./resolve";

// Global state to track streaming context
Expand Down

0 comments on commit b6b1b9a

Please sign in to comment.