@things-factory/ai-client-base 10.1.207 → 10.1.212
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/dist-server/service/assistant/tool-budget.js +17 -2
- package/dist-server/service/assistant/tool-budget.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/server/service/assistant/tool-budget.test.ts +18 -0
- package/server/service/assistant/tool-budget.ts +17 -2
- package/translations/ko.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/ai-client-base",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.212",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"things-factory": true,
|
|
6
6
|
"author": "heartyoh",
|
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@anthropic-ai/sdk": "^0.40.0",
|
|
26
26
|
"@google/generative-ai": "^0.24.0",
|
|
27
|
-
"@things-factory/auth-base": "^10.1.
|
|
27
|
+
"@things-factory/auth-base": "^10.1.212",
|
|
28
28
|
"@things-factory/env": "^10.1.149",
|
|
29
|
-
"@things-factory/setting-base": "^10.1.
|
|
30
|
-
"@things-factory/shell": "^10.1.
|
|
29
|
+
"@things-factory/setting-base": "^10.1.212",
|
|
30
|
+
"@things-factory/shell": "^10.1.208",
|
|
31
31
|
"openai": "^4.0.0"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "1e1cdb79fca2915580429af451b6cf1dae653a93"
|
|
34
34
|
}
|
|
@@ -136,6 +136,24 @@ describe('a scope larger than one call carries', () => {
|
|
|
136
136
|
expect(result.openableTools).not.toContain('readList150')
|
|
137
137
|
})
|
|
138
138
|
|
|
139
|
+
it('★ the list says its tools are the model\'s to use - not something to tell the person is missing', async () => {
|
|
140
|
+
const categories = registerLists(165)
|
|
141
|
+
const { client, seen } = recordingClient()
|
|
142
|
+
await registryAssistantChat(input({ client, toolCategories: categories, front: { categories: ['list-3'] } }))
|
|
143
|
+
|
|
144
|
+
const prompt = seen[0].options.systemPrompt
|
|
145
|
+
expect(prompt).toMatch(/never tell the person a tool on this list is missing/)
|
|
146
|
+
expect(prompt).toMatch(/never ask the person to choose instead of opening it/)
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it('★ opening a tool that is already offered says so - call it now', async () => {
|
|
150
|
+
const categories = registerLists(165)
|
|
151
|
+
const { client, seen } = recordingClient([reply(undefined, [TC(OPEN_TOOLS, { names: ['readList3', 'readList150'] })]), reply('done')])
|
|
152
|
+
await registryAssistantChat(input({ client, toolCategories: categories, front: { categories: ['list-3'] } }))
|
|
153
|
+
|
|
154
|
+
expect(JSON.parse(seen[1].messages.at(-1).content[0].content)).toMatchObject({ opened: ['readList150'], alreadyOffered: ['readList3'] })
|
|
155
|
+
})
|
|
156
|
+
|
|
139
157
|
it('★ a tool called before it is opened does not run - the model is told to open it', async () => {
|
|
140
158
|
const categories = registerLists(165)
|
|
141
159
|
const { client, seen } = recordingClient([reply(undefined, [TC('readList150')]), reply('done')])
|
|
@@ -82,7 +82,14 @@ function oneLine(description: string | undefined): string {
|
|
|
82
82
|
export function openableToolCatalog(openable: ReadonlyArray<ToolSpec>): string {
|
|
83
83
|
if (openable.length === 0) return ''
|
|
84
84
|
return [
|
|
85
|
-
|
|
85
|
+
/*
|
|
86
|
+
* Office's model, offered a bank lines' total it could open, told the person that read was not open and asked them
|
|
87
|
+
* to pick a range (2026-10-22) - an app's prompt said a missing tool means a missing permission. What is on this
|
|
88
|
+
* list is the model's to use.
|
|
89
|
+
*/
|
|
90
|
+
`Tools you can open with ${OPEN_TOOLS} (name: what it does). They are yours to use in this conversation, only not loaded yet. ` +
|
|
91
|
+
`When the question needs one, open it with ${OPEN_TOOLS} and call it: never tell the person a tool on this list is missing, ` +
|
|
92
|
+
'and never ask the person to choose instead of opening it.',
|
|
86
93
|
...openable.map(spec => `- ${spec.name}: ${oneLine(spec.description)}`)
|
|
87
94
|
].join('\n')
|
|
88
95
|
}
|
|
@@ -119,6 +126,7 @@ export function toolOfferState(scope: ToolScope, front: ToolFront = {}) {
|
|
|
119
126
|
return { rejected: true, error: 'tool-not-offered', names: unknown, message: `these are not in the list of tools you can open: ${unknown.join(', ')}. Use the exact names from the list.` }
|
|
120
127
|
}
|
|
121
128
|
const fresh = [...new Set(names)].filter(name => !offered.has(name))
|
|
129
|
+
const already = [...new Set(names)].filter(name => offered.has(name) && name !== OPEN_TOOLS)
|
|
122
130
|
const room = MAX_OFFERED_TOOLS - offered.size
|
|
123
131
|
if (fresh.length > room) {
|
|
124
132
|
return {
|
|
@@ -130,7 +138,14 @@ export function toolOfferState(scope: ToolScope, front: ToolFront = {}) {
|
|
|
130
138
|
}
|
|
131
139
|
for (const name of fresh) offered.set(name, openable.get(name)!)
|
|
132
140
|
const guidance = [...new Set(fresh.map(name => categoryOf.get(name)?.guidance).filter(Boolean))]
|
|
133
|
-
return {
|
|
141
|
+
return {
|
|
142
|
+
opened: fresh,
|
|
143
|
+
...(already.length ? { alreadyOffered: already } : {}),
|
|
144
|
+
...(guidance.length ? { guidance: guidance.join('\n') } : {}),
|
|
145
|
+
message: already.length
|
|
146
|
+
? `${already.join(', ')} ${already.length > 1 ? 'are' : 'is'} already open - call ${already.length > 1 ? 'them' : 'it'} now. ${fresh.length ? 'The others are open from your next step on.' : ''}`.trim()
|
|
147
|
+
: 'these tools are open from your next step on. Call them as the question needs.'
|
|
148
|
+
}
|
|
134
149
|
}
|
|
135
150
|
|
|
136
151
|
return {
|
package/translations/ko.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"error.ai-not-configured": "이 사업장에는 AI 가 설정되어 있지 않습니다.",
|
|
3
3
|
"error.ai-agent-not-available": "선택한 AI 에이전트를 이 사업장에서 사용할 수 없습니다.",
|
|
4
|
-
"error.ai-agent-provider-unknown": "\"{provider}\"
|
|
4
|
+
"error.ai-agent-provider-unknown": "\"{provider}\"은(는) 에이전트에서 지원하지 않는 제공자입니다.",
|
|
5
5
|
"error.ai-agent-key-required": "\"{agent}\" 의 API 키를 입력해 주세요.",
|
|
6
6
|
"error.ai-agent-name-required": "에이전트마다 이름이 있어야 합니다.",
|
|
7
7
|
"error.ai-agent-model-required": "\"{agent}\" 의 모델을 선택해 주세요.",
|