Skip to content
Merged
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
49 changes: 49 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# See for instructions on this file https://help.github.com/articles/about-codeowners/

#### Team-owned sample areas ############################################################################
# Each contributing team owns their sample paths for review routing. See CONTRIBUTING.md for setup guide.
/samples/python/hosted-agents/ @microsoft-foundry/hosted-agents
/samples/csharp/hosted-agents/ @microsoft-foundry/hosted-agents

#### files referenced in docs (DO NOT EDIT, except for Docs team!!!) ##########################################
/infrastructure/infrastructure-setup-bicep/01-connections/connection-key-vault.bicep @microsoft-foundry/AI-Platform-Docs
/infrastructure/infrastructure-setup-bicep/05-custom-policy-definitions/deny-disallowed-connections.json @microsoft-foundry/AI-Platform-Docs
/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/main.tf @microsoft-foundry/AI-Platform-Docs
/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/providers.tf @microsoft-foundry/AI-Platform-Docs
/infrastructure/infrastructure-setup-terraform/00-basic-azurerm/code/variables.tf @microsoft-foundry/AI-Platform-Docs
/infrastructure/infrastructure-setup-terraform/00-basic/code/main.tf @microsoft-foundry/AI-Platform-Docs
/infrastructure/infrastructure-setup-terraform/00-basic/code/providers.tf @microsoft-foundry/AI-Platform-Docs
/infrastructure/infrastructure-setup-terraform/00-basic/code/variables.tf @microsoft-foundry/AI-Platform-Docs
/samples-classic/REST/quickstart/quickstart.sh @microsoft-foundry/AI-Platform-Docs
/samples-classic/csharp/quickstart/Samples/.env.example @microsoft-foundry/AI-Platform-Docs
/samples-classic/csharp/quickstart/Samples/AgentFileSearch.cs @microsoft-foundry/AI-Platform-Docs
/samples-classic/csharp/quickstart/Samples/AgentService.cs @microsoft-foundry/AI-Platform-Docs
/samples-classic/csharp/quickstart/Samples/SimpleInference.cs @microsoft-foundry/AI-Platform-Docs
/samples-classic/java/quickstart/src/main/java/com/azure/ai/foundry/samples/AgentSample.java @microsoft-foundry/AI-Platform-Docs
/samples-classic/java/quickstart/src/main/java/com/azure/ai/foundry/samples/ChatCompletionSample.java @microsoft-foundry/AI-Platform-Docs
/samples-classic/java/quickstart/src/main/java/com/azure/ai/foundry/samples/FileSearchAgentSample.java @microsoft-foundry/AI-Platform-Docs
/samples-classic/python/quickstart/create_project.py @microsoft-foundry/AI-Platform-Docs
/samples-classic/python/quickstart/quickstart.py @microsoft-foundry/AI-Platform-Docs
/samples-classic/typescript/quickstart/.env.template @microsoft-foundry/AI-Platform-Docs
/samples-classic/typescript/quickstart/src/quickstart.ts @microsoft-foundry/AI-Platform-Docs
/samples/REST/quickstart/quickstart-chat-with-agent.sh @microsoft-foundry/AI-Platform-Docs
/samples/REST/quickstart/quickstart-create-agent.sh @microsoft-foundry/AI-Platform-Docs
/samples/REST/quickstart/quickstart-responses.sh @microsoft-foundry/AI-Platform-Docs
/samples/csharp/enterprise-agent-tutorial/1-idea-to-prototype/Evaluate/Program.cs @microsoft-foundry/AI-Platform-Docs
/samples/csharp/enterprise-agent-tutorial/1-idea-to-prototype/ModernWorkplaceAssistant/Program.cs @microsoft-foundry/AI-Platform-Docs
/samples/csharp/quickstart/chat-with-agent/quickstart-chat-with-agent.cs @microsoft-foundry/AI-Platform-Docs
/samples/csharp/quickstart/create-agent/quickstart-create-agent.cs @microsoft-foundry/AI-Platform-Docs
/samples/csharp/quickstart/responses/quickstart-responses.cs @microsoft-foundry/AI-Platform-Docs
/samples/java/quickstart/chat-with-agent/src/main/java/com/azure/ai/agents/ChatWithAgent.java @microsoft-foundry/AI-Platform-Docs
/samples/java/quickstart/create-agent/src/main/java/com/azure/ai/agents/CreateAgent.java @microsoft-foundry/AI-Platform-Docs
/samples/python/enterprise-agent-tutorial/1-idea-to-prototype/evaluate.py @microsoft-foundry/AI-Platform-Docs
/samples/python/enterprise-agent-tutorial/1-idea-to-prototype/main.py @microsoft-foundry/AI-Platform-Docs
/samples/python/foundry-models/model-router/model-router-chat-completions.py @microsoft-foundry/AI-Platform-Docs
/samples/python/foundry-models/model-router/model-router-foundry-responses.py @microsoft-foundry/AI-Platform-Docs
/samples/python/quickstart/chat-with-agent/quickstart-chat-with-agent.py @microsoft-foundry/AI-Platform-Docs
/samples/python/quickstart/create-agent/quickstart-create-agent.py @microsoft-foundry/AI-Platform-Docs
/samples/python/quickstart/responses/quickstart-responses.py @microsoft-foundry/AI-Platform-Docs
/samples/typescript/quickstart/chat-with-agent/src/quickstart-chat-with-agent.ts @microsoft-foundry/AI-Platform-Docs
/samples/typescript/quickstart/create-agent/src/quickstart-create-agent.ts @microsoft-foundry/AI-Platform-Docs
/samples/typescript/quickstart/responses/src/quickstart-responses.ts @microsoft-foundry/AI-Platform-Docs

