Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat: initial remix setup #23

Merged
merged 3 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 40 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,40 @@ const config = {
'plugin:typescript-sort-keys/recommended',
],
ignorePatterns: [
'**/build/**',
'**/dist/**',
'**/coverage/**',
'node_modules/**',
'**/node_modules/**',
],
overrides: [
// React
{
extends: [
'plugin:react/recommended',
'plugin:react/jsx-runtime',
'plugin:react-hooks/recommended',
'plugin:jsx-a11y/recommended',
],
files: ['**/*.{js,jsx,ts,tsx}'],
plugins: ['react', 'jsx-a11y'],
settings: {
formComponents: ['Form'],
'import/resolver': {
typescript: {
project: './tsconfig.eslint.json',
},
},
linkComponents: [
{ linkAttribute: 'to', name: 'Link' },
{ linkAttribute: 'to', name: 'NavLink' },
],
react: {
version: 'detect',
},
},
},

{
env: {
node: true,
Expand All @@ -33,13 +61,18 @@ const config = {
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 'latest',
project: './tsconfig.eslint.json',
sourceType: 'module',
},
plugins: [
'@typescript-eslint',
'import',
'jsx-a11y',
'react',
'sonarjs',
'sort-destructure-keys',
'sort-keys-fix',
Expand All @@ -60,6 +93,8 @@ const config = {
'**/tests/**',
'**/*.test.{ts,tsx}',
'**/.eslintrc.cjs',
'**/vite.config.{js,ts}',
'**/tailwind.config.{js,ts}',
],
optionalDependencies: false,
packageDir: [
Expand All @@ -78,7 +113,11 @@ const config = {
settings: {
'import/resolver': {
typescript: {
project: ['cli/tsconfig.json', 'codellm/tsconfig.json'],
project: [
'cli/tsconfig.json',
'codellm/tsconfig.json',
'remix/tsconfig.json',
],
},
},
},
Expand Down
22 changes: 15 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ The system is composed of a few main components. It is designed to be extensible

The system currently supports [ollama](https://ollama.com/) and [openai](https://platform.openai.com/docs/quickstart?context=python) providers. You will need to have ollama running locally or configure an API key for openai.

## CLI Quickstart

The CLI is a simple way to interact with the system. It is
## Quickstart

### Setup

Expand Down Expand Up @@ -72,34 +70,44 @@ By default it will import ts code from this repository. You can change the `CODE
npm run start:import
```

### Ollama
### Run the cli agent

#### Ollama

This assumes you have ollama running locally on the default port.

```bash
npm start
```

### Anthropic (Claude)
#### Anthropic (Claude)

This assumes you have an API key for anthropic set as an environment variable: `ANTHROPIC_API_KEY`.

```bash
CODELLM_PROVIDER=anthropic npm start
```

### Mistral
#### Mistral

This assumes you have an API key for mistral set as an environment variable: `MISTRAL_API_KEY`.

```bash
CODELLM_PROVIDER=mistral npm start
```

### OpenAI
#### OpenAI

This assumes you have an API key for openai set as an environment variable: `OPENAI_API_KEY`.

```bash
CODELLM_PROVIDER=openai npm start
```

### Run the dev remix agent

The remix agent is a simple agent that takes a query and returns a remix of the query. It is a simple example of how to build a web based agent.

```bash
npm run dev
```
1 change: 0 additions & 1 deletion core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
},
"dependencies": {
"@langchain/core": "^0.1.40",
"crypto": "^1.0.1",
"globby": "^14.0.1",
"js-yaml": "^4.1.0",
"lodash": "^4.17.21",
Expand Down
14 changes: 13 additions & 1 deletion core/src/agent/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getLlm } from '@/llm/index.js';
import { log } from '@/log/index.js';
import { newPrompt } from '@/prompt/index.js';
import { AGENT_RECURSION_DEPTH_MAX } from './constants.js';
import { addToHistory } from './history.js';
import * as agentTypes from './types.js';
import { handleToolResponse } from './handleToolResponse.js';

Expand Down Expand Up @@ -93,13 +94,19 @@ export const handleQuestionRecursive = async ({
}

if (agentTypes.isAgentResponseResponse(response)) {
addToHistory(response);
return response;
}

if (depth >= AGENT_RECURSION_DEPTH_MAX) {
return new CodeLlmError({
const e = new CodeLlmError({
code: 'agent:maxDepthExceeded',
});
addToHistory({
content: `error: ${e.message} - ${e.cause}`,
type: 'response',
});
return e;
}

const toolResponse = await handleToolResponse({
Expand Down Expand Up @@ -130,6 +137,11 @@ export const chat = async (question: string) => {
const agentLlm = getLlm('agent');
if (isError(agentLlm)) return agentLlm;

addToHistory({
content: question,
role: 'user',
});

return handleQuestionRecursive({
agentLlm,
question,
Expand Down
3 changes: 3 additions & 0 deletions core/src/agent/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
export const AGENT_ERRORS = {
'agent:addHistory': {
message: 'Error adding to agent history',
},
'agent:decodeResponse': {
message: 'Error decoding agent response',
},
Expand Down
31 changes: 31 additions & 0 deletions core/src/agent/history.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { AgentHistory, AgentHistoryAddParams } from '@/.';
import {
agentResponseResponseSchema,
isAgentHistoryUserItem,
} from '@/agent/types.js';
import { CodeLlmError } from '@/error/index.js';

const agentHistory: AgentHistory = [];

export const getHistory = () => agentHistory;

export const addToHistory = (params: AgentHistoryAddParams) => {
try {
const validAgentResponse = agentResponseResponseSchema.parse(params);
const { code, content, reason } = validAgentResponse;
return agentHistory.push({
code,
content,
reason,
role: 'assistant',
});
} catch (error) {
// ignore
}

if (!isAgentHistoryUserItem(params)) {
return new CodeLlmError({ code: 'agent:addHistory', meta: { params } });
}

return agentHistory.push(params);
};
2 changes: 2 additions & 0 deletions core/src/agent/newAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { log } from '@/log/index.js';
import { initPrompts } from '@/prompt/index.js';
import { initTools } from '@/tool/index.js';
import chat from './chat.js';
import { getHistory } from './history.js';

/**
* Create a new agent which is the primary interface to interact with the LLMs
Expand Down Expand Up @@ -43,6 +44,7 @@ export const newAgent = async (configParam: PartialConfig) => {

return {
chat,
getHistory: () => getHistory(),
} as Agent;
};

Expand Down
45 changes: 36 additions & 9 deletions core/src/agent/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { CodeLlmError, LlmClient } from '@/.';

import { z } from 'zod';

import { isError } from '@/error/index.js';
import { toolRunParamsParamSchema } from '@/tool/types.js';

export const agentResponseResponseSchema = z.object({
Expand All @@ -21,9 +21,9 @@ export const agentResponseResponseSchema = z.object({
export type AgentResponseResponse = z.infer<typeof agentResponseResponseSchema>;

export const isAgentResponseResponse = (
i: AgentSelectToolResponse,
i: AgentSelectToolResponse | CodeLlmError,
): i is AgentResponseResponse => {
return i.type === 'response';
return !isError(i) && i.type === 'response';
};

export const agentToolResponseSchema = z.object({
Expand All @@ -36,9 +36,9 @@ export const agentToolResponseSchema = z.object({
export type AgentToolResponse = z.infer<typeof agentToolResponseSchema>;

export const isAgentToolResponse = (
i: AgentSelectToolResponse,
i: AgentSelectToolResponse | CodeLlmError,
): i is AgentToolResponse => {
return i.type === 'tool';
return !isError(i) && i.type === 'tool';
};

export const agentLlmResponseSchema = z.union([
Expand All @@ -48,10 +48,6 @@ export const agentLlmResponseSchema = z.union([

export type AgentLlmResponse = z.infer<typeof agentLlmResponseSchema>;

export type Agent = {
chat: (message: string) => Promise<AgentResponse>;
};

export type AgentResponseCodeItem = {
code: string;
language: string;
Expand Down Expand Up @@ -82,3 +78,34 @@ export type AgentHandleToolResponseParams = {
response: AgentSelectToolResponse;
toolResponses: AgentToolResponses;
};

export type AgentHistoryUserItem = {
content: string;
role: 'user';
};

export type AgentHistoryAssistantItem = {
code: AgentResponseResponse['code'] | undefined;
content: AgentResponseResponse['content'];
reason: AgentToolResponse['reason'] | undefined;
role: 'assistant';
};

export type AgentHistoryItem = AgentHistoryUserItem | AgentHistoryAssistantItem;

export type AgentHistory = AgentHistoryItem[];

export type AgentHistoryAddParams =
| AgentResponseResponse
| AgentHistoryUserItem;

export const isAgentHistoryUserItem = (
i: AgentHistoryAddParams,
): i is AgentHistoryUserItem => {
return 'role' in i && i.role === 'user';
};

export type Agent = {
chat: (message: string) => Promise<AgentResponse>;
getHistory: () => AgentHistory;
};
4 changes: 3 additions & 1 deletion core/src/importer/newImporter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { afterEach, describe, expect, it, vi } from 'vitest';

import { CodeLlmError, Config } from '@/index.js';
import { unitTestConfig, validTool } from '@tests/mocks';
import { expectError } from '@tests/tools';
import { expectError, testSetup } from '@tests/tools';
import { initConfig } from '@/config/index.js';
import { newImporter } from './newImporter.js';

testSetup();

const mocks = vi.hoisted(() => {
return {
initTools: vi.fn(),
Expand Down
3 changes: 2 additions & 1 deletion core/src/llm/conversation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ const conversationHistory: ConversationHistory = SERVICES.reduce(
{} as ConversationHistory,
);

export const getHistory = (service: Service) => conversationHistory[service];
export const getHistory = (service: Service) =>
conversationHistory[service] as MessageList;

export const addMessages = (service: Service, messages: MessageList) => {
conversationHistory[service] = [...conversationHistory[service], ...messages];
Expand Down
Loading
Loading