checkpoint
This commit is contained in:
parent
f1b5a560a3
commit
49d4290088
@ -1,16 +1,20 @@
|
|||||||
# The Agentic Workflow Loop
|
# The Agentic Workflow Loop
|
||||||
|
|
||||||
Gadget Code is a software engineering Integrated Development Environment (IDE) built around an Agentic Workflow Loop (AWL). The User can edit project files by hand, and also ask Gadget to do work for them in the project.
|
Gadget Code is an Agentic Integrated Development Environment (AIDE) built around a bespoke Agentic Workflow Loop (AWL). The AWL resides and executes within the Gadget Drone.
|
||||||
|
|
||||||
A technical chat interface is offered as the Chat Session view where the User can send a prompt to Gadget for processing. The prompt is packaged as a Work Order, and sent to an available Gadget Drone for processing. The Agentic Workflow Loop resides and executes within the Gadget Drone.
|
The User can edit project files by hand. The User can also ask Gadget (the Gadget Code AI Programming Agent) to do work for them in the project. The User sends a natural language prompt to the Gadget programming agent for processing. The prompt is packaged as a Work Order and sent to an available Gadget Drone for processing. This is what starts the AWL.
|
||||||
|
|
||||||
The browser is used as a remote control of sorts for Agentic Workflow Loops running in the User's drones on the user's behalf. As the agent is performing work, it emits messages back to the browser (using Socket.IO by way of the web server) to update the User's display in the Chat Session view.
|
The loop starts when the User submits a prompt for processing, and ends when an AI API call responds with no further tool function calls. If a response contains tool calls, the loop calls the tools, inserts tool role response messages in the context (messages array), and remains _in_ the loop to submit the context back to the model for additional thinking, response(s), and tool call response(s).
|
||||||
|
|
||||||
The loop starts when the User submits a prompt for processing, and ends when an AI API call responds with zero tool calls. If a response contains tool calls, the loop calls the tools, inserts "tool" role response messages in the context, and remains in the loop to submit the context back to the model for additional thinking, response, and tool call responses.
|
## Chat Session Turns and the AWL
|
||||||
|
|
||||||
## The Work Order
|
From when a prompt work order is received until the final AI API response received is referred to as a Turn in the Chat Session, and represents one execution of the AWL.
|
||||||
|
|
||||||
Each Gadget Drone registered by the User implements a named Bull job queue. Gadget Code will create a Work Order job for the Drone to process.
|
Any amount of work can occur within a single execution of the AWL. There are no imposed limits on loop counts. The agent can keep working for as long as necessary in one Turn.
|
||||||
|
|
||||||
|
## Prompt Work Orders
|
||||||
|
|
||||||
|
Each gadget-drone registered by the User maintains a Socket.IO connection to gadget-code's web services. The User can send a prompt to the Gadget Drone by sending a Work Order to the drone's Socket.IO connection.
|
||||||
|
|
||||||
The Work Order is a JSON object that contains information about the project, AI service provider and model, and also the User's prompt.
|
The Work Order is a JSON object that contains information about the project, AI service provider and model, and also the User's prompt.
|
||||||
|
|
||||||
|
|||||||
@ -4,33 +4,6 @@
|
|||||||
|
|
||||||
import { Schema, Document, model } from "mongoose";
|
import { Schema, Document, model } from "mongoose";
|
||||||
|
|
||||||
export type AiApiType = "ollama" | "openai";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normalised capability flags stored with each model record. These are
|
|
||||||
* populated during model refresh from provider-specific metadata and drive
|
|
||||||
* slot-based filtering in the UI (e.g. only canCallTools models for Agent).
|
|
||||||
*/
|
|
||||||
export interface IAiModelSettings {
|
|
||||||
temperature?: number;
|
|
||||||
topP?: number;
|
|
||||||
topK?: number;
|
|
||||||
numCtx?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IAiModelCapabilities {
|
|
||||||
/** Model supports structured function / tool calling via the API. */
|
|
||||||
canCallTools: boolean;
|
|
||||||
/** Model accepts image inputs (multimodal / vision). */
|
|
||||||
hasVision: boolean;
|
|
||||||
/** Model can produce vector embeddings (required for the Vector slot). */
|
|
||||||
hasEmbedding: boolean;
|
|
||||||
/** Model has an explicit reasoning / thinking phase (e.g. o1, QwQ). */
|
|
||||||
hasThinking: boolean;
|
|
||||||
/** Model is instruction-tuned / chat-tuned (as opposed to a base model). */
|
|
||||||
isInstructTuned: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const AiModelCapabilitiesSchema = new Schema<IAiModelCapabilities>(
|
export const AiModelCapabilitiesSchema = new Schema<IAiModelCapabilities>(
|
||||||
{
|
{
|
||||||
canCallTools: { type: Boolean, default: false },
|
canCallTools: { type: Boolean, default: false },
|
||||||
@ -42,23 +15,6 @@ export const AiModelCapabilitiesSchema = new Schema<IAiModelCapabilities>(
|
|||||||
{ _id: false },
|
{ _id: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
export interface IAiModel {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
/**
|
|
||||||
* Raw parameter count in billions (float). Use parameterLabel for display.
|
|
||||||
*/
|
|
||||||
parameterCount?: number;
|
|
||||||
/**
|
|
||||||
* Human-readable parameter size label sourced directly from the provider,
|
|
||||||
* e.g. "7b", "70b", "3.8b".
|
|
||||||
*/
|
|
||||||
parameterLabel?: string;
|
|
||||||
contextWindow?: number;
|
|
||||||
capabilities: IAiModelCapabilities;
|
|
||||||
settings?: IAiModelSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const AiModelSettingsSchema = new Schema<IAiModelSettings>(
|
export const AiModelSettingsSchema = new Schema<IAiModelSettings>(
|
||||||
{
|
{
|
||||||
temperature: { type: Number },
|
temperature: { type: Number },
|
||||||
@ -94,16 +50,6 @@ export const AiModelSchema = new Schema<IAiModel>(
|
|||||||
{ _id: false },
|
{ _id: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
export interface IAiProvider extends Document {
|
|
||||||
name: string;
|
|
||||||
apiType: AiApiType;
|
|
||||||
baseUrl: string;
|
|
||||||
apiKey: string;
|
|
||||||
enabled: boolean;
|
|
||||||
models: IAiModel[];
|
|
||||||
lastModelRefresh: Date;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const AiProviderSchema = new Schema<IAiProvider>({
|
export const AiProviderSchema = new Schema<IAiProvider>({
|
||||||
name: { type: String, required: true },
|
name: { type: String, required: true },
|
||||||
apiType: { type: String, enum: ["ollama", "openai"], required: true },
|
apiType: { type: String, enum: ["ollama", "openai"], required: true },
|
||||||
@ -118,7 +64,3 @@ AiProviderSchema.index({ name: 1 }, { unique: true });
|
|||||||
|
|
||||||
export const AiProvider = model<IAiProvider>("AiProvider", AiProviderSchema);
|
export const AiProvider = model<IAiProvider>("AiProvider", AiProviderSchema);
|
||||||
export default AiProvider;
|
export default AiProvider;
|
||||||
|
|
||||||
// Note: Index synchronization is now handled during application startup
|
|
||||||
// to ensure the database connection is established first.
|
|
||||||
// See src/lib/db.ts for the syncDatabaseIndexes function.
|
|
||||||
|
|||||||
@ -2,42 +2,12 @@
|
|||||||
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
|
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
|
|
||||||
import { Types, Schema, Document, model } from "mongoose";
|
import { Types, Schema, model } from "mongoose";
|
||||||
|
|
||||||
import { IUser } from "./user.js";
|
|
||||||
import { IProject } from "./project.js";
|
|
||||||
|
|
||||||
export enum ChatSessionMode {
|
|
||||||
Plan = "plan", // for planning and brainstorming
|
|
||||||
Build = "build", // for building and coding
|
|
||||||
Test = "test", // for testing and debugging
|
|
||||||
Ship = "ship", // for finalizing and shipping
|
|
||||||
Develop = "dev", // for working on the Gadget Code harness itself
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IChatSessionPin {
|
|
||||||
_id?: Types.ObjectId;
|
|
||||||
content: string;
|
|
||||||
}
|
|
||||||
export const ChatSessionPinSchema = new Schema<IChatSessionPin>({
|
export const ChatSessionPinSchema = new Schema<IChatSessionPin>({
|
||||||
content: { type: String, required: true },
|
content: { type: String, required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface IChatSession extends Document {
|
|
||||||
createdAt: Date;
|
|
||||||
lastMessageAt?: Date;
|
|
||||||
user: IUser | Types.ObjectId;
|
|
||||||
project: IProject | Types.ObjectId;
|
|
||||||
name: string;
|
|
||||||
mode: ChatSessionMode;
|
|
||||||
stats: {
|
|
||||||
turnCount: number;
|
|
||||||
toolCallCount: number;
|
|
||||||
inputTokens: number;
|
|
||||||
outputTokens: number;
|
|
||||||
};
|
|
||||||
pins: IChatSessionPin[];
|
|
||||||
}
|
|
||||||
export const ChatSessionSchema = new Schema<IChatSession>({
|
export const ChatSessionSchema = new Schema<IChatSession>({
|
||||||
createdAt: { type: Date, default: Date.now, required: true },
|
createdAt: { type: Date, default: Date.now, required: true },
|
||||||
lastMessageAt: { type: Date },
|
lastMessageAt: { type: Date },
|
||||||
@ -63,4 +33,5 @@ export const ChatSession = model<IChatSession>(
|
|||||||
"ChatSession",
|
"ChatSession",
|
||||||
ChatSessionSchema,
|
ChatSessionSchema,
|
||||||
);
|
);
|
||||||
|
|
||||||
export default ChatSession;
|
export default ChatSession;
|
||||||
|
|||||||
@ -9,20 +9,6 @@ import { IProject } from "./project.js";
|
|||||||
import { ChatSessionMode, IChatSession } from "./chat-session.js";
|
import { ChatSessionMode, IChatSession } from "./chat-session.js";
|
||||||
import { IAiProvider } from "./ai-provider.js";
|
import { IAiProvider } from "./ai-provider.js";
|
||||||
|
|
||||||
export enum ChatTurnStatus {
|
|
||||||
Processing = "processing",
|
|
||||||
Finished = "finished",
|
|
||||||
Error = "error",
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IChatTurnStats {
|
|
||||||
toolCallCount: number; // total number of tool functions called this turn
|
|
||||||
inputTokens: number; // total number of input tokens processed this turn
|
|
||||||
thinkingTokenCount: number; // total number of thinking tokens generated this turn
|
|
||||||
responseTokens: number; // total number of response/output tokens generated this turn
|
|
||||||
durationMs: number; // total turn runtime in seconds
|
|
||||||
durationLabel: string; // total turn runtime as hh:mm:ss
|
|
||||||
}
|
|
||||||
export const ChatTurnStatsSchema = new Schema<IChatTurnStats>({
|
export const ChatTurnStatsSchema = new Schema<IChatTurnStats>({
|
||||||
toolCallCount: { type: Number, default: 0, required: true },
|
toolCallCount: { type: Number, default: 0, required: true },
|
||||||
inputTokens: { type: Number, default: 0, required: true },
|
inputTokens: { type: Number, default: 0, required: true },
|
||||||
@ -32,24 +18,12 @@ export const ChatTurnStatsSchema = new Schema<IChatTurnStats>({
|
|||||||
durationLabel: { type: String, default: "pending", required: true },
|
durationLabel: { type: String, default: "pending", required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface IChatToolCall {
|
|
||||||
name: string; // tool function name being called
|
|
||||||
parameters: string; // JSON.stringify of input parameters
|
|
||||||
response: string; // the tool's response
|
|
||||||
}
|
|
||||||
export const ChatToolCallSchema = new Schema<IChatToolCall>({
|
export const ChatToolCallSchema = new Schema<IChatToolCall>({
|
||||||
name: { type: String, required: true },
|
name: { type: String, required: true },
|
||||||
parameters: { type: String, required: false },
|
parameters: { type: String, required: false },
|
||||||
response: { type: String, required: false },
|
response: { type: String, required: false },
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface IChatSubagentProcess {
|
|
||||||
prompt: string;
|
|
||||||
thinking?: string;
|
|
||||||
response: string;
|
|
||||||
toolCalls: IChatToolCall[];
|
|
||||||
stats: IChatTurnStats;
|
|
||||||
}
|
|
||||||
export const ChatSubagentProcessSchema = new Schema<IChatSubagentProcess>({
|
export const ChatSubagentProcessSchema = new Schema<IChatSubagentProcess>({
|
||||||
prompt: { type: String, required: true },
|
prompt: { type: String, required: true },
|
||||||
thinking: { type: String, required: false },
|
thinking: { type: String, required: false },
|
||||||
@ -58,28 +32,6 @@ export const ChatSubagentProcessSchema = new Schema<IChatSubagentProcess>({
|
|||||||
stats: { type: ChatTurnStatsSchema, default: {}, required: true },
|
stats: { type: ChatTurnStatsSchema, default: {}, required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* A chat turn is a single prompt/response pair with tool call accounting. It
|
|
||||||
* stores all data generated by one run of the Agentic Workflow Loop by a Gadget
|
|
||||||
* Drone process.
|
|
||||||
*/
|
|
||||||
export interface IChatTurn extends Document {
|
|
||||||
_id: Types.ObjectId;
|
|
||||||
createdAt: Date;
|
|
||||||
user: IUser | Types.ObjectId;
|
|
||||||
project: IProject | Types.ObjectId;
|
|
||||||
session: IChatSession | Types.ObjectId;
|
|
||||||
provider: IAiProvider | Types.ObjectId;
|
|
||||||
llm: string; // id/name of the model used to process the prompt
|
|
||||||
mode: ChatSessionMode; // session mode for this turn/prompt
|
|
||||||
status: ChatTurnStatus;
|
|
||||||
prompt: string;
|
|
||||||
thinking?: string;
|
|
||||||
response?: string;
|
|
||||||
toolCalls: IChatToolCall[];
|
|
||||||
subagents: IChatSubagentProcess[]; // subagents used while processing this turn
|
|
||||||
stats: IChatTurnStats;
|
|
||||||
}
|
|
||||||
export const ChatTurnSchema = new Schema<IChatTurn>({
|
export const ChatTurnSchema = new Schema<IChatTurn>({
|
||||||
createdAt: { type: Date, default: Date.now, required: true },
|
createdAt: { type: Date, default: Date.now, required: true },
|
||||||
user: { type: Types.ObjectId, required: true, ref: "User" },
|
user: { type: Types.ObjectId, required: true, ref: "User" },
|
||||||
|
|||||||
@ -1,48 +0,0 @@
|
|||||||
import { Schema, model } from "mongoose";
|
|
||||||
|
|
||||||
import { DtpLog } from "../lib/log.js";
|
|
||||||
const log = new DtpLog({ name: "PostalCodeModel", slug: "postalCode" });
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This model provides storage for the Postal Code database found here:
|
|
||||||
* https://data.opendatasoft.com/explore/dataset/geonames-postal-code@public/export/?flg=en-us
|
|
||||||
*
|
|
||||||
* When uniqued by country+postalCode, there are many dupes. So the ingest
|
|
||||||
* routine filters them out.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface IPostalCode {
|
|
||||||
country: string; // "country code"
|
|
||||||
postalCode: string; // "postal code"
|
|
||||||
city: string; // "place name"
|
|
||||||
state: string; // "admin name1"
|
|
||||||
stateCode: string; // "admin code1"
|
|
||||||
county: string; // "admin name2"
|
|
||||||
}
|
|
||||||
export const PostalCodeSchema = new Schema<IPostalCode>({
|
|
||||||
country: { type: String, required: true },
|
|
||||||
postalCode: { type: String, required: true },
|
|
||||||
city: { type: String },
|
|
||||||
state: { type: String },
|
|
||||||
stateCode: { type: String },
|
|
||||||
county: { type: String },
|
|
||||||
});
|
|
||||||
|
|
||||||
PostalCodeSchema.index(
|
|
||||||
{
|
|
||||||
country: 1,
|
|
||||||
postalCode: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
unique: true,
|
|
||||||
name: "postal_code_unique",
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const PostalCode = model<IPostalCode>("PostalCode", PostalCodeSchema);
|
|
||||||
export default PostalCode;
|
|
||||||
|
|
||||||
(async () => {
|
|
||||||
log.info("Syncing indexes...");
|
|
||||||
await PostalCode.syncIndexes();
|
|
||||||
})();
|
|
||||||
@ -5,14 +5,6 @@
|
|||||||
import { Types, Schema, Document, model } from "mongoose";
|
import { Types, Schema, Document, model } from "mongoose";
|
||||||
import { IUser } from "./user.js";
|
import { IUser } from "./user.js";
|
||||||
|
|
||||||
export interface IProject extends Document {
|
|
||||||
createdAt: Date;
|
|
||||||
user: IUser | Types.ObjectId;
|
|
||||||
name: string;
|
|
||||||
slug: string;
|
|
||||||
gitUrl?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ProjectSchema = new Schema<IProject>({
|
export const ProjectSchema = new Schema<IProject>({
|
||||||
createdAt: { type: Date, default: Date.now, required: true },
|
createdAt: { type: Date, default: Date.now, required: true },
|
||||||
user: { type: Types.ObjectId, required: true, index: 1, ref: "User" },
|
user: { type: Types.ObjectId, required: true, index: 1, ref: "User" },
|
||||||
@ -50,4 +42,5 @@ ProjectSchema.index(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const Project = model<IProject>("Project", ProjectSchema);
|
export const Project = model<IProject>("Project", ProjectSchema);
|
||||||
|
|
||||||
export default Project;
|
export default Project;
|
||||||
|
|||||||
@ -10,12 +10,6 @@ const log = new DtpLog({
|
|||||||
slug: "user",
|
slug: "user",
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface IUserFlags {
|
|
||||||
isEmailVerified: boolean;
|
|
||||||
isAdmin: boolean;
|
|
||||||
isTest: boolean;
|
|
||||||
isBanned: boolean;
|
|
||||||
}
|
|
||||||
export const UserFlagsSchema = new Schema<IUserFlags>(
|
export const UserFlagsSchema = new Schema<IUserFlags>(
|
||||||
{
|
{
|
||||||
isEmailVerified: { type: Boolean, default: false, required: true },
|
isEmailVerified: { type: Boolean, default: false, required: true },
|
||||||
@ -23,18 +17,9 @@ export const UserFlagsSchema = new Schema<IUserFlags>(
|
|||||||
isTest: { type: Boolean, default: false, required: true },
|
isTest: { type: Boolean, default: false, required: true },
|
||||||
isBanned: { type: Boolean, default: false, required: true },
|
isBanned: { type: Boolean, default: false, required: true },
|
||||||
},
|
},
|
||||||
{ _id: false }
|
{ _id: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
export interface IUser extends Document {
|
|
||||||
_id: Types.ObjectId;
|
|
||||||
email: string;
|
|
||||||
email_lc: string;
|
|
||||||
passwordSalt?: string;
|
|
||||||
password?: string;
|
|
||||||
displayName: string;
|
|
||||||
flags: IUserFlags;
|
|
||||||
}
|
|
||||||
export const UserSchema = new Schema<IUser>({
|
export const UserSchema = new Schema<IUser>({
|
||||||
email: { type: String, required: true },
|
email: { type: String, required: true },
|
||||||
email_lc: { type: String, required: true, lowercase: true, unique: true },
|
email_lc: { type: String, required: true, lowercase: true, unique: true },
|
||||||
|
|||||||
11
packages/api/src/index.ts
Normal file
11
packages/api/src/index.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// src/index.ts
|
||||||
|
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
|
||||||
|
// All Rights Reserved
|
||||||
|
|
||||||
|
export * from "./interfaces/ai-provider.ts";
|
||||||
|
|
||||||
|
export * from "./interfaces/user.ts";
|
||||||
|
export * from "./interfaces/project.ts";
|
||||||
|
|
||||||
|
export * from "./interfaces/chat-session.ts";
|
||||||
|
export * from "./interfaces/chat-turn.ts";
|
||||||
57
packages/api/src/interfaces/ai-provider.ts
Normal file
57
packages/api/src/interfaces/ai-provider.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// src/interfaces/ai-provider.ts
|
||||||
|
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
|
||||||
|
// Licensed under the Apache License, Version 2.0
|
||||||
|
|
||||||
|
export type AiApiType = "ollama" | "openai";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalised capability flags stored with each model record. These are
|
||||||
|
* populated during model refresh from provider-specific metadata and drive
|
||||||
|
* slot-based filtering in the UI (e.g. only canCallTools models for Agent).
|
||||||
|
*/
|
||||||
|
export interface IAiModelSettings {
|
||||||
|
temperature?: number;
|
||||||
|
topP?: number;
|
||||||
|
topK?: number;
|
||||||
|
numCtx?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IAiModelCapabilities {
|
||||||
|
/** Model supports structured function / tool calling via the API. */
|
||||||
|
canCallTools: boolean;
|
||||||
|
/** Model accepts image inputs (multimodal / vision). */
|
||||||
|
hasVision: boolean;
|
||||||
|
/** Model can produce vector embeddings (required for the Vector slot). */
|
||||||
|
hasEmbedding: boolean;
|
||||||
|
/** Model has an explicit reasoning / thinking phase (e.g. o1, QwQ). */
|
||||||
|
hasThinking: boolean;
|
||||||
|
/** Model is instruction-tuned / chat-tuned (as opposed to a base model). */
|
||||||
|
isInstructTuned: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IAiModel {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
/**
|
||||||
|
* Raw parameter count in billions (float). Use parameterLabel for display.
|
||||||
|
*/
|
||||||
|
parameterCount?: number;
|
||||||
|
/**
|
||||||
|
* Human-readable parameter size label sourced directly from the provider,
|
||||||
|
* e.g. "7b", "70b", "3.8b".
|
||||||
|
*/
|
||||||
|
parameterLabel?: string;
|
||||||
|
contextWindow?: number;
|
||||||
|
capabilities: IAiModelCapabilities;
|
||||||
|
settings?: IAiModelSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IAiProvider extends Document {
|
||||||
|
name: string;
|
||||||
|
apiType: AiApiType;
|
||||||
|
baseUrl: string;
|
||||||
|
apiKey: string;
|
||||||
|
enabled: boolean;
|
||||||
|
models: IAiModel[];
|
||||||
|
lastModelRefresh: Date;
|
||||||
|
}
|
||||||
32
packages/api/src/interfaces/chat-session.ts
Normal file
32
packages/api/src/interfaces/chat-session.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// src/interfaces/chat-session.ts
|
||||||
|
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
|
||||||
|
// Licensed under the Apache License, Version 2.0
|
||||||
|
|
||||||
|
export enum ChatSessionMode {
|
||||||
|
Plan = "plan", // for planning and brainstorming
|
||||||
|
Build = "build", // for building and coding
|
||||||
|
Test = "test", // for testing and debugging
|
||||||
|
Ship = "ship", // for finalizing and shipping
|
||||||
|
Develop = "dev", // for working on the Gadget Code harness itself
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IChatSessionPin {
|
||||||
|
_id?: Types.ObjectId;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IChatSession extends Document {
|
||||||
|
createdAt: Date;
|
||||||
|
lastMessageAt?: Date;
|
||||||
|
user: IUser | Types.ObjectId;
|
||||||
|
project: IProject | Types.ObjectId;
|
||||||
|
name: string;
|
||||||
|
mode: ChatSessionMode;
|
||||||
|
stats: {
|
||||||
|
turnCount: number;
|
||||||
|
toolCallCount: number;
|
||||||
|
inputTokens: number;
|
||||||
|
outputTokens: number;
|
||||||
|
};
|
||||||
|
pins: IChatSessionPin[];
|
||||||
|
}
|
||||||
55
packages/api/src/interfaces/chat-turn.ts
Normal file
55
packages/api/src/interfaces/chat-turn.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// src/interfaces/chat-turn.ts
|
||||||
|
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
|
||||||
|
// Licensed under the Apache License, Version 2.0
|
||||||
|
|
||||||
|
export enum ChatTurnStatus {
|
||||||
|
Processing = "processing",
|
||||||
|
Finished = "finished",
|
||||||
|
Error = "error",
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IChatTurnStats {
|
||||||
|
toolCallCount: number; // total number of tool functions called this turn
|
||||||
|
inputTokens: number; // total number of input tokens processed this turn
|
||||||
|
thinkingTokenCount: number; // total number of thinking tokens generated this turn
|
||||||
|
responseTokens: number; // total number of response/output tokens generated this turn
|
||||||
|
durationMs: number; // total turn runtime in seconds
|
||||||
|
durationLabel: string; // total turn runtime as hh:mm:ss
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IChatToolCall {
|
||||||
|
name: string; // tool function name being called
|
||||||
|
parameters: string; // JSON.stringify of input parameters
|
||||||
|
response: string; // the tool's response
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IChatSubagentProcess {
|
||||||
|
prompt: string;
|
||||||
|
thinking?: string;
|
||||||
|
response: string;
|
||||||
|
toolCalls: IChatToolCall[];
|
||||||
|
stats: IChatTurnStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A chat turn is a single prompt/response pair with tool call accounting. It
|
||||||
|
* stores all data generated by one run of the Agentic Workflow Loop by a Gadget
|
||||||
|
* Drone process.
|
||||||
|
*/
|
||||||
|
export interface IChatTurn extends Document {
|
||||||
|
_id: Types.ObjectId;
|
||||||
|
createdAt: Date;
|
||||||
|
user: IUser | Types.ObjectId;
|
||||||
|
project: IProject | Types.ObjectId;
|
||||||
|
session: IChatSession | Types.ObjectId;
|
||||||
|
provider: IAiProvider | Types.ObjectId;
|
||||||
|
llm: string; // id/name of the model used to process the prompt
|
||||||
|
mode: ChatSessionMode; // session mode for this turn/prompt
|
||||||
|
status: ChatTurnStatus;
|
||||||
|
prompt: string;
|
||||||
|
thinking?: string;
|
||||||
|
response?: string;
|
||||||
|
toolCalls: IChatToolCall[];
|
||||||
|
subagents: IChatSubagentProcess[]; // subagents used while processing this turn
|
||||||
|
stats: IChatTurnStats;
|
||||||
|
}
|
||||||
11
packages/api/src/interfaces/project.ts
Normal file
11
packages/api/src/interfaces/project.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// src/models/chat-session.ts
|
||||||
|
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
|
||||||
|
// Licensed under the Apache License, Version 2.0
|
||||||
|
|
||||||
|
export interface IProject extends Document {
|
||||||
|
createdAt: Date;
|
||||||
|
user: IUser | Types.ObjectId;
|
||||||
|
name: string;
|
||||||
|
slug: string;
|
||||||
|
gitUrl?: string;
|
||||||
|
}
|
||||||
20
packages/api/src/interfaces/user.ts
Normal file
20
packages/api/src/interfaces/user.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// src/interfaces/user.ts
|
||||||
|
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
|
||||||
|
// Licensed under the Apache License, Version 2.0
|
||||||
|
|
||||||
|
export interface IUserFlags {
|
||||||
|
isEmailVerified: boolean;
|
||||||
|
isAdmin: boolean;
|
||||||
|
isTest: boolean;
|
||||||
|
isBanned: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IUser extends Document {
|
||||||
|
_id: Types.ObjectId;
|
||||||
|
email: string;
|
||||||
|
email_lc: string;
|
||||||
|
passwordSalt?: string;
|
||||||
|
password?: string;
|
||||||
|
displayName: string;
|
||||||
|
flags: IUserFlags;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user