Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
docs/rfcs/credentials.md
31 changes: 31 additions & 0 deletions Examples/01-QuickStart.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/// # Quick Start
///
/// The simplest way to use aiXplainKit v2.
///
/// Set your API key via environment variable:
/// export TEAM_API_KEY="your-api-key"
///
/// Or pass it explicitly to `Aixplain(apiKey:)`.

import aiXplainKit

@main
struct QuickStart {
static func main() async throws {

// 1. Initialize the SDK
let aix = try Aixplain(apiKey: "your-team-api-key")

// 2. Run a model
let model = try await Model.get("669a63646eb56306647e1091", context: aix) // GPT-4o Mini
let result = try await model.run(text: "Say hello in French")
print("Model output:", result.data ?? "no output")

// 3. Run an agent
let agents = try await Agent.search(pageSize: 1, context: aix)
if let agent = agents.results.first {
let response = try await agent.run("What can you help me with?")
print("Agent says:", response.data?.output ?? "no output")
}
}
}
39 changes: 39 additions & 0 deletions Examples/02-Models.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/// # Working with Models
///
/// Search, fetch, run, and stream AI models.

import aiXplainKit

@main
struct ModelsExample {
static func main() async throws {
let aix = try Aixplain()

// --- Search models ---
let page = try await Model.search(query: "gpt", pageSize: 5, context: aix)
print("Found \(page.total) models matching 'gpt'")
for model in page.results {
print(" - \(model.name ?? "?") [\(model.id ?? "")]")
}

// --- Get a specific model ---
let gpt4oMini = try await Model.get("669a63646eb56306647e1091", context: aix)
print("\nModel: \(gpt4oMini.name ?? "?")")
print(" Host: \(gpt4oMini.host ?? "?")")
print(" Streaming: \(gpt4oMini.supportsStreaming ?? false)")
print(" Connection: \(gpt4oMini.connectionType ?? [])")

// --- Run a model ---
let result = try await gpt4oMini.run(text: "Explain quantum computing in one sentence")
print("\nResult: \(result.data?.description ?? "no data")")
print(" Credits used: \(result.usedCredits ?? 0)")
print(" Run time: \(result.runTime ?? 0)s")

// --- Use a model as an agent tool ---
let toolDict = gpt4oMini.asAgentTool()
print("\nAs agent tool:")
print(" ID: \(toolDict.id)")
print(" Type: \(toolDict.type)")
print(" Supplier: \(toolDict.supplier)")
}
}
57 changes: 57 additions & 0 deletions Examples/03-Agents.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/// # Working with Agents
///
/// Search, fetch, run agents, manage sessions, and use tools with agents.

import aiXplainKit

@main
struct AgentsExample {
static func main() async throws {
let aix = try Aixplain()

// --- Search agents ---
let page = try await Agent.search(pageSize: 5, context: aix)
print("Found \(page.total) agents")

// --- Get a specific agent ---
guard let agentId = page.results.first?.id else {
print("No agents found")
return
}
let agent = try await Agent.get(agentId, context: aix)
print("Agent: \(agent.name ?? "?")")
print(" Status: \(agent.status)")
print(" LLM: \(agent.llmId)")
print(" Instructions: \(agent.instructions ?? "(none)")")

// --- Run the agent ---
let result = try await agent.run("What is the capital of France?")
print("\nAgent response: \(result.data?.output ?? "no output")")
print(" Session: \(result.sessionId ?? "none")")
print(" Credits: \(result.usedCredits)")

// --- Multi-turn conversation ---
let sessionId = try await agent.generateSessionId()
print("\nSession ID: \(sessionId)")

let turn1 = try await agent.run("My name is Alice", sessionId: sessionId)
print("Turn 1: \(turn1.data?.output ?? "")")

let turn2 = try await agent.run("What is my name?", sessionId: sessionId)
print("Turn 2: \(turn2.data?.output ?? "")")

// --- Create a new agent with a model as a tool ---
let model = try await Model.get("669a63646eb56306647e1091", context: aix)
let newAgent = Agent(
name: "My Assistant",
instructions: "You are a helpful assistant. Use the provided tools when needed.",
tools: [model],
context: aix
)
// newAgent.save() would persist it to the platform
print("\nNew agent payload preview:")
let payload = try newAgent.buildSavePayload()
print(" Name: \(payload["name"] ?? "?")")
print(" Tools: \((payload["tools"] as? [[String: Any]])?.count ?? 0) tool(s)")
}
}
62 changes: 62 additions & 0 deletions Examples/04-Tools.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/// # Working with Tools
///
/// Search tools, use them with agents, and work with integrations.

