File size: 4,206 Bytes
fd2c364
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
  __resetActiveStoreForTests,
  setActiveSelection,
  setRegisteredBackends,
} from "#/api/backend-registry/active-store";
import type { Backend } from "#/api/backend-registry/types";
import AgentServerConversationService from "#/api/conversation-service/agent-server-conversation-service.api";
import {
  getFetchCall,
  getJsonBody,
  mockJsonResponse,
} from "./fetch-test-utils";

const cloudBackend: Backend = {
  id: "prod",
  name: "Production",
  host: "https://app.all-hands.dev",
  apiKey: "bearer-token",
  kind: "cloud",
};

const originalFetch = global.fetch;
const fetchMock = vi.fn();

beforeEach(() => {
  window.localStorage.clear();
  __resetActiveStoreForTests();
  setRegisteredBackends([cloudBackend]);
  setActiveSelection({ backendId: cloudBackend.id });
  fetchMock.mockReset();
  global.fetch = fetchMock as typeof fetch;
});

afterEach(() => {
  window.localStorage.clear();
  __resetActiveStoreForTests();
  fetchMock.mockReset();
  global.fetch = originalFetch;
});

describe("AgentServerConversationService cloud branch", () => {
  it("createConversation POSTs the cloud payload directly and returns a WORKING task", async () => {
    fetchMock.mockResolvedValue(
      mockJsonResponse({
        id: "task-123",
        created_by_user_id: null,
        status: "WORKING",
        detail: null,
        app_conversation_id: null,
        agent_server_url: null,
        request: {},
        created_at: "2026-05-06T00:00:00Z",
        updated_at: "2026-05-06T00:00:00Z",
      }),
    );

    const result = await AgentServerConversationService.createConversation({
      initialUserMsg: "fix the bug",
      conversationInstructions: "Optional title",
      metadata: {
        selected_repository: "user/repo",
        selected_branch: "main",
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        git_provider: "github" as any,
      },
    });

    expect(fetchMock).toHaveBeenCalledOnce();
    const [url, init] = getFetchCall(fetchMock);
    expect(url).toBe(`${cloudBackend.host}/api/v1/app-conversations`);
    expect(init).toMatchObject({
      method: "POST",
      headers: { Authorization: "Bearer bearer-token" },
    });
    const requestBody = getJsonBody(init);

    // cloud payload shape — flat fields, NO encrypted-settings round-trip.
    expect(requestBody.selected_repository).toBe("user/repo");
    expect(requestBody.selected_branch).toBe("main");
    expect(requestBody.git_provider).toBe("github");
    expect(requestBody.title).toBe("Optional title");
    expect(requestBody.initial_message).toEqual({
      role: "user",
      content: [{ type: "text", text: "fix the bug" }],
    });
    // The local-only encrypted-settings keys must NOT be present.
    expect(requestBody).not.toHaveProperty("agent_settings_encrypted");
    expect(requestBody).not.toHaveProperty("conversation_settings_encrypted");

    // The returned task is the upstream task — WORKING, no app_conversation_id yet.
    expect(result.id).toBe("task-123");
    expect(result.status).toBe("WORKING");
    expect(result.app_conversation_id).toBeNull();
  });

  it("getStartTask polls /api/v1/app-conversations/start-tasks?ids= directly", async () => {
    fetchMock.mockResolvedValue(
      mockJsonResponse([
        {
          id: "task-123",
          created_by_user_id: null,
          status: "READY",
          detail: null,
          app_conversation_id: "conv-456",
          agent_server_url: "https://runtime-456.app.all-hands.dev",
          request: {},
          created_at: "2026-05-06T00:00:00Z",
          updated_at: "2026-05-06T00:00:00Z",
        },
      ]),
    );

    const result =
      await AgentServerConversationService.getStartTask("task-123");

    const [url, init] = getFetchCall(fetchMock);
    expect(url).toBe(
      `${cloudBackend.host}/api/v1/app-conversations/start-tasks?ids=task-123`,
    );
    expect(init).toMatchObject({
      method: "GET",
      headers: { Authorization: "Bearer bearer-token" },
    });
    expect(result?.status).toBe("READY");
    expect(result?.app_conversation_id).toBe("conv-456");
  });
});