freddie 0.0.117 → 0.0.118

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": "freddie",
3
- "version": "0.0.117",
3
+ "version": "0.0.118",
4
4
  "type": "module",
5
5
  "description": "Open JS agent harness built on pi-mono, floosie, xstate, and anentrypoint-design",
6
6
  "bin": {
@@ -121,7 +121,7 @@ function adaptResponse(r) {
121
121
 
122
122
  function tryParseJson(s) { try { return typeof s === 'string' ? JSON.parse(s) : (s || {}) } catch { return {} } }
123
123
 
124
- export async function isReachable(timeoutMs = 2000) {
124
+ export async function isReachable(timeoutMs = 10000) {
125
125
  try {
126
126
  const controller = new AbortController()
127
127
  const timeoutId = setTimeout(() => controller.abort(), timeoutMs)
@@ -55,7 +55,18 @@ export function createAgentMachine({ provider, model, maxIterations = 90, callLL
55
55
  input: ({ context }) => ({ messages: context.messages, model: context.model, provider: context.provider, enabledToolsets: context.enabledToolsets, disabledToolsets: context.disabledToolsets }),
56
56
  onDone: [
57
57
  { guard: ({ event }) => Array.isArray(event.output?.tool_calls) && event.output.tool_calls.length > 0, target: 'tool_calls', actions: assign({ messages: ({ context, event }) => [...context.messages, { role: 'assistant', content: event.output.content || '', tool_calls: event.output.tool_calls }] }) },
58
- { target: 'done', actions: assign({ messages: ({ context, event }) => [...context.messages, { role: 'assistant', content: event.output.content || '' }], lastResult: ({ event }) => event.output.content || '' }) },
58
+ { target: 'done', actions: assign({ messages: ({ context, event }) => [...context.messages, { role: 'assistant', content: event.output.content || '' }], lastResult: ({ context, event }) => {
59
+ // Prefer this turn's content, but if the model ended with empty
60
+ // text (it may have put its answer in an earlier turn alongside a
61
+ // tool_call), fall back to the last non-empty assistant message so
62
+ // the caller never gets an empty result after a successful run.
63
+ if (event.output.content && event.output.content.trim()) return event.output.content;
64
+ for (let i = context.messages.length - 1; i >= 0; i--) {
65
+ const m = context.messages[i];
66
+ if (m.role === 'assistant' && typeof m.content === 'string' && m.content.trim()) return m.content;
67
+ }
68
+ return event.output.content || '';
69
+ } }) },
59
70
  ],
60
71
  onError: { target: 'done', actions: assign({ error: ({ event }) => String(event.error?.message || event.error) }) },
61
72
  },