on main help sign in
fix: quota for subagents in copilot
a94866cKujtim Hoxha
internal/agent/agentic_fetch_tool.go+1−1
@@ -143,7 +143,7 @@ func (c *coordinator) agenticFetchTool(_ context.Context, client *http.Client) (
143 return fantasy.ToolResponse{}, fmt.Errorf("error creating prompt: %s", err)
143 return fantasy.ToolResponse{}, fmt.Errorf("error creating prompt: %s", err)
144 }
144 }
145
145
146− _, small, err := c.buildAgentModels(ctx)
146+ _, small, err := c.buildAgentModels(ctx, true)
147 if err != nil {
147 if err != nil {
148 return fantasy.ToolResponse{}, fmt.Errorf("error building models: %s", err)
148 return fantasy.ToolResponse{}, fmt.Errorf("error building models: %s", err)
149 }
149 }
internal/agent/coordinator.go+9−9
@@ -317,7 +317,7 @@ func mergeCallOptions(model Model, cfg config.ProviderConfig) (fantasy.ProviderO
317}
317}
318
318
319func (c *coordinator) buildAgent(ctx context.Context, prompt *prompt.Prompt, agent config.Agent, isSubAgent bool) (SessionAgent, error) {
319func (c *coordinator) buildAgent(ctx context.Context, prompt *prompt.Prompt, agent config.Agent, isSubAgent bool) (SessionAgent, error) {
320− large, small, err := c.buildAgentModels(ctx)
320+ large, small, err := c.buildAgentModels(ctx, isSubAgent)
321 if err != nil {
321 if err != nil {
322 return nil, err
322 return nil, err
323 }
323 }
@@ -441,7 +441,7 @@ func (c *coordinator) buildTools(ctx context.Context, agent config.Agent) ([]fan
441}
441}
442
442
443// TODO: when we support multiple agents we need to change this so that we pass in the agent specific model config
443// TODO: when we support multiple agents we need to change this so that we pass in the agent specific model config
444−func (c *coordinator) buildAgentModels(ctx context.Context) (Model, Model, error) {
444+func (c *coordinator) buildAgentModels(ctx context.Context, isSubAgent bool) (Model, Model, error) {
445 largeModelCfg, ok := c.cfg.Models[config.SelectedModelTypeLarge]
445 largeModelCfg, ok := c.cfg.Models[config.SelectedModelTypeLarge]
446 if !ok {
446 if !ok {
447 return Model{}, Model{}, errors.New("large model not selected")
447 return Model{}, Model{}, errors.New("large model not selected")
@@ -456,7 +456,7 @@ func (c *coordinator) buildAgentModels(ctx context.Context) (Model, Model, error
456 return Model{}, Model{}, errors.New("large model provider not configured")
456 return Model{}, Model{}, errors.New("large model provider not configured")
457 }
457 }
458
458
459− largeProvider, err := c.buildProvider(largeProviderCfg, largeModelCfg)
459+ largeProvider, err := c.buildProvider(largeProviderCfg, largeModelCfg, isSubAgent)
460 if err != nil {
460 if err != nil {
461 return Model{}, Model{}, err
461 return Model{}, Model{}, err
462 }
462 }
@@ -466,7 +466,7 @@ func (c *coordinator) buildAgentModels(ctx context.Context) (Model, Model, error
466 return Model{}, Model{}, errors.New("large model provider not configured")
466 return Model{}, Model{}, errors.New("large model provider not configured")
467 }
467 }
468
468
469− smallProvider, err := c.buildProvider(smallProviderCfg, largeModelCfg)
469+ smallProvider, err := c.buildProvider(smallProviderCfg, largeModelCfg, isSubAgent)
470 if err != nil {
470 if err != nil {
471 return Model{}, Model{}, err
471 return Model{}, Model{}, err
472 }
472 }
@@ -583,7 +583,7 @@ func (c *coordinator) buildOpenrouterProvider(_, apiKey string, headers map[stri
583 return openrouter.New(opts...)
583 return openrouter.New(opts...)
584}
584}
585
585
586−func (c *coordinator) buildOpenaiCompatProvider(baseURL, apiKey string, headers map[string]string, extraBody map[string]any, providerID string) (fantasy.Provider, error) {
586+func (c *coordinator) buildOpenaiCompatProvider(baseURL, apiKey string, headers map[string]string, extraBody map[string]any, providerID string, isSubAgent bool) (fantasy.Provider, error) {
587 opts := []openaicompat.Option{
587 opts := []openaicompat.Option{
588 openaicompat.WithBaseURL(baseURL),
588 openaicompat.WithBaseURL(baseURL),
589 openaicompat.WithAPIKey(apiKey),
589 openaicompat.WithAPIKey(apiKey),
@@ -592,7 +592,7 @@ func (c *coordinator) buildOpenaiCompatProvider(baseURL, apiKey string, headers
592 // Set HTTP client based on provider and debug mode.
592 // Set HTTP client based on provider and debug mode.
593 var httpClient *http.Client
593 var httpClient *http.Client
594 if providerID == string(catwalk.InferenceProviderCopilot) {
594 if providerID == string(catwalk.InferenceProviderCopilot) {
595− httpClient = copilot.NewClient(c.cfg.Options.Debug)
595+ httpClient = copilot.NewClient(isSubAgent, c.cfg.Options.Debug)
596 } else if c.cfg.Options.Debug {
596 } else if c.cfg.Options.Debug {
597 httpClient = log.NewHTTPClient()
597 httpClient = log.NewHTTPClient()
598 }
598 }
@@ -714,7 +714,7 @@ func (c *coordinator) isAnthropicThinking(model config.SelectedModel) bool {
714 return false
714 return false
715}
715}
716
716
717−func (c *coordinator) buildProvider(providerCfg config.ProviderConfig, model config.SelectedModel) (fantasy.Provider, error) {
717+func (c *coordinator) buildProvider(providerCfg config.ProviderConfig, model config.SelectedModel, isSubAgent bool) (fantasy.Provider, error) {
718 headers := maps.Clone(providerCfg.ExtraHeaders)
718 headers := maps.Clone(providerCfg.ExtraHeaders)
719 if headers == nil {
719 if headers == nil {
720 headers = make(map[string]string)
720 headers = make(map[string]string)
@@ -754,7 +754,7 @@ func (c *coordinator) buildProvider(providerCfg config.ProviderConfig, model con
754 }
754 }
755 providerCfg.ExtraBody["tool_stream"] = true
755 providerCfg.ExtraBody["tool_stream"] = true
756 }
756 }
757− return c.buildOpenaiCompatProvider(baseURL, apiKey, headers, providerCfg.ExtraBody, providerCfg.ID)
757+ return c.buildOpenaiCompatProvider(baseURL, apiKey, headers, providerCfg.ExtraBody, providerCfg.ID, isSubAgent)
758 case hyper.Name:
758 case hyper.Name:
759 return c.buildHyperProvider(baseURL, apiKey)
759 return c.buildHyperProvider(baseURL, apiKey)
760 default:
760 default:
@@ -799,7 +799,7 @@ func (c *coordinator) Model() Model {
799
799
800func (c *coordinator) UpdateModels(ctx context.Context) error {
800func (c *coordinator) UpdateModels(ctx context.Context) error {
801 // build the models again so we make sure we get the latest config
801 // build the models again so we make sure we get the latest config
802− large, small, err := c.buildAgentModels(ctx)
802+ large, small, err := c.buildAgentModels(ctx, false)
803 if err != nil {
803 if err != nil {
804 return err
804 return err
805 }
805 }
internal/oauth/copilot/client.go+5−4
@@ -14,14 +14,15 @@ import (
14
14
15// NewClient creates a new HTTP client with a custom transport that adds the
15// NewClient creates a new HTTP client with a custom transport that adds the
16// X-Initiator header based on message history in the request body.
16// X-Initiator header based on message history in the request body.
17−func NewClient(debug bool) *http.Client {
17+func NewClient(isSubAgent, debug bool) *http.Client {
18 return &http.Client{
18 return &http.Client{
19− Transport: &initiatorTransport{debug: debug},
19+ Transport: &initiatorTransport{debug: debug, isSubAgent: isSubAgent},
20 }
20 }
21}
21}
22
22
23type initiatorTransport struct {
23type initiatorTransport struct {
24− debug bool
24+ debug bool
25+ isSubAgent bool
25}
26}
26
27
27func (t *initiatorTransport) RoundTrip(req *http.Request) (*http.Response, error) {
28func (t *initiatorTransport) RoundTrip(req *http.Request) (*http.Response, error) {
@@ -58,7 +59,7 @@ func (t *initiatorTransport) RoundTrip(req *http.Request) (*http.Response, error
58 // variations in the JSON while avoiding full unmarshalling overhead.
59 // variations in the JSON while avoiding full unmarshalling overhead.
59 initiator := userInitiator
60 initiator := userInitiator
60 assistantRolePattern := regexp.MustCompile(`"role"\s*:\s*"assistant"`)
61 assistantRolePattern := regexp.MustCompile(`"role"\s*:\s*"assistant"`)
61− if assistantRolePattern.Match(bodyBytes) {
62+ if assistantRolePattern.Match(bodyBytes) || t.isSubAgent {
62 slog.Debug("Setting X-Initiator header to agent (found assistant messages in history)")
63 slog.Debug("Setting X-Initiator header to agent (found assistant messages in history)")
63 initiator = agentInitiator
64 initiator = agentInitiator
64 } else {
65 } else {