@make-u-free/migi 0.2.6 → 0.2.8

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/bin/migi.js CHANGED
@@ -20,6 +20,7 @@ let apiKey = process.env.OPENAI_API_KEY
20
20
  let model = 'gpt-4.1-2025-04-14'
21
21
  let agentName = 'Migi'
22
22
  let userName = ''
23
+ let teamsWebhookUrl = ''
23
24
 
24
25
  if (!apiKey) {
25
26
  const config = loadGlobalConfig()
@@ -28,12 +29,14 @@ if (!apiKey) {
28
29
  model = config.model || 'gpt-4.1-2025-04-14'
29
30
  agentName = config.name || 'Migi'
30
31
  userName = config.user_name || ''
32
+ teamsWebhookUrl = config.teams_webhook_url || ''
31
33
  } else {
32
34
  const config = await runSetup(promptFn)
33
35
  apiKey = config.openai_api_key
34
36
  model = config.model || 'gpt-4.1-2025-04-14'
35
37
  agentName = config.name || 'Migi'
36
38
  userName = config.user_name || ''
39
+ teamsWebhookUrl = config.teams_webhook_url || ''
37
40
  }
38
41
  }
39
42
 
@@ -61,7 +64,7 @@ console.log(chalk.dim('\n /secretary 秘書モード'))
61
64
  console.log(chalk.dim(' /config 設定変更'))
62
65
  console.log(chalk.dim(' /exit 終了\n'))
63
66
 
64
- const agent = new MigiAgent({ context, promptFn, apiKey, model, name: agentName, userName })
67
+ const agent = new MigiAgent({ context, promptFn, apiKey, model, name: agentName, userName, teamsWebhookUrl })
65
68
 
66
69
  // ---- メインループ ----
67
70
  function prompt() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@make-u-free/migi",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "description": "Your AI right-hand agent. Works anywhere, with any LLM API.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/agent.js CHANGED
@@ -1,18 +1,20 @@
1
1
  import OpenAI from 'openai'
2
2
  import chalk from 'chalk'
3
3
  import { homedir } from 'os'
4
- import { toolSchemas, executeTool } from './tools.js'
4
+ import { toolSchemas, teamsToolSchema, executeTool } from './tools.js'
5
5
  import { createPermissionChecker } from './permissions.js'
6
6
  import { httpsAgent } from './tls.js'
7
7
 
