@mariozechner/pi-ai 0.30.2 → 0.31.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.
- package/README.md +0 -270
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/models.generated.d.ts +1084 -1063
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +3880 -3873
- package/dist/models.generated.js.map +1 -1
- package/dist/providers/google-gemini-cli.d.ts +6 -2
- package/dist/providers/google-gemini-cli.d.ts.map +1 -1
- package/dist/providers/google-gemini-cli.js +1 -0
- package/dist/providers/google-gemini-cli.js.map +1 -1
- package/dist/providers/google.d.ts +2 -2
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +1 -0
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/openai-completions.d.ts.map +1 -1
- package/dist/providers/openai-completions.js +13 -7
- package/dist/providers/openai-completions.js.map +1 -1
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +17 -15
- package/dist/stream.js.map +1 -1
- package/dist/utils/oauth/anthropic.d.ts.map +1 -1
- package/dist/utils/oauth/anthropic.js +3 -11
- package/dist/utils/oauth/anthropic.js.map +1 -1
- package/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/dist/utils/oauth/github-copilot.js +1 -1
- package/dist/utils/oauth/github-copilot.js.map +1 -1
- package/dist/utils/oauth/google-antigravity.d.ts +3 -0
- package/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
- package/dist/utils/oauth/google-antigravity.js +8 -13
- package/dist/utils/oauth/google-antigravity.js.map +1 -1
- package/dist/utils/oauth/google-gemini-cli.d.ts +3 -0
- package/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
- package/dist/utils/oauth/google-gemini-cli.js +8 -13
- package/dist/utils/oauth/google-gemini-cli.js.map +1 -1
- package/dist/utils/oauth/pkce.d.ts +13 -0
- package/dist/utils/oauth/pkce.d.ts.map +1 -0
- package/dist/utils/oauth/pkce.js +31 -0
- package/dist/utils/oauth/pkce.js.map +1 -0
- package/package.json +1 -1
- package/dist/agent/agent-loop.d.ts +0 -16
- package/dist/agent/agent-loop.d.ts.map +0 -1
- package/dist/agent/agent-loop.js +0 -286
- package/dist/agent/agent-loop.js.map +0 -1
- package/dist/agent/index.d.ts +0 -4
- package/dist/agent/index.d.ts.map +0 -1
- package/dist/agent/index.js +0 -3
- package/dist/agent/index.js.map +0 -1
- package/dist/agent/tools/calculate.d.ts +0 -15
- package/dist/agent/tools/calculate.d.ts.map +0 -1
- package/dist/agent/tools/calculate.js +0 -23
- package/dist/agent/tools/calculate.js.map +0 -1
- package/dist/agent/tools/get-current-time.d.ts +0 -15
- package/dist/agent/tools/get-current-time.d.ts.map +0 -1
- package/dist/agent/tools/get-current-time.js +0 -38
- package/dist/agent/tools/get-current-time.js.map +0 -1
- package/dist/agent/tools/index.d.ts +0 -3
- package/dist/agent/tools/index.d.ts.map +0 -1
- package/dist/agent/tools/index.js +0 -3
- package/dist/agent/tools/index.js.map +0 -1
- package/dist/agent/types.d.ts +0 -78
- package/dist/agent/types.d.ts.map +0 -1
- package/dist/agent/types.js +0 -2
- package/dist/agent/types.js.map +0 -1
package/README.md
CHANGED
|
@@ -782,276 +782,6 @@ const continuation = await complete(newModel, restored);
|
|
|
782
782
|
|
|
783
783
|
> **Note**: If the context contains images (encoded as base64 as shown in the Image Input section), those will also be serialized.
|
|
784
784
|
|
|
785
|
-
## Agent API
|
|
786
|
-
|
|
787
|
-
The Agent API provides a higher-level interface for building agents with tools. It handles tool execution, validation, and provides detailed event streaming for interactive applications.
|
|
788
|
-
|
|
789
|
-
### Event System
|
|
790
|
-
|
|
791
|
-
The Agent API streams events during execution, allowing you to build reactive UIs and track agent progress. The agent processes prompts in **turns**, where each turn consists of:
|
|
792
|
-
1. An assistant message (the LLM's response)
|
|
793
|
-
2. Optional tool executions if the assistant calls tools
|
|
794
|
-
3. Tool result messages that are fed back to the LLM
|
|
795
|
-
|
|
796
|
-
This continues until the assistant produces a response without tool calls.
|
|
797
|
-
|
|
798
|
-
**Queued messages**: If you provide `getQueuedMessages` in the loop config, the agent checks for queued user messages after each tool call. When queued messages are found, any remaining tool calls from the current assistant message are skipped and returned as error tool results (`isError: true`) with the message "Skipped due to queued user message." The queued user messages are injected before the next assistant response.
|
|
799
|
-
|
|
800
|
-
### Event Flow Example
|
|
801
|
-
|
|
802
|
-
Given a prompt asking to calculate two expressions and sum them:
|
|
803
|
-
|
|
804
|
-
```typescript
|
|
805
|
-
import { agentLoop, AgentContext, calculateTool } from '@mariozechner/pi-ai';
|
|
806
|
-
|
|
807
|
-
const context: AgentContext = {
|
|
808
|
-
systemPrompt: 'You are a helpful math assistant.',
|
|
809
|
-
messages: [],
|
|
810
|
-
tools: [calculateTool]
|
|
811
|
-
};
|
|
812
|
-
|
|
813
|
-
const stream = agentLoop(
|
|
814
|
-
{ role: 'user', content: 'Calculate 15 * 20 and 30 * 40, then sum the results', timestamp: Date.now() },
|
|
815
|
-
context,
|
|
816
|
-
{ model: getModel('openai', 'gpt-4o-mini') }
|
|
817
|
-
);
|
|
818
|
-
|
|
819
|
-
// Expected event sequence:
|
|
820
|
-
// 1. agent_start - Agent begins processing
|
|
821
|
-
// 2. turn_start - First turn begins
|
|
822
|
-
// 3. message_start - User message starts
|
|
823
|
-
// 4. message_end - User message ends
|
|
824
|
-
// 5. message_start - Assistant message starts
|
|
825
|
-
// 6. message_update - Assistant streams response with tool calls
|
|
826
|
-
// 7. message_end - Assistant message ends
|
|
827
|
-
// 8. tool_execution_start - First calculation (15 * 20)
|
|
828
|
-
// 9. tool_execution_update - Streaming progress (for long-running tools)
|
|
829
|
-
// 10. tool_execution_end - Result: 300
|
|
830
|
-
// 11. tool_execution_start - Second calculation (30 * 40)
|
|
831
|
-
// 12. tool_execution_update - Streaming progress
|
|
832
|
-
// 13. tool_execution_end - Result: 1200
|
|
833
|
-
// 12. message_start - Tool result message for first calculation
|
|
834
|
-
// 13. message_end - Tool result message ends
|
|
835
|
-
// 14. message_start - Tool result message for second calculation
|
|
836
|
-
// 15. message_end - Tool result message ends
|
|
837
|
-
// 16. turn_end - First turn ends with 2 tool results
|
|
838
|
-
// 17. turn_start - Second turn begins
|
|
839
|
-
// 18. message_start - Assistant message starts
|
|
840
|
-
// 19. message_update - Assistant streams response with sum calculation
|
|
841
|
-
// 20. message_end - Assistant message ends
|
|
842
|
-
// 21. tool_execution_start - Sum calculation (300 + 1200)
|
|
843
|
-
// 22. tool_execution_end - Result: 1500
|
|
844
|
-
// 23. message_start - Tool result message for sum
|
|
845
|
-
// 24. message_end - Tool result message ends
|
|
846
|
-
// 25. turn_end - Second turn ends with 1 tool result
|
|
847
|
-
// 26. turn_start - Third turn begins
|
|
848
|
-
// 27. message_start - Final assistant message starts
|
|
849
|
-
// 28. message_update - Assistant streams final answer
|
|
850
|
-
// 29. message_end - Final assistant message ends
|
|
851
|
-
// 30. turn_end - Third turn ends with 0 tool results
|
|
852
|
-
// 31. agent_end - Agent completes with all messages
|
|
853
|
-
```
|
|
854
|
-
|
|
855
|
-
### Handling Events
|
|
856
|
-
|
|
857
|
-
```typescript
|
|
858
|
-
for await (const event of stream) {
|
|
859
|
-
switch (event.type) {
|
|
860
|
-
case 'agent_start':
|
|
861
|
-
console.log('Agent started');
|
|
862
|
-
break;
|
|
863
|
-
|
|
864
|
-
case 'turn_start':
|
|
865
|
-
console.log('New turn started');
|
|
866
|
-
break;
|
|
867
|
-
|
|
868
|
-
case 'message_start':
|
|
869
|
-
console.log(`${event.message.role} message started`);
|
|
870
|
-
break;
|
|
871
|
-
|
|
872
|
-
case 'message_update':
|
|
873
|
-
// Only for assistant messages during streaming
|
|
874
|
-
if (event.message.content.some(c => c.type === 'text')) {
|
|
875
|
-
console.log('Assistant:', event.message.content);
|
|
876
|
-
}
|
|
877
|
-
break;
|
|
878
|
-
|
|
879
|
-
case 'tool_execution_start':
|
|
880
|
-
console.log(`Calling ${event.toolName} with:`, event.args);
|
|
881
|
-
break;
|
|
882
|
-
|
|
883
|
-
case 'tool_execution_update':
|
|
884
|
-
// Streaming progress for long-running tools (e.g., bash output)
|
|
885
|
-
console.log(`Progress:`, event.partialResult.content);
|
|
886
|
-
break;
|
|
887
|
-
|
|
888
|
-
case 'tool_execution_end':
|
|
889
|
-
if (event.isError) {
|
|
890
|
-
console.error(`Tool failed:`, event.result);
|
|
891
|
-
} else {
|
|
892
|
-
console.log(`Tool result:`, event.result.content);
|
|
893
|
-
}
|
|
894
|
-
break;
|
|
895
|
-
|
|
896
|
-
case 'turn_end':
|
|
897
|
-
console.log(`Turn ended with ${event.toolResults.length} tool calls`);
|
|
898
|
-
break;
|
|
899
|
-
|
|
900
|
-
case 'agent_end':
|
|
901
|
-
console.log(`Agent completed with ${event.messages.length} new messages`);
|
|
902
|
-
break;
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
// Get all messages generated during this agent execution
|
|
907
|
-
// These include the user message and can be directly appended to context.messages
|
|
908
|
-
const messages = await stream.result();
|
|
909
|
-
context.messages.push(...messages);
|
|
910
|
-
```
|
|
911
|
-
|
|
912
|
-
### Continuing from Existing Context
|
|
913
|
-
|
|
914
|
-
Use `agentLoopContinue` to resume an agent loop without adding a new user message. This is useful for:
|
|
915
|
-
- Retrying after context overflow (after compaction reduces context size)
|
|
916
|
-
- Resuming from tool results that were added manually to the context
|
|
917
|
-
|
|
918
|
-
```typescript
|
|
919
|
-
import { agentLoopContinue, AgentContext } from '@mariozechner/pi-ai';
|
|
920
|
-
|
|
921
|
-
// Context already has messages - last must be 'user' or 'toolResult'
|
|
922
|
-
const context: AgentContext = {
|
|
923
|
-
systemPrompt: 'You are helpful.',
|
|
924
|
-
messages: [userMessage, assistantMessage, toolResult],
|
|
925
|
-
tools: [myTool]
|
|
926
|
-
};
|
|
927
|
-
|
|
928
|
-
// Continue processing from the tool result
|
|
929
|
-
const stream = agentLoopContinue(context, { model });
|
|
930
|
-
|
|
931
|
-
for await (const event of stream) {
|
|
932
|
-
// Same events as agentLoop, but no user message events emitted
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
const newMessages = await stream.result();
|
|
936
|
-
```
|
|
937
|
-
|
|
938
|
-
**Validation**: Throws if context has no messages or if the last message is an assistant message.
|
|
939
|
-
|
|
940
|
-
### Defining Tools with TypeBox
|
|
941
|
-
|
|
942
|
-
Tools use TypeBox schemas for runtime validation and type inference:
|
|
943
|
-
|
|
944
|
-
```typescript
|
|
945
|
-
import { Type, Static, AgentTool, AgentToolResult, StringEnum } from '@mariozechner/pi-ai';
|
|
946
|
-
|
|
947
|
-
const weatherSchema = Type.Object({
|
|
948
|
-
city: Type.String({ minLength: 1 }),
|
|
949
|
-
units: StringEnum(['celsius', 'fahrenheit'], { default: 'celsius' })
|
|
950
|
-
});
|
|
951
|
-
|
|
952
|
-
type WeatherParams = Static<typeof weatherSchema>;
|
|
953
|
-
|
|
954
|
-
const weatherTool: AgentTool<typeof weatherSchema, { temp: number }> = {
|
|
955
|
-
label: 'Get Weather',
|
|
956
|
-
name: 'get_weather',
|
|
957
|
-
description: 'Get current weather for a city',
|
|
958
|
-
parameters: weatherSchema,
|
|
959
|
-
execute: async (toolCallId, args, signal, onUpdate) => {
|
|
960
|
-
// args is fully typed: { city: string, units: 'celsius' | 'fahrenheit' }
|
|
961
|
-
// signal: AbortSignal for cancellation
|
|
962
|
-
// onUpdate: Optional callback for streaming progress (emits tool_execution_update events)
|
|
963
|
-
const temp = Math.round(Math.random() * 30);
|
|
964
|
-
return {
|
|
965
|
-
content: [{ type: 'text', text: `Temperature in ${args.city}: ${temp}°${args.units[0].toUpperCase()}` }],
|
|
966
|
-
details: { temp }
|
|
967
|
-
};
|
|
968
|
-
}
|
|
969
|
-
};
|
|
970
|
-
|
|
971
|
-
// Tools can also return images alongside text
|
|
972
|
-
const chartTool: AgentTool<typeof Type.Object({ data: Type.Array(Type.Number()) })> = {
|
|
973
|
-
label: 'Generate Chart',
|
|
974
|
-
name: 'generate_chart',
|
|
975
|
-
description: 'Generate a chart from data',
|
|
976
|
-
parameters: Type.Object({ data: Type.Array(Type.Number()) }),
|
|
977
|
-
execute: async (toolCallId, args) => {
|
|
978
|
-
const chartImage = await generateChartImage(args.data);
|
|
979
|
-
return {
|
|
980
|
-
content: [
|
|
981
|
-
{ type: 'text', text: `Generated chart with ${args.data.length} data points` },
|
|
982
|
-
{ type: 'image', data: chartImage.toString('base64'), mimeType: 'image/png' }
|
|
983
|
-
]
|
|
984
|
-
};
|
|
985
|
-
}
|
|
986
|
-
};
|
|
987
|
-
|
|
988
|
-
// Tools can stream progress via the onUpdate callback (emits tool_execution_update events)
|
|
989
|
-
const bashTool: AgentTool<typeof Type.Object({ command: Type.String() }), { exitCode: number }> = {
|
|
990
|
-
label: 'Run Bash',
|
|
991
|
-
name: 'bash',
|
|
992
|
-
description: 'Execute a bash command',
|
|
993
|
-
parameters: Type.Object({ command: Type.String() }),
|
|
994
|
-
execute: async (toolCallId, args, signal, onUpdate) => {
|
|
995
|
-
let output = '';
|
|
996
|
-
const child = spawn('bash', ['-c', args.command]);
|
|
997
|
-
|
|
998
|
-
child.stdout.on('data', (data) => {
|
|
999
|
-
output += data.toString();
|
|
1000
|
-
// Stream partial output to UI via tool_execution_update events
|
|
1001
|
-
onUpdate?.({
|
|
1002
|
-
content: [{ type: 'text', text: output }],
|
|
1003
|
-
details: { exitCode: -1 } // Not finished yet
|
|
1004
|
-
});
|
|
1005
|
-
});
|
|
1006
|
-
|
|
1007
|
-
const exitCode = await new Promise<number>((resolve) => {
|
|
1008
|
-
child.on('close', resolve);
|
|
1009
|
-
});
|
|
1010
|
-
|
|
1011
|
-
return {
|
|
1012
|
-
content: [{ type: 'text', text: output }],
|
|
1013
|
-
details: { exitCode }
|
|
1014
|
-
};
|
|
1015
|
-
}
|
|
1016
|
-
};
|
|
1017
|
-
```
|
|
1018
|
-
|
|
1019
|
-
### Validation and Error Handling
|
|
1020
|
-
|
|
1021
|
-
Tool arguments are automatically validated using AJV with the TypeBox schema. Invalid arguments result in detailed error messages:
|
|
1022
|
-
|
|
1023
|
-
```typescript
|
|
1024
|
-
// If the LLM calls with invalid arguments:
|
|
1025
|
-
// get_weather({ city: '', units: 'kelvin' })
|
|
1026
|
-
|
|
1027
|
-
// The tool execution will fail with:
|
|
1028
|
-
/*
|
|
1029
|
-
Validation failed for tool "get_weather":
|
|
1030
|
-
- city: must NOT have fewer than 1 characters
|
|
1031
|
-
- units: must be equal to one of the allowed values
|
|
1032
|
-
|
|
1033
|
-
Received arguments:
|
|
1034
|
-
{
|
|
1035
|
-
"city": "",
|
|
1036
|
-
"units": "kelvin"
|
|
1037
|
-
}
|
|
1038
|
-
*/
|
|
1039
|
-
```
|
|
1040
|
-
|
|
1041
|
-
### Built-in Example Tools
|
|
1042
|
-
|
|
1043
|
-
The library includes example tools for common operations:
|
|
1044
|
-
|
|
1045
|
-
```typescript
|
|
1046
|
-
import { calculateTool, getCurrentTimeTool } from '@mariozechner/pi-ai';
|
|
1047
|
-
|
|
1048
|
-
const context: AgentContext = {
|
|
1049
|
-
systemPrompt: 'You are a helpful assistant.',
|
|
1050
|
-
messages: [],
|
|
1051
|
-
tools: [calculateTool, getCurrentTimeTool]
|
|
1052
|
-
};
|
|
1053
|
-
```
|
|
1054
|
-
|
|
1055
785
|
## Browser Usage
|
|
1056
786
|
|
|
1057
787
|
The library supports browser environments. You must pass the API key explicitly since environment variables are not available in browsers:
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * from "./agent/index.js";
|
|
2
1
|
export * from "./models.js";
|
|
3
2
|
export * from "./providers/anthropic.js";
|
|
4
3
|
export * from "./providers/google.js";
|
|
@@ -7,6 +6,7 @@ export * from "./providers/openai-completions.js";
|
|
|
7
6
|
export * from "./providers/openai-responses.js";
|
|
8
7
|
export * from "./stream.js";
|
|
9
8
|
export * from "./types.js";
|
|
9
|
+
export * from "./utils/event-stream.js";
|
|
10
10
|
export * from "./utils/oauth/index.js";
|
|
11
11
|
export * from "./utils/overflow.js";
|
|
12
12
|
export * from "./utils/typebox-helpers.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,iCAAiC,CAAC;AAChD,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC","sourcesContent":["export * from \"./models.js\";\nexport * from \"./providers/anthropic.js\";\nexport * from \"./providers/google.js\";\nexport * from \"./providers/google-gemini-cli.js\";\nexport * from \"./providers/openai-completions.js\";\nexport * from \"./providers/openai-responses.js\";\nexport * from \"./stream.js\";\nexport * from \"./types.js\";\nexport * from \"./utils/event-stream.js\";\nexport * from \"./utils/oauth/index.js\";\nexport * from \"./utils/overflow.js\";\nexport * from \"./utils/typebox-helpers.js\";\nexport * from \"./utils/validation.js\";\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * from "./agent/index.js";
|
|
2
1
|
export * from "./models.js";
|
|
3
2
|
export * from "./providers/anthropic.js";
|
|
4
3
|
export * from "./providers/google.js";
|
|
@@ -7,6 +6,7 @@ export * from "./providers/openai-completions.js";
|
|
|
7
6
|
export * from "./providers/openai-responses.js";
|
|
8
7
|
export * from "./stream.js";
|
|
9
8
|
export * from "./types.js";
|
|
9
|
+
export * from "./utils/event-stream.js";
|
|
10
10
|
export * from "./utils/oauth/index.js";
|
|
11
11
|
export * from "./utils/overflow.js";
|
|
12
12
|
export * from "./utils/typebox-helpers.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,iCAAiC,CAAC;AAChD,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC","sourcesContent":["export * from \"./models.js\";\nexport * from \"./providers/anthropic.js\";\nexport * from \"./providers/google.js\";\nexport * from \"./providers/google-gemini-cli.js\";\nexport * from \"./providers/openai-completions.js\";\nexport * from \"./providers/openai-responses.js\";\nexport * from \"./stream.js\";\nexport * from \"./types.js\";\nexport * from \"./utils/event-stream.js\";\nexport * from \"./utils/oauth/index.js\";\nexport * from \"./utils/overflow.js\";\nexport * from \"./utils/typebox-helpers.js\";\nexport * from \"./utils/validation.js\";\n"]}
|