Skip to content

Commit

Permalink
Refactor to reduce coupling between modules. Add agent parent/child p… (
Browse files Browse the repository at this point in the history
#38)

* Refactor to reduce coupling between modules. 
* Add agent parent/child properties.
* Remove file based services
  • Loading branch information
danielcampagnolitg authored Dec 4, 2024
1 parent 6c83d5f commit edde4fc
Show file tree
Hide file tree
Showing 82 changed files with 516 additions and 601 deletions.
19 changes: 19 additions & 0 deletions CONVENTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,22 @@ Use async/await where possible

Test exceptional cases first and return/throw early.

Never edit files name CONVENTIONS.md or .cursorrules

# Test code standards

Unit test files should be in the same directory as the source file.

Any usage of chai-as-promised should use async/await
```
it('should work well with async/await', async () => {
(await Promise.resolve(42)).should.equal(42)
await Promise.reject(new Error()).should.be.rejectedWith(Error);
});
```

# Tool/function classes

Function classes with the @funcClass(__filename) must only have the default constructor.

Always use the Filesystem class in src/functions/storage/filesystem.ts to read/search/write to the local filesystem.
4 changes: 2 additions & 2 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sophia/ui",
"version": "0.1.0",
"version": "0.2.0",
"description": "Sophia AI platform",
"author": "https://themeforest.net/user/srcn, Daniel Campagnoli, TrafficGuard Pty Ltd, and contributors",
"license": "https://themeforest.net/licenses/standard",
Expand Down
26 changes: 20 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@trafficguard/sophia",
"version": "0.1.0",
"version": "0.2.0",
"description": "AI agent & LLM app platform",
"private": true,
"type": "commonjs",
Expand All @@ -19,6 +19,7 @@
"py": " node --env-file=variables/local.env -r ts-node/register src/cli/py.ts",
"code": " node --env-file=variables/local.env -r ts-node/register src/cli/code.ts",
"query": " node --env-file=variables/local.env -r ts-node/register src/cli/query.ts",
"repos": " node --env-file=variables/local.env -r ts-node/register src/cli/repos.ts",
"scrape": " node --env-file=variables/local.env -r ts-node/register src/cli/scrape.ts",
"slack": " node --env-file=variables/local.env -r ts-node/register src/cli/slack.ts",
"summarize": "node --env-file=variables/local.env -r ts-node/register src/cli/summarize.ts",
Expand All @@ -32,7 +33,6 @@
"functionSchemas": "node --env-file=variables/local.env -r ts-node/register src/generateFunctionSchemas.ts",
"start": " node -r ts-node/register src/index.ts",
"start:local": "node -r ts-node/register --env-file=variables/local.env --inspect=0.0.0.0:9229 src/index.ts",
"start:file": " node -r ts-node/register --env-file=variables/local.env src/index.ts --db=file",
"emulators": "gcloud emulators firestore start --host-port=127.0.0.1:8243",
"test": "npm run test:unit && echo \"No system or integration tests\"",
"test:ci": "firebase emulators:exec --only firestore \"npm run test\"",
Expand Down Expand Up @@ -92,6 +92,7 @@
"@types/axios": "^0.14.0",
"@types/bcrypt": "^5.0.2",
"@types/chai": "^4.3.16",
"@types/micromatch": "^4.0.9",
"@types/pg": "^8.11.4",
"ai": "3.4.20",
"api": "^6.1.1",
Expand All @@ -117,7 +118,7 @@
"ignore": "^5.3.1",
"jsdom": "^24.0.0",
"lodash": "^4.17.20",
"micromatch": "^4.0.7",
"micromatch": "^4.0.8",
"module-alias": "^2.2.2",
"openai": "^4.28.4",
"pino": "^8.18.0",
Expand Down
10 changes: 4 additions & 6 deletions src/agent/LlmFunctions.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { Agent } from '#agent/agentFunctions';
import { functionFactory } from '#functionSchema/functionDecorators';
import { FUNC_SEP, FunctionSchema, getFunctionSchemas } from '#functionSchema/functions';
import { FileSystemRead } from '#functions/storage/FileSystemRead';
import { ToolType, toolType } from '#functions/toolType';
import { FunctionCall } from '#llm/llm';
import { logger } from '#o11y/logger';

import { FileSystemService } from '#functions/storage/fileSystemService';
import { GetToolType, ToolType, toolType } from '#functions/toolType';

import { functionFactory } from '#functionSchema/functionDecorators';
import { FileSystemRead } from '#functions/storage/FileSystemRead';

/**
* Holds the instances of the classes with function callable methods.
*/
Expand All @@ -28,6 +25,7 @@ export class LlmFunctions {
}

fromJSON(obj: any): this {
if (!obj) return this;
const functionClassNames = (obj.functionClasses ?? obj.tools) as string[]; // obj.tools for backward compat with dev version
for (const functionClassName of functionClassNames) {
const ctor = functionFactory()[functionClassName];
Expand Down
2 changes: 1 addition & 1 deletion src/agent/agentContext.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { deserializeAgentContext, serializeContext } from '#agent/agentSerializa
import { FileSystemRead } from '#functions/storage/FileSystemRead';
import { LlmTools } from '#functions/util';
import { GPT4o } from '#llm/services/openai';
import { appContext } from '../app';
import { appContext } from '../applicationContext';
import { functionRegistry } from '../functionRegistry';

describe('agentContext', () => {
Expand Down
2 changes: 2 additions & 0 deletions src/agent/agentContextLocalStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ export function createContext(config: RunAgentConfig): AgentContext {
const hilBudget = config.humanInLoop?.budget ?? (process.env.HIL_BUDGET ? parseFloat(process.env.HIL_BUDGET) : 2);
const context: AgentContext = {
agentId: config.resumeAgentId || randomUUID(),
parentAgentId: config.parentAgentId,
executionId: randomUUID(),
childAgents: [],
traceId: '',
metadata: config.metadata ?? {},
name: config.agentName,
Expand Down
6 changes: 4 additions & 2 deletions src/agent/agentContextTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ export type AgentLLMs = Record<TaskLevel, LLM>;
export interface AgentContext {
/** Primary Key - Agent instance id. Allocated when the agent is first starts */
agentId: string;
/** Id of the running execution. This changes after the agent restarts due to an error, pausing, human in loop, etc */
/** Child agent ids */
childAgents?: string[];
/** Id of the running execution. This changes after the agent restarts due to an error, pausing, human in loop, completion etc */
executionId: string;
/** Current OpenTelemetry traceId */
traceId: string;
Expand Down Expand Up @@ -123,7 +125,7 @@ export interface AgentContext {
invoking: FunctionCall[];
/** Additional notes that tool functions can add to the response to the agent */
notes: string[];
/** The initial user prompt */
/** The initial prompt provided by the user or parent agent */
userPrompt: string;
/** The prompt the agent execution started/resumed with */
inputPrompt: string;
Expand Down
4 changes: 3 additions & 1 deletion src/agent/agentRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { logger } from '#o11y/logger';
import { User } from '#user/user';
import { errorToString } from '#utils/errors';
import { CDATA_END, CDATA_START } from '#utils/xml-utils';
import { appContext } from '../app';
import { appContext } from '../applicationContext';

export const SUPERVISOR_RESUMED_FUNCTION_NAME: string = `Supervisor${FUNC_SEP}Resumed`;
export const SUPERVISOR_CANCELLED_FUNCTION_NAME: string = `Supervisor${FUNC_SEP}Cancelled`;
Expand All @@ -22,6 +22,8 @@ const FUNCTION_OUTPUT_SUMMARIZE_MIN_LENGTH = 2000;
export interface RunAgentConfig {
/** The user who created the agent. Uses currentUser() if not provided */
user?: User;
/** The parent agentId */
parentAgentId?: string;
/** The name of this agent */
agentName: string;
/** The type of autonomous agent function calling. Defaults to codegen */
Expand Down
8 changes: 7 additions & 1 deletion src/agent/agentSerialization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getCompletedHandler } from '#agent/completionHandlerRegistry';
import { FileSystemService } from '#functions/storage/fileSystemService';
import { deserializeLLMs } from '#llm/llmFactory';
import { currentUser } from '#user/userService/userContext';
import { appContext } from '../app';
import { appContext } from '../applicationContext';

export function serializeContext(context: AgentContext): Record<string, any> {
const serialized = {};
Expand All @@ -15,6 +15,10 @@ export function serializeContext(context: AgentContext): Record<string, any> {
} else if (context[key] === null) {
serialized[key] = null;
}
// Handle childAgents array specially to ensure it's always an array
else if (key === 'childAgents') {
serialized[key] = context[key] || [];
}
// Copy primitive properties across
else if (typeof context[key] === 'string' || typeof context[key] === 'number' || typeof context[key] === 'boolean') {
serialized[key] = context[key];
Expand Down Expand Up @@ -65,6 +69,7 @@ export async function deserializeAgentContext(serialized: Record<keyof AgentCont

context.memory = serialized.memory;
context.metadata = serialized.metadata;
context.childAgents = serialized.childAgents || [];
context.llms = deserializeLLMs(serialized.llms);

const user = currentUser();
Expand All @@ -79,6 +84,7 @@ export async function deserializeAgentContext(serialized: Record<keyof AgentCont
if (!context.iterations) context.iterations = 0;

// Need to default empty parameters. Seems to get lost in Firestore
context.functionCallHistory ??= [];
for (const call of context.functionCallHistory) call.parameters ??= {};

return context as AgentContext;
Expand Down
Loading

0 comments on commit edde4fc

Please sign in to comment.