Skip to content

Commit

Permalink
Fix
Browse files Browse the repository at this point in the history
  • Loading branch information
crazygao committed Mar 27, 2024
1 parent 1270364 commit 7887c57
Show file tree
Hide file tree
Showing 28 changed files with 177 additions and 88 deletions.
1 change: 0 additions & 1 deletion .github/workflows/promptflow-sdk-cli-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ on:
env:
packageSetupType: promptflow_with_extra
testWorkingDirectory: ${{ github.workspace }}/src/promptflow
PYTHONPATH: ${{ github.workspace }}/src/promptflow
IS_IN_CI_PIPELINE: "true"
RECORD_DIRECTORY: ${{ github.workspace }}/src/promptflow-recording
jobs:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@
)
from promptflow._sdk._errors import InvalidRunStatusError, RunNotFoundError, RunOperationParameterError
from promptflow._sdk._telemetry import ActivityType, WorkspaceTelemetryMixin, monitor_operation
from promptflow._sdk._utils import incremental_print, is_multi_container_enabled, is_remote_uri, print_red_error
from promptflow._sdk._utils import (
incremental_print,
is_multi_container_enabled,
is_remote_uri,
print_red_error,
)
from promptflow._sdk.entities import Run
from promptflow._utils.async_utils import async_run_allowing_running_loop
from promptflow._utils.logger_utils import get_cli_sdk_logger
Expand Down
18 changes: 13 additions & 5 deletions src/promptflow-core/promptflow/contracts/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,13 +546,21 @@ def get_environment_variables_with_overrides(
environment_variables[k] = v
return environment_variables

def get_connection_names(self):
"""Return connection names."""
connection_names = set({})
def get_connection_names(self, environment_variables_overrides: Dict[str, str] = None):
"""Return connection names with environment variables overrides.
Note: only environment variables exist in flow.environment_variables will be considered.
:param environment_variables_overrides: used to override flow's environment variables.
:return: connection names used in this flow.
"""
environment_variables_overrides = environment_variables_overrides or {}
connection_names = set({})
# Add connection names from environment variable reference
if self.environment_variables:
for k, v in self.environment_variables.items():
if k in environment_variables_overrides:
# Apply environment variables overrides
v = environment_variables_overrides[k]
if not isinstance(v, str) or not v.startswith("${"):
continue
connection_name, _ = _match_reference(v)
Expand Down Expand Up @@ -853,9 +861,9 @@ def _get_connection_inputs_from_tool(cls, tool: Tool) -> list:
connection_inputs.append(k)
return connection_inputs

def get_connection_names(self):
def get_connection_names(self, environment_variables_overrides: Dict[str, str] = None):
"""Return connection names."""
connection_names = super().get_connection_names()
connection_names = super().get_connection_names(environment_variables_overrides=environment_variables_overrides)
nodes = [
self._apply_default_node_variant(node, self.node_variants) if node.use_variants else node
for node in self.nodes
Expand Down
3 changes: 1 addition & 2 deletions src/promptflow-core/promptflow/contracts/multimedia.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import base64
import filetype
import hashlib
from typing import Callable, Optional

import filetype


class PFBytes(bytes):
"""This class is used to represent a bytes object in PromptFlow.
Expand Down
7 changes: 6 additions & 1 deletion src/promptflow-core/promptflow/contracts/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from enum import Enum
from typing import Any, Dict, List, Optional, Type, TypeVar

from promptflow._constants import CONNECTION_NAME_PROPERTY
from promptflow._constants import CONNECTION_NAME_PROPERTY, CONNECTION_DATA_CLASS_KEY

from .multimedia import Image
from .types import AssistantDefinition, FilePath, PromptTemplate, Secret
Expand Down Expand Up @@ -190,6 +190,11 @@ def is_connection_value(val: Any) -> bool:
from promptflow._core.tools_manager import connections

val = type(val) if not isinstance(val, type) else val
if hasattr(val, CONNECTION_DATA_CLASS_KEY):
# Get the data class for sdk connection object
data_class = getattr(val, CONNECTION_DATA_CLASS_KEY)
logger.debug(f"val {val} has DATA_CLASS key, get the data plane class {data_class}.")
val = data_class
return val in connections.values() or ConnectionType.is_custom_strong_type(val)

@staticmethod
Expand Down
5 changes: 0 additions & 5 deletions src/promptflow-core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,6 @@ markers = [
# durations - list the slowest test durations
addopts = """
--junit-xml=test-results.xml \
--cov=promptflow \
--cov-config=pyproject.toml \
--cov-report=term \
--cov-report=html \
--cov-report=xml \
--dist loadfile \
--log-level=info \
--log-format="%(asctime)s %(levelname)s %(message)s" \
Expand Down
2 changes: 1 addition & 1 deletion src/promptflow-devkit/promptflow/_cli/_pf/_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ def _build_run_obj():
logger.debug(f"resume_from specified, append params override {params_override} to run params.")
run_params.update(list_of_dict_to_nested_dict(params_override))
logger.debug(f"Run params: {run_params}")
run = resume_func(**run_params)
run = resume_func(**run_params, stream=stream)
else:
run = create_func(run=_build_run_obj(), stream=stream)
if stream:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# ---------------------------------------------------------
from pathlib import Path
from typing import List
from typing import Dict, List


class AbstractInspectorProxy:
Expand All @@ -22,6 +22,8 @@ class AbstractInspectorProxy:
def __init__(self):
pass

def get_used_connection_names(self, flow_file: Path, working_dir: Path) -> List[str]:
def get_used_connection_names(
self, flow_file: Path, working_dir: Path, environment_variables_overrides: Dict[str, str] = None
) -> List[str]:
"""Check the type of each node input/attribute and return the connection names used in the flow."""
raise NotImplementedError()
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import re
from collections import defaultdict
from pathlib import Path
from typing import List
from typing import Dict, List

import pydash

Expand All @@ -16,7 +16,10 @@ class CSharpInspectorProxy(AbstractInspectorProxy):
def __init__(self):
super().__init__()

def get_used_connection_names(self, flow_file: Path, working_dir: Path) -> List[str]:
def get_used_connection_names(
self, flow_file: Path, working_dir: Path, environment_variables_overrides: Dict[str, str] = None
) -> List[str]:
# TODO: support environment_variables_overrides
flow_tools_json_path = working_dir / PROMPT_FLOW_DIR_NAME / FLOW_TOOLS_JSON
tools_meta = read_json_content(flow_tools_json_path, "meta of tools")
flow_dag = load_yaml(flow_file)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pathlib import Path
from typing import List
from typing import Dict, List

from ._base_inspector_proxy import AbstractInspectorProxy

Expand All @@ -8,10 +8,12 @@ class PythonInspectorProxy(AbstractInspectorProxy):
def __init__(self):
super().__init__()

def get_used_connection_names(self, flow_file: Path, working_dir: Path) -> List[str]:
def get_used_connection_names(
self, flow_file: Path, working_dir: Path, environment_variables_overrides: Dict[str, str] = None
) -> List[str]:
from promptflow._utils.context_utils import _change_working_dir
from promptflow.contracts.flow import Flow as ExecutableFlow

with _change_working_dir(working_dir):
executable = ExecutableFlow.from_yaml(flow_file=flow_file, working_dir=working_dir)
return executable.get_connection_names()
return executable.get_connection_names(environment_variables_overrides=environment_variables_overrides)
4 changes: 2 additions & 2 deletions src/promptflow-devkit/promptflow/_sdk/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
PROMPT_FLOW_DIR_NAME,
ConnectionAuthMode,
ConnectionType,
CustomStrongTypeConnectionConfigs,
CustomStrongTypeConnectionConfigs, CONNECTION_SCRUBBED_VALUE_NO_CHANGE,
)

LOGGER_NAME = "promptflow"
Expand Down Expand Up @@ -113,7 +113,7 @@ def _prepare_home_dir() -> Path:
REFRESH_CONNECTIONS_DIR_LOCK_PATH = (HOME_PROMPT_FLOW_DIR / "refresh_connections_dir.lock").resolve()
# Note: Use this only for show. Reading input should regard all '*' string as scrubbed, no matter the length.
SCRUBBED_VALUE = CONNECTION_SCRUBBED_VALUE
SCRUBBED_VALUE_NO_CHANGE = "<no-change>"
SCRUBBED_VALUE_NO_CHANGE = CONNECTION_SCRUBBED_VALUE_NO_CHANGE
SCRUBBED_VALUE_USER_INPUT = "<user-input>"
WORKSPACE_LINKED_DATASTORE_NAME = "workspaceblobstore"
LINE_NUMBER = "line_number"
Expand Down
4 changes: 2 additions & 2 deletions src/promptflow-devkit/promptflow/_sdk/_orm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore

from promptflow._sdk._orm.experiment_node_run import ExperimentNodeRun
from promptflow._sdk._orm.orchestrator import Orchestrator
from promptflow._sdk._orm.run_info import RunInfo
from promptflow._sdk._orm.orchestrator import Orchestrator
from promptflow._sdk._orm.experiment_node_run import ExperimentNodeRun

from .connection import Connection
from .experiment import Experiment
Expand Down
8 changes: 4 additions & 4 deletions src/promptflow-devkit/promptflow/_sdk/_service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ If you don't specify a port to start service, pfs will first use the port in the
If not found port configuration or the port is used, pfs will use a random port to start the service.

### Swagger of service
After start the service, it will provide Swagger UI documentation, served from "http://localhost:your-port/v1.0/swagger.json".
After start the service, it will provide Swagger UI documentation, served from "http://localhost:your-port/v1.0/swagger.json".

For details, please refer to [swagger.json](./swagger.json).

#### Generate C# client
1. Right click the project, Add -> Rest API Client... -> Generate with OpenAPI Generator

1. Right click the project, Add -> Rest API Client... -> Generate with OpenAPI Generator
2. It will open a dialog, fill in the file name and swagger url, it will generate the client under the project.

For details, please refer to [REST API Client Code Generator](https://marketplace.visualstudio.com/items?itemName=ChristianResmaHelle.ApiClientCodeGenerator2022).
For details, please refer to [REST API Client Code Generator](https://marketplace.visualstudio.com/items?itemName=ChristianResmaHelle.ApiClientCodeGenerator2022).
4 changes: 2 additions & 2 deletions src/promptflow-devkit/promptflow/_sdk/_service/entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def validate_port(port, force_start):
app.logger.setLevel(logging.DEBUG)
else:
app.logger.setLevel(logging.INFO)
message = f"Start Prompt Flow Service on {port}, version: {get_promptflow_sdk_version()}"
message = f"Start Prompt Flow Service on {port}, version: {get_promptflow_sdk_version()}."
app.logger.info(message)
print(message)
sys.stdout.flush()
Expand Down Expand Up @@ -197,7 +197,7 @@ def validate_port(port, force_start):
subprocess.Popen(cmd, stdout=subprocess.DEVNULL, start_new_session=True)
is_healthy = check_pfs_service_status(port)
if is_healthy:
message = f"Start Prompt Flow Service on {port}, version: {get_promptflow_sdk_version()}"
message = f"Start Prompt Flow Service on port {port}, version: {get_promptflow_sdk_version()}."
print(message)
logger.info(message)
else:
Expand Down
7 changes: 3 additions & 4 deletions src/promptflow-devkit/promptflow/_sdk/_service/pfsvc.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# ---------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# ---------------------------------------------------------
from promptflow._sdk._service.entry import main
import sys

import servicemanager # Simple setup and logging
import win32service # Events
import win32serviceutil # ServiceFramework and commandline helper

from promptflow._sdk._service.entry import main
import win32service # Events
import servicemanager # Simple setup and logging


class PromptFlowService:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -631,12 +631,12 @@ function DFe() {
var Rr = Se._result;
return Rr === void 0 && fe(`lazy: Expected the result of a dynamic import() call. Instead received: %s

Your code should look like:
Your code should look like:
const MyComponent = lazy(() => import('./MyComponent'))

Did you accidentally put curly braces around the import?`, Rr), "default" in Rr || fe(`lazy: Expected the result of a dynamic import() call. Instead received: %s

Your code should look like:
Your code should look like:
const MyComponent = lazy(() => import('./MyComponent'))`, Rr), Rr.default;
} else
throw Se._result;
Expand Down Expand Up @@ -4471,7 +4471,7 @@ var QO = [], X$ = void 0;
function MBe(e) {
var t = j1.__options, r = 2e3, n = 10;
t.disableWarnings || (QO.push(e), X$ === void 0 && (X$ = setTimeout(function() {
Ab(`Some icons were re-registered. Applications should only call registerIcons for any given icon once. Redefining what an icon is may have unintended consequences. Duplicates include:
Ab(`Some icons were re-registered. Applications should only call registerIcons for any given icon once. Redefining what an icon is may have unintended consequences. Duplicates include:
` + QO.slice(0, n).join(", ") + (QO.length > n ? " (+ ".concat(QO.length - n, " more)") : "")), X$ = void 0, QO = [];
}, r)));
}
Expand Down Expand Up @@ -38766,18 +38766,18 @@ const gze = vze.compose({
template: QPe,
styles: pze,
checkedIndicator: `
<svg
<svg
part="checked-indicator"
class="checked-indicator"
width="16"
height="16"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M14.431 3.323l-8.47 10-.79-.036-3.35-4.77.818-.574 2.978 4.24 8.051-9.506.764.646z"
/>
</svg>
Expand Down Expand Up @@ -39034,18 +39034,18 @@ const Nze = Rze.compose({
template: kje,
styles: Oze,
indicator: `
<svg
<svg
class="select-indicator"
part="select-indicator"
width="16"
height="16"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M7.976 10.072l4.357-4.357.62.618L8.284 11h-.618L3 6.333l.619-.618 4.357 4.357z"
/>
</svg>
Expand Down Expand Up @@ -69889,7 +69889,7 @@ function Vft(e, t, r, n) {
if (!o)
return;
if (o === t) {
Wft.NODE_ENV !== "production" && Pu(!1, `[JSS] A rule tries to extend itself
Wft.NODE_ENV !== "production" && Pu(!1, `[JSS] A rule tries to extend itself
` + t.toString());
return;
}
Expand Down Expand Up @@ -70030,8 +70030,8 @@ function vK(e, t) {
var i = e.options, o = i.parent;
if (t[0] === "$") {
var a = o.getRule(t.substr(1));
return a ? a === e ? (xpe.NODE_ENV !== "production" && Pu(!1, `[JSS] Cyclic composition detected.
` + e.toString()), !1) : (o.classes[e.key] += " " + o.classes[a.key], !0) : (xpe.NODE_ENV !== "production" && Pu(!1, `[JSS] Referenced rule is not defined.
return a ? a === e ? (xpe.NODE_ENV !== "production" && Pu(!1, `[JSS] Cyclic composition detected.
` + e.toString()), !1) : (o.classes[e.key] += " " + o.classes[a.key], !0) : (xpe.NODE_ENV !== "production" && Pu(!1, `[JSS] Referenced rule is not defined.
` + e.toString()), !1);
}
return o.classes[e.key] += " " + t, !0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1255,4 +1255,4 @@
"description": "When any error occurs on the server, return a formatted error message"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,13 @@ def test(
logger.info("Testing completed. See full logs at %s.", test_context.output_path.as_posix())
return test_context.node_results

def _test_node(self, node, test_context) -> Run:
def _test_node(self, node, test_context):
if node.type == ExperimentNodeType.FLOW:
return self._test_flow_node(node, test_context)
elif node.type == ExperimentNodeType.COMMAND:
return self._test_command_node(node, test_context)
elif node.type == ExperimentNodeType.CHAT_GROUP:
return self._test_chat_group_node(node, test_context)
raise ExperimentValueError(f"Unknown experiment node {node.name!r} type {node.type!r}")

def _test_flow_node(self, node, test_context):
Expand Down Expand Up @@ -166,6 +168,14 @@ def _test_flow_node(self, node, test_context):
def _test_command_node(self, *args, **kwargs):
raise NotImplementedError

def _test_chat_group_node(self, node, test_context):
from promptflow._sdk.entities._chat_group._chat_group import ChatGroup

chat_group = ChatGroup._from_node(node, test_context)
logger.debug(f"Invoking chat group node {node.name!r}.")
chat_group.invoke()
return chat_group.conversation_history

def start(self, nodes=None, from_nodes=None, attempt=None, **kwargs):
"""Start an execution of nodes.
Expand Down
Loading

0 comments on commit 7887c57

Please sign in to comment.