march-start-cli 0.1.0

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.
@@ -0,0 +1,36 @@
1
+
2
+ HOST=0.0.0.0
3
+ PORT=8000
4
+
5
+ GATEWAY_URL=your-gateway-url-here
6
+ CONNECTION_SECURE=false
7
+
8
+ GATEWAY_API_KEY=your-gateway-key-here
9
+
10
+
11
+ HEARTBEAT_INTERVAL=10
12
+
13
+ AGENT_BASE_URL=http://localhost:8060
14
+
15
+
16
+ OPENAI_API_KEY=your-open-api-key-here
17
+
18
+ OPENAI_MODEL=gpt-4o-mini
19
+
20
+
21
+ JWT_SECRET=your-secret-key-change-in-production
22
+
23
+ JWT_ALGORITHM=HS256
24
+
25
+
26
+ JWT_COOKIE_NAME=agent_token
27
+
28
+
29
+ CORS_ORIGINS=*
30
+
31
+
32
+ NEXT_PUBLIC_API_URL=http://localhost:8060
33
+
34
+
35
+
36
+ DEBUG=true
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "march-agent-template-ts",
3
+ "version": "1.0.0",
4
+ "description": "TypeScript template agent for March AI platform",
5
+ "type": "module",
6
+ "main": "dist/agent.js",
7
+ "scripts": {
8
+ "dev": "tsx watch src/agent.ts",
9
+ "start": "node dist/agent.js",
10
+ "build": "tsc",
11
+ "typecheck": "tsc --noEmit"
12
+ },
13
+ "dependencies": {
14
+ "@langchain/openai": "^0.3.17",
15
+ "@langchain/langgraph": "^0.2.39",
16
+ "@langchain/langgraph-checkpoint": "^0.0.15",
17
+ "@langchain/core": "^0.3.30",
18
+ "ai": "^4.1.0",
19
+ "@ai-sdk/openai": "^1.1.0",
20
+ "dotenv": "^16.4.7"
21
+ },
22
+ "devDependencies": {
23
+ "@types/node": "^22.10.7",
24
+ "tsx": "^4.19.2",
25
+ "typescript": "^5.7.3"
26
+ }
27
+ }
@@ -0,0 +1,186 @@
1
+ /**
2
+ * March Agent - TypeScript Template
3
+ *
4
+ * Run with: pnpm dev
5
+ *
6
+ * This template demonstrates:
7
+ * 1. Basic agent setup and message handling
8
+ * 2. Streaming responses with LangChain
9
+ * 3. Conversation history management
10
+ * 4. Attachment handling (images and files)
11
+ */
12
+
13
+ import { config } from 'dotenv'
14
+ import { resolve } from 'path'
15
+
16
+ // Load environment variables from .env file
17
+ const envPath = resolve(process.cwd(), '.env')
18
+ config({ path: envPath, override: true })
19
+
20
+ import { ChatOpenAI } from '@langchain/openai'
21
+ import { HumanMessage, AIMessage, SystemMessage, type BaseMessage } from '@langchain/core/messages'
22
+
23
+ // Import from local framework (change to 'march-ai-sdk' when published)
24
+ import { MarchAgentApp, Message } from '../../ai-ts-framework/dist/index.js'
25
+
26
+ // ============================================================================
27
+ // CONFIGURATION
28
+ // ============================================================================
29
+
30
+ const AGENT_NAME = process.env.AGENT_NAME || 'my-agent'
31
+ const AGENT_ABOUT = process.env.AGENT_ABOUT || 'A helpful AI assistant'
32
+
33
+ const SYSTEM_PROMPT = `You are a helpful AI assistant. Your role is to assist users with their questions and tasks.
34
+
35
+ Guidelines:
36
+ 1. Be helpful, accurate, and concise
37
+ 2. If you don't know something, say so honestly
38
+ 3. Provide clear explanations when needed
39
+ 4. Be friendly and professional`
40
+
41
+ // ============================================================================
42
+ // LLM SETUP
43
+ // ============================================================================
44
+
45
+ // Vision-capable model for image analysis
46
+ const visionLlm = new ChatOpenAI({
47
+ model: process.env.OPENAI_VISION_MODEL || 'gpt-4o',
48
+ streaming: true,
49
+ openAIApiKey: process.env.OPENAI_API_KEY,
50
+ })
51
+
52
+ // Standard model for text-only interactions
53
+ const llm = new ChatOpenAI({
54
+ model: process.env.OPENAI_MODEL || 'gpt-4o-mini',
55
+ streaming: true,
56
+ openAIApiKey: process.env.OPENAI_API_KEY,
57
+ })
58
+
59
+ // ============================================================================
60
+ // APP INITIALIZATION
61
+ // ============================================================================
62
+
63
+ const app = new MarchAgentApp({
64
+ gatewayUrl: process.env.GATEWAY_URL || 'agent-gateway:8080',
65
+ apiKey: process.env.GATEWAY_API_KEY || 'agent-key',
66
+ heartbeatInterval: parseInt(process.env.HEARTBEAT_INTERVAL || '10'),
67
+ secure: process.env.CONNECTION_SECURE === 'true',
68
+ })
69
+
70
+ // ============================================================================
71
+ // MAIN
72
+ // ============================================================================
73
+
74
+ async function main() {
75
+ const agent = await app.registerMe({
76
+ name: AGENT_NAME,
77
+ about: AGENT_ABOUT,
78
+ document: `${AGENT_NAME} is a helpful AI assistant built with the March Agent SDK.`,
79
+ representationName: AGENT_NAME,
80
+ baseUrl: process.env.AGENT_BASE_URL || 'http://localhost:8060',
81
+ metadata: { version: '1.0.0' },
82
+ })
83
+
84
+ // -------------------------------------------------------------------------
85
+ // MESSAGE HANDLER
86
+ // -------------------------------------------------------------------------
87
+
88
+ agent.onMessage(async (message: Message, sender: string) => {
89
+ const messages: BaseMessage[] = [new SystemMessage(SYSTEM_PROMPT)]
90
+
91
+ // Load conversation history
92
+ if (message.conversation) {
93
+ const history = await message.conversation.getAgentHistory({ limit: 20 })
94
+ for (const msg of history) {
95
+ if (msg.role === 'user') {
96
+ messages.push(new HumanMessage(msg.content))
97
+ } else {
98
+ messages.push(new AIMessage(msg.content))
99
+ }
100
+ }
101
+ }
102
+
103
+ // Check for attachments
104
+ let useVisionModel = false
105
+
106
+ if (message.hasAttachment() && message.attachment) {
107
+ const attachment = message.attachment
108
+ const isImage = attachment.contentType?.startsWith('image/')
109
+
110
+ if (isImage) {
111
+ // Handle image attachment with vision model
112
+ useVisionModel = true
113
+ try {
114
+ const base64Image = await message.getAttachmentBase64()
115
+ const userMessage = new HumanMessage({
116
+ content: [
117
+ { type: 'text', text: message.content || 'What do you see in this image?' },
118
+ { type: 'image_url', image_url: { url: `data:${attachment.contentType};base64,${base64Image}` } },
119
+ ],
120
+ })
121
+ messages.push(userMessage)
122
+ } catch (e) {
123
+ // Fallback if image download fails
124
+ messages.push(new HumanMessage(`${message.content}\n\n[Note: An image was attached but could not be processed]`))
125
+ }
126
+ } else {
127
+ // Other file types - mention them in the message
128
+ messages.push(new HumanMessage(`${message.content}\n\n[Attachment: ${attachment.filename}]`))
129
+ }
130
+ } else {
131
+ // Text-only message
132
+ messages.push(new HumanMessage(message.content))
133
+ }
134
+
135
+ // Select model based on content type
136
+ const selectedLlm = useVisionModel ? visionLlm : llm
137
+
138
+ // Create streamer for response
139
+ const streamer = agent.streamer(message)
140
+
141
+ // Set optional metadata
142
+ streamer.setMessageMetadata({
143
+ model: useVisionModel ? (process.env.OPENAI_VISION_MODEL || 'gpt-4o') : (process.env.OPENAI_MODEL || 'gpt-4o-mini'),
144
+ hasAttachment: message.hasAttachment(),
145
+ })
146
+
147
+ // Add artifacts for testing frontend rendering
148
+ streamer.addArtifact({
149
+ url: `/api/dashboard/${message.conversationId}`,
150
+ type: 'iframe',
151
+ title: 'Patient Dashboard',
152
+ description: 'Interactive dashboard showing conversation statistics',
153
+ })
154
+
155
+ streamer.addArtifact({
156
+ url: `/api/artifacts/document/${message.conversationId}`,
157
+ type: 'document',
158
+ title: 'Health Summary Report',
159
+ description: 'Comprehensive health summary document',
160
+ })
161
+
162
+ try {
163
+ // Stream response
164
+ const stream = await selectedLlm.stream(messages)
165
+ for await (const chunk of stream) {
166
+ if (chunk.content) {
167
+ streamer.stream(chunk.content as string)
168
+ }
169
+ }
170
+ } catch (e) {
171
+ console.error('LLM error:', e)
172
+ streamer.stream('I apologize, but I encountered an error. Please try again.')
173
+ }
174
+
175
+ await streamer.finish()
176
+ })
177
+
178
+ // Start the agent
179
+ console.log(`Starting ${AGENT_NAME}...`)
180
+ await app.run()
181
+ }
182
+
183
+ main().catch((error: Error) => {
184
+ console.error('Failed to start agent:', error)
185
+ process.exit(1)
186
+ })
@@ -0,0 +1,27 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": [
7
+ "ES2022"
8
+ ],
9
+ "outDir": "./dist",
10
+ "rootDir": "./src",
11
+ "declaration": true,
12
+ "sourceMap": true,
13
+ "strict": true,
14
+ "esModuleInterop": true,
15
+ "skipLibCheck": true,
16
+ "forceConsistentCasingInFileNames": true,
17
+ "resolveJsonModule": true,
18
+ "isolatedModules": true
19
+ },
20
+ "include": [
21
+ "src/**/*"
22
+ ],
23
+ "exclude": [
24
+ "node_modules",
25
+ "dist"
26
+ ]
27
+ }
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "march-start-cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI to scaffold new March AI agent projects",
5
+ "type": "module",
6
+ "bin": {
7
+ "march-start": "./dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "scripts": {
17
+ "build": "tsup",
18
+ "dev": "tsup --watch",
19
+ "typecheck": "tsc --noEmit",
20
+ "clean": "rm -rf dist",
21
+ "check-secrets": "tsx src/security.ts --check",
22
+ "prepublishOnly": "npm run check-secrets && npm run build"
23
+ },
24
+ "dependencies": {
25
+ "prompts": "^2.4.2",
26
+ "picocolors": "^1.1.1",
27
+ "fs-extra": "^11.2.0"
28
+ },
29
+ "devDependencies": {
30
+ "@types/fs-extra": "^11.0.4",
31
+ "@types/node": "^22.10.7",
32
+ "@types/prompts": "^2.4.9",
33
+ "tsup": "^8.3.5",
34
+ "tsx": "^4.19.2",
35
+ "typescript": "^5.7.3"
36
+ },
37
+ "engines": {
38
+ "node": ">=18"
39
+ },
40
+ "keywords": [
41
+ "march",
42
+ "agent",
43
+ "ai",
44
+ "sdk",
45
+ "cli",
46
+ "scaffold",
47
+ "generator"
48
+ ],
49
+ "author": "March Health",
50
+ "license": "MIT"
51
+ }