12 changes: 12 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## Files owned by the AI Platform Docs team

If a file is listed in the CODEOWNERS file with @azure-ai-foundry/ai-platform-docs as the owner, it is owned by the AI Platform Docs team. For these files:

- Do not change the filename or move the file.
- Do not remove any comments which contain <some_text> or </some_text> (for any text in between the tags)
- Do not remove any cell in a notebook if it contains metadata with "name:" in it.

In a code review, if any of the above rules are broken, please add the following text to your review:
🛑STOP! This PR contains changes that may break documentation. Please post a message on [ai-platform-docs](https://teams.microsoft.com/l/team/19%3AHhf4F_YfPn3kYGdmWvePNwlbF5-RR8wciQEUwwrcggw1%40thread.tacv2/conversations?groupId=fdaf4412-8993-4ea6-a7d4-aeaded7fc854&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47) to request help.

Only files owned by the AI Platform Docs team are subject to these rules.
211 changes: 211 additions & 0 deletions .github/scripts/commit-filesize-diff-summary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
#!/usr/bin/env python3
import argparse
import subprocess
import sys
from dataclasses import dataclass
from itertools import chain
from pathlib import Path
from typing import Dict, Iterable, List, Literal, Optional, Tuple


@dataclass
class GitDiffTreeRecord:
"""Represents a line of output from 'git diff-tree'"""

src_mode: str
src_hash: str
dst_mode: str
dst_hash: str
src_path: Path
dst_path: Optional[Path]
status: Literal["A", "C", "D", "M", "R", "T", "U", "X"]
score: Optional[int]


@dataclass
class GitChange:
diff_record: GitDiffTreeRecord
bytes_changed: int


def parse_git_diff_tree_output(output: str) -> List[GitDiffTreeRecord]:
"""Parses the output of `git diff-tree` as described in the "Raw Output" section
of the man page
"""

def make_record(line: str) -> GitDiffTreeRecord:
src_mode, dst_mode, src_hash, dst_hash, rest = line[1:].split(" ", maxsplit=4)
status_score_and_paths = rest.split("\t")
return GitDiffTreeRecord(
src_mode=src_mode,
src_hash=src_hash,
dst_mode=dst_mode,
dst_hash=dst_hash,
status=status_score_and_paths[0][0],
score=int(status_score_and_paths[0][1:]) if len(status_score_and_paths[0]) > 1 else None,
src_path=Path(status_score_and_paths[1]),
dst_path=Path(status_score_and_paths[2]) if len(status_score_and_paths) >= 3 else None,
)

return [make_record(line) for line in output.splitlines(keepends=False)]


def get_blob_sizes(hashes: Iterable[str]) -> Dict[str, Optional[int]]:
"""Fetches the sizes, in bytes, of git blobs

:param hashes: A iterable of git blob hashes
:type hashes: Iterable[str]

:return: A dictionary that mapping blob hashes to their size if the blob exists,
or None otherwise
:rtype: Dict[str, Optional[int]]
"""
input = "\n".join(set(hashes))
cat_file_output = subprocess.run(
["git", "cat-file", "--batch-check"],
input=input,
check=True,
text=True,
capture_output=True,
).stdout

def make_object_size_tuple(line: str) -> Tuple[str, Optional[int]]:
hash, *_, size = line.split()
return (hash, int(size) if size != "missing" else None)

return dict(make_object_size_tuple(line) for line in cat_file_output.splitlines(keepends=False))


def get_file_size_differences(commit_range: str) -> Dict[Path, GitChange]:
"""Computes the size difference, in bytes, of files changed between two commits

:param commit_range: A git commit range (e.g. HEAD~3..HEAD)
:type commit_range: str

:return: A dictionary mapping paths (relative to repository root) to size
differences.
:rtype: dict[Path, GitChange]
"""
changed_records = parse_git_diff_tree_output(
subprocess.run(
["git", "diff-tree", "-r", commit_range],
capture_output=True,
text=True,
check=True,
).stdout
)

sizes = get_blob_sizes(chain.from_iterable((idx.src_hash, idx.dst_hash) for idx in changed_records))

assert {"A", "D", "M"}.issuperset(idx.status for idx in changed_records)

def as_int(maybe_num: Optional[int]) -> int:
return maybe_num or 0

return {
x.src_path: GitChange(
diff_record=x,
bytes_changed=as_int(sizes[x.dst_hash]) - as_int(sizes[x.src_hash]),
)
for x in changed_records
}


def main(
commit_range: str,
quiet: bool = False,
limit: Optional[int] = None,
show_n_largest_files: int = 30,
) -> Literal[0, 1]:
size_differences = get_file_size_differences(commit_range)
cumulative_size_difference = sum(x.bytes_changed for x in size_differences.values())
exceeds_limit = limit is not None and cumulative_size_difference > limit

def bytes_diff(num: int) -> str:
return ("+" if num >= 0 else "") + human_friendly_bytes(num)

if not quiet:
print(f"Total file size difference for commit range '{commit_range}': ")
print(f"\t{bytes_diff(cumulative_size_difference)}", end="")
print(f" (Exceeds set limit of {bytes_diff(limit)})" if exceeds_limit else "")

largest_n_sizes = sorted(size_differences.items(), key=lambda x: x[1].bytes_changed, reverse=True)[
:show_n_largest_files
]

if largest_n_sizes:
print("")
print(f"Largest {len(largest_n_sizes)} filesize differences:")

for path, val in largest_n_sizes:
print(f"\t{bytes_diff(val.bytes_changed)}\t{path}")

return 1 if exceeds_limit else 0


def num_bytes(arg: str) -> int:
"""Converts a string to a number of bytes"""
error = argparse.ArgumentTypeError(f"'{arg}' cannot be parsed into a number of bytes")
try:
return int(arg)
except ValueError:
pass

if len(arg) < 3:
raise error

num, suffix = (arg[:-2], arg[-2:])
shift_values = {
"KB": 1,
"MB": 2,
"GB": 3,
"TB": 4,
"PB": 5,
"EB": 6,
"ZB": 7,
"YB": 8,
}

shift = shift_values.get(suffix)

if shift is None:
raise error
try:
return int(num) << (shift * 10)
except ValueError as e:
raise error from e


def human_friendly_bytes(num: int) -> str:
"""Prints a number of bytes as a human friendly string"""
for prefix in ["", "K", "M", "G", "T", "P", "E", "Z"]:
if abs(num) < 1024.0:
return f"{num:.1f}{prefix}B"
num /= 1024.0
return f"{num:.1f}YB"


if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="A program that summarizes the file size " + "differences between two git commits."
)
parser.add_argument(
"commit_range",
default="HEAD^..HEAD",
type=str,
help="Commit range to commit the diff for (e.g. HEAD~3..HEAD)",
)
parser.add_argument("--quiet", action="store_true", help="Silence all output")
parser.add_argument(
"--limit",
type=num_bytes,
help="Exit non-zero if total changes exceeds this value. "
+ "Can be a raw number of bytes (e.g. 65536) or a suffixed value (e.g 2MB)",
)
parser.add_argument(
"--show-n-largest-files",
type=int,
help="Show this many of the largest files in diff",
default=30,
)
sys.exit(main(**vars(parser.parse_args())))
52 changes: 52 additions & 0 deletions .github/workflows/ado-automation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Create ADO user story from GitHub issue
run-name: GitHub Issue #${{ github.event.issue.number }}

