Skip to content

Commit

Permalink
Documentation refactoring (#44)
Browse files Browse the repository at this point in the history
* We don't care about old formatters/dialyzer

* Fix how config is passed in

* Add to module section docs

* This was causing docs to unexpectedly link out

* Fix example return value

* Fix formatting and documentation errors

* Only one version is running

* Fix txt
  • Loading branch information
estreeper authored May 4, 2024
1 parent d5137c7 commit ff8e4f3
Show file tree
Hide file tree
Showing 10 changed files with 186 additions and 73 deletions.
7 changes: 7 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ For convenience we recommend using this as a pre-push hook:
cp presubmit.sh .git/hooks/pre-push
```

You can run the library via the `iex` shell to run functions through it, e.g.:

```
iex -S mix
iex()> ProdopsEx.Artifact.get(123, "story")
```

## Submitting Changes

1. Find or open an Issue related to the changes you're making
Expand Down
61 changes: 50 additions & 11 deletions lib/prodops/artifact.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
defmodule ProdopsEx.Artifact do
@moduledoc """
Handles artifact operations for the ProdOps API such as retrieving artifacts for a given project, creating artifacts, refining artifacts, and deleting artifacts.
Handles artifact operations for the ProdOps API such as retrieving artifacts
for a given project, creating artifacts, refining artifacts, and deleting artifacts.
Artifacts are any generated content, i.e. user stories, blog posts, code
snippets, etc. They are organized by `artifact_slug`s, which define what type
of content they are. Most artifact operations require specifying the
`artifact_slug`.
They are generated by passing input into a prompt template. Inputs come from
up to three places:
- user inputs: you can specify what values these have when creating Artifacts
- document queries: semantically similar parts of documents are automatically
found within a collection of documents, and inserted into the prompt template
prior to generation, known as Retrieval-Augmented Generation (RAG)
- document attachments: an entire document, such as something uploaded by you,
is inserted into the prompt template prior to generation
"""
alias ProdopsEx.Client
alias ProdopsEx.Config
Expand All @@ -12,7 +27,7 @@ defmodule ProdopsEx.Artifact do
end

@doc """
Retrieves artifacts for a given project.
Retrieves artifacts of one type based on the `artifact_slug` for a given project.
## Parameters
Expand All @@ -34,16 +49,18 @@ defmodule ProdopsEx.Artifact do
"content" => "You are going to be a product manager and write a BDD-style user story...",
"role" => "user"
},
...
%{
"content" => "## Background ...",
"role" => "assistant"
}
],
"content" => "## Background ...",
"id" => 1,
"manually_edited" => false,
"name" => "Artifact Name",
"notes" => nil,
"share_token" => nil
},
...
}
]
}
}}
Expand Down Expand Up @@ -74,6 +91,7 @@ defmodule ProdopsEx.Artifact do
iex> ProdopsEx.Artifact.create(%{
...> prompt_template_id: 2,
...> artifact_slug: "story",
...> project_id: 1,
...> inputs: [
...> %{name: "Context", value: "this is a test"}
...> ],
Expand Down Expand Up @@ -117,8 +135,28 @@ defmodule ProdopsEx.Artifact do
iex> ProdopsEx.Artifact.get(1, "story")
{:ok,
}
%{
status: "ok",
response: %{
"artifact" => %{
"chat_history" => [
%{
"content" => "some user prompt content",
"role" => "user"
},
%{
"content" => "some assistant response content",
"role" => "assistant"
}
],
"id" => 123,
"manually_edited" => false,
"name" => "Some Name",
"notes" => nil,
"share_token" => nil
}
}
}}
"""
@spec get(integer(), String.t(), Keyword.t()) :: {:ok, map} | {:error, any}
def get(artifact_id, artifact_slug, config \\ []) when is_integer(artifact_id) and is_binary(artifact_slug) do
Expand All @@ -138,7 +176,7 @@ defmodule ProdopsEx.Artifact do
## Example
iex> ProdopsEx.Artifact.delete(1)
iex> ProdopsEx.Artifact.delete(1, "story")
{:ok,
%{status: "ok", response: %{"message" => "Artifact deleted successfully."}}}
"""
Expand All @@ -158,7 +196,7 @@ defmodule ProdopsEx.Artifact do
## Example
iex> ProdopsEx.Artifacts.refine_artifact(%{
iex> ProdopsEx.Artifact.refine_artifact(%{
...> artifact_id: 1,
...> artifact_slug: "story",
...> refine_prompt: "Refine this story"
Expand All @@ -172,7 +210,8 @@ defmodule ProdopsEx.Artifact do
},
Keyword.t()
) :: {:ok, map} | {:error, any}
def refine_artifact(%{artifact_slug: artifact_slug, artifact_id: artifact_id} = params, config) do
def refine_artifact(%{artifact_slug: artifact_slug, artifact_id: artifact_id} = params, config \\ []) do
config = Config.resolve_config(config)
url = url(config) <> "/#{artifact_slug}/artifacts/#{artifact_id}/refine"
Client.api_post(url, params, config)
end
Expand All @@ -187,7 +226,7 @@ defmodule ProdopsEx.Artifact do
## Example
iex> ProdopsEx.stream_refine_artifact(%{artifact_slug: "story", artifact_id: 1}, %ProdopsEx.Config{bearer_token: "your_api_key_here"})
iex> ProdopsEx.Artifact.stream_refine_artifact(%{artifact_slug: "story", artifact_id: 1, refine_prompt: "some prompt"})
"""
@spec stream_refine_artifact(map, Keyword.t()) :: {:ok, map} | {:error, any}
def stream_refine_artifact(params, config \\ []) do
Expand Down
26 changes: 19 additions & 7 deletions lib/prodops/artifact_type.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
defmodule ProdopsEx.ArtifactType do
@moduledoc """
Handles artifact type operations for the ProdOps API.
These represent types of outputs. They may be things like user stories, code
snippets, blog posts, or anything else that has been defined within the
ProdOps UI. They are used to classify generated Artifacts into groups.
"""
alias ProdopsEx.Client
alias ProdopsEx.Config
Expand All @@ -13,13 +17,21 @@ defmodule ProdopsEx.ArtifactType do
## Examples
iex> ProdopsEx.ArtifactType.list()
{:ok, %{status: "ok", response: %{ "artifact_types": [
{
"slug": "story",
"name": "Story",
"description": "This is a story"
}
]}}}
{:ok,
%{
status: "ok",
response: %{
"artifact_types" => [
%{
"description" => "This is a story",
"name" => "Story",
"slug" => "story"
},
...
]
}
}
}
"""
@spec list(Keyword.t()) :: {:ok, map} | {:error, any}
def list(config \\ []) do
Expand Down
4 changes: 1 addition & 3 deletions lib/prodops/client.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
defmodule ProdopsEx.Client do
@moduledoc """
Handles HTTP client operations for interacting with the ProdOps API.
"""
@moduledoc false
use HTTPoison.Base

alias ProdopsEx.Stream
Expand Down
4 changes: 1 addition & 3 deletions lib/prodops/config.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
defmodule ProdopsEx.Config do
@moduledoc """
Defines the configuration structure for interacting with the ProdOps API.
"""
@moduledoc false

@definition [
api_url: [
Expand Down
10 changes: 9 additions & 1 deletion lib/prodops/data_center.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
defmodule ProdopsEx.DataCenter do
@moduledoc """
Handles data center operations for the ProdOps API.
The Data Center is used for:
- uploading documents
- managing collections of documents
- connecting external Data Sources (GitHub, Jira, Notion, etc.)
Not all of these items are currently supported by the ProdOps API, so there
is additional functionality in the UI not yet available in this SDK.
"""
alias ProdopsEx.Client
alias ProdopsEx.Config
Expand All @@ -17,7 +25,7 @@ defmodule ProdopsEx.DataCenter do
## Examples
iex> ProdopsEx.DataCenter.upload_document("/path/to/file.txt"})
iex> ProdopsEx.DataCenter.upload_document("/path/to/file.txt")
{:ok, %{status: "ok", response: %{"id" => 4}}}
"""
@spec upload_document(map, Keyword.t()) :: {:ok, map} | {:error, any}
Expand Down
30 changes: 23 additions & 7 deletions lib/prodops/project.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
defmodule ProdopsEx.Project do
@moduledoc """
Handles project operations for the ProdOps API.
A Project is used for organization, and likely represents some real-world
project, such as development of an application. Some resources can be
Project-scoped. A Team may have multiple Projects.
"""
alias ProdopsEx.Client
alias ProdopsEx.Config
Expand All @@ -21,13 +25,25 @@ defmodule ProdopsEx.Project do
## Examples
iex> ProdopsEx.Project.list()
{:ok, %{status: "ok", response: %{ "projects": [
{
"id": 1,
"name": "ProdOps",
"overview": "This is the project overview"
}
]}}}
{:ok,
%{
status: "ok",
response: %{
"projects" => [
%{
"id" => 1,
"name" => "Project Name",
"overview" => "Project Overview"
},
%{
"id" => 2,
"name" => "Second Project",
"overview" => "Second Project Overview"
}
]
}
}
}
"""
@spec list(Keyword.t()) :: {:ok, map} | {:error, any}
def list(config \\ []) do
Expand Down
106 changes: 69 additions & 37 deletions lib/prodops/prompt_template.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,40 @@
defmodule ProdopsEx.PromptTemplate do
@moduledoc """
Handles prompt template operations for the ProdOps API
Handles prompt template operations for the ProdOps API.
Prompt Templates are the building blocks used for generating Artifacts.
They are a combination of hard-coded information and variables which represent
data that can be inserted. They are the basic building block for setting up
repeatable workflows to generate Artifacts.
They may look something like this:
```txt
You are a helpful assistant. A user has asked a question about company
policies, which you must answer. This is their question:
{custom.Question}
Use this information to answer the question:
{query.Company Policies}
```
The value `{custom.Question}` can be explicitly passed into the template
when generating a new Artifact.
The value `{query.Company Policies}` will automatically find relevant
information by checking the value of an explicit input such as
`{custom.Question}`, and can search through all Documents or a Collection of
Documents. In this example, it might search a Collection of employee manuals,
playbooks, etc., and will calculate the most semantically similar values
between their sections and the user's question, which is the value input into
`{custom.Question}`. It will then return the relevant segments and insert them
into the prompt prior to generation. This technique is known as
Retrieval-Augmented Generation.
For more information, see the [ProdOps.AI Prompts help page](https://help.prodops.ai/docs/category/prompts).
"""
alias ProdopsEx.Client
alias ProdopsEx.Config
Expand All @@ -16,42 +50,40 @@ defmodule ProdopsEx.PromptTemplate do
- `config` (optional): a configuration map used to override default config values
## Example
iex> ProdopsEx.PromptTemplate.list("story")
{:ok,
%{
status: "ok",
response: %{
"prompt_templates" => [
{
"id": 3,
"name": "Example Prompt",
"content": "This is an example prompt template body",
"description": "This is an example prompt template",
"custom_variables": [
{
"id": "df57af61-7741-4152-b5eb-0484b281eaaa",
"name": "Example Input",
"description": null
}
],
"document_queries": [
{
"id": "dcbbc393-9f00-4020-a150-ac5fa5f66095",
"name": "Example Document Query",
"query": "{custom.Example Input}",
"count": 1,
"type": "code",
"min_score": 0.75,
"collection_id": null,
"collection_ids": []
}
]
},
...
]
}
}}
iex> ProdopsEx.PromptTemplate.list("questions")
{:ok,
%{
status: "ok",
response: %{
"prompt_templates" => [
%{
"content" => "Answer this: {custom.Question} Use these docs: {query.Documents}",
"custom_variables" => [
%{
"question" => "Question",
"id" => "fc4cbbe7-8f90-4c39-a8e6-582d37884f14",
"name" => "Question"
}
],
"description" => "Answers a question using document queries",
"document_queries" => [
%{
"collection_id" => nil,
"collection_ids" => ~c"s",
"count" => 3,
"id" => "6c69b859-8c40-41c9-b8f9-8bb1bdf369a1",
"min_score" => 0.75,
"name" => "Documents",
"query" => "{custom.Question}",
"type" => nil
}
],
"id" => 1,
"name" => "Question Answering"
}
]
}
}}
## Returns
The function returns a list of prompt templates for the specified artifact type.
Expand Down
Loading

0 comments on commit ff8e4f3

Please sign in to comment.