@lota-sdk/core 0.1.43 → 0.1.44
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lota-sdk/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.44",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@chat-adapter/slack": "^4.23.0",
|
|
33
33
|
"@chat-adapter/state-ioredis": "^4.23.0",
|
|
34
34
|
"@logtape/logtape": "^2.0.5",
|
|
35
|
-
"@lota-sdk/shared": "0.1.
|
|
35
|
+
"@lota-sdk/shared": "0.1.44",
|
|
36
36
|
"@mendable/firecrawl-js": "^4.18.0",
|
|
37
37
|
"@surrealdb/node": "^3.0.3",
|
|
38
38
|
"ai": "^6.0.141",
|
|
@@ -45,26 +45,48 @@ function extractJson(text: string): unknown {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/** Extract usable text from agent result — reasoning-only models put output in reasoning tokens */
|
|
49
|
+
function extractResultText(result: { text?: string; reasoning?: unknown }): string {
|
|
50
|
+
const text = typeof result.text === 'string' ? result.text : ''
|
|
51
|
+
if (text.trim()) return text
|
|
52
|
+
// Reasoning can be a string or an array of { type, text } objects
|
|
53
|
+
const reasoning = result.reasoning
|
|
54
|
+
if (typeof reasoning === 'string') return reasoning
|
|
55
|
+
if (Array.isArray(reasoning)) {
|
|
56
|
+
return reasoning
|
|
57
|
+
.map((r) => (typeof r === 'string' ? r : typeof r === 'object' && r && 'text' in r ? String(r.text) : ''))
|
|
58
|
+
.join('')
|
|
59
|
+
}
|
|
60
|
+
return ''
|
|
61
|
+
}
|
|
62
|
+
|
|
48
63
|
// ---------------------------------------------------------------------------
|
|
49
64
|
// Prompts
|
|
50
65
|
// ---------------------------------------------------------------------------
|
|
51
66
|
|
|
52
|
-
const TRIAGE_SYSTEM_PROMPT = `You are a workstream message router. Decide which team member should respond to the user message.
|
|
67
|
+
const TRIAGE_SYSTEM_PROMPT = `You are a workstream message router. Decide which team member should respond FIRST to the user message.
|
|
53
68
|
|
|
54
69
|
Rules:
|
|
55
70
|
- Pick the single best-fit agent from the members list based on domain expertise.
|
|
71
|
+
- If the user explicitly addresses an agent by name or role (e.g. "CTO: ..." or "CMO: ..."), route to that agent.
|
|
56
72
|
- If no specialist clearly matches (general chat, greetings, coordination), respond with agentId "".
|
|
57
73
|
- Be decisive. Reply with ONLY a JSON object, no other text.
|
|
58
74
|
|
|
59
75
|
Format: {"agentId":"<id>","routingContext":"<1-sentence instruction>"}`
|
|
60
76
|
|
|
61
|
-
const CHECK_SYSTEM_PROMPT = `You decide if another team member should
|
|
77
|
+
const CHECK_SYSTEM_PROMPT = `You decide if another team member should ALSO respond after the previous agent's response.
|
|
78
|
+
|
|
79
|
+
You will receive:
|
|
80
|
+
- The original user message
|
|
81
|
+
- Which agents already responded
|
|
82
|
+
- The last agent's actual response
|
|
83
|
+
- The remaining available agents
|
|
62
84
|
|
|
63
85
|
Rules:
|
|
64
|
-
-
|
|
65
|
-
- If the
|
|
66
|
-
- If the
|
|
67
|
-
- Do NOT add agents for agreement or
|
|
86
|
+
- If the user explicitly addressed multiple agents (e.g. "CTO: ... CMO: ...") and one hasn't responded yet, they MUST respond. Return done:false.
|
|
87
|
+
- If the last agent's response explicitly defers to or recommends another specialist, that specialist SHOULD respond. Return done:false.
|
|
88
|
+
- If there is a clearly separate dimension of the user's question not yet covered by any responded agent, add the best-fit remaining agent.
|
|
89
|
+
- Do NOT add agents just for agreement, acknowledgement, or minor additions.
|
|
68
90
|
- Reply with ONLY a JSON object, no other text.
|
|
69
91
|
|
|
70
92
|
Format: {"done":true} or {"done":false,"agentId":"<id>","routingContext":"<1-sentence>"}`
|
|
@@ -114,12 +136,8 @@ export async function triageWorkstreamMessage(params: {
|
|
|
114
136
|
return null
|
|
115
137
|
}
|
|
116
138
|
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
console.log('[workstream-router] triage raw text:', rawText.slice(0, 300))
|
|
120
|
-
console.log('[workstream-router] triage reasoning:', reasoning.slice(0, 300))
|
|
121
|
-
// Use reasoning as fallback if text is empty (reasoning-only models like gpt-oss-120b)
|
|
122
|
-
const effectiveText = rawText || reasoning
|
|
139
|
+
const effectiveText = extractResultText(result as { text?: string; reasoning?: unknown })
|
|
140
|
+
console.log('[workstream-router] triage raw:', effectiveText.slice(0, 300))
|
|
123
141
|
const json = extractJson(effectiveText)
|
|
124
142
|
const parsed = TriageResultSchema.safeParse(json)
|
|
125
143
|
if (!parsed.success) {
|
|
@@ -157,17 +175,35 @@ export async function checkForNextAgent(params: {
|
|
|
157
175
|
`Remaining members:\n${membersDesc}`,
|
|
158
176
|
`Already responded: ${respondedList}`,
|
|
159
177
|
`User message: "${params.messageText}"`,
|
|
160
|
-
`Last response
|
|
178
|
+
`Last agent response:\n"${params.lastResponseSummary}"`,
|
|
161
179
|
].join('\n\n')
|
|
162
180
|
|
|
163
181
|
const agent = createRouterAgent(CHECK_SYSTEM_PROMPT)
|
|
164
|
-
|
|
182
|
+
let result: Awaited<ReturnType<typeof agent.generate>>
|
|
183
|
+
try {
|
|
184
|
+
result = await agent.generate({ messages: [{ role: 'user', content: prompt }], timeout: { totalMs: 30_000 } })
|
|
185
|
+
} catch (error) {
|
|
186
|
+
console.error('[workstream-router] check failed:', error instanceof Error ? error.message : error)
|
|
187
|
+
return { done: true }
|
|
188
|
+
}
|
|
165
189
|
|
|
166
|
-
const
|
|
190
|
+
const effectiveText = extractResultText(result as { text?: string; reasoning?: unknown })
|
|
191
|
+
console.log('[workstream-router] check raw:', effectiveText.slice(0, 300))
|
|
192
|
+
const json = extractJson(effectiveText)
|
|
167
193
|
const parsed = CheckResultSchema.safeParse(json)
|
|
168
|
-
if (!parsed.success)
|
|
169
|
-
|
|
170
|
-
|
|
194
|
+
if (!parsed.success) {
|
|
195
|
+
console.log('[workstream-router] check parse failed:', JSON.stringify(parsed.error.issues))
|
|
196
|
+
return { done: true }
|
|
197
|
+
}
|
|
198
|
+
if (parsed.data.done) {
|
|
199
|
+
console.log('[workstream-router] check: done, no more agents needed')
|
|
200
|
+
return { done: true }
|
|
201
|
+
}
|
|
202
|
+
if (!parsed.data.agentId || !remainingMembers.includes(parsed.data.agentId)) {
|
|
203
|
+
console.log('[workstream-router] check: invalid agentId:', parsed.data.agentId)
|
|
204
|
+
return { done: true }
|
|
205
|
+
}
|
|
171
206
|
|
|
207
|
+
console.log('[workstream-router] check: next agent:', parsed.data.agentId)
|
|
172
208
|
return parsed.data
|
|
173
209
|
}
|