@recombine-ai/bosun 0.8.2 → 0.9.0

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.
Files changed (106) hide show
  1. package/bin/bosun.js +22 -0
  2. package/build/client/_app/immutable/chunks/{aFZ7RY4i.js → CAnrK2Rl.js} +1 -1
  3. package/build/client/_app/immutable/chunks/CAnrK2Rl.js.br +0 -0
  4. package/build/client/_app/immutable/chunks/CAnrK2Rl.js.gz +0 -0
  5. package/build/client/_app/immutable/chunks/{CYF48L9_.js → CD54oo-Q.js} +1 -1
  6. package/build/client/_app/immutable/chunks/CD54oo-Q.js.br +0 -0
  7. package/build/client/_app/immutable/chunks/CD54oo-Q.js.gz +0 -0
  8. package/build/client/_app/immutable/chunks/{2QZUjt52.js → DYY6aMTA.js} +1 -1
  9. package/build/client/_app/immutable/chunks/DYY6aMTA.js.br +0 -0
  10. package/build/client/_app/immutable/chunks/DYY6aMTA.js.gz +0 -0
  11. package/build/client/_app/immutable/entry/{app.CBFo0y_h.js → app.DoUqDuhT.js} +2 -2
  12. package/build/client/_app/immutable/entry/app.DoUqDuhT.js.br +0 -0
  13. package/build/client/_app/immutable/entry/app.DoUqDuhT.js.gz +0 -0
  14. package/build/client/_app/immutable/entry/start.Ck039vGm.js +1 -0
  15. package/build/client/_app/immutable/entry/start.Ck039vGm.js.br +2 -0
  16. package/build/client/_app/immutable/entry/start.Ck039vGm.js.gz +0 -0
  17. package/build/client/_app/immutable/nodes/{0.BS46Erbu.js → 0.DsSFrs8j.js} +1 -1
  18. package/build/client/_app/immutable/nodes/0.DsSFrs8j.js.br +0 -0
  19. package/build/client/_app/immutable/nodes/0.DsSFrs8j.js.gz +0 -0
  20. package/build/client/_app/immutable/nodes/{1.BkQc4vam.js → 1.mgTJXkii.js} +1 -1
  21. package/build/client/_app/immutable/nodes/1.mgTJXkii.js.br +0 -0
  22. package/build/client/_app/immutable/nodes/1.mgTJXkii.js.gz +0 -0
  23. package/build/client/_app/immutable/nodes/{17.C7bkiGOl.js → 17.CgqWHP0Y.js} +1 -1
  24. package/build/client/_app/immutable/nodes/17.CgqWHP0Y.js.br +0 -0
  25. package/build/client/_app/immutable/nodes/17.CgqWHP0Y.js.gz +0 -0
  26. package/build/client/_app/immutable/nodes/{18.CjBHM2ng.js → 18.BV7lLFx7.js} +1 -1
  27. package/build/client/_app/immutable/nodes/18.BV7lLFx7.js.br +0 -0
  28. package/build/client/_app/immutable/nodes/18.BV7lLFx7.js.gz +0 -0
  29. package/build/client/_app/immutable/nodes/{2.CAYQyVDJ.js → 2.COX-RTiI.js} +1 -1
  30. package/build/client/_app/immutable/nodes/2.COX-RTiI.js.br +0 -0
  31. package/build/client/_app/immutable/nodes/2.COX-RTiI.js.gz +0 -0
  32. package/build/client/_app/immutable/nodes/{3.CoWzFM8T.js → 3.CCDyeAHw.js} +1 -1
  33. package/build/client/_app/immutable/nodes/3.CCDyeAHw.js.br +0 -0
  34. package/build/client/_app/immutable/nodes/3.CCDyeAHw.js.gz +0 -0
  35. package/build/client/_app/immutable/nodes/{4.BC-cU8Pp.js → 4.Cd9dzHLx.js} +1 -1
  36. package/build/client/_app/immutable/nodes/4.Cd9dzHLx.js.br +0 -0
  37. package/build/client/_app/immutable/nodes/4.Cd9dzHLx.js.gz +0 -0
  38. package/build/client/_app/immutable/nodes/{6.D4x8Wh9M.js → 6.kgmUVW62.js} +1 -1
  39. package/build/client/_app/immutable/nodes/6.kgmUVW62.js.br +0 -0
  40. package/build/client/_app/immutable/nodes/6.kgmUVW62.js.gz +0 -0
  41. package/build/client/_app/immutable/nodes/{9.BwiEOYkX.js → 9.DatTKw7a.js} +1 -1
  42. package/build/client/_app/immutable/nodes/9.DatTKw7a.js.br +0 -0
  43. package/build/client/_app/immutable/nodes/9.DatTKw7a.js.gz +0 -0
  44. package/build/client/_app/version.json +1 -1
  45. package/build/client/_app/version.json.br +0 -0
  46. package/build/client/_app/version.json.gz +0 -0
  47. package/build/server/chunks/{0-6QwqOuSN.js → 0-CXtwDtnz.js} +2 -2
  48. package/build/server/chunks/{0-6QwqOuSN.js.map → 0-CXtwDtnz.js.map} +1 -1
  49. package/build/server/chunks/{1-BqEYCSqb.js → 1-D6-Ps83z.js} +2 -2
  50. package/build/server/chunks/{1-BqEYCSqb.js.map → 1-D6-Ps83z.js.map} +1 -1
  51. package/build/server/chunks/{17-C5jRC6rL.js → 17-CH4MLdY7.js} +2 -2
  52. package/build/server/chunks/{17-C5jRC6rL.js.map → 17-CH4MLdY7.js.map} +1 -1
  53. package/build/server/chunks/{18-BzERVoaR.js → 18-C48_VgcC.js} +2 -2
  54. package/build/server/chunks/{18-BzERVoaR.js.map → 18-C48_VgcC.js.map} +1 -1
  55. package/build/server/chunks/{2-DTdewCMV.js → 2-CSbZQChk.js} +2 -2
  56. package/build/server/chunks/{2-DTdewCMV.js.map → 2-CSbZQChk.js.map} +1 -1
  57. package/build/server/chunks/{3-Xnzo0PPo.js → 3-DMPvS2tl.js} +2 -2
  58. package/build/server/chunks/{3-Xnzo0PPo.js.map → 3-DMPvS2tl.js.map} +1 -1
  59. package/build/server/chunks/{4-BKFeDeOj.js → 4-DJMua_Cs.js} +2 -2
  60. package/build/server/chunks/{4-BKFeDeOj.js.map → 4-DJMua_Cs.js.map} +1 -1
  61. package/build/server/chunks/{6-CYC178cM.js → 6-BdiDB4wj.js} +2 -2
  62. package/build/server/chunks/{6-CYC178cM.js.map → 6-BdiDB4wj.js.map} +1 -1
  63. package/build/server/chunks/{9-COYHphb5.js → 9-BtgYu4El.js} +2 -2
  64. package/build/server/chunks/{9-COYHphb5.js.map → 9-BtgYu4El.js.map} +1 -1
  65. package/build/server/index.js +1 -1
  66. package/build/server/index.js.map +1 -1
  67. package/build/server/manifest.js +10 -10
  68. package/build/server/manifest.js.map +1 -1
  69. package/package.json +4 -2
  70. package/src/backend/lib/get-agent-factories.ts +1 -1
  71. package/src/backend/roleplay/agents.ts +19 -43
  72. package/src/backend/roleplay/message-dispatcher.ts +5 -9
  73. package/src/backend/roleplay/router.ts +8 -6
  74. package/src/backend/roleplay/scheduler.ts +2 -15
  75. package/src/backend/roleplay/variants.ts +11 -26
  76. package/src/backend/tests/academy.ts +1 -21
  77. package/src/backend/tests/emulate-agents.ts +66 -76
  78. package/build/client/_app/immutable/chunks/2QZUjt52.js.br +0 -0
  79. package/build/client/_app/immutable/chunks/2QZUjt52.js.gz +0 -0
  80. package/build/client/_app/immutable/chunks/CYF48L9_.js.br +0 -0
  81. package/build/client/_app/immutable/chunks/CYF48L9_.js.gz +0 -0
  82. package/build/client/_app/immutable/chunks/aFZ7RY4i.js.br +0 -0
  83. package/build/client/_app/immutable/chunks/aFZ7RY4i.js.gz +0 -0
  84. package/build/client/_app/immutable/entry/app.CBFo0y_h.js.br +0 -0
  85. package/build/client/_app/immutable/entry/app.CBFo0y_h.js.gz +0 -0
  86. package/build/client/_app/immutable/entry/start.B7Oj0YZC.js +0 -1
  87. package/build/client/_app/immutable/entry/start.B7Oj0YZC.js.br +0 -2
  88. package/build/client/_app/immutable/entry/start.B7Oj0YZC.js.gz +0 -0
  89. package/build/client/_app/immutable/nodes/0.BS46Erbu.js.br +0 -0
  90. package/build/client/_app/immutable/nodes/0.BS46Erbu.js.gz +0 -0
  91. package/build/client/_app/immutable/nodes/1.BkQc4vam.js.br +0 -0
  92. package/build/client/_app/immutable/nodes/1.BkQc4vam.js.gz +0 -0
  93. package/build/client/_app/immutable/nodes/17.C7bkiGOl.js.br +0 -0
  94. package/build/client/_app/immutable/nodes/17.C7bkiGOl.js.gz +0 -0
  95. package/build/client/_app/immutable/nodes/18.CjBHM2ng.js.br +0 -0
  96. package/build/client/_app/immutable/nodes/18.CjBHM2ng.js.gz +0 -0
  97. package/build/client/_app/immutable/nodes/2.CAYQyVDJ.js.br +0 -0
  98. package/build/client/_app/immutable/nodes/2.CAYQyVDJ.js.gz +0 -0
  99. package/build/client/_app/immutable/nodes/3.CoWzFM8T.js.br +0 -0
  100. package/build/client/_app/immutable/nodes/3.CoWzFM8T.js.gz +0 -0
  101. package/build/client/_app/immutable/nodes/4.BC-cU8Pp.js.br +0 -0
  102. package/build/client/_app/immutable/nodes/4.BC-cU8Pp.js.gz +0 -0
  103. package/build/client/_app/immutable/nodes/6.D4x8Wh9M.js.br +0 -0
  104. package/build/client/_app/immutable/nodes/6.D4x8Wh9M.js.gz +0 -0
  105. package/build/client/_app/immutable/nodes/9.BwiEOYkX.js.br +0 -0
  106. package/build/client/_app/immutable/nodes/9.BwiEOYkX.js.gz +0 -0
