@alexkroman1/aai 0.12.2 → 1.0.2

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 (135) hide show
  1. package/.turbo/turbo-build.log +20 -0
  2. package/CHANGELOG.md +174 -0
  3. package/dist/constants-VTFoymJ-.js +47 -0
  4. package/dist/host/_run-code.d.ts +4 -2
  5. package/dist/host/_runtime-conformance.d.ts +4 -5
  6. package/dist/host/builtin-tools.d.ts +11 -7
  7. package/dist/host/runtime-barrel.d.ts +15 -0
  8. package/dist/{direct-executor-ZUU0Ke4j.js → host/runtime-barrel.js} +463 -345
  9. package/dist/host/runtime-config.d.ts +42 -0
  10. package/dist/host/runtime.d.ts +119 -35
  11. package/dist/host/s2s.d.ts +14 -38
  12. package/dist/host/server.d.ts +16 -8
  13. package/dist/host/session-ctx.d.ts +55 -0
  14. package/dist/host/session.d.ts +21 -70
  15. package/dist/host/tool-executor.d.ts +20 -0
  16. package/dist/host/unstorage-kv.d.ts +1 -1
  17. package/dist/host/ws-handler.d.ts +4 -2
  18. package/dist/index.d.ts +9 -20
  19. package/dist/index.js +63 -2
  20. package/dist/{isolate → sdk}/_internal-types.d.ts +6 -10
  21. package/dist/{isolate → sdk}/constants.d.ts +6 -4
  22. package/dist/sdk/define.d.ts +66 -0
  23. package/dist/{isolate → sdk}/kv.d.ts +1 -49
  24. package/dist/sdk/manifest-barrel.d.ts +8 -0
  25. package/dist/sdk/manifest-barrel.js +52 -0
  26. package/dist/sdk/manifest.d.ts +50 -0
  27. package/dist/{isolate → sdk}/protocol.d.ts +59 -36
  28. package/dist/sdk/protocol.js +163 -0
  29. package/dist/{isolate → sdk}/system-prompt.d.ts +3 -2
  30. package/dist/sdk/types.d.ts +201 -0
  31. package/dist/sdk/ws-upgrade.d.ts +5 -0
  32. package/dist/{system-prompt-CVJSQJiA.js → system-prompt-nik_iavo.js} +11 -10
  33. package/dist/types-Cfx_4QDK.js +39 -0
  34. package/dist/ws-upgrade-BeOQ7fXL.js +30 -0
  35. package/exports-no-dev-deps.test.ts +62 -0
  36. package/host/_mock-ws.ts +185 -0
  37. package/host/_run-code.ts +217 -0
  38. package/host/_runtime-conformance.ts +143 -0
  39. package/host/_test-utils.ts +276 -0
  40. package/host/builtin-tools.test.ts +774 -0
  41. package/host/builtin-tools.ts +255 -0
  42. package/host/cleanup.test.ts +422 -0
  43. package/host/fixture-replay.test.ts +463 -0
  44. package/host/fixtures/README.md +40 -0
  45. package/host/fixtures/greeting-session-sequence.json +40 -0
  46. package/host/fixtures/reply-audio-samples.json +42 -0
  47. package/host/fixtures/reply-lifecycle.json +21 -0
  48. package/host/fixtures/session-ready.json +48 -0
  49. package/host/fixtures/session-updated.json +45 -0
  50. package/host/fixtures/simple-question-sequence.json +73 -0
  51. package/host/fixtures/tool-call-sequence.json +114 -0
  52. package/host/fixtures/tool-calls.json +11 -0
  53. package/host/fixtures/tool-config-session-sequence.json +51 -0
  54. package/host/fixtures/user-speech-recognition.json +30 -0
  55. package/host/fixtures/web-search-sequence.json +122 -0
  56. package/host/integration.test.ts +222 -0
  57. package/host/runtime-barrel.ts +25 -0
  58. package/host/runtime-config.test.ts +71 -0
  59. package/host/runtime-config.ts +99 -0
  60. package/host/runtime.test.ts +641 -0
  61. package/host/runtime.ts +308 -0
  62. package/host/s2s-fixtures.test.ts +237 -0
  63. package/host/s2s.test.ts +562 -0
  64. package/host/s2s.ts +310 -0
  65. package/host/server-shutdown.test.ts +76 -0
  66. package/host/server.test.ts +116 -0
  67. package/host/server.ts +223 -0
  68. package/host/session-ctx.ts +107 -0
  69. package/host/session-fixture-replay.test.ts +136 -0
  70. package/host/session-prompt.test.ts +77 -0
  71. package/host/session.test.ts +590 -0
  72. package/host/session.ts +370 -0
  73. package/host/tool-executor.test.ts +124 -0
  74. package/host/tool-executor.ts +80 -0
  75. package/host/unstorage-kv.test.ts +99 -0
  76. package/host/unstorage-kv.ts +69 -0
  77. package/host/ws-handler.test.ts +739 -0
  78. package/host/ws-handler.ts +255 -0
  79. package/index.ts +16 -0
  80. package/package.json +28 -72
  81. package/sdk/_internal-types.test.ts +34 -0
  82. package/sdk/_internal-types.ts +115 -0
  83. package/sdk/compat-fixtures/README.md +26 -0
  84. package/sdk/compat-fixtures/v1.json +68 -0
  85. package/sdk/constants.ts +77 -0
  86. package/sdk/define.test.ts +57 -0
  87. package/sdk/define.ts +88 -0
  88. package/sdk/kv.ts +60 -0
  89. package/sdk/manifest-barrel.ts +12 -0
  90. package/sdk/manifest.test.ts +56 -0
  91. package/sdk/manifest.ts +89 -0
  92. package/sdk/protocol-compat.test.ts +187 -0
  93. package/sdk/protocol-snapshot.test.ts +199 -0
  94. package/sdk/protocol.test.ts +170 -0
  95. package/sdk/protocol.ts +223 -0
  96. package/sdk/schema-alignment.test.ts +191 -0
  97. package/sdk/system-prompt.test.ts +111 -0
  98. package/sdk/system-prompt.ts +74 -0
  99. package/sdk/tsconfig.json +12 -0
  100. package/sdk/types-inference.test.ts +122 -0
  101. package/sdk/types.test.ts +14 -0
  102. package/sdk/types.ts +226 -0
  103. package/sdk/utils.test.ts +52 -0
  104. package/sdk/utils.ts +20 -0
  105. package/sdk/ws-upgrade.test.ts +48 -0
  106. package/sdk/ws-upgrade.ts +13 -0
  107. package/tsconfig.build.json +14 -0
  108. package/tsconfig.json +10 -0
  109. package/tsdown.config.ts +26 -0
  110. package/vitest.config.ts +17 -0
  111. package/dist/host/_test-utils.d.ts +0 -73
  112. package/dist/host/direct-executor.d.ts +0 -128
  113. package/dist/host/index.d.ts +0 -18
  114. package/dist/host/index.js +0 -165
  115. package/dist/host/matchers.d.ts +0 -20
  116. package/dist/host/matchers.js +0 -41
  117. package/dist/host/server.js +0 -164
  118. package/dist/host/testing.d.ts +0 -294
  119. package/dist/host/testing.js +0 -2
  120. package/dist/host/vite-plugin.d.ts +0 -15
  121. package/dist/host/vite-plugin.js +0 -83
  122. package/dist/isolate/_kv-utils.d.ts +0 -10
  123. package/dist/isolate/_utils.js +0 -17
  124. package/dist/isolate/hooks.d.ts +0 -44
  125. package/dist/isolate/hooks.js +0 -58
  126. package/dist/isolate/index.d.ts +0 -18
  127. package/dist/isolate/index.js +0 -6
  128. package/dist/isolate/kv.js +0 -1
  129. package/dist/isolate/protocol.js +0 -2
  130. package/dist/isolate/types.d.ts +0 -418
  131. package/dist/isolate/types.js +0 -175
  132. package/dist/protocol-rcOrz7T3.js +0 -183
  133. package/dist/testing-Bb2B5Uob.js +0 -513
  134. package/dist/types.test-d.d.ts +0 -7
  135. /package/dist/{isolate/_utils.d.ts → sdk/utils.d.ts} +0 -0