on:
issues:
types: [opened]

jobs:
create-ado-story:
runs-on: ubuntu-latest

steps:
- name: Build payload and call Azure DevOps
env:
ADO_ORG: ${{ secrets.ADO_ORG }}
ADO_PROJECT: ${{ secrets.ADO_PROJECT }}
ADO_PAT: ${{ secrets.ADO_PAT }}
DRI_EMAIL: ${{ secrets.DRI_EMAIL }}
ADO_AREA_PATH: ${{ secrets.ADO_AREA_PATH }}
ADO_ITERATION_PATH: ${{ secrets.ADO_ITERATION_PATH }}
ADO_TAG: ${{ secrets.ADO_TAG }}
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_BODY: ${{ github.event.issue.body }}
ISSUE_URL: ${{ github.event.issue.html_url }}
run: |
DESCRIPTION="<div>${ISSUE_BODY//$'\n'/<br/>}<br/><br/><a href=\"$ISSUE_URL\">$ISSUE_URL</a></div>"

jq -n \
--arg title "$ISSUE_TITLE" \
--arg desc "$DESCRIPTION" \
--arg area "$ADO_AREA_PATH" \
--arg iter "$ADO_ITERATION_PATH" \
--arg assn "$DRI_EMAIL" \
--arg tags "$ADO_TAG" \
'[
{ "op":"add", "path":"/fields/System.Title", "value":$title },
{ "op":"add", "path":"/fields/System.Description", "value":$desc },
{ "op":"add", "path":"/fields/System.AreaPath", "value":$area },
{ "op":"add", "path":"/fields/System.IterationPath", "value":$iter },
{ "op":"add", "path":"/fields/System.AssignedTo", "value":$assn },
{ "op":"add", "path":"/fields/System.Tags", "value":$tags }
]' > /tmp/payload.json

