@positronic/spec 0.0.67 → 0.0.69

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.
@@ -123,39 +123,43 @@ function _ts_generator(thisArg, body) {
123
123
  }
124
124
  }
125
125
  import { STATUS, BRAIN_EVENTS } from '@positronic/core';
126
+ import { startBrainRun, readSseUntil } from './helpers.js';
126
127
  export var brains = {
127
128
  run: /**
128
129
  * Test POST /brains/runs - Create a new brain run
129
130
  */ function run(fetch, identifier, options) {
130
131
  return _async_to_generator(function() {
131
- var body, request, response, data, error;
132
+ var request, response, data, error;
132
133
  return _ts_generator(this, function(_state) {
133
134
  switch(_state.label){
134
135
  case 0:
135
- _state.trys.push([
136
- 0,
136
+ if (!(options && Object.keys(options).length > 0)) return [
137
137
  3,
138
+ 5
139
+ ];
140
+ _state.label = 1;
141
+ case 1:
142
+ _state.trys.push([
143
+ 1,
144
+ 4,
138
145
  ,
139
- 4
146
+ 5
140
147
  ]);
141
- body = {
142
- identifier: identifier
143
- };
144
- if (options && Object.keys(options).length > 0) {
145
- body.options = options;
146
- }
147
148
  request = new Request('http://example.com/brains/runs', {
148
149
  method: 'POST',
149
150
  headers: {
150
151
  'Content-Type': 'application/json'
151
152
  },
152
- body: JSON.stringify(body)
153
+ body: JSON.stringify({
154
+ identifier: identifier,
155
+ options: options
156
+ })
153
157
  });
154
158
  return [
155
159
  4,
156
160
  fetch(request)
157
161
  ];
158
- case 1:
162
+ case 2:
159
163
  response = _state.sent();
160
164
  if (response.status !== 201) {
161
165
  console.error("POST /brains/runs returned ".concat(response.status, ", expected 201"));
@@ -168,7 +172,7 @@ export var brains = {
168
172
  4,
169
173
  response.json()
170
174
  ];
171
- case 2:
175
+ case 3:
172
176
  data = _state.sent();
173
177
  if (!data.brainRunId || typeof data.brainRunId !== 'string') {
174
178
  console.error("Expected brainRunId to be string, got ".concat(_type_of(data.brainRunId)));
@@ -181,16 +185,17 @@ export var brains = {
181
185
  2,
182
186
  data.brainRunId
183
187
  ];
184
- case 3:
188
+ case 4:
185
189
  error = _state.sent();
186
190
  console.error("Failed to test POST /brains/runs:", error);
187
191
  return [
188
192
  2,
189
193
  null
190
194
  ];
191
- case 4:
195
+ case 5:
192
196
  return [
193
- 2
197
+ 2,
198
+ startBrainRun(fetch, identifier)
194
199
  ];
195
200
  }
196
201
  });
@@ -1544,45 +1549,26 @@ export var brains = {
1544
1549
  * Requires a brain with a loop step that will pause on a webhook.
1545
1550
  */ function killSuspended(fetch, loopBrainIdentifier, webhookSlug, webhookPayload) {
1546
1551
  return _async_to_generator(function() {
1547
- var runRequest, runResponse, brainRunId, watchRequest, watchResponse, foundWebhookEvent, reader, decoder, buffer, _ref, value, done, eventEndIndex, message, event, killRequest, killResponse, getRunRequest, getRunResponse, runData, webhookRequest, webhookResponse, webhookResult, finalCheckRequest, finalCheckResponse, finalRunData, error;
1552
+ var brainRunId, watchRequest, watchResponse, earlyTermination, events, foundWebhookEvent, killRequest, killResponse, getRunRequest, getRunResponse, runData, webhookRequest, webhookResponse, webhookResult, finalCheckRequest, finalCheckResponse, finalRunData, error;
1548
1553
  return _ts_generator(this, function(_state) {
1549
1554
  switch(_state.label){
1550
1555
  case 0:
1551
1556
  _state.trys.push([
1552
1557
  0,
1553
- 18,
1558
+ 11,
1554
1559
  ,
1555
- 19
1560
+ 12
1556
1561
  ]);
1557
- // Step 1: Start the loop brain
1558
- runRequest = new Request('http://example.com/brains/runs', {
1559
- method: 'POST',
1560
- headers: {
1561
- 'Content-Type': 'application/json'
1562
- },
1563
- body: JSON.stringify({
1564
- identifier: loopBrainIdentifier
1565
- })
1566
- });
1567
1562
  return [
1568
1563
  4,
1569
- fetch(runRequest)
1564
+ startBrainRun(fetch, loopBrainIdentifier)
1570
1565
  ];
1571
1566
  case 1:
1572
- runResponse = _state.sent();
1573
- if (runResponse.status !== 201) {
1574
- console.error("POST /brains/runs returned ".concat(runResponse.status, ", expected 201"));
1575
- return [
1576
- 2,
1577
- false
1578
- ];
1579
- }
1580
- return [
1581
- 4,
1582
- runResponse.json()
1567
+ brainRunId = _state.sent();
1568
+ if (!brainRunId) return [
1569
+ 2,
1570
+ false
1583
1571
  ];
1584
- case 2:
1585
- brainRunId = _state.sent().brainRunId;
1586
1572
  // Step 2: Watch until WEBHOOK event (brain pauses)
1587
1573
  watchRequest = new Request("http://example.com/brains/runs/".concat(brainRunId, "/watch"), {
1588
1574
  method: 'GET'
@@ -1591,7 +1577,7 @@ export var brains = {
1591
1577
  4,
1592
1578
  fetch(watchRequest)
1593
1579
  ];
1594
- case 3:
1580
+ case 2:
1595
1581
  watchResponse = _state.sent();
1596
1582
  if (!watchResponse.ok) {
1597
1583
  console.error("GET /brains/runs/".concat(brainRunId, "/watch returned ").concat(watchResponse.status));
@@ -1600,84 +1586,35 @@ export var brains = {
1600
1586
  false
1601
1587
  ];
1602
1588
  }
1603
- foundWebhookEvent = false;
1604
- if (!watchResponse.body) return [
1605
- 3,
1606
- 10
1607
- ];
1608
- reader = watchResponse.body.getReader();
1609
- decoder = new TextDecoder();
1610
- buffer = '';
1611
- _state.label = 4;
1612
- case 4:
1613
- _state.trys.push([
1614
- 4,
1615
- ,
1616
- 8,
1617
- 10
1618
- ]);
1619
- _state.label = 5;
1620
- case 5:
1621
- if (!!foundWebhookEvent) return [
1622
- 3,
1623
- 7
1624
- ];
1625
- return [
1626
- 4,
1627
- reader.read()
1628
- ];
1629
- case 6:
1630
- _ref = _state.sent(), value = _ref.value, done = _ref.done;
1631
- if (done) return [
1632
- 3,
1633
- 7
1634
- ];
1635
- buffer += decoder.decode(value, {
1636
- stream: true
1637
- });
1638
- eventEndIndex = void 0;
1639
- while((eventEndIndex = buffer.indexOf('\n\n')) !== -1){
1640
- message = buffer.substring(0, eventEndIndex);
1641
- buffer = buffer.substring(eventEndIndex + 2);
1642
- if (message.startsWith('data: ')) {
1643
- try {
1644
- event = JSON.parse(message.substring(6));
1645
- if (event.type === BRAIN_EVENTS.WEBHOOK) {
1646
- foundWebhookEvent = true;
1647
- break;
1648
- }
1649
- if (event.type === BRAIN_EVENTS.COMPLETE || event.type === BRAIN_EVENTS.ERROR) {
1650
- console.error("Brain completed/errored before WEBHOOK event: ".concat(event.type));
1651
- return [
1652
- 2,
1653
- false
1654
- ];
1655
- }
1656
- } catch (e) {
1657
- // Ignore parse errors
1658
- }
1659
- }
1589
+ if (!watchResponse.body) {
1590
+ console.error('Watch response has no body');
1591
+ return [
1592
+ 2,
1593
+ false
1594
+ ];
1660
1595
  }
1661
- return [
1662
- 3,
1663
- 5
1664
- ];
1665
- case 7:
1666
- return [
1667
- 3,
1668
- 10
1669
- ];
1670
- case 8:
1596
+ earlyTermination = false;
1671
1597
  return [
1672
1598
  4,
1673
- reader.cancel()
1599
+ readSseUntil(watchResponse.body, function(event) {
1600
+ if (event.type === BRAIN_EVENTS.WEBHOOK) return true;
1601
+ if (event.type === BRAIN_EVENTS.COMPLETE || event.type === BRAIN_EVENTS.ERROR) {
1602
+ console.error("Brain completed/errored before WEBHOOK event: ".concat(event.type));
1603
+ earlyTermination = true;
1604
+ return true;
1605
+ }
1606
+ return false;
1607
+ })
1674
1608
  ];
1675
- case 9:
1676
- _state.sent();
1677
- return [
1678
- 7
1609
+ case 3:
1610
+ events = _state.sent();
1611
+ if (earlyTermination) return [
1612
+ 2,
1613
+ false
1679
1614
  ];
1680
- case 10:
1615
+ foundWebhookEvent = events.some(function(e) {
1616
+ return e.type === BRAIN_EVENTS.WEBHOOK;
1617
+ });
1681
1618
  if (!foundWebhookEvent) {
1682
1619
  console.error('Brain did not emit WEBHOOK event');
1683
1620
  return [
@@ -1693,7 +1630,7 @@ export var brains = {
1693
1630
  4,
1694
1631
  fetch(killRequest)
1695
1632
  ];
1696
- case 11:
1633
+ case 4:
1697
1634
  killResponse = _state.sent();
1698
1635
  if (killResponse.status !== 204) {
1699
1636
  console.error("DELETE /brains/runs/".concat(brainRunId, " returned ").concat(killResponse.status, ", expected 204"));
@@ -1710,7 +1647,7 @@ export var brains = {
1710
1647
  4,
1711
1648
  fetch(getRunRequest)
1712
1649
  ];
1713
- case 12:
1650
+ case 5:
1714
1651
  getRunResponse = _state.sent();
1715
1652
  if (!getRunResponse.ok) {
1716
1653
  console.error("GET /brains/runs/".concat(brainRunId, " returned ").concat(getRunResponse.status));
@@ -1723,7 +1660,7 @@ export var brains = {
1723
1660
  4,
1724
1661
  getRunResponse.json()
1725
1662
  ];
1726
- case 13:
1663
+ case 6:
1727
1664
  runData = _state.sent();
1728
1665
  if (runData.status !== STATUS.CANCELLED) {
1729
1666
  console.error("Expected status to be '".concat(STATUS.CANCELLED, "', got '").concat(runData.status, "'"));
@@ -1745,7 +1682,7 @@ export var brains = {
1745
1682
  4,
1746
1683
  fetch(webhookRequest)
1747
1684
  ];
1748
- case 14:
1685
+ case 7:
1749
1686
  webhookResponse = _state.sent();
1750
1687
  // Accept 200/202 - the important thing is it doesn't resume the brain
1751
1688
  if (!webhookResponse.ok) {
@@ -1759,7 +1696,7 @@ export var brains = {
1759
1696
  4,
1760
1697
  webhookResponse.json()
1761
1698
  ];
1762
- case 15:
1699
+ case 8:
1763
1700
  webhookResult = _state.sent();
1764
1701
  // The action should be 'no-match' since webhook registrations were cleared
1765
1702
  if (webhookResult.action === 'resumed') {
@@ -1777,7 +1714,7 @@ export var brains = {
1777
1714
  4,
1778
1715
  fetch(finalCheckRequest)
1779
1716
  ];
1780
- case 16:
1717
+ case 9:
1781
1718
  finalCheckResponse = _state.sent();
1782
1719
  if (!finalCheckResponse.ok) {
1783
1720
  console.error("Final GET /brains/runs/".concat(brainRunId, " returned ").concat(finalCheckResponse.status));
@@ -1790,7 +1727,7 @@ export var brains = {
1790
1727
  4,
1791
1728
  finalCheckResponse.json()
1792
1729
  ];
1793
- case 17:
1730
+ case 10:
1794
1731
  finalRunData = _state.sent();
1795
1732
  if (finalRunData.status !== STATUS.CANCELLED) {
1796
1733
  console.error("Final status check: expected '".concat(STATUS.CANCELLED, "', got '").concat(finalRunData.status, "'"));
@@ -1803,14 +1740,14 @@ export var brains = {
1803
1740
  2,
1804
1741
  true
1805
1742
  ];
1806
- case 18:
1743
+ case 11:
1807
1744
  error = _state.sent();
1808
1745
  console.error("Failed to test kill suspended brain for ".concat(loopBrainIdentifier, ":"), error);
1809
1746
  return [
1810
1747
  2,
1811
1748
  false
1812
1749
  ];
1813
- case 19:
1750
+ case 12:
1814
1751
  return [
1815
1752
  2
1816
1753
  ];
@@ -1830,45 +1767,26 @@ export var brains = {
1830
1767
  * - WEBHOOK
1831
1768
  */ function watchAgentEvents(fetch, agentBrainIdentifier) {
1832
1769
  return _async_to_generator(function() {
1833
- var runRequest, runResponse, brainRunId, watchRequest, watchResponse, events, reader, decoder, buffer, done, _ref, value, streamDone, eventEndIndex, message, event, hasAgentStart, agentStartEvent, hasAgentIteration, hasAgentToolCall, webhookIndex, agentWebhookIndex, agentWebhookEvent, error;
1770
+ var brainRunId, watchRequest, watchResponse, events, _tmp, hasAgentStart, agentStartEvent, hasAgentIteration, hasAgentToolCall, webhookIndex, agentWebhookIndex, agentWebhookEvent, error;
1834
1771
  return _ts_generator(this, function(_state) {
1835
1772
  switch(_state.label){
1836
1773
  case 0:
1837
1774
  _state.trys.push([
1838
1775
  0,
1839
- 11,
1776
+ 6,
1840
1777
  ,
1841
- 12
1778
+ 7
1842
1779
  ]);
1843
- // Start the agent brain
1844
- runRequest = new Request('http://example.com/brains/runs', {
1845
- method: 'POST',
1846
- headers: {
1847
- 'Content-Type': 'application/json'
1848
- },
1849
- body: JSON.stringify({
1850
- identifier: agentBrainIdentifier
1851
- })
1852
- });
1853
1780
  return [
1854
1781
  4,
1855
- fetch(runRequest)
1782
+ startBrainRun(fetch, agentBrainIdentifier)
1856
1783
  ];
1857
1784
  case 1:
1858
- runResponse = _state.sent();
1859
- if (runResponse.status !== 201) {
1860
- console.error("POST /brains/runs returned ".concat(runResponse.status, ", expected 201"));
1861
- return [
1862
- 2,
1863
- false
1864
- ];
1865
- }
1866
- return [
1867
- 4,
1868
- runResponse.json()
1785
+ brainRunId = _state.sent();
1786
+ if (!brainRunId) return [
1787
+ 2,
1788
+ false
1869
1789
  ];
1870
- case 2:
1871
- brainRunId = _state.sent().brainRunId;
1872
1790
  // Watch the brain run
1873
1791
  watchRequest = new Request("http://example.com/brains/runs/".concat(brainRunId, "/watch"), {
1874
1792
  method: 'GET'
@@ -1877,7 +1795,7 @@ export var brains = {
1877
1795
  4,
1878
1796
  fetch(watchRequest)
1879
1797
  ];
1880
- case 3:
1798
+ case 2:
1881
1799
  watchResponse = _state.sent();
1882
1800
  if (!watchResponse.ok) {
1883
1801
  console.error("GET /brains/runs/".concat(brainRunId, "/watch returned ").concat(watchResponse.status));
@@ -1886,82 +1804,27 @@ export var brains = {
1886
1804
  false
1887
1805
  ];
1888
1806
  }
1889
- // Read SSE events until we get WEBHOOK or COMPLETE/ERROR
1890
- events = [];
1891
1807
  if (!watchResponse.body) return [
1892
1808
  3,
1893
- 10
1894
- ];
1895
- reader = watchResponse.body.getReader();
1896
- decoder = new TextDecoder();
1897
- buffer = '';
1898
- done = false;
1899
- _state.label = 4;
1900
- case 4:
1901
- _state.trys.push([
1902
- 4,
1903
- ,
1904
- 8,
1905
- 10
1906
- ]);
1907
- _state.label = 5;
1908
- case 5:
1909
- if (!!done) return [
1910
- 3,
1911
- 7
1809
+ 4
1912
1810
  ];
1913
1811
  return [
1914
1812
  4,
1915
- reader.read()
1916
- ];
1917
- case 6:
1918
- _ref = _state.sent(), value = _ref.value, streamDone = _ref.done;
1919
- if (streamDone) return [
1920
- 3,
1921
- 7
1813
+ readSseUntil(watchResponse.body, function(event) {
1814
+ return event.type === BRAIN_EVENTS.WEBHOOK || event.type === BRAIN_EVENTS.COMPLETE || event.type === BRAIN_EVENTS.ERROR;
1815
+ })
1922
1816
  ];
1923
- buffer += decoder.decode(value, {
1924
- stream: true
1925
- });
1926
- // Process complete SSE messages
1927
- eventEndIndex = void 0;
1928
- while((eventEndIndex = buffer.indexOf('\n\n')) !== -1){
1929
- message = buffer.substring(0, eventEndIndex);
1930
- buffer = buffer.substring(eventEndIndex + 2);
1931
- if (message.startsWith('data: ')) {
1932
- try {
1933
- event = JSON.parse(message.substring(6));
1934
- events.push(event);
1935
- // Stop on terminal events
1936
- if (event.type === BRAIN_EVENTS.WEBHOOK || event.type === BRAIN_EVENTS.COMPLETE || event.type === BRAIN_EVENTS.ERROR) {
1937
- done = true;
1938
- break;
1939
- }
1940
- } catch (e) {
1941
- // Ignore parse errors
1942
- }
1943
- }
1944
- }
1817
+ case 3:
1818
+ _tmp = _state.sent();
1945
1819
  return [
1946
1820
  3,
1947
1821
  5
1948
1822
  ];
1949
- case 7:
1950
- return [
1951
- 3,
1952
- 10
1953
- ];
1954
- case 8:
1955
- return [
1956
- 4,
1957
- reader.cancel()
1958
- ];
1959
- case 9:
1960
- _state.sent();
1961
- return [
1962
- 7
1963
- ];
1964
- case 10:
1823
+ case 4:
1824
+ _tmp = [];
1825
+ _state.label = 5;
1826
+ case 5:
1827
+ events = _tmp;
1965
1828
  // Verify required agent events are present
1966
1829
  hasAgentStart = events.some(function(e) {
1967
1830
  return e.type === BRAIN_EVENTS.AGENT_START;
@@ -2040,14 +1903,14 @@ export var brains = {
2040
1903
  2,
2041
1904
  true
2042
1905
  ];
2043
- case 11:
1906
+ case 6:
2044
1907
  error = _state.sent();
2045
1908
  console.error("Failed to test agent events for ".concat(agentBrainIdentifier, ":"), error);
2046
1909
  return [
2047
1910
  2,
2048
1911
  false
2049
1912
  ];
2050
- case 12:
1913
+ case 7:
2051
1914
  return [
2052
1915
  2
2053
1916
  ];
@@ -2067,45 +1930,26 @@ export var brains = {
2067
1930
  * - The webhook slug and identifier to trigger
2068
1931
  */ function agentWebhookResume(fetch, agentBrainIdentifier, webhookSlug, webhookPayload) {
2069
1932
  return _async_to_generator(function() {
2070
- var runRequest, runResponse, brainRunId, watchRequest, watchResponse, foundWebhookEvent, reader, decoder, buffer, _ref, value, done, eventEndIndex, message, event, webhookRequest, webhookResponse, webhookResult, resumeWatchRequest, resumeWatchResponse, resumeEvents, reader1, decoder1, buffer1, done1, _ref1, value1, streamDone, eventEndIndex1, message1, event1, hasWebhookResponse, hasAgentToolResult, completeEvent, error;
1933
+ var brainRunId, watchRequest, watchResponse, earlyTermination, watchEvents, foundWebhookEvent, webhookRequest, webhookResponse, webhookResult, resumeWatchRequest, resumeWatchResponse, resumeEvents, _tmp, hasWebhookResponse, hasAgentToolResult, completeEvent, error;
2071
1934
  return _ts_generator(this, function(_state) {
2072
1935
  switch(_state.label){
2073
1936
  case 0:
2074
1937
  _state.trys.push([
2075
1938
  0,
2076
- 21,
1939
+ 10,
2077
1940
  ,
2078
- 22
1941
+ 11
2079
1942
  ]);
2080
- // Step 1: Start the agent brain
2081
- runRequest = new Request('http://example.com/brains/runs', {
2082
- method: 'POST',
2083
- headers: {
2084
- 'Content-Type': 'application/json'
2085
- },
2086
- body: JSON.stringify({
2087
- identifier: agentBrainIdentifier
2088
- })
2089
- });
2090
1943
  return [
2091
1944
  4,
2092
- fetch(runRequest)
1945
+ startBrainRun(fetch, agentBrainIdentifier)
2093
1946
  ];
2094
1947
  case 1:
2095
- runResponse = _state.sent();
2096
- if (runResponse.status !== 201) {
2097
- console.error("POST /brains/runs returned ".concat(runResponse.status, ", expected 201"));
2098
- return [
2099
- 2,
2100
- false
2101
- ];
2102
- }
2103
- return [
2104
- 4,
2105
- runResponse.json()
1948
+ brainRunId = _state.sent();
1949
+ if (!brainRunId) return [
1950
+ 2,
1951
+ false
2106
1952
  ];
2107
- case 2:
2108
- brainRunId = _state.sent().brainRunId;
2109
1953
  // Step 2: Watch until WEBHOOK event (brain pauses)
2110
1954
  watchRequest = new Request("http://example.com/brains/runs/".concat(brainRunId, "/watch"), {
2111
1955
  method: 'GET'
@@ -2114,7 +1958,7 @@ export var brains = {
2114
1958
  4,
2115
1959
  fetch(watchRequest)
2116
1960
  ];
2117
- case 3:
1961
+ case 2:
2118
1962
  watchResponse = _state.sent();
2119
1963
  if (!watchResponse.ok) {
2120
1964
  console.error("GET /brains/runs/".concat(brainRunId, "/watch returned ").concat(watchResponse.status));
@@ -2123,84 +1967,35 @@ export var brains = {
2123
1967
  false
2124
1968
  ];
2125
1969
  }
2126
- foundWebhookEvent = false;
2127
- if (!watchResponse.body) return [
2128
- 3,
2129
- 10
2130
- ];
2131
- reader = watchResponse.body.getReader();
2132
- decoder = new TextDecoder();
2133
- buffer = '';
2134
- _state.label = 4;
2135
- case 4:
2136
- _state.trys.push([
2137
- 4,
2138
- ,
2139
- 8,
2140
- 10
2141
- ]);
2142
- _state.label = 5;
2143
- case 5:
2144
- if (!!foundWebhookEvent) return [
2145
- 3,
2146
- 7
2147
- ];
2148
- return [
2149
- 4,
2150
- reader.read()
2151
- ];
2152
- case 6:
2153
- _ref = _state.sent(), value = _ref.value, done = _ref.done;
2154
- if (done) return [
2155
- 3,
2156
- 7
2157
- ];
2158
- buffer += decoder.decode(value, {
2159
- stream: true
2160
- });
2161
- eventEndIndex = void 0;
2162
- while((eventEndIndex = buffer.indexOf('\n\n')) !== -1){
2163
- message = buffer.substring(0, eventEndIndex);
2164
- buffer = buffer.substring(eventEndIndex + 2);
2165
- if (message.startsWith('data: ')) {
2166
- try {
2167
- event = JSON.parse(message.substring(6));
2168
- if (event.type === BRAIN_EVENTS.WEBHOOK) {
2169
- foundWebhookEvent = true;
2170
- break;
2171
- }
2172
- if (event.type === BRAIN_EVENTS.COMPLETE || event.type === BRAIN_EVENTS.ERROR) {
2173
- console.error("Brain completed/errored before WEBHOOK event: ".concat(event.type));
2174
- return [
2175
- 2,
2176
- false
2177
- ];
2178
- }
2179
- } catch (e) {
2180
- // Ignore parse errors
2181
- }
2182
- }
1970
+ if (!watchResponse.body) {
1971
+ console.error('Watch response has no body');
1972
+ return [
1973
+ 2,
1974
+ false
1975
+ ];
2183
1976
  }
2184
- return [
2185
- 3,
2186
- 5
2187
- ];
2188
- case 7:
2189
- return [
2190
- 3,
2191
- 10
2192
- ];
2193
- case 8:
1977
+ earlyTermination = false;
2194
1978
  return [
2195
1979
  4,
2196
- reader.cancel()
1980
+ readSseUntil(watchResponse.body, function(event) {
1981
+ if (event.type === BRAIN_EVENTS.WEBHOOK) return true;
1982
+ if (event.type === BRAIN_EVENTS.COMPLETE || event.type === BRAIN_EVENTS.ERROR) {
1983
+ console.error("Brain completed/errored before WEBHOOK event: ".concat(event.type));
1984
+ earlyTermination = true;
1985
+ return true;
1986
+ }
1987
+ return false;
1988
+ })
2197
1989
  ];
2198
- case 9:
2199
- _state.sent();
2200
- return [
2201
- 7
1990
+ case 3:
1991
+ watchEvents = _state.sent();
1992
+ if (earlyTermination) return [
1993
+ 2,
1994
+ false
2202
1995
  ];
2203
- case 10:
1996
+ foundWebhookEvent = watchEvents.some(function(e) {
1997
+ return e.type === BRAIN_EVENTS.WEBHOOK;
1998
+ });
2204
1999
  if (!foundWebhookEvent) {
2205
2000
  console.error('Brain did not emit WEBHOOK event');
2206
2001
  return [
@@ -2220,7 +2015,7 @@ export var brains = {
2220
2015
  4,
2221
2016
  fetch(webhookRequest)
2222
2017
  ];
2223
- case 11:
2018
+ case 4:
2224
2019
  webhookResponse = _state.sent();
2225
2020
  if (!webhookResponse.ok) {
2226
2021
  console.error("POST /webhooks/".concat(webhookSlug, " returned ").concat(webhookResponse.status));
@@ -2233,7 +2028,7 @@ export var brains = {
2233
2028
  4,
2234
2029
  webhookResponse.json()
2235
2030
  ];
2236
- case 12:
2031
+ case 5:
2237
2032
  webhookResult = _state.sent();
2238
2033
  if (!webhookResult.received) {
2239
2034
  console.error('Webhook was not received');
@@ -2257,7 +2052,7 @@ export var brains = {
2257
2052
  4,
2258
2053
  fetch(resumeWatchRequest)
2259
2054
  ];
2260
- case 13:
2055
+ case 6:
2261
2056
  resumeWatchResponse = _state.sent();
2262
2057
  if (!resumeWatchResponse.ok) {
2263
2058
  console.error("GET /brains/runs/".concat(brainRunId, "/watch (resume) returned ").concat(resumeWatchResponse.status));
@@ -2266,79 +2061,27 @@ export var brains = {
2266
2061
  false
2267
2062
  ];
2268
2063
  }
2269
- resumeEvents = [];
2270
2064
  if (!resumeWatchResponse.body) return [
2271
2065
  3,
2272
- 20
2273
- ];
2274
- reader1 = resumeWatchResponse.body.getReader();
2275
- decoder1 = new TextDecoder();
2276
- buffer1 = '';
2277
- done1 = false;
2278
- _state.label = 14;
2279
- case 14:
2280
- _state.trys.push([
2281
- 14,
2282
- ,
2283
- 18,
2284
- 20
2285
- ]);
2286
- _state.label = 15;
2287
- case 15:
2288
- if (!!done1) return [
2289
- 3,
2290
- 17
2066
+ 8
2291
2067
  ];
2292
2068
  return [
2293
2069
  4,
2294
- reader1.read()
2295
- ];
2296
- case 16:
2297
- _ref1 = _state.sent(), value1 = _ref1.value, streamDone = _ref1.done;
2298
- if (streamDone) return [
2299
- 3,
2300
- 17
2301
- ];
2302
- buffer1 += decoder1.decode(value1, {
2303
- stream: true
2304
- });
2305
- eventEndIndex1 = void 0;
2306
- while((eventEndIndex1 = buffer1.indexOf('\n\n')) !== -1){
2307
- message1 = buffer1.substring(0, eventEndIndex1);
2308
- buffer1 = buffer1.substring(eventEndIndex1 + 2);
2309
- if (message1.startsWith('data: ')) {
2310
- try {
2311
- event1 = JSON.parse(message1.substring(6));
2312
- resumeEvents.push(event1);
2313
- if (event1.type === BRAIN_EVENTS.COMPLETE || event1.type === BRAIN_EVENTS.ERROR) {
2314
- done1 = true;
2315
- break;
2316
- }
2317
- } catch (e) {
2318
- // Ignore parse errors
2319
- }
2320
- }
2321
- }
2322
- return [
2323
- 3,
2324
- 15
2070
+ readSseUntil(resumeWatchResponse.body, function(event) {
2071
+ return event.type === BRAIN_EVENTS.COMPLETE || event.type === BRAIN_EVENTS.ERROR;
2072
+ })
2325
2073
  ];
2326
- case 17:
2074
+ case 7:
2075
+ _tmp = _state.sent();
2327
2076
  return [
2328
2077
  3,
2329
- 20
2078
+ 9
2330
2079
  ];
2331
- case 18:
2332
- return [
2333
- 4,
2334
- reader1.cancel()
2335
- ];
2336
- case 19:
2337
- _state.sent();
2338
- return [
2339
- 7
2340
- ];
2341
- case 20:
2080
+ case 8:
2081
+ _tmp = [];
2082
+ _state.label = 9;
2083
+ case 9:
2084
+ resumeEvents = _tmp;
2342
2085
  // Verify WEBHOOK_RESPONSE event is present
2343
2086
  hasWebhookResponse = resumeEvents.some(function(e) {
2344
2087
  return e.type === BRAIN_EVENTS.WEBHOOK_RESPONSE;
@@ -2383,14 +2126,14 @@ export var brains = {
2383
2126
  2,
2384
2127
  true
2385
2128
  ];
2386
- case 21:
2129
+ case 10:
2387
2130
  error = _state.sent();
2388
2131
  console.error("Failed to test agent webhook resume for ".concat(agentBrainIdentifier, ":"), error);
2389
2132
  return [
2390
2133
  2,
2391
2134
  false
2392
2135
  ];
2393
- case 22:
2136
+ case 11:
2394
2137
  return [
2395
2138
  2
2396
2139
  ];
@@ -2413,45 +2156,26 @@ export var brains = {
2413
2156
  * 6. Assert final status is COMPLETE
2414
2157
  */ function innerBrainCompleteDoesNotAffectOuterStatus(fetch, outerBrainIdentifier, webhookSlug, webhookPayload) {
2415
2158
  return _async_to_generator(function() {
2416
- var runRequest, runResponse, brainRunId, watchRequest, watchResponse, foundOuterWebhook, innerCompleteCount, reader, decoder, buffer, _ref, value, done, eventEndIndex, message, event, historyRequest, historyResponse, historyData, ourRun, webhookRequest, webhookResponse, resumeWatchRequest, resumeWatchResponse, foundFinalComplete, depth, reader1, decoder1, buffer1, _ref1, value1, done1, eventEndIndex1, message1, event1, finalHistoryResponse, finalHistoryData, finalRun, error;
2159
+ var brainRunId, watchRequest, watchResponse, innerCompleteCount, hitError, watchEvents, foundOuterWebhook, historyRequest, historyResponse, historyData, ourRun, webhookRequest, webhookResponse, resumeWatchRequest, resumeWatchResponse, depth, finalHistoryResponse, finalHistoryData, finalRun, error;
2417
2160
  return _ts_generator(this, function(_state) {
2418
2161
  switch(_state.label){
2419
2162
  case 0:
2420
2163
  _state.trys.push([
2421
2164
  0,
2422
- 24,
2165
+ 12,
2423
2166
  ,
2424
- 25
2167
+ 13
2425
2168
  ]);
2426
- // Step 1: Start the outer brain
2427
- runRequest = new Request('http://example.com/brains/runs', {
2428
- method: 'POST',
2429
- headers: {
2430
- 'Content-Type': 'application/json'
2431
- },
2432
- body: JSON.stringify({
2433
- identifier: outerBrainIdentifier
2434
- })
2435
- });
2436
2169
  return [
2437
2170
  4,
2438
- fetch(runRequest)
2171
+ startBrainRun(fetch, outerBrainIdentifier)
2439
2172
  ];
2440
2173
  case 1:
2441
- runResponse = _state.sent();
2442
- if (runResponse.status !== 201) {
2443
- console.error("POST /brains/runs returned ".concat(runResponse.status, ", expected 201"));
2444
- return [
2445
- 2,
2446
- false
2447
- ];
2448
- }
2449
- return [
2450
- 4,
2451
- runResponse.json()
2174
+ brainRunId = _state.sent();
2175
+ if (!brainRunId) return [
2176
+ 2,
2177
+ false
2452
2178
  ];
2453
- case 2:
2454
- brainRunId = _state.sent().brainRunId;
2455
2179
  // Step 2: Watch SSE until WEBHOOK event from outer brain (after inner completes)
2456
2180
  watchRequest = new Request("http://example.com/brains/runs/".concat(brainRunId, "/watch"), {
2457
2181
  method: 'GET'
@@ -2460,7 +2184,7 @@ export var brains = {
2460
2184
  4,
2461
2185
  fetch(watchRequest)
2462
2186
  ];
2463
- case 3:
2187
+ case 2:
2464
2188
  watchResponse = _state.sent();
2465
2189
  if (!watchResponse.ok) {
2466
2190
  console.error("GET /brains/runs/".concat(brainRunId, "/watch returned ").concat(watchResponse.status));
@@ -2469,91 +2193,39 @@ export var brains = {
2469
2193
  false
2470
2194
  ];
2471
2195
  }
2472
- foundOuterWebhook = false;
2196
+ if (!watchResponse.body) {
2197
+ console.error('Watch response has no body');
2198
+ return [
2199
+ 2,
2200
+ false
2201
+ ];
2202
+ }
2473
2203
  innerCompleteCount = 0;
2474
- if (!watchResponse.body) return [
2475
- 3,
2476
- 10
2477
- ];
2478
- reader = watchResponse.body.getReader();
2479
- decoder = new TextDecoder();
2480
- buffer = '';
2481
- _state.label = 4;
2482
- case 4:
2483
- _state.trys.push([
2484
- 4,
2485
- ,
2486
- 8,
2487
- 10
2488
- ]);
2489
- _state.label = 5;
2490
- case 5:
2491
- if (!!foundOuterWebhook) return [
2492
- 3,
2493
- 7
2494
- ];
2204
+ hitError = false;
2495
2205
  return [
2496
2206
  4,
2497
- reader.read()
2498
- ];
2499
- case 6:
2500
- _ref = _state.sent(), value = _ref.value, done = _ref.done;
2501
- if (done) return [
2502
- 3,
2503
- 7
2504
- ];
2505
- buffer += decoder.decode(value, {
2506
- stream: true
2507
- });
2508
- eventEndIndex = void 0;
2509
- while((eventEndIndex = buffer.indexOf('\n\n')) !== -1){
2510
- message = buffer.substring(0, eventEndIndex);
2511
- buffer = buffer.substring(eventEndIndex + 2);
2512
- if (message.startsWith('data: ')) {
2513
- try {
2514
- event = JSON.parse(message.substring(6));
2515
- // Track inner brain completes
2516
- if (event.type === BRAIN_EVENTS.COMPLETE) {
2517
- innerCompleteCount++;
2518
- // First complete is inner brain, second would be outer
2519
- }
2520
- // Outer brain webhook (happens after inner brain completes)
2521
- if (event.type === BRAIN_EVENTS.WEBHOOK) {
2522
- foundOuterWebhook = true;
2523
- break;
2524
- }
2525
- if (event.type === BRAIN_EVENTS.ERROR) {
2526
- console.error("Brain errored: ".concat(JSON.stringify(event.error)));
2527
- return [
2528
- 2,
2529
- false
2530
- ];
2531
- }
2532
- } catch (e) {
2533
- // Ignore parse errors
2207
+ readSseUntil(watchResponse.body, function(event) {
2208
+ if (event.type === BRAIN_EVENTS.COMPLETE) {
2209
+ innerCompleteCount++;
2534
2210
  }
2535
- }
2536
- }
2537
- return [
2538
- 3,
2539
- 5
2540
- ];
2541
- case 7:
2542
- return [
2543
- 3,
2544
- 10
2545
- ];
2546
- case 8:
2547
- return [
2548
- 4,
2549
- reader.cancel()
2211
+ if (event.type === BRAIN_EVENTS.WEBHOOK) return true;
2212
+ if (event.type === BRAIN_EVENTS.ERROR) {
2213
+ console.error("Brain errored: ".concat(JSON.stringify(event.error)));
2214
+ hitError = true;
2215
+ return true;
2216
+ }
2217
+ return false;
2218
+ })
2550
2219
  ];
2551
- case 9:
2552
- _state.sent();
2553
- return [
2554
- 7
2220
+ case 3:
2221
+ watchEvents = _state.sent();
2222
+ if (hitError) return [
2223
+ 2,
2224
+ false
2555
2225
  ];
2556
- case 10:
2226
+ foundOuterWebhook = watchEvents.some(function(e) {
2227
+ return e.type === BRAIN_EVENTS.WEBHOOK;
2228
+ });
2557
2229
  if (!foundOuterWebhook) {
2558
2230
  console.error('Did not receive outer brain WEBHOOK event');
2559
2231
  return [
@@ -2576,7 +2248,7 @@ export var brains = {
2576
2248
  4,
2577
2249
  fetch(historyRequest)
2578
2250
  ];
2579
- case 11:
2251
+ case 4:
2580
2252
  historyResponse = _state.sent();
2581
2253
  if (!historyResponse.ok) {
2582
2254
  console.error("GET /brains/".concat(outerBrainIdentifier, "/history returned ").concat(historyResponse.status));
@@ -2589,7 +2261,7 @@ export var brains = {
2589
2261
  4,
2590
2262
  historyResponse.json()
2591
2263
  ];
2592
- case 12:
2264
+ case 5:
2593
2265
  historyData = _state.sent();
2594
2266
  ourRun = historyData.runs.find(function(r) {
2595
2267
  return r.brainRunId === brainRunId;
@@ -2622,7 +2294,7 @@ export var brains = {
2622
2294
  4,
2623
2295
  fetch(webhookRequest)
2624
2296
  ];
2625
- case 13:
2297
+ case 6:
2626
2298
  webhookResponse = _state.sent();
2627
2299
  if (!webhookResponse.ok) {
2628
2300
  console.error("POST /webhooks/".concat(webhookSlug, " returned ").concat(webhookResponse.status));
@@ -2639,7 +2311,7 @@ export var brains = {
2639
2311
  4,
2640
2312
  fetch(resumeWatchRequest)
2641
2313
  ];
2642
- case 14:
2314
+ case 7:
2643
2315
  resumeWatchResponse = _state.sent();
2644
2316
  if (!resumeWatchResponse.ok) {
2645
2317
  console.error("Resume watch returned ".concat(resumeWatchResponse.status));
@@ -2648,93 +2320,32 @@ export var brains = {
2648
2320
  false
2649
2321
  ];
2650
2322
  }
2651
- // Wait for the OUTER brain's COMPLETE event specifically (by tracking depth)
2652
- // When resuming, the SSE stream includes historical events, so we need to
2653
- // track START/COMPLETE events to know when the outer brain truly finishes
2654
- foundFinalComplete = false;
2655
- depth = 0;
2656
2323
  if (!resumeWatchResponse.body) return [
2657
2324
  3,
2658
- 21
2659
- ];
2660
- reader1 = resumeWatchResponse.body.getReader();
2661
- decoder1 = new TextDecoder();
2662
- buffer1 = '';
2663
- _state.label = 15;
2664
- case 15:
2665
- _state.trys.push([
2666
- 15,
2667
- ,
2668
- 19,
2669
- 21
2670
- ]);
2671
- _state.label = 16;
2672
- case 16:
2673
- if (!!foundFinalComplete) return [
2674
- 3,
2675
- 18
2325
+ 9
2676
2326
  ];
2327
+ depth = 0;
2677
2328
  return [
2678
2329
  4,
2679
- reader1.read()
2680
- ];
2681
- case 17:
2682
- _ref1 = _state.sent(), value1 = _ref1.value, done1 = _ref1.done;
2683
- if (done1) return [
2684
- 3,
2685
- 18
2686
- ];
2687
- buffer1 += decoder1.decode(value1, {
2688
- stream: true
2689
- });
2690
- eventEndIndex1 = void 0;
2691
- while((eventEndIndex1 = buffer1.indexOf('\n\n')) !== -1){
2692
- message1 = buffer1.substring(0, eventEndIndex1);
2693
- buffer1 = buffer1.substring(eventEndIndex1 + 2);
2694
- if (message1.startsWith('data: ')) {
2695
- try {
2696
- event1 = JSON.parse(message1.substring(6));
2697
- // Track depth to find the outer brain's COMPLETE
2698
- if (event1.type === BRAIN_EVENTS.START) {
2699
- depth++;
2700
- } else if (event1.type === BRAIN_EVENTS.COMPLETE) {
2701
- depth--;
2702
- // When depth reaches 0, the outer brain has completed
2703
- if (depth <= 0) {
2704
- foundFinalComplete = true;
2705
- break;
2706
- }
2707
- }
2708
- } catch (e) {
2709
- // Ignore parse errors
2330
+ readSseUntil(resumeWatchResponse.body, function(event) {
2331
+ if (event.type === BRAIN_EVENTS.START) {
2332
+ depth++;
2333
+ } else if (event.type === BRAIN_EVENTS.COMPLETE) {
2334
+ depth--;
2335
+ if (depth <= 0) return true;
2710
2336
  }
2711
- }
2712
- }
2713
- return [
2714
- 3,
2715
- 16
2716
- ];
2717
- case 18:
2718
- return [
2719
- 3,
2720
- 21
2721
- ];
2722
- case 19:
2723
- return [
2724
- 4,
2725
- reader1.cancel()
2337
+ return false;
2338
+ })
2726
2339
  ];
2727
- case 20:
2340
+ case 8:
2728
2341
  _state.sent();
2729
- return [
2730
- 7
2731
- ];
2732
- case 21:
2342
+ _state.label = 9;
2343
+ case 9:
2733
2344
  return [
2734
2345
  4,
2735
2346
  fetch(historyRequest)
2736
2347
  ];
2737
- case 22:
2348
+ case 10:
2738
2349
  finalHistoryResponse = _state.sent();
2739
2350
  if (!finalHistoryResponse.ok) {
2740
2351
  console.error('Final history query failed');
@@ -2747,7 +2358,7 @@ export var brains = {
2747
2358
  4,
2748
2359
  finalHistoryResponse.json()
2749
2360
  ];
2750
- case 23:
2361
+ case 11:
2751
2362
  finalHistoryData = _state.sent();
2752
2363
  finalRun = finalHistoryData.runs.find(function(r) {
2753
2364
  return r.brainRunId === brainRunId;
@@ -2763,14 +2374,14 @@ export var brains = {
2763
2374
  2,
2764
2375
  true
2765
2376
  ];
2766
- case 24:
2377
+ case 12:
2767
2378
  error = _state.sent();
2768
2379
  console.error("Failed to test inner brain complete status for ".concat(outerBrainIdentifier, ":"), error);
2769
2380
  return [
2770
2381
  2,
2771
2382
  false
2772
2383
  ];
2773
- case 25:
2384
+ case 13:
2774
2385
  return [
2775
2386
  2
2776
2387
  ];