@@ -0,0 +1,45 @@
1
+ [
2
+ {
3
+ "type": "session.updated",
4
+ "timestamp": 1774669383.6972675,
5
+ "config": {
6
+ "system_prompt": "You are a helpful assistant. Keep responses very short, under 10 words.",
7
+ "tools": [],
8
+ "greeting": "Hello! How can I help you today?"
9
+ }
10
+ },
11
+ {
12
+ "type": "session.updated",
13
+ "timestamp": 1774669390.5091305,
14
+ "config": {
15
+ "system_prompt": "You are a helpful assistant. Keep responses to one short sentence.",
16
+ "tools": [],
17
+ "greeting": "Hi!"
18
+ }
19
+ },
20
+ {
21
+ "type": "session.updated",
22
+ "timestamp": 1774669401.4762232,
23
+ "config": {
24
+ "system_prompt": "You are a weather assistant. Always use the get_weather tool for weather questions. After getting the result, tell the user the weather in one sentence.",
25
+ "tools": [
26
+ {
27
+ "type": "function",
28
+ "name": "get_weather",
29
+ "description": "Get the current weather for a city",
30
+ "parameters": {
31
+ "type": "object",
32
+ "properties": {
33
+ "city": {
34
+ "type": "string",
35
+ "description": "City name"
36
+ }
37
+ },
38
+ "required": ["city"]
39
+ }
40
+ }
41
+ ],
42
+ "greeting": "Ask me about the weather!"
43
+ }
44
+ }
45
+ ]
@@ -0,0 +1,73 @@
1
+ [
2
+ {
3
+ "type": "session.updated",
4
+ "timestamp": 1774669390.5091305,
5
+ "config": {
6
+ "system_prompt": "You are a helpful assistant. Keep responses to one short sentence.",
7
+ "tools": [],
8
+ "greeting": "Hi!"
9
+ }
10
+ },
11
+ {
12
+ "type": "session.ready",
13
+ "timestamp": 1774669390.5586526,
14
+ "session_id": "sess_2246ce7e2eb146e08e62c9476278fbef",
15
+ "config": {
16
+ "system_prompt": "You are a helpful assistant. Keep responses to one short sentence.",
17
+ "tools": [],
18
+ "greeting": "Hi!"
19
+ }
20
+ },
21
+ {
22
+ "type": "reply.started",
23
+ "timestamp": 1774669390.5646203,
24
+ "reply_id": "resp_b202d16235bf47c39e9704df37c45e1c"
25
+ },
26
+ {
27
+ "type": "transcript.agent",
28
+ "timestamp": 1774669391.9406674,
29
+ "reply_id": "resp_b202d16235bf47c39e9704df37c45e1c",
30
+ "item_id": "msg_8c5ec0e896704aaf99db0aaa564ce98f",
31
+ "text": "Hi!",
32
+ "interrupted": false
33
+ },
34
+ {
35
+ "type": "reply.done",
36
+ "timestamp": 1774669392.302396,
37
+ "reply_id": "resp_b202d16235bf47c39e9704df37c45e1c",
38
+ "status": "completed"
39
+ },
40
+ {
41
+ "type": "input.speech.started",
42
+ "timestamp": 1774669393.0812206
43
+ },
44
+ {
45
+ "type": "reply.started",
46
+ "timestamp": 1774669393.4352796,
47
+ "reply_id": "resp_a3b4fed4e6d9413bbf51fd55324a5a0a"
48
+ },
49
+ {
50
+ "type": "input.speech.stopped",
51
+ "timestamp": 1774669394.1324704
52
+ },
53
+ {
54
+ "type": "transcript.user",
55
+ "timestamp": 1774669394.2344203,
56
+ "item_id": "msg_8ee3b8ef00ec4354ae5c084bebfc5361",
57
+ "text": "Tell me a fun fact about space."
58
+ },
59
+ {
60
+ "type": "transcript.agent",
61
+ "timestamp": 1774669397.911438,
62
+ "reply_id": "resp_a3b4fed4e6d9413bbf51fd55324a5a0a",
63
+ "item_id": "msg_54b36b413ce94b62a66926dbd4475508",
64
+ "text": "A day on Venus is longer than its year.",
65
+ "interrupted": false
66
+ },
67
+ {
68
+ "type": "reply.done",
69
+ "timestamp": 1774669398.1820145,
70
+ "reply_id": "resp_a3b4fed4e6d9413bbf51fd55324a5a0a",
71
+ "status": "completed"
72
+ }
73
+ ]
@@ -0,0 +1,114 @@
1
+ [
2
+ {
3
+ "type": "session.updated",
4
+ "timestamp": 1774669401.4762232,
5
+ "config": {
6
+ "system_prompt": "You are a weather assistant. Always use the get_weather tool for weather questions. After getting the result, tell the user the weather in one sentence.",
7
+ "tools": [
8
+ {
9
+ "type": "function",
10
+ "name": "get_weather",
11
+ "description": "Get the current weather for a city",
12
+ "parameters": {
13
+ "type": "object",
14
+ "properties": {
15
+ "city": {
16
+ "type": "string",
17
+ "description": "City name"
18
+ }
19
+ },
20
+ "required": ["city"]
21
+ }
22
+ }
23
+ ],
24
+ "greeting": "Ask me about the weather!"
25
+ }
26
+ },
27
+ {
28
+ "type": "session.ready",
29
+ "timestamp": 1774669401.5069516,
30
+ "session_id": "sess_b01d5d5f1865418b955dc30b00b3d52b",
31
+ "config": {
32
+ "system_prompt": "You are a weather assistant. Always use the get_weather tool for weather questions. After getting the result, tell the user the weather in one sentence.",
33
+ "tools": [
34
+ {
35
+ "type": "function",
36
+ "name": "get_weather",
37
+ "description": "Get the current weather for a city",
38
+ "parameters": {
39
+ "type": "object",
40
+ "properties": {
41
+ "city": {
42
+ "type": "string",
43
+ "description": "City name"
44
+ }
45
+ },
46
+ "required": ["city"]
47
+ }
48
+ }
49
+ ],
50
+ "greeting": "Ask me about the weather!"
51
+ }
52
+ },
53
+ {
54
+ "type": "reply.started",
55
+ "timestamp": 1774669401.5081005,
56
+ "reply_id": "resp_0c5069c8a284417696b0fb94121b5302"
57
+ },
58
+ {
59
+ "type": "transcript.agent",
60
+ "timestamp": 1774669403.61195,
61
+ "reply_id": "resp_0c5069c8a284417696b0fb94121b5302",
62
+ "item_id": "msg_f3a8a53d8cce4ad6b92607ea38131f7d",
63
+ "text": "Ask me about the weather!",
64
+ "interrupted": false
65
+ },
66
+ {
67
+ "type": "reply.done",
68
+ "timestamp": 1774669403.9528494,
69
+ "reply_id": "resp_0c5069c8a284417696b0fb94121b5302",
70
+ "status": "completed"
71
+ },
72
+ {
73
+ "type": "input.speech.started",
74
+ "timestamp": 1774669404.8296304
75
+ },
76
+ {
77
+ "type": "reply.started",
78
+ "timestamp": 1774669405.0349832,
79
+ "reply_id": "resp_c8b83fbfde1d4dbc8cb39318c3012981"
80
+ },
81
+ {
82
+ "type": "input.speech.stopped",
83
+ "timestamp": 1774669406.0299
84
+ },
85
+ {
86
+ "type": "transcript.user",
87
+ "timestamp": 1774669406.184384,
88
+ "item_id": "msg_2ff13ff4b77b46e19d2b7f20ad88d822",
89
+ "text": "What is the weather like in San Francisco?"
90
+ },
91
+ {
92
+ "type": "tool.call",
93
+ "timestamp": 1774669406.466613,
94
+ "call_id": "chatcmpl-tool-9793a062159342bb8e221cbab79229e3",
95
+ "name": "get_weather",
96
+ "args": {
97
+ "city": "San Francisco"
98
+ }
99
+ },
100
+ {
101
+ "type": "transcript.agent",
102
+ "timestamp": 1774669417.728002,
103
+ "reply_id": "resp_c8b83fbfde1d4dbc8cb39318c3012981",
104
+ "item_id": "msg_8421a07d995e4f25b07983ce420b7eca",
105
+ "text": "The weather in San Francisco is sunny with a temperature of 72 degrees Fahrenheit, 45 percent humidity, and winds at 8 miles per hour from the northwest.",
106
+ "interrupted": false
107
+ },
108
+ {
109
+ "type": "reply.done",
110
+ "timestamp": 1774669417.9831085,
111
+ "reply_id": "resp_c8b83fbfde1d4dbc8cb39318c3012981",
112
+ "status": "completed"
113
+ }
114
+ ]
@@ -0,0 +1,11 @@
1
+ [
2
+ {
3
+ "type": "tool.call",
4
+ "timestamp": 1774669406.466613,
5
+ "call_id": "chatcmpl-tool-9793a062159342bb8e221cbab79229e3",
6
+ "name": "get_weather",
7
+ "args": {
8
+ "city": "San Francisco"
9
+ }
10
+ }
11
+ ]
@@ -0,0 +1,51 @@
1
+ [
2
+ {
3
+ "type": "session.updated",
4
+ "timestamp": 1774668542.389923,
5
+ "config": {
6
+ "system_prompt": "You are a weather assistant. Always use the get_weather tool when asked about weather. Keep responses under 10 words.",
7
+ "tools": [
8
+ {
9
+ "type": "function",
10
+ "name": "get_weather",
11
+ "description": "Get the current weather for a city",
12
+ "parameters": {
13
+ "type": "object",
14
+ "properties": {
15
+ "city": {
16
+ "type": "string",
17
+ "description": "City name"
18
+ }
19
+ },
20
+ "required": ["city"]
21
+ }
22
+ }
23
+ ]
24
+ }
25
+ },
26
+ {
27
+ "type": "session.ready",
28
+ "timestamp": 1774668542.4018698,
29
+ "session_id": "sess_d0b0b408c00944c49183bb2d6f18feb9",
30
+ "config": {
31
+ "system_prompt": "You are a weather assistant. Always use the get_weather tool when asked about weather. Keep responses under 10 words.",
32
+ "tools": [
33
+ {
34
+ "type": "function",
35
+ "name": "get_weather",
36
+ "description": "Get the current weather for a city",
37
+ "parameters": {
38
+ "type": "object",
39
+ "properties": {
40
+ "city": {
41
+ "type": "string",
42
+ "description": "City name"
43
+ }
44
+ },
45
+ "required": ["city"]
46
+ }
47
+ }
48
+ ]
49
+ }
50
+ }
51
+ ]
@@ -0,0 +1,30 @@
1
+ [
2
+ {
3
+ "type": "input.speech.started",
4
+ "timestamp": 1774669393.0812206
5
+ },
6
+ {
7
+ "type": "input.speech.stopped",
8
+ "timestamp": 1774669394.1324704
9
+ },
10
+ {
11
+ "type": "transcript.user",
12
+ "timestamp": 1774669394.2344203,
13
+ "item_id": "msg_8ee3b8ef00ec4354ae5c084bebfc5361",
14
+ "text": "Tell me a fun fact about space."
15
+ },
16
+ {
17
+ "type": "input.speech.started",
18
+ "timestamp": 1774669404.8296304
19
+ },
20
+ {
21
+ "type": "input.speech.stopped",
22
+ "timestamp": 1774669406.0299
23
+ },
24
+ {
25
+ "type": "transcript.user",
26
+ "timestamp": 1774669406.184384,
27
+ "item_id": "msg_2ff13ff4b77b46e19d2b7f20ad88d822",
28
+ "text": "What is the weather like in San Francisco?"
29
+ }
30
+ ]
@@ -0,0 +1,122 @@
1
+ [
2
+ {
3
+ "type": "session.updated",
4
+ "timestamp": 1774669501.4762232,
5
+ "config": {
6
+ "system_prompt": "You are a research assistant. Use the web_search tool to find current information.",
7
+ "tools": [
8
+ {
9
+ "type": "function",
10
+ "name": "web_search",
11
+ "description": "Search the web for current information, facts, news, or answers to questions. Returns a list of results with title, URL, and description. Use this when the user asks about something you don't know, need up-to-date information, or want to verify facts.",
12
+ "parameters": {
13
+ "type": "object",
14
+ "properties": {
15
+ "query": {
16
+ "type": "string",
17
+ "description": "The search query"
18
+ },
19
+ "max_results": {
20
+ "type": "number",
21
+ "description": "Maximum number of results to return (default 5)"
22
+ }
23
+ },
24
+ "required": ["query"]
25
+ }
26
+ }
27
+ ],
28
+ "greeting": "Hi! I can search the web for you."
29
+ }
30
+ },
31
+ {
32
+ "type": "session.ready",
33
+ "timestamp": 1774669501.5069516,
34
+ "session_id": "sess_a12c3d4e5f6789ab0cde12345f678901",
35
+ "config": {
36
+ "system_prompt": "You are a research assistant. Use the web_search tool to find current information.",
37
+ "tools": [
38
+ {
39
+ "type": "function",
40
+ "name": "web_search",
41
+ "description": "Search the web for current information, facts, news, or answers to questions. Returns a list of results with title, URL, and description. Use this when the user asks about something you don't know, need up-to-date information, or want to verify facts.",
42
+ "parameters": {
43
+ "type": "object",
44
+ "properties": {
45
+ "query": {
46
+ "type": "string",
47
+ "description": "The search query"
48
+ },
49
+ "max_results": {
50
+ "type": "number",
51
+ "description": "Maximum number of results to return (default 5)"
52
+ }
53
+ },
54
+ "required": ["query"]
55
+ }
56
+ }
57
+ ],
58
+ "greeting": "Hi! I can search the web for you."
59
+ }
60
+ },
61
+ {
62
+ "type": "reply.started",
63
+ "timestamp": 1774669501.5081005,
64
+ "reply_id": "resp_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d"
65
+ },
66
+ {
67
+ "type": "transcript.agent",
68
+ "timestamp": 1774669503.61195,
69
+ "reply_id": "resp_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
70
+ "item_id": "msg_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
71
+ "text": "Hi! I can search the web for you.",
72
+ "interrupted": false
73
+ },
74
+ {
75
+ "type": "reply.done",
76
+ "timestamp": 1774669503.9528494,
77
+ "reply_id": "resp_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
78
+ "status": "completed"
79
+ },
80
+ {
81
+ "type": "input.speech.started",
82
+ "timestamp": 1774669504.8296304
83
+ },
84
+ {
85
+ "type": "reply.started",
86
+ "timestamp": 1774669505.0349832,
87
+ "reply_id": "resp_2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d"
88
+ },
89
+ {
90
+ "type": "input.speech.stopped",
91
+ "timestamp": 1774669506.0299
92
+ },
93
+ {
94
+ "type": "transcript.user",
95
+ "timestamp": 1774669506.184384,
96
+ "item_id": "msg_b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7",
97
+ "text": "Search for the latest Mars rover findings"
98
+ },
99
+ {
100
+ "type": "tool.call",
101
+ "timestamp": 1774669506.466613,
102
+ "call_id": "chatcmpl-tool-8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d",
103
+ "name": "web_search",
104
+ "args": {
105
+ "query": "latest Mars rover findings"
106
+ }
107
+ },
108
+ {
109
+ "type": "transcript.agent",
110
+ "timestamp": 1774669517.728002,
111
+ "reply_id": "resp_2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d",
112
+ "item_id": "msg_c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8",
113
+ "text": "Based on my search, NASA's Perseverance rover has discovered organic molecules in Jezero Crater.",
114
+ "interrupted": false
115
+ },
116
+ {
117
+ "type": "reply.done",
118
+ "timestamp": 1774669517.9831085,
119
+ "reply_id": "resp_2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d",
120
+ "status": "completed"
121
+ }
122
+ ]
@@ -0,0 +1,222 @@
1
+ // Copyright 2025 the AAI authors. MIT license.
2
+ /**
3
+ * Integration tests for the SDK public API surface.
4
+ *
5
+ * These test the connected flow as a consumer would use it:
6
+ * AgentDef → tools → direct executor → KV in tool context.
7
+ */
8
+
9
+ import { createStorage } from "unstorage";
10
+ import { describe, expect, test } from "vitest";
11
+ import { z } from "zod";
12
+ import { toAgentConfig } from "../sdk/_internal-types.ts";
13
+ import type { AgentDef } from "../sdk/types.ts";
14
+ import { createRuntime } from "./runtime.ts";
15
+ import { createUnstorageKv } from "./unstorage-kv.ts";
16
+
17
+ describe("SDK integration: AgentDef → tool execution", () => {
18
+ test("AgentDef + tools + executeToolCall round-trip", async () => {
19
+ const agent: AgentDef = {
20
+ name: "test-agent",
21
+ systemPrompt: "Be helpful.",
22
+ greeting: "Hello!",
23
+ maxSteps: 5,
24
+ tools: {
25
+ greet: {
26
+ description: "Greet by name",
27
+ parameters: z.object({ name: z.string() }),
28
+ execute: ({ name }: { name: string }) => `Hello, ${name}!`,
29
+ },
30
+ },
31
+ };
32
+
33
+ const exec = createRuntime({ agent, env: {} });
34
+ const result = await exec.executeTool("greet", { name: "Alice" }, "s1", []);
35
+ expect(result).toBe("Hello, Alice!");
36
+ });
37
+
38
+ test("tool with KV access works end-to-end", async () => {
39
+ const kv = createUnstorageKv({ storage: createStorage() });
40
+ const agent: AgentDef = {
41
+ name: "kv-agent",
42
+ systemPrompt: "Be helpful.",
43
+ greeting: "Hello!",
44
+ maxSteps: 5,
45
+ tools: {
46
+ save: {
47
+ description: "Save a value",
48
+ parameters: z.object({ key: z.string(), value: z.string() }),
49
+ execute: async ({ key, value }: { key: string; value: string }, ctx) => {
50
+ await ctx.kv.set(key, value);
51
+ return "saved";
52
+ },
53
+ },
54
+ load: {
55
+ description: "Load a value",
56
+ parameters: z.object({ key: z.string() }),
57
+ execute: async ({ key }: { key: string }, ctx) => {
58
+ const val = await ctx.kv.get<string>(key);
59
+ return val ?? "not found";
60
+ },
61
+ },
62
+ },
63
+ };
64
+
65
+ const exec = createRuntime({ agent, env: {}, kv });
66
+ await exec.executeTool("save", { key: "color", value: "blue" }, "s1", []);
67
+ const result = await exec.executeTool("load", { key: "color" }, "s1", []);
68
+ expect(result).toBe("blue");
69
+ });
70
+
71
+ test("env vars are passed to tool context", async () => {
72
+ const agent: AgentDef = {
73
+ name: "env-agent",
74
+ systemPrompt: "Be helpful.",
75
+ greeting: "Hello!",
76
+ maxSteps: 5,
77
+ tools: {
78
+ check_key: {
79
+ description: "Check API key",
80
+ execute: (_args, ctx) => ctx.env.API_KEY ?? "missing",
81
+ },
82
+ },
83
+ };
84
+
85
+ const exec = createRuntime({ agent, env: { API_KEY: "sk-test-123" } });
86
+ const result = await exec.executeTool("check_key", {}, "s1", []);
87
+ expect(result).toBe("sk-test-123");
88
+ });
89
+
90
+ test("per-session state isolation", async () => {
91
+ const agent: AgentDef<{ count: number }> = {
92
+ name: "state-agent",
93
+ systemPrompt: "Be helpful.",
94
+ greeting: "Hello!",
95
+ maxSteps: 5,
96
+ state: () => ({ count: 0 }),
97
+ tools: {
98
+ increment: {
99
+ description: "Increment counter",
100
+ execute: (_args, ctx) => {
101
+ ctx.state.count += 1;
102
+ return String(ctx.state.count);
103
+ },
104
+ },
105
+ },
106
+ };
107
+
108
+ const exec = createRuntime({ agent, env: {} });
109
+ expect(await exec.executeTool("increment", {}, "session-a", [])).toBe("1");
110
+ expect(await exec.executeTool("increment", {}, "session-a", [])).toBe("2");
111
+ // Different session starts fresh
112
+ expect(await exec.executeTool("increment", {}, "session-b", [])).toBe("1");
113
+ });
114
+
115
+ test("unknown tool returns error JSON", async () => {
116
+ const agent: AgentDef = {
117
+ name: "test",
118
+ systemPrompt: "Be helpful.",
119
+ greeting: "Hello!",
120
+ maxSteps: 5,
121
+ tools: {},
122
+ };
123
+ const exec = createRuntime({ agent, env: {} });
124
+ const result = await exec.executeTool("nonexistent", {}, "s1", []);
125
+ expect(JSON.parse(result)).toEqual({ error: "Unknown tool: nonexistent" });
126
+ });
127
+
128
+ test("tool parameter validation rejects bad input", async () => {
129
+ const agent: AgentDef = {
130
+ name: "validation-agent",
131
+ systemPrompt: "Be helpful.",
132
+ greeting: "Hello!",
133
+ maxSteps: 5,
134
+ tools: {
135
+ typed: {
136
+ description: "Typed tool",
137
+ parameters: z.object({ count: z.number() }),
138
+ execute: ({ count }: { count: number }) => String(count * 2),
139
+ },
140
+ },
141
+ };
142
+
143
+ const exec = createRuntime({ agent, env: {} });
144
+ // Valid input
145
+ expect(await exec.executeTool("typed", { count: 5 }, "s1", [])).toBe("10");
146
+ // Invalid input
147
+ const err = await exec.executeTool("typed", { count: "not a number" }, "s1", []);
148
+ expect(err).toContain("error");
149
+ });
150
+
151
+ test("toAgentConfig produces serializable config", () => {
152
+ const agent: AgentDef = {
153
+ name: "config-test",
154
+ systemPrompt: "Custom instructions",
155
+ greeting: "Hello!",
156
+ maxSteps: 10,
157
+ tools: {},
158
+ builtinTools: ["web_search"],
159
+ toolChoice: "required",
160
+ };
161
+
162
+ const config = toAgentConfig(agent);
163
+ // Should survive JSON round-trip
164
+ const parsed = JSON.parse(JSON.stringify(config));
165
+ expect(parsed.name).toBe("config-test");
166
+ expect(parsed.systemPrompt).toBe("Custom instructions");
167
+ expect(parsed.builtinTools).toEqual(["web_search"]);
168
+ expect(parsed.maxSteps).toBe(10);
169
+ expect(parsed.toolChoice).toBe("required");
170
+ });
171
+
172
+ test("builtin tools are available alongside custom tools", async () => {
173
+ const agent: AgentDef = {
174
+ name: "mixed-tools",
175
+ systemPrompt: "Be helpful.",
176
+ greeting: "Hello!",
177
+ maxSteps: 5,
178
+ builtinTools: ["run_code"],
179
+ tools: {
180
+ custom: { description: "Custom tool", execute: () => "custom result" },
181
+ },
182
+ };
183
+
184
+ const exec = createRuntime({ agent, env: {} });
185
+ // Custom tool works
186
+ expect(await exec.executeTool("custom", {}, "s1", [])).toBe("custom result");
187
+ // Builtin tool works
188
+ const codeResult = await exec.executeTool(
189
+ "run_code",
190
+ { code: 'console.log("from builtin")' },
191
+ "s1",
192
+ [],
193
+ );
194
+ expect(codeResult).toBe("from builtin");
195
+ // Tool schemas include both
196
+ const names = exec.toolSchemas.map((s) => s.name);
197
+ expect(names).toContain("custom");
198
+ expect(names).toContain("run_code");
199
+ });
200
+
201
+ test("messages are passed through to tool context", async () => {
202
+ const agent: AgentDef = {
203
+ name: "messages-agent",
204
+ systemPrompt: "Be helpful.",
205
+ greeting: "Hello!",
206
+ maxSteps: 5,
207
+ tools: {
208
+ count_msgs: {
209
+ description: "Count messages",
210
+ execute: (_args, ctx) => String(ctx.messages.length),
211
+ },
212
+ },
213
+ };
214
+
215
+ const exec = createRuntime({ agent, env: {} });
216
+ const result = await exec.executeTool("count_msgs", {}, "s1", [
217
+ { role: "user", content: "hi" },
218
+ { role: "assistant", content: "hello" },
219
+ ]);
220
+ expect(result).toBe("2");
221
+ });
222
+ });