import aiXplainKit

@main
struct ToolsExample {
static func main() async throws {
let aix = try Aixplain()

// --- Search tools ---
let page = try await Tool.searchTools(pageSize: 5, context: aix)
print("Found \(page.total) tools")
for tool in page.results {
print(" - \(tool.name ?? "?") [\(tool.id ?? "")]")
print(" Actions available: \(tool.actionsAvailable ?? false)")
print(" Allowed actions: \(tool.allowedActions)")
}

// --- Get a specific tool ---
if let toolId = page.results.first?.id {
let tool = try await Tool.getTool(toolId, context: aix)
print("\nTool details: \(tool.name ?? "?")")

// Convert to agent tool format
let agentTool = tool.asAgentTool()
print(" As agent tool type: \(agentTool.type)")
if let actions = agentTool.actions {
print(" Actions: \(actions)")
}

// List actions (if available)
if tool.actionsAvailable == true {
let actions = try await tool.listActions()
print(" Available actions:")
for action in actions {
print(" - \(action.name ?? action.slug ?? "?")")
}
}
}

// --- Use multiple tools with an agent ---
let model = try await Model.get("669a63646eb56306647e1091", context: aix)
let tools: [any AgentToolConvertible] = [model]
if let firstTool = page.results.first {
let allTools: [any AgentToolConvertible] = [model, firstTool]
let agent = Agent(
name: "Multi-tool Agent",
instructions: "Use available tools to answer questions",
tools: allTools,
context: aix
)
let payload = try agent.buildSavePayload()
let toolsList = payload["tools"] as? [[String: Any]] ?? []
print("\nAgent with \(toolsList.count) tools:")
for t in toolsList {
print(" - \(t["name"] ?? "?") (type: \(t["type"] ?? "?"))")
}
}
}
}
64 changes: 64 additions & 0 deletions Examples/05-Index.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/// # Working with Index & Search
///
/// Create indexes, add records, and perform semantic search.

import aiXplainKit

@main
struct IndexExample {
static func main() async throws {
let aix = try Aixplain()

// --- Create records ---
let records = [
Record(text: "Swift is a programming language developed by Apple"),
Record(text: "Python is widely used for data science and AI"),
Record(text: "Rust focuses on memory safety and performance"),
Record(text: "TypeScript adds types to JavaScript"),
]
print("Created \(records.count) records")

// --- Record with metadata ---
let taggedRecord = Record(
text: "Go is a statically typed language from Google",
attributes: ["category": "languages", "year": "2009"]
)
print("Tagged record: \(taggedRecord.value)")
print(" Attributes: \(taggedRecord.attributes)")

// --- Build search filters ---
let filters = IndexFilter.builder()
.where("category", .equals("languages"))
.where("year", .greaterThan("2005"))
.build()
print("\nFilters: \(filters.map { $0.toDict() })")

// --- Subscript shorthand ---
let quickFilter = IndexFilter["language", .contains("en")]
print("Quick filter: \(quickFilter.toDict())")

// --- Embedding models ---
print("\nAvailable embedding models:")
print(" OpenAI Ada 002: \(EmbeddingModel.openaiAda002.id)")
print(" BGE-M3: \(EmbeddingModel.bgeM3.id)")
print(" Multilingual E5: \(EmbeddingModel.multilingualE5Large.id)")

// --- Work with an existing index ---
// let index = try await Index.get("your-index-id", context: aix)
// let results = try await index.search("What is Swift?", topK: 3)
// for hit in results.hits {
// print(" [\(hit.score)] \(hit.data)")
// }

// --- Create a new index ---
// let newIndex = try await Index.create(
// name: "Programming Languages",
// description: "Knowledge base about programming languages",
// embedding: .openaiAda002,
// context: aix
// )
// try await newIndex.upsert(records)
// let count = try await newIndex.count()
// print("Index has \(count) documents")
}
}
65 changes: 65 additions & 0 deletions Examples/06-ErrorHandling.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/// # Error Handling
///
/// How to handle errors from the aiXplain SDK.