AUTH=$(printf ":$ADO_PAT" | base64 | tr -d '\n')
WORK_ITEM_URL="https://dev.azure.com/${ADO_ORG}/${ADO_PROJECT}/_apis/wit/workitems/\$User%20Story?api-version=7.1-preview.3"

curl --fail-with-body -sS \
-H "Content-Type: application/json-patch+json" \
-H "Authorization: Basic $AUTH" \
-X POST \
--data-binary @/tmp/payload.json \
"$WORK_ITEM_URL"
Comment on lines +10 to +52
23 changes: 23 additions & 0 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Pre-Commit


on:
# push:
# branches:
# - main
# pull_request:
# branches:
# - main
workflow_dispatch:

jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.9"
- run: pip install -r dev-requirements.txt
- name: Run Pre-Commit
run: pre-commit run --all-files
Comment on lines +15 to +23
24 changes: 24 additions & 0 deletions .github/workflows/pull-request-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Pull Request Checks

on:
# push:
# branches:
# - main
# pull_request:
# branches:
# - main
workflow_dispatch:

jobs:
pull_request_size:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.9"
- name: Check Pull Request Size
run: |
git fetch origin ${{ github.event.pull_request.base.ref }} --quiet # Need to manually fetch base branch in CI
python ./.github/scripts/commit-filesize-diff-summary.py --limit 1MB origin/${{ github.event.pull_request.base.ref }}..HEAD
Comment on lines +14 to +24
Loading
Loading