applied-cli 0.5.55__tar.gz → 0.5.56__tar.gz
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.
- {applied_cli-0.5.55 → applied_cli-0.5.56}/PKG-INFO +1 -1
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli/__init__.py +1 -1
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli/cli.py +285 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli/client.py +135 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli/tools.py +205 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli.egg-info/PKG-INFO +1 -1
- {applied_cli-0.5.55 → applied_cli-0.5.56}/pyproject.toml +1 -1
- {applied_cli-0.5.55 → applied_cli-0.5.56}/README.md +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli/agent_scoped_flows.py +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli/conversation_lookup.py +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli/conversations.py +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli/credentials.py +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli/flow_helpers.py +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli/formatters.py +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli.egg-info/SOURCES.txt +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli.egg-info/dependency_links.txt +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli.egg-info/entry_points.txt +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli.egg-info/requires.txt +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/applied_cli.egg-info/top_level.txt +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/setup.cfg +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/tests/test_agent_scoped_flows.py +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/tests/test_audit_tools.py +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/tests/test_benchmark_scenario_tools.py +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/tests/test_cli.py +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/tests/test_client.py +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/tests/test_conversation_tools.py +0 -0
- {applied_cli-0.5.55 → applied_cli-0.5.56}/tests/test_flow_tools.py +0 -0
|
@@ -1853,6 +1853,291 @@ def connector_types(
|
|
|
1853
1853
|
typer.echo(result)
|
|
1854
1854
|
|
|
1855
1855
|
|
|
1856
|
+
@app.command("agent-update")
|
|
1857
|
+
def agent_update(
|
|
1858
|
+
id: str = typer.Argument(..., help="Agent ID"),
|
|
1859
|
+
name: str = typer.Option(None, "--name", help="Agent name"),
|
|
1860
|
+
prompt: str = typer.Option(None, "--prompt", help="Guidance/guardrails text"),
|
|
1861
|
+
model: str = typer.Option(None, "--model", help="Model name"),
|
|
1862
|
+
modality: str = typer.Option(
|
|
1863
|
+
None, "--modality", help="Modality: Chat, Email, Call, SMS, All"
|
|
1864
|
+
),
|
|
1865
|
+
agent_type: str = typer.Option(
|
|
1866
|
+
None, "--type", help="Type: Customer Support, Generic, etc."
|
|
1867
|
+
),
|
|
1868
|
+
escalation_mode: str = typer.Option(
|
|
1869
|
+
None,
|
|
1870
|
+
"--escalation-mode",
|
|
1871
|
+
help="Escalation mode: default, email, sms, email_non_opening_hours, ticketing_integration",
|
|
1872
|
+
),
|
|
1873
|
+
auto_reply: bool = typer.Option(None, "--auto-reply", help="Enable auto-reply"),
|
|
1874
|
+
metadata: str = typer.Option(
|
|
1875
|
+
None, "--metadata", help="JSON metadata to set on the agent"
|
|
1876
|
+
),
|
|
1877
|
+
shop_id: str = typer.Option(None, "--shop-id", help="Override shop ID"),
|
|
1878
|
+
) -> None:
|
|
1879
|
+
"""Update an agent."""
|
|
1880
|
+
metadata_dict = _parse_json_option(metadata, option_name="--metadata")
|
|
1881
|
+
client = get_client(shop_id=shop_id)
|
|
1882
|
+
result = asyncio.run(
|
|
1883
|
+
tools.agent_update(
|
|
1884
|
+
client,
|
|
1885
|
+
id,
|
|
1886
|
+
name=name,
|
|
1887
|
+
prompt=prompt,
|
|
1888
|
+
model=model,
|
|
1889
|
+
modality=modality,
|
|
1890
|
+
agent_type=agent_type,
|
|
1891
|
+
escalation_mode=escalation_mode,
|
|
1892
|
+
auto_reply=auto_reply,
|
|
1893
|
+
metadata=metadata_dict,
|
|
1894
|
+
)
|
|
1895
|
+
)
|
|
1896
|
+
typer.echo(result)
|
|
1897
|
+
|
|
1898
|
+
|
|
1899
|
+
@app.command("knowledge-create")
|
|
1900
|
+
def knowledge_create(
|
|
1901
|
+
kb_type: str = typer.Option(
|
|
1902
|
+
..., "--type", "-t", help="Type: qa, exact, escalate, context, greeting, signature"
|
|
1903
|
+
),
|
|
1904
|
+
question: str = typer.Option(..., "--question", "-q", help="Trigger text / question"),
|
|
1905
|
+
answer: str = typer.Option(..., "--answer", "-a", help="Response text / answer"),
|
|
1906
|
+
guardrail: str = typer.Option("", "--guardrail", help="Guardrail instructions"),
|
|
1907
|
+
active: bool = typer.Option(True, "--active/--inactive", help="Whether the item is active"),
|
|
1908
|
+
agent_ids: str = typer.Option(
|
|
1909
|
+
None, "--agent-ids", help="Comma-separated agent UUIDs (empty = shop-wide)"
|
|
1910
|
+
),
|
|
1911
|
+
label_id: str = typer.Option(None, "--label-id", help="Topic label UUID"),
|
|
1912
|
+
flow_id: str = typer.Option(None, "--flow-id", help="Flow UUID to associate with"),
|
|
1913
|
+
shop_id: str = typer.Option(None, "--shop-id", help="Override shop ID"),
|
|
1914
|
+
) -> None:
|
|
1915
|
+
"""Create a knowledge base item."""
|
|
1916
|
+
parsed_agent_ids = _parse_csv_option(agent_ids)
|
|
1917
|
+
client = get_client(shop_id=shop_id)
|
|
1918
|
+
result = asyncio.run(
|
|
1919
|
+
tools.knowledge_create(
|
|
1920
|
+
client,
|
|
1921
|
+
kb_type=kb_type,
|
|
1922
|
+
question=question,
|
|
1923
|
+
answer=answer,
|
|
1924
|
+
guardrail=guardrail,
|
|
1925
|
+
active=active,
|
|
1926
|
+
agent_ids=parsed_agent_ids,
|
|
1927
|
+
label_id=label_id,
|
|
1928
|
+
flow_id=flow_id,
|
|
1929
|
+
)
|
|
1930
|
+
)
|
|
1931
|
+
typer.echo(result)
|
|
1932
|
+
|
|
1933
|
+
|
|
1934
|
+
@app.command("knowledge-update")
|
|
1935
|
+
def knowledge_update(
|
|
1936
|
+
id: str = typer.Argument(..., help="Knowledge item ID"),
|
|
1937
|
+
question: str = typer.Option(None, "--question", "-q", help="Trigger text / question"),
|
|
1938
|
+
answer: str = typer.Option(None, "--answer", "-a", help="Response text / answer"),
|
|
1939
|
+
guardrail: str = typer.Option(None, "--guardrail", help="Guardrail instructions"),
|
|
1940
|
+
active: bool = typer.Option(None, "--active/--inactive", help="Whether the item is active"),
|
|
1941
|
+
shop_id: str = typer.Option(None, "--shop-id", help="Override shop ID"),
|
|
1942
|
+
) -> None:
|
|
1943
|
+
"""Update a knowledge base item."""
|
|
1944
|
+
client = get_client(shop_id=shop_id)
|
|
1945
|
+
result = asyncio.run(
|
|
1946
|
+
tools.knowledge_update(
|
|
1947
|
+
client,
|
|
1948
|
+
id,
|
|
1949
|
+
question=question,
|
|
1950
|
+
answer=answer,
|
|
1951
|
+
guardrail=guardrail,
|
|
1952
|
+
active=active,
|
|
1953
|
+
)
|
|
1954
|
+
)
|
|
1955
|
+
typer.echo(result)
|
|
1956
|
+
|
|
1957
|
+
|
|
1958
|
+
@app.command("product-create")
|
|
1959
|
+
def product_create(
|
|
1960
|
+
title: str = typer.Option(..., "--title", help="Product title"),
|
|
1961
|
+
description: str = typer.Option("", "--description", help="Product description"),
|
|
1962
|
+
url: str = typer.Option("", "--url", help="Product page URL"),
|
|
1963
|
+
images: str = typer.Option(None, "--images", help="Comma-separated image URLs"),
|
|
1964
|
+
price: str = typer.Option(None, "--price", help="Price (e.g. '29.99')"),
|
|
1965
|
+
compare_at_price: str = typer.Option(None, "--compare-at-price", help="Compare-at price"),
|
|
1966
|
+
currency: str = typer.Option("USD", "--currency", help="Currency code"),
|
|
1967
|
+
rating: float = typer.Option(None, "--rating", help="Average rating"),
|
|
1968
|
+
review_count: int = typer.Option(None, "--review-count", help="Number of reviews"),
|
|
1969
|
+
status: str = typer.Option("Active", "--status", help="Status: Active, Draft, Pending"),
|
|
1970
|
+
auto_generate_kb: bool = typer.Option(
|
|
1971
|
+
True, "--auto-generate-kb/--no-auto-generate-kb", help="Auto-generate Q&A"
|
|
1972
|
+
),
|
|
1973
|
+
shop_id: str = typer.Option(None, "--shop-id", help="Override shop ID"),
|
|
1974
|
+
) -> None:
|
|
1975
|
+
"""Create a product."""
|
|
1976
|
+
parsed_images = _parse_csv_option(images)
|
|
1977
|
+
client = get_client(shop_id=shop_id)
|
|
1978
|
+
result = asyncio.run(
|
|
1979
|
+
tools.product_create(
|
|
1980
|
+
client,
|
|
1981
|
+
title=title,
|
|
1982
|
+
description=description,
|
|
1983
|
+
url=url,
|
|
1984
|
+
images=parsed_images,
|
|
1985
|
+
price=price,
|
|
1986
|
+
compare_at_price=compare_at_price,
|
|
1987
|
+
currency=currency,
|
|
1988
|
+
rating=rating,
|
|
1989
|
+
review_count=review_count,
|
|
1990
|
+
status=status,
|
|
1991
|
+
auto_generate_kb=auto_generate_kb,
|
|
1992
|
+
)
|
|
1993
|
+
)
|
|
1994
|
+
typer.echo(result)
|
|
1995
|
+
|
|
1996
|
+
|
|
1997
|
+
@app.command("taxonomy-create")
|
|
1998
|
+
def taxonomy_create(
|
|
1999
|
+
name: str = typer.Option(..., "--name", "-n", help="Topic or intent name"),
|
|
2000
|
+
parent_id: str = typer.Option(
|
|
2001
|
+
None, "--parent-id", help="Parent topic UUID (if set, creates an intent)"
|
|
2002
|
+
),
|
|
2003
|
+
color: str = typer.Option(None, "--color", help="Color"),
|
|
2004
|
+
description: str = typer.Option(None, "--description", help="Description"),
|
|
2005
|
+
comments: str = typer.Option(None, "--comments", help="Example queries (3 per line)"),
|
|
2006
|
+
shop_id: str = typer.Option(None, "--shop-id", help="Override shop ID"),
|
|
2007
|
+
) -> None:
|
|
2008
|
+
"""Create a topic or intent."""
|
|
2009
|
+
client = get_client(shop_id=shop_id)
|
|
2010
|
+
result = asyncio.run(
|
|
2011
|
+
tools.taxonomy_create(
|
|
2012
|
+
client,
|
|
2013
|
+
name=name,
|
|
2014
|
+
parent_id=parent_id,
|
|
2015
|
+
color=color,
|
|
2016
|
+
description=description,
|
|
2017
|
+
comments=comments,
|
|
2018
|
+
)
|
|
2019
|
+
)
|
|
2020
|
+
typer.echo(result)
|
|
2021
|
+
|
|
2022
|
+
|
|
2023
|
+
@app.command("taxonomy-update")
|
|
2024
|
+
def taxonomy_update(
|
|
2025
|
+
id: str = typer.Argument(..., help="Topic or intent ID"),
|
|
2026
|
+
name: str = typer.Option(None, "--name", "-n", help="Name"),
|
|
2027
|
+
color: str = typer.Option(None, "--color", help="Color"),
|
|
2028
|
+
description: str = typer.Option(None, "--description", help="Description"),
|
|
2029
|
+
comments: str = typer.Option(None, "--comments", help="Example queries"),
|
|
2030
|
+
shop_id: str = typer.Option(None, "--shop-id", help="Override shop ID"),
|
|
2031
|
+
) -> None:
|
|
2032
|
+
"""Update a topic or intent."""
|
|
2033
|
+
client = get_client(shop_id=shop_id)
|
|
2034
|
+
result = asyncio.run(
|
|
2035
|
+
tools.taxonomy_update(
|
|
2036
|
+
client,
|
|
2037
|
+
id,
|
|
2038
|
+
name=name,
|
|
2039
|
+
color=color,
|
|
2040
|
+
description=description,
|
|
2041
|
+
comments=comments,
|
|
2042
|
+
)
|
|
2043
|
+
)
|
|
2044
|
+
typer.echo(result)
|
|
2045
|
+
|
|
2046
|
+
|
|
2047
|
+
@app.command("agent-create")
|
|
2048
|
+
def agent_create(
|
|
2049
|
+
name: str = typer.Option(..., "--name", help="Agent name"),
|
|
2050
|
+
modality: str = typer.Option(
|
|
2051
|
+
..., "--modality", help="Modality: Chat, Email, Call, SMS, All"
|
|
2052
|
+
),
|
|
2053
|
+
agent_type: str = typer.Option(
|
|
2054
|
+
"Customer Support", "--type", help="Type: Customer Support, Generic, etc."
|
|
2055
|
+
),
|
|
2056
|
+
model: str = typer.Option("GPT-4.1-mini", "--model", help="Model name"),
|
|
2057
|
+
prompt: str = typer.Option("", "--prompt", help="Guidance/guardrails text"),
|
|
2058
|
+
escalation_mode: str = typer.Option(
|
|
2059
|
+
"default",
|
|
2060
|
+
"--escalation-mode",
|
|
2061
|
+
help="Escalation mode: default, email, sms, email_non_opening_hours, ticketing_integration",
|
|
2062
|
+
),
|
|
2063
|
+
auto_reply: bool = typer.Option(False, "--auto-reply", help="Enable auto-reply"),
|
|
2064
|
+
shop_id: str = typer.Option(None, "--shop-id", help="Override shop ID"),
|
|
2065
|
+
) -> None:
|
|
2066
|
+
"""Create a new agent."""
|
|
2067
|
+
client = get_client(shop_id=shop_id)
|
|
2068
|
+
result = asyncio.run(
|
|
2069
|
+
tools.agent_create(
|
|
2070
|
+
client,
|
|
2071
|
+
name=name,
|
|
2072
|
+
modality=modality,
|
|
2073
|
+
agent_type=agent_type,
|
|
2074
|
+
model=model,
|
|
2075
|
+
prompt=prompt,
|
|
2076
|
+
escalation_mode=escalation_mode,
|
|
2077
|
+
auto_reply=auto_reply,
|
|
2078
|
+
)
|
|
2079
|
+
)
|
|
2080
|
+
typer.echo(result)
|
|
2081
|
+
|
|
2082
|
+
|
|
2083
|
+
@app.command("agent-set-picture")
|
|
2084
|
+
def agent_set_picture(
|
|
2085
|
+
id: str = typer.Argument(..., help="Agent ID"),
|
|
2086
|
+
image: str = typer.Option(
|
|
2087
|
+
..., "--image", "-i", help="Path to image file (PNG, JPG, etc.)"
|
|
2088
|
+
),
|
|
2089
|
+
shop_id: str = typer.Option(None, "--shop-id", help="Override shop ID"),
|
|
2090
|
+
) -> None:
|
|
2091
|
+
"""Set an agent's profile picture."""
|
|
2092
|
+
client = get_client(shop_id=shop_id)
|
|
2093
|
+
result = asyncio.run(tools.agent_set_picture(client, id, image))
|
|
2094
|
+
typer.echo(result)
|
|
2095
|
+
|
|
2096
|
+
|
|
2097
|
+
@app.command("agent-delete")
|
|
2098
|
+
def agent_delete(
|
|
2099
|
+
id: str = typer.Argument(..., help="Agent ID"),
|
|
2100
|
+
shop_id: str = typer.Option(None, "--shop-id", help="Override shop ID"),
|
|
2101
|
+
) -> None:
|
|
2102
|
+
"""Delete an agent."""
|
|
2103
|
+
client = get_client(shop_id=shop_id)
|
|
2104
|
+
result = asyncio.run(tools.agent_delete(client, id))
|
|
2105
|
+
typer.echo(result)
|
|
2106
|
+
|
|
2107
|
+
|
|
2108
|
+
@app.command("knowledge-delete")
|
|
2109
|
+
def knowledge_delete(
|
|
2110
|
+
id: str = typer.Argument(..., help="Knowledge item ID"),
|
|
2111
|
+
shop_id: str = typer.Option(None, "--shop-id", help="Override shop ID"),
|
|
2112
|
+
) -> None:
|
|
2113
|
+
"""Delete a knowledge base item."""
|
|
2114
|
+
client = get_client(shop_id=shop_id)
|
|
2115
|
+
result = asyncio.run(tools.knowledge_delete(client, id))
|
|
2116
|
+
typer.echo(result)
|
|
2117
|
+
|
|
2118
|
+
|
|
2119
|
+
@app.command("product-delete")
|
|
2120
|
+
def product_delete(
|
|
2121
|
+
id: str = typer.Argument(..., help="Product ID"),
|
|
2122
|
+
shop_id: str = typer.Option(None, "--shop-id", help="Override shop ID"),
|
|
2123
|
+
) -> None:
|
|
2124
|
+
"""Delete a product."""
|
|
2125
|
+
client = get_client(shop_id=shop_id)
|
|
2126
|
+
result = asyncio.run(tools.product_delete(client, id))
|
|
2127
|
+
typer.echo(result)
|
|
2128
|
+
|
|
2129
|
+
|
|
2130
|
+
@app.command("taxonomy-delete")
|
|
2131
|
+
def taxonomy_delete(
|
|
2132
|
+
id: str = typer.Argument(..., help="Topic or intent ID"),
|
|
2133
|
+
shop_id: str = typer.Option(None, "--shop-id", help="Override shop ID"),
|
|
2134
|
+
) -> None:
|
|
2135
|
+
"""Delete a topic or intent."""
|
|
2136
|
+
client = get_client(shop_id=shop_id)
|
|
2137
|
+
result = asyncio.run(tools.taxonomy_delete(client, id))
|
|
2138
|
+
typer.echo(result)
|
|
2139
|
+
|
|
2140
|
+
|
|
1856
2141
|
def main() -> None:
|
|
1857
2142
|
"""CLI entrypoint."""
|
|
1858
2143
|
nested_exit_code = run_agent_scoped_flow_command(sys.argv[1:], get_client)
|
|
@@ -382,6 +382,50 @@ class AppliedClient:
|
|
|
382
382
|
return None
|
|
383
383
|
return resp.json()
|
|
384
384
|
|
|
385
|
+
async def _upload_request(
|
|
386
|
+
self,
|
|
387
|
+
method: str,
|
|
388
|
+
path: str,
|
|
389
|
+
files: dict[str, Any],
|
|
390
|
+
data: dict[str, Any] | None = None,
|
|
391
|
+
) -> Any:
|
|
392
|
+
"""Make an authenticated multipart file upload request."""
|
|
393
|
+
headers = {
|
|
394
|
+
"Authorization": f"Bearer {self.token}",
|
|
395
|
+
}
|
|
396
|
+
if self.shop_id:
|
|
397
|
+
headers["X-Shop-Id"] = self.shop_id
|
|
398
|
+
url = f"{self.base_url}{path}"
|
|
399
|
+
|
|
400
|
+
async with httpx.AsyncClient(timeout=self.timeout) as client:
|
|
401
|
+
resp = await client.request(
|
|
402
|
+
method, url, headers=headers, files=files, data=data or {}
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
if resp.status_code >= 400:
|
|
406
|
+
detail = ""
|
|
407
|
+
try:
|
|
408
|
+
err_data = resp.json()
|
|
409
|
+
if isinstance(err_data, dict):
|
|
410
|
+
detail = str(
|
|
411
|
+
err_data.get("detail")
|
|
412
|
+
or err_data.get("error")
|
|
413
|
+
or err_data.get("message")
|
|
414
|
+
or ""
|
|
415
|
+
)
|
|
416
|
+
except Exception:
|
|
417
|
+
detail = resp.text[:200] if resp.text else ""
|
|
418
|
+
|
|
419
|
+
raise AppliedAPIError(
|
|
420
|
+
message=f"{method} {path} failed",
|
|
421
|
+
status_code=resp.status_code,
|
|
422
|
+
detail=detail,
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
if resp.status_code == 204:
|
|
426
|
+
return None
|
|
427
|
+
return resp.json()
|
|
428
|
+
|
|
385
429
|
def _require_shop_id(self, shop_id: str | None = None) -> str:
|
|
386
430
|
resolved_shop_id = shop_id or self.shop_id
|
|
387
431
|
if not resolved_shop_id:
|
|
@@ -431,6 +475,59 @@ class AppliedClient:
|
|
|
431
475
|
)
|
|
432
476
|
return self._normalize_response(data)
|
|
433
477
|
|
|
478
|
+
async def create_agent(
|
|
479
|
+
self,
|
|
480
|
+
name: str,
|
|
481
|
+
modality: str,
|
|
482
|
+
agent_type: str = "Customer Support",
|
|
483
|
+
model: str = "GPT-4.1-mini",
|
|
484
|
+
prompt: str = "",
|
|
485
|
+
escalation_mode: str = "default",
|
|
486
|
+
auto_reply: bool = False,
|
|
487
|
+
) -> dict:
|
|
488
|
+
"""Create a new agent."""
|
|
489
|
+
body: dict[str, Any] = {
|
|
490
|
+
"name": name,
|
|
491
|
+
"modality": modality,
|
|
492
|
+
"type": agent_type,
|
|
493
|
+
"model": model,
|
|
494
|
+
"escalation_mode": escalation_mode,
|
|
495
|
+
"auto_reply": auto_reply,
|
|
496
|
+
}
|
|
497
|
+
if prompt:
|
|
498
|
+
body["prompt"] = prompt
|
|
499
|
+
return await self._request("POST", "/v1/agents/", body=body)
|
|
500
|
+
|
|
501
|
+
async def update_agent(
|
|
502
|
+
self,
|
|
503
|
+
agent_id: str,
|
|
504
|
+
**kwargs: Any,
|
|
505
|
+
) -> dict:
|
|
506
|
+
"""Update an agent's properties."""
|
|
507
|
+
return await self._request(
|
|
508
|
+
"PATCH", f"/v1/agents/{agent_id}/", body=kwargs
|
|
509
|
+
)
|
|
510
|
+
|
|
511
|
+
async def update_agent_picture(
|
|
512
|
+
self,
|
|
513
|
+
agent_id: str,
|
|
514
|
+
image_path: str,
|
|
515
|
+
) -> dict:
|
|
516
|
+
"""Update an agent's profile picture via file upload."""
|
|
517
|
+
import mimetypes
|
|
518
|
+
|
|
519
|
+
content_type = mimetypes.guess_type(image_path)[0] or "image/png"
|
|
520
|
+
filename = image_path.rsplit("/", 1)[-1]
|
|
521
|
+
with open(image_path, "rb") as f:
|
|
522
|
+
files = {"profile_picture": (filename, f, content_type)}
|
|
523
|
+
return await self._upload_request(
|
|
524
|
+
"PATCH", f"/v1/agents/{agent_id}/", files=files
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
async def delete_agent(self, agent_id: str) -> None:
|
|
528
|
+
"""Delete an agent."""
|
|
529
|
+
await self._request("DELETE", f"/v1/agents/{agent_id}/")
|
|
530
|
+
|
|
434
531
|
# -------------------------------------------------------------------------
|
|
435
532
|
# Connector Types
|
|
436
533
|
# -------------------------------------------------------------------------
|
|
@@ -471,6 +568,40 @@ class AppliedClient:
|
|
|
471
568
|
data = await self._request("GET", "/v1/property-choices/", params=params)
|
|
472
569
|
return self._normalize_response(data)
|
|
473
570
|
|
|
571
|
+
async def create_taxonomy(
|
|
572
|
+
self,
|
|
573
|
+
name: str,
|
|
574
|
+
parent_id: str | None = None,
|
|
575
|
+
color: str | None = None,
|
|
576
|
+
description: str | None = None,
|
|
577
|
+
comments: str | None = None,
|
|
578
|
+
) -> dict:
|
|
579
|
+
"""Create a topic or intent (property choice)."""
|
|
580
|
+
body: dict[str, Any] = {"name": name}
|
|
581
|
+
if parent_id:
|
|
582
|
+
body["parent_choice_id"] = parent_id
|
|
583
|
+
if color:
|
|
584
|
+
body["color"] = color
|
|
585
|
+
if description:
|
|
586
|
+
body["description"] = description
|
|
587
|
+
if comments:
|
|
588
|
+
body["comments"] = comments
|
|
589
|
+
return await self._request("POST", "/v1/property-choices/", body=body)
|
|
590
|
+
|
|
591
|
+
async def update_taxonomy(
|
|
592
|
+
self,
|
|
593
|
+
choice_id: str,
|
|
594
|
+
**kwargs: Any,
|
|
595
|
+
) -> dict:
|
|
596
|
+
"""Update a topic or intent (property choice)."""
|
|
597
|
+
return await self._request(
|
|
598
|
+
"PATCH", f"/v1/property-choices/{choice_id}/", body=kwargs
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
async def delete_taxonomy(self, choice_id: str) -> None:
|
|
602
|
+
"""Delete a topic or intent (property choice)."""
|
|
603
|
+
await self._request("DELETE", f"/v1/property-choices/{choice_id}/")
|
|
604
|
+
|
|
474
605
|
# -------------------------------------------------------------------------
|
|
475
606
|
# Analytics
|
|
476
607
|
# -------------------------------------------------------------------------
|
|
@@ -2057,6 +2188,10 @@ class AppliedClient:
|
|
|
2057
2188
|
"PATCH", f"/v1/responses/{response_id}/", body=kwargs
|
|
2058
2189
|
)
|
|
2059
2190
|
|
|
2191
|
+
async def delete_response(self, response_id: str) -> None:
|
|
2192
|
+
"""Delete a knowledge base item."""
|
|
2193
|
+
await self._request("DELETE", f"/v1/responses/{response_id}/")
|
|
2194
|
+
|
|
2060
2195
|
# -------------------------------------------------------------------------
|
|
2061
2196
|
# Products (Content type=Product)
|
|
2062
2197
|
# -------------------------------------------------------------------------
|
|
@@ -5941,3 +5941,208 @@ async def product_delete(
|
|
|
5941
5941
|
return _format_error(e)
|
|
5942
5942
|
|
|
5943
5943
|
return f"Product {product_id} deleted successfully."
|
|
5944
|
+
|
|
5945
|
+
|
|
5946
|
+
# -----------------------------------------------------------------------------
|
|
5947
|
+
# Agent - Create / Update / Delete
|
|
5948
|
+
# -----------------------------------------------------------------------------
|
|
5949
|
+
|
|
5950
|
+
|
|
5951
|
+
async def agent_create(
|
|
5952
|
+
client: AppliedClient,
|
|
5953
|
+
name: str,
|
|
5954
|
+
modality: str,
|
|
5955
|
+
agent_type: str = "Customer Support",
|
|
5956
|
+
model: str = "GPT-4.1-mini",
|
|
5957
|
+
prompt: str = "",
|
|
5958
|
+
escalation_mode: str = "default",
|
|
5959
|
+
auto_reply: bool = False,
|
|
5960
|
+
) -> str:
|
|
5961
|
+
"""Create a new agent."""
|
|
5962
|
+
try:
|
|
5963
|
+
agent = await client.create_agent(
|
|
5964
|
+
name=name,
|
|
5965
|
+
modality=modality,
|
|
5966
|
+
agent_type=agent_type,
|
|
5967
|
+
model=model,
|
|
5968
|
+
prompt=prompt,
|
|
5969
|
+
escalation_mode=escalation_mode,
|
|
5970
|
+
auto_reply=auto_reply,
|
|
5971
|
+
)
|
|
5972
|
+
except AppliedAPIError as e:
|
|
5973
|
+
return _format_error(e)
|
|
5974
|
+
|
|
5975
|
+
result = "# Created Agent\n"
|
|
5976
|
+
result += f"id: {agent.get('id')}\n"
|
|
5977
|
+
result += f"name: {agent.get('name')}\n"
|
|
5978
|
+
result += f"modality: {agent.get('modality')}\n"
|
|
5979
|
+
return result
|
|
5980
|
+
|
|
5981
|
+
|
|
5982
|
+
async def agent_update(
|
|
5983
|
+
client: AppliedClient,
|
|
5984
|
+
agent_id: str,
|
|
5985
|
+
name: str | None = None,
|
|
5986
|
+
prompt: str | None = None,
|
|
5987
|
+
model: str | None = None,
|
|
5988
|
+
modality: str | None = None,
|
|
5989
|
+
agent_type: str | None = None,
|
|
5990
|
+
escalation_mode: str | None = None,
|
|
5991
|
+
auto_reply: bool | None = None,
|
|
5992
|
+
metadata: dict | None = None,
|
|
5993
|
+
) -> str:
|
|
5994
|
+
"""Update an agent's properties."""
|
|
5995
|
+
updates: dict = {}
|
|
5996
|
+
if name is not None:
|
|
5997
|
+
updates["name"] = name
|
|
5998
|
+
if prompt is not None:
|
|
5999
|
+
updates["prompt"] = prompt
|
|
6000
|
+
if model is not None:
|
|
6001
|
+
updates["model"] = model
|
|
6002
|
+
if modality is not None:
|
|
6003
|
+
updates["modality"] = modality
|
|
6004
|
+
if agent_type is not None:
|
|
6005
|
+
updates["type"] = agent_type
|
|
6006
|
+
if escalation_mode is not None:
|
|
6007
|
+
updates["escalation_mode"] = escalation_mode
|
|
6008
|
+
if auto_reply is not None:
|
|
6009
|
+
updates["auto_reply"] = auto_reply
|
|
6010
|
+
if metadata is not None:
|
|
6011
|
+
updates["metadata"] = metadata
|
|
6012
|
+
|
|
6013
|
+
try:
|
|
6014
|
+
agent = await client.update_agent(agent_id, **updates)
|
|
6015
|
+
except AppliedAPIError as e:
|
|
6016
|
+
return _format_error(e)
|
|
6017
|
+
|
|
6018
|
+
result = "# Updated Agent\n"
|
|
6019
|
+
result += f"id: {agent.get('id')}\n"
|
|
6020
|
+
result += f"name: {agent.get('name')}\n"
|
|
6021
|
+
result += f"modality: {agent.get('modality')}\n"
|
|
6022
|
+
return result
|
|
6023
|
+
|
|
6024
|
+
|
|
6025
|
+
async def agent_set_picture(
|
|
6026
|
+
client: AppliedClient,
|
|
6027
|
+
agent_id: str,
|
|
6028
|
+
image_path: str,
|
|
6029
|
+
) -> str:
|
|
6030
|
+
"""Set an agent's profile picture from a local file."""
|
|
6031
|
+
import os
|
|
6032
|
+
|
|
6033
|
+
if not os.path.isfile(image_path):
|
|
6034
|
+
return f"Error: File not found: {image_path}"
|
|
6035
|
+
|
|
6036
|
+
try:
|
|
6037
|
+
agent = await client.update_agent_picture(agent_id, image_path)
|
|
6038
|
+
except AppliedAPIError as e:
|
|
6039
|
+
return _format_error(e)
|
|
6040
|
+
|
|
6041
|
+
result = "# Updated Agent Picture\n"
|
|
6042
|
+
result += f"id: {agent.get('id')}\n"
|
|
6043
|
+
result += f"name: {agent.get('name')}\n"
|
|
6044
|
+
result += f"profile_picture: {agent.get('profile_picture')}\n"
|
|
6045
|
+
return result
|
|
6046
|
+
|
|
6047
|
+
|
|
6048
|
+
async def agent_delete(
|
|
6049
|
+
client: AppliedClient,
|
|
6050
|
+
agent_id: str,
|
|
6051
|
+
) -> str:
|
|
6052
|
+
"""Delete an agent."""
|
|
6053
|
+
try:
|
|
6054
|
+
await client.delete_agent(agent_id)
|
|
6055
|
+
except AppliedAPIError as e:
|
|
6056
|
+
return _format_error(e)
|
|
6057
|
+
|
|
6058
|
+
return f"Agent {agent_id} deleted successfully."
|
|
6059
|
+
|
|
6060
|
+
|
|
6061
|
+
# -----------------------------------------------------------------------------
|
|
6062
|
+
# Knowledge Base - Delete
|
|
6063
|
+
# -----------------------------------------------------------------------------
|
|
6064
|
+
|
|
6065
|
+
|
|
6066
|
+
async def knowledge_delete(
|
|
6067
|
+
client: AppliedClient,
|
|
6068
|
+
knowledge_id: str,
|
|
6069
|
+
) -> str:
|
|
6070
|
+
"""Delete a knowledge base item."""
|
|
6071
|
+
try:
|
|
6072
|
+
await client.delete_response(knowledge_id)
|
|
6073
|
+
except AppliedAPIError as e:
|
|
6074
|
+
return _format_error(e)
|
|
6075
|
+
|
|
6076
|
+
return f"Knowledge item {knowledge_id} deleted successfully."
|
|
6077
|
+
|
|
6078
|
+
|
|
6079
|
+
# -----------------------------------------------------------------------------
|
|
6080
|
+
# Taxonomy - Create / Update / Delete
|
|
6081
|
+
# -----------------------------------------------------------------------------
|
|
6082
|
+
|
|
6083
|
+
|
|
6084
|
+
async def taxonomy_create(
|
|
6085
|
+
client: AppliedClient,
|
|
6086
|
+
name: str,
|
|
6087
|
+
parent_id: str | None = None,
|
|
6088
|
+
color: str | None = None,
|
|
6089
|
+
description: str | None = None,
|
|
6090
|
+
comments: str | None = None,
|
|
6091
|
+
) -> str:
|
|
6092
|
+
"""Create a topic or intent."""
|
|
6093
|
+
try:
|
|
6094
|
+
item = await client.create_taxonomy(
|
|
6095
|
+
name=name,
|
|
6096
|
+
parent_id=parent_id,
|
|
6097
|
+
color=color,
|
|
6098
|
+
description=description,
|
|
6099
|
+
comments=comments,
|
|
6100
|
+
)
|
|
6101
|
+
except AppliedAPIError as e:
|
|
6102
|
+
return _format_error(e)
|
|
6103
|
+
|
|
6104
|
+
item_type = "intent" if parent_id else "topic"
|
|
6105
|
+
result = f"# Created {item_type.title()}\n"
|
|
6106
|
+
result += f"id: {item.get('id')}\n"
|
|
6107
|
+
result += f"name: {item.get('name')}\n"
|
|
6108
|
+
return result
|
|
6109
|
+
|
|
6110
|
+
|
|
6111
|
+
async def taxonomy_update(
|
|
6112
|
+
client: AppliedClient,
|
|
6113
|
+
choice_id: str,
|
|
6114
|
+
name: str | None = None,
|
|
6115
|
+
color: str | None = None,
|
|
6116
|
+
description: str | None = None,
|
|
6117
|
+
comments: str | None = None,
|
|
6118
|
+
) -> str:
|
|
6119
|
+
"""Update a topic or intent."""
|
|
6120
|
+
updates: dict = {}
|
|
6121
|
+
if name is not None:
|
|
6122
|
+
updates["name"] = name
|
|
6123
|
+
if color is not None:
|
|
6124
|
+
updates["color"] = color
|
|
6125
|
+
if description is not None:
|
|
6126
|
+
updates["description"] = description
|
|
6127
|
+
if comments is not None:
|
|
6128
|
+
updates["comments"] = comments
|
|
6129
|
+
|
|
6130
|
+
try:
|
|
6131
|
+
item = await client.update_taxonomy(choice_id, **updates)
|
|
6132
|
+
except AppliedAPIError as e:
|
|
6133
|
+
return _format_error(e)
|
|
6134
|
+
|
|
6135
|
+
return f"# Updated Taxonomy Item\nid: {item.get('id')}\nname: {item.get('name')}"
|
|
6136
|
+
|
|
6137
|
+
|
|
6138
|
+
async def taxonomy_delete(
|
|
6139
|
+
client: AppliedClient,
|
|
6140
|
+
choice_id: str,
|
|
6141
|
+
) -> str:
|
|
6142
|
+
"""Delete a topic or intent."""
|
|
6143
|
+
try:
|
|
6144
|
+
await client.delete_taxonomy(choice_id)
|
|
6145
|
+
except AppliedAPIError as e:
|
|
6146
|
+
return _format_error(e)
|
|
6147
|
+
|
|
6148
|
+
return f"Taxonomy item {choice_id} deleted successfully."
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|