import aiXplainKit

@main
struct ErrorHandlingExample {
static func main() async throws {
// --- Credential errors ---
do {
_ = try Credential(scheme: .teamKey(""))
} catch let error as AuthError {
print("Auth error: \(error.errorDescription ?? "")")
// "API key must not be empty."
}

do {
_ = try Credential.resolve(environment: [:])
} catch let error as AuthError {
print("Auth error: \(error.errorDescription ?? "")")
// "API key is required. Pass it as an argument or set the TEAM_API_KEY environment variable."
}

// --- API errors with the unified error type ---
let aix = try Aixplain()
do {
_ = try await Agent.get("nonexistent-agent-id", context: aix)
} catch let error as AixplainError {
switch error {
case .auth(let authError):
print("Authentication failed: \(authError)")
case .api(let apiError):
print("API error [\(apiError.statusCode)]: \(apiError.message)")
if let rid = apiError.requestId {
print(" Request ID: \(rid)")
}
// User-friendly message for UI
print(" User message: \(apiError.userMessage)")
case .validation(let valError):
print("Validation: \(valError.message)")
case .timeout(let timeoutError):
print("Timeout: \(timeoutError.message)")
if let url = timeoutError.pollingURL {
print(" Polling URL: \(url)")
}
case .fileUpload(let uploadError):
print("Upload failed: \(uploadError.message)")
case .resource(let resourceError):
print("Resource error: \(resourceError.message)")
}

// Or use the unified userMessage
print("User-facing: \(error.userMessage)")
}

// --- Validation before requests ---
let agent = Agent(name: "Test")
do {
try agent.ensureValidState()
} catch {
print("Expected: \(error)") // Agent not saved yet
}
}
}
49 changes: 49 additions & 0 deletions Examples/07-TeamAgents.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/// # Team Agents (Multi-Agent Systems)
///
/// In v2, team agents are just agents with subagents. No separate class.

import aiXplainKit

@main
struct TeamAgentsExample {
static func main() async throws {
let aix = try Aixplain()

// --- A TeamAgent is just an Agent with subagents ---
// The typealias exists for discoverability:
// public typealias TeamAgent = Agent

// --- Check if an agent is a team agent ---
let agent = Agent(name: "Solo Agent", context: aix)
print("Is team agent: \(agent.isTeamAgent)") // false

// --- Create a team agent from existing agents ---
let agents = try await Agent.search(pageSize: 3, context: aix)
guard agents.results.count >= 2 else {
print("Need at least 2 agents to form a team")
return
}

let subAgent1 = agents.results[0]
let subAgent2 = agents.results[1]

let team = Agent(
name: "Research Team",
instructions: "Coordinate the sub-agents to answer research questions",
context: aix
)
team.subagents = [subAgent1, subAgent2]

print("Team agent: \(team.name ?? "?")")
print(" Is team: \(team.isTeamAgent)") // true
print(" Subagents: \(team.subagents.count)")
for sub in team.subagents {
print(" - \(sub.name ?? "?") [\(sub.id ?? "")]")
}

// --- The save payload includes agent references ---
let payload = try team.buildSavePayload()
let agentRefs = payload["agents"] as? [[String: Any]] ?? []
print("\nSave payload agent refs: \(agentRefs.count)")
}
}
Loading