@@ -1,11 +1,6 @@
1
- import {
2
- createContext,
3
- type Message,
4
- type StepTracer,
5
- type Logger,
6
- type TestAgent,
7
- type TestVoiceAgent
8
- } from '@recombine-ai/engine'
1
+ import { createContext, type Message, type Logger, type Scheduler } from '@recombine-ai/engine'
2
+ import { type TestAgent, type TestVoiceAgent } from '@recombine-ai/bosun-lib'
3
+ import { type StepTracer } from '@recombine-ai/telescope'
9
4
  import { getAgentFactories } from '../lib/get-agent-factories'
10
5
  import { getImportNonce } from '../lib/import-nonce'
11
6
  import { getRootPath } from '../lib/get-root-path'
@@ -17,8 +12,7 @@ export async function loadAgents(props: {
17
12
  sendMessage: (message: Message | string) => Promise<void>
18
13
  stepTracer: StepTracer
19
14
  logger?: Logger
20
- context?: Record<string, any>
21
- timeoutSeconds: number
15
+ context?: Record<string, unknown>
22
16
  abortSignal?: AbortSignal
23
17
  }): Promise<void> {
24
18
  const {
@@ -29,7 +23,6 @@ export async function loadAgents(props: {
29
23
  stepTracer: stepTracer,
30
24
  logger: providedLogger,
31
25
  context,
32
- timeoutSeconds,
33
26
  abortSignal
34
27
  } = props
35
28
  const importNonce = getImportNonce()
@@ -44,34 +37,20 @@ export async function loadAgents(props: {
44
37
  error: () => {},
45
38
  warn: () => {}
46
39
  }
47
- const scheduler = {
40
+ const scheduler: Scheduler = {
48
41
  clearAllPendingActions: async () => {},
49
- registerAction: () => async () => {},
50
- triggerAction: async () => {},
51
- serialize: () => ({}) as any,
52
- setState: (_: any) => {}
53
- }
54
- const ctx = createContext({})
55
-
56
- // Maintain in-run history so sendMessage appends to it, mirroring backend behavior
57
- const history = getMessages()
58
- const getMessagesWithHistory = () => history
59
- const sendMessageWithHistory = async (message: Message | string) => {
60
- const m =
61
- typeof message === 'string' ? ({ sender: 'agent', text: message } as Message) : message
62
- try {
63
- history.push(m)
64
- } catch {
65
- // Best-effort: if history is immutable, ignore push errors
66
- logger.log('Failed to push message to history:', m)
67
- }
68
- await sendMessage(m)
42
+ registerAction: () => async () => {}
69
43
  }
70
44
 
71
45
  const stepRegistry = {
72
46
  addStep: () => {}
73
47
  }
74
48
 
49
+ const ctx = createContext({})
50
+
51
+ // Maintain in-run history so sendMessage appends to it, mirroring backend behavior
52
+ let history: Message[] = []
53
+
75
54
  if (region) {
76
55
  // The UI-selected region is stored in Bosun's runtime ctx and consumed by the project's workflows.
77
56
  // Setting it before calling the factory ensures region-scoped config/strings are used for this run.
@@ -82,13 +61,25 @@ export async function loadAgents(props: {
82
61
  const agent = await factory({
83
62
  stepTracer: stepTracer,
84
63
  stepRegistry,
85
- tracer: stepRegistry,
86
64
  logger: logger,
87
- scheduler: scheduler as any,
88
- getMessages: getMessagesWithHistory,
89
- sendMessage: sendMessageWithHistory,
90
- sendAction: async () => {},
91
- ctx
65
+ scheduler: scheduler,
66
+ getMessages: () => history,
67
+ async sendMessage(message) {
68
+ const m =
69
+ typeof message === 'string' ? ({ sender: 'agent', text: message } as Message) : message
70
+ try {
71
+ history.push(m)
72
+ } catch {
73
+ // Best-effort: if history is immutable, ignore push errors
74
+ logger.log('Failed to push message to history:', m)
75
+ }
76
+ await sendMessage(m)
77
+ },
78
+ ctx,
79
+ config: {
80
+ isTest: true,
81
+ enableTimers: false
82
+ }
92
83
  })
93
84
 
94
85
  if (context && typeof context === 'object') {
@@ -100,7 +91,42 @@ export async function loadAgents(props: {
100
91
  console.error('UNHANDLED', r)
101
92
  })
102
93
 
103
- const withAbort = async <T>(p: Promise<T>): Promise<T> => {
94
+ const withAbort = wrapAbort(abortSignal)
95
+
96
+ process.env.IS_TEST = 'true'
97
+ try {
98
+ if (isVoiceAgent(agent)) {
99
+ // preparation
100
+ history = []
101
+ await withAbort(agent.onCallStart())
102
+ await withAbort(agent.waitForIdle())
103
+
104
+ // actual test
105
+ history = getMessages()
106
+ await withAbort(agent.streamResponse())
107
+ await withAbort(agent.waitForIdle())
108
+ } else {
109
+ await withAbort(agent.start())
110
+ await withAbort(agent.respondToMessage())
111
+ }
112
+ } catch (err) {
113
+ const error = err instanceof Error ? err : new Error(String(err))
114
+ try {
115
+ logger.error('Error in agent.respondToMessage():', error.message)
116
+ if (error.stack) logger.error(error.stack)
117
+ } catch {
118
+ /* noop */
119
+ }
120
+ }
121
+ process.env.IS_TEST = undefined
122
+ }
123
+
124
+ function isVoiceAgent(agent: TestAgent): agent is TestVoiceAgent {
125
+ return 'streamResponse' in agent
126
+ }
127
+
128
+ function wrapAbort(abortSignal: AbortSignal | undefined) {
129
+ return async <T>(p: Promise<T>): Promise<T> => {
104
130
  if (!abortSignal) return p
105
131
  if (abortSignal.aborted) throw new Error('Operation cancelled')
106
132
  return await new Promise<T>((resolve, reject) => {
@@ -127,45 +153,9 @@ export async function loadAgents(props: {
127
153
  },
128
154
  (e) => {
129
155
  cleanup()
130
- reject(e)
156
+ reject(e as Error)
131
157
  }
132
158
  )
133
159
  })
134
160
  }
135
-
136
- try {
137
- if (hasStart(agent)) {
138
- // Some project workflows (e.g. voice) persist required per-run state (like region) during `start()`.
139
- await withAbort(Promise.resolve().then(() => agent.start()))
140
- }
141
- if (isVoiceAgent(agent)) {
142
- await withAbort(agent.streamResponse())
143
- } else {
144
- await withAbort(agent.respondToMessage())
145
- }
146
- await withAbort(new Promise((resolve) => setTimeout(resolve, timeoutSeconds * 1000)))
147
- } catch (err) {
148
- const msg = err instanceof Error ? `${err.name}: ${err.message}` : String(err)
149
- const stack = err instanceof Error ? err.stack : undefined
150
- try {
151
- logger.error('Error in agent.respondToMessage():', msg)
152
- } catch {
153
- /* noop */
154
- }
155
- if (stack) {
156
- try {
157
- logger.error(stack)
158
- } catch {
159
- /* noop */
160
- }
161
- }
162
- }
163
- }
164
-
165
- function isVoiceAgent(agent: TestAgent): agent is TestVoiceAgent {
166
- return 'streamResponse' in agent
167
- }
168
-
169
- function hasStart(agent: TestAgent): agent is TestAgent & { start: () => Promise<void> | void } {
170
- return typeof (agent as { start?: unknown }).start === 'function'
171
161
  }
@@ -1 +0,0 @@
1
- import{l as o,a as r}from"../chunks/CYF48L9_.js";export{o as load_css,r as start};
@@ -1,2 +0,0 @@
1
- )�import{l as o,a as r}from"../chunks/CYF48L9_.js";export{o as load_css,r as start};
2
-