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.
- package/README.md +71 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +295 -0
- package/dist/index.js.map +1 -0
- package/dist/template/README.md +1092 -0
- package/dist/template/env.example +36 -0
- package/dist/template/package.json +27 -0
- package/dist/template/src/agent.ts +186 -0
- package/dist/template/tsconfig.json +27 -0
- package/package.json +51 -0
|
@@ -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
|
+
}
|