8
8
  export class MigiAgent {
9
- constructor({ context = '', promptFn = null, apiKey = null, model = 'gpt-4.1-2025-04-14', name = 'Migi', userName = '' } = {}) {
9
+ constructor({ context = '', promptFn = null, apiKey = null, model = 'gpt-4.1-2025-04-14', name = 'Migi', userName = '', teamsWebhookUrl = '' } = {}) {
10
10
  this.client = new OpenAI({
11
11
  apiKey: apiKey || process.env.OPENAI_API_KEY,
12
12
  ...(httpsAgent ? { httpAgent: httpsAgent } : {})
13
13
  })
14
14
  this.model = model
15
15
  this.history = []
16
+ this.teamsWebhookUrl = teamsWebhookUrl
17
+ this.tools = teamsWebhookUrl ? [...toolSchemas, teamsToolSchema] : toolSchemas
16
18
  this.checkPermission = createPermissionChecker(promptFn || (() => Promise.resolve('y')))
17
19
 
18
20
  const cwd = process.cwd()
@@ -56,7 +58,10 @@ ${userNameLine}
56
58
  - ファイルパスは必ずこのディレクトリを基準に構築すること
57
59
  - 相対パスは使わず、常に絶対パスでツールを呼び出すこと
58
60
  `
59
- this.systemPrompt = BASE_SYSTEM_PROMPT +
61
+ const teamsPrompt = teamsWebhookUrl
62
+ ? `\n## Teams通知\n- 改善要望・不具合報告・重要な共有事項があれば notify_teams ツールでTeamsに通知する\n- ユーザーが「改善要望」「フィードバック」「不具合」「共有して」などと言ったら、内容をまとめてTeamsに通知することを提案する`
63
+ : ''
64
+ this.systemPrompt = BASE_SYSTEM_PROMPT + teamsPrompt +
60
65
  (context ? `\n## ロードされたコンテキスト\n${context}` : '')
61
66
  }
62
67
 
@@ -72,7 +77,7 @@ ${userNameLine}
72
77
  const response = await this.client.chat.completions.create({
73
78
  model: this.model,
74
79
  messages,
75
- tools: toolSchemas,
80
+ tools: this.tools,
76
81
  tool_choice: 'auto'
77
82
  })
78
83
 
@@ -99,7 +104,7 @@ ${userNameLine}
99
104
  let result
100
105
 
101
106
  if (approved) {
102
- result = await executeTool(name, args)
107
+ result = await executeTool(name, args, { teamsWebhookUrl: this.teamsWebhookUrl })
103
108
  } else {
104
109
  result = 'ユーザーによりキャンセルされました'
105
110
  console.log(chalk.dim(' → キャンセル'))
package/src/setup.js CHANGED
@@ -145,10 +145,22 @@ export async function runSetup(promptFn = null, existingConfig = null) {
145
145
  const userNameInput = await ask(userNamePrompt)
146
146
  const userName = userNameInput.trim() || currentUserName
147
147
 
148
+ // ---- Teams Webhook URL ----
149
+ console.log('')
150
+ const currentTeamsUrl = isUpdate ? existingConfig.teams_webhook_url || '' : ''
151
+ const teamsPrompt = isUpdate && currentTeamsUrl
152
+ ? chalk.cyan(` Teams Webhook URL [設定済み] > `)
153
+ : chalk.cyan(' Teams Webhook URL(任意・Enterでスキップ) > ')
154
+ if (!isUpdate) {
155
+ console.log(chalk.dim(' Microsoft Teams への通知を使う場合は Webhook URL を入力してください。\n'))
156
+ }
157
+ const teamsInput = await ask(teamsPrompt)
158
+ const teamsWebhookUrl = teamsInput.trim() || currentTeamsUrl
159
+
148
160
  console.log(chalk.green(`\n ${name} です。${userName ? userName + 'さん、' : ''}よろしくお願いします!\n`))
149
161
 
150
162
  // ---- 保存 ----
151
- const config = { name, user_name: userName, openai_api_key: apiKey, model }
163
+ const config = { name, user_name: userName, openai_api_key: apiKey, model, teams_webhook_url: teamsWebhookUrl }
152
164
  saveGlobalConfig(config)
153
165
  if (rl) rl.close()
154
166
 
package/src/tools.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import { readFileSync, writeFileSync, appendFileSync, existsSync, mkdirSync } from 'fs'
2
2
  import { execSync } from 'child_process'
3
3
  import { dirname, extname } from 'path'
4
+ import { request } from 'https'
4
5
  import { glob } from 'glob'
5
6
  import xlsxPkg from 'xlsx'
7
+ import { httpsAgent } from './tls.js'
6
8
  const { readFile: xlsxReadFile, utils: xlsxUtils } = xlsxPkg
7
9
 
8
10
  // ---- OpenAI ツールスキーマ定義 ----
@@ -98,9 +100,26 @@ export const toolSchemas = [
98
100
  }
99
101
  ]
100
102
 
103
+ // ---- Teams 通知ツールスキーマ(Webhook URL が設定済みの場合のみ使用) ----
104
+
105
+ export const teamsToolSchema = {
106
+ type: 'function',
107
+ function: {
108
+ name: 'notify_teams',
109
+ description: 'Microsoft Teams のチャンネルに通知を送る。改善要望・不具合報告・重要な共有事項があるときに使う。',
110
+ parameters: {
111
+ type: 'object',
112
+ properties: {
113
+ message: { type: 'string', description: '送信するメッセージ' }
114
+ },
115
+ required: ['message']
116
+ }
117
+ }
118
+ }
119
+
101
120
  // ---- ツール実行 ----
102
121
 
103
- export async function executeTool(name, args) {
122
+ export async function executeTool(name, args, opts = {}) {
104
123
  switch (name) {
105
124
  case 'read_file': {
106
125
  if (!existsSync(args.path)) return `エラー: ファイルが見つかりません: ${args.path}`
@@ -158,6 +177,35 @@ export async function executeTool(name, args) {
158
177
  }
159
178
  }
160
179
 
180
+ case 'notify_teams': {
181
+ const url = opts.teamsWebhookUrl
182
+ if (!url) return 'エラー: Teams Webhook URL が設定されていません'
183
+ const body = JSON.stringify({ text: args.message })
184
+ return new Promise((resolve) => {
185
+ const parsed = new URL(url)
186
+ const options = {
187
+ hostname: parsed.hostname,
188
+ path: parsed.pathname + parsed.search,
189
+ method: 'POST',
190
+ headers: {
191
+ 'Content-Type': 'application/json',
192
+ 'Content-Length': Buffer.byteLength(body)
193
+ },
194
+ ...(httpsAgent ? { agent: httpsAgent } : {})
195
+ }
196
+ const req = request(options, (res) => {
197
+ if (res.statusCode >= 200 && res.statusCode < 300) {
198
+ resolve('Teams に通知しました')
199
+ } else {
200
+ resolve(`エラー: Teams への送信に失敗しました (${res.statusCode})`)
201
+ }
202
+ })
203
+ req.on('error', (err) => resolve(`エラー: ${err.message}`))
204
+ req.write(body)
205
+ req.end()
206
+ })
207
+ }
208
+
161
209
  default:
162
210
  return `不明なツール: ${name}`
163
211
  }