Provide a standalone agent client for l-ai-chat with service-token auth, safe at-least-once subscriptions, ordered cumulative ACK tracking, and self-contained gRPC fake tests. Co-authored-by: Cursor <cursoragent@cursor.com>
100 lines
2.3 KiB
Go
100 lines
2.3 KiB
Go
package chatclient_test
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
|
|
chatclient "git.be.kaien.ru/l-ai/l-ai-chat-client-go"
|
|
)
|
|
|
|
func ExampleNew() {
|
|
ctx := context.Background()
|
|
client, err := chatclient.New(ctx, "chat.internal:443",
|
|
chatclient.WithStaticToken("service-token-from-secret-store"),
|
|
)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer client.Close()
|
|
}
|
|
|
|
func ExampleClient_PostMessage() {
|
|
ctx := context.Background()
|
|
client, _ := chatclient.New(ctx, "chat.internal:443",
|
|
chatclient.WithStaticToken("service-token-from-secret-store"),
|
|
)
|
|
defer client.Close()
|
|
|
|
key := "security-agent:logical-action-123"
|
|
_, err := client.PostMessage(ctx, chatclient.PostMessageRequest{
|
|
TopicID: "11111111-1111-1111-1111-111111111111",
|
|
Content: "scan completed",
|
|
IdempotencyKey: key,
|
|
})
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func ExampleSubscription_sequential() {
|
|
ctx := context.Background()
|
|
client, _ := chatclient.New(ctx, "chat.internal:443",
|
|
chatclient.WithStaticToken("service-token-from-secret-store"),
|
|
)
|
|
defer client.Close()
|
|
|
|
sub, err := client.Subscribe(ctx, chatclient.SubscribeRequest{
|
|
TopicID: "11111111-1111-1111-1111-111111111111",
|
|
})
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer sub.Close()
|
|
|
|
for delivery := range sub.Deliveries() {
|
|
if err := process(ctx, delivery); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
if err := sub.MarkProcessed(ctx, delivery); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
if err := sub.Err(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func ExampleSubscription_concurrentProcessing() {
|
|
ctx := context.Background()
|
|
client, _ := chatclient.New(ctx, "chat.internal:443",
|
|
chatclient.WithStaticToken("service-token-from-secret-store"),
|
|
)
|
|
defer client.Close()
|
|
|
|
sub, err := client.Subscribe(ctx, chatclient.SubscribeRequest{
|
|
TopicID: "11111111-1111-1111-1111-111111111111",
|
|
})
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer sub.Close()
|
|
|
|
sem := make(chan struct{}, 4)
|
|
for delivery := range sub.Deliveries() {
|
|
delivery := delivery
|
|
sem <- struct{}{}
|
|
go func() {
|
|
defer func() { <-sem }()
|
|
if err := process(ctx, delivery); err != nil {
|
|
_ = sub.Close()
|
|
return
|
|
}
|
|
// Safe even when goroutines finish out of order: MarkProcessed
|
|
// advances only the processed prefix in actual delivery order.
|
|
_ = sub.MarkProcessed(ctx, delivery)
|
|
}()
|
|
}
|
|
}
|
|
|
|
func process(context.Context, chatclient.Delivery) error { return nil }
|