@make-u-free/migi 0.3.0 → 0.3.2
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/package.json +2 -1
- package/src/agent.js +7 -2
- package/src/tls.js +6 -6
- package/src/tools.js +43 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@make-u-free/migi",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Your AI right-hand agent. Works anywhere, with any LLM API.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"chalk": "^5.3.0",
|
|
14
14
|
"dotenv": "^16.4.0",
|
|
15
15
|
"glob": "^11.0.0",
|
|
16
|
+
"officeparser": "^6.0.7",
|
|
16
17
|
"openai": "^4.0.0",
|
|
17
18
|
"xlsx": "^0.18.5"
|
|
18
19
|
},
|
package/src/agent.js
CHANGED
|
@@ -7,8 +7,9 @@ import { httpsAgent } from './tls.js'
|
|
|
7
7
|
|
|
8
8
|
export class MigiAgent {
|
|
9
9
|
constructor({ context = '', promptFn = null, apiKey = null, model = 'gpt-4.1-2025-04-14', name = 'Migi', userName = '', teamsWebhookUrl = '' } = {}) {
|
|
10
|
+
this.apiKey = apiKey || process.env.OPENAI_API_KEY
|
|
10
11
|
this.client = new OpenAI({
|
|
11
|
-
apiKey: apiKey
|
|
12
|
+
apiKey: this.apiKey,
|
|
12
13
|
...(httpsAgent ? { httpAgent: httpsAgent } : {})
|
|
13
14
|
})
|
|
14
15
|
this.model = model
|
|
@@ -123,7 +124,11 @@ ${userNameLine}
|
|
|
123
124
|
|
|
124
125
|
if (approved) {
|
|
125
126
|
try {
|
|
126
|
-
result = await executeTool(name, args, {
|
|
127
|
+
result = await executeTool(name, args, {
|
|
128
|
+
teamsWebhookUrl: this.teamsWebhookUrl,
|
|
129
|
+
apiKey: this.apiKey,
|
|
130
|
+
model: this.model
|
|
131
|
+
})
|
|
127
132
|
} catch (err) {
|
|
128
133
|
result = `エラー: ${err.message}`
|
|
129
134
|
}
|
package/src/tls.js
CHANGED
|
@@ -41,13 +41,13 @@ if (caPath) {
|
|
|
41
41
|
|
|
42
42
|
// ① tls.createSecureContext パッチ
|
|
43
43
|
// Node 18+ built-in fetch (undici) を含む全TLS接続に効く
|
|
44
|
+
// デフォルトのCA(tls.rootCertificates)に追加する形にする
|
|
44
45
|
const _origCreate = tls.createSecureContext
|
|
45
46
|
tls.createSecureContext = (options = {}) => {
|
|
46
|
-
const
|
|
47
|
-
const existing = options.ca
|
|
47
|
+
const base = options.ca
|
|
48
48
|
? (Array.isArray(options.ca) ? options.ca : [options.ca])
|
|
49
|
-
:
|
|
50
|
-
return _origCreate({ ...options, ca: [...
|
|
49
|
+
: tls.rootCertificates // デフォルトCAを引き継ぐ
|
|
50
|
+
return _origCreate({ ...options, ca: [...base, caCert] })
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// ② NODE_EXTRA_CA_CERTS(環境変数で起動する場合のフォールバック)
|
|
@@ -55,8 +55,8 @@ if (caPath) {
|
|
|
55
55
|
process.env.NODE_EXTRA_CA_CERTS = caPath
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
// ③ https.Agent
|
|
59
|
-
_httpsAgent = new https.Agent({ ca: caCert })
|
|
58
|
+
// ③ https.Agent: デフォルトCA + Zscaler CA を合わせて渡す
|
|
59
|
+
_httpsAgent = new https.Agent({ ca: [...tls.rootCertificates, caCert] })
|
|
60
60
|
|
|
61
61
|
console.log(` [TLS] CA loaded: ${caPath}`)
|
|
62
62
|
} else {
|
package/src/tools.js
CHANGED
|
@@ -4,9 +4,15 @@ import { dirname, extname } from 'path'
|
|
|
4
4
|
import { request } from 'https'
|
|
5
5
|
import { glob } from 'glob'
|
|
6
6
|
import xlsxPkg from 'xlsx'
|
|
7
|
+
import officeParser from 'officeparser'
|
|
8
|
+
import OpenAI from 'openai'
|
|
7
9
|
import { httpsAgent } from './tls.js'
|
|
8
10
|
const { readFile: xlsxReadFile, utils: xlsxUtils } = xlsxPkg
|
|
9
11
|
|
|
12
|
+
const IMAGE_EXTS = new Set(['.jpg', '.jpeg', '.png', '.gif', '.webp'])
|
|
13
|
+
const OFFICE_EXTS = new Set(['.pdf', '.pptx', '.ppt', '.docx', '.doc', '.odp', '.odt'])
|
|
14
|
+
const MIME = { '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.png': 'image/png', '.gif': 'image/gif', '.webp': 'image/webp' }
|
|
15
|
+
|
|
10
16
|
// ---- OpenAI ツールスキーマ定義 ----
|
|
11
17
|
|
|
12
18
|
export const toolSchemas = [
|
|
@@ -14,7 +20,7 @@ export const toolSchemas = [
|
|
|
14
20
|
type: 'function',
|
|
15
21
|
function: {
|
|
16
22
|
name: 'read_file',
|
|
17
|
-
description: '
|
|
23
|
+
description: 'ファイルの内容を読み込む。テキスト・Excel・PDF・Word・PowerPoint・画像に対応',
|
|
18
24
|
parameters: {
|
|
19
25
|
type: 'object',
|
|
20
26
|
properties: {
|
|
@@ -124,6 +130,8 @@ export async function executeTool(name, args, opts = {}) {
|
|
|
124
130
|
case 'read_file': {
|
|
125
131
|
if (!existsSync(args.path)) return `エラー: ファイルが見つかりません: ${args.path}`
|
|
126
132
|
const ext = extname(args.path).toLowerCase()
|
|
133
|
+
|
|
134
|
+
// Excel
|
|
127
135
|
if (ext === '.xlsx' || ext === '.xls') {
|
|
128
136
|
const workbook = xlsxReadFile(args.path)
|
|
129
137
|
const result = []
|
|
@@ -134,6 +142,40 @@ export async function executeTool(name, args, opts = {}) {
|
|
|
134
142
|
}
|
|
135
143
|
return result.join('\n\n')
|
|
136
144
|
}
|
|
145
|
+
|
|
146
|
+
// PDF / PowerPoint / Word
|
|
147
|
+
if (OFFICE_EXTS.has(ext)) {
|
|
148
|
+
try {
|
|
149
|
+
const text = await officeParser.parseOfficeAsync(args.path)
|
|
150
|
+
return text?.trim() || '(テキストが抽出できませんでした)'
|
|
151
|
+
} catch (err) {
|
|
152
|
+
return `エラー: ファイルの解析に失敗しました: ${err.message}`
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// 画像 → Vision API で内容を説明させる
|
|
157
|
+
if (IMAGE_EXTS.has(ext)) {
|
|
158
|
+
if (!opts.apiKey) return 'エラー: 画像読み込みにはAPIキーが必要です'
|
|
159
|
+
const base64 = readFileSync(args.path).toString('base64')
|
|
160
|
+
const mimeType = MIME[ext] || 'image/jpeg'
|
|
161
|
+
const client = new OpenAI({
|
|
162
|
+
apiKey: opts.apiKey,
|
|
163
|
+
...(httpsAgent ? { httpAgent: httpsAgent } : {})
|
|
164
|
+
})
|
|
165
|
+
const res = await client.chat.completions.create({
|
|
166
|
+
model: opts.model || 'gpt-4.1-2025-04-14',
|
|
167
|
+
messages: [{
|
|
168
|
+
role: 'user',
|
|
169
|
+
content: [
|
|
170
|
+
{ type: 'image_url', image_url: { url: `data:${mimeType};base64,${base64}` } },
|
|
171
|
+
{ type: 'text', text: 'この画像の内容を詳しく説明してください。テキストが含まれている場合はすべて書き起こしてください。' }
|
|
172
|
+
]
|
|
173
|
+
}],
|
|
174
|
+
max_tokens: 2000
|
|
175
|
+
})
|
|
176
|
+
return res.choices[0].message.content
|
|
177
|
+
}
|
|
178
|
+
|
|
137
179
|
return readFileSync(args.path, 'utf-8')
|
|
138
180
|
}
|
|
139
181
|
|