@langwatch/better-agents 0.1.18 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.js +235 -71
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -92,6 +92,7 @@ The CLI will guide you through selecting your programming language, agent framew
|
|
|
92
92
|
- A coding assistant (one of the following):
|
|
93
93
|
- [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code-agent) (`claude` CLI)
|
|
94
94
|
- [Cursor](https://www.cursor.com/)
|
|
95
|
+
- [Antigravity](https://antigravity.google/) (`agy`)
|
|
95
96
|
- [Kilocode CLI](https://www.kilocode.ai/) (`kilocode`)
|
|
96
97
|
- API Keys:
|
|
97
98
|
- Your chosen LLM Provider API key
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
-
import * as
|
|
4
|
-
import * as
|
|
3
|
+
import * as fs11 from 'fs/promises';
|
|
4
|
+
import * as path11 from 'path';
|
|
5
5
|
import { dirname, join } from 'path';
|
|
6
6
|
import { select, password, input, confirm } from '@inquirer/prompts';
|
|
7
7
|
import { exec, spawn, spawnSync } from 'child_process';
|
|
@@ -9,6 +9,7 @@ import pino from 'pino';
|
|
|
9
9
|
import chalk from 'chalk';
|
|
10
10
|
import ora from 'ora';
|
|
11
11
|
import { promisify } from 'util';
|
|
12
|
+
import * as os from 'os';
|
|
12
13
|
import { readFileSync } from 'fs';
|
|
13
14
|
import { fileURLToPath } from 'url';
|
|
14
15
|
|
|
@@ -29,11 +30,11 @@ var BaseLogger = class {
|
|
|
29
30
|
*/
|
|
30
31
|
async setupProjectLogging(projectPath) {
|
|
31
32
|
try {
|
|
32
|
-
const logDir =
|
|
33
|
+
const logDir = path11.join(projectPath, ".better-agents");
|
|
33
34
|
const now = /* @__PURE__ */ new Date();
|
|
34
35
|
const timestamp = now.toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
35
|
-
const logPath =
|
|
36
|
-
await
|
|
36
|
+
const logPath = path11.join(logDir, `debug-${timestamp}.log`);
|
|
37
|
+
await fs11.mkdir(logDir, { recursive: true });
|
|
37
38
|
this.projectLogger = pino(
|
|
38
39
|
{
|
|
39
40
|
level: "debug",
|
|
@@ -409,7 +410,9 @@ var buildLanguageChoices = () => {
|
|
|
409
410
|
};
|
|
410
411
|
|
|
411
412
|
// src/providers/frameworks/agno/knowledge.ts
|
|
412
|
-
var getKnowledge = (
|
|
413
|
+
var getKnowledge = ({
|
|
414
|
+
config: _config
|
|
415
|
+
}) => ({
|
|
413
416
|
setupInstructions: "Python w/uv + pytest",
|
|
414
417
|
toolingInstructions: "Use the Agno MCP to learn about Agno and how to build agents",
|
|
415
418
|
agentsGuideSection: `## Framework-Specific Guidelines
|
|
@@ -562,7 +565,7 @@ var MastraFrameworkProvider = {
|
|
|
562
565
|
language: "typescript",
|
|
563
566
|
getKnowledge: getKnowledge2,
|
|
564
567
|
getMCPConfig: getMCPConfig2,
|
|
565
|
-
setup: async () => {
|
|
568
|
+
setup: async ({ projectPath, config }) => {
|
|
566
569
|
}
|
|
567
570
|
};
|
|
568
571
|
|
|
@@ -618,7 +621,7 @@ var LangGraphPyFrameworkProvider = {
|
|
|
618
621
|
language: "python",
|
|
619
622
|
getKnowledge: getKnowledge3,
|
|
620
623
|
getMCPConfig: getMCPConfig3,
|
|
621
|
-
setup: async () => {
|
|
624
|
+
setup: async ({ projectPath, config }) => {
|
|
622
625
|
}
|
|
623
626
|
};
|
|
624
627
|
|
|
@@ -680,7 +683,114 @@ var LangGraphTSFrameworkProvider = {
|
|
|
680
683
|
language: "typescript",
|
|
681
684
|
getKnowledge: getKnowledge4,
|
|
682
685
|
getMCPConfig: getMCPConfig4,
|
|
683
|
-
setup: async () => {
|
|
686
|
+
setup: async ({ projectPath, config }) => {
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
// src/providers/frameworks/google-adk/knowledge.ts
|
|
691
|
+
var getKnowledge5 = ({
|
|
692
|
+
config
|
|
693
|
+
}) => {
|
|
694
|
+
const selectedProvider = config.llmProvider;
|
|
695
|
+
return {
|
|
696
|
+
setupInstructions: "Python w/uv + pytest",
|
|
697
|
+
toolingInstructions: "Use the Google ADK MCP to learn about Google Agent Developer Kit and how to build agents",
|
|
698
|
+
agentsGuideSection: `## Framework-Specific Guidelines
|
|
699
|
+
|
|
700
|
+
### Google Agent Developer Kit (ADK) Framework
|
|
701
|
+
|
|
702
|
+
**Framework vs. model:** This project always uses **Google ADK as the agent framework**. The LLM provider you selected (OpenAI, Anthropic, Gemini, etc.) is used **only as the model backend**, not as a separate agent framework.
|
|
703
|
+
|
|
704
|
+
**Your launch configuration:** Better Agents scaffolded this project with \`${selectedProvider}\` as the LLM provider.
|
|
705
|
+
|
|
706
|
+
**LLM Provider Awareness:** This template works with both native Gemini models and LiteLLM-wrapped providers like OpenAI/Anthropic. Review the generated project README to confirm which provider was selected during setup.
|
|
707
|
+
|
|
708
|
+
**How non-Google models are used (LiteLLM pattern):**
|
|
709
|
+
|
|
710
|
+
- When you choose a non-Google provider, the agent is still a **Google ADK Agent**.
|
|
711
|
+
- The non-Google model is plugged in via **LiteLLM** inside that agent, for example:
|
|
712
|
+
|
|
713
|
+
\`\`\`python
|
|
714
|
+
from google.adk.agents import Agent
|
|
715
|
+
from google.adk.models.lite_llm import LiteLlm
|
|
716
|
+
|
|
717
|
+
agent = Agent(
|
|
718
|
+
name="customer_support_agent",
|
|
719
|
+
# OpenAI is just the model backend; Google ADK is still the framework
|
|
720
|
+
model=LiteLlm(model="openai/gpt-4.1"),
|
|
721
|
+
description="Customer support agent for your project",
|
|
722
|
+
instruction="You are a helpful support assistant.",
|
|
723
|
+
tools=[...],
|
|
724
|
+
)
|
|
725
|
+
\`\`\`
|
|
726
|
+
|
|
727
|
+
For Gemini, you use the native Google ADK / Google AI SDK models instead of LiteLLM:
|
|
728
|
+
|
|
729
|
+
\`\`\`python
|
|
730
|
+
from google.adk.agents import Agent
|
|
731
|
+
from google.adk.models.google_genai import GoogleGenAIGemini
|
|
732
|
+
|
|
733
|
+
agent = Agent(
|
|
734
|
+
name="customer_support_agent",
|
|
735
|
+
model=gemini-2.0-flash-exp",
|
|
736
|
+
description="Customer support agent for your project",
|
|
737
|
+
instruction="You are a helpful support assistant.",
|
|
738
|
+
tools=[...],
|
|
739
|
+
)
|
|
740
|
+
\`\`\`
|
|
741
|
+
|
|
742
|
+
**Always use the Google ADK MCP for learning:**
|
|
743
|
+
|
|
744
|
+
- The Google ADK MCP server provides real-time documentation for the Agent Developer Kit
|
|
745
|
+
- Ask it questions about Google ADK APIs, tools, and best practices
|
|
746
|
+
- Follow Google's recommended patterns for building and orchestrating agents
|
|
747
|
+
|
|
748
|
+
**LLM Provider Configuration:**
|
|
749
|
+
|
|
750
|
+
- **Gemini path:** Uses the Google AI SDK + Google ADK's native integrations in your ADK agent
|
|
751
|
+
- **Other providers (OpenAI, Anthropic, etc.):** Uses the LiteLLM wrapper *inside a Google ADK Agent* (NEVER SWITCH FRAMEWORKS)
|
|
752
|
+
- Use the \`.env\` generated by the CLI to set the right keys for the chosen provider
|
|
753
|
+
|
|
754
|
+
**When implementing agent features:**
|
|
755
|
+
1. Consult the Google ADK MCP: "How do I [do X] with Google ADK?"
|
|
756
|
+
2. Use Google ADK's primitives for tools, state management, and workflows
|
|
757
|
+
3. Follow Google's Python patterns and conventions for ADK-based agents
|
|
758
|
+
4. Leverage Google ADK integrations for external services and data sources
|
|
759
|
+
|
|
760
|
+
**Initial setup:**
|
|
761
|
+
1. Install dependencies: \`uv sync\` or \`uv pip install -r requirements.txt\`
|
|
762
|
+
2. Set up your API key in the \`.env\` file (check which env var is needed in app.py)
|
|
763
|
+
3. Implement the requested agent logic following Google ADK patterns
|
|
764
|
+
4. Run the app with \`uv run app.py\` to validate behaviour
|
|
765
|
+
---
|
|
766
|
+
`
|
|
767
|
+
};
|
|
768
|
+
};
|
|
769
|
+
|
|
770
|
+
// src/providers/frameworks/google-adk/mcp-config.ts
|
|
771
|
+
var getMCPConfig5 = () => ({
|
|
772
|
+
type: "stdio",
|
|
773
|
+
command: "uvx",
|
|
774
|
+
args: [
|
|
775
|
+
"--from",
|
|
776
|
+
"mcpdoc",
|
|
777
|
+
"mcpdoc",
|
|
778
|
+
"--urls",
|
|
779
|
+
"Google-Adk:https://github.com/google/adk-python/blob/main/llms.txt",
|
|
780
|
+
"--transport",
|
|
781
|
+
"stdio"
|
|
782
|
+
]
|
|
783
|
+
});
|
|
784
|
+
|
|
785
|
+
// src/providers/frameworks/google-adk/index.ts
|
|
786
|
+
var GoogleAdkFrameworkProvider = {
|
|
787
|
+
id: "google-adk",
|
|
788
|
+
displayName: "Google ADK",
|
|
789
|
+
language: "python",
|
|
790
|
+
getKnowledge: getKnowledge5,
|
|
791
|
+
getMCPConfig: getMCPConfig5,
|
|
792
|
+
// setup,
|
|
793
|
+
setup: async ({ projectPath, config }) => {
|
|
684
794
|
}
|
|
685
795
|
};
|
|
686
796
|
|
|
@@ -689,7 +799,8 @@ var PROVIDERS = {
|
|
|
689
799
|
agno: AgnoFrameworkProvider,
|
|
690
800
|
mastra: MastraFrameworkProvider,
|
|
691
801
|
"langgraph-py": LangGraphPyFrameworkProvider,
|
|
692
|
-
"langgraph-ts": LangGraphTSFrameworkProvider
|
|
802
|
+
"langgraph-ts": LangGraphTSFrameworkProvider,
|
|
803
|
+
"google-adk": GoogleAdkFrameworkProvider
|
|
693
804
|
};
|
|
694
805
|
var getFrameworkProvider = ({
|
|
695
806
|
framework
|
|
@@ -768,7 +879,7 @@ var CliUtils = class {
|
|
|
768
879
|
};
|
|
769
880
|
|
|
770
881
|
// src/providers/languages/python/knowledge.ts
|
|
771
|
-
var
|
|
882
|
+
var getKnowledge6 = () => ({
|
|
772
883
|
setupInstructions: "Python with uv + pytest (install uv for them if they don't have it)",
|
|
773
884
|
sourceExtensions: [".py"],
|
|
774
885
|
testFramework: "pytest"
|
|
@@ -778,11 +889,11 @@ var getKnowledge5 = () => ({
|
|
|
778
889
|
var PythonLanguageProvider = {
|
|
779
890
|
id: "python",
|
|
780
891
|
displayName: "Python",
|
|
781
|
-
getKnowledge:
|
|
892
|
+
getKnowledge: getKnowledge6
|
|
782
893
|
};
|
|
783
894
|
|
|
784
895
|
// src/providers/languages/typescript/knowledge.ts
|
|
785
|
-
var
|
|
896
|
+
var getKnowledge7 = () => ({
|
|
786
897
|
setupInstructions: "TypeScript with pnpm + vitest (install pnpm for them if they don't have it)",
|
|
787
898
|
sourceExtensions: [".ts", ".tsx"],
|
|
788
899
|
testFramework: "vitest"
|
|
@@ -792,7 +903,7 @@ var getKnowledge6 = () => ({
|
|
|
792
903
|
var TypeScriptLanguageProvider = {
|
|
793
904
|
id: "typescript",
|
|
794
905
|
displayName: "TypeScript",
|
|
795
|
-
getKnowledge:
|
|
906
|
+
getKnowledge: getKnowledge7
|
|
796
907
|
};
|
|
797
908
|
|
|
798
909
|
// src/providers/languages/index.ts
|
|
@@ -818,7 +929,7 @@ var buildInitialPrompt = ({
|
|
|
818
929
|
framework: config.framework
|
|
819
930
|
});
|
|
820
931
|
const languageProvider = getLanguageProvider({ language: config.language });
|
|
821
|
-
const frameworkKnowledge = frameworkProvider.getKnowledge();
|
|
932
|
+
const frameworkKnowledge = frameworkProvider.getKnowledge({ config });
|
|
822
933
|
const languageKnowledge = languageProvider.getKnowledge();
|
|
823
934
|
const instructions = `You are an expert AI agent developer. This project has been set up with Better Agents best practices.
|
|
824
935
|
|
|
@@ -829,11 +940,10 @@ First steps:
|
|
|
829
940
|
4. Set up the ${languageKnowledge.setupInstructions}
|
|
830
941
|
5. ${frameworkKnowledge.toolingInstructions}
|
|
831
942
|
6. Execute any installation steps needed yourself, for the library dependencies, the CLI tools, etc
|
|
832
|
-
7. Use the LangWatch MCP to learn about prompt management and
|
|
833
|
-
8.
|
|
834
|
-
9.
|
|
835
|
-
10.
|
|
836
|
-
11. If available from the framework, tell the user how to open a dev server give them the url they will be able to access so they can play with the agent themselves, don't run it for them
|
|
943
|
+
7. Use the LangWatch MCP to learn about prompt management and scenarios
|
|
944
|
+
8. Instrument the agent with LangWatch
|
|
945
|
+
9. Use Scenario tests to ensure the agent is working as expected, integrate with the agent and consider it done only when all scenarios pass, check scenario docs on how to implement
|
|
946
|
+
10. If available from the framework, tell the user how to open a dev server give them the url they will be able to access so they can play with the agent themselves, don't run it for them
|
|
837
947
|
|
|
838
948
|
Remember:
|
|
839
949
|
- The LLM and LangWatch API keys are already available in the .env file, you don't need to set them up
|
|
@@ -913,7 +1023,7 @@ var ClaudeCodingAssistantProvider = {
|
|
|
913
1023
|
cwd: projectPath
|
|
914
1024
|
});
|
|
915
1025
|
logger.userSuccess("Session complete!");
|
|
916
|
-
} catch
|
|
1026
|
+
} catch {
|
|
917
1027
|
logger.userWarning(`Could not auto-launch ${this.displayName}.`);
|
|
918
1028
|
showManualLaunchInstructions({
|
|
919
1029
|
targetPath,
|
|
@@ -957,6 +1067,59 @@ var CursorCodingAssistantProvider = {
|
|
|
957
1067
|
logger.userPlain("");
|
|
958
1068
|
}
|
|
959
1069
|
};
|
|
1070
|
+
var AntigravityCodingAssistantProvider = {
|
|
1071
|
+
id: "antigravity",
|
|
1072
|
+
displayName: "Antigravity",
|
|
1073
|
+
command: "agy",
|
|
1074
|
+
async isAvailable() {
|
|
1075
|
+
return { installed: true };
|
|
1076
|
+
},
|
|
1077
|
+
async launch({
|
|
1078
|
+
targetPath
|
|
1079
|
+
}) {
|
|
1080
|
+
const isCurrentDir = targetPath === ".";
|
|
1081
|
+
logger.userPlain("");
|
|
1082
|
+
logger.userPlain("To get started with Antigravity:");
|
|
1083
|
+
logger.userPlain("");
|
|
1084
|
+
if (isCurrentDir) {
|
|
1085
|
+
logger.userPlain(" 1. Open the current folder in Antigravity:");
|
|
1086
|
+
logger.userPlain("");
|
|
1087
|
+
logger.userPlain(" agy .");
|
|
1088
|
+
} else {
|
|
1089
|
+
logger.userPlain(" 1. Open the project in Antigravity:");
|
|
1090
|
+
logger.userPlain("");
|
|
1091
|
+
logger.userPlain(` agy ${targetPath}`);
|
|
1092
|
+
}
|
|
1093
|
+
logger.userPlain("");
|
|
1094
|
+
logger.userPlain(" 2. Copy and paste the prompt above to start building your agent");
|
|
1095
|
+
logger.userPlain("");
|
|
1096
|
+
}
|
|
1097
|
+
};
|
|
1098
|
+
var setupAntigravityMCPConfig = async (mcpConfig) => {
|
|
1099
|
+
const antigravityConfigDir = path11.join(os.homedir(), ".gemini", "antigravity");
|
|
1100
|
+
const antigravityConfigPath = path11.join(antigravityConfigDir, "mcp_config.json");
|
|
1101
|
+
await fs11.mkdir(antigravityConfigDir, { recursive: true });
|
|
1102
|
+
let existingConfig = { mcpServers: {} };
|
|
1103
|
+
try {
|
|
1104
|
+
const existingContent = await fs11.readFile(antigravityConfigPath, "utf-8");
|
|
1105
|
+
existingConfig = JSON.parse(existingContent);
|
|
1106
|
+
if (!existingConfig.mcpServers) {
|
|
1107
|
+
existingConfig.mcpServers = {};
|
|
1108
|
+
}
|
|
1109
|
+
} catch {
|
|
1110
|
+
existingConfig = { mcpServers: {} };
|
|
1111
|
+
}
|
|
1112
|
+
for (const [key, value] of Object.entries(mcpConfig.mcpServers)) {
|
|
1113
|
+
if (!(key in existingConfig.mcpServers)) {
|
|
1114
|
+
existingConfig.mcpServers[key] = value;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
await fs11.writeFile(
|
|
1118
|
+
antigravityConfigPath,
|
|
1119
|
+
JSON.stringify(existingConfig, null, 2)
|
|
1120
|
+
);
|
|
1121
|
+
logger.userInfo(`Antigravity MCP config updated at: ${antigravityConfigPath}`);
|
|
1122
|
+
};
|
|
960
1123
|
|
|
961
1124
|
// src/providers/coding-assistants/kilocode/index.ts
|
|
962
1125
|
var KilocodeCodingAssistantProvider = {
|
|
@@ -1014,6 +1177,7 @@ var PROVIDERS3 = {
|
|
|
1014
1177
|
kilocode: KilocodeCodingAssistantProvider,
|
|
1015
1178
|
"claude-code": ClaudeCodingAssistantProvider,
|
|
1016
1179
|
cursor: CursorCodingAssistantProvider,
|
|
1180
|
+
antigravity: AntigravityCodingAssistantProvider,
|
|
1017
1181
|
none: NoneCodingAssistantProvider
|
|
1018
1182
|
};
|
|
1019
1183
|
var getCodingAssistantProvider = ({
|
|
@@ -1033,28 +1197,25 @@ var getAllCodingAssistants = () => {
|
|
|
1033
1197
|
var CodingAssistantUtils = class {
|
|
1034
1198
|
/**
|
|
1035
1199
|
* Detects which coding assistants are installed on the system.
|
|
1200
|
+
* Uses each provider's own isAvailable() method for detection.
|
|
1036
1201
|
*
|
|
1037
1202
|
* @returns Promise resolving to a map of assistant IDs to installation status
|
|
1038
1203
|
*
|
|
1039
1204
|
* @example
|
|
1040
1205
|
* ```ts
|
|
1041
1206
|
* const installed = await CodingAssistantUtils.detectInstalledAgents();
|
|
1042
|
-
* // Returns: { 'claude-code': true, 'cursor': false, 'kilocode': true }
|
|
1207
|
+
* // Returns: { 'claude-code': true, 'cursor': false, 'kilocode': true, ... }
|
|
1043
1208
|
* ```
|
|
1044
1209
|
*/
|
|
1045
1210
|
static async detectInstalledAgents() {
|
|
1046
|
-
const
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
kilocode: hasKilocode,
|
|
1055
|
-
none: true
|
|
1056
|
-
// Always available since it doesn't require installation
|
|
1057
|
-
};
|
|
1211
|
+
const providers = getAllCodingAssistants();
|
|
1212
|
+
const results = await Promise.all(
|
|
1213
|
+
providers.map(async (provider) => {
|
|
1214
|
+
const availability = await provider.isAvailable();
|
|
1215
|
+
return [provider.id, availability.installed];
|
|
1216
|
+
})
|
|
1217
|
+
);
|
|
1218
|
+
return Object.fromEntries(results);
|
|
1058
1219
|
}
|
|
1059
1220
|
};
|
|
1060
1221
|
|
|
@@ -1389,7 +1550,7 @@ var createDirectories = async ({
|
|
|
1389
1550
|
"tests/scenarios"
|
|
1390
1551
|
];
|
|
1391
1552
|
for (const dir of directories) {
|
|
1392
|
-
await
|
|
1553
|
+
await fs11.mkdir(path11.join(projectPath, dir), { recursive: true });
|
|
1393
1554
|
}
|
|
1394
1555
|
};
|
|
1395
1556
|
var generateEnvFiles = async ({
|
|
@@ -1409,7 +1570,7 @@ var generateEnvFiles = async ({
|
|
|
1409
1570
|
"LANGWATCH_API_KEY=your_langwatch_api_key_here"
|
|
1410
1571
|
];
|
|
1411
1572
|
const envExample = envExampleLines.join("\n") + "\n";
|
|
1412
|
-
await
|
|
1573
|
+
await fs11.writeFile(path11.join(projectPath, ".env.example"), envExample);
|
|
1413
1574
|
const envContentLines = [
|
|
1414
1575
|
"# LLM Provider API Keys",
|
|
1415
1576
|
...envVars.map((v) => `${v.key}=${v.value}`),
|
|
@@ -1418,7 +1579,7 @@ var generateEnvFiles = async ({
|
|
|
1418
1579
|
`LANGWATCH_API_KEY=${config.langwatchApiKey}`
|
|
1419
1580
|
];
|
|
1420
1581
|
const envContent = envContentLines.join("\n") + "\n";
|
|
1421
|
-
await
|
|
1582
|
+
await fs11.writeFile(path11.join(projectPath, ".env"), envContent);
|
|
1422
1583
|
};
|
|
1423
1584
|
var generateSamplePrompt = async ({
|
|
1424
1585
|
projectPath
|
|
@@ -1431,12 +1592,12 @@ messages:
|
|
|
1431
1592
|
content: |
|
|
1432
1593
|
You are a helpful AI assistant.
|
|
1433
1594
|
`;
|
|
1434
|
-
await
|
|
1435
|
-
|
|
1595
|
+
await fs11.writeFile(
|
|
1596
|
+
path11.join(projectPath, "prompts", "sample_prompt.yaml"),
|
|
1436
1597
|
samplePromptYaml
|
|
1437
1598
|
);
|
|
1438
|
-
await
|
|
1439
|
-
|
|
1599
|
+
await fs11.writeFile(
|
|
1600
|
+
path11.join(projectPath, "prompts.json"),
|
|
1440
1601
|
JSON.stringify({ prompts: [] }, null, 2)
|
|
1441
1602
|
);
|
|
1442
1603
|
};
|
|
@@ -1476,8 +1637,8 @@ var generateSampleEvaluation = async ({
|
|
|
1476
1637
|
nbformat: 4,
|
|
1477
1638
|
nbformat_minor: 4
|
|
1478
1639
|
};
|
|
1479
|
-
await
|
|
1480
|
-
|
|
1640
|
+
await fs11.writeFile(
|
|
1641
|
+
path11.join(projectPath, "tests", "evaluations", "example_eval.ipynb"),
|
|
1481
1642
|
JSON.stringify(sampleEvalNotebook, null, 2)
|
|
1482
1643
|
);
|
|
1483
1644
|
};
|
|
@@ -1501,8 +1662,8 @@ Follow the Agent Testing Pyramid: use Scenario for end-to-end agentic tests, but
|
|
|
1501
1662
|
// TODO: Add your scenario tests here
|
|
1502
1663
|
// Refer to https://scenario.langwatch.ai/ for documentation
|
|
1503
1664
|
`;
|
|
1504
|
-
await
|
|
1505
|
-
|
|
1665
|
+
await fs11.writeFile(
|
|
1666
|
+
path11.join(
|
|
1506
1667
|
projectPath,
|
|
1507
1668
|
"tests",
|
|
1508
1669
|
"scenarios",
|
|
@@ -1538,8 +1699,8 @@ const main = () => {
|
|
|
1538
1699
|
main();
|
|
1539
1700
|
`;
|
|
1540
1701
|
const mainFileName = config.language === "python" ? "main.py" : "index.ts";
|
|
1541
|
-
await
|
|
1542
|
-
|
|
1702
|
+
await fs11.writeFile(
|
|
1703
|
+
path11.join(projectPath, srcDir, mainFileName),
|
|
1543
1704
|
mainFileContent
|
|
1544
1705
|
);
|
|
1545
1706
|
};
|
|
@@ -1592,18 +1753,18 @@ build/
|
|
|
1592
1753
|
var ensureGitignore = async ({
|
|
1593
1754
|
projectPath
|
|
1594
1755
|
}) => {
|
|
1595
|
-
const gitignorePath =
|
|
1756
|
+
const gitignorePath = path11.join(projectPath, ".gitignore");
|
|
1596
1757
|
try {
|
|
1597
|
-
const existingContent = await
|
|
1758
|
+
const existingContent = await fs11.readFile(gitignorePath, "utf-8");
|
|
1598
1759
|
if (!existingContent.includes(".better-agents")) {
|
|
1599
1760
|
const appendContent = `
|
|
1600
1761
|
# Better Agents
|
|
1601
1762
|
.better-agents/
|
|
1602
1763
|
`;
|
|
1603
|
-
await
|
|
1764
|
+
await fs11.appendFile(gitignorePath, appendContent);
|
|
1604
1765
|
}
|
|
1605
1766
|
} catch {
|
|
1606
|
-
await
|
|
1767
|
+
await fs11.writeFile(gitignorePath, DEFAULT_GITIGNORE);
|
|
1607
1768
|
}
|
|
1608
1769
|
};
|
|
1609
1770
|
|
|
@@ -1616,7 +1777,7 @@ var buildOverviewSection = ({ config }) => {
|
|
|
1616
1777
|
|
|
1617
1778
|
**Goal:** ${projectGoal}
|
|
1618
1779
|
|
|
1619
|
-
|
|
1780
|
+
**Framework:** ${framework === "agno" ? "Agno" : framework === "langgraph-py" ? "LangGraph (Python)" : framework === "langgraph-ts" ? "LangGraph (TypeScript)" : framework === "google-adk" ? "Google ADK" : "Mastra"}
|
|
1620
1781
|
**Language:** ${language === "python" ? "Python" : "TypeScript"}
|
|
1621
1782
|
|
|
1622
1783
|
This project follows LangWatch best practices for building production-ready AI agents.
|
|
@@ -1647,7 +1808,7 @@ Best practices:
|
|
|
1647
1808
|
- When broken, run on single scenario at a time to debug and iterate faster, not the whole suite
|
|
1648
1809
|
- Write as few scenarios as possible, try to cover more ground with few scenarios, as they are heavy to run
|
|
1649
1810
|
- If user made 1 request, just 1 scenario might be enough, run it at the end of the implementation to check if it works
|
|
1650
|
-
- ALWAYS consult the Scenario docs **through the LangWatch MCP** on how to write scenarios.
|
|
1811
|
+
- ALWAYS consult the Scenario docs **through the LangWatch MCP** on how to install and write scenarios.
|
|
1651
1812
|
|
|
1652
1813
|
### 2. Prompt Management
|
|
1653
1814
|
|
|
@@ -1811,7 +1972,7 @@ The MCP will provide up-to-date documentation and examples. For Scenario specifi
|
|
|
1811
1972
|
- **Scenario Documentation**: https://scenario.langwatch.ai/
|
|
1812
1973
|
- **Agent Testing Pyramid**: https://scenario.langwatch.ai/best-practices/the-agent-testing-pyramid
|
|
1813
1974
|
- **LangWatch Dashboard**: https://app.langwatch.ai/
|
|
1814
|
-
${config.framework === "agno" ? "- **Agno Documentation**: https://docs.agno.com/" : config.framework === "langgraph-py" ? "- **LangGraph/LangChain Documentation**: Use the LangGraph MCP for up-to-date docs" : config.framework === "langgraph-ts" ? "- **LangGraph.js Documentation**: Use the LangGraph MCP for up-to-date docs" : "- **Mastra Documentation**: Use the Mastra MCP for up-to-date docs"}
|
|
1975
|
+
${config.framework === "agno" ? "- **Agno Documentation**: https://docs.agno.com/" : config.framework === "langgraph-py" ? "- **LangGraph/LangChain Documentation**: Use the LangGraph MCP for up-to-date docs" : config.framework === "langgraph-ts" ? "- **LangGraph.js Documentation**: Use the LangGraph MCP for up-to-date docs" : config.framework === "google-adk" ? "- **Google ADK Documentation**: Use the Google ADK MCP for up-to-date docs" : "- **Mastra Documentation**: Use the Mastra MCP for up-to-date docs"}
|
|
1815
1976
|
|
|
1816
1977
|
---
|
|
1817
1978
|
|
|
@@ -1827,14 +1988,14 @@ var buildAgentsGuide = async ({
|
|
|
1827
1988
|
const frameworkProvider = getFrameworkProvider({
|
|
1828
1989
|
framework: config.framework
|
|
1829
1990
|
});
|
|
1830
|
-
const frameworkKnowledge = frameworkProvider.getKnowledge();
|
|
1991
|
+
const frameworkKnowledge = frameworkProvider.getKnowledge({ config });
|
|
1831
1992
|
const content = [
|
|
1832
1993
|
buildOverviewSection({ config }),
|
|
1833
1994
|
buildPrinciplesSection(),
|
|
1834
1995
|
frameworkKnowledge.agentsGuideSection,
|
|
1835
1996
|
buildWorkflowSection({ config })
|
|
1836
1997
|
].join("\n");
|
|
1837
|
-
await
|
|
1998
|
+
await fs11.writeFile(path11.join(projectPath, "AGENTS.md"), content);
|
|
1838
1999
|
};
|
|
1839
2000
|
|
|
1840
2001
|
// src/builders/mcp-config-builder.ts
|
|
@@ -1861,22 +2022,22 @@ var setupEditorConfigs = async ({
|
|
|
1861
2022
|
projectPath,
|
|
1862
2023
|
mcpConfig
|
|
1863
2024
|
}) => {
|
|
1864
|
-
const mcpConfigPath =
|
|
1865
|
-
await
|
|
1866
|
-
const cursorDir =
|
|
1867
|
-
await
|
|
1868
|
-
const cursorMcpPath =
|
|
2025
|
+
const mcpConfigPath = path11.join(projectPath, ".mcp.json");
|
|
2026
|
+
await fs11.writeFile(mcpConfigPath, JSON.stringify(mcpConfig, null, 2));
|
|
2027
|
+
const cursorDir = path11.join(projectPath, ".cursor");
|
|
2028
|
+
await fs11.mkdir(cursorDir, { recursive: true });
|
|
2029
|
+
const cursorMcpPath = path11.join(cursorDir, "mcp.json");
|
|
1869
2030
|
try {
|
|
1870
|
-
await
|
|
2031
|
+
await fs11.unlink(cursorMcpPath).catch(() => {
|
|
1871
2032
|
});
|
|
1872
|
-
await
|
|
2033
|
+
await fs11.symlink("../.mcp.json", cursorMcpPath);
|
|
1873
2034
|
} catch {
|
|
1874
|
-
await
|
|
2035
|
+
await fs11.writeFile(cursorMcpPath, JSON.stringify(mcpConfig, null, 2));
|
|
1875
2036
|
}
|
|
1876
|
-
const claudeMdPath =
|
|
2037
|
+
const claudeMdPath = path11.join(projectPath, "CLAUDE.md");
|
|
1877
2038
|
const claudeMdContent = `@AGENTS.md
|
|
1878
2039
|
`;
|
|
1879
|
-
await
|
|
2040
|
+
await fs11.writeFile(claudeMdPath, claudeMdContent);
|
|
1880
2041
|
};
|
|
1881
2042
|
|
|
1882
2043
|
// src/commands/init.ts
|
|
@@ -1907,7 +2068,7 @@ var initCommand = async (targetPath, debug = false) => {
|
|
|
1907
2068
|
const configTimer = logger2.startTimer("config-collection");
|
|
1908
2069
|
const config = await collectConfig();
|
|
1909
2070
|
configTimer();
|
|
1910
|
-
const absolutePath =
|
|
2071
|
+
const absolutePath = path11.resolve(process.cwd(), targetPath);
|
|
1911
2072
|
const projectLogger = new LoggerFacade(absolutePath);
|
|
1912
2073
|
const spinner = projectLogger.startSpinner("Setting up your agent project...");
|
|
1913
2074
|
try {
|
|
@@ -1924,7 +2085,7 @@ var initCommand = async (targetPath, debug = false) => {
|
|
|
1924
2085
|
}
|
|
1925
2086
|
});
|
|
1926
2087
|
const mkdirTimer = projectLogger.startTimer("directory-creation");
|
|
1927
|
-
await
|
|
2088
|
+
await fs11.mkdir(absolutePath, { recursive: true });
|
|
1928
2089
|
mkdirTimer();
|
|
1929
2090
|
const structureTimer = projectLogger.startTimer("project-structure");
|
|
1930
2091
|
await createProjectStructure({ projectPath: absolutePath, config });
|
|
@@ -1934,13 +2095,16 @@ var initCommand = async (targetPath, debug = false) => {
|
|
|
1934
2095
|
const frameworkProvider = getFrameworkProvider({
|
|
1935
2096
|
framework: config.framework
|
|
1936
2097
|
});
|
|
1937
|
-
await frameworkProvider.setup({ projectPath: absolutePath });
|
|
2098
|
+
await frameworkProvider.setup({ projectPath: absolutePath, config });
|
|
1938
2099
|
frameworkTimer();
|
|
1939
2100
|
spinner.text = "Framework configuration set up";
|
|
1940
2101
|
await ensureGitignore({ projectPath: absolutePath });
|
|
1941
2102
|
const editorTimer = projectLogger.startTimer("editor-setup");
|
|
1942
2103
|
const mcpConfig = buildMCPConfig({ config });
|
|
1943
2104
|
await setupEditorConfigs({ projectPath: absolutePath, mcpConfig });
|
|
2105
|
+
if (config.codingAssistant === "antigravity") {
|
|
2106
|
+
await setupAntigravityMCPConfig(mcpConfig);
|
|
2107
|
+
}
|
|
1944
2108
|
editorTimer();
|
|
1945
2109
|
spinner.text = "Editor configurations set up";
|
|
1946
2110
|
const agentsTimer = projectLogger.startTimer("agents-guide");
|
|
@@ -1985,9 +2149,9 @@ program.command("init").description("Initialize a new agent project").argument(
|
|
|
1985
2149
|
"[path]",
|
|
1986
2150
|
"Path to initialize the project (defaults to current directory)",
|
|
1987
2151
|
"."
|
|
1988
|
-
).action((
|
|
2152
|
+
).action((path13, options) => {
|
|
1989
2153
|
const debug = options.parent?.debug || false;
|
|
1990
|
-
return initCommand(
|
|
2154
|
+
return initCommand(path13, debug);
|
|
1991
2155
|
});
|
|
1992
2156
|
program.parse();
|
|
1993
2157
|
//# sourceMappingURL=index.js.map
|