Milow is still in beta version, he is waiting for your feedback and contributions.
Milow runs on Bun. Ensure you have the latest version of Bun installed before proceeding.
curl -sSL https://raw.githubusercontent.com/etienneleba/milow/main/install.sh | bash milow init # this command creates a milow.config.json file- testCommand: The command you use to run your tests
- model : The model you want to use. Run
milow check modelsto see all available models - viewableFilesPattern : Glob pattern of all files Milow can access
- contextFilesPattern : Glob pattern of files included in Milow's context
export OPENAI_API_KEY=sk-*******Create a docs/milow folder to store all documentation Milow can use to understand your project. Examples of useful
files to include:
business.md: Describe the business context of your project.folder_structure.md: Explain the project architecture and the purpose of folders visible to Milow.technical_stack.md: Provide details about the language, framework, and libraries used in the project.test_strategy.md: Describe your testing approach, including the use of mocks, fakes, or in-memory objects, and your workflow (TDD, ATDD, Test-First, Wishful Thinking Programming, etc.).examples.md: List files Milow can use as examples (e.g., controllers, domain models, commands, command handlers, tests, buses, etc.).
The more accurately you describe your project, the more efficient Milow will be in generating quality code.
You can run Milow using the following command:
milow runYou can also provide more specific commands:
milow run -f ./tests/functional/milow.test.tsmilow run -p "I want to create the AddProductToBasket feature" # This prompt will remain in Milow's context throughout the interactionThe guidelines to contribute : Contributing guidelines
- A function patch file, to avoid rewrite all the file (Quite hard to do well with an LLM)
- Confirm before writing option in the config
- Context buffer size in the config
Milow has been designed to abstract the concept of model, so it's quite easy to add new model provider (Claude, Mistral, Gemini, etc).
Here the steps to create a new Model Provider :
In src/infrastructure/model/models create a new file, I'll take OpenAI for the exemple here :
// src/infrastructure/model/models/OpenAIModel.ts
export default class OpenAIModel {
...
}There are 2 interfaces to implements the Model interface and the ModelProvider interface.
...
export default class OpenAIModel implements Model, ModelProvider {
private client: OpenAI;
private _modelName: string;
constructor() {
}
async call(
context: Context,
functionSchema: object[],
): Promise<ModelResponse> {...}
getModelNames(): string[] {
return ["gpt-4o", "gpt-4o-mini", "gpt-4-turbo", "gpt-4"];
}
set modelName(value: string) {
this._modelName = value;
}
set apiKey(value: string) {
this.client = new OpenAI({
apiKey: value,
});
}
getAPIKeyName(): string {
return "OPENAI_API_KEY"
}
}This function is where everything happens, most of the model providers user the same API interface, so you can use the GenericTranslator to help you convert the Milow models to the provider ones.
...
export default class OpenAIModel implements Model, ModelProvider {
private client: OpenAI;
private _modelName: string;
private translator: GenericTranslator;
constructor() {
this.translator = new GenericTranslator();
}
async call(
context: Context,
functionSchema: object[],
): Promise<ModelResponse> {
const messages = this.translator.translateContextToMessages(
context.conversations,
);
const tools = this.translator.translateFunctionsToTools(functionSchema);
const params = {
messages: messages,
model: this._modelName,
tools: tools,
temperature: 0.3,
top_p: 0.1,
};
const completion = await this.client.chat.completions.create(params);
const message = completion.choices[0].message;
let functionCalls = [];
if (message.tool_calls) {
functionCalls = this.translator.translateToolsToFunctions(
message.tool_calls,
);
}
return new ModelResponse(message.content, functionCalls);
}
...
}Then you just need to add the new provider to the ModelResolver, and that's it !
You can create a pull request to share it with the community ! π
